prismic-ts-codegen 0.1.10 → 0.1.12

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.
Files changed (198) hide show
  1. package/dist/constants.cjs +19 -21
  2. package/dist/constants.cjs.map +1 -1
  3. package/dist/constants.d.ts +2 -3
  4. package/dist/constants.js +19 -21
  5. package/dist/constants.js.map +1 -1
  6. package/dist/generateTypes.cjs +71 -90
  7. package/dist/generateTypes.cjs.map +1 -1
  8. package/dist/generateTypes.d.ts +2 -1
  9. package/dist/generateTypes.js +71 -90
  10. package/dist/generateTypes.js.map +1 -1
  11. package/dist/lib/addBlankLine.cjs +12 -0
  12. package/dist/lib/addBlankLine.cjs.map +1 -0
  13. package/dist/lib/addBlankLine.d.ts +5 -0
  14. package/dist/lib/addBlankLine.js +12 -0
  15. package/dist/lib/addBlankLine.js.map +1 -0
  16. package/dist/lib/addLine.cjs +8 -0
  17. package/dist/lib/addLine.cjs.map +1 -0
  18. package/dist/lib/addLine.d.ts +1 -0
  19. package/dist/lib/addLine.js +8 -0
  20. package/dist/lib/addLine.js.map +1 -0
  21. package/dist/lib/addSection.cjs +8 -0
  22. package/dist/lib/addSection.cjs.map +1 -0
  23. package/dist/lib/addSection.d.ts +1 -0
  24. package/dist/lib/addSection.js +8 -0
  25. package/dist/lib/addSection.js.map +1 -0
  26. package/dist/lib/addTrailingNewLine.cjs +11 -0
  27. package/dist/lib/addTrailingNewLine.cjs.map +1 -0
  28. package/dist/lib/addTrailingNewLine.d.ts +5 -0
  29. package/dist/lib/addTrailingNewLine.js +11 -0
  30. package/dist/lib/addTrailingNewLine.js.map +1 -0
  31. package/dist/lib/buildCustomTypeDataType.cjs +51 -0
  32. package/dist/lib/buildCustomTypeDataType.cjs.map +1 -0
  33. package/dist/lib/buildCustomTypeDataType.d.ts +13 -0
  34. package/dist/lib/buildCustomTypeDataType.js +51 -0
  35. package/dist/lib/buildCustomTypeDataType.js.map +1 -0
  36. package/dist/lib/buildCustomTypeType.cjs +60 -0
  37. package/dist/lib/buildCustomTypeType.cjs.map +1 -0
  38. package/dist/lib/buildCustomTypeType.d.ts +17 -0
  39. package/dist/lib/buildCustomTypeType.js +60 -0
  40. package/dist/lib/buildCustomTypeType.js.map +1 -0
  41. package/dist/lib/buildFieldDocs.cjs +67 -35
  42. package/dist/lib/buildFieldDocs.cjs.map +1 -1
  43. package/dist/lib/buildFieldDocs.d.ts +7 -11
  44. package/dist/lib/buildFieldDocs.js +67 -35
  45. package/dist/lib/buildFieldDocs.js.map +1 -1
  46. package/dist/lib/buildFieldProperties.cjs +300 -0
  47. package/dist/lib/buildFieldProperties.cjs.map +1 -0
  48. package/dist/lib/buildFieldProperties.d.ts +14 -0
  49. package/dist/lib/buildFieldProperties.js +300 -0
  50. package/dist/lib/buildFieldProperties.js.map +1 -0
  51. package/dist/lib/buildSharedSliceType.cjs +140 -0
  52. package/dist/lib/buildSharedSliceType.cjs.map +1 -0
  53. package/dist/lib/buildSharedSliceType.d.ts +16 -0
  54. package/dist/lib/buildSharedSliceType.js +140 -0
  55. package/dist/lib/buildSharedSliceType.js.map +1 -0
  56. package/dist/lib/buildTypeName.cjs +4 -2
  57. package/dist/lib/buildTypeName.cjs.map +1 -1
  58. package/dist/lib/buildTypeName.js +4 -2
  59. package/dist/lib/buildTypeName.js.map +1 -1
  60. package/dist/lib/buildUnion.cjs +7 -0
  61. package/dist/lib/buildUnion.cjs.map +1 -0
  62. package/dist/lib/buildUnion.d.ts +1 -0
  63. package/dist/lib/buildUnion.js +7 -0
  64. package/dist/lib/buildUnion.js.map +1 -0
  65. package/dist/lib/checkHasUIDFIeld.cjs +7 -0
  66. package/dist/lib/checkHasUIDFIeld.cjs.map +1 -0
  67. package/dist/lib/checkHasUIDFIeld.d.ts +2 -0
  68. package/dist/lib/checkHasUIDFIeld.js +7 -0
  69. package/dist/lib/checkHasUIDFIeld.js.map +1 -0
  70. package/dist/lib/getAPIIDPath.cjs +18 -14
  71. package/dist/lib/getAPIIDPath.cjs.map +1 -1
  72. package/dist/lib/getAPIIDPath.d.ts +4 -8
  73. package/dist/lib/getAPIIDPath.js +18 -14
  74. package/dist/lib/getAPIIDPath.js.map +1 -1
  75. package/dist/lib/getCacheKey.cjs +25 -0
  76. package/dist/lib/getCacheKey.cjs.map +1 -0
  77. package/dist/lib/getCacheKey.d.ts +9 -0
  78. package/dist/lib/getCacheKey.js +8 -0
  79. package/dist/lib/getCacheKey.js.map +1 -0
  80. package/dist/lib/getHumanReadableModelName.cjs +13 -17
  81. package/dist/lib/getHumanReadableModelName.cjs.map +1 -1
  82. package/dist/lib/getHumanReadableModelName.d.ts +3 -3
  83. package/dist/lib/getHumanReadableModelName.js +13 -17
  84. package/dist/lib/getHumanReadableModelName.js.map +1 -1
  85. package/dist/lib/{getHumanReadableFieldPath.cjs → getHumanReadablePath.cjs} +8 -8
  86. package/dist/lib/getHumanReadablePath.cjs.map +1 -0
  87. package/dist/lib/getHumanReadablePath.d.ts +6 -0
  88. package/dist/lib/{getHumanReadableFieldPath.js → getHumanReadablePath.js} +8 -8
  89. package/dist/lib/getHumanReadablePath.js.map +1 -0
  90. package/dist/types.d.ts +9 -1
  91. package/package.json +19 -18
  92. package/src/constants.ts +19 -22
  93. package/src/generateTypes.ts +109 -108
  94. package/src/lib/addBlankLine.ts +13 -0
  95. package/src/lib/addLine.ts +5 -0
  96. package/src/lib/addSection.ts +5 -0
  97. package/src/lib/addTrailingNewLine.ts +14 -0
  98. package/src/lib/buildCustomTypeDataType.ts +74 -0
  99. package/src/lib/buildCustomTypeType.ts +101 -0
  100. package/src/lib/buildFieldDocs.ts +128 -68
  101. package/src/lib/buildFieldProperties.ts +513 -0
  102. package/src/lib/buildSharedSliceType.ts +213 -0
  103. package/src/lib/buildTypeName.ts +4 -2
  104. package/src/lib/buildUnion.ts +3 -0
  105. package/src/lib/checkHasUIDFIeld.ts +5 -0
  106. package/src/lib/getAPIIDPath.ts +40 -41
  107. package/src/lib/getCacheKey.ts +13 -0
  108. package/src/lib/getHumanReadableModelName.ts +23 -20
  109. package/src/lib/getHumanReadablePath.ts +24 -0
  110. package/src/types.ts +11 -1
  111. package/dist/lib/addInterfacePropertiesForFields.cjs +0 -489
  112. package/dist/lib/addInterfacePropertiesForFields.cjs.map +0 -1
  113. package/dist/lib/addInterfacePropertiesForFields.d.ts +0 -21
  114. package/dist/lib/addInterfacePropertiesForFields.js +0 -489
  115. package/dist/lib/addInterfacePropertiesForFields.js.map +0 -1
  116. package/dist/lib/addTypeAliasForCustomType.cjs +0 -81
  117. package/dist/lib/addTypeAliasForCustomType.cjs.map +0 -1
  118. package/dist/lib/addTypeAliasForCustomType.d.ts +0 -11
  119. package/dist/lib/addTypeAliasForCustomType.js +0 -81
  120. package/dist/lib/addTypeAliasForCustomType.js.map +0 -1
  121. package/dist/lib/addTypeAliasForSharedSlice.cjs +0 -149
  122. package/dist/lib/addTypeAliasForSharedSlice.cjs.map +0 -1
  123. package/dist/lib/addTypeAliasForSharedSlice.d.ts +0 -10
  124. package/dist/lib/addTypeAliasForSharedSlice.js +0 -149
  125. package/dist/lib/addTypeAliasForSharedSlice.js.map +0 -1
  126. package/dist/lib/buildSharedSliceInterfaceNamePart.cjs +0 -8
  127. package/dist/lib/buildSharedSliceInterfaceNamePart.cjs.map +0 -1
  128. package/dist/lib/buildSharedSliceInterfaceNamePart.d.ts +0 -5
  129. package/dist/lib/buildSharedSliceInterfaceNamePart.js +0 -8
  130. package/dist/lib/buildSharedSliceInterfaceNamePart.js.map +0 -1
  131. package/dist/lib/getFieldDocumentationURL.cjs +0 -8
  132. package/dist/lib/getFieldDocumentationURL.cjs.map +0 -1
  133. package/dist/lib/getFieldDocumentationURL.d.ts +0 -6
  134. package/dist/lib/getFieldDocumentationURL.js +0 -8
  135. package/dist/lib/getFieldDocumentationURL.js.map +0 -1
  136. package/dist/lib/getHumanReadableFieldPath.cjs.map +0 -1
  137. package/dist/lib/getHumanReadableFieldPath.d.ts +0 -10
  138. package/dist/lib/getHumanReadableFieldPath.js.map +0 -1
  139. package/dist/lib/getHumanReadableFieldType.cjs +0 -36
  140. package/dist/lib/getHumanReadableFieldType.cjs.map +0 -1
  141. package/dist/lib/getHumanReadableFieldType.d.ts +0 -6
  142. package/dist/lib/getHumanReadableFieldType.js +0 -36
  143. package/dist/lib/getHumanReadableFieldType.js.map +0 -1
  144. package/dist/lib/getSourceFileText.cjs +0 -9
  145. package/dist/lib/getSourceFileText.cjs.map +0 -1
  146. package/dist/lib/getSourceFileText.d.ts +0 -2
  147. package/dist/lib/getSourceFileText.js +0 -9
  148. package/dist/lib/getSourceFileText.js.map +0 -1
  149. package/dist/lib/hasOwnProperty.cjs +0 -7
  150. package/dist/lib/hasOwnProperty.cjs.map +0 -1
  151. package/dist/lib/hasOwnProperty.d.ts +0 -10
  152. package/dist/lib/hasOwnProperty.js +0 -7
  153. package/dist/lib/hasOwnProperty.js.map +0 -1
  154. package/dist/lib/isCustomTypeModel.cjs +0 -7
  155. package/dist/lib/isCustomTypeModel.cjs.map +0 -1
  156. package/dist/lib/isCustomTypeModel.d.ts +0 -2
  157. package/dist/lib/isCustomTypeModel.js +0 -7
  158. package/dist/lib/isCustomTypeModel.js.map +0 -1
  159. package/dist/lib/isCustomTypeModelField.cjs +0 -7
  160. package/dist/lib/isCustomTypeModelField.cjs.map +0 -1
  161. package/dist/lib/isCustomTypeModelField.d.ts +0 -2
  162. package/dist/lib/isCustomTypeModelField.js +0 -7
  163. package/dist/lib/isCustomTypeModelField.js.map +0 -1
  164. package/dist/lib/isCustomTypeModelSlice.cjs +0 -8
  165. package/dist/lib/isCustomTypeModelSlice.cjs.map +0 -1
  166. package/dist/lib/isCustomTypeModelSlice.d.ts +0 -2
  167. package/dist/lib/isCustomTypeModelSlice.js +0 -8
  168. package/dist/lib/isCustomTypeModelSlice.js.map +0 -1
  169. package/dist/lib/isSharedSliceModel.cjs +0 -8
  170. package/dist/lib/isSharedSliceModel.cjs.map +0 -1
  171. package/dist/lib/isSharedSliceModel.d.ts +0 -2
  172. package/dist/lib/isSharedSliceModel.js +0 -8
  173. package/dist/lib/isSharedSliceModel.js.map +0 -1
  174. package/dist/lib/pascalCase.cjs +0 -8
  175. package/dist/lib/pascalCase.cjs.map +0 -1
  176. package/dist/lib/pascalCase.d.ts +0 -1
  177. package/dist/lib/pascalCase.js +0 -8
  178. package/dist/lib/pascalCase.js.map +0 -1
  179. package/dist/lib/writeFieldDocsDescription.cjs +0 -29
  180. package/dist/lib/writeFieldDocsDescription.cjs.map +0 -1
  181. package/dist/lib/writeFieldDocsDescription.d.ts +0 -13
  182. package/dist/lib/writeFieldDocsDescription.js +0 -29
  183. package/dist/lib/writeFieldDocsDescription.js.map +0 -1
  184. package/src/lib/addInterfacePropertiesForFields.ts +0 -665
  185. package/src/lib/addTypeAliasForCustomType.ts +0 -120
  186. package/src/lib/addTypeAliasForSharedSlice.ts +0 -201
  187. package/src/lib/buildSharedSliceInterfaceNamePart.ts +0 -11
  188. package/src/lib/getFieldDocumentationURL.ts +0 -15
  189. package/src/lib/getHumanReadableFieldPath.ts +0 -36
  190. package/src/lib/getHumanReadableFieldType.ts +0 -55
  191. package/src/lib/getSourceFileText.ts +0 -14
  192. package/src/lib/hasOwnProperty.ts +0 -15
  193. package/src/lib/isCustomTypeModel.ts +0 -5
  194. package/src/lib/isCustomTypeModelField.ts +0 -7
  195. package/src/lib/isCustomTypeModelSlice.ts +0 -14
  196. package/src/lib/isSharedSliceModel.ts +0 -14
  197. package/src/lib/pascalCase.ts +0 -9
  198. package/src/lib/writeFieldDocsDescription.ts +0 -51
@@ -1,75 +1,135 @@
1
- import type {
2
- CustomTypeModel,
3
- CustomTypeModelField,
4
- CustomTypeModelSlice,
5
- SharedSliceModel,
6
- } from "@prismicio/client";
7
- import type { JSDocableNodeStructure } from "ts-morph";
1
+ import { CustomTypeModelField } from "@prismicio/client";
8
2
 
9
- import { PathElement } from "../types";
3
+ import { FieldPath } from "../types";
10
4
 
5
+ import { FIELD_DOCUMENTATION_URLS } from "../constants";
6
+
7
+ import { addLine } from "./addLine";
11
8
  import { getAPIIDPath } from "./getAPIIDPath";
12
- import { getFieldDocumentationURL } from "./getFieldDocumentationURL";
13
- import { getHumanReadableFieldPath } from "./getHumanReadableFieldPath";
14
- import { getHumanReadableFieldType } from "./getHumanReadableFieldType";
15
9
  import { getHumanReadableModelName } from "./getHumanReadableModelName";
16
- import { writeFieldDocsDescription } from "./writeFieldDocsDescription";
17
-
18
- type BuildFieldDocsConfig = {
19
- id: string;
20
- model: CustomTypeModelField;
21
- path: [
22
- PathElement<CustomTypeModel | SharedSliceModel>,
23
- ...PathElement<CustomTypeModelField | CustomTypeModelSlice>[],
24
- ];
25
- tabName?: string;
10
+ import { getHumanReadablePath } from "./getHumanReadablePath";
11
+
12
+ type GetFieldHumanReadableTypeArgs = {
13
+ field: CustomTypeModelField;
26
14
  };
27
15
 
28
- export const buildFieldDocs = (
29
- config: BuildFieldDocsConfig,
30
- ): NonNullable<JSDocableNodeStructure["docs"]> => {
31
- return [
32
- {
33
- description: (writer) => {
34
- const name = getHumanReadableModelName({
35
- id: config.id,
36
- model: config.model,
37
- });
38
- const humanReadablePath = getHumanReadableFieldPath({
39
- path: config.path,
40
- });
41
-
42
- const fieldType = getHumanReadableFieldType({
43
- model: config.model,
44
- });
45
-
46
- const placeholder =
47
- config.model.config &&
48
- "placeholder" in config.model.config &&
49
- config.model.config.placeholder
50
- ? config.model.config.placeholder
51
- : `*None*`;
52
-
53
- const defaultValue =
54
- config.model.config && "default_value" in config.model.config
55
- ? config.model.config.default_value
56
- : undefined;
57
-
58
- const apiIDPath = getAPIIDPath({
59
- path: [...config.path, { id: config.id, model: config.model }],
60
- });
61
-
62
- writeFieldDocsDescription({
63
- writer,
64
- description: `${name} field in *${humanReadablePath}*`,
65
- fieldType,
66
- placeholder,
67
- defaultValue,
68
- apiIDPath,
69
- tabName: config.tabName,
70
- documentationURL: getFieldDocumentationURL({ model: config.model }),
71
- });
72
- },
73
- },
74
- ];
16
+ function getHumanReadableFieldType(
17
+ args: GetFieldHumanReadableTypeArgs,
18
+ ): string {
19
+ switch (args.field.type) {
20
+ case "StructuredText": {
21
+ const isTitleField =
22
+ args.field.config &&
23
+ "single" in args.field.config &&
24
+ args.field.config.single &&
25
+ args.field.config.single
26
+ .split(",")
27
+ .every((blockType) => /heading/.test(blockType));
28
+
29
+ return isTitleField ? "Title" : "Rich Text";
30
+ }
31
+
32
+ case "IntegrationFields": {
33
+ const catalog = args.field.config?.catalog;
34
+
35
+ return `Integration Fields (Catalog: ${
36
+ catalog ? `\`${catalog}\`` : "*unknown*"
37
+ })`;
38
+ }
39
+
40
+ case "Link": {
41
+ switch (args.field.config?.select) {
42
+ case "document": {
43
+ return "Content Relationship";
44
+ }
45
+
46
+ case "media": {
47
+ return "Link to Media";
48
+ }
49
+
50
+ default: {
51
+ return "Link";
52
+ }
53
+ }
54
+ }
55
+
56
+ case "Slices": {
57
+ return "Slice Zone";
58
+ }
59
+
60
+ default: {
61
+ return args.field.type;
62
+ }
63
+ }
64
+ }
65
+
66
+ type BuildFieldDocsArgs = {
67
+ name: string;
68
+ field: CustomTypeModelField;
69
+ path: FieldPath;
70
+ tabName?: string;
75
71
  };
72
+
73
+ export function buildFieldDocs(args: BuildFieldDocsArgs): string {
74
+ let result = "/**";
75
+
76
+ const humanReadableName = getHumanReadableModelName({
77
+ model: args.field,
78
+ name: args.name,
79
+ });
80
+ const humanReadablePath = getHumanReadablePath({ path: args.path });
81
+ const humanReadableFieldType = getHumanReadableFieldType({
82
+ field: args.field,
83
+ });
84
+
85
+ result = addLine(
86
+ ` * ${humanReadableName} field in *${humanReadablePath}*`,
87
+ result,
88
+ );
89
+
90
+ result = addLine(" *", result);
91
+
92
+ result = addLine(` * - **Field Type**: ${humanReadableFieldType}`, result);
93
+
94
+ const placeholder =
95
+ (args.field.config &&
96
+ "placeholder" in args.field.config &&
97
+ args.field.config.placeholder) ||
98
+ `*None*`;
99
+ result = addLine(` * - **Placeholder**: ${placeholder}`, result);
100
+
101
+ const defaultValue =
102
+ args.field.config && "default_value" in args.field.config
103
+ ? args.field.config.default_value
104
+ : undefined;
105
+ if (defaultValue !== undefined) {
106
+ const stringifiedDefaultValue =
107
+ typeof defaultValue === "boolean" ? `${defaultValue}` : defaultValue;
108
+
109
+ result = addLine(
110
+ ` * - **Default Value**: ${stringifiedDefaultValue}`,
111
+ result,
112
+ );
113
+ }
114
+
115
+ const apiIDPath = getAPIIDPath({
116
+ path: [...args.path, { name: args.name, model: args.field }],
117
+ });
118
+ result = addLine(` * - **API ID Path**: ${apiIDPath}`, result);
119
+
120
+ if (args.tabName) {
121
+ result = addLine(` * - **Tab**: ${args.tabName}`, result);
122
+ }
123
+
124
+ const documentationURL =
125
+ FIELD_DOCUMENTATION_URLS[
126
+ args.field.type as keyof typeof FIELD_DOCUMENTATION_URLS
127
+ ];
128
+ if (documentationURL) {
129
+ result = addLine(` * - **Documentation**: ${documentationURL}`, result);
130
+ }
131
+
132
+ result = addLine(" */", result);
133
+
134
+ return result;
135
+ }
@@ -0,0 +1,513 @@
1
+ import {
2
+ CustomTypeModelField,
3
+ CustomTypeModelFieldType,
4
+ CustomTypeModelLinkSelectType,
5
+ } from "@prismicio/client";
6
+ import { source, stripIndent } from "common-tags";
7
+
8
+ import { AuxiliaryType, FieldConfigs, FieldPath } from "../types";
9
+
10
+ import { addLine } from "./addLine";
11
+ import { addSection } from "./addSection";
12
+ import { buildFieldDocs } from "./buildFieldDocs";
13
+ import { buildTypeName } from "./buildTypeName";
14
+ import { buildUnion } from "./buildUnion";
15
+ import { getHumanReadablePath } from "./getHumanReadablePath";
16
+
17
+ type BuildFieldPropertyArgs = Pick<
18
+ BuildFieldPropertiesArgs,
19
+ "path" | "fieldConfigs" | "tabName"
20
+ > & {
21
+ name: string;
22
+ field: CustomTypeModelField;
23
+ };
24
+
25
+ type BuildFieldPropertyReturnType = {
26
+ code: string;
27
+ auxiliaryTypes: AuxiliaryType[];
28
+ };
29
+
30
+ function buildFieldProperty(
31
+ args: BuildFieldPropertyArgs,
32
+ ): BuildFieldPropertyReturnType {
33
+ let code = buildFieldDocs({
34
+ name: args.name,
35
+ field: args.field,
36
+ path: args.path,
37
+ tabName: args.tabName,
38
+ });
39
+
40
+ const auxiliaryTypes: AuxiliaryType[] = [];
41
+
42
+ const name =
43
+ args.name.includes("-") ||
44
+ args.name.includes(":") ||
45
+ /^[0-9]/.test(args.name)
46
+ ? `"${args.name}"`
47
+ : args.name;
48
+
49
+ switch (args.field.type) {
50
+ case CustomTypeModelFieldType.UID: {
51
+ // UID fields are not included in Data.
52
+ break;
53
+ }
54
+
55
+ case CustomTypeModelFieldType.Boolean: {
56
+ code = addLine(`${name}: prismic.BooleanField;`, code);
57
+
58
+ break;
59
+ }
60
+
61
+ case CustomTypeModelFieldType.Color: {
62
+ code = addLine(`${name}: prismic.ColorField;`, code);
63
+
64
+ break;
65
+ }
66
+
67
+ case CustomTypeModelFieldType.Date: {
68
+ code = addLine(`${name}: prismic.DateField;`, code);
69
+
70
+ break;
71
+ }
72
+
73
+ case CustomTypeModelFieldType.Embed: {
74
+ const providerTypes: string[] = [];
75
+
76
+ if (args.fieldConfigs.embed?.providerTypes) {
77
+ for (const providerType in args.fieldConfigs.embed?.providerTypes) {
78
+ const configuredProviderType =
79
+ args.fieldConfigs.embed?.providerTypes[providerType];
80
+
81
+ providerTypes.push(
82
+ `({ provider_name: "${providerType}" } & ${configuredProviderType})`,
83
+ );
84
+ }
85
+ }
86
+
87
+ const providerTypesUnion = buildUnion(providerTypes);
88
+
89
+ code =
90
+ providerTypes.length > 0
91
+ ? addLine(
92
+ `${name}: prismic.EmbedField<prismic.AnyOEmbed & prismic.OEmbedExtra & (${providerTypesUnion})>`,
93
+ code,
94
+ )
95
+ : addLine(`${name}: prismic.EmbedField`, code);
96
+
97
+ break;
98
+ }
99
+
100
+ case CustomTypeModelFieldType.GeoPoint: {
101
+ code = addLine(`${name}: prismic.GeoPointField;`, code);
102
+
103
+ break;
104
+ }
105
+
106
+ case CustomTypeModelFieldType.Image: {
107
+ if (
108
+ args.field.config?.thumbnails &&
109
+ args.field.config.thumbnails.length > 0
110
+ ) {
111
+ const thumbnailNames = buildUnion(
112
+ args.field.config.thumbnails.map((thumb) => `"${thumb.name}"`),
113
+ );
114
+
115
+ code = addLine(`${name}: prismic.ImageField<${thumbnailNames}>;`, code);
116
+ } else {
117
+ code = addLine(`${name}: prismic.ImageField<never>;`, code);
118
+ }
119
+
120
+ break;
121
+ }
122
+
123
+ case CustomTypeModelFieldType.Integration: {
124
+ const catalogType = args.field.config?.catalog
125
+ ? args.fieldConfigs.integrationFields?.catalogTypes?.[
126
+ args.field.config.catalog
127
+ ]
128
+ : undefined;
129
+
130
+ if (catalogType) {
131
+ code = addLine(
132
+ `${name}: prismic.IntegrationField<${catalogType}>;`,
133
+ code,
134
+ );
135
+ } else {
136
+ code = addLine(`${name}: prismic.IntegrationField;`, code);
137
+ }
138
+
139
+ break;
140
+ }
141
+
142
+ case CustomTypeModelFieldType.Link: {
143
+ switch (args.field.config?.select) {
144
+ case CustomTypeModelLinkSelectType.Document: {
145
+ if (
146
+ "customtypes" in args.field.config &&
147
+ args.field.config.customtypes &&
148
+ args.field.config.customtypes.length > 0
149
+ ) {
150
+ const customTypeIDsUnion = buildUnion(
151
+ args.field.config.customtypes.map((type) => `"${type}"`),
152
+ );
153
+
154
+ code = addLine(
155
+ `${name}: prismic.ContentRelationshipField<${customTypeIDsUnion}>;`,
156
+ code,
157
+ );
158
+ } else {
159
+ code = addLine(`${name}: prismic.ContentRelationshipField;`, code);
160
+ }
161
+
162
+ break;
163
+ }
164
+
165
+ case CustomTypeModelLinkSelectType.Media: {
166
+ code = addLine(`${name}: prismic.LinkToMediaField;`, code);
167
+
168
+ break;
169
+ }
170
+
171
+ default: {
172
+ code = addLine(`${name}: prismic.LinkField;`, code);
173
+ }
174
+ }
175
+
176
+ break;
177
+ }
178
+
179
+ case CustomTypeModelFieldType.Number: {
180
+ code = addLine(`${name}: prismic.NumberField;`, code);
181
+
182
+ break;
183
+ }
184
+
185
+ case CustomTypeModelFieldType.StructuredText: {
186
+ const isTitleField =
187
+ args.field.config &&
188
+ "single" in args.field.config &&
189
+ args.field.config.single &&
190
+ args.field.config.single
191
+ .split(",")
192
+ .every((blockType) => /heading/.test(blockType));
193
+
194
+ if (isTitleField) {
195
+ code = addLine(`${name}: prismic.TitleField;`, code);
196
+ } else {
197
+ code = addLine(`${name}: prismic.RichTextField;`, code);
198
+ }
199
+
200
+ break;
201
+ }
202
+
203
+ case CustomTypeModelFieldType.Select: {
204
+ const options: string[] =
205
+ args.field.config?.options?.map((option) => `"${option}"`) || [];
206
+ const optionsType = options.length ? buildUnion(options) : "string";
207
+
208
+ const hasDefault = Boolean(args.field.config?.default_value);
209
+
210
+ if (hasDefault) {
211
+ code = addLine(
212
+ `${name}: prismic.SelectField<${optionsType}, "filled">;`,
213
+ code,
214
+ );
215
+ } else {
216
+ code = addLine(
217
+ `${name}: prismic.SelectField${
218
+ options.length > 0 ? `<${optionsType}>` : ""
219
+ };`,
220
+ code,
221
+ );
222
+ }
223
+
224
+ break;
225
+ }
226
+
227
+ case CustomTypeModelFieldType.Text: {
228
+ code = addLine(`${name}: prismic.KeyTextField;`, code);
229
+
230
+ break;
231
+ }
232
+
233
+ case CustomTypeModelFieldType.Timestamp: {
234
+ code = addLine(`${name}: prismic.TimestampField;`, code);
235
+
236
+ break;
237
+ }
238
+
239
+ case CustomTypeModelFieldType.Group: {
240
+ const itemName = buildTypeName(
241
+ args.path[0].name,
242
+ "Document",
243
+ "Data",
244
+ args.name,
245
+ "Item",
246
+ );
247
+
248
+ const path: FieldPath = [
249
+ ...args.path,
250
+ {
251
+ name: name,
252
+ model: args.field,
253
+ },
254
+ ];
255
+ const humanReadablePath = getHumanReadablePath({ path });
256
+
257
+ const itemFieldProperties = buildFieldProperties({
258
+ fields: args.field.config?.fields || {},
259
+ fieldConfigs: args.fieldConfigs,
260
+ path,
261
+ });
262
+
263
+ auxiliaryTypes.push({
264
+ name: itemName,
265
+ code: source`
266
+ /**
267
+ * Item in *${humanReadablePath}*
268
+ */
269
+ export interface ${itemName} {
270
+ ${itemFieldProperties.code}
271
+ }
272
+ `,
273
+ });
274
+
275
+ code = addLine(
276
+ `${name}: prismic.GroupField<Simplify<${itemName}>>;`,
277
+ code,
278
+ );
279
+
280
+ break;
281
+ }
282
+
283
+ case CustomTypeModelFieldType.Slices: {
284
+ const choiceNames: string[] = [];
285
+
286
+ if (args.field.config?.choices) {
287
+ for (const choiceID in args.field.config.choices) {
288
+ const choice = args.field.config.choices[choiceID];
289
+
290
+ if (choice.type === "SharedSlice") {
291
+ // TODO: Verify that the Shared Slice
292
+ // is provided to the global
293
+ // `sharedSlices` array. If it is not,
294
+ // the type won't exist, so we can't
295
+ // add it to the union. We should
296
+ // probably throw an error if we reach
297
+ // that state, or maybe the input can
298
+ // be validated early so we don't
299
+ // generate any code using invalid
300
+ // models.
301
+ choiceNames.push(buildTypeName(choiceID, "Slice"));
302
+ } else if (choice.type === "Slice") {
303
+ const sliceName = buildTypeName(
304
+ args.path[0].name,
305
+ "Document",
306
+ "Data",
307
+ args.name,
308
+ choiceID,
309
+ "Slice",
310
+ );
311
+
312
+ let primaryInterfaceName: string | undefined;
313
+ if (
314
+ choice["non-repeat"] &&
315
+ Object.keys(choice["non-repeat"]).length > 0
316
+ ) {
317
+ primaryInterfaceName = buildTypeName(sliceName, "Primary");
318
+
319
+ const path: FieldPath = [
320
+ ...args.path,
321
+ {
322
+ name: args.name,
323
+ model: args.field,
324
+ },
325
+ {
326
+ name: choiceID,
327
+ model: choice,
328
+ },
329
+ {
330
+ name: "primary",
331
+ label: "Primary",
332
+ },
333
+ ];
334
+ const humanReadablePath = getHumanReadablePath({ path });
335
+
336
+ const primaryFieldProperties = buildFieldProperties({
337
+ fields: choice["non-repeat"],
338
+ fieldConfigs: args.fieldConfigs,
339
+ path,
340
+ });
341
+
342
+ let primaryCode = stripIndent`
343
+ /**
344
+ * Primary content in *${humanReadablePath}*
345
+ */
346
+ `;
347
+ primaryCode = primaryFieldProperties.code
348
+ ? addLine(
349
+ source`
350
+ export interface ${primaryInterfaceName} {
351
+ ${primaryFieldProperties.code}
352
+ }
353
+ `,
354
+ primaryCode,
355
+ )
356
+ : addLine(
357
+ `export interface ${primaryInterfaceName} {}`,
358
+ primaryCode,
359
+ );
360
+
361
+ auxiliaryTypes.push({
362
+ name: primaryInterfaceName,
363
+ code: primaryCode,
364
+ });
365
+ }
366
+
367
+ let itemInterfaceName: string | undefined;
368
+ if (choice.repeat && Object.keys(choice.repeat).length > 0) {
369
+ itemInterfaceName = buildTypeName(sliceName, "Item");
370
+
371
+ const path: FieldPath = [
372
+ ...args.path,
373
+ {
374
+ name: args.name,
375
+ model: args.field,
376
+ },
377
+ {
378
+ name: choiceID,
379
+ model: choice,
380
+ },
381
+ {
382
+ name: "items",
383
+ label: "Items",
384
+ },
385
+ ];
386
+ const humanReadablePath = getHumanReadablePath({ path });
387
+
388
+ const itemFieldProperties = buildFieldProperties({
389
+ fields: choice.repeat,
390
+ fieldConfigs: args.fieldConfigs,
391
+ path,
392
+ });
393
+
394
+ let itemCode = stripIndent`
395
+ /**
396
+ * Item content in *${humanReadablePath}*
397
+ */
398
+ `;
399
+ itemCode = itemFieldProperties.code
400
+ ? addLine(
401
+ source`
402
+ export interface ${itemInterfaceName} {
403
+ ${itemFieldProperties.code}
404
+ }
405
+ `,
406
+ itemCode,
407
+ )
408
+ : addLine(`export interface ${itemInterfaceName} {}`, itemCode);
409
+
410
+ auxiliaryTypes.push({
411
+ name: itemInterfaceName,
412
+ code: itemCode,
413
+ });
414
+ }
415
+
416
+ auxiliaryTypes.push({
417
+ name: sliceName,
418
+ code: stripIndent`
419
+ /**
420
+ * Slice for *${getHumanReadablePath({
421
+ path: [
422
+ ...args.path,
423
+ {
424
+ name: args.name,
425
+ model: args.field,
426
+ },
427
+ ],
428
+ })}*
429
+ */
430
+ export type ${sliceName} = prismic.Slice<"${choiceID}", ${
431
+ primaryInterfaceName
432
+ ? `Simplify<${primaryInterfaceName}>`
433
+ : `Record<string, never>`
434
+ }, ${
435
+ itemInterfaceName ? `Simplify<${itemInterfaceName}>` : `never`
436
+ }>
437
+ `,
438
+ });
439
+
440
+ choiceNames.push(sliceName);
441
+ }
442
+ }
443
+ }
444
+
445
+ const choiceUnionName = buildTypeName(
446
+ args.path[0].name,
447
+ "Document",
448
+ "Data",
449
+ args.name,
450
+ "Slice",
451
+ );
452
+ const choiceUnion = buildUnion(choiceNames);
453
+ auxiliaryTypes.push({
454
+ name: choiceUnionName,
455
+ code: `type ${choiceUnionName} = ${choiceUnion}`,
456
+ });
457
+
458
+ code = addLine(`${name}: prismic.SliceZone<${choiceUnionName}>;`, code);
459
+
460
+ break;
461
+ }
462
+
463
+ default: {
464
+ code = addLine(`${name}: unknown;`, code);
465
+ }
466
+ }
467
+
468
+ return {
469
+ code,
470
+ auxiliaryTypes,
471
+ };
472
+ }
473
+
474
+ type BuildFieldPropertiesArgs = {
475
+ fields: Record<string, CustomTypeModelField>;
476
+ path: FieldPath;
477
+ fieldConfigs: FieldConfigs;
478
+ tabName?: string;
479
+ };
480
+
481
+ type BuildFieldPropertiesReturnType = {
482
+ code: string;
483
+ auxiliaryTypes: AuxiliaryType[];
484
+ };
485
+
486
+ export function buildFieldProperties(
487
+ args: BuildFieldPropertiesArgs,
488
+ ): BuildFieldPropertiesReturnType {
489
+ let code = "";
490
+
491
+ const auxiliaryTypes: AuxiliaryType[] = [];
492
+
493
+ for (const name in args.fields) {
494
+ const field = args.fields[name];
495
+
496
+ const fieldProperty = buildFieldProperty({
497
+ name,
498
+ field,
499
+ path: args.path,
500
+ fieldConfigs: args.fieldConfigs,
501
+ tabName: args.tabName,
502
+ });
503
+
504
+ code = addSection(fieldProperty.code, code);
505
+
506
+ auxiliaryTypes.push(...fieldProperty.auxiliaryTypes);
507
+ }
508
+
509
+ return {
510
+ code,
511
+ auxiliaryTypes,
512
+ };
513
+ }