Skip to content

Commit 26a10ed

Browse files
authored
perf: reduce generated types for select by respecting interfaceName (#9870)
This PR can significantly reduce your `payload-types.ts` file if you have sharable fields / blocks that use the `interfaceName` property. Previously we didn't respect it for select types. Before: ```ts export interface Collection1Select<T extends boolean = true> { testing?: T; title?: T; meta?: | T | { title?: T; description?: T; id?: T; }; blocks?: | T | { block1?: | T | { b1title?: T; b1description?: T; id?: T; blockName?: T; }; block2?: | T | { b2title?: T; b2description?: T; id?: T; blockName?: T; }; }; updatedAt?: T; createdAt?: T; } ``` After: ```ts export interface Collection1Select<T extends boolean = true> { testing?: T; title?: T; meta?: T | SharedMetaArraySelect<T>; blocks?: | T | { block1?: T | SharedMetaBlockSelect<T>; block2?: T | AnotherSharedBlockSelect<T>; }; updatedAt?: T; createdAt?: T; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "SharedMetaArray_select". */ export interface SharedMetaArraySelect<T extends boolean = true> { title?: T; description?: T; id?: T; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "SharedMetaBlock_select". */ export interface SharedMetaBlockSelect<T extends boolean = true> { b1title?: T; b1description?: T; id?: T; blockName?: T; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "AnotherSharedBlock_select". */ export interface AnotherSharedBlockSelect<T extends boolean = true> { b2title?: T; b2description?: T; id?: T; blockName?: T; } ``` Regenerated all the types in `/test`. The diff is noticeable for `fields` - https://github.com/payloadcms/payload/pull/9870/files#diff-95beaac24c72c7bd60933e325cdcd94a4c3630a1ce22fabad624ec80cc74fc8c
1 parent 727fba7 commit 26a10ed

File tree

7 files changed

+409
-652
lines changed

7 files changed

+409
-652
lines changed

packages/payload/src/utilities/addSelectGenericsToGeneratedTyoes.spec.ts renamed to packages/payload/src/utilities/addSelectGenericsToGeneratedTypes.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ export interface PayloadMigration {
178178
export interface PostsSelect {
179179
text?: boolean;
180180
number?: boolean;
181+
sharedGroup?: boolean | SharedGroup;
181182
group?:
182183
| boolean
183184
| {
@@ -451,6 +452,7 @@ export interface PayloadMigration {
451452
export interface PostsSelect<T extends boolean = true> {
452453
text?: T;
453454
number?: T;
455+
sharedGroup?: T | SharedGroup<T>;
454456
group?:
455457
| T
456458
| {

packages/payload/src/utilities/addSelectGenericsToGeneretedTypes.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ export const addSelectGenericsToGeneratedTypes = ({
3535
// add generic to the interface
3636
newLine = line.replace(/(export interface\s+\w+)(\s*\{)/g, '$1<T extends boolean = true>$2')
3737
} else {
38-
// replace booleans with T on the line
39-
newLine = line.replace(/(?<!\?)\bboolean\b/g, 'T')
38+
newLine = line
39+
// replace booleans with T on the line
40+
.replace(/(?<!\?)\bboolean\b/g, 'T')
41+
// replace interface names like CtaBlock to CtaBlock<T>
42+
.replace(
43+
/\b(\w+)\s*\|\s*(\w+)\b/g,
44+
(_match, left, right) => `${left} | ${right}<${left}>`,
45+
)
4046

4147
if (line === '}') {
4248
isSelectTypeToken = false

packages/payload/src/utilities/configToJSONSchema.ts

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,13 @@ export function entityToJSONSchema(
643643
}
644644
}
645645

646-
export function fieldsToSelectJSONSchema({ fields }: { fields: FlattenedField[] }): JSONSchema4 {
646+
export function fieldsToSelectJSONSchema({
647+
fields,
648+
interfaceNameDefinitions,
649+
}: {
650+
fields: FlattenedField[]
651+
interfaceNameDefinitions: Map<string, JSONSchema4>
652+
}): JSONSchema4 {
647653
const schema: JSONSchema4 = {
648654
type: 'object',
649655
additionalProperties: false,
@@ -654,16 +660,32 @@ export function fieldsToSelectJSONSchema({ fields }: { fields: FlattenedField[]
654660
switch (field.type) {
655661
case 'array':
656662
case 'group':
657-
case 'tab':
663+
case 'tab': {
664+
let fieldSchema: JSONSchema4 = fieldsToSelectJSONSchema({
665+
fields: field.flattenedFields,
666+
interfaceNameDefinitions,
667+
})
668+
669+
if (field.interfaceName) {
670+
const definition = `${field.interfaceName}_select`
671+
interfaceNameDefinitions.set(definition, fieldSchema)
672+
673+
fieldSchema = {
674+
$ref: `#/definitions/${definition}`,
675+
}
676+
}
677+
658678
schema.properties[field.name] = {
659679
oneOf: [
660680
{
661681
type: 'boolean',
662682
},
663-
fieldsToSelectJSONSchema({ fields: field.flattenedFields }),
683+
fieldSchema,
664684
],
665685
}
686+
666687
break
688+
}
667689

668690
case 'blocks': {
669691
const blocksSchema: JSONSchema4 = {
@@ -673,12 +695,25 @@ export function fieldsToSelectJSONSchema({ fields }: { fields: FlattenedField[]
673695
}
674696

675697
for (const block of field.blocks) {
698+
let blockSchema = fieldsToSelectJSONSchema({
699+
fields: block.flattenedFields,
700+
interfaceNameDefinitions,
701+
})
702+
703+
if (block.interfaceName) {
704+
const definition = `${block.interfaceName}_select`
705+
interfaceNameDefinitions.set(definition, blockSchema)
706+
blockSchema = {
707+
$ref: `#/definitions/${definition}`,
708+
}
709+
}
710+
676711
blocksSchema.properties[block.slug] = {
677712
oneOf: [
678713
{
679714
type: 'boolean',
680715
},
681-
fieldsToSelectJSONSchema({ fields: block.flattenedFields }),
716+
blockSchema,
682717
],
683718
}
684719
}
@@ -900,7 +935,10 @@ export function configToJSONSchema(
900935
defaultIDType,
901936
collectionIDFieldTypes,
902937
)
903-
const select = fieldsToSelectJSONSchema({ fields: entity.flattenedFields })
938+
const select = fieldsToSelectJSONSchema({
939+
fields: entity.flattenedFields,
940+
interfaceNameDefinitions,
941+
})
904942

905943
if (type === 'global') {
906944
select.properties.globalType = {

test/auth/payload-types.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export interface Config {
3535
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
3636
};
3737
db: {
38-
defaultIDType: number;
38+
defaultIDType: string;
3939
};
4040
globals: {};
4141
globalsSelect: {};
@@ -135,7 +135,7 @@ export interface PublicUserAuthOperations {
135135
* via the `definition` "users".
136136
*/
137137
export interface User {
138-
id: number;
138+
id: string;
139139
adminOnlyField?: string | null;
140140
roles: ('admin' | 'editor' | 'moderator' | 'user' | 'viewer')[];
141141
namedSaveToJWT?: string | null;
@@ -175,7 +175,7 @@ export interface User {
175175
* via the `definition` "partial-disable-locale-strategies".
176176
*/
177177
export interface PartialDisableLocaleStrategy {
178-
id: number;
178+
id: string;
179179
updatedAt: string;
180180
createdAt: string;
181181
email: string;
@@ -192,7 +192,7 @@ export interface PartialDisableLocaleStrategy {
192192
* via the `definition` "api-keys".
193193
*/
194194
export interface ApiKey {
195-
id: number;
195+
id: string;
196196
updatedAt: string;
197197
createdAt: string;
198198
enableAPIKey?: boolean | null;
@@ -204,7 +204,7 @@ export interface ApiKey {
204204
* via the `definition` "public-users".
205205
*/
206206
export interface PublicUser {
207-
id: number;
207+
id: string;
208208
updatedAt: string;
209209
createdAt: string;
210210
email: string;
@@ -223,8 +223,8 @@ export interface PublicUser {
223223
* via the `definition` "relationsCollection".
224224
*/
225225
export interface RelationsCollection {
226-
id: number;
227-
rel?: (number | null) | User;
226+
id: string;
227+
rel?: (string | null) | User;
228228
text?: string | null;
229229
updatedAt: string;
230230
createdAt: string;
@@ -234,45 +234,45 @@ export interface RelationsCollection {
234234
* via the `definition` "payload-locked-documents".
235235
*/
236236
export interface PayloadLockedDocument {
237-
id: number;
237+
id: string;
238238
document?:
239239
| ({
240240
relationTo: 'users';
241-
value: number | User;
241+
value: string | User;
242242
} | null)
243243
| ({
244244
relationTo: 'partial-disable-locale-strategies';
245-
value: number | PartialDisableLocaleStrategy;
245+
value: string | PartialDisableLocaleStrategy;
246246
} | null)
247247
| ({
248248
relationTo: 'api-keys';
249-
value: number | ApiKey;
249+
value: string | ApiKey;
250250
} | null)
251251
| ({
252252
relationTo: 'public-users';
253-
value: number | PublicUser;
253+
value: string | PublicUser;
254254
} | null)
255255
| ({
256256
relationTo: 'relationsCollection';
257-
value: number | RelationsCollection;
257+
value: string | RelationsCollection;
258258
} | null);
259259
globalSlug?: string | null;
260260
user:
261261
| {
262262
relationTo: 'users';
263-
value: number | User;
263+
value: string | User;
264264
}
265265
| {
266266
relationTo: 'partial-disable-locale-strategies';
267-
value: number | PartialDisableLocaleStrategy;
267+
value: string | PartialDisableLocaleStrategy;
268268
}
269269
| {
270270
relationTo: 'api-keys';
271-
value: number | ApiKey;
271+
value: string | ApiKey;
272272
}
273273
| {
274274
relationTo: 'public-users';
275-
value: number | PublicUser;
275+
value: string | PublicUser;
276276
};
277277
updatedAt: string;
278278
createdAt: string;
@@ -282,23 +282,23 @@ export interface PayloadLockedDocument {
282282
* via the `definition` "payload-preferences".
283283
*/
284284
export interface PayloadPreference {
285-
id: number;
285+
id: string;
286286
user:
287287
| {
288288
relationTo: 'users';
289-
value: number | User;
289+
value: string | User;
290290
}
291291
| {
292292
relationTo: 'partial-disable-locale-strategies';
293-
value: number | PartialDisableLocaleStrategy;
293+
value: string | PartialDisableLocaleStrategy;
294294
}
295295
| {
296296
relationTo: 'api-keys';
297-
value: number | ApiKey;
297+
value: string | ApiKey;
298298
}
299299
| {
300300
relationTo: 'public-users';
301-
value: number | PublicUser;
301+
value: string | PublicUser;
302302
};
303303
key?: string | null;
304304
value?:
@@ -318,7 +318,7 @@ export interface PayloadPreference {
318318
* via the `definition` "payload-migrations".
319319
*/
320320
export interface PayloadMigration {
321-
id: number;
321+
id: string;
322322
name?: string | null;
323323
batch?: number | null;
324324
updatedAt: string;

test/fields/collections/Blocks/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const getBlocksField = (prefix?: string): BlocksField => ({
1111
blocks: [
1212
{
1313
slug: prefix ? `${prefix}Content` : 'content',
14+
interfaceName: prefix ? `${prefix}ContentBlock` : 'ContentBlock',
1415
fields: [
1516
{
1617
name: 'text',
@@ -26,6 +27,7 @@ export const getBlocksField = (prefix?: string): BlocksField => ({
2627
},
2728
{
2829
slug: prefix ? `${prefix}Number` : 'number',
30+
interfaceName: prefix ? `${prefix}NumberBlock` : 'NumberBlock',
2931
fields: [
3032
{
3133
name: 'number',
@@ -36,6 +38,7 @@ export const getBlocksField = (prefix?: string): BlocksField => ({
3638
},
3739
{
3840
slug: prefix ? `${prefix}SubBlocks` : 'subBlocks',
41+
interfaceName: prefix ? `${prefix}SubBlocksBlock` : 'SubBlocksBlock',
3942
fields: [
4043
{
4144
type: 'collapsible',
@@ -73,6 +76,7 @@ export const getBlocksField = (prefix?: string): BlocksField => ({
7376
},
7477
{
7578
slug: prefix ? `${prefix}Tabs` : 'tabs',
79+
interfaceName: prefix ? `${prefix}TabsBlock` : 'TabsBlock',
7680
fields: [
7781
{
7882
type: 'tabs',

0 commit comments

Comments
 (0)