prismic-ts-codegen 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,941 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const tsMorph = require('ts-morph');
6
+ const commonTags = require('common-tags');
7
+ const pascalCase$1 = require('pascal-case');
8
+
9
+ const BLANK_LINE_IDENTIFIER = "// ___BLANK_LINE_TO_BE_REPLACED___";
10
+ const NON_EDITABLE_FILE_HEADER = commonTags.stripIndent`
11
+ // Code generated by prismic-ts-codegen. DO NOT EDIT.
12
+ ${BLANK_LINE_IDENTIFIER}
13
+ `;
14
+ const CUSTOM_TYPES_DOCUMENTATION_URL = "https://prismic.io/docs/core-concepts/custom-types";
15
+ const SHARED_SLICES_DOCUMENTATION_URL = "https://prismic.io/docs/core-concepts/reusing-slices";
16
+ const FIELD_DOCUMENTATION_URLS = {
17
+ UID: "https://prismic.io/docs/core-concepts/uid",
18
+ Boolean: "https://prismic.io/docs/core-concepts/boolean",
19
+ Color: "https://prismic.io/docs/core-concepts/color",
20
+ Date: "https://prismic.io/docs/core-concepts/date",
21
+ Timestamp: "https://prismic.io/docs/core-concepts/timestamp",
22
+ Number: "https://prismic.io/docs/core-concepts/number",
23
+ Text: "https://prismic.io/docs/core-concepts/key-text",
24
+ Select: "https://prismic.io/docs/core-concepts/select",
25
+ StructuredText: "https://prismic.io/docs/core-concepts/rich-text-title",
26
+ Image: "https://prismic.io/docs/core-concepts/image",
27
+ Link: "https://prismic.io/docs/core-concepts/link-content-relationship",
28
+ Embed: "https://prismic.io/docs/core-concepts/embed",
29
+ GeoPoint: "https://prismic.io/docs/core-concepts/geopoint",
30
+ Group: "https://prismic.io/docs/core-concepts/group",
31
+ IntegrationFields: "https://prismic.io/docs/core-concepts/integration-fields",
32
+ Slices: "https://prismic.io/docs/core-concepts/slices"
33
+ };
34
+
35
+ const CustomTypeModelFieldType = {
36
+ Boolean: "Boolean",
37
+ Color: "Color",
38
+ Date: "Date",
39
+ Embed: "Embed",
40
+ GeoPoint: "GeoPoint",
41
+ Group: "Group",
42
+ Image: "Image",
43
+ IntegrationFields: "IntegrationFields",
44
+ Link: "Link",
45
+ Number: "Number",
46
+ Select: "Select",
47
+ Slices: "Slices",
48
+ StructuredText: "StructuredText",
49
+ Text: "Text",
50
+ Timestamp: "Timestamp",
51
+ UID: "UID"
52
+ };
53
+ const CustomTypeModelLinkSelectType = {
54
+ Document: "document",
55
+ Media: "media"
56
+ };
57
+ const CustomTypeModelSliceType = {
58
+ Slice: "Slice",
59
+ SharedSlice: "SharedSlice"
60
+ };
61
+
62
+ const isCustomTypeModelField = (model) => {
63
+ return typeof model === "object" && model !== null && "type" in model && "config" in model;
64
+ };
65
+
66
+ const isCustomTypeModelSlice = (model) => {
67
+ return typeof model === "object" && model !== null && "non-repeat" in model && "repeat" in model;
68
+ };
69
+
70
+ const isSharedSliceModel = (model) => {
71
+ return typeof model === "object" && model !== null && "variations" in model;
72
+ };
73
+
74
+ const getAPIIDPath = (config) => {
75
+ return config.path.map((element, i) => {
76
+ if (isCustomTypeModelField(element.model) && (element.model.type === CustomTypeModelFieldType.Group || element.model.type === CustomTypeModelFieldType.Slices)) {
77
+ return `${element.id}[]`;
78
+ } else {
79
+ if (element.id === "items") {
80
+ const previousElement = config.path[i - 1];
81
+ if (isCustomTypeModelSlice(previousElement.model) || isSharedSliceModel(previousElement.model)) {
82
+ return `${element.id}[]`;
83
+ }
84
+ }
85
+ return element.id;
86
+ }
87
+ }).join(".");
88
+ };
89
+
90
+ const getFieldDocumentationURL = (config) => {
91
+ return FIELD_DOCUMENTATION_URLS[config.model.type];
92
+ };
93
+
94
+ const isCustomTypeModel = (model) => {
95
+ return typeof model === "object" && model !== null && "json" in model;
96
+ };
97
+
98
+ const getHumanReadableModelName = (config) => {
99
+ if (isCustomTypeModel(config.model)) {
100
+ return config.model.label;
101
+ } else if (isSharedSliceModel(config.model)) {
102
+ return config.model.name;
103
+ } else if (isCustomTypeModelField(config.model) && "label" in config.model.config) {
104
+ return config.model.config.label;
105
+ } else if (isCustomTypeModelSlice(config.model)) {
106
+ return config.model.fieldset;
107
+ } else {
108
+ return `Slice Zone (\`${config.id}\`)`;
109
+ }
110
+ };
111
+
112
+ const getHumanReadableFieldPath = (config) => {
113
+ return config.path.map((element) => {
114
+ if (element.label) {
115
+ return element.label;
116
+ } else if (element.model) {
117
+ return getHumanReadableModelName({
118
+ id: element.id,
119
+ model: element.model
120
+ });
121
+ } else {
122
+ return element.id;
123
+ }
124
+ }).join(" \u2192 ");
125
+ };
126
+
127
+ const getHumanReadableFieldType = (config) => {
128
+ switch (config.model.type) {
129
+ case "StructuredText": {
130
+ const isTitleField = "single" in config.model.config && config.model.config.single.split(",").every((blockType) => /heading/.test(blockType));
131
+ return isTitleField ? "Title" : "Rich Text";
132
+ }
133
+ case "IntegrationFields": {
134
+ return `Integration Fields (Catalog: \`${config.model.config.catalog}\`)`;
135
+ }
136
+ case "Link": {
137
+ switch (config.model.config.select) {
138
+ case CustomTypeModelLinkSelectType.Document: {
139
+ return "Content Relationship";
140
+ }
141
+ case CustomTypeModelLinkSelectType.Media: {
142
+ return "Link to Media";
143
+ }
144
+ default: {
145
+ return "Link";
146
+ }
147
+ }
148
+ }
149
+ case "Slices": {
150
+ return "Slice Zone";
151
+ }
152
+ default: {
153
+ return config.model.type;
154
+ }
155
+ }
156
+ };
157
+
158
+ const writeFieldDocsDescription = (config) => {
159
+ if (config.description) {
160
+ config.writer.writeLine(config.description);
161
+ }
162
+ config.writer.blankLineIfLastNot();
163
+ if (config.fieldType) {
164
+ config.writer.writeLine(`- **Field Type**: ${config.fieldType}`);
165
+ }
166
+ if (config.placeholder) {
167
+ config.writer.writeLine(`- **Placeholder**: ${config.placeholder}`);
168
+ }
169
+ if (config.defaultValue !== void 0) {
170
+ const stringifiedDefaultValue = typeof config.defaultValue === "boolean" ? `${config.defaultValue}` : config.defaultValue;
171
+ config.writer.writeLine(`- **Default Value**: ${stringifiedDefaultValue}`);
172
+ }
173
+ if (config.apiIDPath) {
174
+ config.writer.writeLine(`- **API ID Path**: ${config.apiIDPath}`);
175
+ }
176
+ if (config.documentationURL) {
177
+ config.writer.writeLine(`- **Documentation**: ${config.documentationURL}`);
178
+ }
179
+ };
180
+
181
+ const buildFieldDocs = (config) => {
182
+ return [
183
+ {
184
+ description: (writer) => {
185
+ const name = getHumanReadableModelName({
186
+ id: config.id,
187
+ model: config.model
188
+ });
189
+ const humanReadablePath = getHumanReadableFieldPath({
190
+ path: config.path
191
+ });
192
+ const fieldType = getHumanReadableFieldType({
193
+ model: config.model
194
+ });
195
+ const placeholder = "placeholder" in config.model.config && config.model.config.placeholder ? config.model.config.placeholder : `*None*`;
196
+ const defaultValue = "default_value" in config.model.config ? config.model.config.default_value : void 0;
197
+ const apiIDPath = getAPIIDPath({
198
+ path: [...config.path, { id: config.id, model: config.model }]
199
+ });
200
+ writeFieldDocsDescription({
201
+ writer,
202
+ description: `${name} field in *${humanReadablePath}*`,
203
+ fieldType,
204
+ placeholder,
205
+ defaultValue,
206
+ apiIDPath,
207
+ documentationURL: getFieldDocumentationURL({ model: config.model })
208
+ });
209
+ }
210
+ }
211
+ ];
212
+ };
213
+
214
+ const pascalCase = (input) => pascalCase$1.pascalCase(input, {
215
+ transform: pascalCase$1.pascalCaseTransformMerge
216
+ });
217
+
218
+ const buildSharedSliceInterfaceName = (config) => {
219
+ return pascalCase(`${config.id} Slice`);
220
+ };
221
+
222
+ const addInterfacePropertyFromField = (config) => {
223
+ switch (config.model.type) {
224
+ case "UID": {
225
+ break;
226
+ }
227
+ case "Boolean": {
228
+ config.interface.addProperty({
229
+ name: config.id,
230
+ type: "prismicT.BooleanField",
231
+ docs: buildFieldDocs({
232
+ id: config.id,
233
+ model: config.model,
234
+ path: config.path
235
+ })
236
+ });
237
+ break;
238
+ }
239
+ case "Color": {
240
+ config.interface.addProperty({
241
+ name: config.id,
242
+ type: "prismicT.ColorField",
243
+ docs: buildFieldDocs({
244
+ id: config.id,
245
+ model: config.model,
246
+ path: config.path
247
+ })
248
+ });
249
+ break;
250
+ }
251
+ case "Date": {
252
+ config.interface.addProperty({
253
+ name: config.id,
254
+ type: "prismicT.DateField",
255
+ docs: buildFieldDocs({
256
+ id: config.id,
257
+ model: config.model,
258
+ path: config.path
259
+ })
260
+ });
261
+ break;
262
+ }
263
+ case "Embed": {
264
+ const providerTypes = [];
265
+ if (config.fieldConfigs.embed?.providerTypes) {
266
+ for (const providerType in config.fieldConfigs.embed?.providerTypes) {
267
+ const configuredProviderType = config.fieldConfigs.embed?.providerTypes[providerType];
268
+ providerTypes.push(`({ provider_name: "${providerType}" } & ${configuredProviderType})`);
269
+ }
270
+ }
271
+ config.interface.addProperty({
272
+ name: config.id,
273
+ type: providerTypes.length > 0 ? `prismicT.EmbedField<prismicT.AnyOEmbed & prismicT.OEmbedExtra & (${providerTypes.join(" | ")})>` : "prismicT.EmbedField",
274
+ docs: buildFieldDocs({
275
+ id: config.id,
276
+ model: config.model,
277
+ path: config.path
278
+ })
279
+ });
280
+ break;
281
+ }
282
+ case "GeoPoint": {
283
+ config.interface.addProperty({
284
+ name: config.id,
285
+ type: "prismicT.GeoPointField",
286
+ docs: buildFieldDocs({
287
+ id: config.id,
288
+ model: config.model,
289
+ path: config.path
290
+ })
291
+ });
292
+ break;
293
+ }
294
+ case "Image": {
295
+ if (config.model.config.thumbnails.length > 0) {
296
+ const thumbnailNames = config.model.config.thumbnails.map((thumbnail) => `"${thumbnail.name}"`).join(" | ");
297
+ config.interface.addProperty({
298
+ name: config.id,
299
+ type: `prismicT.ImageField<${thumbnailNames}>`,
300
+ docs: buildFieldDocs({
301
+ id: config.id,
302
+ model: config.model,
303
+ path: config.path
304
+ })
305
+ });
306
+ } else {
307
+ config.interface.addProperty({
308
+ name: config.id,
309
+ type: "prismicT.ImageField<null>",
310
+ docs: buildFieldDocs({
311
+ id: config.id,
312
+ model: config.model,
313
+ path: config.path
314
+ })
315
+ });
316
+ }
317
+ break;
318
+ }
319
+ case "IntegrationFields": {
320
+ const catalogType = config.fieldConfigs.integrationFields?.catalogTypes?.[config.model.config.catalog];
321
+ config.interface.addProperty({
322
+ name: config.id,
323
+ type: catalogType ? `prismicT.IntegrationFields<${catalogType}>` : "prismicT.IntegrationFields",
324
+ docs: buildFieldDocs({
325
+ id: config.id,
326
+ model: config.model,
327
+ path: config.path
328
+ })
329
+ });
330
+ break;
331
+ }
332
+ case "Link": {
333
+ switch (config.model.config.select) {
334
+ case CustomTypeModelLinkSelectType.Document: {
335
+ config.interface.addProperty({
336
+ name: config.id,
337
+ type: config.model.config.customtypes && config.model.config.customtypes.length > 0 ? `prismicT.RelationField<${config.model.config.customtypes.map((type) => `"${type}"`).join(" | ")}>` : "prismicT.RelationField",
338
+ docs: buildFieldDocs({
339
+ id: config.id,
340
+ model: config.model,
341
+ path: config.path
342
+ })
343
+ });
344
+ break;
345
+ }
346
+ case CustomTypeModelLinkSelectType.Media: {
347
+ config.interface.addProperty({
348
+ name: config.id,
349
+ type: "prismicT.LinkToMediaField",
350
+ docs: buildFieldDocs({
351
+ id: config.id,
352
+ model: config.model,
353
+ path: config.path
354
+ })
355
+ });
356
+ break;
357
+ }
358
+ default: {
359
+ config.interface.addProperty({
360
+ name: config.id,
361
+ type: "prismicT.LinkField",
362
+ docs: buildFieldDocs({
363
+ id: config.id,
364
+ model: config.model,
365
+ path: config.path
366
+ })
367
+ });
368
+ }
369
+ }
370
+ break;
371
+ }
372
+ case "Number": {
373
+ config.interface.addProperty({
374
+ name: config.id,
375
+ type: "prismicT.NumberField",
376
+ docs: buildFieldDocs({
377
+ id: config.id,
378
+ model: config.model,
379
+ path: config.path
380
+ })
381
+ });
382
+ break;
383
+ }
384
+ case "StructuredText": {
385
+ const isTitleField = "single" in config.model.config && config.model.config.single.split(",").every((blockType) => /heading/.test(blockType));
386
+ if (isTitleField) {
387
+ config.interface.addProperty({
388
+ name: config.id,
389
+ type: "prismicT.TitleField",
390
+ docs: buildFieldDocs({
391
+ id: config.id,
392
+ model: config.model,
393
+ path: config.path
394
+ })
395
+ });
396
+ } else {
397
+ config.interface.addProperty({
398
+ name: config.id,
399
+ type: "prismicT.RichTextField",
400
+ docs: buildFieldDocs({
401
+ id: config.id,
402
+ model: config.model,
403
+ path: config.path
404
+ })
405
+ });
406
+ }
407
+ break;
408
+ }
409
+ case "Select": {
410
+ const options = config.model.config.options.map((option) => `"${option}"`).join(" | ");
411
+ const hasDefault = Boolean(config.model.config.default_value);
412
+ if (hasDefault) {
413
+ config.interface.addProperty({
414
+ name: config.id,
415
+ type: `prismicT.SelectField<${options}, "filled">`,
416
+ docs: buildFieldDocs({
417
+ id: config.id,
418
+ model: config.model,
419
+ path: config.path
420
+ })
421
+ });
422
+ } else {
423
+ config.interface.addProperty({
424
+ name: config.id,
425
+ type: `prismicT.SelectField<${options}>`,
426
+ docs: buildFieldDocs({
427
+ id: config.id,
428
+ model: config.model,
429
+ path: config.path
430
+ })
431
+ });
432
+ }
433
+ break;
434
+ }
435
+ case "Text": {
436
+ config.interface.addProperty({
437
+ name: config.id,
438
+ type: "prismicT.KeyTextField",
439
+ docs: buildFieldDocs({
440
+ id: config.id,
441
+ model: config.model,
442
+ path: config.path
443
+ })
444
+ });
445
+ break;
446
+ }
447
+ case "Timestamp": {
448
+ config.interface.addProperty({
449
+ name: config.id,
450
+ type: "prismicT.TimestampField",
451
+ docs: buildFieldDocs({
452
+ id: config.id,
453
+ model: config.model,
454
+ path: config.path
455
+ })
456
+ });
457
+ break;
458
+ }
459
+ case "Group": {
460
+ const itemInterface = config.sourceFile.addInterface({
461
+ name: pascalCase(`${config.path[0].id} Document Data ${config.id} Item`),
462
+ docs: [
463
+ {
464
+ description: (writer) => {
465
+ const humanReadablePath = getHumanReadableFieldPath({
466
+ path: [
467
+ ...config.path,
468
+ {
469
+ id: config.id,
470
+ model: config.model
471
+ }
472
+ ]
473
+ });
474
+ writer.writeLine(`Item in ${humanReadablePath}`);
475
+ }
476
+ }
477
+ ]
478
+ });
479
+ addInterfacePropertiesForFields({
480
+ interface: itemInterface,
481
+ sourceFile: config.sourceFile,
482
+ fields: config.model.config.fields,
483
+ path: [
484
+ ...config.path,
485
+ {
486
+ id: config.id,
487
+ model: config.model
488
+ }
489
+ ],
490
+ fieldConfigs: config.fieldConfigs
491
+ });
492
+ config.interface.addProperty({
493
+ name: config.id,
494
+ type: `prismicT.GroupField<Simplify<${itemInterface.getName()}>>`,
495
+ docs: buildFieldDocs({
496
+ id: config.id,
497
+ model: config.model,
498
+ path: config.path
499
+ })
500
+ });
501
+ break;
502
+ }
503
+ case "Slices": {
504
+ const choiceInterfaceNames = [];
505
+ for (const choiceId in config.model.config.choices) {
506
+ const choice = config.model.config.choices[choiceId];
507
+ if (choice.type === CustomTypeModelSliceType.SharedSlice) {
508
+ choiceInterfaceNames.push(buildSharedSliceInterfaceName({ id: choiceId }));
509
+ } else if (choice.type === CustomTypeModelSliceType.Slice) {
510
+ let primaryInterface;
511
+ if (Object.keys(choice["non-repeat"]).length > 0) {
512
+ primaryInterface = config.sourceFile.addInterface({
513
+ name: pascalCase(`${config.path[0].id} Document Data ${config.id} ${choiceId} Slice Primary`),
514
+ docs: [
515
+ {
516
+ description: (writer) => {
517
+ const humanReadablePath = getHumanReadableFieldPath({
518
+ path: [
519
+ ...config.path,
520
+ {
521
+ id: config.id,
522
+ model: config.model
523
+ },
524
+ {
525
+ id: choiceId,
526
+ model: choice
527
+ },
528
+ {
529
+ id: "primary",
530
+ label: "Primary"
531
+ }
532
+ ]
533
+ });
534
+ writer.writeLine(`Primary content in ${humanReadablePath}`);
535
+ }
536
+ }
537
+ ]
538
+ });
539
+ addInterfacePropertiesForFields({
540
+ interface: primaryInterface,
541
+ sourceFile: config.sourceFile,
542
+ fields: choice["non-repeat"],
543
+ path: [
544
+ ...config.path,
545
+ {
546
+ id: config.id,
547
+ model: config.model
548
+ },
549
+ {
550
+ id: choiceId,
551
+ model: choice
552
+ },
553
+ {
554
+ id: "primary",
555
+ label: "Primary"
556
+ }
557
+ ],
558
+ fieldConfigs: config.fieldConfigs
559
+ });
560
+ }
561
+ let itemInterface;
562
+ if (Object.keys(choice.repeat).length > 0) {
563
+ itemInterface = config.sourceFile.addInterface({
564
+ name: pascalCase(`${config.path[0].id} Document Data ${config.id} ${choiceId} Slice Item`),
565
+ docs: [
566
+ {
567
+ description: (writer) => {
568
+ const humanReadablePath = getHumanReadableFieldPath({
569
+ path: [
570
+ ...config.path,
571
+ {
572
+ id: config.id,
573
+ model: config.model
574
+ },
575
+ {
576
+ id: choiceId,
577
+ model: choice
578
+ },
579
+ {
580
+ id: "items",
581
+ label: "Items"
582
+ }
583
+ ]
584
+ });
585
+ writer.writeLine(`Item in ${humanReadablePath}`);
586
+ }
587
+ }
588
+ ]
589
+ });
590
+ addInterfacePropertiesForFields({
591
+ interface: itemInterface,
592
+ sourceFile: config.sourceFile,
593
+ fields: choice.repeat,
594
+ path: [
595
+ ...config.path,
596
+ {
597
+ id: config.id,
598
+ model: config.model
599
+ },
600
+ {
601
+ id: choiceId,
602
+ model: choice
603
+ },
604
+ {
605
+ id: "items",
606
+ label: "Items"
607
+ }
608
+ ],
609
+ fieldConfigs: config.fieldConfigs
610
+ });
611
+ }
612
+ const sliceType = config.sourceFile.addTypeAlias({
613
+ name: pascalCase(`${config.path[0].id} Document Data ${config.id} ${choiceId} Slice`),
614
+ type: `prismicT.Slice<"${choiceId}", ${primaryInterface ? `Simplify<${primaryInterface.getName()}>` : "Record<string, never>"}, ${itemInterface ? `Simplify<${itemInterface.getName()}>` : "never"}>`
615
+ });
616
+ choiceInterfaceNames.push(sliceType.getName());
617
+ }
618
+ }
619
+ const slicesType = config.sourceFile.addTypeAlias({
620
+ name: pascalCase(`${config.path[0].id} Document Data ${config.id} Slice`),
621
+ type: choiceInterfaceNames.length > 0 ? choiceInterfaceNames.join(" | ") : "never",
622
+ docs: [
623
+ {
624
+ description: (writer) => {
625
+ const humanReadablePath = getHumanReadableFieldPath({
626
+ path: [
627
+ ...config.path,
628
+ {
629
+ id: config.id,
630
+ model: config.model
631
+ }
632
+ ]
633
+ });
634
+ writer.writeLine(`Slice for *${humanReadablePath}*`);
635
+ }
636
+ }
637
+ ]
638
+ });
639
+ config.interface.addProperty({
640
+ name: config.id,
641
+ type: `prismicT.SliceZone<${slicesType.getName()}>`,
642
+ docs: buildFieldDocs({
643
+ id: config.id,
644
+ model: config.model,
645
+ path: config.path
646
+ })
647
+ });
648
+ break;
649
+ }
650
+ default: {
651
+ config.interface.addProperty({
652
+ name: config.id,
653
+ type: "unknown",
654
+ docs: buildFieldDocs({
655
+ id: config.id,
656
+ model: config.model,
657
+ path: config.path
658
+ })
659
+ });
660
+ }
661
+ }
662
+ };
663
+ const addInterfacePropertiesForFields = (config) => {
664
+ for (const name in config.fields) {
665
+ addInterfacePropertyFromField({
666
+ ...config,
667
+ id: name,
668
+ model: config.fields[name]
669
+ });
670
+ }
671
+ };
672
+
673
+ const collectCustomTypeFields = (model) => {
674
+ return Object.assign({}, ...Object.values(model.json));
675
+ };
676
+ const addTypeAliasForCustomType = ({
677
+ model,
678
+ sourceFile,
679
+ localeIDs,
680
+ fieldConfigs
681
+ }) => {
682
+ const { uid: uidField, ...fields } = collectCustomTypeFields(model);
683
+ const hasDataFields = Object.keys(fields).length > 0;
684
+ const hasUIDField = Boolean(uidField);
685
+ let dataInterface;
686
+ if (hasDataFields) {
687
+ dataInterface = sourceFile.addInterface({
688
+ name: pascalCase(`${model.id} Document Data`),
689
+ docs: [
690
+ {
691
+ description: `Content for ${model.label} documents`
692
+ }
693
+ ]
694
+ });
695
+ addInterfacePropertiesForFields({
696
+ fields,
697
+ interface: dataInterface,
698
+ sourceFile,
699
+ path: [
700
+ {
701
+ id: model.id,
702
+ model
703
+ }
704
+ ],
705
+ fieldConfigs
706
+ });
707
+ } else {
708
+ dataInterface = sourceFile.addTypeAlias({
709
+ name: pascalCase(`${model.id} Document Data`),
710
+ type: `Record<string, never>`,
711
+ docs: [
712
+ {
713
+ description: `Content for ${model.label} documents`
714
+ }
715
+ ]
716
+ });
717
+ }
718
+ return sourceFile.addTypeAlias({
719
+ name: pascalCase(`${model.id} Document`),
720
+ typeParameters: [
721
+ {
722
+ name: "Lang",
723
+ constraint: "string",
724
+ default: localeIDs.length > 0 ? localeIDs.map((localeID) => `"${localeID}"`).join(" | ") : "string"
725
+ }
726
+ ],
727
+ type: hasUIDField ? `prismicT.PrismicDocumentWithUID<Simplify<${dataInterface.getName()}>, "${model.id}", Lang>` : `prismicT.PrismicDocumentWithoutUID<Simplify<${dataInterface.getName()}>, "${model.id}", Lang>`,
728
+ docs: [
729
+ {
730
+ description: (writer) => {
731
+ writer.writeLine(`${model.label} document from Prismic`);
732
+ writer.blankLine();
733
+ writer.writeLine(`- **API ID**: \`${model.id}\``);
734
+ writer.writeLine(`- **Repeatable**: \`${model.repeatable}\``);
735
+ writer.writeLine(`- **Documentation**: ${CUSTOM_TYPES_DOCUMENTATION_URL}`);
736
+ },
737
+ tags: [
738
+ {
739
+ tagName: "typeParam",
740
+ text: "Lang - Language API ID of the document."
741
+ }
742
+ ]
743
+ }
744
+ ],
745
+ isExported: true
746
+ });
747
+ };
748
+
749
+ const addTypeAliasForSharedSlice = (config) => {
750
+ const variationTypeNames = [];
751
+ for (const variation of config.model.variations) {
752
+ let primaryInterface;
753
+ if (Object.keys(variation.primary).length > 0) {
754
+ primaryInterface = config.sourceFile.addInterface({
755
+ name: pascalCase(`${buildSharedSliceInterfaceName({ id: config.model.id })} ${variation.id} Primary`),
756
+ docs: [
757
+ {
758
+ description: (writer) => {
759
+ const humanReadablePath = getHumanReadableFieldPath({
760
+ path: [
761
+ {
762
+ id: config.model.id,
763
+ model: config.model
764
+ },
765
+ {
766
+ id: "primary",
767
+ label: "Primary"
768
+ }
769
+ ]
770
+ });
771
+ writer.writeLine(`Primary content in ${humanReadablePath}`);
772
+ }
773
+ }
774
+ ]
775
+ });
776
+ addInterfacePropertiesForFields({
777
+ interface: primaryInterface,
778
+ sourceFile: config.sourceFile,
779
+ fields: variation.primary,
780
+ path: [
781
+ {
782
+ id: config.model.id,
783
+ model: config.model
784
+ },
785
+ {
786
+ id: "primary",
787
+ label: "Primary"
788
+ }
789
+ ],
790
+ fieldConfigs: config.fieldConfigs
791
+ });
792
+ }
793
+ let itemInterface;
794
+ if (Object.keys(variation.items).length > 0) {
795
+ itemInterface = config.sourceFile.addInterface({
796
+ name: pascalCase(`${buildSharedSliceInterfaceName({ id: config.model.id })} ${variation.id} Item`),
797
+ docs: [
798
+ {
799
+ description: (writer) => {
800
+ const humanReadablePath = getHumanReadableFieldPath({
801
+ path: [
802
+ {
803
+ id: config.model.id,
804
+ model: config.model
805
+ },
806
+ {
807
+ id: "items",
808
+ label: "Items"
809
+ }
810
+ ]
811
+ });
812
+ writer.writeLine(`Item in ${humanReadablePath}`);
813
+ }
814
+ }
815
+ ]
816
+ });
817
+ addInterfacePropertiesForFields({
818
+ interface: itemInterface,
819
+ sourceFile: config.sourceFile,
820
+ fields: variation.items,
821
+ path: [
822
+ {
823
+ id: config.model.id,
824
+ model: config.model
825
+ },
826
+ {
827
+ id: "items",
828
+ label: "Items"
829
+ }
830
+ ],
831
+ fieldConfigs: config.fieldConfigs
832
+ });
833
+ }
834
+ const variationType = config.sourceFile.addTypeAlias({
835
+ name: pascalCase(`${buildSharedSliceInterfaceName({
836
+ id: config.model.id
837
+ })} ${variation.id}`),
838
+ type: `prismicT.SharedSliceVariation<"${variation.id}", ${primaryInterface ? `Simplify<${primaryInterface.getName()}>` : "Record<string, never>"}, ${itemInterface ? `Simplify<${itemInterface.getName()}>` : "never"}>`,
839
+ docs: [
840
+ {
841
+ description: (writer) => {
842
+ writer.writeLine(`${variation.name} variation for ${config.model.name} Slice`);
843
+ writer.blankLine();
844
+ writer.writeLine(`- **API ID**: \`${variation.id}\``);
845
+ writer.writeLine(`- **Description**: \`${variation.description}\``);
846
+ writer.writeLine(`- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`);
847
+ }
848
+ }
849
+ ]
850
+ });
851
+ variationTypeNames.push(variationType.getName());
852
+ }
853
+ const variationsType = config.sourceFile.addTypeAlias({
854
+ name: pascalCase(`${config.model.id} Slice Variation`),
855
+ type: variationTypeNames.length > 0 ? variationTypeNames.join(" | ") : "never",
856
+ docs: [
857
+ {
858
+ description: (writer) => {
859
+ const humanReadablePath = getHumanReadableFieldPath({
860
+ path: [
861
+ {
862
+ id: config.model.id,
863
+ model: config.model
864
+ }
865
+ ]
866
+ });
867
+ writer.writeLine(`Slice variation for *${humanReadablePath}*`);
868
+ }
869
+ }
870
+ ]
871
+ });
872
+ return config.sourceFile.addTypeAlias({
873
+ name: pascalCase(buildSharedSliceInterfaceName({
874
+ id: config.model.id
875
+ })),
876
+ type: `prismicT.SharedSlice<"${config.model.id}", ${variationsType.getName()}>`,
877
+ docs: [
878
+ {
879
+ description: (writer) => {
880
+ writer.writeLine(`${config.model.name} Shared Slice`);
881
+ writer.blankLine();
882
+ writer.writeLine(`- **API ID**: \`${config.model.id}\``);
883
+ writer.writeLine(`- **Description**: \`${config.model.description}\``);
884
+ writer.writeLine(`- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`);
885
+ }
886
+ }
887
+ ],
888
+ isExported: true
889
+ });
890
+ };
891
+
892
+ const getSourceFileText = (sourceFile) => {
893
+ const text = sourceFile.print().replace(new RegExp(BLANK_LINE_IDENTIFIER, "g"), "");
894
+ return text;
895
+ };
896
+
897
+ const generateTypes = (config = {}) => {
898
+ const project = new tsMorph.Project({
899
+ useInMemoryFileSystem: true
900
+ });
901
+ const sourceFile = project.createSourceFile("types.d.ts");
902
+ sourceFile.addImportDeclaration({
903
+ moduleSpecifier: "@prismicio/types",
904
+ namespaceImport: "prismicT",
905
+ isTypeOnly: true,
906
+ leadingTrivia: NON_EDITABLE_FILE_HEADER
907
+ });
908
+ sourceFile.addStatements(BLANK_LINE_IDENTIFIER);
909
+ sourceFile.addTypeAlias({
910
+ name: "Simplify",
911
+ typeParameters: [
912
+ {
913
+ name: "T"
914
+ }
915
+ ],
916
+ type: `{ [KeyType in keyof T]: T[KeyType] }`
917
+ });
918
+ if (config.customTypeModels) {
919
+ for (const model of config.customTypeModels) {
920
+ addTypeAliasForCustomType({
921
+ model,
922
+ sourceFile,
923
+ localeIDs: config.localeIDs || [],
924
+ fieldConfigs: config.fieldConfigs || {}
925
+ });
926
+ }
927
+ }
928
+ if (config.sharedSliceModels) {
929
+ for (const model of config.sharedSliceModels) {
930
+ addTypeAliasForSharedSlice({
931
+ model,
932
+ sourceFile,
933
+ fieldConfigs: config.fieldConfigs || {}
934
+ });
935
+ }
936
+ }
937
+ return getSourceFileText(sourceFile);
938
+ };
939
+
940
+ exports.generateTypes = generateTypes;
941
+ //# sourceMappingURL=index.cjs.map