prismic-ts-codegen 0.1.11 → 0.1.13

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 (202) hide show
  1. package/dist/_node_modules/quick-lru/index.cjs +234 -0
  2. package/dist/_node_modules/quick-lru/index.cjs.map +1 -0
  3. package/dist/_node_modules/quick-lru/index.js +235 -0
  4. package/dist/_node_modules/quick-lru/index.js.map +1 -0
  5. package/dist/constants.cjs +19 -21
  6. package/dist/constants.cjs.map +1 -1
  7. package/dist/constants.d.ts +2 -3
  8. package/dist/constants.js +19 -21
  9. package/dist/constants.js.map +1 -1
  10. package/dist/generateTypes.cjs +71 -90
  11. package/dist/generateTypes.cjs.map +1 -1
  12. package/dist/generateTypes.d.ts +2 -1
  13. package/dist/generateTypes.js +71 -90
  14. package/dist/generateTypes.js.map +1 -1
  15. package/dist/lib/addBlankLine.cjs +12 -0
  16. package/dist/lib/addBlankLine.cjs.map +1 -0
  17. package/dist/lib/addBlankLine.d.ts +5 -0
  18. package/dist/lib/addBlankLine.js +12 -0
  19. package/dist/lib/addBlankLine.js.map +1 -0
  20. package/dist/lib/addLine.cjs +8 -0
  21. package/dist/lib/addLine.cjs.map +1 -0
  22. package/dist/lib/addLine.d.ts +1 -0
  23. package/dist/lib/addLine.js +8 -0
  24. package/dist/lib/addLine.js.map +1 -0
  25. package/dist/lib/addSection.cjs +8 -0
  26. package/dist/lib/addSection.cjs.map +1 -0
  27. package/dist/lib/addSection.d.ts +1 -0
  28. package/dist/lib/addSection.js +8 -0
  29. package/dist/lib/addSection.js.map +1 -0
  30. package/dist/lib/addTrailingNewLine.cjs +11 -0
  31. package/dist/lib/addTrailingNewLine.cjs.map +1 -0
  32. package/dist/lib/addTrailingNewLine.d.ts +5 -0
  33. package/dist/lib/addTrailingNewLine.js +11 -0
  34. package/dist/lib/addTrailingNewLine.js.map +1 -0
  35. package/dist/lib/buildCustomTypeDataType.cjs +51 -0
  36. package/dist/lib/buildCustomTypeDataType.cjs.map +1 -0
  37. package/dist/lib/buildCustomTypeDataType.d.ts +13 -0
  38. package/dist/lib/buildCustomTypeDataType.js +51 -0
  39. package/dist/lib/buildCustomTypeDataType.js.map +1 -0
  40. package/dist/lib/buildCustomTypeType.cjs +60 -0
  41. package/dist/lib/buildCustomTypeType.cjs.map +1 -0
  42. package/dist/lib/buildCustomTypeType.d.ts +17 -0
  43. package/dist/lib/buildCustomTypeType.js +60 -0
  44. package/dist/lib/buildCustomTypeType.js.map +1 -0
  45. package/dist/lib/buildFieldDocs.cjs +67 -35
  46. package/dist/lib/buildFieldDocs.cjs.map +1 -1
  47. package/dist/lib/buildFieldDocs.d.ts +7 -11
  48. package/dist/lib/buildFieldDocs.js +67 -35
  49. package/dist/lib/buildFieldDocs.js.map +1 -1
  50. package/dist/lib/buildFieldProperties.cjs +300 -0
  51. package/dist/lib/buildFieldProperties.cjs.map +1 -0
  52. package/dist/lib/buildFieldProperties.d.ts +14 -0
  53. package/dist/lib/buildFieldProperties.js +300 -0
  54. package/dist/lib/buildFieldProperties.js.map +1 -0
  55. package/dist/lib/buildSharedSliceType.cjs +140 -0
  56. package/dist/lib/buildSharedSliceType.cjs.map +1 -0
  57. package/dist/lib/buildSharedSliceType.d.ts +16 -0
  58. package/dist/lib/buildSharedSliceType.js +140 -0
  59. package/dist/lib/buildSharedSliceType.js.map +1 -0
  60. package/dist/lib/buildTypeName.cjs +4 -2
  61. package/dist/lib/buildTypeName.cjs.map +1 -1
  62. package/dist/lib/buildTypeName.js +4 -2
  63. package/dist/lib/buildTypeName.js.map +1 -1
  64. package/dist/lib/buildUnion.cjs +7 -0
  65. package/dist/lib/buildUnion.cjs.map +1 -0
  66. package/dist/lib/buildUnion.d.ts +1 -0
  67. package/dist/lib/buildUnion.js +7 -0
  68. package/dist/lib/buildUnion.js.map +1 -0
  69. package/dist/lib/checkHasUIDFIeld.cjs +7 -0
  70. package/dist/lib/checkHasUIDFIeld.cjs.map +1 -0
  71. package/dist/lib/checkHasUIDFIeld.d.ts +2 -0
  72. package/dist/lib/checkHasUIDFIeld.js +7 -0
  73. package/dist/lib/checkHasUIDFIeld.js.map +1 -0
  74. package/dist/lib/getAPIIDPath.cjs +18 -14
  75. package/dist/lib/getAPIIDPath.cjs.map +1 -1
  76. package/dist/lib/getAPIIDPath.d.ts +4 -8
  77. package/dist/lib/getAPIIDPath.js +18 -14
  78. package/dist/lib/getAPIIDPath.js.map +1 -1
  79. package/dist/lib/getCacheKey.cjs +25 -0
  80. package/dist/lib/getCacheKey.cjs.map +1 -0
  81. package/dist/lib/getCacheKey.d.ts +9 -0
  82. package/dist/lib/getCacheKey.js +8 -0
  83. package/dist/lib/getCacheKey.js.map +1 -0
  84. package/dist/lib/getHumanReadableModelName.cjs +13 -17
  85. package/dist/lib/getHumanReadableModelName.cjs.map +1 -1
  86. package/dist/lib/getHumanReadableModelName.d.ts +3 -3
  87. package/dist/lib/getHumanReadableModelName.js +13 -17
  88. package/dist/lib/getHumanReadableModelName.js.map +1 -1
  89. package/dist/lib/{getHumanReadableFieldPath.cjs → getHumanReadablePath.cjs} +8 -8
  90. package/dist/lib/getHumanReadablePath.cjs.map +1 -0
  91. package/dist/lib/getHumanReadablePath.d.ts +6 -0
  92. package/dist/lib/{getHumanReadableFieldPath.js → getHumanReadablePath.js} +8 -8
  93. package/dist/lib/getHumanReadablePath.js.map +1 -0
  94. package/dist/types.d.ts +9 -1
  95. package/package.json +18 -17
  96. package/src/constants.ts +19 -22
  97. package/src/generateTypes.ts +109 -108
  98. package/src/lib/addBlankLine.ts +13 -0
  99. package/src/lib/addLine.ts +5 -0
  100. package/src/lib/addSection.ts +5 -0
  101. package/src/lib/addTrailingNewLine.ts +14 -0
  102. package/src/lib/buildCustomTypeDataType.ts +74 -0
  103. package/src/lib/buildCustomTypeType.ts +101 -0
  104. package/src/lib/buildFieldDocs.ts +128 -68
  105. package/src/lib/buildFieldProperties.ts +513 -0
  106. package/src/lib/buildSharedSliceType.ts +213 -0
  107. package/src/lib/buildTypeName.ts +4 -2
  108. package/src/lib/buildUnion.ts +3 -0
  109. package/src/lib/checkHasUIDFIeld.ts +5 -0
  110. package/src/lib/getAPIIDPath.ts +40 -41
  111. package/src/lib/getCacheKey.ts +13 -0
  112. package/src/lib/getHumanReadableModelName.ts +23 -20
  113. package/src/lib/getHumanReadablePath.ts +24 -0
  114. package/src/types.ts +11 -1
  115. package/dist/lib/addInterfacePropertiesForFields.cjs +0 -489
  116. package/dist/lib/addInterfacePropertiesForFields.cjs.map +0 -1
  117. package/dist/lib/addInterfacePropertiesForFields.d.ts +0 -21
  118. package/dist/lib/addInterfacePropertiesForFields.js +0 -489
  119. package/dist/lib/addInterfacePropertiesForFields.js.map +0 -1
  120. package/dist/lib/addTypeAliasForCustomType.cjs +0 -81
  121. package/dist/lib/addTypeAliasForCustomType.cjs.map +0 -1
  122. package/dist/lib/addTypeAliasForCustomType.d.ts +0 -11
  123. package/dist/lib/addTypeAliasForCustomType.js +0 -81
  124. package/dist/lib/addTypeAliasForCustomType.js.map +0 -1
  125. package/dist/lib/addTypeAliasForSharedSlice.cjs +0 -149
  126. package/dist/lib/addTypeAliasForSharedSlice.cjs.map +0 -1
  127. package/dist/lib/addTypeAliasForSharedSlice.d.ts +0 -10
  128. package/dist/lib/addTypeAliasForSharedSlice.js +0 -149
  129. package/dist/lib/addTypeAliasForSharedSlice.js.map +0 -1
  130. package/dist/lib/buildSharedSliceInterfaceNamePart.cjs +0 -8
  131. package/dist/lib/buildSharedSliceInterfaceNamePart.cjs.map +0 -1
  132. package/dist/lib/buildSharedSliceInterfaceNamePart.d.ts +0 -5
  133. package/dist/lib/buildSharedSliceInterfaceNamePart.js +0 -8
  134. package/dist/lib/buildSharedSliceInterfaceNamePart.js.map +0 -1
  135. package/dist/lib/getFieldDocumentationURL.cjs +0 -8
  136. package/dist/lib/getFieldDocumentationURL.cjs.map +0 -1
  137. package/dist/lib/getFieldDocumentationURL.d.ts +0 -6
  138. package/dist/lib/getFieldDocumentationURL.js +0 -8
  139. package/dist/lib/getFieldDocumentationURL.js.map +0 -1
  140. package/dist/lib/getHumanReadableFieldPath.cjs.map +0 -1
  141. package/dist/lib/getHumanReadableFieldPath.d.ts +0 -10
  142. package/dist/lib/getHumanReadableFieldPath.js.map +0 -1
  143. package/dist/lib/getHumanReadableFieldType.cjs +0 -36
  144. package/dist/lib/getHumanReadableFieldType.cjs.map +0 -1
  145. package/dist/lib/getHumanReadableFieldType.d.ts +0 -6
  146. package/dist/lib/getHumanReadableFieldType.js +0 -36
  147. package/dist/lib/getHumanReadableFieldType.js.map +0 -1
  148. package/dist/lib/getSourceFileText.cjs +0 -9
  149. package/dist/lib/getSourceFileText.cjs.map +0 -1
  150. package/dist/lib/getSourceFileText.d.ts +0 -2
  151. package/dist/lib/getSourceFileText.js +0 -9
  152. package/dist/lib/getSourceFileText.js.map +0 -1
  153. package/dist/lib/hasOwnProperty.cjs +0 -7
  154. package/dist/lib/hasOwnProperty.cjs.map +0 -1
  155. package/dist/lib/hasOwnProperty.d.ts +0 -10
  156. package/dist/lib/hasOwnProperty.js +0 -7
  157. package/dist/lib/hasOwnProperty.js.map +0 -1
  158. package/dist/lib/isCustomTypeModel.cjs +0 -7
  159. package/dist/lib/isCustomTypeModel.cjs.map +0 -1
  160. package/dist/lib/isCustomTypeModel.d.ts +0 -2
  161. package/dist/lib/isCustomTypeModel.js +0 -7
  162. package/dist/lib/isCustomTypeModel.js.map +0 -1
  163. package/dist/lib/isCustomTypeModelField.cjs +0 -7
  164. package/dist/lib/isCustomTypeModelField.cjs.map +0 -1
  165. package/dist/lib/isCustomTypeModelField.d.ts +0 -2
  166. package/dist/lib/isCustomTypeModelField.js +0 -7
  167. package/dist/lib/isCustomTypeModelField.js.map +0 -1
  168. package/dist/lib/isCustomTypeModelSlice.cjs +0 -8
  169. package/dist/lib/isCustomTypeModelSlice.cjs.map +0 -1
  170. package/dist/lib/isCustomTypeModelSlice.d.ts +0 -2
  171. package/dist/lib/isCustomTypeModelSlice.js +0 -8
  172. package/dist/lib/isCustomTypeModelSlice.js.map +0 -1
  173. package/dist/lib/isSharedSliceModel.cjs +0 -8
  174. package/dist/lib/isSharedSliceModel.cjs.map +0 -1
  175. package/dist/lib/isSharedSliceModel.d.ts +0 -2
  176. package/dist/lib/isSharedSliceModel.js +0 -8
  177. package/dist/lib/isSharedSliceModel.js.map +0 -1
  178. package/dist/lib/pascalCase.cjs +0 -8
  179. package/dist/lib/pascalCase.cjs.map +0 -1
  180. package/dist/lib/pascalCase.d.ts +0 -1
  181. package/dist/lib/pascalCase.js +0 -8
  182. package/dist/lib/pascalCase.js.map +0 -1
  183. package/dist/lib/writeFieldDocsDescription.cjs +0 -29
  184. package/dist/lib/writeFieldDocsDescription.cjs.map +0 -1
  185. package/dist/lib/writeFieldDocsDescription.d.ts +0 -13
  186. package/dist/lib/writeFieldDocsDescription.js +0 -29
  187. package/dist/lib/writeFieldDocsDescription.js.map +0 -1
  188. package/src/lib/addInterfacePropertiesForFields.ts +0 -665
  189. package/src/lib/addTypeAliasForCustomType.ts +0 -120
  190. package/src/lib/addTypeAliasForSharedSlice.ts +0 -201
  191. package/src/lib/buildSharedSliceInterfaceNamePart.ts +0 -11
  192. package/src/lib/getFieldDocumentationURL.ts +0 -15
  193. package/src/lib/getHumanReadableFieldPath.ts +0 -36
  194. package/src/lib/getHumanReadableFieldType.ts +0 -55
  195. package/src/lib/getSourceFileText.ts +0 -14
  196. package/src/lib/hasOwnProperty.ts +0 -15
  197. package/src/lib/isCustomTypeModel.ts +0 -5
  198. package/src/lib/isCustomTypeModelField.ts +0 -7
  199. package/src/lib/isCustomTypeModelSlice.ts +0 -14
  200. package/src/lib/isSharedSliceModel.ts +0 -14
  201. package/src/lib/pascalCase.ts +0 -9
  202. package/src/lib/writeFieldDocsDescription.ts +0 -51
@@ -1,17 +1,19 @@
1
1
  import type { CustomTypeModel, SharedSliceModel } from "@prismicio/client";
2
- import { ModuleDeclarationKind, Project } from "ts-morph";
2
+ import { source } from "common-tags";
3
+ import QuickLRU from "quick-lru";
3
4
 
4
- import { addTypeAliasForCustomType } from "./lib/addTypeAliasForCustomType";
5
- import { addTypeAliasForSharedSlice } from "./lib/addTypeAliasForSharedSlice";
6
- import { buildTypeName } from "./lib/buildTypeName";
7
- import { getSourceFileText } from "./lib/getSourceFileText";
5
+ import { addLine } from "./lib/addLine";
6
+ import { addSection } from "./lib/addSection";
7
+ import { buildCustomTypeType } from "./lib/buildCustomTypeType";
8
+ import { buildSharedSliceType } from "./lib/buildSharedSliceType";
9
+ import { buildUnion } from "./lib/buildUnion";
8
10
 
9
11
  import { FieldConfigs } from "./types";
10
12
 
11
- import { BLANK_LINE_IDENTIFIER } from "./constants";
12
-
13
13
  export type TypesProvider = "@prismicio/client" | "@prismicio/types";
14
14
 
15
+ const cache = new QuickLRU<string, unknown>({ maxSize: 1000 });
16
+
15
17
  export type GenerateTypesConfig = {
16
18
  customTypeModels?: CustomTypeModel[];
17
19
  sharedSliceModels?: SharedSliceModel[];
@@ -22,65 +24,92 @@ export type GenerateTypesConfig = {
22
24
  includeCreateClientInterface?: boolean;
23
25
  includeContentNamespace?: boolean;
24
26
  };
27
+ cache?: boolean;
25
28
  };
26
29
 
27
- export const generateTypes = (config: GenerateTypesConfig = {}) => {
28
- const project = new Project({
29
- useInMemoryFileSystem: true,
30
- });
30
+ export function generateTypes(config: GenerateTypesConfig = {}): string {
31
+ const fieldConfigs = config.fieldConfigs || {};
32
+ const shouldUseCache = config.cache ?? true;
31
33
 
32
- const sourceFile = project.createSourceFile("types.d.ts");
34
+ let code = "";
33
35
 
34
36
  const typesProvider = config.typesProvider || "@prismicio/types";
37
+ let clientImportName = "prismic";
35
38
 
36
- sourceFile.addImportDeclaration({
37
- moduleSpecifier: typesProvider,
38
- namespaceImport: "prismic",
39
- isTypeOnly: true,
40
- });
39
+ code = addLine(`import type * as prismic from "${typesProvider}";`, code);
41
40
 
42
- sourceFile.addStatements(BLANK_LINE_IDENTIFIER);
41
+ if (
42
+ config.clientIntegration?.includeCreateClientInterface ||
43
+ config.clientIntegration?.includeContentNamespace
44
+ ) {
45
+ if (typesProvider !== "@prismicio/client") {
46
+ clientImportName = "prismicClient";
43
47
 
44
- const simplifyTypeAlias = sourceFile.addTypeAlias({
45
- name: "Simplify",
46
- typeParameters: [
47
- {
48
- name: "T",
49
- },
50
- ],
51
- type: `{ [KeyType in keyof T]: T[KeyType] }`,
52
- });
48
+ // This import declaration would be a duplicate if the types
49
+ // provider is @prismicio/client.
50
+ code = addLine(
51
+ `import type * as ${clientImportName} from "@prismicio/client";`,
52
+ code,
53
+ );
54
+ }
55
+ }
56
+
57
+ code = addSection(
58
+ `type Simplify<T> = { [KeyType in keyof T]: T[KeyType] };`,
59
+ code,
60
+ );
61
+
62
+ const contentTypeNames: string[] = [];
53
63
 
54
64
  if (config.customTypeModels) {
65
+ const allDocumentTypesTypeNames: string[] = [];
66
+
55
67
  for (const model of config.customTypeModels) {
56
- addTypeAliasForCustomType({
68
+ const customTypeType = buildCustomTypeType({
57
69
  model,
58
- sourceFile,
59
- localeIDs: config.localeIDs || [],
60
- fieldConfigs: config.fieldConfigs || {},
70
+ localeIDs: config.localeIDs,
71
+ fieldConfigs,
72
+ cache: shouldUseCache ? cache : undefined,
61
73
  });
74
+
75
+ for (const auxiliaryType of customTypeType.auxiliaryTypes) {
76
+ code = addSection(auxiliaryType.code, code);
77
+ }
78
+
79
+ code = addSection(customTypeType.code, code);
80
+
81
+ allDocumentTypesTypeNames.push(customTypeType.name);
82
+
83
+ contentTypeNames.push(customTypeType.name);
84
+ contentTypeNames.push(customTypeType.dataName);
62
85
  }
63
86
 
64
87
  if (config.customTypeModels.length > 0) {
65
- sourceFile.addTypeAlias({
66
- name: "AllDocumentTypes",
67
- type: config.customTypeModels
68
- .map((customTypeModel) =>
69
- buildTypeName(customTypeModel.id, "Document"),
70
- )
71
- .join(" | "),
72
- isExported: true,
73
- });
88
+ const allDocumentTypesUnionName = "AllDocumentTypes";
89
+ const allDocumentTypesUnion = buildUnion(allDocumentTypesTypeNames);
90
+
91
+ code = addSection(
92
+ `export type ${allDocumentTypesUnionName} = ${allDocumentTypesUnion};`,
93
+ code,
94
+ );
95
+
96
+ contentTypeNames.push(allDocumentTypesUnionName);
74
97
  }
75
98
  }
76
99
 
77
100
  if (config.sharedSliceModels) {
78
101
  for (const model of config.sharedSliceModels) {
79
- addTypeAliasForSharedSlice({
102
+ const sharedSliceType = buildSharedSliceType({
80
103
  model,
81
- sourceFile,
82
- fieldConfigs: config.fieldConfigs || {},
104
+ fieldConfigs,
105
+ cache: shouldUseCache ? cache : undefined,
83
106
  });
107
+
108
+ code = addSection(sharedSliceType.code, code);
109
+
110
+ contentTypeNames.push(sharedSliceType.name);
111
+ contentTypeNames.push(sharedSliceType.variationUnionName);
112
+ contentTypeNames.push(...sharedSliceType.variationNames);
84
113
  }
85
114
  }
86
115
 
@@ -88,76 +117,48 @@ export const generateTypes = (config: GenerateTypesConfig = {}) => {
88
117
  config.clientIntegration?.includeCreateClientInterface ||
89
118
  config.clientIntegration?.includeContentNamespace
90
119
  ) {
91
- let clientNamespaceImportName = "prismic";
92
-
93
- if (typesProvider !== "@prismicio/client") {
94
- clientNamespaceImportName = "prismicClient";
95
-
96
- // This import declaration would be a duplicate if the types
97
- // provider is @prismicio/client.
98
- sourceFile.addImportDeclaration({
99
- moduleSpecifier: "@prismicio/client",
100
- namespaceImport: clientNamespaceImportName,
101
- isTypeOnly: true,
102
- });
103
- }
104
-
105
- const clientModuleDeclaration = sourceFile.addModule({
106
- name: '"@prismicio/client"',
107
- hasDeclareKeyword: true,
108
- declarationKind: ModuleDeclarationKind.Module,
109
- });
120
+ let clientModuleCode = "";
110
121
 
111
122
  if (config.clientIntegration.includeCreateClientInterface) {
112
- clientModuleDeclaration.addInterface({
113
- name: "CreateClient",
114
- callSignatures: [
115
- {
116
- parameters: [
117
- {
118
- name: "repositoryNameOrEndpoint",
119
- type: "string",
120
- },
121
- {
122
- name: "options",
123
- type: `${clientNamespaceImportName}.ClientConfig`,
124
- hasQuestionToken: true,
125
- },
126
- ],
127
- returnType:
128
- (config.customTypeModels?.length || 0) > 0
129
- ? `${clientNamespaceImportName}.Client<AllDocumentTypes>`
130
- : `${clientNamespaceImportName}.Client`,
131
- },
132
- ],
133
- });
123
+ if ((config.customTypeModels?.length || 0) > 0) {
124
+ clientModuleCode = addSection(
125
+ `interface CreateClient {
126
+ (repositoryNameOrEndpoint: string, options?: ${clientImportName}.ClientConfig): ${clientImportName}.Client<AllDocumentTypes>;
127
+ }`,
128
+ clientModuleCode,
129
+ );
130
+ } else {
131
+ clientModuleCode = addSection(
132
+ `interface CreateClient {
133
+ (repositoryNameOrEndpoint: string, options?: ${clientImportName}.ClientConfig): ${clientImportName}.Client;
134
+ }`,
135
+ clientModuleCode,
136
+ );
137
+ }
134
138
  }
135
139
 
136
140
  if (config.clientIntegration.includeContentNamespace) {
137
- const contentNamespaceDeclaration = clientModuleDeclaration.addModule({
138
- name: "Content",
139
- declarationKind: ModuleDeclarationKind.Namespace,
140
- });
141
-
142
- const exportSymbols = sourceFile
143
- .getExportSymbols()
144
- .filter((exportSymbol) => {
145
- // The Simplify utility type should not
146
- // be exported, but it is included in
147
- // `getExportSymbols()`'s result.
148
- return exportSymbol.getName() !== simplifyTypeAlias.getName();
149
- });
150
-
151
- contentNamespaceDeclaration.addExportDeclaration({
152
- isTypeOnly: true,
153
- namedExports: exportSymbols.map((exportSymbol) => {
154
- return {
155
- name: exportSymbol.getName(),
156
- };
157
- }),
158
- });
141
+ clientModuleCode = addSection(
142
+ source`
143
+ namespace Content {
144
+ export type {
145
+ ${contentTypeNames.join(",\n")}
146
+ }
147
+ }
148
+ `,
149
+ clientModuleCode,
150
+ );
159
151
  }
152
+
153
+ code = addSection(
154
+ source`
155
+ declare module "@prismicio/client" {
156
+ ${clientModuleCode}
157
+ }
158
+ `,
159
+ code,
160
+ );
160
161
  }
161
162
 
162
- return getSourceFileText(sourceFile);
163
- };
163
+ return code;
164
+ }
@@ -0,0 +1,13 @@
1
+ import { addTrailingNewLine } from "./addTrailingNewLine";
2
+
3
+ type AddBlankLineConfig = {
4
+ force?: boolean;
5
+ };
6
+
7
+ export function addBlankLine(state: string, config?: AddBlankLineConfig) {
8
+ if ((!state || state.endsWith("\n\n")) && !config?.force) {
9
+ return state;
10
+ } else {
11
+ return addTrailingNewLine(state) + "\n";
12
+ }
13
+ }
@@ -0,0 +1,5 @@
1
+ import { addTrailingNewLine } from "./addTrailingNewLine";
2
+
3
+ export function addLine(line: string, state: string) {
4
+ return addTrailingNewLine(state) + line;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { addBlankLine } from "./addBlankLine";
2
+
3
+ export function addSection(section: string, state: string) {
4
+ return addBlankLine(state) + section;
5
+ }
@@ -0,0 +1,14 @@
1
+ type AddTrailingNewLineConfig = {
2
+ force?: boolean;
3
+ };
4
+
5
+ export function addTrailingNewLine(
6
+ state: string,
7
+ config?: AddTrailingNewLineConfig,
8
+ ) {
9
+ if ((!state || state.endsWith("\n")) && !config?.force) {
10
+ return state;
11
+ } else {
12
+ return state + "\n";
13
+ }
14
+ }
@@ -0,0 +1,74 @@
1
+ import { CustomTypeModel } from "@prismicio/client";
2
+ import { source } from "common-tags";
3
+
4
+ import { buildTypeName } from "../lib/buildTypeName";
5
+
6
+ import { AuxiliaryType, FieldConfigs } from "../types";
7
+
8
+ import { buildFieldProperties } from "./buildFieldProperties";
9
+ import { getHumanReadableModelName } from "./getHumanReadableModelName";
10
+
11
+ type BuildCustomTypeDataTypeArgs = {
12
+ model: CustomTypeModel;
13
+ fieldConfigs: FieldConfigs;
14
+ };
15
+
16
+ type BuildCustomTypeDataTypeReturnValue = {
17
+ name: string;
18
+ code: string;
19
+ auxiliaryTypes: AuxiliaryType[];
20
+ };
21
+
22
+ export function buildCustomTypeDataType(
23
+ args: BuildCustomTypeDataTypeArgs,
24
+ ): BuildCustomTypeDataTypeReturnValue {
25
+ let code = "";
26
+ const auxiliaryTypes: AuxiliaryType[] = [];
27
+
28
+ const name = buildTypeName(args.model.id, "Document", "Data");
29
+ const humanReadableName = getHumanReadableModelName({
30
+ name: args.model.id,
31
+ model: args.model,
32
+ });
33
+
34
+ let fieldProperties = "";
35
+
36
+ for (const tabName in args.model.json) {
37
+ const { uid: _uid, ...fields } = args.model.json[tabName];
38
+
39
+ const tabFieldProperties = buildFieldProperties({
40
+ fields,
41
+ fieldConfigs: args.fieldConfigs,
42
+ path: [
43
+ {
44
+ name: args.model.id,
45
+ model: args.model,
46
+ },
47
+ ],
48
+ tabName,
49
+ });
50
+
51
+ fieldProperties += tabFieldProperties.code;
52
+
53
+ auxiliaryTypes.push(...tabFieldProperties.auxiliaryTypes);
54
+ }
55
+
56
+ if (fieldProperties) {
57
+ code = source`
58
+ /**
59
+ * Content for ${humanReadableName} documents
60
+ */
61
+ interface ${name} {
62
+ ${fieldProperties}
63
+ }
64
+ `;
65
+ } else {
66
+ code = `interface ${name} {}`;
67
+ }
68
+
69
+ return {
70
+ name,
71
+ code,
72
+ auxiliaryTypes,
73
+ };
74
+ }
@@ -0,0 +1,101 @@
1
+ import { CustomTypeModel } from "@prismicio/client";
2
+ import { source } from "common-tags";
3
+ import QuickLRU from "quick-lru";
4
+
5
+ import { AuxiliaryType, FieldConfigs } from "../types";
6
+
7
+ import { CUSTOM_TYPES_DOCUMENTATION_URL } from "../constants";
8
+
9
+ import { addSection } from "./addSection";
10
+ import { buildCustomTypeDataType } from "./buildCustomTypeDataType";
11
+ import { buildTypeName } from "./buildTypeName";
12
+ import { buildUnion } from "./buildUnion";
13
+ import { checkHasUIDField } from "./checkHasUIDFIeld";
14
+ import { getCacheKey } from "./getCacheKey";
15
+ import { getHumanReadableModelName } from "./getHumanReadableModelName";
16
+
17
+ type BuildCustomTypeTypesArgs = {
18
+ model: CustomTypeModel;
19
+ localeIDs?: string[];
20
+ fieldConfigs: FieldConfigs;
21
+ cache?: QuickLRU<string, unknown>;
22
+ };
23
+
24
+ type BuildCustomTypeTypeReturnValue = {
25
+ name: string;
26
+ dataName: string;
27
+ code: string;
28
+ auxiliaryTypes: AuxiliaryType[];
29
+ };
30
+
31
+ export function buildCustomTypeType(
32
+ args: BuildCustomTypeTypesArgs,
33
+ ): BuildCustomTypeTypeReturnValue {
34
+ if (args.cache) {
35
+ const key = getCacheKey(args.model);
36
+ const cached = args.cache.get(key);
37
+
38
+ if (cached) {
39
+ return cached as BuildCustomTypeTypeReturnValue;
40
+ }
41
+ }
42
+
43
+ let code = "";
44
+
45
+ const auxiliaryTypes: AuxiliaryType[] = [];
46
+
47
+ const name = buildTypeName(args.model.id, "Document");
48
+ const langDefault =
49
+ args.localeIDs && args.localeIDs.length > 0
50
+ ? buildUnion(args.localeIDs.map((localeID) => `"${localeID}"`))
51
+ : "string";
52
+ const baseDocumentType = checkHasUIDField(args.model)
53
+ ? "PrismicDocumentWithUID"
54
+ : "PrismicDocumentWithoutUID";
55
+ const humanReadableName = getHumanReadableModelName({
56
+ name: args.model.id,
57
+ model: args.model,
58
+ });
59
+
60
+ const dataType = buildCustomTypeDataType({
61
+ model: args.model,
62
+ fieldConfigs: args.fieldConfigs,
63
+ });
64
+
65
+ auxiliaryTypes.push(...dataType.auxiliaryTypes);
66
+
67
+ code = addSection(dataType.code, code);
68
+
69
+ code = addSection(
70
+ source`
71
+ /**
72
+ * ${humanReadableName} document from Prismic
73
+ *
74
+ * - **API ID**: \`${args.model.id}\`
75
+ * - **Repeatable**: \`${args.model.repeatable.toString()}\`
76
+ * - **Documentation**: ${CUSTOM_TYPES_DOCUMENTATION_URL}
77
+ *
78
+ * @typeParam Lang - Language API ID of the document.
79
+ */
80
+ export type ${name}<Lang extends string = ${langDefault}> = prismic.${baseDocumentType}<Simplify<${
81
+ dataType.name
82
+ }>, "${args.model.id}", Lang>;
83
+ `,
84
+ code,
85
+ );
86
+
87
+ const result = {
88
+ name,
89
+ dataName: dataType.name,
90
+ code,
91
+ auxiliaryTypes,
92
+ };
93
+
94
+ if (args.cache) {
95
+ const key = getCacheKey(args.model);
96
+
97
+ args.cache.set(key, result);
98
+ }
99
+
100
+ return result;
101
+ }
@@ -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
+ }