From e7b145efd8110b3f44cd51aa198476ba83408b63 Mon Sep 17 00:00:00 2001 From: Nathaniel Tucker Date: Tue, 25 Jun 2024 16:48:12 +0200 Subject: [PATCH] enhance: Update denormalize() args order --- .gitignore | 2 + packages/core/src/controller/Controller.ts | 4 +- .../src-4.0-types/schemas/Entity.d.ts | 2 +- .../src-4.0-types/schemas/EntitySchema.d.ts | 2 +- .../src/__tests__/validateRequired.test.ts | 6 +- packages/endpoint/src/interface.ts | 2 +- packages/endpoint/src/schema.d.ts | 10 +- packages/endpoint/src/schemaTypes.ts | 2 +- packages/endpoint/src/schemas/Array.ts | 2 +- packages/endpoint/src/schemas/Collection.ts | 4 +- packages/endpoint/src/schemas/Entity.ts | 2 +- packages/endpoint/src/schemas/EntitySchema.ts | 6 +- .../endpoint/src/schemas/ImmutableUtils.ts | 4 +- packages/endpoint/src/schemas/Invalidate.ts | 4 +- packages/endpoint/src/schemas/Object.ts | 6 +- packages/endpoint/src/schemas/Polymorphic.ts | 4 +- packages/endpoint/src/schemas/Query.ts | 4 +- packages/endpoint/src/schemas/Union.ts | 2 +- packages/endpoint/src/schemas/Values.ts | 2 +- .../src/schemas/__tests__/All.test.ts | 2 +- .../src/schemas/__tests__/Array.test.js | 40 +++--- .../src/schemas/__tests__/Collection.test.ts | 26 ++-- .../src/schemas/__tests__/Entity.test.ts | 86 ++++++------ .../schemas/__tests__/EntitySchema.test.ts | 86 ++++++------ .../src/schemas/__tests__/Invalidate.test.ts | 16 +-- .../src/schemas/__tests__/Object.test.js | 36 +++--- .../schemas/__tests__/Serializable.test.ts | 4 +- .../src/schemas/__tests__/Union.test.js | 18 +-- .../src/schemas/__tests__/Values.test.js | 10 +- .../src/schemas/__tests__/denormalize.ts | 4 +- packages/endpoint/typescript-tests/array.ts | 2 +- .../endpoint/typescript-tests/array_schema.ts | 2 +- .../endpoint/typescript-tests/denormalize.ts | 6 +- packages/endpoint/typescript-tests/entity.ts | 2 +- packages/normalizr/README.md | 10 +- packages/normalizr/docs/api.md | 4 +- packages/normalizr/src/__tests__/MemoCache.ts | 122 ++++++++---------- .../normalizr/src/__tests__/index.test.js | 68 +++++----- .../src/__tests__/normalizerMerge.test.tsx | 6 +- .../normalizr/src/denormalize/denormalize.ts | 4 +- packages/normalizr/src/denormalize/unvisit.ts | 14 +- packages/normalizr/src/interface.ts | 2 +- packages/normalizr/src/memo/MemoCache.ts | 6 +- packages/normalizr/src/schemas/Array.ts | 2 +- .../normalizr/src/schemas/ImmutableUtils.ts | 2 +- packages/normalizr/src/schemas/Object.ts | 2 +- 46 files changed, 324 insertions(+), 328 deletions(-) diff --git a/.gitignore b/.gitignore index f4bda0d998de..906d2c21ec77 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,5 @@ typings/ # build info **/tsconfig*.tsbuildinfo + +/codemods \ No newline at end of file diff --git a/packages/core/src/controller/Controller.ts b/packages/core/src/controller/Controller.ts index 3de12f7aa3be..fb31eea26e76 100644 --- a/packages/core/src/controller/Controller.ts +++ b/packages/core/src/controller/Controller.ts @@ -117,7 +117,7 @@ export default class Controller< if (endpoint.schema) { return action.meta.promise.then(input => - denormalize(input, endpoint.schema, {}, args), + denormalize(endpoint.schema, input, {}, args), ) as any; } return action.meta.promise as any; @@ -464,8 +464,8 @@ export default class Controller< // second argument is false if any entities are missing // eslint-disable-next-line prefer-const const { data, paths } = this.memo.denormalize( - input, schema, + input, state.entities, args, ) as { data: any; paths: EntityPath[] }; diff --git a/packages/endpoint/src-4.0-types/schemas/Entity.d.ts b/packages/endpoint/src-4.0-types/schemas/Entity.d.ts index dd982ecea9d8..add13efcba00 100644 --- a/packages/endpoint/src-4.0-types/schemas/Entity.d.ts +++ b/packages/endpoint/src-4.0-types/schemas/Entity.d.ts @@ -89,7 +89,7 @@ export default abstract class Entity extends Entity_base { this: T, input: any, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ) => AbstractInstanceType; } export {}; diff --git a/packages/endpoint/src-4.0-types/schemas/EntitySchema.d.ts b/packages/endpoint/src-4.0-types/schemas/EntitySchema.d.ts index f716fe397936..a9b1d2275316 100644 --- a/packages/endpoint/src-4.0-types/schemas/EntitySchema.d.ts +++ b/packages/endpoint/src-4.0-types/schemas/EntitySchema.d.ts @@ -236,7 +236,7 @@ export interface IEntityClass { this: T, input: any, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): AbstractInstanceType; /** All instance defaults set */ readonly defaults: any; diff --git a/packages/endpoint/src/__tests__/validateRequired.test.ts b/packages/endpoint/src/__tests__/validateRequired.test.ts index 10385906c8de..4d02e3ac545d 100644 --- a/packages/endpoint/src/__tests__/validateRequired.test.ts +++ b/packages/endpoint/src/__tests__/validateRequired.test.ts @@ -58,7 +58,7 @@ describe(`validateRequired`, () => { const schema = MyEntity; expect( - new SimpleMemoCache().denormalize('bob', schema, { + new SimpleMemoCache().denormalize(schema, 'bob', { MyEntity: { bob: { name: 'bob', secondthing: 'hi' } }, }), ).toMatchInlineSnapshot(` @@ -73,7 +73,7 @@ describe(`validateRequired`, () => { const schema = MyEntity; expect( - new SimpleMemoCache().denormalize('bob', schema, { + new SimpleMemoCache().denormalize(schema, 'bob', { MyEntity: { bob: { name: 'bob', @@ -93,7 +93,7 @@ describe(`validateRequired`, () => { it('should be invalid (suspend) with required fields missing', () => { const schema = MyEntity; - const data = new SimpleMemoCache().denormalize('bob', schema, { + const data = new SimpleMemoCache().denormalize(schema, 'bob', { MyEntity: { bob: { name: 'bob', diff --git a/packages/endpoint/src/interface.ts b/packages/endpoint/src/interface.ts index 232436aeaec0..654f538311c4 100644 --- a/packages/endpoint/src/interface.ts +++ b/packages/endpoint/src/interface.ts @@ -38,7 +38,7 @@ export interface SchemaSimple { denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): T; queryKey( args: Args, diff --git a/packages/endpoint/src/schema.d.ts b/packages/endpoint/src/schema.d.ts index c314511e90b0..dda9b25b123c 100644 --- a/packages/endpoint/src/schema.d.ts +++ b/packages/endpoint/src/schema.d.ts @@ -88,7 +88,7 @@ export class Array implements SchemaClass { denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): (S extends EntityMap ? T : Denormalize)[]; queryKey( @@ -145,7 +145,7 @@ export class All< denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): (S extends EntityMap ? T : Denormalize)[]; queryKey( @@ -189,7 +189,7 @@ export class Object = Record> denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): DenormalizeObject; queryKey( @@ -281,7 +281,7 @@ export interface UnionInstance< denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): AbstractInstanceType; queryKey( @@ -366,7 +366,7 @@ export class Values implements SchemaClass { denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): Record< string, Choices extends EntityMap ? T : Denormalize diff --git a/packages/endpoint/src/schemaTypes.ts b/packages/endpoint/src/schemaTypes.ts index 2436c1634283..ff0d7344f087 100644 --- a/packages/endpoint/src/schemaTypes.ts +++ b/packages/endpoint/src/schemaTypes.ts @@ -145,7 +145,7 @@ export interface CollectionInterface< denormalize( input: any, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): ReturnType; _denormalizeNullable(): ReturnType; diff --git a/packages/endpoint/src/schemas/Array.ts b/packages/endpoint/src/schemas/Array.ts index 8bc20de6ae49..08feae66d324 100644 --- a/packages/endpoint/src/schemas/Array.ts +++ b/packages/endpoint/src/schemas/Array.ts @@ -27,7 +27,7 @@ export default class ArraySchema extends PolymorphicSchema { denormalize( input: any, args: any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ) { return input.map ? input diff --git a/packages/endpoint/src/schemas/Collection.ts b/packages/endpoint/src/schemas/Collection.ts index 887db0e8afea..31d0f241859c 100644 --- a/packages/endpoint/src/schemas/Collection.ts +++ b/packages/endpoint/src/schemas/Collection.ts @@ -233,7 +233,7 @@ export default class CollectionSchema< denormalize( input: any, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): ReturnType { return this.schema.denormalize(input, args, unvisit) as any; } @@ -351,7 +351,7 @@ function denormalize( this: CollectionSchema, input: any, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): any { return Array.isArray(input) ? (this.schema.denormalize(input, args, unvisit) as any) diff --git a/packages/endpoint/src/schemas/Entity.ts b/packages/endpoint/src/schemas/Entity.ts index 4a12cace57f6..76a31b4b48a9 100644 --- a/packages/endpoint/src/schemas/Entity.ts +++ b/packages/endpoint/src/schemas/Entity.ts @@ -110,7 +110,7 @@ First three members: ${JSON.stringify(input.slice(0, 3), null, 2)}`; this: T, input: any, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ) => AbstractInstanceType; } diff --git a/packages/endpoint/src/schemas/EntitySchema.ts b/packages/endpoint/src/schemas/EntitySchema.ts index 228779ce2881..b957749203d9 100644 --- a/packages/endpoint/src/schemas/EntitySchema.ts +++ b/packages/endpoint/src/schemas/EntitySchema.ts @@ -348,7 +348,7 @@ export default function EntitySchema( this: T, input: any, args: any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): AbstractInstanceType { if (typeof input === 'symbol') { return input as any; @@ -357,7 +357,7 @@ export default function EntitySchema( // note: iteration order must be stable for (const key of Object.keys(this.schema)) { const schema = this.schema[key]; - const value = unvisit(input[key], schema); + const value = unvisit(schema, input[key]); if (typeof value === 'symbol') { // if default is not 'falsy', then this is required, so propagate INVALID symbol @@ -668,7 +668,7 @@ export interface IEntityClass { this: T, input: any, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): AbstractInstanceType; /** All instance defaults set */ readonly defaults: any; diff --git a/packages/endpoint/src/schemas/ImmutableUtils.ts b/packages/endpoint/src/schemas/ImmutableUtils.ts index 038aa4b4b152..c3f93e721e7e 100644 --- a/packages/endpoint/src/schemas/ImmutableUtils.ts +++ b/packages/endpoint/src/schemas/ImmutableUtils.ts @@ -35,7 +35,7 @@ export function isImmutable(object: {}): object is { export function denormalizeImmutable( schema: any, input: any, - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): any { let deleted; const value = Object.keys(schema).reduce((object, key) => { @@ -43,7 +43,7 @@ export function denormalizeImmutable( // we're accessing them using string keys. const stringKey = `${key}`; - const item = unvisit(object.get(stringKey), schema[stringKey]); + const item = unvisit(schema[stringKey], object.get(stringKey)); if (typeof item === 'symbol') { deleted = item; } diff --git a/packages/endpoint/src/schemas/Invalidate.ts b/packages/endpoint/src/schemas/Invalidate.ts index ad8166b51634..6ea4270f59e3 100644 --- a/packages/endpoint/src/schemas/Invalidate.ts +++ b/packages/endpoint/src/schemas/Invalidate.ts @@ -116,9 +116,9 @@ export default class Invalidate< denormalize( id: string, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): AbstractInstanceType { - return unvisit(id, this._entity) as any; + return unvisit(this._entity, id) as any; } /* istanbul ignore next */ diff --git a/packages/endpoint/src/schemas/Object.ts b/packages/endpoint/src/schemas/Object.ts index 2fc7de556281..62b682c6656f 100644 --- a/packages/endpoint/src/schemas/Object.ts +++ b/packages/endpoint/src/schemas/Object.ts @@ -29,7 +29,7 @@ export function denormalize( schema: any, input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): any { if (isImmutable(input)) { return denormalizeImmutable(schema, input, unvisit); @@ -38,7 +38,7 @@ export function denormalize( const object: Record = { ...input }; for (const key of Object.keys(schema)) { - const item = unvisit(object[key], schema[key]); + const item = unvisit(schema[key], object[key]); if (object[key] !== undefined) { object[key] = item; } @@ -103,7 +103,7 @@ export default class ObjectSchema { denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): any { return denormalize(this.schema, input, args, unvisit); } diff --git a/packages/endpoint/src/schemas/Polymorphic.ts b/packages/endpoint/src/schemas/Polymorphic.ts index abbda26e3f5e..0642f8add909 100644 --- a/packages/endpoint/src/schemas/Polymorphic.ts +++ b/packages/endpoint/src/schemas/Polymorphic.ts @@ -91,7 +91,7 @@ Value: ${JSON.stringify(value, undefined, 2)}`, // construct the correct Entity instance if (typeof value === 'object' && value !== null) { const schema = this.inferSchema(value, undefined, undefined); - if (schema) return unvisit(value, schema); + if (schema) return unvisit(schema, value); } /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production' && value) { @@ -107,6 +107,6 @@ Value: ${JSON.stringify(value, undefined, 2)}.`, : isImmutable(value) ? value.get('id') : value.id; const schema = this.isSingleSchema ? this.schema : this.schema[schemaKey]; - return unvisit(id || value, schema); + return unvisit(schema, id || value); } } diff --git a/packages/endpoint/src/schemas/Query.ts b/packages/endpoint/src/schemas/Query.ts index 3401bbe2b7fc..3e5891d64559 100644 --- a/packages/endpoint/src/schemas/Query.ts +++ b/packages/endpoint/src/schemas/Query.ts @@ -34,7 +34,7 @@ export default class Query< } denormalize(input: {}, args: any, unvisit: any): ReturnType

{ - const value = unvisit(input, this.schema); + const value = unvisit(this.schema, input); return typeof value === 'symbol' ? value : this.process(value, ...args); } @@ -55,7 +55,7 @@ export default class Query< declare _denormalizeNullable: ( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ) => ReturnType

| undefined; declare _normalizeNullable: () => NormalizeNullable; diff --git a/packages/endpoint/src/schemas/Union.ts b/packages/endpoint/src/schemas/Union.ts index f1b206680b7e..5faa16edf54d 100644 --- a/packages/endpoint/src/schemas/Union.ts +++ b/packages/endpoint/src/schemas/Union.ts @@ -31,7 +31,7 @@ export default class UnionSchema extends PolymorphicSchema { denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ) { return this.denormalizeValue(input, unvisit); } diff --git a/packages/endpoint/src/schemas/Values.ts b/packages/endpoint/src/schemas/Values.ts index 0f551b614024..20168b3ed010 100644 --- a/packages/endpoint/src/schemas/Values.ts +++ b/packages/endpoint/src/schemas/Values.ts @@ -30,7 +30,7 @@ export default class ValuesSchema extends PolymorphicSchema { denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): any { return Object.keys(input).reduce((output, key) => { const entityOrId = (input as any)[key]; diff --git a/packages/endpoint/src/schemas/__tests__/All.test.ts b/packages/endpoint/src/schemas/__tests__/All.test.ts index 3c140b3b4d01..a845da7b8acd 100644 --- a/packages/endpoint/src/schemas/__tests__/All.test.ts +++ b/packages/endpoint/src/schemas/__tests__/All.test.ts @@ -293,7 +293,7 @@ describe.each([ }, }, }; - expect(denormalize('123', Taco, createInput(entities))).toMatchSnapshot(); + expect(denormalize(Taco, '123', createInput(entities))).toMatchSnapshot(); }); test('denormalizes multiple entities', () => { diff --git a/packages/endpoint/src/schemas/__tests__/Array.test.js b/packages/endpoint/src/schemas/__tests__/Array.test.js index c2881e639857..275685929e4e 100644 --- a/packages/endpoint/src/schemas/__tests__/Array.test.js +++ b/packages/endpoint/src/schemas/__tests__/Array.test.js @@ -155,19 +155,19 @@ describe.each([ }; const sch = new schema.Object({ user: User, tacos: [] }); expect( - denormalize({ user: '1' }, sch, createInput(entities)), + denormalize(sch, { user: '1' }, createInput(entities)), ).toMatchSnapshot(); expect( - denormalize(createInput({ user: '1' }), sch, createInput(entities)), + denormalize(sch, createInput({ user: '1' }), createInput(entities)), ).toMatchSnapshot(); expect( - denormalize({ user: '1', tacos: [] }, sch, createInput(entities)), + denormalize(sch, { user: '1', tacos: [] }, createInput(entities)), ).toMatchSnapshot(); expect( denormalize( - createInput({ user: '1', tacos: [] }), sch, + createInput({ user: '1', tacos: [] }), createInput(entities), ), ).toMatchSnapshot(); @@ -186,7 +186,7 @@ describe.each([ }, }; expect( - denormalize(['1', '2'], createSchema(Cat), createInput(entities)), + denormalize(createSchema(Cat), ['1', '2'], createInput(entities)), ).toMatchSnapshot(); }); @@ -200,8 +200,8 @@ describe.each([ }; expect( denormalize( - { a: '1', b: '2' }, createSchema(Cat), + { a: '1', b: '2' }, createInput(entities), ), ).toMatchSnapshot(); @@ -219,19 +219,19 @@ describe.each([ tacos: createSchema({ next: '' }), }); expect( - denormalize({ user: '1' }, sch, createInput(entities)), + denormalize(sch, { user: '1' }, createInput(entities)), ).toMatchSnapshot(); expect( - denormalize(createInput({ user: '1' }), sch, createInput(entities)), + denormalize(sch, createInput({ user: '1' }), createInput(entities)), ).toMatchSnapshot(); expect( - denormalize({ user: '1', tacos: [] }, sch, createInput(entities)), + denormalize(sch, { user: '1', tacos: [] }, createInput(entities)), ).toMatchSnapshot(); expect( denormalize( - createInput({ user: '1', tacos: [] }), sch, + createInput({ user: '1', tacos: [] }), createInput(entities), ), ).toMatchSnapshot(); @@ -247,7 +247,7 @@ describe.each([ }, }; expect( - denormalize({ results: ['1', '2'] }, catSchema, createInput(entities)), + denormalize(catSchema, { results: ['1', '2'] }, createInput(entities)), ).toMatchSnapshot(); }); @@ -264,14 +264,14 @@ describe.each([ }, }; let value = denormalize( - { results: ['1', '2'] }, catSchema, + { results: ['1', '2'] }, createInput(entities), ); expect(value).toMatchSnapshot(); value = denormalize( - createInput({ results: ['1', '2'] }), catSchema, + createInput({ results: ['1', '2'] }), createInput(entities), ); expect(value).toMatchSnapshot(); @@ -290,14 +290,14 @@ describe.each([ }, }; let value = denormalize( - createInput({ results: ['1', undefined, '2', null] }), catSchema, + createInput({ results: ['1', undefined, '2', null] }), createInput(entities), ); expect(value).toMatchSnapshot(); value = denormalize( - { results: ['1', '2'] }, catSchema, + { results: ['1', '2'] }, createInput(entities), ); expect(value).toMatchSnapshot(); @@ -313,8 +313,8 @@ describe.each([ }, }; let value = denormalize( - createInput({ results: undefined }), catSchema, + createInput({ results: undefined }), createInput(entities), ); expect(value).toMatchSnapshot(); @@ -329,8 +329,8 @@ describe.each([ }, }; let value = denormalize( - createInput([{ data: '1' }, { data: '2' }, { data: '3' }]), createSchema(new schema.Object({ data: Cat })), + createInput([{ data: '1' }, { data: '2' }, { data: '3' }]), createInput(entities), ); expect(value).toMatchSnapshot(); @@ -350,7 +350,7 @@ describe.each([ }, }; - expect(denormalize('123', Taco, createInput(entities))).toMatchSnapshot(); + expect(denormalize(Taco, '123', createInput(entities))).toMatchSnapshot(); }); test('denormalizes multiple entities', () => { @@ -396,8 +396,8 @@ describe.each([ ]; const value = denormalize( - createInput(input), listSchema, + createInput(input), createInput(entities), ); expect(value).toMatchSnapshot(); @@ -415,7 +415,7 @@ describe.each([ ]; const output = normalize(input, catList); expect(output).toMatchSnapshot(); - expect(denormalize(output.result, catList, output.entities)).toEqual( + expect(denormalize(catList, output.result, output.entities)).toEqual( input, ); }); diff --git a/packages/endpoint/src/schemas/__tests__/Collection.test.ts b/packages/endpoint/src/schemas/__tests__/Collection.test.ts index 036a71adb57b..afaaa30a49bd 100644 --- a/packages/endpoint/src/schemas/__tests__/Collection.test.ts +++ b/packages/endpoint/src/schemas/__tests__/Collection.test.ts @@ -249,8 +249,8 @@ describe(`${schema.Collection.name} normalization`, () => { expect( ( denormalize( - JSON.stringify({ userId: '1' }), sch, + JSON.stringify({ userId: '1' }), state.entities, ) as any )?.length, @@ -268,8 +268,8 @@ describe(`${schema.Collection.name} normalization`, () => { }; function getResponse(...args: any) { return denormalize( - sch.pk(undefined, undefined, '', args), sch, + sch.pk(undefined, undefined, '', args), testState.entities, ) as any; } @@ -408,13 +408,13 @@ describe(`${schema.Collection.name} denormalization`, () => { test('denormalizes nested collections', () => { expect( - denormalize(normalizeNested.result, User, normalizeNested.entities), + denormalize(User, normalizeNested.result, normalizeNested.entities), ).toMatchSnapshot(); }); test('denormalizes top level collections', () => { expect( - denormalize('{"userId":"1"}', userTodos, normalizeNested.entities), + denormalize(userTodos, '{"userId":"1"}', normalizeNested.entities), ).toMatchSnapshot(); }); @@ -422,15 +422,15 @@ describe(`${schema.Collection.name} denormalization`, () => { const memo = new SimpleMemoCache(); test('denormalizes nested and top level share referential equality', () => { const todos = memo.denormalize( - '{"userId":"1"}', userTodos, + '{"userId":"1"}', normalizeNested.entities, [{ userId: '1' }], ); const user = memo.denormalize( - normalizeNested.result, User, + normalizeNested.result, normalizeNested.entities, ); expect(user).toBeDefined(); @@ -449,15 +449,15 @@ describe(`${schema.Collection.name} denormalization`, () => { normalizeNested.entityMeta, ); const todos = memo.denormalize( - '{"userId":"1"}', userTodos, + '{"userId":"1"}', pushedState.entities, [{ userId: '1' }], ); const user = memo.denormalize( - normalizeNested.result, User, + normalizeNested.result, pushedState.entities, [{ id: '1' }], ); @@ -478,14 +478,14 @@ describe(`${schema.Collection.name} denormalization`, () => { normalizeNested.entityMeta, ); const todos = memo.denormalize( - '{"userId":"1"}', userTodos, + '{"userId":"1"}', unshiftState.entities, [{ userId: '1' }], ); const user = memo.denormalize( - normalizeNested.result, User, + normalizeNested.result, unshiftState.entities, [{ id: '1' }], ); @@ -499,8 +499,8 @@ describe(`${schema.Collection.name} denormalization`, () => { test('denormalizes unshift', () => { const todos = memo.denormalize( - [{ id: '2', title: 'from the start' }], userTodos.unshift, + [{ id: '2', title: 'from the start' }], {}, [{ id: '1' }], ); @@ -522,8 +522,8 @@ describe(`${schema.Collection.name} denormalization`, () => { test('denormalizes unshift (single item)', () => { const todos = memo.denormalize( - { id: '2', title: 'from the start' }, userTodos.unshift, + { id: '2', title: 'from the start' }, {}, [{ id: '1' }], ); @@ -553,7 +553,7 @@ describe(`${schema.Collection.name} denormalization`, () => { ); expect(queryKey).toBeDefined(); // now ensure our queryKey is usable - const results = denormalize(queryKey, userTodos, normalizeNested.entities); + const results = denormalize(userTodos, queryKey, normalizeNested.entities); expect(results).toBeDefined(); expect(results).toMatchInlineSnapshot(` [ diff --git a/packages/endpoint/src/schemas/__tests__/Entity.test.ts b/packages/endpoint/src/schemas/__tests__/Entity.test.ts index 850751da653b..f938c3ee70fe 100644 --- a/packages/endpoint/src/schemas/__tests__/Entity.test.ts +++ b/packages/endpoint/src/schemas/__tests__/Entity.test.ts @@ -527,8 +527,8 @@ describe(`${Entity.name} normalization`, () => { ProcessTaco, ); const final = new SimpleMemoCache().denormalize( - result, ProcessTaco, + result, entities, ); expect(final).not.toEqual(expect.any(Symbol)); @@ -567,8 +567,8 @@ describe(`${Entity.name} normalization`, () => { ParentEntity, ); const final = new SimpleMemoCache().denormalize( - result, ParentEntity, + result, entities, ); expect(final).not.toEqual(expect.any(Symbol)); @@ -599,8 +599,8 @@ describe(`${Entity.name} normalization`, () => { EntriesEntity, ); const final = new SimpleMemoCache().denormalize( - result, EntriesEntity, + result, entities, ); expect(final).not.toEqual(expect.any(Symbol)); @@ -618,8 +618,8 @@ describe(`${Entity.name} denormalization`, () => { '1': { id: '1', name: 'foo' }, }, }; - expect(denormalize('1', Tacos, entities)).toMatchSnapshot(); - expect(denormalize('1', Tacos, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Tacos, '1', entities)).toMatchSnapshot(); + expect(denormalize(Tacos, '1', fromJS(entities))).toMatchSnapshot(); }); class Food extends IDEntity {} @@ -640,13 +640,13 @@ describe(`${Entity.name} denormalization`, () => { }, }; - const de1 = denormalize('1', Menu, entities); + const de1 = denormalize(Menu, '1', entities); expect(de1).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toEqual(de1); + expect(denormalize(Menu, '1', fromJS(entities))).toEqual(de1); - const de2 = denormalize('2', Menu, entities); + const de2 = denormalize(Menu, '2', entities); expect(de2).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toEqual(de2); + expect(denormalize(Menu, '2', fromJS(entities))).toEqual(de2); }); test('denormalizes deep entities while maintaining referential equality', () => { @@ -661,8 +661,8 @@ describe(`${Entity.name} denormalization`, () => { }; const memo = new SimpleMemoCache(); - const first = memo.denormalize('1', Menu, entities); - const second = memo.denormalize('1', Menu, entities); + const first = memo.denormalize(Menu, '1', entities); + const second = memo.denormalize(Menu, '1', entities); expect(first).not.toEqual(expect.any(Symbol)); if (typeof first === 'symbol') return; expect(second).not.toEqual(expect.any(Symbol)); @@ -682,8 +682,8 @@ describe(`${Entity.name} denormalization`, () => { '1': { id: '1' }, }, }; - expect(denormalize('1', MyTacos, entities)).toEqual(expect.any(Symbol)); - expect(denormalize('1', MyTacos, fromJS(entities))).toEqual( + expect(denormalize(MyTacos, '1', entities)).toEqual(expect.any(Symbol)); + expect(denormalize(MyTacos, '1', fromJS(entities))).toEqual( expect.any(Symbol), ); }); @@ -698,11 +698,11 @@ describe(`${Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('2', Menu, entities)).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '2', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot(); }); it('should handle optional schema entries Entity', () => { @@ -721,7 +721,7 @@ describe(`${Entity.name} denormalization`, () => { const schema = MyEntity; expect( - denormalize('bob', schema, { + denormalize(schema, 'bob', { MyEntity: { bob: { name: 'bob', secondthing: 'hi' } }, }), ).toMatchInlineSnapshot(` @@ -749,7 +749,7 @@ describe(`${Entity.name} denormalization`, () => { const schema = MyEntity; expect( - denormalize('bob', schema, { + denormalize(schema, 'bob', { MyEntity: { bob: { name: 'bob', secondthing: 'hi', blarb: null } }, }), ).toMatchInlineSnapshot(` @@ -773,11 +773,11 @@ describe(`${Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('2', Menu, entities)).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '2', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot(); }); test('denormalizes deep entities with records', () => { @@ -797,11 +797,11 @@ describe(`${Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('2', Menu, entities)).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '2', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot(); }); test('can denormalize already partially denormalized data', () => { @@ -815,8 +815,8 @@ describe(`${Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); }); class User extends IDEntity { @@ -864,11 +864,11 @@ describe(`${Entity.name} denormalization`, () => { }, }; - expect(denormalize('123', Report, entities)).toMatchSnapshot(); - expect(denormalize('123', Report, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Report, '123', entities)).toMatchSnapshot(); + expect(denormalize(Report, '123', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('456', User, entities)).toMatchSnapshot(); - expect(denormalize('456', User, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(User, '456', entities)).toMatchSnapshot(); + expect(denormalize(User, '456', fromJS(entities))).toMatchSnapshot(); }); test('denormalizes recursive entities with referential equality', () => { @@ -903,7 +903,7 @@ describe(`${Entity.name} denormalization`, () => { }; const memo = new SimpleMemoCache(); - const denormalizedReport = memo.denormalize('123', Report, entities); + const denormalizedReport = memo.denormalize(Report, '123', entities); expect(denormalizedReport).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport === 'symbol') return; @@ -916,7 +916,7 @@ describe(`${Entity.name} denormalization`, () => { denormalizedReport.draftedBy, ); - const denormalizedReport2 = memo.denormalize('123', Report, entities); + const denormalizedReport2 = memo.denormalize(Report, '123', entities); expect(denormalizedReport2).toStrictEqual(denormalizedReport); expect(denormalizedReport2).toBe(denormalizedReport); @@ -962,7 +962,7 @@ describe(`${Entity.name} denormalization`, () => { comment: Comment, }); - const denormalizedReport = memo.denormalize(input, sch, entities); + const denormalizedReport = memo.denormalize(sch, input, entities); expect(denormalizedReport).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport === 'symbol') return; @@ -975,7 +975,7 @@ describe(`${Entity.name} denormalization`, () => { denormalizedReport.comment.author, ); - const denormalizedReport2 = memo.denormalize(input, sch, entities); + const denormalizedReport2 = memo.denormalize(sch, input, entities); expect(denormalizedReport2).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport2 === 'symbol') return; @@ -994,7 +994,7 @@ describe(`${Entity.name} denormalization`, () => { }, }; - const denormalizedReport3 = memo.denormalize(input, sch, nextEntities); + const denormalizedReport3 = memo.denormalize(sch, input, nextEntities); expect(denormalizedReport3).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport3 === 'symbol') return; @@ -1006,7 +1006,7 @@ describe(`${Entity.name} denormalization`, () => { describe('optional entities', () => { it('should be marked as found even when optional is not there', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: { id: 'abc', @@ -1031,7 +1031,7 @@ describe(`${Entity.name} denormalization`, () => { }); it('should be marked as found when nested entity is missing', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: WithOptional.fromJS({ id: 'abc', @@ -1057,7 +1057,7 @@ describe(`${Entity.name} denormalization`, () => { }); it('should be marked as deleted when required entity is deleted symbol', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: { id: 'abc', @@ -1074,7 +1074,7 @@ describe(`${Entity.name} denormalization`, () => { }); it('should be non-required deleted members should not result in deleted indicator', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: WithOptional.fromJS({ id: 'abc', @@ -1103,8 +1103,8 @@ describe(`${Entity.name} denormalization`, () => { it('should be deleted when both are true in different parts of schema', () => { const denormalized = denormalize( - { data: 'abc' }, new schema.Object({ data: WithOptional, other: ArticleEntity }), + { data: 'abc' }, { [WithOptional.key]: { abc: WithOptional.fromJS({ diff --git a/packages/endpoint/src/schemas/__tests__/EntitySchema.test.ts b/packages/endpoint/src/schemas/__tests__/EntitySchema.test.ts index 1073a27c6c73..c8d15954652e 100644 --- a/packages/endpoint/src/schemas/__tests__/EntitySchema.test.ts +++ b/packages/endpoint/src/schemas/__tests__/EntitySchema.test.ts @@ -677,7 +677,7 @@ describe(`${schema.Entity.name} normalization`, () => { { id: '1', name: 'foo' }, ProcessTaco, ); - const final = denormalize(result, ProcessTaco, entities); + const final = denormalize(ProcessTaco, result, entities); expect(final).not.toEqual(expect.any(Symbol)); if (typeof final === 'symbol') return; expect(final?.slug).toEqual('thing-1'); @@ -717,7 +717,7 @@ describe(`${schema.Entity.name} normalization`, () => { }, ParentEntity, ); - const final = denormalize(result, ParentEntity, entities); + const final = denormalize(ParentEntity, result, entities); expect(final).not.toEqual(expect.any(Symbol)); if (typeof final === 'symbol') return; expect(final?.child?.parentId).toEqual('1'); @@ -767,7 +767,7 @@ describe(`${schema.Entity.name} normalization`, () => { { message: { id: '123', data: { attachment: { id: '456' } } } }, EntriesEntity, ); - const final = denormalize(result, EntriesEntity, entities); + const final = denormalize(EntriesEntity, result, entities); expect(final).not.toEqual(expect.any(Symbol)); if (typeof final === 'symbol') return; expect(final?.type).toEqual('message'); @@ -785,8 +785,8 @@ describe(`${schema.Entity.name} denormalization`, () => { '1': { id: '1', name: 'foo' }, }, }; - expect(denormalize('1', Tacos, entities)).toMatchSnapshot(); - expect(denormalize('1', Tacos, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Tacos, '1', entities)).toMatchSnapshot(); + expect(denormalize(Tacos, '1', fromJS(entities))).toMatchSnapshot(); }); class Food extends schema.Entity( @@ -811,13 +811,13 @@ describe(`${schema.Entity.name} denormalization`, () => { }, }; - const de1 = denormalize('1', Menu, entities); + const de1 = denormalize(Menu, '1', entities); expect(de1).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toEqual(de1); + expect(denormalize(Menu, '1', fromJS(entities))).toEqual(de1); - const de2 = denormalize('2', Menu, entities); + const de2 = denormalize(Menu, '2', entities); expect(de2).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toEqual(de2); + expect(denormalize(Menu, '2', fromJS(entities))).toEqual(de2); }); test('denormalizes deep entities while maintaining referential equality', () => { @@ -832,8 +832,8 @@ describe(`${schema.Entity.name} denormalization`, () => { }; const memo = new SimpleMemoCache(); - const first = memo.denormalize('1', Menu, entities); - const second = memo.denormalize('1', Menu, entities); + const first = memo.denormalize(Menu, '1', entities); + const second = memo.denormalize(Menu, '1', entities); expect(first).not.toEqual(expect.any(Symbol)); if (typeof first === 'symbol') return; expect(second).not.toEqual(expect.any(Symbol)); @@ -853,8 +853,8 @@ describe(`${schema.Entity.name} denormalization`, () => { '1': { id: '1' }, }, }; - expect(denormalize('1', MyTacos, entities)).toEqual(expect.any(Symbol)); - expect(denormalize('1', MyTacos, fromJS(entities))).toEqual( + expect(denormalize(MyTacos, '1', entities)).toEqual(expect.any(Symbol)); + expect(denormalize(MyTacos, '1', fromJS(entities))).toEqual( expect.any(Symbol), ); }); @@ -869,11 +869,11 @@ describe(`${schema.Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('2', Menu, entities)).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '2', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot(); }); it('should handle optional schema entries Entity', () => { @@ -888,7 +888,7 @@ describe(`${schema.Entity.name} denormalization`, () => { }) {} expect( - denormalize('bob', MyEntity, { + denormalize(MyEntity, 'bob', { MyEntity: { bob: { name: 'bob', secondthing: 'hi' } }, }), ).toMatchInlineSnapshot(` @@ -912,7 +912,7 @@ describe(`${schema.Entity.name} denormalization`, () => { }) {} expect( - denormalize('bob', MyEntity, { + denormalize(MyEntity, 'bob', { MyEntity: { bob: { name: 'bob', secondthing: 'hi', blarb: null } }, }), ).toMatchInlineSnapshot(` @@ -936,11 +936,11 @@ describe(`${schema.Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('2', Menu, entities)).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '2', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot(); }); test('denormalizes deep entities with records', () => { @@ -960,11 +960,11 @@ describe(`${schema.Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('2', Menu, entities)).toMatchSnapshot(); - expect(denormalize('2', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '2', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot(); }); test('can denormalize already partially denormalized data', () => { @@ -978,8 +978,8 @@ describe(`${schema.Entity.name} denormalization`, () => { }, }; - expect(denormalize('1', Menu, entities)).toMatchSnapshot(); - expect(denormalize('1', Menu, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Menu, '1', entities)).toMatchSnapshot(); + expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot(); }); describe('nesting', () => { @@ -1032,11 +1032,11 @@ describe(`${schema.Entity.name} denormalization`, () => { }, }; - expect(denormalize('123', Report, entities)).toMatchSnapshot(); - expect(denormalize('123', Report, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(Report, '123', entities)).toMatchSnapshot(); + expect(denormalize(Report, '123', fromJS(entities))).toMatchSnapshot(); - expect(denormalize('456', User, entities)).toMatchSnapshot(); - expect(denormalize('456', User, fromJS(entities))).toMatchSnapshot(); + expect(denormalize(User, '456', entities)).toMatchSnapshot(); + expect(denormalize(User, '456', fromJS(entities))).toMatchSnapshot(); }); test('denormalizes recursive entities with referential equality', () => { @@ -1071,7 +1071,7 @@ describe(`${schema.Entity.name} denormalization`, () => { }; const memo = new SimpleMemoCache(); - const denormalizedReport = memo.denormalize('123', Report, entities); + const denormalizedReport = memo.denormalize(Report, '123', entities); expect(denormalizedReport).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport === 'symbol') return; @@ -1084,7 +1084,7 @@ describe(`${schema.Entity.name} denormalization`, () => { denormalizedReport.draftedBy, ); - const denormalizedReport2 = memo.denormalize('123', Report, entities); + const denormalizedReport2 = memo.denormalize(Report, '123', entities); expect(denormalizedReport2).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport2 === 'symbol') return; @@ -1132,7 +1132,7 @@ describe(`${schema.Entity.name} denormalization`, () => { comment: Comment, }); - const denormalizedReport = memo.denormalize(input, sch, entities); + const denormalizedReport = memo.denormalize(sch, input, entities); expect(denormalizedReport).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport === 'symbol') return; @@ -1145,7 +1145,7 @@ describe(`${schema.Entity.name} denormalization`, () => { denormalizedReport.comment.author, ); - const denormalizedReport2 = memo.denormalize(input, sch, entities); + const denormalizedReport2 = memo.denormalize(sch, input, entities); expect(denormalizedReport2).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport2 === 'symbol') return; @@ -1164,7 +1164,7 @@ describe(`${schema.Entity.name} denormalization`, () => { }, }; - const denormalizedReport3 = memo.denormalize(input, sch, nextEntities); + const denormalizedReport3 = memo.denormalize(sch, input, nextEntities); expect(denormalizedReport3).not.toEqual(expect.any(Symbol)); if (typeof denormalizedReport3 === 'symbol') return; @@ -1176,7 +1176,7 @@ describe(`${schema.Entity.name} denormalization`, () => { describe('optional entities', () => { it('should be marked as found even when optional is not there', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: { id: 'abc', @@ -1201,7 +1201,7 @@ describe(`${schema.Entity.name} denormalization`, () => { }); it('should be marked as found when nested entity is missing', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: WithOptional.fromJS({ id: 'abc', @@ -1229,7 +1229,7 @@ describe(`${schema.Entity.name} denormalization`, () => { }); it('should be marked as deleted when required entity is deleted symbol', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: { id: 'abc', @@ -1246,7 +1246,7 @@ describe(`${schema.Entity.name} denormalization`, () => { }); it('should be non-required deleted members should not result in deleted indicator', () => { - const denormalized = denormalize('abc', WithOptional, { + const denormalized = denormalize(WithOptional, 'abc', { [WithOptional.key]: { abc: WithOptional.fromJS({ id: 'abc', @@ -1276,8 +1276,8 @@ describe(`${schema.Entity.name} denormalization`, () => { it('should be both deleted and not found when both are true in different parts of schema', () => { const denormalized = denormalize( - { data: 'abc' }, new schema.Object({ data: WithOptional, other: ArticleEntity }), + { data: 'abc' }, { [WithOptional.key]: { abc: WithOptional.fromJS({ diff --git a/packages/endpoint/src/schemas/__tests__/Invalidate.test.ts b/packages/endpoint/src/schemas/__tests__/Invalidate.test.ts index 8b1bf4cfbc63..16e001c00758 100644 --- a/packages/endpoint/src/schemas/__tests__/Invalidate.test.ts +++ b/packages/endpoint/src/schemas/__tests__/Invalidate.test.ts @@ -96,8 +96,8 @@ describe(`${schema.Invalidate.name} denormalization`, () => { test('denormalizes an object in the same manner as the Entity', () => { const user = new SimpleMemoCache().denormalize( - '1', new schema.Invalidate(User), + '1', entities, ); expect(user).not.toEqual(expect.any(Symbol)); @@ -129,8 +129,8 @@ describe(`${schema.Invalidate.name} denormalization`, () => { (_, createArray, createObject, denormalize) => { test('denormalizes deleted entities as symbol', () => { const user = denormalize( - '1', new schema.Invalidate(User), + '1', createInput({ User: { '1': INVALID }, }), @@ -139,8 +139,8 @@ describe(`${schema.Invalidate.name} denormalization`, () => { expect( denormalize( - createInput({ data: '1' }), createObject({ data: new schema.Invalidate(User) }), + createInput({ data: '1' }), createInput({ User: { '1': INVALID }, }), @@ -151,8 +151,8 @@ describe(`${schema.Invalidate.name} denormalization`, () => { test('denormalize removes deleted entries in array', () => { expect( denormalize( - createInput([{ data: '1' }]), createArray(createObject({ data: new schema.Invalidate(User) })), + createInput([{ data: '1' }]), createInput({ User: { '1': INVALID }, }), @@ -160,8 +160,8 @@ describe(`${schema.Invalidate.name} denormalization`, () => { ).toMatchSnapshot(); expect( denormalize( - createInput([{ data: '1' }]), createArray(createObject({ data: User })), + createInput([{ data: '1' }]), createInput({ User: { '1': INVALID }, }), @@ -172,24 +172,24 @@ describe(`${schema.Invalidate.name} denormalization`, () => { test('denormalize sets undefined entities that are not present', () => { expect( denormalize( - createInput([{ data: '1' }]), createArray(createObject({ data: new schema.Invalidate(User) })), + createInput([{ data: '1' }]), createInput([{}]), ), ).toMatchSnapshot(); expect( denormalize( - createInput([{ data: '1' }]), createArray(createObject({ data: User })), + createInput([{ data: '1' }]), createInput([{}]), ), ).toMatchSnapshot(); expect( denormalize( - createInput({ data: '1' }), createObject({ data: User }), + createInput({ data: '1' }), createInput({}), ), ).toMatchSnapshot(); diff --git a/packages/endpoint/src/schemas/__tests__/Object.test.js b/packages/endpoint/src/schemas/__tests__/Object.test.js index 8f9b499df532..1c2d4a0a4a51 100644 --- a/packages/endpoint/src/schemas/__tests__/Object.test.js +++ b/packages/endpoint/src/schemas/__tests__/Object.test.js @@ -97,12 +97,12 @@ describe(`${schema.Object.name} denormalization`, () => { 1: { id: '1', name: 'Nacho' }, }, }; - expect(denormalize({ user: '1' }, object, entities)).toMatchSnapshot(); + expect(denormalize(object, { user: '1' }, entities)).toMatchSnapshot(); expect( - denormalize({ user: '1' }, object, fromJS(entities)), + denormalize(object, { user: '1' }, fromJS(entities)), ).toMatchSnapshot(); expect( - denormalize(fromJS({ user: '1' }), object, fromJS(entities)), + denormalize(object, fromJS({ user: '1' }), fromJS(entities)), ).toMatchSnapshot(); }); @@ -117,12 +117,12 @@ describe(`${schema.Object.name} denormalization`, () => { 1: { id: '1', name: 'Nacho' }, }, }; - expect(denormalize({ user: '1' }, object, entities)).toMatchSnapshot(); + expect(denormalize(object, { user: '1' }, entities)).toMatchSnapshot(); expect( - denormalize({ user: '1' }, object, fromJS(entities)), + denormalize(object, { user: '1' }, fromJS(entities)), ).toMatchSnapshot(); expect( - denormalize(fromJS({ user: '1' }), object, fromJS(entities)), + denormalize(object, fromJS({ user: '1' }), fromJS(entities)), ).toMatchSnapshot(); }); @@ -138,11 +138,11 @@ describe(`${schema.Object.name} denormalization`, () => { 1: { id: '1', name: 'Nacho' }, }, }; - let value = denormalize({ item: null }, object, entities); + let value = denormalize(object, { item: null }, entities); expect(value).toMatchSnapshot(); - value = denormalize({ item: null }, object, fromJS(entities)); + value = denormalize(object, { item: null }, fromJS(entities)); expect(value).toMatchSnapshot(); - value = denormalize(fromJS({ item: null }), object, fromJS(entities)); + value = denormalize(object, fromJS({ item: null }), fromJS(entities)); expect(value).toMatchSnapshot(); }); @@ -155,44 +155,44 @@ describe(`${schema.Object.name} denormalization`, () => { }; expect( denormalize( - { user: '1' }, new schema.Object({ user: User, tacos: {} }), + { user: '1' }, entities, ), ).toMatchSnapshot(); expect( denormalize( - { user: '1' }, new schema.Object({ user: User, tacos: {} }), + { user: '1' }, fromJS(entities), ), ).toMatchSnapshot(); expect( denormalize( - fromJS({ user: '1' }), new schema.Object({ user: User, tacos: {} }), + fromJS({ user: '1' }), fromJS(entities), ), ).toMatchSnapshot(); expect( denormalize( - { user: '1', tacos: {} }, new schema.Object({ user: User, tacos: {} }), + { user: '1', tacos: {} }, entities, ), ).toMatchSnapshot(); expect( denormalize( - { user: '1', tacos: {} }, new schema.Object({ user: User, tacos: {} }), + { user: '1', tacos: {} }, fromJS(entities), ), ).toMatchSnapshot(); expect( denormalize( - fromJS({ user: '1', tacos: {} }), new schema.Object({ user: User, tacos: {} }), + fromJS({ user: '1', tacos: {} }), fromJS(entities), ), ).toMatchSnapshot(); @@ -208,12 +208,12 @@ describe(`${schema.Object.name} denormalization`, () => { 0: { id: '0', name: 'Chancho' }, }, }; - expect(denormalize({ user: '0' }, object, entities)).toMatchSnapshot(); + expect(denormalize(object, { user: '0' }, entities)).toMatchSnapshot(); expect( - denormalize({ user: '0' }, object, fromJS(entities)), + denormalize(object, { user: '0' }, fromJS(entities)), ).toMatchSnapshot(); expect( - denormalize(fromJS({ user: '0' }), object, fromJS(entities)), + denormalize(object, fromJS({ user: '0' }), fromJS(entities)), ).toMatchSnapshot(); }); }); diff --git a/packages/endpoint/src/schemas/__tests__/Serializable.test.ts b/packages/endpoint/src/schemas/__tests__/Serializable.test.ts index 36d3f9756b31..06f19ceedc00 100644 --- a/packages/endpoint/src/schemas/__tests__/Serializable.test.ts +++ b/packages/endpoint/src/schemas/__tests__/Serializable.test.ts @@ -69,12 +69,12 @@ describe(`Serializable denormalization`, () => { }, }; const response = new SimpleMemoCache().denormalize( + objectSchema, { user: '1', anotherItem: Other({ thing: 500 }), time: '2020-06-07T02:00:15+0000', }, - objectSchema, entities, ); expect(response).not.toEqual(expect.any(Symbol)); @@ -97,12 +97,12 @@ describe(`Serializable denormalization`, () => { }, }; const response = new SimpleMemoCache().denormalize( + objectSchema, { user: '1', anotherItem: { thing: 500 }, time: '2020-06-07T02:00:15Z', }, - objectSchema, entities, ); expect(response).not.toEqual(expect.any(Symbol)); diff --git a/packages/endpoint/src/schemas/__tests__/Union.test.js b/packages/endpoint/src/schemas/__tests__/Union.test.js index 2ccc76b89ad1..e5b024c8dee8 100644 --- a/packages/endpoint/src/schemas/__tests__/Union.test.js +++ b/packages/endpoint/src/schemas/__tests__/Union.test.js @@ -250,8 +250,8 @@ describe('complex case', () => { expect(denorm).toMatchSnapshot(); expect( new SimpleMemoCache().denormalize( - denorm.result, waterfallSchema, + denorm.result, denorm.entities, ), ).toMatchSnapshot(); @@ -286,16 +286,16 @@ describe.each([ expect( denormalize( - createInput({ id: '1', schema: 'users' }), union, + createInput({ id: '1', schema: 'users' }), createInput(entities), ), ).toMatchSnapshot(); expect( denormalize( - createInput({ id: '2', schema: 'groups' }), union, + createInput({ id: '2', schema: 'groups' }), createInput(entities), ), ).toMatchSnapshot(); @@ -314,16 +314,16 @@ describe.each([ expect( denormalize( - createInput({ id: '1', schema: 'users' }), union, + createInput({ id: '1', schema: 'users' }), createInput(entities), ), ).toMatchSnapshot(); expect( denormalize( - createInput({ id: '2', schema: 'groups' }), union, + createInput({ id: '2', schema: 'groups' }), createInput(entities), ), ).toMatchSnapshot(); @@ -345,7 +345,7 @@ describe.each([ ); expect( - denormalize(createInput({ id: '1' }), union, createInput(entities)), + denormalize(union, createInput({ id: '1' }), createInput(entities)), ).toMatchSnapshot(); expect(warnSpy.mock.calls).toMatchSnapshot(); }); @@ -366,7 +366,7 @@ describe.each([ ); expect( - denormalize('1', union, createInput(entities)), + denormalize(union, '1', createInput(entities)), ).toMatchSnapshot(); expect(warnSpy.mock.calls).toMatchSnapshot(); }); @@ -386,7 +386,7 @@ describe.each([ }, ); - expect(denormalize(null, union, createInput(entities))).toBeNull(); + expect(denormalize(union, null, createInput(entities))).toBeNull(); }); test('returns the original value when undefined is given', () => { @@ -405,7 +405,7 @@ describe.each([ ); expect( - denormalize(undefined, union, createInput(entities)), + denormalize(union, undefined, createInput(entities)), ).toBeUndefined(); }); }, diff --git a/packages/endpoint/src/schemas/__tests__/Values.test.js b/packages/endpoint/src/schemas/__tests__/Values.test.js index 53cb3ec1b933..8c117b71eee7 100644 --- a/packages/endpoint/src/schemas/__tests__/Values.test.js +++ b/packages/endpoint/src/schemas/__tests__/Values.test.js @@ -235,11 +235,11 @@ describe.each([ expect( denormalize( + valuesSchema, { first: '1', second: '2', }, - valuesSchema, createInput(entities), ), ).toMatchSnapshot(); @@ -261,11 +261,11 @@ describe.each([ expect( denormalize( + valuesSchema, { fido: { id: '1', schema: 'dogs' }, fluffy: { id: '1', schema: 'cats' }, }, - valuesSchema, createInput(entities), ), ).toMatchSnapshot(); @@ -287,12 +287,12 @@ describe.each([ expect( denormalize( + valuesSchema, { fido: { id: '1', schema: 'dogs' }, fluffy: { id: '1', schema: 'cats' }, prancy: { id: '5', schema: 'cats' }, }, - valuesSchema, createInput(entities), ), ).toMatchSnapshot(); @@ -314,12 +314,12 @@ describe.each([ expect( denormalize( + valuesSchema, { fido: { id: '1', schema: 'dogs' }, fluffy: { id: '1', schema: 'cats' }, prancy: { id: '5', schema: 'cats' }, }, - valuesSchema, createInput(entities), ), ).toMatchSnapshot(); @@ -410,7 +410,7 @@ describe.each([ }); const { result, entities } = normalize(response, shape); expect( - denormalize(result, shape, createInput(entities)), + denormalize(shape, result, createInput(entities)), ).toMatchSnapshot(); }); }, diff --git a/packages/endpoint/src/schemas/__tests__/denormalize.ts b/packages/endpoint/src/schemas/__tests__/denormalize.ts index 586134052045..e959bb0fa0cb 100644 --- a/packages/endpoint/src/schemas/__tests__/denormalize.ts +++ b/packages/endpoint/src/schemas/__tests__/denormalize.ts @@ -9,12 +9,12 @@ export class SimpleMemoCache { private memo = new MemoCache(); denormalize = ( - input: any, schema: S | undefined, + input: any, entities: any, args: any[] = [], ): Denormalize | DenormalizeNullable | symbol => - this.memo.denormalize(input, schema, entities, args).data as any; + this.memo.denormalize(schema, input, entities, args).data as any; } export default SimpleMemoCache; diff --git a/packages/endpoint/typescript-tests/array.ts b/packages/endpoint/typescript-tests/array.ts index af0ffa82655b..ef8a764e3a50 100644 --- a/packages/endpoint/typescript-tests/array.ts +++ b/packages/endpoint/typescript-tests/array.ts @@ -16,7 +16,7 @@ const userListSchemaAlt = [User]; const normalizedDataAlt = normalize(data, userListSchemaAlt); const denormalizedData = denormalize( - normalizedData.result, userListSchema, + normalizedData.result, normalizedData.entities, ); diff --git a/packages/endpoint/typescript-tests/array_schema.ts b/packages/endpoint/typescript-tests/array_schema.ts index daa9b3cd460f..d096be7c1b99 100644 --- a/packages/endpoint/typescript-tests/array_schema.ts +++ b/packages/endpoint/typescript-tests/array_schema.ts @@ -25,8 +25,8 @@ const myArray = new schema.Array( const normalizedData = normalize(data, myArray); const denormalizedData = denormalize( - normalizedData.result, myArray, + normalizedData.result, normalizedData.entities, ); diff --git a/packages/endpoint/typescript-tests/denormalize.ts b/packages/endpoint/typescript-tests/denormalize.ts index a1ccaa105661..f09b0f573ea0 100644 --- a/packages/endpoint/typescript-tests/denormalize.ts +++ b/packages/endpoint/typescript-tests/denormalize.ts @@ -37,7 +37,7 @@ const scheme = { }; const schemeEntity = Magic; -const data = denormalize({}, scheme, {}); +const data = denormalize(scheme, {}, {}); const r = normalize({}, scheme); type A = DenormalizeNullable; @@ -58,7 +58,7 @@ if (typeof data === 'symbol') { const schemeValues = new schema.Values({ btc: Magic, eth: Magic2 }); const schemeValuesSimple = new schema.Values(Magic); -const valueValues = denormalize({}, schemeValues, {}); +const valueValues = denormalize(schemeValues, {}, {}); if (typeof valueValues !== 'symbol') { Object.keys(schemeValues).forEach(k => { const v = valueValues[k]; @@ -68,4 +68,4 @@ if (typeof valueValues !== 'symbol') { }); } -const valueValuesSimple = denormalize({}, schemeValuesSimple, {}); +const valueValuesSimple = denormalize(schemeValuesSimple, {}, {}); diff --git a/packages/endpoint/typescript-tests/entity.ts b/packages/endpoint/typescript-tests/entity.ts index b80f37f5f570..126b0d0ec4cd 100644 --- a/packages/endpoint/typescript-tests/entity.ts +++ b/packages/endpoint/typescript-tests/entity.ts @@ -55,8 +55,8 @@ const tweet = Tweet; const normalizedData = normalize(data, tweet); const denormalizedData = denormalize( - normalizedData.result, tweet, + normalizedData.result, normalizedData.entities, ); diff --git a/packages/normalizr/README.md b/packages/normalizr/README.md index 3519cb397ca4..a53a084ae334 100644 --- a/packages/normalizr/README.md +++ b/packages/normalizr/README.md @@ -174,8 +174,8 @@ Accessing the store can then be done using flux `selectors` by `denormalizing`: import { denormalize } from '@data-client/normalizr'; const denormalizedData = denormalize( - normalizedData.result, Article, + normalizedData.result, normalizedData.entities, args, ); @@ -214,11 +214,11 @@ import { MemoCache } from '@data-client/normalizr'; // you can construct a new memo anytime you want to reset the cache const memo = new MemoCache(); -const { data, paths } = memo.denormalize(input, schema, state.entities, args); +const { data, paths } = memo.denormalize(schema, input, state.entities, args); -const data = memo.query(key, schema, args, state.entities, state.indexes); +const data = memo.query(schema, key, args, state.entities, state.indexes); -function query(key, schema, args, state) { +function query(schema, key, args, state) { const queryKey = memo.buildQueryKey( key, schema, @@ -226,7 +226,7 @@ function query(key, schema, args, state) { state.entities, state.indexes, ); - const { data } = this.denormalize(queryKey, schema, state.entities, args); + const { data } = this.denormalize(schema, queryKey, state.entities, args); return typeof data === 'symbol' ? undefined : (data as any); } ``` diff --git a/packages/normalizr/docs/api.md b/packages/normalizr/docs/api.md index a14e7185edb1..4ed7ee8fa632 100644 --- a/packages/normalizr/docs/api.md +++ b/packages/normalizr/docs/api.md @@ -42,7 +42,7 @@ const normalizedData = normalize(myData, mySchema); } ``` -## `denormalize(input, schema, entities): [denormalized, foundAllEntities]` +## `denormalize(schema, input, entities): [denormalized, foundAllEntities]` Denormalizes an input based on schema and provided entities from a plain object or Immutable data. The reverse of `normalize`. @@ -50,8 +50,8 @@ _Special Note:_ Be careful with denormalization. Prematurely reverting your data If your schema and data have recursive references, only the first instance of an entity will be given. Subsequent references will be returned as the `id` provided. -- `input`: **required** The normalized result that should be _de-normalized_. Usually the same value that was given in the `result` key of the output of `normalize`. - `schema`: **required** A schema definition that was used to get the value for `input`. +- `input`: **required** The normalized result that should be _de-normalized_. Usually the same value that was given in the `result` key of the output of `normalize`. - `entities`: **required** An object, keyed by entity schema names that may appear in the denormalized output. Also accepts an object with Immutable data. ### Usage diff --git a/packages/normalizr/src/__tests__/MemoCache.ts b/packages/normalizr/src/__tests__/MemoCache.ts index 2916e99ea243..51e169a48e73 100644 --- a/packages/normalizr/src/__tests__/MemoCache.ts +++ b/packages/normalizr/src/__tests__/MemoCache.ts @@ -42,7 +42,7 @@ describe('MemoCache', () => { 1: Symbol('ENTITY WAS DELETED'), }, }; - expect(new MemoCache().denormalize('1', Tacos, entities).data).toEqual( + expect(new MemoCache().denormalize(Tacos, '1', entities).data).toEqual( expect.any(Symbol), ); }); @@ -57,23 +57,23 @@ describe('MemoCache', () => { const result = ['1', '2']; const schema = [Tacos]; const { data: first, paths: pathsFirst } = memo.denormalize( - result, schema, + result, entities, ); const { data: second, paths: pathsSecond } = memo.denormalize( - result, schema, + result, entities, ); expect(first).toBe(second); expect(pathsFirst).toEqual(pathsSecond); - const { data: third } = memo.denormalize([...result], schema, entities); + const { data: third } = memo.denormalize(schema, [...result], entities); expect(first).not.toBe(third); expect(first).toEqual(third); - const fourth = memo.denormalize(result, schema, { + const fourth = memo.denormalize(schema, result, { Tacos: { ...entities.Tacos, 2: { id: '2', type: 'bar' } }, }).data; expect(first).not.toBe(fourth); @@ -89,10 +89,10 @@ describe('MemoCache', () => { }; const result = { data: ['1', '2'], nextPage: 'initial' }; const schema = { data: [Tacos], nextPage: '' }; - const { data: first, paths } = memo.denormalize(result, schema, entities); + const { data: first, paths } = memo.denormalize(schema, result, entities); const { data: second, paths: pathsSecond } = memo.denormalize( - { ...result, nextPage: 'second' }, schema, + { ...result, nextPage: 'second' }, entities, ); if (typeof first === 'symbol' || typeof second === 'symbol') @@ -106,8 +106,8 @@ describe('MemoCache', () => { } const { data: fourth, paths: fourthPaths } = memo.denormalize( - result, schema, + result, { Tacos: { ...entities.Tacos, 2: { id: '2', type: 'bar' } }, }, @@ -175,11 +175,11 @@ describe('MemoCache', () => { const result = { data: '123' }; const schema = { data: Article }; - const first = memo.denormalize(result, schema, entities).data; - const second = memo.denormalize(result, schema, entities).data; + const first = memo.denormalize(schema, result, entities).data; + const second = memo.denormalize(schema, result, entities).data; expect(first).toBe(second); - const third = memo.denormalize('123', Article, entities).data; - const fourth = memo.denormalize('123', Article, entities).data; + const third = memo.denormalize(Article, '123', entities).data; + const fourth = memo.denormalize(Article, '123', entities).data; expect(third).toBe(fourth); }); @@ -189,13 +189,13 @@ describe('MemoCache', () => { const result1 = { data: '123' }; const result2 = { results: ['123'] }; const first = memo.denormalize( - result1, { data: Article }, + result1, entities, ).data; const second = memo.denormalize( - result2, { results: [Article] }, + result2, entities, ).data; if ( @@ -205,7 +205,7 @@ describe('MemoCache', () => { ) throw new Error(); expect(first.data).toBe(second.results[0]); - const third = memo.denormalize('123', Article, entities).data; + const third = memo.denormalize(Article, '123', entities).data; expect(third).toBe(first.data); // now change @@ -220,14 +220,14 @@ describe('MemoCache', () => { }, }; const firstChanged = memo.denormalize( - result1, { data: Article }, + result1, nextState, ).data; expect(firstChanged).not.toBe(first); const secondChanged = memo.denormalize( - result2, { results: [Article] }, + result2, nextState, ).data; expect(secondChanged).not.toBe(second); @@ -258,8 +258,8 @@ describe('MemoCache', () => { const resultC = '123'; const firstSchema = { data: ArticleSummary }; const secondSchema = { data: Article }; - const first = memo.denormalize(resultA, firstSchema, entities).data; - const second = memo.denormalize(resultB, secondSchema, entities).data; + const first = memo.denormalize(firstSchema, resultA, entities).data; + const second = memo.denormalize(secondSchema, resultB, entities).data; if ( typeof first === 'symbol' || typeof second === 'symbol' || @@ -277,13 +277,13 @@ describe('MemoCache', () => { `); expect(first.data).not.toBe(second.data); const firstWithoutChange = memo.denormalize( - resultA, firstSchema, + resultA, entities, ).data; expect(first).toBe(firstWithoutChange); - const third = memo.denormalize(resultC, Article, entities).data; + const third = memo.denormalize(Article, resultC, entities).data; expect(third).toBe(second.data); // now change @@ -298,14 +298,14 @@ describe('MemoCache', () => { }, }; const firstChanged = memo.denormalize( - resultA, firstSchema, + resultA, nextState, ).data; expect(firstChanged).not.toBe(first); const secondChanged = memo.denormalize( - resultB, secondSchema, + resultB, nextState, ).data; expect(secondChanged).not.toBe(second); @@ -330,26 +330,22 @@ describe('MemoCache', () => { const result = { data: '123' }; const { data: first } = memo.denormalize( - result, { data: Article }, + result, entities, ); - const { data: second } = memo.denormalize( - result, - { data: Article }, - { - ...entities, - Article: { - 123: { - author: '8472', - body: 'This article is great.', - comments: ['comment-123-4738'], - id: '123', - title: 'A Great Article', - }, + const { data: second } = memo.denormalize({ data: Article }, result, { + ...entities, + Article: { + 123: { + author: '8472', + body: 'This article is great.', + comments: ['comment-123-4738'], + id: '123', + title: 'A Great Article', }, }, - ); + }); expect(first).not.toBe(second); if ( typeof first === 'symbol' || @@ -367,25 +363,21 @@ describe('MemoCache', () => { const result = { data: '123' }; const { data: first } = memo.denormalize( - result, { data: Article }, + result, entities, ); - const { data: second } = memo.denormalize( - result, - { data: Article }, - { - ...entities, - Comment: { - 'comment-123-4738': { - comment: 'Updated comment!', - id: 'comment-123-4738', - user: '10293', - }, + const { data: second } = memo.denormalize({ data: Article }, result, { + ...entities, + Comment: { + 'comment-123-4738': { + comment: 'Updated comment!', + id: 'comment-123-4738', + user: '10293', }, }, - ); + }); expect(first).not.toBe(second); if ( @@ -412,20 +404,20 @@ describe('MemoCache', () => { User: {}, }; const { data: first } = memo.denormalize( - result, { data: Article }, + result, emptyEntities, ); const { data: second } = memo.denormalize( - result, { data: Article }, + result, emptyEntities, ); const { data: third } = memo.denormalize( - result, { data: Article }, + result, // now has users entities, ); @@ -485,20 +477,20 @@ describe('MemoCache', () => { User: {}, }; const { data: first } = memo.denormalize( - result, { data: Article }, + result, emptyEntities, ); const { data: second } = memo.denormalize( - result, { data: Article }, + result, emptyEntities, ); const { data: third } = memo.denormalize( - result, { data: Article }, + result, // now has users entities, ); @@ -534,10 +526,10 @@ describe('MemoCache', () => { firstThing: { five: 0, seven: 0 }, secondThing: { cars: '' }, }; - const { data: first } = memo.denormalize(input, schema, {}); + const { data: first } = memo.denormalize(schema, input, {}); expect(first).toEqual(input); // should maintain referential equality - const { data: second } = memo.denormalize(input, schema, {}); + const { data: second } = memo.denormalize(schema, input, {}); expect(second).toBe(first); }); @@ -548,7 +540,7 @@ describe('MemoCache', () => { firstThing: { five: 5, seven: 42 }, secondThing: { cars: 'never' }, }; - const { data } = memo.denormalize(input, null, {}); + const { data } = memo.denormalize(null, input, {}); expect(data).toBe(input); }); @@ -556,7 +548,7 @@ describe('MemoCache', () => { const memo = new MemoCache(); const input = 5; - const { data } = memo.denormalize(input, null, {}); + const { data } = memo.denormalize(null, input, {}); expect(data).toBe(input); }); @@ -567,7 +559,7 @@ describe('MemoCache', () => { firstThing: { five: 5, seven: 42 }, secondThing: { cars: 'never' }, }; - const { data } = memo.denormalize(input, undefined, {}); + const { data } = memo.denormalize(undefined, input, {}); expect(data).toBe(input); }); @@ -593,14 +585,14 @@ describe('MemoCache', () => { test('handles null at top level', () => { const memo = new MemoCache(); - const denorm = memo.denormalize(null, { data: Article }, {}).data; + const denorm = memo.denormalize({ data: Article }, null, {}).data; expect(denorm).toEqual(null); }); test('handles undefined at top level', () => { const memo = new MemoCache(); - const denorm = memo.denormalize(undefined, { data: Article }, {}).data; + const denorm = memo.denormalize({ data: Article }, undefined, {}).data; expect(denorm).toEqual(undefined); }); @@ -610,7 +602,7 @@ describe('MemoCache', () => { const input = { data: { id: '5', title: 'hehe', author: null, comments: [] }, }; - const denorm = memo.denormalize(input, { data: Article }, {}).data; + const denorm = memo.denormalize({ data: Article }, input, {}).data; expect(denorm).toMatchInlineSnapshot(` { "data": Article { diff --git a/packages/normalizr/src/__tests__/index.test.js b/packages/normalizr/src/__tests__/index.test.js index 94d0a5a7bac6..849d058a0e8d 100644 --- a/packages/normalizr/src/__tests__/index.test.js +++ b/packages/normalizr/src/__tests__/index.test.js @@ -431,15 +431,15 @@ describe.each([ ])(`denormalize [%s]`, (_, denormalize) => { test('passthrough with undefined schema', () => { const input = {}; - expect(denormalize(input)).toEqual(input); + expect(denormalize(undefined, input)).toEqual(input); }); test('returns the input if undefined', () => { - expect(denormalize(undefined, {}, {})).toEqual(undefined); + expect(denormalize({}, undefined, {})).toEqual(undefined); }); test('returns the input if string', () => { - expect(denormalize('bob', '', {})).toEqual('bob'); + expect(denormalize('', 'bob', {})).toEqual('bob'); }); test('denormalizes entities', () => { @@ -449,15 +449,15 @@ describe.each([ 2: { id: '2', type: 'bar' }, }, }; - expect(denormalize(['1', '2'], [Tacos], entities)).toMatchSnapshot(); + expect(denormalize([Tacos], ['1', '2'], entities)).toMatchSnapshot(); }); test('denormalizes without entities fills undefined', () => { - expect(denormalize({ data: '1' }, { data: Tacos }, {})).toMatchSnapshot(); + expect(denormalize({ data: Tacos }, { data: '1' }, {})).toMatchSnapshot(); expect( - denormalize(fromJS({ data: '1' }), { data: Tacos }, {}), + denormalize({ data: Tacos }, fromJS({ data: '1' }), {}), ).toMatchSnapshot(); - expect(denormalize('1', Tacos, {})).toEqual(undefined); + expect(denormalize(Tacos, '1', {})).toEqual(undefined); }); test('denormalizes ignoring unfound entities in arrays', () => { @@ -466,9 +466,9 @@ describe.each([ 1: { id: '1', type: 'foo' }, }, }; - expect(denormalize(['1', '2'], [Tacos], entities)).toMatchSnapshot(); + expect(denormalize([Tacos], ['1', '2'], entities)).toMatchSnapshot(); expect( - denormalize({ results: ['1', '2'] }, { results: [Tacos] }, entities), + denormalize({ results: [Tacos] }, { results: ['1', '2'] }, entities), ).toMatchSnapshot(); }); @@ -478,7 +478,7 @@ describe.each([ 1: Symbol('ENTITY WAS INVALID'), }, }; - expect(denormalize('1', Tacos, entities)).toEqual(expect.any(Symbol)); + expect(denormalize(Tacos, '1', entities)).toEqual(expect.any(Symbol)); }); test('denormalizes ignoring deleted entities in arrays', () => { @@ -488,9 +488,9 @@ describe.each([ 2: INVALID, }, }; - expect(denormalize(['1', '2'], [Tacos], entities)).toMatchSnapshot(); + expect(denormalize([Tacos], ['1', '2'], entities)).toMatchSnapshot(); expect( - denormalize({ results: ['1', '2'] }, { results: [Tacos] }, entities), + denormalize({ results: [Tacos] }, { results: ['1', '2'] }, entities), ).toMatchSnapshot(); }); @@ -501,10 +501,10 @@ describe.each([ }, }; /*expect( - denormalize([{ data: 1 }, { data: 2 }], [{ data: Tacos }], {}), + denormalize([{ data: Tacos }],[{ data: 1 }, { data: 2 }], {}), ).toEqual([]);*/ expect( - denormalize([{ data: 1 }, { data: 2 }], [{ data: Tacos }], entities), + denormalize([{ data: Tacos }], [{ data: 1 }, { data: 2 }], entities), ).toMatchSnapshot(); }); @@ -517,16 +517,6 @@ describe.each([ }; expect( denormalize( - { - data: ['1', '2'], - extra: '5', - page: { - first: null, - second: { thing: 'two' }, - third: 1, - complex: { complex: false, next: true }, - }, - }, { data: [Tacos], extra: '', @@ -537,6 +527,17 @@ describe.each([ complex: { complex: true, next: false }, }, }, + { + data: ['1', '2'], + extra: '5', + page: { + first: null, + second: { thing: 'two' }, + third: 1, + complex: { complex: false, next: true }, + }, + }, + entities, ), ).toMatchSnapshot(); @@ -551,9 +552,6 @@ describe.each([ }; expect( denormalize( - { - data: ['1', '2'], - }, { data: [Tacos], extra: '', @@ -564,6 +562,10 @@ describe.each([ complex: { complex: true, next: false }, }, }, + { + data: ['1', '2'], + }, + entities, ), ).toMatchSnapshot(); @@ -614,7 +616,7 @@ describe.each([ }, }, }; - expect(denormalize('123', Article, entities)).toMatchSnapshot(); + expect(denormalize(Article, '123', entities)).toMatchSnapshot(); }); test('gracefully handles when nested entities are primitives', () => { @@ -658,7 +660,7 @@ describe.each([ }, }, }; - expect(() => denormalize('123', Article, entities)).toMatchSnapshot(); + expect(() => denormalize(Article, '123', entities)).toMatchSnapshot(); }); test('set to undefined if schema key is not in entities', () => { @@ -695,7 +697,7 @@ describe.each([ }, }, }; - expect(denormalize('123', Article, entities)).toMatchSnapshot(); + expect(denormalize(Article, '123', entities)).toMatchSnapshot(); }); test('does not modify the original entities', () => { @@ -720,7 +722,7 @@ describe.each([ }), }), }); - expect(() => denormalize('123', Article, entities)).not.toThrow(); + expect(() => denormalize(Article, '123', entities)).not.toThrow(); }); test('denormalizes with function as pk()', () => { @@ -747,18 +749,18 @@ describe.each([ }; expect( - denormalize(normalizedData.result, [Patron], normalizedData.entities), + denormalize([Patron], normalizedData.result, normalizedData.entities), ).toMatchSnapshot(); }); test('denormalizes where id is only in key', () => { expect( denormalize( + new schema.Values(Tacos), { 1: { type: 'foo' }, 2: { type: 'bar' }, }, - new schema.Values(Tacos), {}, ), ).toMatchSnapshot(); diff --git a/packages/normalizr/src/__tests__/normalizerMerge.test.tsx b/packages/normalizr/src/__tests__/normalizerMerge.test.tsx index fcdcbc700b5b..415842e18df8 100644 --- a/packages/normalizr/src/__tests__/normalizerMerge.test.tsx +++ b/packages/normalizr/src/__tests__/normalizerMerge.test.tsx @@ -26,7 +26,7 @@ describe('normalizer() merging', () => { firstEM, ); - const merged = denormalize(result, Article, entities); + const merged = denormalize(Article, result, entities); expect(merged).toBeInstanceOf(Article); expect(merged).toEqual( Article.fromJS({ @@ -86,7 +86,7 @@ describe('normalizer() merging', () => { firstEM, ); - const merged = denormalize(result, Article, entities); + const merged = denormalize(Article, result, entities); expect(merged).toBeInstanceOf(Article); expect(merged).toEqual( Article.fromJS({ @@ -110,7 +110,7 @@ describe('normalizer() merging', () => { normalize({ id, title: 'hello' }, Article, [], first); - const merged = denormalize(id, Article, first); + const merged = denormalize(Article, id, first); expect(merged).toBeInstanceOf(Article); expect(merged).toEqual( Article.fromJS({ diff --git a/packages/normalizr/src/denormalize/denormalize.ts b/packages/normalizr/src/denormalize/denormalize.ts index d1155198531b..b831f7f31129 100644 --- a/packages/normalizr/src/denormalize/denormalize.ts +++ b/packages/normalizr/src/denormalize/denormalize.ts @@ -5,8 +5,8 @@ import type { Schema } from '../interface.js'; import type { DenormalizeNullable } from '../types.js'; export function denormalize( - input: any, schema: S | undefined, + input: any, entities: any, args: readonly any[] = [], ): DenormalizeNullable | symbol { @@ -19,5 +19,5 @@ export function denormalize( getEntities(entities), new LocalCache(), args, - )(input, schema).data; + )(schema, input).data; } diff --git a/packages/normalizr/src/denormalize/unvisit.ts b/packages/normalizr/src/denormalize/unvisit.ts index 1e1e2d68cca8..23d5197a94ff 100644 --- a/packages/normalizr/src/denormalize/unvisit.ts +++ b/packages/normalizr/src/denormalize/unvisit.ts @@ -10,10 +10,10 @@ import { denormalize as objectDenormalize } from '../schemas/Object.js'; import type { EntityPath } from '../types.js'; function unvisitEntity( - entityOrId: Record | string, schema: EntityInterface, + entityOrId: Record | string, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, getEntity: GetEntity, cache: Cache, ): object | undefined | symbol { @@ -82,7 +82,7 @@ function noCacheGetEntity( function unvisitEntityObject( entity: object, schema: EntityInterface, - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, pk: string, localCacheKey: Record, args: readonly any[], @@ -107,7 +107,7 @@ const getUnvisit = ( cache: Cache, args: readonly any[], ) => { - function unvisit(input: any, schema: any): any { + function unvisit(schema: any, input: any): any { if (!schema) return input; if (input === null || input === undefined) { @@ -128,7 +128,7 @@ const getUnvisit = ( } } else { if (isEntity(schema)) { - return unvisitEntity(input, schema, args, unvisit, getEntity, cache); + return unvisitEntity(schema, input, args, unvisit, getEntity, cache); } return schema.denormalize(input, args, unvisit); @@ -137,11 +137,11 @@ const getUnvisit = ( return input; } - return (input: any, schema: any): { data: any; paths: EntityPath[] } => { + return (schema: any, input: any): { data: any; paths: EntityPath[] } => { // in the case where WeakMap cannot be used // this test ensures null is properly excluded from WeakMap const cachable = Object(input) === input && Object(schema) === schema; - return cache.getResults(input, cachable, () => unvisit(input, schema)); + return cache.getResults(input, cachable, () => unvisit(schema, input)); }; }; export default getUnvisit; diff --git a/packages/normalizr/src/interface.ts b/packages/normalizr/src/interface.ts index 6a07c707324c..2cb3280383e3 100644 --- a/packages/normalizr/src/interface.ts +++ b/packages/normalizr/src/interface.ts @@ -34,7 +34,7 @@ export interface SchemaSimple { denormalize( input: {}, args: readonly any[], - unvisit: (input: any, schema: any) => any, + unvisit: (schema: any, input: any) => any, ): T; queryKey( args: Args, diff --git a/packages/normalizr/src/memo/MemoCache.ts b/packages/normalizr/src/memo/MemoCache.ts index c58ef9c5a434..dfc0cc7a1694 100644 --- a/packages/normalizr/src/memo/MemoCache.ts +++ b/packages/normalizr/src/memo/MemoCache.ts @@ -25,8 +25,8 @@ export default class MemoCache { /** Compute denormalized form maintaining referential equality for same inputs */ denormalize( - input: unknown, schema: S | undefined, + input: unknown, entities: any, args: readonly any[] = [], ): { @@ -50,7 +50,7 @@ export default class MemoCache { getEntity, new GlobalCache(getEntity, this.entities, this.endpoints), args, - )(input, schema); + )(schema, input); } /** Compute denormalized form maintaining referential equality for same inputs */ @@ -75,7 +75,7 @@ export default class MemoCache { return; } - const { data } = this.denormalize(input, schema, entities, args); + const { data } = this.denormalize(schema, input, entities, args); return typeof data === 'symbol' ? undefined : (data as any); } diff --git a/packages/normalizr/src/schemas/Array.ts b/packages/normalizr/src/schemas/Array.ts index be2a4ec19e5f..70b446316b7e 100644 --- a/packages/normalizr/src/schemas/Array.ts +++ b/packages/normalizr/src/schemas/Array.ts @@ -47,7 +47,7 @@ export const denormalize = ( ): any => { schema = validateSchema(schema); return input.map ? - input.map(entityOrId => unvisit(entityOrId, schema)).filter(filterEmpty) + input.map(entityOrId => unvisit(schema, entityOrId)).filter(filterEmpty) : input; }; diff --git a/packages/normalizr/src/schemas/ImmutableUtils.ts b/packages/normalizr/src/schemas/ImmutableUtils.ts index 6e19ace178c7..653bdf715d83 100644 --- a/packages/normalizr/src/schemas/ImmutableUtils.ts +++ b/packages/normalizr/src/schemas/ImmutableUtils.ts @@ -46,7 +46,7 @@ export function denormalizeImmutable( // we're accessing them using string keys. const stringKey = `${key}`; - const item = unvisit(object.get(stringKey), schema[stringKey]); + const item = unvisit(schema[stringKey], object.get(stringKey)); if (typeof item === 'symbol') { deleted = true; } diff --git a/packages/normalizr/src/schemas/Object.ts b/packages/normalizr/src/schemas/Object.ts index 79496513f1fc..4daca1dbb889 100644 --- a/packages/normalizr/src/schemas/Object.ts +++ b/packages/normalizr/src/schemas/Object.ts @@ -40,7 +40,7 @@ export const denormalize = ( const object = { ...input }; let deleted = false; Object.keys(schema).forEach(key => { - const item = unvisit(object[key], schema[key]); + const item = unvisit(schema[key], object[key]); if (object[key] !== undefined) { object[key] = item; }