payload 3.62.0-internal.7fb5145 → 3.62.0-internal.ec3a6fa
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/dist/auth/cookies.spec.js +1 -0
- package/dist/auth/cookies.spec.js.map +1 -1
- package/dist/bin/generateImportMap/generateImportMap.spec.js +2 -1
- package/dist/bin/generateImportMap/generateImportMap.spec.js.map +1 -1
- package/dist/collections/config/useAsTitle.spec.js +1 -0
- package/dist/collections/config/useAsTitle.spec.js.map +1 -1
- package/dist/config/types.d.ts +5 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/migrations/findMigrationDir.spec.js +2 -1
- package/dist/database/migrations/findMigrationDir.spec.js.map +1 -1
- package/dist/database/migrations/readMigrationFiles.d.ts.map +1 -1
- package/dist/database/migrations/readMigrationFiles.js +1 -3
- package/dist/database/migrations/readMigrationFiles.js.map +1 -1
- package/dist/fields/config/reservedFieldNames.spec.js +1 -0
- package/dist/fields/config/reservedFieldNames.spec.js.map +1 -1
- package/dist/fields/config/sanitize.spec.js +1 -0
- package/dist/fields/config/sanitize.spec.js.map +1 -1
- package/dist/fields/validations.spec.js +2 -2
- package/dist/fields/validations.spec.js.map +1 -1
- package/dist/index.bundled.d.ts +6 -0
- package/dist/queues/config/types/index.d.ts +1 -0
- package/dist/queues/config/types/index.d.ts.map +1 -1
- package/dist/queues/config/types/index.js.map +1 -1
- package/dist/uploads/mimeTypeValidator.spec.js +1 -0
- package/dist/uploads/mimeTypeValidator.spec.js.map +1 -1
- package/dist/utilities/addSelectGenericsToGeneratedTypes.spec.js +3 -2
- package/dist/utilities/addSelectGenericsToGeneratedTypes.spec.js.map +1 -1
- package/dist/utilities/combineWhereConstraints.spec.js +1 -0
- package/dist/utilities/combineWhereConstraints.spec.js.map +1 -1
- package/dist/utilities/configToJSONSchema.spec.js +1 -0
- package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
- package/dist/utilities/flattenTopLevelFields.spec.js +1 -0
- package/dist/utilities/flattenTopLevelFields.spec.js.map +1 -1
- package/dist/utilities/formatLabels.spec.js +1 -0
- package/dist/utilities/formatLabels.spec.js.map +1 -1
- package/dist/utilities/getFieldByPath.spec.js +1 -0
- package/dist/utilities/getFieldByPath.spec.js.map +1 -1
- package/dist/utilities/getFieldPermissions.spec.js +1 -0
- package/dist/utilities/getFieldPermissions.spec.js.map +1 -1
- package/dist/utilities/getSafeRedirect.spec.js +1 -0
- package/dist/utilities/getSafeRedirect.spec.js.map +1 -1
- package/dist/utilities/sanitizePermissions.spec.js +1 -0
- package/dist/utilities/sanitizePermissions.spec.js.map +1 -1
- package/dist/utilities/sanitizeUserDataForEmail.spec.js +1 -0
- package/dist/utilities/sanitizeUserDataForEmail.spec.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/addSelectGenericsToGeneratedTypes.spec.ts"],"sourcesContent":["import { addSelectGenericsToGeneratedTypes } from './addSelectGenericsToGeneretedTypes.js'\n\nconst INPUT_AND_OUTPUT = [\n {\n input: `\n/* tslint:disable */\n/* eslint-disable */\n/**\n * This file was automatically generated by Payload.\n * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,\n * and re-run \\`payload generate:types\\` to regenerate this file.\n */\n\nexport interface Config {\n auth: {\n users: UserAuthOperations;\n };\n collections: {\n posts: Post;\n users: User;\n 'payload-locked-documents': PayloadLockedDocument;\n 'payload-preferences': PayloadPreference;\n 'payload-migrations': PayloadMigration;\n };\n collectionsSelect: {\n posts: PostsSelect;\n users: UsersSelect;\n 'payload-locked-documents': PayloadLockedDocumentsSelect;\n 'payload-preferences': PayloadPreferencesSelect;\n 'payload-migrations': PayloadMigrationsSelect;\n };\n db: {\n defaultIDType: string;\n };\n globals: {};\n globalsSelect: {};\n locale: null;\n user: User & {\n collection: 'users';\n };\n}\nexport interface UserAuthOperations {\n forgotPassword: {\n email: string;\n password: string;\n };\n login: {\n email: string;\n password: string;\n };\n registerFirstUser: {\n email: string;\n password: string;\n };\n unlock: {\n email: string;\n password: string;\n };\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts\".\n */\nexport interface Post {\n id: string;\n text?: string | null;\n number?: number | null;\n group?: {\n text?: string | null;\n number?: number | null;\n };\n array?:\n | {\n text?: string | null;\n number?: number | null;\n id?: string | null;\n }[]\n | null;\n blocks?:\n | (\n | {\n text?: string | null;\n introText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'intro';\n }\n | {\n text?: string | null;\n ctaText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'cta';\n }\n )[]\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users\".\n */\nexport interface User {\n id: string;\n updatedAt: string;\n createdAt: string;\n email: string;\n resetPasswordToken?: string | null;\n resetPasswordExpiration?: string | null;\n salt?: string | null;\n hash?: string | null;\n loginAttempts?: number | null;\n lockUntil?: string | null;\n password?: string | null;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents\".\n */\nexport interface PayloadLockedDocument {\n id: string;\n document?:\n | ({\n relationTo: 'posts';\n value: string | Post;\n } | null)\n | ({\n relationTo: 'users';\n value: string | User;\n } | null);\n globalSlug?: string | null;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences\".\n */\nexport interface PayloadPreference {\n id: string;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n key?: string | null;\n value?:\n | {\n [k: string]: unknown;\n }\n | unknown[]\n | string\n | number\n | boolean\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations\".\n */\nexport interface PayloadMigration {\n id: string;\n name?: string | null;\n batch?: number | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts_select\".\n */\nexport interface PostsSelect {\n text?: boolean;\n number?: boolean;\n sharedGroup?: boolean | SharedGroup;\n group?:\n | boolean\n | {\n text?: boolean;\n number?: boolean;\n };\n array?:\n | boolean\n | {\n text?: boolean;\n number?: boolean;\n id?: boolean;\n };\n blocks?:\n | boolean\n | {\n intro?:\n | boolean\n | {\n text?: boolean;\n introText?: boolean;\n id?: boolean;\n blockName?: boolean;\n };\n cta?:\n | boolean\n | {\n text?: boolean;\n ctaText?: boolean;\n id?: boolean;\n blockName?: boolean;\n };\n };\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users_select\".\n */\nexport interface UsersSelect {\n updatedAt?: boolean;\n createdAt?: boolean;\n email?: boolean;\n resetPasswordToken?: boolean;\n resetPasswordExpiration?: boolean;\n salt?: boolean;\n hash?: boolean;\n loginAttempts?: boolean;\n lockUntil?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents_select\".\n */\nexport interface PayloadLockedDocumentsSelect {\n document?: boolean;\n globalSlug?: boolean;\n user?: boolean;\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences_select\".\n */\nexport interface PayloadPreferencesSelect {\n user?: boolean;\n key?: boolean;\n value?: boolean;\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations_select\".\n */\nexport interface PayloadMigrationsSelect {\n name?: boolean;\n batch?: boolean;\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"auth\".\n */\nexport interface Auth {\n [k: string]: unknown;\n}\n\n\ndeclare module 'payload' {\n // @ts-ignore \n export interface GeneratedTypes extends Config {}\n}\n`,\n output: `\n/* tslint:disable */\n/* eslint-disable */\n/**\n * This file was automatically generated by Payload.\n * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,\n * and re-run \\`payload generate:types\\` to regenerate this file.\n */\n\nexport interface Config {\n auth: {\n users: UserAuthOperations;\n };\n collections: {\n posts: Post;\n users: User;\n 'payload-locked-documents': PayloadLockedDocument;\n 'payload-preferences': PayloadPreference;\n 'payload-migrations': PayloadMigration;\n };\n collectionsSelect: {\n posts: PostsSelect<false> | PostsSelect<true>;\n users: UsersSelect<false> | UsersSelect<true>;\n 'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;\n 'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;\n 'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;\n };\n db: {\n defaultIDType: string;\n };\n globals: {};\n globalsSelect: {};\n locale: null;\n user: User & {\n collection: 'users';\n };\n}\nexport interface UserAuthOperations {\n forgotPassword: {\n email: string;\n password: string;\n };\n login: {\n email: string;\n password: string;\n };\n registerFirstUser: {\n email: string;\n password: string;\n };\n unlock: {\n email: string;\n password: string;\n };\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts\".\n */\nexport interface Post {\n id: string;\n text?: string | null;\n number?: number | null;\n group?: {\n text?: string | null;\n number?: number | null;\n };\n array?:\n | {\n text?: string | null;\n number?: number | null;\n id?: string | null;\n }[]\n | null;\n blocks?:\n | (\n | {\n text?: string | null;\n introText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'intro';\n }\n | {\n text?: string | null;\n ctaText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'cta';\n }\n )[]\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users\".\n */\nexport interface User {\n id: string;\n updatedAt: string;\n createdAt: string;\n email: string;\n resetPasswordToken?: string | null;\n resetPasswordExpiration?: string | null;\n salt?: string | null;\n hash?: string | null;\n loginAttempts?: number | null;\n lockUntil?: string | null;\n password?: string | null;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents\".\n */\nexport interface PayloadLockedDocument {\n id: string;\n document?:\n | ({\n relationTo: 'posts';\n value: string | Post;\n } | null)\n | ({\n relationTo: 'users';\n value: string | User;\n } | null);\n globalSlug?: string | null;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences\".\n */\nexport interface PayloadPreference {\n id: string;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n key?: string | null;\n value?:\n | {\n [k: string]: unknown;\n }\n | unknown[]\n | string\n | number\n | boolean\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations\".\n */\nexport interface PayloadMigration {\n id: string;\n name?: string | null;\n batch?: number | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts_select\".\n */\nexport interface PostsSelect<T extends boolean = true> {\n text?: T;\n number?: T;\n sharedGroup?: T | SharedGroup<T>;\n group?:\n | T\n | {\n text?: T;\n number?: T;\n };\n array?:\n | T\n | {\n text?: T;\n number?: T;\n id?: T;\n };\n blocks?:\n | T\n | {\n intro?:\n | T\n | {\n text?: T;\n introText?: T;\n id?: T;\n blockName?: T;\n };\n cta?:\n | T\n | {\n text?: T;\n ctaText?: T;\n id?: T;\n blockName?: T;\n };\n };\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users_select\".\n */\nexport interface UsersSelect<T extends boolean = true> {\n updatedAt?: T;\n createdAt?: T;\n email?: T;\n resetPasswordToken?: T;\n resetPasswordExpiration?: T;\n salt?: T;\n hash?: T;\n loginAttempts?: T;\n lockUntil?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents_select\".\n */\nexport interface PayloadLockedDocumentsSelect<T extends boolean = true> {\n document?: T;\n globalSlug?: T;\n user?: T;\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences_select\".\n */\nexport interface PayloadPreferencesSelect<T extends boolean = true> {\n user?: T;\n key?: T;\n value?: T;\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations_select\".\n */\nexport interface PayloadMigrationsSelect<T extends boolean = true> {\n name?: T;\n batch?: T;\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"auth\".\n */\nexport interface Auth {\n [k: string]: unknown;\n}\n\n\ndeclare module 'payload' {\n // @ts-ignore \n export interface GeneratedTypes extends Config {}\n}\n`,\n },\n]\n\ndescribe('addSelectGenericsToGeneratedTypes', () => {\n it('should match return of given input with output', () => {\n for (const { input, output } of INPUT_AND_OUTPUT) {\n expect(\n addSelectGenericsToGeneratedTypes({\n compiledGeneratedTypes: input,\n }),\n ).toStrictEqual(output)\n }\n })\n})\n"],"names":["addSelectGenericsToGeneratedTypes","INPUT_AND_OUTPUT","input","output","describe","it","expect","compiledGeneratedTypes","toStrictEqual"],"mappings":"AAAA,SAASA,iCAAiC,QAAQ,yCAAwC;AAE1F,MAAMC,mBAAmB;IACvB;QACEC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiRZ,CAAC;QACGC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiRb,CAAC;IACC;CACD;AAEDC,SAAS,qCAAqC;IAC5CC,GAAG,kDAAkD;QACnD,KAAK,MAAM,EAAEH,KAAK,EAAEC,MAAM,EAAE,IAAIF,iBAAkB;YAChDK,OACEN,kCAAkC;gBAChCO,wBAAwBL;YAC1B,IACAM,aAAa,CAACL;QAClB;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/addSelectGenericsToGeneratedTypes.spec.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport { addSelectGenericsToGeneratedTypes } from './addSelectGenericsToGeneretedTypes.js'\n\nconst INPUT_AND_OUTPUT = [\n {\n input: `\n/* tslint:disable */\n/* eslint-disable */\n/**\n * This file was automatically generated by Payload.\n * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,\n * and re-run \\`payload generate:types\\` to regenerate this file.\n */\n\nexport interface Config {\n auth: {\n users: UserAuthOperations;\n };\n collections: {\n posts: Post;\n users: User;\n 'payload-locked-documents': PayloadLockedDocument;\n 'payload-preferences': PayloadPreference;\n 'payload-migrations': PayloadMigration;\n };\n collectionsSelect: {\n posts: PostsSelect;\n users: UsersSelect;\n 'payload-locked-documents': PayloadLockedDocumentsSelect;\n 'payload-preferences': PayloadPreferencesSelect;\n 'payload-migrations': PayloadMigrationsSelect;\n };\n db: {\n defaultIDType: string;\n };\n globals: {};\n globalsSelect: {};\n locale: null;\n user: User & {\n collection: 'users';\n };\n}\nexport interface UserAuthOperations {\n forgotPassword: {\n email: string;\n password: string;\n };\n login: {\n email: string;\n password: string;\n };\n registerFirstUser: {\n email: string;\n password: string;\n };\n unlock: {\n email: string;\n password: string;\n };\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts\".\n */\nexport interface Post {\n id: string;\n text?: string | null;\n number?: number | null;\n group?: {\n text?: string | null;\n number?: number | null;\n };\n array?:\n | {\n text?: string | null;\n number?: number | null;\n id?: string | null;\n }[]\n | null;\n blocks?:\n | (\n | {\n text?: string | null;\n introText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'intro';\n }\n | {\n text?: string | null;\n ctaText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'cta';\n }\n )[]\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users\".\n */\nexport interface User {\n id: string;\n updatedAt: string;\n createdAt: string;\n email: string;\n resetPasswordToken?: string | null;\n resetPasswordExpiration?: string | null;\n salt?: string | null;\n hash?: string | null;\n loginAttempts?: number | null;\n lockUntil?: string | null;\n password?: string | null;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents\".\n */\nexport interface PayloadLockedDocument {\n id: string;\n document?:\n | ({\n relationTo: 'posts';\n value: string | Post;\n } | null)\n | ({\n relationTo: 'users';\n value: string | User;\n } | null);\n globalSlug?: string | null;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences\".\n */\nexport interface PayloadPreference {\n id: string;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n key?: string | null;\n value?:\n | {\n [k: string]: unknown;\n }\n | unknown[]\n | string\n | number\n | boolean\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations\".\n */\nexport interface PayloadMigration {\n id: string;\n name?: string | null;\n batch?: number | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts_select\".\n */\nexport interface PostsSelect {\n text?: boolean;\n number?: boolean;\n sharedGroup?: boolean | SharedGroup;\n group?:\n | boolean\n | {\n text?: boolean;\n number?: boolean;\n };\n array?:\n | boolean\n | {\n text?: boolean;\n number?: boolean;\n id?: boolean;\n };\n blocks?:\n | boolean\n | {\n intro?:\n | boolean\n | {\n text?: boolean;\n introText?: boolean;\n id?: boolean;\n blockName?: boolean;\n };\n cta?:\n | boolean\n | {\n text?: boolean;\n ctaText?: boolean;\n id?: boolean;\n blockName?: boolean;\n };\n };\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users_select\".\n */\nexport interface UsersSelect {\n updatedAt?: boolean;\n createdAt?: boolean;\n email?: boolean;\n resetPasswordToken?: boolean;\n resetPasswordExpiration?: boolean;\n salt?: boolean;\n hash?: boolean;\n loginAttempts?: boolean;\n lockUntil?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents_select\".\n */\nexport interface PayloadLockedDocumentsSelect {\n document?: boolean;\n globalSlug?: boolean;\n user?: boolean;\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences_select\".\n */\nexport interface PayloadPreferencesSelect {\n user?: boolean;\n key?: boolean;\n value?: boolean;\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations_select\".\n */\nexport interface PayloadMigrationsSelect {\n name?: boolean;\n batch?: boolean;\n updatedAt?: boolean;\n createdAt?: boolean;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"auth\".\n */\nexport interface Auth {\n [k: string]: unknown;\n}\n\n\ndeclare module 'payload' {\n // @ts-ignore\n export interface GeneratedTypes extends Config {}\n}\n`,\n output: `\n/* tslint:disable */\n/* eslint-disable */\n/**\n * This file was automatically generated by Payload.\n * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,\n * and re-run \\`payload generate:types\\` to regenerate this file.\n */\n\nexport interface Config {\n auth: {\n users: UserAuthOperations;\n };\n collections: {\n posts: Post;\n users: User;\n 'payload-locked-documents': PayloadLockedDocument;\n 'payload-preferences': PayloadPreference;\n 'payload-migrations': PayloadMigration;\n };\n collectionsSelect: {\n posts: PostsSelect<false> | PostsSelect<true>;\n users: UsersSelect<false> | UsersSelect<true>;\n 'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;\n 'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;\n 'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;\n };\n db: {\n defaultIDType: string;\n };\n globals: {};\n globalsSelect: {};\n locale: null;\n user: User & {\n collection: 'users';\n };\n}\nexport interface UserAuthOperations {\n forgotPassword: {\n email: string;\n password: string;\n };\n login: {\n email: string;\n password: string;\n };\n registerFirstUser: {\n email: string;\n password: string;\n };\n unlock: {\n email: string;\n password: string;\n };\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts\".\n */\nexport interface Post {\n id: string;\n text?: string | null;\n number?: number | null;\n group?: {\n text?: string | null;\n number?: number | null;\n };\n array?:\n | {\n text?: string | null;\n number?: number | null;\n id?: string | null;\n }[]\n | null;\n blocks?:\n | (\n | {\n text?: string | null;\n introText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'intro';\n }\n | {\n text?: string | null;\n ctaText?: string | null;\n id?: string | null;\n blockName?: string | null;\n blockType: 'cta';\n }\n )[]\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users\".\n */\nexport interface User {\n id: string;\n updatedAt: string;\n createdAt: string;\n email: string;\n resetPasswordToken?: string | null;\n resetPasswordExpiration?: string | null;\n salt?: string | null;\n hash?: string | null;\n loginAttempts?: number | null;\n lockUntil?: string | null;\n password?: string | null;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents\".\n */\nexport interface PayloadLockedDocument {\n id: string;\n document?:\n | ({\n relationTo: 'posts';\n value: string | Post;\n } | null)\n | ({\n relationTo: 'users';\n value: string | User;\n } | null);\n globalSlug?: string | null;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences\".\n */\nexport interface PayloadPreference {\n id: string;\n user: {\n relationTo: 'users';\n value: string | User;\n };\n key?: string | null;\n value?:\n | {\n [k: string]: unknown;\n }\n | unknown[]\n | string\n | number\n | boolean\n | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations\".\n */\nexport interface PayloadMigration {\n id: string;\n name?: string | null;\n batch?: number | null;\n updatedAt: string;\n createdAt: string;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"posts_select\".\n */\nexport interface PostsSelect<T extends boolean = true> {\n text?: T;\n number?: T;\n sharedGroup?: T | SharedGroup<T>;\n group?:\n | T\n | {\n text?: T;\n number?: T;\n };\n array?:\n | T\n | {\n text?: T;\n number?: T;\n id?: T;\n };\n blocks?:\n | T\n | {\n intro?:\n | T\n | {\n text?: T;\n introText?: T;\n id?: T;\n blockName?: T;\n };\n cta?:\n | T\n | {\n text?: T;\n ctaText?: T;\n id?: T;\n blockName?: T;\n };\n };\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"users_select\".\n */\nexport interface UsersSelect<T extends boolean = true> {\n updatedAt?: T;\n createdAt?: T;\n email?: T;\n resetPasswordToken?: T;\n resetPasswordExpiration?: T;\n salt?: T;\n hash?: T;\n loginAttempts?: T;\n lockUntil?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-locked-documents_select\".\n */\nexport interface PayloadLockedDocumentsSelect<T extends boolean = true> {\n document?: T;\n globalSlug?: T;\n user?: T;\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-preferences_select\".\n */\nexport interface PayloadPreferencesSelect<T extends boolean = true> {\n user?: T;\n key?: T;\n value?: T;\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"payload-migrations_select\".\n */\nexport interface PayloadMigrationsSelect<T extends boolean = true> {\n name?: T;\n batch?: T;\n updatedAt?: T;\n createdAt?: T;\n}\n/**\n * This interface was referenced by \\`Config\\`'s JSON-Schema\n * via the \\`definition\\` \"auth\".\n */\nexport interface Auth {\n [k: string]: unknown;\n}\n\n\ndeclare module 'payload' {\n // @ts-ignore\n export interface GeneratedTypes extends Config {}\n}\n`,\n },\n]\n\ndescribe('addSelectGenericsToGeneratedTypes', () => {\n it('should match return of given input with output', () => {\n for (const { input, output } of INPUT_AND_OUTPUT) {\n expect(\n addSelectGenericsToGeneratedTypes({\n compiledGeneratedTypes: input,\n }),\n ).toStrictEqual(output)\n }\n })\n})\n"],"names":["describe","it","expect","addSelectGenericsToGeneratedTypes","INPUT_AND_OUTPUT","input","output","compiledGeneratedTypes","toStrictEqual"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,SAAQ;AAC7C,SAASC,iCAAiC,QAAQ,yCAAwC;AAE1F,MAAMC,mBAAmB;IACvB;QACEC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiRZ,CAAC;QACGC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiRb,CAAC;IACC;CACD;AAEDN,SAAS,qCAAqC;IAC5CC,GAAG,kDAAkD;QACnD,KAAK,MAAM,EAAEI,KAAK,EAAEC,MAAM,EAAE,IAAIF,iBAAkB;YAChDF,OACEC,kCAAkC;gBAChCI,wBAAwBF;YAC1B,IACAG,aAAa,CAACF;QAClB;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/combineWhereConstraints.spec.ts"],"sourcesContent":["import { Where } from '../types/index.js'\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\n\ndescribe('combineWhereConstraints', () => {\n it('should merge matching constraint keys', async () => {\n const constraint: Where = {\n test: {\n equals: 'value',\n },\n }\n\n // should merge and queries\n const andConstraint: Where = {\n and: [constraint],\n }\n expect(combineWhereConstraints([andConstraint], 'and')).toEqual(andConstraint)\n // should merge multiple and queries\n expect(combineWhereConstraints([andConstraint, andConstraint], 'and')).toEqual({\n and: [constraint, constraint],\n })\n\n // should merge or queries\n const orConstraint: Where = {\n or: [constraint],\n }\n expect(combineWhereConstraints([orConstraint], 'or')).toEqual(orConstraint)\n // should merge multiple or queries\n expect(combineWhereConstraints([orConstraint, orConstraint], 'or')).toEqual({\n or: [constraint, constraint],\n })\n })\n\n it('should push mismatching constraints keys into `as` key', async () => {\n const constraint: Where = {\n test: {\n equals: 'value',\n },\n }\n\n // should push `and` into `or` key\n const andConstraint: Where = {\n and: [constraint],\n }\n expect(combineWhereConstraints([andConstraint], 'or')).toEqual({\n or: [andConstraint],\n })\n\n // should push `or` into `and` key\n const orConstraint: Where = {\n or: [constraint],\n }\n expect(combineWhereConstraints([orConstraint], 'and')).toEqual({\n and: [orConstraint],\n })\n\n // should merge `and` but push `or` into `and` key\n expect(combineWhereConstraints([andConstraint, orConstraint], 'and')).toEqual({\n and: [constraint, orConstraint],\n })\n })\n\n it('should push non and/or constraint key into `as` key', async () => {\n const basicConstraint: Where = {\n test: {\n equals: 'value',\n },\n }\n\n expect(combineWhereConstraints([basicConstraint], 'and')).toEqual({\n and: [basicConstraint],\n })\n expect(combineWhereConstraints([basicConstraint], 'or')).toEqual({\n or: [basicConstraint],\n })\n })\n\n it('should return an empty object when no constraints are provided', async () => {\n expect(combineWhereConstraints([], 'and')).toEqual({})\n expect(combineWhereConstraints([], 'or')).toEqual({})\n })\n\n it('should return an empty object when all constraints are empty', async () => {\n expect(combineWhereConstraints([{}, {}, undefined], 'and')).toEqual({})\n expect(combineWhereConstraints([{}, {}, undefined], 'or')).toEqual({})\n })\n})\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/combineWhereConstraints.spec.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport { Where } from '../types/index.js'\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\n\ndescribe('combineWhereConstraints', () => {\n it('should merge matching constraint keys', async () => {\n const constraint: Where = {\n test: {\n equals: 'value',\n },\n }\n\n // should merge and queries\n const andConstraint: Where = {\n and: [constraint],\n }\n expect(combineWhereConstraints([andConstraint], 'and')).toEqual(andConstraint)\n // should merge multiple and queries\n expect(combineWhereConstraints([andConstraint, andConstraint], 'and')).toEqual({\n and: [constraint, constraint],\n })\n\n // should merge or queries\n const orConstraint: Where = {\n or: [constraint],\n }\n expect(combineWhereConstraints([orConstraint], 'or')).toEqual(orConstraint)\n // should merge multiple or queries\n expect(combineWhereConstraints([orConstraint, orConstraint], 'or')).toEqual({\n or: [constraint, constraint],\n })\n })\n\n it('should push mismatching constraints keys into `as` key', async () => {\n const constraint: Where = {\n test: {\n equals: 'value',\n },\n }\n\n // should push `and` into `or` key\n const andConstraint: Where = {\n and: [constraint],\n }\n expect(combineWhereConstraints([andConstraint], 'or')).toEqual({\n or: [andConstraint],\n })\n\n // should push `or` into `and` key\n const orConstraint: Where = {\n or: [constraint],\n }\n expect(combineWhereConstraints([orConstraint], 'and')).toEqual({\n and: [orConstraint],\n })\n\n // should merge `and` but push `or` into `and` key\n expect(combineWhereConstraints([andConstraint, orConstraint], 'and')).toEqual({\n and: [constraint, orConstraint],\n })\n })\n\n it('should push non and/or constraint key into `as` key', async () => {\n const basicConstraint: Where = {\n test: {\n equals: 'value',\n },\n }\n\n expect(combineWhereConstraints([basicConstraint], 'and')).toEqual({\n and: [basicConstraint],\n })\n expect(combineWhereConstraints([basicConstraint], 'or')).toEqual({\n or: [basicConstraint],\n })\n })\n\n it('should return an empty object when no constraints are provided', async () => {\n expect(combineWhereConstraints([], 'and')).toEqual({})\n expect(combineWhereConstraints([], 'or')).toEqual({})\n })\n\n it('should return an empty object when all constraints are empty', async () => {\n expect(combineWhereConstraints([{}, {}, undefined], 'and')).toEqual({})\n expect(combineWhereConstraints([{}, {}, undefined], 'or')).toEqual({})\n })\n})\n"],"names":["describe","it","expect","combineWhereConstraints","constraint","test","equals","andConstraint","and","toEqual","orConstraint","or","basicConstraint","undefined"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,SAAQ;AAE7C,SAASC,uBAAuB,QAAQ,+BAA8B;AAEtEH,SAAS,2BAA2B;IAClCC,GAAG,yCAAyC;QAC1C,MAAMG,aAAoB;YACxBC,MAAM;gBACJC,QAAQ;YACV;QACF;QAEA,2BAA2B;QAC3B,MAAMC,gBAAuB;YAC3BC,KAAK;gBAACJ;aAAW;QACnB;QACAF,OAAOC,wBAAwB;YAACI;SAAc,EAAE,QAAQE,OAAO,CAACF;QAChE,oCAAoC;QACpCL,OAAOC,wBAAwB;YAACI;YAAeA;SAAc,EAAE,QAAQE,OAAO,CAAC;YAC7ED,KAAK;gBAACJ;gBAAYA;aAAW;QAC/B;QAEA,0BAA0B;QAC1B,MAAMM,eAAsB;YAC1BC,IAAI;gBAACP;aAAW;QAClB;QACAF,OAAOC,wBAAwB;YAACO;SAAa,EAAE,OAAOD,OAAO,CAACC;QAC9D,mCAAmC;QACnCR,OAAOC,wBAAwB;YAACO;YAAcA;SAAa,EAAE,OAAOD,OAAO,CAAC;YAC1EE,IAAI;gBAACP;gBAAYA;aAAW;QAC9B;IACF;IAEAH,GAAG,0DAA0D;QAC3D,MAAMG,aAAoB;YACxBC,MAAM;gBACJC,QAAQ;YACV;QACF;QAEA,kCAAkC;QAClC,MAAMC,gBAAuB;YAC3BC,KAAK;gBAACJ;aAAW;QACnB;QACAF,OAAOC,wBAAwB;YAACI;SAAc,EAAE,OAAOE,OAAO,CAAC;YAC7DE,IAAI;gBAACJ;aAAc;QACrB;QAEA,kCAAkC;QAClC,MAAMG,eAAsB;YAC1BC,IAAI;gBAACP;aAAW;QAClB;QACAF,OAAOC,wBAAwB;YAACO;SAAa,EAAE,QAAQD,OAAO,CAAC;YAC7DD,KAAK;gBAACE;aAAa;QACrB;QAEA,kDAAkD;QAClDR,OAAOC,wBAAwB;YAACI;YAAeG;SAAa,EAAE,QAAQD,OAAO,CAAC;YAC5ED,KAAK;gBAACJ;gBAAYM;aAAa;QACjC;IACF;IAEAT,GAAG,uDAAuD;QACxD,MAAMW,kBAAyB;YAC7BP,MAAM;gBACJC,QAAQ;YACV;QACF;QAEAJ,OAAOC,wBAAwB;YAACS;SAAgB,EAAE,QAAQH,OAAO,CAAC;YAChED,KAAK;gBAACI;aAAgB;QACxB;QACAV,OAAOC,wBAAwB;YAACS;SAAgB,EAAE,OAAOH,OAAO,CAAC;YAC/DE,IAAI;gBAACC;aAAgB;QACvB;IACF;IAEAX,GAAG,kEAAkE;QACnEC,OAAOC,wBAAwB,EAAE,EAAE,QAAQM,OAAO,CAAC,CAAC;QACpDP,OAAOC,wBAAwB,EAAE,EAAE,OAAOM,OAAO,CAAC,CAAC;IACrD;IAEAR,GAAG,gEAAgE;QACjEC,OAAOC,wBAAwB;YAAC,CAAC;YAAG,CAAC;YAAGU;SAAU,EAAE,QAAQJ,OAAO,CAAC,CAAC;QACrEP,OAAOC,wBAAwB;YAAC,CAAC;YAAG,CAAC;YAAGU;SAAU,EAAE,OAAOJ,OAAO,CAAC,CAAC;IACtE;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/configToJSONSchema.spec.ts"],"sourcesContent":["import type { JSONSchema4 } from 'json-schema'\n\nimport type { Config } from '../config/types.js'\n\nimport { sanitizeConfig } from '../config/sanitize.js'\nimport { configToJSONSchema } from './configToJSONSchema.js'\nimport type { Block, BlocksField, RichTextField } from '../fields/config/types.js'\n\ndescribe('configToJSONSchema', () => {\n it('should handle optional arrays with required fields', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'someRequiredField',\n type: 'array',\n fields: [\n {\n name: 'someRequiredField',\n type: 'text',\n required: true,\n },\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n someRequiredField: {\n type: ['array', 'null'],\n items: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: ['string', 'null'],\n },\n someRequiredField: {\n type: 'string',\n },\n },\n required: ['someRequiredField'],\n },\n },\n },\n required: ['id'],\n title: 'Test',\n })\n })\n\n it('should handle block fields with no blocks', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'blockField',\n type: 'blocks',\n blocks: [],\n },\n {\n name: 'blockFieldRequired',\n type: 'blocks',\n blocks: [],\n required: true,\n },\n {\n name: 'blockFieldWithFields',\n type: 'blocks',\n blocks: [\n {\n slug: 'test',\n fields: [\n {\n name: 'field',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n name: 'blockFieldWithFieldsRequired',\n type: 'blocks',\n blocks: [\n {\n slug: 'test',\n fields: [\n {\n name: 'field',\n type: 'text',\n required: true,\n },\n ],\n },\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n blockField: {\n type: ['array', 'null'],\n items: {},\n },\n blockFieldRequired: {\n type: 'array',\n items: {},\n },\n blockFieldWithFields: {\n type: ['array', 'null'],\n items: {\n oneOf: [\n {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: ['string', 'null'],\n },\n blockName: {\n type: ['string', 'null'],\n },\n blockType: {\n const: 'test',\n },\n field: {\n type: ['string', 'null'],\n },\n },\n required: ['blockType'],\n },\n ],\n },\n },\n blockFieldWithFieldsRequired: {\n type: ['array', 'null'],\n items: {\n oneOf: [\n {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: ['string', 'null'],\n },\n blockName: {\n type: ['string', 'null'],\n },\n blockType: {\n const: 'test',\n },\n field: {\n type: 'string',\n },\n },\n required: ['blockType', 'field'],\n },\n ],\n },\n },\n },\n required: ['id', 'blockFieldRequired'],\n title: 'Test',\n })\n })\n\n it('should handle tabs and named tabs with required fields', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n type: 'tabs',\n tabs: [\n {\n fields: [\n {\n name: 'fieldInUnnamedTab',\n type: 'text',\n },\n ],\n label: 'unnamedTab',\n },\n {\n name: 'namedTab',\n fields: [\n {\n name: 'fieldInNamedTab',\n type: 'text',\n },\n ],\n label: 'namedTab',\n },\n {\n name: 'namedTabWithRequired',\n fields: [\n {\n name: 'fieldInNamedTab',\n type: 'text',\n required: true,\n },\n ],\n label: 'namedTabWithRequired',\n },\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n fieldInUnnamedTab: {\n type: ['string', 'null'],\n },\n namedTab: {\n type: 'object',\n additionalProperties: false,\n properties: {\n fieldInNamedTab: {\n type: ['string', 'null'],\n },\n },\n required: [],\n },\n namedTabWithRequired: {\n type: 'object',\n additionalProperties: false,\n properties: {\n fieldInNamedTab: {\n type: 'string',\n },\n },\n required: ['fieldInNamedTab'],\n },\n },\n required: ['id', 'namedTabWithRequired'],\n title: 'Test',\n })\n })\n\n it('should handle custom typescript schema and JSON field schema', async () => {\n const customSchema: JSONSchema4 = {\n type: 'object',\n properties: {\n id: {\n type: 'number',\n },\n required: ['id'],\n },\n }\n\n const config: Partial<Config> = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'withCustom',\n type: 'text',\n typescriptSchema: [() => customSchema],\n },\n {\n name: 'jsonWithSchema',\n type: 'json',\n jsonSchema: {\n fileMatch: ['a://b/foo.json'],\n schema: customSchema,\n uri: 'a://b/foo.json',\n },\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config as Config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n jsonWithSchema: customSchema,\n withCustom: customSchema,\n },\n required: ['id'],\n title: 'Test',\n })\n })\n\n it('should handle same block object being referenced in both collection and config.blocks', async () => {\n const sharedBlock: Block = {\n slug: 'sharedBlock',\n interfaceName: 'SharedBlock',\n fields: [\n {\n name: 'richText',\n type: 'richText',\n editor: () => {\n // stub rich text editor\n return {\n CellComponent: '',\n FieldComponent: '',\n validate: () => true,\n }\n },\n },\n ],\n }\n\n // @ts-expect-error\n const config: Config = {\n blocks: [sharedBlock],\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'someBlockField',\n type: 'blocks',\n blocks: [sharedBlock],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n // Ensure both rich text editor are sanitized\n const sanitizedConfig = await sanitizeConfig(config)\n expect(typeof (sanitizedConfig?.blocks?.[0]?.fields?.[0] as RichTextField)?.editor).toBe(\n 'object',\n )\n expect(\n typeof (\n (sanitizedConfig.collections[0].fields[0] as BlocksField)?.blocks?.[0]\n ?.fields?.[0] as RichTextField\n )?.editor,\n ).toBe('object')\n\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n title: 'Test',\n properties: {\n id: {\n type: 'string',\n },\n someBlockField: {\n type: ['array', 'null'],\n items: {\n oneOf: [\n {\n $ref: '#/definitions/SharedBlock',\n },\n ],\n },\n },\n },\n required: ['id'],\n })\n\n expect(schema?.definitions?.SharedBlock).toBeDefined()\n })\n\n it('should allow overriding required to false', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n defaultValue: 'test',\n typescriptSchema: [\n () => ({\n type: 'string',\n required: false,\n }),\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n // @ts-expect-error\n expect(schema.definitions.test.properties.title.required).toStrictEqual(false)\n })\n})\n"],"names":["sanitizeConfig","configToJSONSchema","describe","it","config","collections","slug","fields","name","type","required","timestamps","sanitizedConfig","schema","expect","definitions","test","toStrictEqual","additionalProperties","properties","id","someRequiredField","items","title","blocks","blockField","blockFieldRequired","blockFieldWithFields","oneOf","blockName","blockType","const","field","blockFieldWithFieldsRequired","tabs","label","fieldInUnnamedTab","namedTab","fieldInNamedTab","namedTabWithRequired","customSchema","typescriptSchema","jsonSchema","fileMatch","uri","jsonWithSchema","withCustom","sharedBlock","interfaceName","editor","CellComponent","FieldComponent","validate","toBe","someBlockField","$ref","SharedBlock","toBeDefined","defaultValue"],"mappings":"AAIA,SAASA,cAAc,QAAQ,wBAAuB;AACtD,SAASC,kBAAkB,QAAQ,0BAAyB;AAG5DC,SAAS,sBAAsB;IAC7BC,GAAG,sDAAsD;QACvD,mBAAmB;QACnB,MAAMC,SAAiB;YACrBC,aAAa;gBACX;oBACEC,MAAM;oBACNC,QAAQ;wBACN;4BACEC,MAAM;4BACNC,MAAM;4BACNF,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNC,UAAU;gCACZ;6BACD;wBACH;qBACD;oBACDC,YAAY;gBACd;aACD;QACH;QAEA,MAAMC,kBAAkB,MAAMZ,eAAeI;QAC7C,MAAMS,SAASZ,mBAAmBW,iBAAiB;QAEnDE,OAAOD,QAAQE,aAAaC,MAAMC,aAAa,CAAC;YAC9CR,MAAM;YACNS,sBAAsB;YACtBC,YAAY;gBACVC,IAAI;oBACFX,MAAM;gBACR;gBACAY,mBAAmB;oBACjBZ,MAAM;wBAAC;wBAAS;qBAAO;oBACvBa,OAAO;wBACLb,MAAM;wBACNS,sBAAsB;wBACtBC,YAAY;4BACVC,IAAI;gCACFX,MAAM;oCAAC;oCAAU;iCAAO;4BAC1B;4BACAY,mBAAmB;gCACjBZ,MAAM;4BACR;wBACF;wBACAC,UAAU;4BAAC;yBAAoB;oBACjC;gBACF;YACF;YACAA,UAAU;gBAAC;aAAK;YAChBa,OAAO;QACT;IACF;IAEApB,GAAG,6CAA6C;QAC9C,mBAAmB;QACnB,MAAMC,SAAiB;YACrBC,aAAa;gBACX;oBACEC,MAAM;oBACNC,QAAQ;wBACN;4BACEC,MAAM;4BACNC,MAAM;4BACNe,QAAQ,EAAE;wBACZ;wBACA;4BACEhB,MAAM;4BACNC,MAAM;4BACNe,QAAQ,EAAE;4BACVd,UAAU;wBACZ;wBACA;4BACEF,MAAM;4BACNC,MAAM;4BACNe,QAAQ;gCACN;oCACElB,MAAM;oCACNC,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;wCACR;qCACD;gCACH;6BACD;wBACH;wBACA;4BACED,MAAM;4BACNC,MAAM;4BACNe,QAAQ;gCACN;oCACElB,MAAM;oCACNC,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNC,UAAU;wCACZ;qCACD;gCACH;6BACD;wBACH;qBACD;oBACDC,YAAY;gBACd;aACD;QACH;QAEA,MAAMC,kBAAkB,MAAMZ,eAAeI;QAC7C,MAAMS,SAASZ,mBAAmBW,iBAAiB;QAEnDE,OAAOD,QAAQE,aAAaC,MAAMC,aAAa,CAAC;YAC9CR,MAAM;YACNS,sBAAsB;YACtBC,YAAY;gBACVC,IAAI;oBACFX,MAAM;gBACR;gBACAgB,YAAY;oBACVhB,MAAM;wBAAC;wBAAS;qBAAO;oBACvBa,OAAO,CAAC;gBACV;gBACAI,oBAAoB;oBAClBjB,MAAM;oBACNa,OAAO,CAAC;gBACV;gBACAK,sBAAsB;oBACpBlB,MAAM;wBAAC;wBAAS;qBAAO;oBACvBa,OAAO;wBACLM,OAAO;4BACL;gCACEnB,MAAM;gCACNS,sBAAsB;gCACtBC,YAAY;oCACVC,IAAI;wCACFX,MAAM;4CAAC;4CAAU;yCAAO;oCAC1B;oCACAoB,WAAW;wCACTpB,MAAM;4CAAC;4CAAU;yCAAO;oCAC1B;oCACAqB,WAAW;wCACTC,OAAO;oCACT;oCACAC,OAAO;wCACLvB,MAAM;4CAAC;4CAAU;yCAAO;oCAC1B;gCACF;gCACAC,UAAU;oCAAC;iCAAY;4BACzB;yBACD;oBACH;gBACF;gBACAuB,8BAA8B;oBAC5BxB,MAAM;wBAAC;wBAAS;qBAAO;oBACvBa,OAAO;wBACLM,OAAO;4BACL;gCACEnB,MAAM;gCACNS,sBAAsB;gCACtBC,YAAY;oCACVC,IAAI;wCACFX,MAAM;4CAAC;4CAAU;yCAAO;oCAC1B;oCACAoB,WAAW;wCACTpB,MAAM;4CAAC;4CAAU;yCAAO;oCAC1B;oCACAqB,WAAW;wCACTC,OAAO;oCACT;oCACAC,OAAO;wCACLvB,MAAM;oCACR;gCACF;gCACAC,UAAU;oCAAC;oCAAa;iCAAQ;4BAClC;yBACD;oBACH;gBACF;YACF;YACAA,UAAU;gBAAC;gBAAM;aAAqB;YACtCa,OAAO;QACT;IACF;IAEApB,GAAG,0DAA0D;QAC3D,mBAAmB;QACnB,MAAMC,SAAiB;YACrBC,aAAa;gBACX;oBACEC,MAAM;oBACNC,QAAQ;wBACN;4BACEE,MAAM;4BACNyB,MAAM;gCACJ;oCACE3B,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;wCACR;qCACD;oCACD0B,OAAO;gCACT;gCACA;oCACE3B,MAAM;oCACND,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;wCACR;qCACD;oCACD0B,OAAO;gCACT;gCACA;oCACE3B,MAAM;oCACND,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNC,UAAU;wCACZ;qCACD;oCACDyB,OAAO;gCACT;6BACD;wBACH;qBACD;oBACDxB,YAAY;gBACd;aACD;QACH;QAEA,MAAMC,kBAAkB,MAAMZ,eAAeI;QAC7C,MAAMS,SAASZ,mBAAmBW,iBAAiB;QAEnDE,OAAOD,QAAQE,aAAaC,MAAMC,aAAa,CAAC;YAC9CR,MAAM;YACNS,sBAAsB;YACtBC,YAAY;gBACVC,IAAI;oBACFX,MAAM;gBACR;gBACA2B,mBAAmB;oBACjB3B,MAAM;wBAAC;wBAAU;qBAAO;gBAC1B;gBACA4B,UAAU;oBACR5B,MAAM;oBACNS,sBAAsB;oBACtBC,YAAY;wBACVmB,iBAAiB;4BACf7B,MAAM;gCAAC;gCAAU;6BAAO;wBAC1B;oBACF;oBACAC,UAAU,EAAE;gBACd;gBACA6B,sBAAsB;oBACpB9B,MAAM;oBACNS,sBAAsB;oBACtBC,YAAY;wBACVmB,iBAAiB;4BACf7B,MAAM;wBACR;oBACF;oBACAC,UAAU;wBAAC;qBAAkB;gBAC/B;YACF;YACAA,UAAU;gBAAC;gBAAM;aAAuB;YACxCa,OAAO;QACT;IACF;IAEApB,GAAG,gEAAgE;QACjE,MAAMqC,eAA4B;YAChC/B,MAAM;YACNU,YAAY;gBACVC,IAAI;oBACFX,MAAM;gBACR;gBACAC,UAAU;oBAAC;iBAAK;YAClB;QACF;QAEA,MAAMN,SAA0B;YAC9BC,aAAa;gBACX;oBACEC,MAAM;oBACNC,QAAQ;wBACN;4BACEC,MAAM;4BACNC,MAAM;4BACNgC,kBAAkB;gCAAC,IAAMD;6BAAa;wBACxC;wBACA;4BACEhC,MAAM;4BACNC,MAAM;4BACNiC,YAAY;gCACVC,WAAW;oCAAC;iCAAiB;gCAC7B9B,QAAQ2B;gCACRI,KAAK;4BACP;wBACF;qBACD;oBACDjC,YAAY;gBACd;aACD;QACH;QAEA,MAAMC,kBAAkB,MAAMZ,eAAeI;QAC7C,MAAMS,SAASZ,mBAAmBW,iBAAiB;QAEnDE,OAAOD,QAAQE,aAAaC,MAAMC,aAAa,CAAC;YAC9CR,MAAM;YACNS,sBAAsB;YACtBC,YAAY;gBACVC,IAAI;oBACFX,MAAM;gBACR;gBACAoC,gBAAgBL;gBAChBM,YAAYN;YACd;YACA9B,UAAU;gBAAC;aAAK;YAChBa,OAAO;QACT;IACF;IAEApB,GAAG,yFAAyF;QAC1F,MAAM4C,cAAqB;YACzBzC,MAAM;YACN0C,eAAe;YACfzC,QAAQ;gBACN;oBACEC,MAAM;oBACNC,MAAM;oBACNwC,QAAQ;wBACN,wBAAwB;wBACxB,OAAO;4BACLC,eAAe;4BACfC,gBAAgB;4BAChBC,UAAU,IAAM;wBAClB;oBACF;gBACF;aACD;QACH;QAEA,mBAAmB;QACnB,MAAMhD,SAAiB;YACrBoB,QAAQ;gBAACuB;aAAY;YACrB1C,aAAa;gBACX;oBACEC,MAAM;oBACNC,QAAQ;wBACN;4BACEC,MAAM;4BACNC,MAAM;4BACNe,QAAQ;gCAACuB;6BAAY;wBACvB;qBACD;oBACDpC,YAAY;gBACd;aACD;QACH;QAEA,6CAA6C;QAC7C,MAAMC,kBAAkB,MAAMZ,eAAeI;QAC7CU,OAAO,OAAQF,iBAAiBY,QAAQ,CAAC,EAAE,EAAEjB,QAAQ,CAAC,EAAE,EAAoB0C,QAAQI,IAAI,CACtF;QAEFvC,OACE,OACGF,gBAAgBP,WAAW,CAAC,EAAE,CAACE,MAAM,CAAC,EAAE,EAAkBiB,QAAQ,CAAC,EAAE,EAClEjB,QAAQ,CAAC,EAAE,EACd0C,QACHI,IAAI,CAAC;QAEP,MAAMxC,SAASZ,mBAAmBW,iBAAiB;QAEnDE,OAAOD,QAAQE,aAAaC,MAAMC,aAAa,CAAC;YAC9CR,MAAM;YACNS,sBAAsB;YACtBK,OAAO;YACPJ,YAAY;gBACVC,IAAI;oBACFX,MAAM;gBACR;gBACA6C,gBAAgB;oBACd7C,MAAM;wBAAC;wBAAS;qBAAO;oBACvBa,OAAO;wBACLM,OAAO;4BACL;gCACE2B,MAAM;4BACR;yBACD;oBACH;gBACF;YACF;YACA7C,UAAU;gBAAC;aAAK;QAClB;QAEAI,OAAOD,QAAQE,aAAayC,aAAaC,WAAW;IACtD;IAEAtD,GAAG,6CAA6C;QAC9C,mBAAmB;QACnB,MAAMC,SAAiB;YACrBC,aAAa;gBACX;oBACEC,MAAM;oBACNC,QAAQ;wBACN;4BACEC,MAAM;4BACNC,MAAM;4BACNC,UAAU;4BACVgD,cAAc;4BACdjB,kBAAkB;gCAChB,IAAO,CAAA;wCACLhC,MAAM;wCACNC,UAAU;oCACZ,CAAA;6BACD;wBACH;qBACD;oBACDC,YAAY;gBACd;aACD;QACH;QAEA,MAAMC,kBAAkB,MAAMZ,eAAeI;QAC7C,MAAMS,SAASZ,mBAAmBW,iBAAiB;QAEnD,mBAAmB;QACnBE,OAAOD,OAAOE,WAAW,CAACC,IAAI,CAACG,UAAU,CAACI,KAAK,CAACb,QAAQ,EAAEO,aAAa,CAAC;IAC1E;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/configToJSONSchema.spec.ts"],"sourcesContent":["import type { JSONSchema4 } from 'json-schema'\nimport { describe, it, expect } from 'vitest'\n\nimport type { Config } from '../config/types.js'\n\nimport { sanitizeConfig } from '../config/sanitize.js'\nimport { configToJSONSchema } from './configToJSONSchema.js'\nimport type { Block, BlocksField, RichTextField } from '../fields/config/types.js'\n\ndescribe('configToJSONSchema', () => {\n it('should handle optional arrays with required fields', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'someRequiredField',\n type: 'array',\n fields: [\n {\n name: 'someRequiredField',\n type: 'text',\n required: true,\n },\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n someRequiredField: {\n type: ['array', 'null'],\n items: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: ['string', 'null'],\n },\n someRequiredField: {\n type: 'string',\n },\n },\n required: ['someRequiredField'],\n },\n },\n },\n required: ['id'],\n title: 'Test',\n })\n })\n\n it('should handle block fields with no blocks', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'blockField',\n type: 'blocks',\n blocks: [],\n },\n {\n name: 'blockFieldRequired',\n type: 'blocks',\n blocks: [],\n required: true,\n },\n {\n name: 'blockFieldWithFields',\n type: 'blocks',\n blocks: [\n {\n slug: 'test',\n fields: [\n {\n name: 'field',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n name: 'blockFieldWithFieldsRequired',\n type: 'blocks',\n blocks: [\n {\n slug: 'test',\n fields: [\n {\n name: 'field',\n type: 'text',\n required: true,\n },\n ],\n },\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n blockField: {\n type: ['array', 'null'],\n items: {},\n },\n blockFieldRequired: {\n type: 'array',\n items: {},\n },\n blockFieldWithFields: {\n type: ['array', 'null'],\n items: {\n oneOf: [\n {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: ['string', 'null'],\n },\n blockName: {\n type: ['string', 'null'],\n },\n blockType: {\n const: 'test',\n },\n field: {\n type: ['string', 'null'],\n },\n },\n required: ['blockType'],\n },\n ],\n },\n },\n blockFieldWithFieldsRequired: {\n type: ['array', 'null'],\n items: {\n oneOf: [\n {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: ['string', 'null'],\n },\n blockName: {\n type: ['string', 'null'],\n },\n blockType: {\n const: 'test',\n },\n field: {\n type: 'string',\n },\n },\n required: ['blockType', 'field'],\n },\n ],\n },\n },\n },\n required: ['id', 'blockFieldRequired'],\n title: 'Test',\n })\n })\n\n it('should handle tabs and named tabs with required fields', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n type: 'tabs',\n tabs: [\n {\n fields: [\n {\n name: 'fieldInUnnamedTab',\n type: 'text',\n },\n ],\n label: 'unnamedTab',\n },\n {\n name: 'namedTab',\n fields: [\n {\n name: 'fieldInNamedTab',\n type: 'text',\n },\n ],\n label: 'namedTab',\n },\n {\n name: 'namedTabWithRequired',\n fields: [\n {\n name: 'fieldInNamedTab',\n type: 'text',\n required: true,\n },\n ],\n label: 'namedTabWithRequired',\n },\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n fieldInUnnamedTab: {\n type: ['string', 'null'],\n },\n namedTab: {\n type: 'object',\n additionalProperties: false,\n properties: {\n fieldInNamedTab: {\n type: ['string', 'null'],\n },\n },\n required: [],\n },\n namedTabWithRequired: {\n type: 'object',\n additionalProperties: false,\n properties: {\n fieldInNamedTab: {\n type: 'string',\n },\n },\n required: ['fieldInNamedTab'],\n },\n },\n required: ['id', 'namedTabWithRequired'],\n title: 'Test',\n })\n })\n\n it('should handle custom typescript schema and JSON field schema', async () => {\n const customSchema: JSONSchema4 = {\n type: 'object',\n properties: {\n id: {\n type: 'number',\n },\n required: ['id'],\n },\n }\n\n const config: Partial<Config> = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'withCustom',\n type: 'text',\n typescriptSchema: [() => customSchema],\n },\n {\n name: 'jsonWithSchema',\n type: 'json',\n jsonSchema: {\n fileMatch: ['a://b/foo.json'],\n schema: customSchema,\n uri: 'a://b/foo.json',\n },\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config as Config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n properties: {\n id: {\n type: 'string',\n },\n jsonWithSchema: customSchema,\n withCustom: customSchema,\n },\n required: ['id'],\n title: 'Test',\n })\n })\n\n it('should handle same block object being referenced in both collection and config.blocks', async () => {\n const sharedBlock: Block = {\n slug: 'sharedBlock',\n interfaceName: 'SharedBlock',\n fields: [\n {\n name: 'richText',\n type: 'richText',\n editor: () => {\n // stub rich text editor\n return {\n CellComponent: '',\n FieldComponent: '',\n validate: () => true,\n }\n },\n },\n ],\n }\n\n // @ts-expect-error\n const config: Config = {\n blocks: [sharedBlock],\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'someBlockField',\n type: 'blocks',\n blocks: [sharedBlock],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n // Ensure both rich text editor are sanitized\n const sanitizedConfig = await sanitizeConfig(config)\n expect(typeof (sanitizedConfig?.blocks?.[0]?.fields?.[0] as RichTextField)?.editor).toBe(\n 'object',\n )\n expect(\n typeof (\n (sanitizedConfig.collections[0].fields[0] as BlocksField)?.blocks?.[0]\n ?.fields?.[0] as RichTextField\n )?.editor,\n ).toBe('object')\n\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n expect(schema?.definitions?.test).toStrictEqual({\n type: 'object',\n additionalProperties: false,\n title: 'Test',\n properties: {\n id: {\n type: 'string',\n },\n someBlockField: {\n type: ['array', 'null'],\n items: {\n oneOf: [\n {\n $ref: '#/definitions/SharedBlock',\n },\n ],\n },\n },\n },\n required: ['id'],\n })\n\n expect(schema?.definitions?.SharedBlock).toBeDefined()\n })\n\n it('should allow overriding required to false', async () => {\n // @ts-expect-error\n const config: Config = {\n collections: [\n {\n slug: 'test',\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n defaultValue: 'test',\n typescriptSchema: [\n () => ({\n type: 'string',\n required: false,\n }),\n ],\n },\n ],\n timestamps: false,\n },\n ],\n }\n\n const sanitizedConfig = await sanitizeConfig(config)\n const schema = configToJSONSchema(sanitizedConfig, 'text')\n\n // @ts-expect-error\n expect(schema.definitions.test.properties.title.required).toStrictEqual(false)\n })\n})\n"],"names":["describe","it","expect","sanitizeConfig","configToJSONSchema","config","collections","slug","fields","name","type","required","timestamps","sanitizedConfig","schema","definitions","test","toStrictEqual","additionalProperties","properties","id","someRequiredField","items","title","blocks","blockField","blockFieldRequired","blockFieldWithFields","oneOf","blockName","blockType","const","field","blockFieldWithFieldsRequired","tabs","label","fieldInUnnamedTab","namedTab","fieldInNamedTab","namedTabWithRequired","customSchema","typescriptSchema","jsonSchema","fileMatch","uri","jsonWithSchema","withCustom","sharedBlock","interfaceName","editor","CellComponent","FieldComponent","validate","toBe","someBlockField","$ref","SharedBlock","toBeDefined","defaultValue"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/flattenTopLevelFields.spec.ts"],"sourcesContent":["import { I18nClient } from '@payloadcms/translations'\nimport { ClientField } from '../fields/config/client.js'\nimport { flattenTopLevelFields } from './flattenTopLevelFields.js'\n\ndescribe('flattenFields', () => {\n const i18n: I18nClient = {\n t: (value: string) => value,\n language: 'en',\n dateFNS: {} as any,\n dateFNSKey: 'en-US',\n fallbackLanguage: 'en',\n translations: {},\n }\n\n const baseField: ClientField = {\n type: 'text',\n name: 'title',\n label: 'Title',\n }\n\n describe('basic flattening', () => {\n it('should return flat list for top-level fields', () => {\n const fields = [baseField]\n const result = flattenTopLevelFields(fields)\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('title')\n })\n })\n\n describe('group flattening', () => {\n it('should flatten fields inside group with accessor and labelWithPrefix with moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n name: 'meta',\n label: 'Meta Info',\n fields: [\n {\n type: 'text',\n name: 'slug',\n label: 'Slug',\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].name).toBe('slug')\n expect(result[1].accessor).toBe('meta.slug')\n expect(result[1].labelWithPrefix).toBe('Meta Info > Slug')\n })\n\n it('should NOT flatten fields inside group without moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n name: 'meta',\n label: 'Meta Info',\n fields: [\n {\n type: 'text',\n name: 'slug',\n label: 'Slug',\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields)\n\n // Should return the group as a top-level item, not the inner field\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('meta')\n expect('fields' in result[0]).toBe(true)\n expect('accessor' in result[0]).toBe(false)\n expect('labelWithPrefix' in result[0]).toBe(false)\n })\n\n it('should correctly handle deeply nested group fields with and without moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n name: 'outer',\n label: 'Outer',\n fields: [\n {\n type: 'group',\n name: 'inner',\n label: 'Inner',\n fields: [\n {\n type: 'text',\n name: 'deep',\n label: 'Deep Field',\n },\n ],\n },\n ],\n },\n ]\n\n const hoisted = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(hoisted).toHaveLength(3)\n expect(hoisted[2].name).toBe('deep')\n expect(hoisted[2].accessor).toBe('outer.inner.deep')\n expect(hoisted[2].labelWithPrefix).toBe('Outer > Inner > Deep Field')\n\n const nonHoisted = flattenTopLevelFields(fields)\n\n expect(nonHoisted).toHaveLength(1)\n expect(nonHoisted[0].name).toBe('outer')\n expect('fields' in nonHoisted[0]).toBe(true)\n expect('accessor' in nonHoisted[0]).toBe(false)\n expect('labelWithPrefix' in nonHoisted[0]).toBe(false)\n })\n\n it('should hoist fields from unnamed group if moveSubFieldsToTop is true', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n label: 'Unnamed group',\n fields: [\n {\n type: 'text',\n name: 'insideUnnamedGroup',\n },\n ],\n },\n ]\n\n const withExtract = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n // Should include top level group and its nested field as a top-level field\n expect(withExtract).toHaveLength(2)\n expect(withExtract[1].type).toBe('text')\n expect(withExtract[1].accessor).toBeUndefined()\n expect(withExtract[1].labelWithPrefix).toBeUndefined()\n\n const withoutExtract = flattenTopLevelFields(fields)\n\n // Should return the group as a top-level item, not the inner field\n expect(withoutExtract).toHaveLength(1)\n expect(withoutExtract[0].type).toBe('text')\n expect(withoutExtract[0].accessor).toBeUndefined()\n expect(withoutExtract[0].labelWithPrefix).toBeUndefined()\n })\n\n it('should hoist using deepest named group only if parents are unnamed', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n label: 'Outer',\n fields: [\n {\n type: 'group',\n label: 'Middle',\n fields: [\n {\n type: 'group',\n name: 'namedGroup',\n label: 'Named Group',\n fields: [\n {\n type: 'group',\n label: 'Inner',\n fields: [\n {\n type: 'text',\n name: 'nestedField',\n label: 'Nested Field',\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const hoistedResult = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(hoistedResult).toHaveLength(5)\n expect(hoistedResult[4].name).toBe('nestedField')\n expect(hoistedResult[4].accessor).toBe('namedGroup.nestedField')\n expect(hoistedResult[4].labelWithPrefix).toBe('Named Group > Nested Field')\n\n const nonHoistedResult = flattenTopLevelFields(fields)\n\n expect(nonHoistedResult).toHaveLength(1)\n expect(nonHoistedResult[0].type).toBe('group')\n expect('fields' in nonHoistedResult[0]).toBe(true)\n expect('accessor' in nonHoistedResult[0]).toBe(false)\n expect('labelWithPrefix' in nonHoistedResult[0]).toBe(false)\n })\n })\n\n describe('array and block edge cases', () => {\n it('should NOT flatten fields in arrays or blocks with moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'array',\n name: 'items',\n label: 'Items',\n fields: [\n {\n type: 'text',\n name: 'label',\n label: 'Label',\n },\n ],\n },\n {\n type: 'blocks',\n name: 'layout',\n blocks: [\n {\n slug: 'block',\n fields: [\n {\n type: 'text',\n name: 'content',\n label: 'Content',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n expect(result).toHaveLength(2)\n expect(result[0].name).toBe('items')\n expect(result[1].name).toBe('layout')\n })\n\n it('should NOT flatten fields in arrays or blocks without moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'array',\n name: 'things',\n label: 'Things',\n fields: [\n {\n type: 'text',\n name: 'thingLabel',\n label: 'Thing Label',\n },\n ],\n },\n {\n type: 'blocks',\n name: 'contentBlocks',\n blocks: [\n {\n slug: 'content',\n fields: [\n {\n type: 'text',\n name: 'body',\n label: 'Body',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields)\n expect(result).toHaveLength(2)\n expect(result[0].name).toBe('things')\n expect(result[1].name).toBe('contentBlocks')\n })\n\n it('should not hoist group fields nested inside arrays', () => {\n const fields: ClientField[] = [\n {\n type: 'array',\n name: 'arrayField',\n label: 'Array Field',\n fields: [\n {\n type: 'group',\n name: 'groupInArray',\n label: 'Group In Array',\n fields: [\n {\n type: 'text',\n name: 'nestedInArrayGroup',\n label: 'Nested In Array Group',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('arrayField')\n })\n\n it('should not hoist group fields nested inside blocks', () => {\n const fields: ClientField[] = [\n {\n type: 'blocks',\n name: 'blockField',\n blocks: [\n {\n slug: 'exampleBlock',\n fields: [\n {\n type: 'group',\n name: 'groupInBlock',\n label: 'Group In Block',\n fields: [\n {\n type: 'text',\n name: 'nestedInBlockGroup',\n label: 'Nested In Block Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('blockField')\n })\n })\n\n describe('row and collapsible behavior', () => {\n it('should recursively flatten collapsible fields regardless of moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'collapsible',\n label: 'Collapsible',\n fields: [\n {\n type: 'text',\n name: 'nickname',\n label: 'Nickname',\n },\n ],\n },\n ]\n\n const defaultResult = flattenTopLevelFields(fields)\n const hoistedResult = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n\n for (const result of [defaultResult, hoistedResult]) {\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('nickname')\n expect('accessor' in result[0]).toBe(false)\n expect('labelWithPrefix' in result[0]).toBe(false)\n }\n })\n\n it('should recursively flatten row fields regardless of moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'row',\n fields: [\n {\n type: 'text',\n name: 'firstName',\n label: 'First Name',\n },\n {\n type: 'text',\n name: 'lastName',\n label: 'Last Name',\n },\n ],\n },\n ]\n\n const defaultResult = flattenTopLevelFields(fields)\n const hoistedResult = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n\n for (const result of [defaultResult, hoistedResult]) {\n expect(result).toHaveLength(2)\n expect(result[0].name).toBe('firstName')\n expect(result[1].name).toBe('lastName')\n expect('accessor' in result[0]).toBe(false)\n expect('labelWithPrefix' in result[0]).toBe(false)\n }\n })\n\n it('should hoist named group fields inside rows', () => {\n const fields: ClientField[] = [\n {\n type: 'row',\n fields: [\n {\n type: 'group',\n name: 'groupInRow',\n label: 'Group In Row',\n fields: [\n {\n type: 'text',\n name: 'nestedInRowGroup',\n label: 'Nested In Row Group',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].accessor).toBe('groupInRow.nestedInRowGroup')\n expect(result[1].labelWithPrefix).toBe('Group In Row > Nested In Row Group')\n })\n\n it('should hoist named group fields inside collapsibles', () => {\n const fields: ClientField[] = [\n {\n type: 'collapsible',\n label: 'Collapsible',\n fields: [\n {\n type: 'group',\n name: 'groupInCollapsible',\n label: 'Group In Collapsible',\n fields: [\n {\n type: 'text',\n name: 'nestedInCollapsibleGroup',\n label: 'Nested In Collapsible Group',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].accessor).toBe('groupInCollapsible.nestedInCollapsibleGroup')\n expect(result[1].labelWithPrefix).toBe('Group In Collapsible > Nested In Collapsible Group')\n })\n })\n\n describe('tab integration', () => {\n const namedTabFields: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n name: 'tabOne',\n fields: [\n {\n type: 'array',\n name: 'array',\n fields: [\n {\n type: 'text',\n name: 'text',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'arrayInRow',\n type: 'array',\n fields: [\n {\n name: 'textInArrayInRow',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n type: 'text',\n name: 'textInTab',\n label: 'Text In Tab',\n },\n {\n type: 'group',\n name: 'groupInTab',\n label: 'Group In Tab',\n fields: [\n {\n type: 'text',\n name: 'nestedTextInTabGroup',\n label: 'Nested Text In Tab Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const unnamedTabFields: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n fields: [\n {\n type: 'array',\n name: 'array',\n fields: [\n {\n type: 'text',\n name: 'text',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'arrayInRow',\n type: 'array',\n fields: [\n {\n name: 'textInArrayInRow',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n type: 'text',\n name: 'textInTab',\n label: 'Text In Tab',\n },\n ],\n },\n ],\n },\n ]\n\n it('should hoist named group fields inside unamed tabs when moveSubFieldsToTop is true', () => {\n const unnamedTabWithNamedGroup: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n fields: [\n {\n type: 'group',\n name: 'groupInTab',\n label: 'Group In Tab',\n fields: [\n {\n type: 'text',\n name: 'nestedInTabGroup',\n label: 'Nested In Tab Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(unnamedTabWithNamedGroup, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].accessor).toBe('groupInTab.nestedInTabGroup')\n expect(result[1].labelWithPrefix).toBe('Group In Tab > Nested In Tab Group')\n })\n\n it('should hoist fields inside unnamed groups inside unnamed tabs when moveSubFieldsToTop is true', () => {\n const unnamedTabWithUnnamedGroup: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n fields: [\n {\n type: 'group',\n label: 'Unnamed Group In Tab',\n fields: [\n {\n type: 'text',\n name: 'nestedInUnnamedGroup',\n label: 'Nested In Unnamed Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const defaultResult = flattenTopLevelFields(unnamedTabWithUnnamedGroup)\n\n expect(defaultResult).toHaveLength(1)\n expect(defaultResult[0].type).toBe('text')\n expect(defaultResult[0].label).toBe('Nested In Unnamed Group')\n expect('accessor' in defaultResult[0]).toBe(false)\n expect('labelWithPrefix' in defaultResult[0]).toBe(false)\n\n const hoistedResult = flattenTopLevelFields(unnamedTabWithUnnamedGroup, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(hoistedResult).toHaveLength(2)\n const hoistedField = hoistedResult[1]\n expect(hoistedField.name).toBe('nestedInUnnamedGroup')\n expect(hoistedField.accessor).toBeUndefined()\n expect(hoistedField.labelWithPrefix).toBeUndefined()\n })\n\n it('should properly hoist fields inside named tabs when moveSubFieldsToTop is true', () => {\n const result = flattenTopLevelFields(namedTabFields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(5)\n expect(result[0].accessor).toBe('tabOne.array')\n expect(result[0].labelWithPrefix).toBe('Tab One > array')\n expect(result[1].accessor).toBe('tabOne.arrayInRow')\n expect(result[1].labelWithPrefix).toBe('Tab One > arrayInRow')\n expect(result[2].accessor).toBe('tabOne.textInTab')\n expect(result[2].labelWithPrefix).toBe('Tab One > Text In Tab')\n expect(result[4].accessor).toBe('tabOne.groupInTab.nestedTextInTabGroup')\n expect(result[4].labelWithPrefix).toBe('Tab One > Group In Tab > Nested Text In Tab Group')\n })\n\n it('should NOT hoist fields inside named tabs when moveSubFieldsToTop is false', () => {\n const result = flattenTopLevelFields(namedTabFields)\n\n // We expect one top-level field: the tabs container itself is *not* hoisted\n expect(result).toHaveLength(1)\n\n const tabField = result[0]\n expect(tabField.type).toBe('tab')\n\n // Confirm nested fields are NOT hoisted: no accessors or labelWithPrefix at the top level\n expect('accessor' in tabField).toBe(false)\n expect('labelWithPrefix' in tabField).toBe(false)\n })\n\n it('should hoist fields inside unnamed tabs regardless of moveSubFieldsToTop', () => {\n const resultDefault = flattenTopLevelFields(unnamedTabFields)\n const resultHoisted = flattenTopLevelFields(unnamedTabFields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(resultDefault).toHaveLength(3)\n expect(resultHoisted).toHaveLength(3)\n expect(resultDefault).toEqual(resultHoisted)\n\n for (const field of resultDefault) {\n expect(field.accessor).toBeUndefined()\n expect(field.labelWithPrefix).toBeUndefined()\n }\n })\n })\n})\n"],"names":["flattenTopLevelFields","describe","i18n","t","value","language","dateFNS","dateFNSKey","fallbackLanguage","translations","baseField","type","name","label","it","fields","result","expect","toHaveLength","toBe","moveSubFieldsToTop","accessor","labelWithPrefix","hoisted","nonHoisted","withExtract","toBeUndefined","withoutExtract","hoistedResult","nonHoistedResult","blocks","slug","defaultResult","namedTabFields","tabs","unnamedTabFields","unnamedTabWithNamedGroup","unnamedTabWithUnnamedGroup","hoistedField","tabField","resultDefault","resultHoisted","toEqual","field"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/flattenTopLevelFields.spec.ts"],"sourcesContent":["import { I18nClient } from '@payloadcms/translations'\nimport { describe, it, expect } from 'vitest'\nimport { ClientField } from '../fields/config/client.js'\nimport { flattenTopLevelFields } from './flattenTopLevelFields.js'\n\ndescribe('flattenFields', () => {\n const i18n: I18nClient = {\n t: (value: string) => value,\n language: 'en',\n dateFNS: {} as any,\n dateFNSKey: 'en-US',\n fallbackLanguage: 'en',\n translations: {},\n }\n\n const baseField: ClientField = {\n type: 'text',\n name: 'title',\n label: 'Title',\n }\n\n describe('basic flattening', () => {\n it('should return flat list for top-level fields', () => {\n const fields = [baseField]\n const result = flattenTopLevelFields(fields)\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('title')\n })\n })\n\n describe('group flattening', () => {\n it('should flatten fields inside group with accessor and labelWithPrefix with moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n name: 'meta',\n label: 'Meta Info',\n fields: [\n {\n type: 'text',\n name: 'slug',\n label: 'Slug',\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].name).toBe('slug')\n expect(result[1].accessor).toBe('meta.slug')\n expect(result[1].labelWithPrefix).toBe('Meta Info > Slug')\n })\n\n it('should NOT flatten fields inside group without moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n name: 'meta',\n label: 'Meta Info',\n fields: [\n {\n type: 'text',\n name: 'slug',\n label: 'Slug',\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields)\n\n // Should return the group as a top-level item, not the inner field\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('meta')\n expect('fields' in result[0]).toBe(true)\n expect('accessor' in result[0]).toBe(false)\n expect('labelWithPrefix' in result[0]).toBe(false)\n })\n\n it('should correctly handle deeply nested group fields with and without moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n name: 'outer',\n label: 'Outer',\n fields: [\n {\n type: 'group',\n name: 'inner',\n label: 'Inner',\n fields: [\n {\n type: 'text',\n name: 'deep',\n label: 'Deep Field',\n },\n ],\n },\n ],\n },\n ]\n\n const hoisted = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(hoisted).toHaveLength(3)\n expect(hoisted[2].name).toBe('deep')\n expect(hoisted[2].accessor).toBe('outer.inner.deep')\n expect(hoisted[2].labelWithPrefix).toBe('Outer > Inner > Deep Field')\n\n const nonHoisted = flattenTopLevelFields(fields)\n\n expect(nonHoisted).toHaveLength(1)\n expect(nonHoisted[0].name).toBe('outer')\n expect('fields' in nonHoisted[0]).toBe(true)\n expect('accessor' in nonHoisted[0]).toBe(false)\n expect('labelWithPrefix' in nonHoisted[0]).toBe(false)\n })\n\n it('should hoist fields from unnamed group if moveSubFieldsToTop is true', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n label: 'Unnamed group',\n fields: [\n {\n type: 'text',\n name: 'insideUnnamedGroup',\n },\n ],\n },\n ]\n\n const withExtract = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n // Should include top level group and its nested field as a top-level field\n expect(withExtract).toHaveLength(2)\n expect(withExtract[1].type).toBe('text')\n expect(withExtract[1].accessor).toBeUndefined()\n expect(withExtract[1].labelWithPrefix).toBeUndefined()\n\n const withoutExtract = flattenTopLevelFields(fields)\n\n // Should return the group as a top-level item, not the inner field\n expect(withoutExtract).toHaveLength(1)\n expect(withoutExtract[0].type).toBe('text')\n expect(withoutExtract[0].accessor).toBeUndefined()\n expect(withoutExtract[0].labelWithPrefix).toBeUndefined()\n })\n\n it('should hoist using deepest named group only if parents are unnamed', () => {\n const fields: ClientField[] = [\n {\n type: 'group',\n label: 'Outer',\n fields: [\n {\n type: 'group',\n label: 'Middle',\n fields: [\n {\n type: 'group',\n name: 'namedGroup',\n label: 'Named Group',\n fields: [\n {\n type: 'group',\n label: 'Inner',\n fields: [\n {\n type: 'text',\n name: 'nestedField',\n label: 'Nested Field',\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const hoistedResult = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(hoistedResult).toHaveLength(5)\n expect(hoistedResult[4].name).toBe('nestedField')\n expect(hoistedResult[4].accessor).toBe('namedGroup.nestedField')\n expect(hoistedResult[4].labelWithPrefix).toBe('Named Group > Nested Field')\n\n const nonHoistedResult = flattenTopLevelFields(fields)\n\n expect(nonHoistedResult).toHaveLength(1)\n expect(nonHoistedResult[0].type).toBe('group')\n expect('fields' in nonHoistedResult[0]).toBe(true)\n expect('accessor' in nonHoistedResult[0]).toBe(false)\n expect('labelWithPrefix' in nonHoistedResult[0]).toBe(false)\n })\n })\n\n describe('array and block edge cases', () => {\n it('should NOT flatten fields in arrays or blocks with moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'array',\n name: 'items',\n label: 'Items',\n fields: [\n {\n type: 'text',\n name: 'label',\n label: 'Label',\n },\n ],\n },\n {\n type: 'blocks',\n name: 'layout',\n blocks: [\n {\n slug: 'block',\n fields: [\n {\n type: 'text',\n name: 'content',\n label: 'Content',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n expect(result).toHaveLength(2)\n expect(result[0].name).toBe('items')\n expect(result[1].name).toBe('layout')\n })\n\n it('should NOT flatten fields in arrays or blocks without moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'array',\n name: 'things',\n label: 'Things',\n fields: [\n {\n type: 'text',\n name: 'thingLabel',\n label: 'Thing Label',\n },\n ],\n },\n {\n type: 'blocks',\n name: 'contentBlocks',\n blocks: [\n {\n slug: 'content',\n fields: [\n {\n type: 'text',\n name: 'body',\n label: 'Body',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields)\n expect(result).toHaveLength(2)\n expect(result[0].name).toBe('things')\n expect(result[1].name).toBe('contentBlocks')\n })\n\n it('should not hoist group fields nested inside arrays', () => {\n const fields: ClientField[] = [\n {\n type: 'array',\n name: 'arrayField',\n label: 'Array Field',\n fields: [\n {\n type: 'group',\n name: 'groupInArray',\n label: 'Group In Array',\n fields: [\n {\n type: 'text',\n name: 'nestedInArrayGroup',\n label: 'Nested In Array Group',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('arrayField')\n })\n\n it('should not hoist group fields nested inside blocks', () => {\n const fields: ClientField[] = [\n {\n type: 'blocks',\n name: 'blockField',\n blocks: [\n {\n slug: 'exampleBlock',\n fields: [\n {\n type: 'group',\n name: 'groupInBlock',\n label: 'Group In Block',\n fields: [\n {\n type: 'text',\n name: 'nestedInBlockGroup',\n label: 'Nested In Block Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('blockField')\n })\n })\n\n describe('row and collapsible behavior', () => {\n it('should recursively flatten collapsible fields regardless of moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'collapsible',\n label: 'Collapsible',\n fields: [\n {\n type: 'text',\n name: 'nickname',\n label: 'Nickname',\n },\n ],\n },\n ]\n\n const defaultResult = flattenTopLevelFields(fields)\n const hoistedResult = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n\n for (const result of [defaultResult, hoistedResult]) {\n expect(result).toHaveLength(1)\n expect(result[0].name).toBe('nickname')\n expect('accessor' in result[0]).toBe(false)\n expect('labelWithPrefix' in result[0]).toBe(false)\n }\n })\n\n it('should recursively flatten row fields regardless of moveSubFieldsToTop', () => {\n const fields: ClientField[] = [\n {\n type: 'row',\n fields: [\n {\n type: 'text',\n name: 'firstName',\n label: 'First Name',\n },\n {\n type: 'text',\n name: 'lastName',\n label: 'Last Name',\n },\n ],\n },\n ]\n\n const defaultResult = flattenTopLevelFields(fields)\n const hoistedResult = flattenTopLevelFields(fields, { moveSubFieldsToTop: true })\n\n for (const result of [defaultResult, hoistedResult]) {\n expect(result).toHaveLength(2)\n expect(result[0].name).toBe('firstName')\n expect(result[1].name).toBe('lastName')\n expect('accessor' in result[0]).toBe(false)\n expect('labelWithPrefix' in result[0]).toBe(false)\n }\n })\n\n it('should hoist named group fields inside rows', () => {\n const fields: ClientField[] = [\n {\n type: 'row',\n fields: [\n {\n type: 'group',\n name: 'groupInRow',\n label: 'Group In Row',\n fields: [\n {\n type: 'text',\n name: 'nestedInRowGroup',\n label: 'Nested In Row Group',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].accessor).toBe('groupInRow.nestedInRowGroup')\n expect(result[1].labelWithPrefix).toBe('Group In Row > Nested In Row Group')\n })\n\n it('should hoist named group fields inside collapsibles', () => {\n const fields: ClientField[] = [\n {\n type: 'collapsible',\n label: 'Collapsible',\n fields: [\n {\n type: 'group',\n name: 'groupInCollapsible',\n label: 'Group In Collapsible',\n fields: [\n {\n type: 'text',\n name: 'nestedInCollapsibleGroup',\n label: 'Nested In Collapsible Group',\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(fields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].accessor).toBe('groupInCollapsible.nestedInCollapsibleGroup')\n expect(result[1].labelWithPrefix).toBe('Group In Collapsible > Nested In Collapsible Group')\n })\n })\n\n describe('tab integration', () => {\n const namedTabFields: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n name: 'tabOne',\n fields: [\n {\n type: 'array',\n name: 'array',\n fields: [\n {\n type: 'text',\n name: 'text',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'arrayInRow',\n type: 'array',\n fields: [\n {\n name: 'textInArrayInRow',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n type: 'text',\n name: 'textInTab',\n label: 'Text In Tab',\n },\n {\n type: 'group',\n name: 'groupInTab',\n label: 'Group In Tab',\n fields: [\n {\n type: 'text',\n name: 'nestedTextInTabGroup',\n label: 'Nested Text In Tab Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const unnamedTabFields: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n fields: [\n {\n type: 'array',\n name: 'array',\n fields: [\n {\n type: 'text',\n name: 'text',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'arrayInRow',\n type: 'array',\n fields: [\n {\n name: 'textInArrayInRow',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n type: 'text',\n name: 'textInTab',\n label: 'Text In Tab',\n },\n ],\n },\n ],\n },\n ]\n\n it('should hoist named group fields inside unamed tabs when moveSubFieldsToTop is true', () => {\n const unnamedTabWithNamedGroup: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n fields: [\n {\n type: 'group',\n name: 'groupInTab',\n label: 'Group In Tab',\n fields: [\n {\n type: 'text',\n name: 'nestedInTabGroup',\n label: 'Nested In Tab Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const result = flattenTopLevelFields(unnamedTabWithNamedGroup, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(2)\n expect(result[1].accessor).toBe('groupInTab.nestedInTabGroup')\n expect(result[1].labelWithPrefix).toBe('Group In Tab > Nested In Tab Group')\n })\n\n it('should hoist fields inside unnamed groups inside unnamed tabs when moveSubFieldsToTop is true', () => {\n const unnamedTabWithUnnamedGroup: ClientField[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab One',\n fields: [\n {\n type: 'group',\n label: 'Unnamed Group In Tab',\n fields: [\n {\n type: 'text',\n name: 'nestedInUnnamedGroup',\n label: 'Nested In Unnamed Group',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const defaultResult = flattenTopLevelFields(unnamedTabWithUnnamedGroup)\n\n expect(defaultResult).toHaveLength(1)\n expect(defaultResult[0].type).toBe('text')\n expect(defaultResult[0].label).toBe('Nested In Unnamed Group')\n expect('accessor' in defaultResult[0]).toBe(false)\n expect('labelWithPrefix' in defaultResult[0]).toBe(false)\n\n const hoistedResult = flattenTopLevelFields(unnamedTabWithUnnamedGroup, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(hoistedResult).toHaveLength(2)\n const hoistedField = hoistedResult[1]\n expect(hoistedField.name).toBe('nestedInUnnamedGroup')\n expect(hoistedField.accessor).toBeUndefined()\n expect(hoistedField.labelWithPrefix).toBeUndefined()\n })\n\n it('should properly hoist fields inside named tabs when moveSubFieldsToTop is true', () => {\n const result = flattenTopLevelFields(namedTabFields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(result).toHaveLength(5)\n expect(result[0].accessor).toBe('tabOne.array')\n expect(result[0].labelWithPrefix).toBe('Tab One > array')\n expect(result[1].accessor).toBe('tabOne.arrayInRow')\n expect(result[1].labelWithPrefix).toBe('Tab One > arrayInRow')\n expect(result[2].accessor).toBe('tabOne.textInTab')\n expect(result[2].labelWithPrefix).toBe('Tab One > Text In Tab')\n expect(result[4].accessor).toBe('tabOne.groupInTab.nestedTextInTabGroup')\n expect(result[4].labelWithPrefix).toBe('Tab One > Group In Tab > Nested Text In Tab Group')\n })\n\n it('should NOT hoist fields inside named tabs when moveSubFieldsToTop is false', () => {\n const result = flattenTopLevelFields(namedTabFields)\n\n // We expect one top-level field: the tabs container itself is *not* hoisted\n expect(result).toHaveLength(1)\n\n const tabField = result[0]\n expect(tabField.type).toBe('tab')\n\n // Confirm nested fields are NOT hoisted: no accessors or labelWithPrefix at the top level\n expect('accessor' in tabField).toBe(false)\n expect('labelWithPrefix' in tabField).toBe(false)\n })\n\n it('should hoist fields inside unnamed tabs regardless of moveSubFieldsToTop', () => {\n const resultDefault = flattenTopLevelFields(unnamedTabFields)\n const resultHoisted = flattenTopLevelFields(unnamedTabFields, {\n moveSubFieldsToTop: true,\n i18n,\n })\n\n expect(resultDefault).toHaveLength(3)\n expect(resultHoisted).toHaveLength(3)\n expect(resultDefault).toEqual(resultHoisted)\n\n for (const field of resultDefault) {\n expect(field.accessor).toBeUndefined()\n expect(field.labelWithPrefix).toBeUndefined()\n }\n })\n })\n})\n"],"names":["describe","it","expect","flattenTopLevelFields","i18n","t","value","language","dateFNS","dateFNSKey","fallbackLanguage","translations","baseField","type","name","label","fields","result","toHaveLength","toBe","moveSubFieldsToTop","accessor","labelWithPrefix","hoisted","nonHoisted","withExtract","toBeUndefined","withoutExtract","hoistedResult","nonHoistedResult","blocks","slug","defaultResult","namedTabFields","tabs","unnamedTabFields","unnamedTabWithNamedGroup","unnamedTabWithUnnamedGroup","hoistedField","tabField","resultDefault","resultHoisted","toEqual","field"],"mappings":"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,CAAC,EAAE,CAACK,eAAe,EAAEH,IAAI,CAAC;QACzC;IACF;IAEAnB,SAAS,mBAAmB;QAC1B,MAAMiC,iBAAgC;YACpC;gBACEpB,MAAM;gBACNqB,MAAM;oBACJ;wBACEnB,OAAO;wBACPD,MAAM;wBACNE,QAAQ;4BACN;gCACEH,MAAM;gCACNC,MAAM;gCACNE,QAAQ;oCACN;wCACEH,MAAM;wCACNC,MAAM;oCACR;iCACD;4BACH;4BACA;gCACED,MAAM;gCACNG,QAAQ;oCACN;wCACEF,MAAM;wCACND,MAAM;wCACNG,QAAQ;4CACN;gDACEF,MAAM;gDACND,MAAM;4CACR;yCACD;oCACH;iCACD;4BACH;4BACA;gCACEA,MAAM;gCACNC,MAAM;gCACNC,OAAO;4BACT;4BACA;gCACEF,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPC,QAAQ;oCACN;wCACEH,MAAM;wCACNC,MAAM;wCACNC,OAAO;oCACT;iCACD;4BACH;yBACD;oBACH;iBACD;YACH;SACD;QAED,MAAMoB,mBAAkC;YACtC;gBACEtB,MAAM;gBACNqB,MAAM;oBACJ;wBACEnB,OAAO;wBACPC,QAAQ;4BACN;gCACEH,MAAM;gCACNC,MAAM;gCACNE,QAAQ;oCACN;wCACEH,MAAM;wCACNC,MAAM;oCACR;iCACD;4BACH;4BACA;gCACED,MAAM;gCACNG,QAAQ;oCACN;wCACEF,MAAM;wCACND,MAAM;wCACNG,QAAQ;4CACN;gDACEF,MAAM;gDACND,MAAM;4CACR;yCACD;oCACH;iCACD;4BACH;4BACA;gCACEA,MAAM;gCACNC,MAAM;gCACNC,OAAO;4BACT;yBACD;oBACH;iBACD;YACH;SACD;QAEDd,GAAG,sFAAsF;YACvF,MAAMmC,2BAA0C;gBAC9C;oBACEvB,MAAM;oBACNqB,MAAM;wBACJ;4BACEnB,OAAO;4BACPC,QAAQ;gCACN;oCACEH,MAAM;oCACNC,MAAM;oCACNC,OAAO;oCACPC,QAAQ;wCACN;4CACEH,MAAM;4CACNC,MAAM;4CACNC,OAAO;wCACT;qCACD;gCACH;6BACD;wBACH;qBACD;gBACH;aACD;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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/formatLabels.spec.ts"],"sourcesContent":["import { formatLabels, toWords } from './formatLabels'\n\ndescribe('formatLabels', () => {\n it('should format singular slug', () => {\n expect(formatLabels('word')).toMatchObject({\n plural: 'Words',\n singular: 'Word',\n })\n })\n\n it('should format plural slug', () => {\n expect(formatLabels('words')).toMatchObject({\n plural: 'Words',\n singular: 'Word',\n })\n })\n\n it('should format kebab case', () => {\n expect(formatLabels('my-slugs')).toMatchObject({\n plural: 'My Slugs',\n singular: 'My Slug',\n })\n })\n\n it('should format camelCase', () => {\n expect(formatLabels('camelCaseItems')).toMatchObject({\n plural: 'Camel Case Items',\n singular: 'Camel Case Item',\n })\n })\n\n describe('toWords', () => {\n it('should convert camel to capitalized words', () => {\n expect(toWords('camelCaseItems')).toBe('Camel Case Items')\n })\n\n it('should allow no separator (used for building GraphQL label from name)', () => {\n expect(toWords('myGraphField', true)).toBe('MyGraphField')\n })\n })\n})\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/formatLabels.spec.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport { formatLabels, toWords } from './formatLabels'\n\ndescribe('formatLabels', () => {\n it('should format singular slug', () => {\n expect(formatLabels('word')).toMatchObject({\n plural: 'Words',\n singular: 'Word',\n })\n })\n\n it('should format plural slug', () => {\n expect(formatLabels('words')).toMatchObject({\n plural: 'Words',\n singular: 'Word',\n })\n })\n\n it('should format kebab case', () => {\n expect(formatLabels('my-slugs')).toMatchObject({\n plural: 'My Slugs',\n singular: 'My Slug',\n })\n })\n\n it('should format camelCase', () => {\n expect(formatLabels('camelCaseItems')).toMatchObject({\n plural: 'Camel Case Items',\n singular: 'Camel Case Item',\n })\n })\n\n describe('toWords', () => {\n it('should convert camel to capitalized words', () => {\n expect(toWords('camelCaseItems')).toBe('Camel Case Items')\n })\n\n it('should allow no separator (used for building GraphQL label from name)', () => {\n expect(toWords('myGraphField', true)).toBe('MyGraphField')\n })\n })\n})\n"],"names":["describe","it","expect","formatLabels","toWords","toMatchObject","plural","singular","toBe"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,SAAQ;AAC7C,SAASC,YAAY,EAAEC,OAAO,QAAQ,iBAAgB;AAEtDJ,SAAS,gBAAgB;IACvBC,GAAG,+BAA+B;QAChCC,OAAOC,aAAa,SAASE,aAAa,CAAC;YACzCC,QAAQ;YACRC,UAAU;QACZ;IACF;IAEAN,GAAG,6BAA6B;QAC9BC,OAAOC,aAAa,UAAUE,aAAa,CAAC;YAC1CC,QAAQ;YACRC,UAAU;QACZ;IACF;IAEAN,GAAG,4BAA4B;QAC7BC,OAAOC,aAAa,aAAaE,aAAa,CAAC;YAC7CC,QAAQ;YACRC,UAAU;QACZ;IACF;IAEAN,GAAG,2BAA2B;QAC5BC,OAAOC,aAAa,mBAAmBE,aAAa,CAAC;YACnDC,QAAQ;YACRC,UAAU;QACZ;IACF;IAEAP,SAAS,WAAW;QAClBC,GAAG,6CAA6C;YAC9CC,OAAOE,QAAQ,mBAAmBI,IAAI,CAAC;QACzC;QAEAP,GAAG,yEAAyE;YAC1EC,OAAOE,QAAQ,gBAAgB,OAAOI,IAAI,CAAC;QAC7C;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getFieldByPath.spec.ts"],"sourcesContent":["import { assert } from 'ts-essentials'\nimport { flattenAllFields } from './flattenAllFields.js'\nimport { getFieldByPath } from './getFieldByPath.js'\nimport type { FlattenedArrayField, FlattenedGroupField } from '../fields/config/types.js'\n\nconst fields = flattenAllFields({\n fields: [\n {\n type: 'text',\n name: 'text',\n },\n {\n type: 'text',\n name: 'textLocalized',\n localized: true,\n },\n {\n type: 'array',\n name: 'array',\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n {\n name: 'textLocalized',\n localized: true,\n type: 'text',\n },\n {\n name: 'group',\n type: 'group',\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n type: 'tabs',\n tabs: [\n {\n name: 'tab',\n fields: [\n {\n type: 'array',\n name: 'localizedArray',\n localized: true,\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n})\n\ndescribe('getFieldByPath', () => {\n it('asserts getFieldByPath', () => {\n const assert_1 = getFieldByPath({ fields, path: 'text' })\n assert(assert_1)\n expect(assert_1.field).toBe(fields[0])\n expect(assert_1.pathHasLocalized).toBe(false)\n\n const assert_2 = getFieldByPath({ fields, path: 'textLocalized' })\n assert(assert_2)\n expect(assert_2.field).toBe(fields[1])\n expect(assert_2.pathHasLocalized).toBe(true)\n expect(assert_2.localizedPath).toBe('textLocalized.<locale>')\n\n const arrayField = fields[2] as FlattenedArrayField\n const assert_3 = getFieldByPath({ fields, path: 'array' })\n assert(assert_3)\n expect(assert_3.field).toBe(arrayField)\n expect(assert_3.pathHasLocalized).toBe(false)\n\n const assert_4 = getFieldByPath({ fields, path: 'array.text' })\n assert(assert_4)\n expect(assert_4.field).toBe(arrayField.flattenedFields[0])\n expect(assert_4.pathHasLocalized).toBe(false)\n\n const assert_5 = getFieldByPath({ fields, path: 'array.textLocalized' })\n assert(assert_5)\n expect(assert_5.field).toBe(arrayField.flattenedFields[1])\n expect(assert_5.pathHasLocalized).toBe(true)\n expect(assert_5.localizedPath).toBe('array.textLocalized.<locale>')\n\n const groupWithinArray = arrayField.flattenedFields[2] as FlattenedGroupField\n const assert_6 = getFieldByPath({ fields, path: 'array.group.text' })\n assert(assert_6)\n expect(assert_6.field).toBe(groupWithinArray.flattenedFields[0])\n expect(assert_6.pathHasLocalized).toBe(false)\n\n const assert_7 = getFieldByPath({ fields, path: 'tab.localizedArray.text' })\n assert(assert_7)\n expect(assert_7.field).toBe((fields[3] as any).flattenedFields[0].flattenedFields[0])\n expect(assert_7.pathHasLocalized).toBe(true)\n expect(assert_7.localizedPath).toBe('tab.localizedArray.<locale>.text')\n })\n})\n"],"names":["assert","flattenAllFields","getFieldByPath","fields","type","name","localized","tabs","
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getFieldByPath.spec.ts"],"sourcesContent":["import { assert } from 'ts-essentials'\nimport { describe, it, expect } from 'vitest'\nimport { flattenAllFields } from './flattenAllFields.js'\nimport { getFieldByPath } from './getFieldByPath.js'\nimport type { FlattenedArrayField, FlattenedGroupField } from '../fields/config/types.js'\n\nconst fields = flattenAllFields({\n fields: [\n {\n type: 'text',\n name: 'text',\n },\n {\n type: 'text',\n name: 'textLocalized',\n localized: true,\n },\n {\n type: 'array',\n name: 'array',\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n {\n name: 'textLocalized',\n localized: true,\n type: 'text',\n },\n {\n name: 'group',\n type: 'group',\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n ],\n },\n ],\n },\n {\n type: 'tabs',\n tabs: [\n {\n name: 'tab',\n fields: [\n {\n type: 'array',\n name: 'localizedArray',\n localized: true,\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n})\n\ndescribe('getFieldByPath', () => {\n it('asserts getFieldByPath', () => {\n const assert_1 = getFieldByPath({ fields, path: 'text' })\n assert(assert_1)\n expect(assert_1.field).toBe(fields[0])\n expect(assert_1.pathHasLocalized).toBe(false)\n\n const assert_2 = getFieldByPath({ fields, path: 'textLocalized' })\n assert(assert_2)\n expect(assert_2.field).toBe(fields[1])\n expect(assert_2.pathHasLocalized).toBe(true)\n expect(assert_2.localizedPath).toBe('textLocalized.<locale>')\n\n const arrayField = fields[2] as FlattenedArrayField\n const assert_3 = getFieldByPath({ fields, path: 'array' })\n assert(assert_3)\n expect(assert_3.field).toBe(arrayField)\n expect(assert_3.pathHasLocalized).toBe(false)\n\n const assert_4 = getFieldByPath({ fields, path: 'array.text' })\n assert(assert_4)\n expect(assert_4.field).toBe(arrayField.flattenedFields[0])\n expect(assert_4.pathHasLocalized).toBe(false)\n\n const assert_5 = getFieldByPath({ fields, path: 'array.textLocalized' })\n assert(assert_5)\n expect(assert_5.field).toBe(arrayField.flattenedFields[1])\n expect(assert_5.pathHasLocalized).toBe(true)\n expect(assert_5.localizedPath).toBe('array.textLocalized.<locale>')\n\n const groupWithinArray = arrayField.flattenedFields[2] as FlattenedGroupField\n const assert_6 = getFieldByPath({ fields, path: 'array.group.text' })\n assert(assert_6)\n expect(assert_6.field).toBe(groupWithinArray.flattenedFields[0])\n expect(assert_6.pathHasLocalized).toBe(false)\n\n const assert_7 = getFieldByPath({ fields, path: 'tab.localizedArray.text' })\n assert(assert_7)\n expect(assert_7.field).toBe((fields[3] as any).flattenedFields[0].flattenedFields[0])\n expect(assert_7.pathHasLocalized).toBe(true)\n expect(assert_7.localizedPath).toBe('tab.localizedArray.<locale>.text')\n })\n})\n"],"names":["assert","describe","it","expect","flattenAllFields","getFieldByPath","fields","type","name","localized","tabs","assert_1","path","field","toBe","pathHasLocalized","assert_2","localizedPath","arrayField","assert_3","assert_4","flattenedFields","assert_5","groupWithinArray","assert_6","assert_7"],"mappings":"AAAA,SAASA,MAAM,QAAQ,gBAAe;AACtC,SAASC,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,SAAQ;AAC7C,SAASC,gBAAgB,QAAQ,wBAAuB;AACxD,SAASC,cAAc,QAAQ,sBAAqB;AAGpD,MAAMC,SAASF,iBAAiB;IAC9BE,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;QACR;QACA;YACED,MAAM;YACNC,MAAM;YACNC,WAAW;QACb;QACA;YACEF,MAAM;YACNC,MAAM;YACNF,QAAQ;gBACN;oBACEE,MAAM;oBACND,MAAM;gBACR;gBACA;oBACEC,MAAM;oBACNC,WAAW;oBACXF,MAAM;gBACR;gBACA;oBACEC,MAAM;oBACND,MAAM;oBACND,QAAQ;wBACN;4BACEE,MAAM;4BACND,MAAM;wBACR;qBACD;gBACH;aACD;QACH;QACA;YACEA,MAAM;YACNG,MAAM;gBACJ;oBACEF,MAAM;oBACNF,QAAQ;wBACN;4BACEC,MAAM;4BACNC,MAAM;4BACNC,WAAW;4BACXH,QAAQ;gCACN;oCACEE,MAAM;oCACND,MAAM;gCACR;6BACD;wBACH;qBACD;gBACH;aACD;QACH;KACD;AACH;AAEAN,SAAS,kBAAkB;IACzBC,GAAG,0BAA0B;QAC3B,MAAMS,WAAWN,eAAe;YAAEC;YAAQM,MAAM;QAAO;QACvDZ,OAAOW;QACPR,OAAOQ,SAASE,KAAK,EAAEC,IAAI,CAACR,MAAM,CAAC,EAAE;QACrCH,OAAOQ,SAASI,gBAAgB,EAAED,IAAI,CAAC;QAEvC,MAAME,WAAWX,eAAe;YAAEC;YAAQM,MAAM;QAAgB;QAChEZ,OAAOgB;QACPb,OAAOa,SAASH,KAAK,EAAEC,IAAI,CAACR,MAAM,CAAC,EAAE;QACrCH,OAAOa,SAASD,gBAAgB,EAAED,IAAI,CAAC;QACvCX,OAAOa,SAASC,aAAa,EAAEH,IAAI,CAAC;QAEpC,MAAMI,aAAaZ,MAAM,CAAC,EAAE;QAC5B,MAAMa,WAAWd,eAAe;YAAEC;YAAQM,MAAM;QAAQ;QACxDZ,OAAOmB;QACPhB,OAAOgB,SAASN,KAAK,EAAEC,IAAI,CAACI;QAC5Bf,OAAOgB,SAASJ,gBAAgB,EAAED,IAAI,CAAC;QAEvC,MAAMM,WAAWf,eAAe;YAAEC;YAAQM,MAAM;QAAa;QAC7DZ,OAAOoB;QACPjB,OAAOiB,SAASP,KAAK,EAAEC,IAAI,CAACI,WAAWG,eAAe,CAAC,EAAE;QACzDlB,OAAOiB,SAASL,gBAAgB,EAAED,IAAI,CAAC;QAEvC,MAAMQ,WAAWjB,eAAe;YAAEC;YAAQM,MAAM;QAAsB;QACtEZ,OAAOsB;QACPnB,OAAOmB,SAAST,KAAK,EAAEC,IAAI,CAACI,WAAWG,eAAe,CAAC,EAAE;QACzDlB,OAAOmB,SAASP,gBAAgB,EAAED,IAAI,CAAC;QACvCX,OAAOmB,SAASL,aAAa,EAAEH,IAAI,CAAC;QAEpC,MAAMS,mBAAmBL,WAAWG,eAAe,CAAC,EAAE;QACtD,MAAMG,WAAWnB,eAAe;YAAEC;YAAQM,MAAM;QAAmB;QACnEZ,OAAOwB;QACPrB,OAAOqB,SAASX,KAAK,EAAEC,IAAI,CAACS,iBAAiBF,eAAe,CAAC,EAAE;QAC/DlB,OAAOqB,SAAST,gBAAgB,EAAED,IAAI,CAAC;QAEvC,MAAMW,WAAWpB,eAAe;YAAEC;YAAQM,MAAM;QAA0B;QAC1EZ,OAAOyB;QACPtB,OAAOsB,SAASZ,KAAK,EAAEC,IAAI,CAAC,AAACR,MAAM,CAAC,EAAE,CAASe,eAAe,CAAC,EAAE,CAACA,eAAe,CAAC,EAAE;QACpFlB,OAAOsB,SAASV,gBAAgB,EAAED,IAAI,CAAC;QACvCX,OAAOsB,SAASR,aAAa,EAAEH,IAAI,CAAC;IACtC;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getFieldPermissions.spec.ts"],"sourcesContent":["import type { SanitizedDocumentPermissions } from '../auth/types.js'\n\nimport { getFieldPermissions } from './getFieldPermissions.js'\n\ndescribe('getFieldPermissions with collection fallback', () => {\n const mockField = {\n name: 'testField',\n type: 'text' as const,\n }\n\n describe('fallback to collection permissions', () => {\n it('should enable read-only mode when field permissions are missing but collection has read access', () => {\n const fieldPermissions = {} // Empty/sanitized field permissions\n const collectionPermissions: SanitizedDocumentPermissions = {\n read: true,\n fields: {},\n }\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n collectionPermissions,\n })\n\n expect(result.read).toBe(true)\n expect(result.operation).toBe(false) // Should be read-only\n expect(result.permissions).toEqual({ read: true })\n })\n\n it('should respect existing field permissions when they exist', () => {\n const fieldPermissions = true // All permissions are true\n const collectionPermissions: SanitizedDocumentPermissions = {\n read: true,\n fields: {},\n }\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n })\n\n expect(result.read).toBe(true)\n expect(result.operation).toBe(true) // Should have operation permission\n expect(result.permissions).toBe(true)\n })\n\n it('should not provide access when neither field nor collection has read permission', () => {\n const fieldPermissions = {}\n const collectionPermissions: SanitizedDocumentPermissions = {\n // No read permission at collection level\n fields: {},\n }\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n collectionPermissions,\n })\n\n expect(result.read).toBe(false)\n expect(result.operation).toBe(false)\n })\n\n it('should work without collection permissions (backward compatibility)', () => {\n const fieldPermissions = true // All permissions\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n // No collectionPermissions provided\n })\n\n expect(result.read).toBe(true)\n expect(result.operation).toBe(true)\n expect(result.permissions).toBe(true)\n })\n })\n})\n"],"names":["getFieldPermissions","describe","mockField","name","type","
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getFieldPermissions.spec.ts"],"sourcesContent":["import type { SanitizedDocumentPermissions } from '../auth/types.js'\n\nimport { getFieldPermissions } from './getFieldPermissions.js'\nimport { describe, expect, it } from 'vitest'\n\ndescribe('getFieldPermissions with collection fallback', () => {\n const mockField = {\n name: 'testField',\n type: 'text' as const,\n }\n\n describe('fallback to collection permissions', () => {\n it('should enable read-only mode when field permissions are missing but collection has read access', () => {\n const fieldPermissions = {} // Empty/sanitized field permissions\n const collectionPermissions: SanitizedDocumentPermissions = {\n read: true,\n fields: {},\n }\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n collectionPermissions,\n })\n\n expect(result.read).toBe(true)\n expect(result.operation).toBe(false) // Should be read-only\n expect(result.permissions).toEqual({ read: true })\n })\n\n it('should respect existing field permissions when they exist', () => {\n const fieldPermissions = true // All permissions are true\n const collectionPermissions: SanitizedDocumentPermissions = {\n read: true,\n fields: {},\n }\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n })\n\n expect(result.read).toBe(true)\n expect(result.operation).toBe(true) // Should have operation permission\n expect(result.permissions).toBe(true)\n })\n\n it('should not provide access when neither field nor collection has read permission', () => {\n const fieldPermissions = {}\n const collectionPermissions: SanitizedDocumentPermissions = {\n // No read permission at collection level\n fields: {},\n }\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n collectionPermissions,\n })\n\n expect(result.read).toBe(false)\n expect(result.operation).toBe(false)\n })\n\n it('should work without collection permissions (backward compatibility)', () => {\n const fieldPermissions = true // All permissions\n\n const result = getFieldPermissions({\n field: mockField,\n operation: 'update',\n parentName: '',\n permissions: fieldPermissions,\n // No collectionPermissions provided\n })\n\n expect(result.read).toBe(true)\n expect(result.operation).toBe(true)\n expect(result.permissions).toBe(true)\n })\n })\n})\n"],"names":["getFieldPermissions","describe","expect","it","mockField","name","type","fieldPermissions","collectionPermissions","read","fields","result","field","operation","parentName","permissions","toBe","toEqual"],"mappings":"AAEA,SAASA,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAE7CF,SAAS,gDAAgD;IACvD,MAAMG,YAAY;QAChBC,MAAM;QACNC,MAAM;IACR;IAEAL,SAAS,sCAAsC;QAC7CE,GAAG,kGAAkG;YACnG,MAAMI,mBAAmB,CAAC,EAAE,oCAAoC;;YAChE,MAAMC,wBAAsD;gBAC1DC,MAAM;gBACNC,QAAQ,CAAC;YACX;YAEA,MAAMC,SAASX,oBAAoB;gBACjCY,OAAOR;gBACPS,WAAW;gBACXC,YAAY;gBACZC,aAAaR;gBACbC;YACF;YAEAN,OAAOS,OAAOF,IAAI,EAAEO,IAAI,CAAC;YACzBd,OAAOS,OAAOE,SAAS,EAAEG,IAAI,CAAC,OAAO,sBAAsB;;YAC3Dd,OAAOS,OAAOI,WAAW,EAAEE,OAAO,CAAC;gBAAER,MAAM;YAAK;QAClD;QAEAN,GAAG,6DAA6D;YAC9D,MAAMI,mBAAmB,KAAK,2BAA2B;;YACzD,MAAMC,wBAAsD;gBAC1DC,MAAM;gBACNC,QAAQ,CAAC;YACX;YAEA,MAAMC,SAASX,oBAAoB;gBACjCY,OAAOR;gBACPS,WAAW;gBACXC,YAAY;gBACZC,aAAaR;YACf;YAEAL,OAAOS,OAAOF,IAAI,EAAEO,IAAI,CAAC;YACzBd,OAAOS,OAAOE,SAAS,EAAEG,IAAI,CAAC,MAAM,mCAAmC;;YACvEd,OAAOS,OAAOI,WAAW,EAAEC,IAAI,CAAC;QAClC;QAEAb,GAAG,mFAAmF;YACpF,MAAMI,mBAAmB,CAAC;YAC1B,MAAMC,wBAAsD;gBAC1D,yCAAyC;gBACzCE,QAAQ,CAAC;YACX;YAEA,MAAMC,SAASX,oBAAoB;gBACjCY,OAAOR;gBACPS,WAAW;gBACXC,YAAY;gBACZC,aAAaR;gBACbC;YACF;YAEAN,OAAOS,OAAOF,IAAI,EAAEO,IAAI,CAAC;YACzBd,OAAOS,OAAOE,SAAS,EAAEG,IAAI,CAAC;QAChC;QAEAb,GAAG,uEAAuE;YACxE,MAAMI,mBAAmB,KAAK,kBAAkB;;YAEhD,MAAMI,SAASX,oBAAoB;gBACjCY,OAAOR;gBACPS,WAAW;gBACXC,YAAY;gBACZC,aAAaR;YAEf;YAEAL,OAAOS,OAAOF,IAAI,EAAEO,IAAI,CAAC;YACzBd,OAAOS,OAAOE,SAAS,EAAEG,IAAI,CAAC;YAC9Bd,OAAOS,OAAOI,WAAW,EAAEC,IAAI,CAAC;QAClC;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getSafeRedirect.spec.ts"],"sourcesContent":["import { getSafeRedirect } from './getSafeRedirect'\n\nconst fallback = '/admin' // default fallback if the input is unsafe or invalid\n\ndescribe('getSafeRedirect', () => {\n // Valid - safe redirect paths\n it.each([['/dashboard'], ['/admin/settings'], ['/projects?id=123'], ['/hello-world']])(\n 'should allow safe relative path: %s',\n (input) => {\n // If the input is a clean relative path, it should be returned as-is\n expect(getSafeRedirect({ redirectTo: input, fallbackTo: fallback })).toBe(input)\n },\n )\n\n // Invalid types or empty inputs\n it.each(['', null, undefined, 123, {}, []])(\n 'should fallback on invalid or non-string input: %s',\n (input) => {\n // If the input is not a valid string, it should return the fallback\n expect(getSafeRedirect({ redirectTo: input as any, fallbackTo: fallback })).toBe(fallback)\n },\n )\n\n // Unsafe redirect patterns\n it.each([\n '//example.com', // protocol-relative URL\n '/javascript:alert(1)', // JavaScript scheme\n '/JavaScript:alert(1)', // case-insensitive JavaScript\n '/http://unknown.com', // disguised external redirect\n '/https://unknown.com', // disguised external redirect\n '/%2Funknown.com', // encoded slash — could resolve to //\n '/\\\\/unknown.com', // escaped slash\n '/\\\\\\\\unknown.com', // double escaped slashes\n '/\\\\unknown.com', // single escaped slash\n '%2F%2Funknown.com', // fully encoded protocol-relative path\n '%2Fjavascript:alert(1)', // encoded JavaScript scheme\n ])('should block unsafe redirect: %s', (input) => {\n // All of these should return the fallback because they’re unsafe\n expect(getSafeRedirect({ redirectTo: input, fallbackTo: fallback })).toBe(fallback)\n })\n\n // Input with extra spaces should still be properly handled\n it('should trim whitespace before evaluating', () => {\n // A valid path with surrounding spaces should still be accepted\n expect(getSafeRedirect({ redirectTo: ' /dashboard ', fallbackTo: fallback })).toBe(\n '/dashboard',\n )\n\n // An unsafe path with spaces should still be rejected\n expect(getSafeRedirect({ redirectTo: ' //example.com ', fallbackTo: fallback })).toBe(\n fallback,\n )\n })\n\n // If decoding the input fails (e.g., invalid percent encoding), it should not crash\n it('should return fallback on invalid encoding', () => {\n expect(getSafeRedirect({ redirectTo: '%E0%A4%A', fallbackTo: fallback })).toBe(fallback)\n })\n})\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getSafeRedirect.spec.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport { getSafeRedirect } from './getSafeRedirect'\n\nconst fallback = '/admin' // default fallback if the input is unsafe or invalid\n\ndescribe('getSafeRedirect', () => {\n // Valid - safe redirect paths\n it.each([['/dashboard'], ['/admin/settings'], ['/projects?id=123'], ['/hello-world']])(\n 'should allow safe relative path: %s',\n (input) => {\n // If the input is a clean relative path, it should be returned as-is\n expect(getSafeRedirect({ redirectTo: input, fallbackTo: fallback })).toBe(input)\n },\n )\n\n // Invalid types or empty inputs\n it.each(['', null, undefined, 123, {}, []])(\n 'should fallback on invalid or non-string input: %s',\n (input) => {\n // If the input is not a valid string, it should return the fallback\n expect(getSafeRedirect({ redirectTo: input as any, fallbackTo: fallback })).toBe(fallback)\n },\n )\n\n // Unsafe redirect patterns\n it.each([\n '//example.com', // protocol-relative URL\n '/javascript:alert(1)', // JavaScript scheme\n '/JavaScript:alert(1)', // case-insensitive JavaScript\n '/http://unknown.com', // disguised external redirect\n '/https://unknown.com', // disguised external redirect\n '/%2Funknown.com', // encoded slash — could resolve to //\n '/\\\\/unknown.com', // escaped slash\n '/\\\\\\\\unknown.com', // double escaped slashes\n '/\\\\unknown.com', // single escaped slash\n '%2F%2Funknown.com', // fully encoded protocol-relative path\n '%2Fjavascript:alert(1)', // encoded JavaScript scheme\n ])('should block unsafe redirect: %s', (input) => {\n // All of these should return the fallback because they’re unsafe\n expect(getSafeRedirect({ redirectTo: input, fallbackTo: fallback })).toBe(fallback)\n })\n\n // Input with extra spaces should still be properly handled\n it('should trim whitespace before evaluating', () => {\n // A valid path with surrounding spaces should still be accepted\n expect(getSafeRedirect({ redirectTo: ' /dashboard ', fallbackTo: fallback })).toBe(\n '/dashboard',\n )\n\n // An unsafe path with spaces should still be rejected\n expect(getSafeRedirect({ redirectTo: ' //example.com ', fallbackTo: fallback })).toBe(\n fallback,\n )\n })\n\n // If decoding the input fails (e.g., invalid percent encoding), it should not crash\n it('should return fallback on invalid encoding', () => {\n expect(getSafeRedirect({ redirectTo: '%E0%A4%A', fallbackTo: fallback })).toBe(fallback)\n })\n})\n"],"names":["describe","it","expect","getSafeRedirect","fallback","each","input","redirectTo","fallbackTo","toBe","undefined"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,SAAQ;AAC7C,SAASC,eAAe,QAAQ,oBAAmB;AAEnD,MAAMC,WAAW,SAAS,qDAAqD;;AAE/EJ,SAAS,mBAAmB;IAC1B,8BAA8B;IAC9BC,GAAGI,IAAI,CAAC;QAAC;YAAC;SAAa;QAAE;YAAC;SAAkB;QAAE;YAAC;SAAmB;QAAE;YAAC;SAAe;KAAC,EACnF,uCACA,CAACC;QACC,qEAAqE;QACrEJ,OAAOC,gBAAgB;YAAEI,YAAYD;YAAOE,YAAYJ;QAAS,IAAIK,IAAI,CAACH;IAC5E;IAGF,gCAAgC;IAChCL,GAAGI,IAAI,CAAC;QAAC;QAAI;QAAMK;QAAW;QAAK,CAAC;QAAG,EAAE;KAAC,EACxC,sDACA,CAACJ;QACC,oEAAoE;QACpEJ,OAAOC,gBAAgB;YAAEI,YAAYD;YAAcE,YAAYJ;QAAS,IAAIK,IAAI,CAACL;IACnF;IAGF,2BAA2B;IAC3BH,GAAGI,IAAI,CAAC;QACN;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD,EAAE,oCAAoC,CAACC;QACtC,iEAAiE;QACjEJ,OAAOC,gBAAgB;YAAEI,YAAYD;YAAOE,YAAYJ;QAAS,IAAIK,IAAI,CAACL;IAC5E;IAEA,2DAA2D;IAC3DH,GAAG,4CAA4C;QAC7C,gEAAgE;QAChEC,OAAOC,gBAAgB;YAAEI,YAAY;YAAoBC,YAAYJ;QAAS,IAAIK,IAAI,CACpF;QAGF,sDAAsD;QACtDP,OAAOC,gBAAgB;YAAEI,YAAY;YAAuBC,YAAYJ;QAAS,IAAIK,IAAI,CACvFL;IAEJ;IAEA,oFAAoF;IACpFH,GAAG,8CAA8C;QAC/CC,OAAOC,gBAAgB;YAAEI,YAAY;YAAYC,YAAYJ;QAAS,IAAIK,IAAI,CAACL;IACjF;AACF"}
|