[next] Tasks (#1777)

* feat: initial support for synced tenants

* fix: cleanup

* fix: logger now respects logging level

* fix: cache now ignores updates issued from itself

* feat: print subscriber count

* feat: initial moderation + validation for new comments

* fix: added Promiseable type

* feat: initial actions impl

* feat: more moderation phases

* fix: handle settings inheritence

* fix: moved settings into new file

* fix: defaults and documentation

* fix: replace merge with object spread

* feat: added integration with akismet

* fix: support tenant cache for oidc strategy

* fix: fixed compile

* fix: import ordering

* feat: added bull for queue support

* feat: support for scraping

* fix: fixes for scraper

- Implemented simple metascraper replacement (to resolve security advisory
  warning)
- Implemented simle dotize replacement (to resolve not
  working version that couldn't handle date objects)
- Plugged in asset scraping to asset creation process

* fix: handles array values

* feat: added initial scraper implementation

* feat: seperate queues but share config

* fix: simplified auth data access

* feat: moved more settings into the graph

* feat: improved mailer design

* fix: fixed issue with dotize

* fix: fixed some issues with adapter

* fix: queue cleanup

* feat: added organizationName to Tenant

* feat: email rendering

* review: support es6 imports

* fix: restore old ci step

* fix: adjusted logging messages
This commit is contained in:
Wyatt Johnson
2018-09-04 18:47:20 +00:00
committed by GitHub
parent 76d198f2a6
commit 59cf728681
46 changed files with 1804 additions and 377 deletions
+67
View File
@@ -0,0 +1,67 @@
import { dotize } from "talk-common/utils/dotize";
it("converts nested properties", () => {
const input = {
a: "property",
can: { be: "nested", really: { deeply: "sometimes" } },
};
const output = dotize(input);
expect(output).toEqual({
a: "property",
"can.be": "nested",
"can.really.deeply": "sometimes",
});
});
it("converts properties with dates", () => {
const now = new Date();
const input = { a: now, can: { be: now } };
const output = dotize(input);
expect(output).toEqual({
a: now,
"can.be": now,
});
});
it("converts array properties when enabled", () => {
const input = {
a: [
{ property: "with", an: "array" },
{ value: [{ sometimes: "nested" }] },
],
other: { times: "not" },
};
const output = dotize(input);
expect(output).toEqual({
"a[0].property": "with",
"a[0].an": "array",
"a[1].value[0].sometimes": "nested",
"other.times": "not",
});
});
it("does not converts array properties when disabled", () => {
const input = {
a: [
{ property: "with", an: "array" },
{ value: [{ sometimes: "nested" }] },
],
other: { times: "not" },
};
const output = dotize(input, { ignoreArrays: true });
expect(output).toEqual({
"other.times": "not",
});
});
it("does convert array properties properly", () => {
expect(
dotize({ wordlist: { banned: ["banned"] } }, { embedArrays: true })
).toEqual({
"wordlist.banned": ["banned"],
});
});
+82
View File
@@ -0,0 +1,82 @@
import { isArray, isNull, isNumber, isPlainObject, isString } from "lodash";
function isObject(obj: any): obj is Record<string, any> {
return isPlainObject(obj);
}
function deriveKey(property: string, prefix?: string) {
if (prefix) {
return `${prefix}.${property}`;
}
return property;
}
function reduce(
result: Record<string, any>,
obj: Record<string, any> | number | null | string,
ignoreArrays: boolean,
embedArrays: boolean,
prefix?: string
) {
if (prefix) {
if (isNumber(obj) || isString(obj) || isNull(obj)) {
result[prefix] = obj;
return result;
}
}
if (isObject(obj)) {
for (const property in obj) {
if (!obj.hasOwnProperty(property)) {
continue;
}
const value = obj[property];
const key = deriveKey(property, prefix);
if (isPlainObject(value)) {
reduce(result, value, ignoreArrays, embedArrays, key);
} else if (isArray(value)) {
if (!ignoreArrays) {
if (embedArrays) {
result[key] = value;
} else {
value.forEach((item, index) => {
reduce(
result,
item,
ignoreArrays,
embedArrays,
`${key}[${index}]`
);
});
}
}
} else {
result[key] = value;
}
}
}
return result;
}
export interface DotizeOptions {
/**
* ignoreArrays will ignore all array properties and not include them in the
* resulting entry.
*/
ignoreArrays?: boolean;
/**
* embedArrays will treat arrays as plain objects, and embed them as is
* without recusing the dotize algorithm to it.
*/
embedArrays?: boolean;
}
export const dotize = (
obj: Record<string, any>,
{ ignoreArrays = false, embedArrays = false }: DotizeOptions = {}
): Record<string, any> => reduce({}, obj, ignoreArrays, embedArrays);