joist-test-utils 2.3.0 → 2.4.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/RunPlugin.cjs +219 -0
- package/build/RunPlugin.cjs.map +1 -0
- package/build/RunPlugin.d.cts +12 -0
- package/build/RunPlugin.d.cts.map +1 -0
- package/build/RunPlugin.d.mts +12 -0
- package/build/RunPlugin.d.mts.map +1 -0
- package/build/RunPlugin.js +203 -341
- package/build/RunPlugin.js.map +1 -1
- package/build/_virtual/_rolldown/runtime.cjs +23 -0
- package/build/context.cjs +2 -0
- package/build/context.d.cts +9 -0
- package/build/context.d.cts.map +1 -0
- package/build/context.d.mts +9 -0
- package/build/context.d.mts.map +1 -0
- package/build/context.js +2 -3
- package/build/index.cjs +38 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.cts +52 -0
- package/build/index.d.cts.map +1 -0
- package/build/index.d.mts +52 -0
- package/build/index.d.mts.map +1 -0
- package/build/index.js +25 -41
- package/build/index.js.map +1 -1
- package/build/run.cjs +77 -0
- package/build/run.cjs.map +1 -0
- package/build/run.d.cts +17 -0
- package/build/run.d.cts.map +1 -0
- package/build/run.d.mts +17 -0
- package/build/run.d.mts.map +1 -0
- package/build/run.js +52 -76
- package/build/run.js.map +1 -1
- package/build/seed.cjs +54 -0
- package/build/seed.cjs.map +1 -0
- package/build/{seed.d.ts → seed.d.cts} +9 -6
- package/build/seed.d.cts.map +1 -0
- package/build/seed.d.mts +35 -0
- package/build/seed.d.mts.map +1 -0
- package/build/seed.js +47 -53
- package/build/seed.js.map +1 -1
- package/build/toMatchEntity.cjs +94 -0
- package/build/toMatchEntity.cjs.map +1 -0
- package/build/toMatchEntity.d.cts +28 -0
- package/build/toMatchEntity.d.cts.map +1 -0
- package/build/toMatchEntity.d.mts +28 -0
- package/build/toMatchEntity.d.mts.map +1 -0
- package/build/toMatchEntity.js +73 -109
- package/build/toMatchEntity.js.map +1 -1
- package/package.json +33 -13
- package/build/RunPlugin.d.ts +0 -9
- package/build/RunPlugin.d.ts.map +0 -1
- package/build/context.d.ts +0 -6
- package/build/context.d.ts.map +0 -1
- package/build/context.js.map +0 -1
- package/build/index.d.ts +0 -42
- package/build/index.d.ts.map +0 -1
- package/build/run.d.ts +0 -15
- package/build/run.d.ts.map +0 -1
- package/build/seed.d.ts.map +0 -1
- package/build/toMatchEntity.d.ts +0 -27
- package/build/toMatchEntity.d.ts.map +0 -1
package/build/toMatchEntity.js
CHANGED
|
@@ -1,129 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
// This might be undefined if running outside of jest
|
|
7
|
-
const jestMatchers = globalThis[Symbol.for("$$jest-matchers-object")];
|
|
8
|
-
const matchers = jestMatchers?.matchers;
|
|
1
|
+
import "./index.js";
|
|
2
|
+
import { BaseEntity, isAsyncProperty, isCollection, isDefined, isEntity, isProperty, isReactiveField, isReference } from "joist-core";
|
|
3
|
+
import { isPlainObject } from "joist-utils";
|
|
4
|
+
//#region src/toMatchEntity.ts
|
|
5
|
+
const isVitest = typeof process !== "undefined" && process.env?.VITEST === "true";
|
|
9
6
|
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
* Provides convenient `toMatchObject`-style matching for Joist entities.
|
|
8
|
+
*
|
|
9
|
+
* The biggest differences over `toMatchObject` are:
|
|
10
|
+
*
|
|
11
|
+
* - We un-wrap relations like m2o/o2m to just the underlying object/arrays, to make
|
|
12
|
+
* asserting against the entities look like asserting against POJOs
|
|
13
|
+
* - We prune the expected/actual values to be as minimal as possible, to avoid Jest
|
|
14
|
+
* recursively crawling into connection pools or other misc non-useful things in the diffs
|
|
15
|
+
*/
|
|
19
16
|
function toMatchEntity(actual, expected) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
else {
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
return matchers.toMatchObject.call(this, cleanActual, cleanExpected);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
// this is bun--it's matcherHint actually seems to do `toMatchObject` already?
|
|
45
|
-
return {
|
|
46
|
-
pass: this.equals(cleanActual, cleanExpected),
|
|
47
|
-
message: () => this.utils.matcherHint("toMatchEntity", cleanActual, cleanExpected),
|
|
48
|
-
};
|
|
49
|
-
}
|
|
17
|
+
const matchers = isVitest ? void 0 : globalThis[Symbol.for("$$jest-matchers-object")]?.matchers;
|
|
18
|
+
const cleanExpected = deepClone(expected);
|
|
19
|
+
const cleanActual = deepClone(deepMirror(cleanExpected, actual));
|
|
20
|
+
if (matchers) {
|
|
21
|
+
if (typeof cleanActual !== "object") return matchers.toEqual.call(this, cleanActual, cleanExpected);
|
|
22
|
+
else return matchers.toMatchObject.call(this, cleanActual, cleanExpected);
|
|
23
|
+
} else if (isVitest) return {
|
|
24
|
+
pass: this.equals(cleanActual, cleanExpected, this.customTesters),
|
|
25
|
+
message: () => {
|
|
26
|
+
const hint = this.utils.matcherHint("toMatchEntity", void 0, void 0, { isNot: this.isNot });
|
|
27
|
+
const diff = this.utils.diff(cleanExpected, cleanActual);
|
|
28
|
+
return diff ? `${hint}\n\n${diff}` : hint;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
else return {
|
|
32
|
+
pass: this.equals(cleanActual, cleanExpected),
|
|
33
|
+
message: () => this.utils.matcherHint("toMatchEntity", cleanActual, cleanExpected)
|
|
34
|
+
};
|
|
50
35
|
}
|
|
51
36
|
function maybeTestId(maybeEntity) {
|
|
52
|
-
|
|
37
|
+
return isEntity(maybeEntity) ? getTestId(maybeEntity.em, maybeEntity) : maybeEntity;
|
|
53
38
|
}
|
|
54
39
|
/** Returns either the persisted id or `tag#<offset-in-EntityManager>`. */
|
|
55
40
|
function getTestId(_, entity) {
|
|
56
|
-
|
|
41
|
+
return entity.toTaggedString();
|
|
57
42
|
}
|
|
58
43
|
/**
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
44
|
+
* Make a "new actual" based on the subset shape of expected.
|
|
45
|
+
*
|
|
46
|
+
* We don't have cycle detection, but that should be fine b/c the user types
|
|
47
|
+
* out the expected as an object literal, so it shouldn't have cycles
|
|
48
|
+
*/
|
|
64
49
|
function deepMirror(expected, actual) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (!(0, joist_core_1.isDefined)(actual))
|
|
72
|
-
return actual;
|
|
73
|
-
// Make a new actual that is a subset that matches expected
|
|
74
|
-
const subset = Array.isArray(expected) ? [] : {};
|
|
75
|
-
// If both are arrays, fill out the whole array
|
|
76
|
-
const keys = Array.isArray(actual) ? Object.keys(actual) : Object.keys(expected);
|
|
77
|
-
for (const key of keys) {
|
|
78
|
-
if (key in actual) {
|
|
79
|
-
// Even if actualValue is an Entity, if expected has a key drilling in to it, we want to object literal-ize it
|
|
80
|
-
subset[key] = deepMirror(expected[key], maybeGetRelation(actual[key]));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return subset;
|
|
50
|
+
if (!isPlainObject(expected) && !Array.isArray(expected)) return actual;
|
|
51
|
+
if (!isDefined(actual)) return actual;
|
|
52
|
+
const subset = Array.isArray(expected) ? [] : {};
|
|
53
|
+
const keys = Array.isArray(actual) ? Object.keys(actual) : Object.keys(expected);
|
|
54
|
+
for (const key of keys) if (key in actual) subset[key] = deepMirror(expected[key], maybeGetRelation(actual[key]));
|
|
55
|
+
return subset;
|
|
84
56
|
}
|
|
85
57
|
/** Make a clone of `obj`, but only recurse into POJOs and Arrays, and replace entities if we find them. */
|
|
86
|
-
function deepClone(obj, map = new WeakMap()) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
Object.assign(result, ...Object.keys(obj).map((key) => ({ [key]: deepClone(obj[key], map) })));
|
|
96
|
-
return result;
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
return obj;
|
|
100
|
-
}
|
|
58
|
+
function deepClone(obj, map = /* @__PURE__ */ new WeakMap()) {
|
|
59
|
+
if (obj instanceof BaseEntity) return maybeTestId(obj);
|
|
60
|
+
else if (obj && typeof obj === "object" && (isPlainObject(obj) || Array.isArray(obj))) {
|
|
61
|
+
if (map.has(obj)) return map.get(obj);
|
|
62
|
+
const result = Array.isArray(obj) ? [] : {};
|
|
63
|
+
map.set(obj, result);
|
|
64
|
+
Object.assign(result, ...Object.keys(obj).map((key) => ({ [key]: deepClone(obj[key], map) })));
|
|
65
|
+
return result;
|
|
66
|
+
} else return obj;
|
|
101
67
|
}
|
|
102
68
|
/** Flattens/simplifies relations into their actual value, i.e. "calls get". */
|
|
103
69
|
function maybeGetRelation(actualValue) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
(0, joist_core_1.isProperty)(actualValue) ||
|
|
107
|
-
(0, joist_core_1.isReactiveField)(actualValue)) {
|
|
108
|
-
return getWithSoftDeleted(actualValue);
|
|
109
|
-
}
|
|
110
|
-
return actualValue;
|
|
70
|
+
if (isReference(actualValue) || isCollection(actualValue) || isProperty(actualValue) || isReactiveField(actualValue) || isAsyncProperty(actualValue)) return getWithSoftDeleted(actualValue);
|
|
71
|
+
return actualValue;
|
|
111
72
|
}
|
|
112
73
|
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
74
|
+
* Adds back soft-deleted to `.get`.
|
|
75
|
+
*
|
|
76
|
+
* In Joist, `.get` filters both soft and hard deleted entities, because `.get`
|
|
77
|
+
* is likely used by real business logic that doesn't want to see either.
|
|
78
|
+
*
|
|
79
|
+
* However, in tests with `toMatchEntity`, we take a stronger stance that the
|
|
80
|
+
* developer needs to know "this is _soft_ deleted and not hard deleted", so
|
|
81
|
+
* we add-back soft deleted entities.
|
|
82
|
+
*
|
|
83
|
+
* We do this by calling `getWithDeleted`, which returns all hard and soft
|
|
84
|
+
* deleted entities, and then filtering out the hard deletes.
|
|
85
|
+
*/
|
|
125
86
|
function getWithSoftDeleted(relation) {
|
|
126
|
-
|
|
127
|
-
|
|
87
|
+
const r = "getWithDeleted" in relation ? relation.getWithDeleted : relation.get;
|
|
88
|
+
return Array.isArray(r) ? r.filter((e) => !e.isDeletedEntity) : r;
|
|
128
89
|
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { toMatchEntity };
|
|
92
|
+
|
|
129
93
|
//# sourceMappingURL=toMatchEntity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toMatchEntity.js","sourceRoot":"","sources":["../src/toMatchEntity.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toMatchEntity.js","names":[],"sources":["../src/toMatchEntity.ts"],"sourcesContent":["import {\n BaseEntity,\n type Entity,\n type EntityManager,\n type Property,\n type ReadOnlyCollection,\n type Reference,\n isAsyncProperty,\n isCollection,\n isDefined,\n isEntity,\n isProperty,\n isReactiveField,\n isReference,\n} from \"joist-core\";\nimport { isPlainObject } from \"joist-utils\";\n\nimport { type CustomMatcherResult } from \"./index.ts\";\n\n// Vitest also populates the `$$jest-matchers-object` symbol, but the matchers it stores there are\n// chai-based and assume `this` is a chai Assertion (with a `this.assert` method), which our custom\n// matcher's `this` context is not--so calling them throws `this.assert is not a function`. Only take\n// the Jest fast-path under actual Jest, and route Vitest through the `this.equals` path below (like Bun).\nconst isVitest = typeof process !== \"undefined\" && process.env?.VITEST === \"true\";\n\n/**\n * Provides convenient `toMatchObject`-style matching for Joist entities.\n *\n * The biggest differences over `toMatchObject` are:\n *\n * - We un-wrap relations like m2o/o2m to just the underlying object/arrays, to make\n * asserting against the entities look like asserting against POJOs\n * - We prune the expected/actual values to be as minimal as possible, to avoid Jest\n * recursively crawling into connection pools or other misc non-useful things in the diffs\n */\nexport function toMatchEntity<T>(this: any, actual: unknown, expected: MatchedEntity<T>): CustomMatcherResult {\n // This module can load before Jest initializes its matcher state, so read the global when invoked.\n const matchers = isVitest ? undefined : (globalThis as any)[Symbol.for(\"$$jest-matchers-object\")]?.matchers;\n // We're given expected, which is an object literal of what the user wants to match\n // against (some intermixed POJOs & entities) and actual (which similarly could be\n // intermixed POJOs & entities, but will likely be more sprawling because it's the\n // full result, and not the subset we're asserting against).\n //\n // Given this, first make a safe clone of `expected`, i.e. turn entities into strings.\n // After that, use `expected` as a template to pick keys out of actual. Finally, do the\n // same \"clean clone\" of actual, and compare the two.\n const cleanExpected = deepClone(expected);\n const cleanActual = deepClone(deepMirror(cleanExpected, actual));\n\n // Watch for `expect(someAuthor).toMatchEntity(a1)` as we'll turn `someAuthor` into \"a:1\",\n // so can't use toMatchObject anymore.\n if (matchers) {\n // this is jest\n if (typeof cleanActual !== \"object\") {\n // @ts-ignore\n return matchers.toEqual.call(this, cleanActual, cleanExpected);\n } else {\n // @ts-ignore\n return matchers.toMatchObject.call(this, cleanActual, cleanExpected);\n }\n } else if (isVitest) {\n // `deepMirror` already pruned `cleanActual` down to the subset of keys that `cleanExpected`\n // declares, so a full `this.equals` deep-equality behaves like Jest's `toMatchObject`. We pass\n // `this.customTesters` so `areEntitiesEqual` still applies. Building the diff into `message`\n // (like Jest's `toMatchObject`) keeps the failure output readable both in the terminal and in\n // `toThrowErrorMatchingInlineSnapshot`, instead of the default `expect([object Object])...`.\n const pass = this.equals(cleanActual, cleanExpected, this.customTesters);\n return {\n pass,\n message: () => {\n const hint = this.utils.matcherHint(\"toMatchEntity\", undefined, undefined, { isNot: this.isNot });\n const diff = this.utils.diff(cleanExpected, cleanActual);\n return diff ? `${hint}\\n\\n${diff}` : hint;\n },\n };\n } else {\n // This is Bun, whose matcher `this.utils` only exposes `matcherHint`.\n return {\n pass: this.equals(cleanActual, cleanExpected),\n message: () => this.utils.matcherHint(\"toMatchEntity\", cleanActual, cleanExpected),\n };\n }\n}\n\nfunction maybeTestId(maybeEntity: any): any {\n return isEntity(maybeEntity) ? getTestId(maybeEntity.em, maybeEntity) : maybeEntity;\n}\n\n/** Returns either the persisted id or `tag#<offset-in-EntityManager>`. */\nfunction getTestId(_: EntityManager, entity: Entity): string {\n return entity.toTaggedString();\n}\n\n/**\n * Given a Joist entity `T`, \"flattens out\" the Reference/Collections.\n *\n * I.e. so that you can `toMatchEntity({ otherEntity: { name: \"foo\" } })` even though\n * `otherEntity` is technically a joist `Reference` or `Collection`.\n *\n * We allow `| null` so that `toMatchEntity` can work against optional fields\n * that are returned from GraphQL object resolvers.\n */\nexport type MatchedEntity<T> =\n T extends ReadonlyArray<infer U>\n ? ReadonlyArray<MatchedEntity<U>>\n :\n | undefined\n | T\n | {\n [K in keyof T]?: T[K] extends Reference<any, infer U, any>\n ? MatchedEntity<U> | U\n : T[K] extends ReadOnlyCollection<any, infer U>\n ? Array<MatchedEntity<U> | U>\n : T[K] extends Property<any, infer V>\n ? V\n : T[K] extends Entity | null | undefined\n ? MatchedEntity<T[K]> | T[K] | null | undefined\n : T[K] extends ReadonlyArray<(infer U) | undefined>\n ? readonly (MatchedEntity<U> | U | undefined)[]\n : T[K] extends ReadonlyArray<infer U> | null\n ? readonly (MatchedEntity<U> | U | null)[]\n : // We recurse similar to a DeepPartial\n MatchedEntity<T[K]> | null;\n };\n\n/**\n * Make a \"new actual\" based on the subset shape of expected.\n *\n * We don't have cycle detection, but that should be fine b/c the user types\n * out the expected as an object literal, so it shouldn't have cycles\n */\nfunction deepMirror(expected: any, actual: any): any {\n // If we've hit a point where the `expected` input is not a POJO object literal/array\n // declaring the subset of the shape to assert against, just return actual as-is.\n // This might be a Date (safe) or an Entity (unsafe) or something else, but if so it will\n // get cleaned up by the `deepClone` pass.\n if (!isPlainObject(expected) && !Array.isArray(expected)) return actual;\n if (!isDefined(actual)) return actual;\n // Make a new actual that is a subset that matches expected\n const subset: any = Array.isArray(expected) ? [] : ({} as any);\n // If both are arrays, fill out the whole array\n const keys = Array.isArray(actual) ? Object.keys(actual) : Object.keys(expected);\n for (const key of keys) {\n if (key in actual) {\n // Even if actualValue is an Entity, if expected has a key drilling in to it, we want to object literal-ize it\n subset[key] = deepMirror((expected as any)[key], maybeGetRelation(actual[key]));\n }\n }\n return subset;\n}\n\n/** Make a clone of `obj`, but only recurse into POJOs and Arrays, and replace entities if we find them. */\nfunction deepClone(obj: unknown, map = new WeakMap()): unknown {\n if (obj instanceof BaseEntity) {\n return maybeTestId(obj);\n } else if (obj && typeof obj === \"object\" && (isPlainObject(obj) || Array.isArray(obj))) {\n if (map.has(obj)) return map.get(obj);\n const result = Array.isArray(obj) ? [] : {};\n map.set(obj, result);\n Object.assign(result, ...Object.keys(obj).map((key) => ({ [key]: deepClone((obj as any)[key], map) })));\n return result;\n } else {\n return obj;\n }\n}\n\n/** Flattens/simplifies relations into their actual value, i.e. \"calls get\". */\nfunction maybeGetRelation(actualValue: unknown): unknown {\n if (\n isReference(actualValue) ||\n isCollection(actualValue) ||\n isProperty(actualValue) ||\n isReactiveField(actualValue) ||\n // hasAsyncPropertys will work if they've been already loaded, so let the user try it\n isAsyncProperty(actualValue)\n ) {\n return getWithSoftDeleted(actualValue);\n }\n return actualValue;\n}\n\n/**\n * Adds back soft-deleted to `.get`.\n *\n * In Joist, `.get` filters both soft and hard deleted entities, because `.get`\n * is likely used by real business logic that doesn't want to see either.\n *\n * However, in tests with `toMatchEntity`, we take a stronger stance that the\n * developer needs to know \"this is _soft_ deleted and not hard deleted\", so\n * we add-back soft deleted entities.\n *\n * We do this by calling `getWithDeleted`, which returns all hard and soft\n * deleted entities, and then filtering out the hard deletes.\n */\nfunction getWithSoftDeleted(relation: any): any {\n const r = \"getWithDeleted\" in relation ? relation.getWithDeleted : relation.get;\n return Array.isArray(r) ? r.filter((e: any) => !e.isDeletedEntity) : r;\n}\n"],"mappings":";;;;AAuBA,MAAM,WAAW,OAAO,YAAY,eAAe,QAAQ,KAAK,WAAW;;;;;;;;;;;AAY3E,SAAgB,cAA4B,QAAiB,UAAiD;CAE5G,MAAM,WAAW,WAAW,KAAA,IAAa,WAAmB,OAAO,IAAI,wBAAwB,EAAE,EAAE;CASnG,MAAM,gBAAgB,UAAU,QAAQ;CACxC,MAAM,cAAc,UAAU,WAAW,eAAe,MAAM,CAAC;CAI/D,IAAI,UAAU;EAEZ,IAAI,OAAO,gBAAgB,UAEzB,OAAO,SAAS,QAAQ,KAAK,MAAM,aAAa,aAAa;OAG7D,OAAO,SAAS,cAAc,KAAK,MAAM,aAAa,aAAa;CAEvE,OAAO,IAAI,UAOT,OAAO;EACL,MAFW,KAAK,OAAO,aAAa,eAAe,KAAK,aAErD;EACH,eAAe;GACb,MAAM,OAAO,KAAK,MAAM,YAAY,iBAAiB,KAAA,GAAW,KAAA,GAAW,EAAE,OAAO,KAAK,MAAM,CAAC;GAChG,MAAM,OAAO,KAAK,MAAM,KAAK,eAAe,WAAW;GACvD,OAAO,OAAO,GAAG,KAAK,MAAM,SAAS;EACvC;CACF;MAGA,OAAO;EACL,MAAM,KAAK,OAAO,aAAa,aAAa;EAC5C,eAAe,KAAK,MAAM,YAAY,iBAAiB,aAAa,aAAa;CACnF;AAEJ;AAEA,SAAS,YAAY,aAAuB;CAC1C,OAAO,SAAS,WAAW,IAAI,UAAU,YAAY,IAAI,WAAW,IAAI;AAC1E;;AAGA,SAAS,UAAU,GAAkB,QAAwB;CAC3D,OAAO,OAAO,eAAe;AAC/B;;;;;;;AAwCA,SAAS,WAAW,UAAe,QAAkB;CAKnD,IAAI,CAAC,cAAc,QAAQ,KAAK,CAAC,MAAM,QAAQ,QAAQ,GAAG,OAAO;CACjE,IAAI,CAAC,UAAU,MAAM,GAAG,OAAO;CAE/B,MAAM,SAAc,MAAM,QAAQ,QAAQ,IAAI,CAAC,IAAK,CAAC;CAErD,MAAM,OAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,QAAQ;CAC/E,KAAK,MAAM,OAAO,MAChB,IAAI,OAAO,QAET,OAAO,OAAO,WAAY,SAAiB,MAAM,iBAAiB,OAAO,IAAI,CAAC;CAGlF,OAAO;AACT;;AAGA,SAAS,UAAU,KAAc,sBAAM,IAAI,QAAQ,GAAY;CAC7D,IAAI,eAAe,YACjB,OAAO,YAAY,GAAG;MACjB,IAAI,OAAO,OAAO,QAAQ,aAAa,cAAc,GAAG,KAAK,MAAM,QAAQ,GAAG,IAAI;EACvF,IAAI,IAAI,IAAI,GAAG,GAAG,OAAO,IAAI,IAAI,GAAG;EACpC,MAAM,SAAS,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;EAC1C,IAAI,IAAI,KAAK,MAAM;EACnB,OAAO,OAAO,QAAQ,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,KAAK,SAAS,GAAG,MAAM,UAAW,IAAY,MAAM,GAAG,EAAE,EAAE,CAAC;EACtG,OAAO;CACT,OACE,OAAO;AAEX;;AAGA,SAAS,iBAAiB,aAA+B;CACvD,IACE,YAAY,WAAW,KACvB,aAAa,WAAW,KACxB,WAAW,WAAW,KACtB,gBAAgB,WAAW,KAE3B,gBAAgB,WAAW,GAE3B,OAAO,mBAAmB,WAAW;CAEvC,OAAO;AACT;;;;;;;;;;;;;;AAeA,SAAS,mBAAmB,UAAoB;CAC9C,MAAM,IAAI,oBAAoB,WAAW,SAAS,iBAAiB,SAAS;CAC5E,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,QAAQ,MAAW,CAAC,EAAE,eAAe,IAAI;AACvE"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "joist-test-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0-next.2",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "build/index.cjs",
|
|
7
|
+
"module": "build/index.js",
|
|
8
|
+
"types": "build/index.d.mts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"bun": {
|
|
12
|
+
"types": "./build/index.d.mts",
|
|
13
|
+
"default": "./build/index.js"
|
|
14
|
+
},
|
|
15
|
+
"module-sync": {
|
|
16
|
+
"types": "./build/index.d.mts",
|
|
17
|
+
"default": "./build/index.js"
|
|
18
|
+
},
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./build/index.d.mts",
|
|
21
|
+
"default": "./build/index.js"
|
|
22
|
+
},
|
|
23
|
+
"require": {
|
|
24
|
+
"types": "./build/index.d.cts",
|
|
25
|
+
"default": "./build/index.cjs"
|
|
26
|
+
},
|
|
27
|
+
"default": "./build/index.js"
|
|
28
|
+
}
|
|
9
29
|
},
|
|
10
30
|
"files": [
|
|
11
31
|
"build"
|
|
12
32
|
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"dotenv": "^17.4.2"
|
|
35
|
+
},
|
|
13
36
|
"peerDependencies": {
|
|
14
|
-
"joist-core": "2.
|
|
15
|
-
"joist-utils": "2.
|
|
16
|
-
"pg": "^8.
|
|
37
|
+
"joist-core": "2.4.0-next.2",
|
|
38
|
+
"joist-utils": "2.4.0-next.2",
|
|
39
|
+
"pg": "^8.23.0"
|
|
17
40
|
},
|
|
18
41
|
"devDependencies": {
|
|
19
|
-
"@swc/core": "^1.
|
|
42
|
+
"@swc/core": "^1.16.1",
|
|
20
43
|
"@swc/jest": "^0.2.39",
|
|
21
44
|
"@types/jest": "^30.0.0",
|
|
22
45
|
"jest": "30.4.2",
|
|
23
|
-
"prettier": "^3.8.4",
|
|
24
|
-
"prettier-plugin-organize-imports": "^4.3.0",
|
|
25
|
-
"ts-node-dev": "^2.0.0",
|
|
26
46
|
"tsconfig-paths": "^4.2.0",
|
|
27
|
-
"typescript": "
|
|
47
|
+
"typescript": "7.0.2"
|
|
28
48
|
}
|
|
29
49
|
}
|
package/build/RunPlugin.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { EntityManager, JoinRowTodo, Plugin, Todo } from "joist-core";
|
|
2
|
-
export declare class RunPlugin extends Plugin {
|
|
3
|
-
#private;
|
|
4
|
-
readonly em: EntityManager;
|
|
5
|
-
constructor(em: EntityManager);
|
|
6
|
-
maybeCloneForNewEm(): this;
|
|
7
|
-
afterWrite(entityTodos: Record<string, Todo>, joinRowTodos: Record<string, JoinRowTodo>): void;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=RunPlugin.d.ts.map
|
package/build/RunPlugin.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RunPlugin.d.ts","sourceRoot":"","sources":["../src/RunPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,aAAa,EAQb,WAAW,EAMX,MAAM,EAMN,IAAI,EACL,MAAM,YAAY,CAAC;AAOpB,qBAAa,SAAU,SAAQ,MAAM;;aAGP,EAAE,EAAE,aAAa;gBAAjB,EAAE,EAAE,aAAa;IAI7C,kBAAkB;IAIlB,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC;CAyMxF"}
|
package/build/context.d.ts
DELETED
package/build/context.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,uEAAuE;AACvE,MAAM,MAAM,OAAO,GAAG;IAAE,EAAE,EAAE,aAAa,CAAA;CAAE,CAAC"}
|
package/build/context.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":""}
|
package/build/index.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { MatchedEntity } from "./toMatchEntity";
|
|
2
|
-
export { Context } from "./context";
|
|
3
|
-
export { ContextFn, makeRun, makeRunEach, newContext, run, runEach } from "./run";
|
|
4
|
-
export { RunPlugin } from "./RunPlugin";
|
|
5
|
-
export { seed, SeedConfig } from "./seed";
|
|
6
|
-
export { toMatchEntity } from "./toMatchEntity";
|
|
7
|
-
export interface CustomMatcherResult {
|
|
8
|
-
pass: boolean;
|
|
9
|
-
message: () => string;
|
|
10
|
-
}
|
|
11
|
-
declare global {
|
|
12
|
-
namespace jest {
|
|
13
|
-
interface Matchers<R extends void | Promise<void>, T = {}> {
|
|
14
|
-
toMatchEntity(expected: MatchedEntity<T>): CustomMatcherResult;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
declare module "expect" {
|
|
19
|
-
interface Matchers<R extends void | Promise<void>, T = unknown> {
|
|
20
|
-
toMatchEntity(expected: MatchedEntity<T>): CustomMatcherResult;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
declare module "bun:test" {
|
|
24
|
-
interface Matchers<T = unknown> {
|
|
25
|
-
toMatchEntity(expected: MatchedEntity<T>): CustomMatcherResult;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* A custom equality tester for Jest, i.e. install it like:
|
|
30
|
-
*
|
|
31
|
-
* ```
|
|
32
|
-
* import { expect } from "@jest/globals";
|
|
33
|
-
* expect.addEqualityTesters([areEntitiesEqual]);
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* This is necessary because Jest's `expect` uses deep equality for instances
|
|
37
|
-
* of classes, but the `__data` key marked as non-enumerable, and all properties
|
|
38
|
-
* made lazy and defined as getters on the prototype, there are no keys on the
|
|
39
|
-
* individual objects left for Jest to see & realize "these are different".
|
|
40
|
-
*/
|
|
41
|
-
export declare function areEntitiesEqual(a: unknown, b: unknown): boolean | undefined;
|
|
42
|
-
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,IAAI,CAAC;QACb,UAAU,QAAQ,CAAC,CAAC,SAAS,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;YACvD,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC;SAChE;KACF;CACF;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,QAAQ,CAAC,CAAC,SAAS,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO;QAC5D,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC;KAChE;CACF;AAGD,OAAO,QAAQ,UAAU,CAAC;IACxB,UAAU,QAAQ,CAAC,CAAC,GAAG,OAAO;QAC5B,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC;KAChE;CACF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,uBAUtD"}
|
package/build/run.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Context } from "./context";
|
|
2
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
3
|
-
export type ContextFn<C> = (ctx: C) => MaybePromise<C>;
|
|
4
|
-
/** Runs the `fn` in a dedicated / non-test Unit of Work . */
|
|
5
|
-
export declare function run<C extends Context, T>(ctx: C, fn: (ctx: C) => MaybePromise<T>, contextFn?: ContextFn<C>): Promise<T>;
|
|
6
|
-
/** Creates a `run` with a custom `newContext` method. */
|
|
7
|
-
export declare function makeRun<C extends Context>(contextFn: ContextFn<C>): <T>(ctx: C, fn: (ctx: C) => MaybePromise<T>) => Promise<T>;
|
|
8
|
-
/** Runs the `fn` in a dedicated / non-test Unit of Work for each value in `values */
|
|
9
|
-
export declare function runEach<C extends Context, T, U>(ctx: C, valuesFn: () => U[], fn: (ctx: C, value: U) => MaybePromise<T>, contextFn?: ContextFn<C>): Promise<T[]>;
|
|
10
|
-
/** Creates a `runEach` with a custom `newContext` method. */
|
|
11
|
-
export declare function makeRunEach<C extends Context>(contextFn: ContextFn<C>): <T, U>(ctx: C, valuesFn: () => U[], fn: (ctx: C, value: U) => MaybePromise<T>) => Promise<T[]>;
|
|
12
|
-
/** A default `newContext` that assumes `ctx.em` is where the `EntityManager` lives. */
|
|
13
|
-
export declare function newContext<C extends Context>(ctx: C): C;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=run.d.ts.map
|
package/build/run.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC;AAMvD,6DAA6D;AAC7D,wBAAsB,GAAG,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAC5C,GAAG,EAAE,CAAC,EACN,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,EAC/B,SAAS,GAAE,SAAS,CAAC,CAAC,CAAc,GACnC,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED,yDAAyD;AACzD,wBAAgB,OAAO,CAAC,CAAC,SAAS,OAAO,EACvC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GACtB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAE5D;AAED,qFAAqF;AACrF,wBAAsB,OAAO,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACnD,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,MAAM,CAAC,EAAE,EACnB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,EACzC,SAAS,GAAE,SAAS,CAAC,CAAC,CAAc,GACnC,OAAO,CAAC,CAAC,EAAE,CAAC,CAad;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,CAAC,SAAS,OAAO,EAC3C,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GACtB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAEhG;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAMvD"}
|
package/build/seed.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAyB,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,WAAW,UAAU;IACzB,4DAA4D;IAC5D,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,aAAa,GAAG,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CA0BpH"}
|
package/build/toMatchEntity.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Entity, Property, ReadOnlyCollection, Reference } from "joist-core";
|
|
2
|
-
import { CustomMatcherResult } from "./index";
|
|
3
|
-
/**
|
|
4
|
-
* Provides convenient `toMatchObject`-style matching for Joist entities.
|
|
5
|
-
*
|
|
6
|
-
* The biggest differences over `toMatchObject` are:
|
|
7
|
-
*
|
|
8
|
-
* - We un-wrap relations like m2o/o2m to just the underlying object/arrays, to make
|
|
9
|
-
* asserting against the entities look like asserting against POJOs
|
|
10
|
-
* - We prune the expected/actual values to be as minimal as possible, to avoid Jest
|
|
11
|
-
* recursively crawling into connection pools or other misc non-useful things in the diffs
|
|
12
|
-
*/
|
|
13
|
-
export declare function toMatchEntity<T>(this: any, actual: unknown, expected: MatchedEntity<T>): CustomMatcherResult;
|
|
14
|
-
/**
|
|
15
|
-
* Given a Joist entity `T`, "flattens out" the Reference/Collections.
|
|
16
|
-
*
|
|
17
|
-
* I.e. so that you can `toMatchEntity({ otherEntity: { name: "foo" } })` even though
|
|
18
|
-
* `otherEntity` is technically a joist `Reference` or `Collection`.
|
|
19
|
-
*
|
|
20
|
-
* We allow `| null` so that `toMatchEntity` can work against optional fields
|
|
21
|
-
* that are returned from GraphQL object resolvers.
|
|
22
|
-
*/
|
|
23
|
-
export type MatchedEntity<T> = T extends ReadonlyArray<infer U> ? ReadonlyArray<MatchedEntity<U>> : undefined | T | {
|
|
24
|
-
[K in keyof T]?: T[K] extends Reference<any, infer U, any> ? MatchedEntity<U> | U : T[K] extends ReadOnlyCollection<any, infer U> ? Array<MatchedEntity<U> | U> : T[K] extends Property<any, infer V> ? V : T[K] extends Entity | null | undefined ? MatchedEntity<T[K]> | T[K] | null | undefined : T[K] extends ReadonlyArray<infer U | undefined> ? readonly (MatchedEntity<U> | U | undefined)[] : T[K] extends ReadonlyArray<infer U> | null ? readonly (MatchedEntity<U> | U | null)[] : // We recurse similar to a DeepPartial
|
|
25
|
-
MatchedEntity<T[K]> | null;
|
|
26
|
-
};
|
|
27
|
-
//# sourceMappingURL=toMatchEntity.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toMatchEntity.d.ts","sourceRoot":"","sources":["../src/toMatchEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EAQN,QAAQ,EACR,kBAAkB,EAClB,SAAS,EACV,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAM9C;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB,CA8B5G;AAWD;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IACzB,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAC5B,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAE3B,SAAS,GACT,CAAC,GACD;KACG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,GACtD,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,GACpB,CAAC,CAAC,CAAC,CAAC,SAAS,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAC3C,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAC3B,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GACjC,CAAC,GACD,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,SAAS,GACpC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,GAC7C,CAAC,CAAC,CAAC,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,GAC7C,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,EAAE,GAC7C,CAAC,CAAC,CAAC,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GACxC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAExC,AADA,sCAAsC;IACtC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;CACzC,CAAC"}
|