fix: addresses issue with creating stories (#2442)

This commit is contained in:
Wyatt Johnson
2019-08-02 21:02:47 +00:00
committed by Kim Gardner
parent fdc6afec42
commit 4e548e8fbf
4 changed files with 78 additions and 21 deletions
+20 -5
View File
@@ -7,7 +7,7 @@ it("converts nested properties", () => {
};
const output = dotize(input);
expect(output).toEqual({
expect(output).toStrictEqual({
a: "property",
"can.be": "nested",
"can.really.deeply": "sometimes",
@@ -19,7 +19,7 @@ it("converts properties with dates", () => {
const input = { a: now, can: { be: now } };
const output = dotize(input);
expect(output).toEqual({
expect(output).toStrictEqual({
a: now,
"can.be": now,
});
@@ -35,7 +35,7 @@ it("converts array properties when enabled", () => {
};
const output = dotize(input);
expect(output).toEqual({
expect(output).toStrictEqual({
"a[0].property": "with",
"a[0].an": "array",
"a[1].value[0].sometimes": "nested",
@@ -53,7 +53,7 @@ it("does not converts array properties when disabled", () => {
};
const output = dotize(input, { ignoreArrays: true });
expect(output).toEqual({
expect(output).toStrictEqual({
"other.times": "not",
});
});
@@ -61,7 +61,22 @@ it("does not converts array properties when disabled", () => {
it("does convert array properties properly", () => {
expect(
dotize({ wordlist: { banned: ["banned"] } }, { embedArrays: true })
).toEqual({
).toStrictEqual({
"wordlist.banned": ["banned"],
});
});
it("does exclude undefined properties by default", () => {
expect(dotize({ test: { is: undefined, a: 1 } })).toStrictEqual({
"test.a": 1,
});
});
it("does include undefined properties when requested", () => {
expect(
dotize({ test: { is: undefined, a: 1 } }, { includeUndefined: true })
).toStrictEqual({
"test.a": 1,
"test.is": undefined,
});
});
+56 -15
View File
@@ -1,4 +1,11 @@
import { isArray, isNull, isNumber, isPlainObject, isString } from "lodash";
import {
isArray,
isNull,
isNumber,
isPlainObject,
isString,
isUndefined,
} from "lodash";
function isObject(obj: any): obj is Record<string, any> {
return isPlainObject(obj);
@@ -12,13 +19,23 @@ function deriveKey(property: string, prefix?: string) {
return property;
}
function reduce(
result: Record<string, any>,
obj: Record<string, any> | number | null | string,
ignoreArrays: boolean,
embedArrays: boolean,
prefix?: string
) {
interface ReduceOptions {
result: Record<string, any>;
obj: Record<string, any> | number | null | string;
ignoreArrays: boolean;
embedArrays: boolean;
includeUndefined: boolean;
prefix?: string;
}
function reduce({
result,
obj,
ignoreArrays,
embedArrays,
includeUndefined,
prefix,
}: ReduceOptions) {
if (prefix) {
if (isNumber(obj) || isString(obj) || isNull(obj)) {
result[prefix] = obj;
@@ -36,24 +53,38 @@ function reduce(
const key = deriveKey(property, prefix);
if (isPlainObject(value)) {
reduce(result, value, ignoreArrays, embedArrays, key);
reduce({
result,
obj: value,
ignoreArrays,
embedArrays,
includeUndefined,
prefix: key,
});
} else if (isArray(value)) {
if (!ignoreArrays) {
if (embedArrays) {
result[key] = value;
} else {
value.forEach((item, index) => {
reduce(
reduce({
result,
item,
obj: item,
ignoreArrays,
embedArrays,
`${key}[${index}]`
);
includeUndefined,
prefix: `${key}[${index}]`,
});
});
}
}
} else {
// If the underlying value is undefined and we aren't including
// undefined elements, then continue.
if (!includeUndefined && isUndefined(value)) {
continue;
}
result[key] = value;
}
}
@@ -74,9 +105,19 @@ export interface DotizeOptions {
* without recusing the dotize algorithm to it.
*/
embedArrays?: boolean;
/**
* includeUndefined if true, will include undefined values in the result.
*/
includeUndefined?: boolean;
}
export const dotize = (
obj: Record<string, any>,
{ ignoreArrays = false, embedArrays = false }: DotizeOptions = {}
): Record<string, any> => reduce({}, obj, ignoreArrays, embedArrays);
{
ignoreArrays = false,
embedArrays = false,
includeUndefined = false,
}: DotizeOptions = {}
): Record<string, any> =>
reduce({ result: {}, obj, ignoreArrays, embedArrays, includeUndefined });
+1 -1
View File
@@ -311,7 +311,7 @@ export async function retrieveManyStoriesByURL(
export type UpdateStoryInput = Omit<
Partial<Story>,
"id" | "tenantID" | "createdAt"
"id" | "tenantID" | "closedAt" | "createdAt"
>;
export async function updateStory(
@@ -7,6 +7,7 @@ export async function createMongoClient(config: Config): Promise<MongoClient> {
try {
return await MongoClient.connect(config.get("mongodb"), {
useNewUrlParser: true,
ignoreUndefined: true,
});
} catch (err) {
throw new InternalError(err, "could not connect to mongodb");