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/LICENSE +202 -0
- package/README.md +130 -0
- package/bin/cli.mjs +1166 -0
- package/dist/index.cjs +941 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +937 -0
- package/dist/index.js.map +1 -0
- package/package.json +87 -0
- package/src/cli/configSchema.ts +64 -0
- package/src/cli/index.ts +125 -0
- package/src/cli/loadConfig.ts +39 -0
- package/src/cli/loadLocaleIDs.ts +34 -0
- package/src/cli/loadModels.ts +88 -0
- package/src/cli/types.ts +30 -0
- package/src/constants.ts +37 -0
- package/src/generateTypes.ts +65 -0
- package/src/index.ts +6 -0
- package/src/lib/addInterfacePropertiesForFields.ts +595 -0
- package/src/lib/addTypeAliasForCustomType.ts +110 -0
- package/src/lib/addTypeAliasForSharedSlice.ts +200 -0
- package/src/lib/buildFieldDocs.ts +71 -0
- package/src/lib/buildSharedSliceInterfaceName.ts +11 -0
- package/src/lib/getAPIIDPath.ts +46 -0
- package/src/lib/getFieldDocumentationURL.ts +13 -0
- package/src/lib/getHumanReadableFieldPath.ts +35 -0
- package/src/lib/getHumanReadableFieldType.ts +50 -0
- package/src/lib/getHumanReadableModelName.ts +40 -0
- package/src/lib/getSourceFileText.ts +14 -0
- package/src/lib/isCustomTypeModel.ts +5 -0
- package/src/lib/isCustomTypeModelField.ts +12 -0
- package/src/lib/isCustomTypeModelSlice.ts +12 -0
- package/src/lib/isSharedSliceModel.ts +7 -0
- package/src/lib/pascalCase.ts +9 -0
- package/src/lib/writeFieldDocsDescription.ts +46 -0
- package/src/types.ts +27 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { CustomTypeModel, CustomTypeModelField } from "@prismicio/types";
|
|
2
|
+
import type {
|
|
3
|
+
SourceFile,
|
|
4
|
+
TypeAliasDeclaration,
|
|
5
|
+
InterfaceDeclaration,
|
|
6
|
+
} from "ts-morph";
|
|
7
|
+
import { CUSTOM_TYPES_DOCUMENTATION_URL } from "../constants";
|
|
8
|
+
import { FieldConfigs } from "../types";
|
|
9
|
+
|
|
10
|
+
import { addInterfacePropertiesForFields } from "./addInterfacePropertiesForFields";
|
|
11
|
+
import { pascalCase } from "./pascalCase";
|
|
12
|
+
|
|
13
|
+
const collectCustomTypeFields = (
|
|
14
|
+
model: CustomTypeModel,
|
|
15
|
+
): Record<string, CustomTypeModelField> => {
|
|
16
|
+
return Object.assign({}, ...Object.values(model.json));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type AddTypeAliasForCustomTypeConfig = {
|
|
20
|
+
model: CustomTypeModel;
|
|
21
|
+
sourceFile: SourceFile;
|
|
22
|
+
localeIDs: string[];
|
|
23
|
+
fieldConfigs: FieldConfigs;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const addTypeAliasForCustomType = ({
|
|
27
|
+
model,
|
|
28
|
+
sourceFile,
|
|
29
|
+
localeIDs,
|
|
30
|
+
fieldConfigs,
|
|
31
|
+
}: AddTypeAliasForCustomTypeConfig): TypeAliasDeclaration => {
|
|
32
|
+
const { uid: uidField, ...fields } = collectCustomTypeFields(model);
|
|
33
|
+
const hasDataFields = Object.keys(fields).length > 0;
|
|
34
|
+
const hasUIDField = Boolean(uidField);
|
|
35
|
+
|
|
36
|
+
let dataInterface: InterfaceDeclaration | TypeAliasDeclaration;
|
|
37
|
+
if (hasDataFields) {
|
|
38
|
+
dataInterface = sourceFile.addInterface({
|
|
39
|
+
name: pascalCase(`${model.id} Document Data`),
|
|
40
|
+
docs: [
|
|
41
|
+
{
|
|
42
|
+
description: `Content for ${model.label} documents`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
addInterfacePropertiesForFields({
|
|
47
|
+
fields,
|
|
48
|
+
interface: dataInterface,
|
|
49
|
+
sourceFile: sourceFile,
|
|
50
|
+
path: [
|
|
51
|
+
{
|
|
52
|
+
id: model.id,
|
|
53
|
+
model: model,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
fieldConfigs,
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
dataInterface = sourceFile.addTypeAlias({
|
|
60
|
+
name: pascalCase(`${model.id} Document Data`),
|
|
61
|
+
type: `Record<string, never>`,
|
|
62
|
+
docs: [
|
|
63
|
+
{
|
|
64
|
+
description: `Content for ${model.label} documents`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return sourceFile.addTypeAlias({
|
|
71
|
+
name: pascalCase(`${model.id} Document`),
|
|
72
|
+
typeParameters: [
|
|
73
|
+
{
|
|
74
|
+
name: "Lang",
|
|
75
|
+
constraint: "string",
|
|
76
|
+
default:
|
|
77
|
+
localeIDs.length > 0
|
|
78
|
+
? localeIDs.map((localeID) => `"${localeID}"`).join(" | ")
|
|
79
|
+
: "string",
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
type: hasUIDField
|
|
83
|
+
? `prismicT.PrismicDocumentWithUID<Simplify<${dataInterface.getName()}>, "${
|
|
84
|
+
model.id
|
|
85
|
+
}", Lang>`
|
|
86
|
+
: `prismicT.PrismicDocumentWithoutUID<Simplify<${dataInterface.getName()}>, "${
|
|
87
|
+
model.id
|
|
88
|
+
}", Lang>`,
|
|
89
|
+
docs: [
|
|
90
|
+
{
|
|
91
|
+
description: (writer) => {
|
|
92
|
+
writer.writeLine(`${model.label} document from Prismic`);
|
|
93
|
+
writer.blankLine();
|
|
94
|
+
writer.writeLine(`- **API ID**: \`${model.id}\``);
|
|
95
|
+
writer.writeLine(`- **Repeatable**: \`${model.repeatable}\``);
|
|
96
|
+
writer.writeLine(
|
|
97
|
+
`- **Documentation**: ${CUSTOM_TYPES_DOCUMENTATION_URL}`,
|
|
98
|
+
);
|
|
99
|
+
},
|
|
100
|
+
tags: [
|
|
101
|
+
{
|
|
102
|
+
tagName: "typeParam",
|
|
103
|
+
text: "Lang - Language API ID of the document.",
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
isExported: true,
|
|
109
|
+
});
|
|
110
|
+
};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import type { SharedSliceModel } from "@prismicio/types";
|
|
2
|
+
import type {
|
|
3
|
+
InterfaceDeclaration,
|
|
4
|
+
SourceFile,
|
|
5
|
+
TypeAliasDeclaration,
|
|
6
|
+
} from "ts-morph";
|
|
7
|
+
|
|
8
|
+
import { addInterfacePropertiesForFields } from "./addInterfacePropertiesForFields";
|
|
9
|
+
import { buildSharedSliceInterfaceName } from "./buildSharedSliceInterfaceName";
|
|
10
|
+
import { pascalCase } from "./pascalCase";
|
|
11
|
+
import { getHumanReadableFieldPath } from "./getHumanReadableFieldPath";
|
|
12
|
+
import { SHARED_SLICES_DOCUMENTATION_URL } from "../constants";
|
|
13
|
+
import { FieldConfigs } from "../types";
|
|
14
|
+
|
|
15
|
+
type AddTypeAliasForSharedSliceConfig = {
|
|
16
|
+
model: SharedSliceModel;
|
|
17
|
+
sourceFile: SourceFile;
|
|
18
|
+
fieldConfigs: FieldConfigs;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const addTypeAliasForSharedSlice = (
|
|
22
|
+
config: AddTypeAliasForSharedSliceConfig,
|
|
23
|
+
): TypeAliasDeclaration => {
|
|
24
|
+
const variationTypeNames: string[] = [];
|
|
25
|
+
|
|
26
|
+
for (const variation of config.model.variations) {
|
|
27
|
+
let primaryInterface: InterfaceDeclaration | undefined;
|
|
28
|
+
if (Object.keys(variation.primary).length > 0) {
|
|
29
|
+
primaryInterface = config.sourceFile.addInterface({
|
|
30
|
+
name: pascalCase(
|
|
31
|
+
`${buildSharedSliceInterfaceName({ id: config.model.id })} ${
|
|
32
|
+
variation.id
|
|
33
|
+
} Primary`,
|
|
34
|
+
),
|
|
35
|
+
docs: [
|
|
36
|
+
{
|
|
37
|
+
description: (writer) => {
|
|
38
|
+
const humanReadablePath = getHumanReadableFieldPath({
|
|
39
|
+
path: [
|
|
40
|
+
{
|
|
41
|
+
id: config.model.id,
|
|
42
|
+
model: config.model,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "primary",
|
|
46
|
+
label: "Primary",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
writer.writeLine(`Primary content in ${humanReadablePath}`);
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
});
|
|
56
|
+
addInterfacePropertiesForFields({
|
|
57
|
+
interface: primaryInterface,
|
|
58
|
+
sourceFile: config.sourceFile,
|
|
59
|
+
fields: variation.primary,
|
|
60
|
+
path: [
|
|
61
|
+
{
|
|
62
|
+
id: config.model.id,
|
|
63
|
+
model: config.model,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "primary",
|
|
67
|
+
label: "Primary",
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
fieldConfigs: config.fieldConfigs,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let itemInterface: InterfaceDeclaration | undefined;
|
|
75
|
+
if (Object.keys(variation.items).length > 0) {
|
|
76
|
+
itemInterface = config.sourceFile.addInterface({
|
|
77
|
+
name: pascalCase(
|
|
78
|
+
`${buildSharedSliceInterfaceName({ id: config.model.id })} ${
|
|
79
|
+
variation.id
|
|
80
|
+
} Item`,
|
|
81
|
+
),
|
|
82
|
+
docs: [
|
|
83
|
+
{
|
|
84
|
+
description: (writer) => {
|
|
85
|
+
const humanReadablePath = getHumanReadableFieldPath({
|
|
86
|
+
path: [
|
|
87
|
+
{
|
|
88
|
+
id: config.model.id,
|
|
89
|
+
model: config.model,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "items",
|
|
93
|
+
label: "Items",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
writer.writeLine(`Item in ${humanReadablePath}`);
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
addInterfacePropertiesForFields({
|
|
104
|
+
interface: itemInterface,
|
|
105
|
+
sourceFile: config.sourceFile,
|
|
106
|
+
fields: variation.items,
|
|
107
|
+
path: [
|
|
108
|
+
{
|
|
109
|
+
id: config.model.id,
|
|
110
|
+
model: config.model,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "items",
|
|
114
|
+
label: "Items",
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
fieldConfigs: config.fieldConfigs,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const variationType = config.sourceFile.addTypeAlias({
|
|
122
|
+
name: pascalCase(
|
|
123
|
+
`${buildSharedSliceInterfaceName({
|
|
124
|
+
id: config.model.id,
|
|
125
|
+
})} ${variation.id}`,
|
|
126
|
+
),
|
|
127
|
+
type: `prismicT.SharedSliceVariation<"${variation.id}", ${
|
|
128
|
+
primaryInterface
|
|
129
|
+
? `Simplify<${primaryInterface.getName()}>`
|
|
130
|
+
: "Record<string, never>"
|
|
131
|
+
}, ${itemInterface ? `Simplify<${itemInterface.getName()}>` : "never"}>`,
|
|
132
|
+
docs: [
|
|
133
|
+
{
|
|
134
|
+
description: (writer) => {
|
|
135
|
+
writer.writeLine(
|
|
136
|
+
`${variation.name} variation for ${config.model.name} Slice`,
|
|
137
|
+
);
|
|
138
|
+
writer.blankLine();
|
|
139
|
+
writer.writeLine(`- **API ID**: \`${variation.id}\``);
|
|
140
|
+
writer.writeLine(`- **Description**: \`${variation.description}\``);
|
|
141
|
+
writer.writeLine(
|
|
142
|
+
`- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`,
|
|
143
|
+
);
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
variationTypeNames.push(variationType.getName());
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const variationsType = config.sourceFile.addTypeAlias({
|
|
153
|
+
name: pascalCase(`${config.model.id} Slice Variation`),
|
|
154
|
+
type:
|
|
155
|
+
variationTypeNames.length > 0 ? variationTypeNames.join(" | ") : "never",
|
|
156
|
+
docs: [
|
|
157
|
+
{
|
|
158
|
+
description: (writer) => {
|
|
159
|
+
const humanReadablePath = getHumanReadableFieldPath({
|
|
160
|
+
path: [
|
|
161
|
+
{
|
|
162
|
+
id: config.model.id,
|
|
163
|
+
model: config.model,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
writer.writeLine(`Slice variation for *${humanReadablePath}*`);
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
return config.sourceFile.addTypeAlias({
|
|
175
|
+
name: pascalCase(
|
|
176
|
+
buildSharedSliceInterfaceName({
|
|
177
|
+
id: config.model.id,
|
|
178
|
+
}),
|
|
179
|
+
),
|
|
180
|
+
type: `prismicT.SharedSlice<"${
|
|
181
|
+
config.model.id
|
|
182
|
+
}", ${variationsType.getName()}>`,
|
|
183
|
+
docs: [
|
|
184
|
+
{
|
|
185
|
+
description: (writer) => {
|
|
186
|
+
writer.writeLine(`${config.model.name} Shared Slice`);
|
|
187
|
+
writer.blankLine();
|
|
188
|
+
writer.writeLine(`- **API ID**: \`${config.model.id}\``);
|
|
189
|
+
writer.writeLine(
|
|
190
|
+
`- **Description**: \`${config.model.description}\``,
|
|
191
|
+
);
|
|
192
|
+
writer.writeLine(
|
|
193
|
+
`- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`,
|
|
194
|
+
);
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
isExported: true,
|
|
199
|
+
});
|
|
200
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CustomTypeModel,
|
|
3
|
+
CustomTypeModelField,
|
|
4
|
+
CustomTypeModelSlice,
|
|
5
|
+
SharedSliceModel,
|
|
6
|
+
} from "@prismicio/types";
|
|
7
|
+
import type { JSDocableNodeStructure } from "ts-morph";
|
|
8
|
+
|
|
9
|
+
import { PathElement } from "../types";
|
|
10
|
+
import { getAPIIDPath } from "./getAPIIDPath";
|
|
11
|
+
import { getFieldDocumentationURL } from "./getFieldDocumentationURL";
|
|
12
|
+
import { getHumanReadableFieldPath } from "./getHumanReadableFieldPath";
|
|
13
|
+
import { getHumanReadableFieldType } from "./getHumanReadableFieldType";
|
|
14
|
+
import { getHumanReadableModelName } from "./getHumanReadableModelName";
|
|
15
|
+
import { writeFieldDocsDescription } from "./writeFieldDocsDescription";
|
|
16
|
+
|
|
17
|
+
type BuildFieldDocsConfig = {
|
|
18
|
+
id: string;
|
|
19
|
+
model: CustomTypeModelField;
|
|
20
|
+
path: [
|
|
21
|
+
PathElement<CustomTypeModel | SharedSliceModel>,
|
|
22
|
+
...PathElement<CustomTypeModelField | CustomTypeModelSlice>[]
|
|
23
|
+
];
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const buildFieldDocs = (
|
|
27
|
+
config: BuildFieldDocsConfig,
|
|
28
|
+
): NonNullable<JSDocableNodeStructure["docs"]> => {
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
description: (writer) => {
|
|
32
|
+
const name = getHumanReadableModelName({
|
|
33
|
+
id: config.id,
|
|
34
|
+
model: config.model,
|
|
35
|
+
});
|
|
36
|
+
const humanReadablePath = getHumanReadableFieldPath({
|
|
37
|
+
path: config.path,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const fieldType = getHumanReadableFieldType({
|
|
41
|
+
model: config.model,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const placeholder =
|
|
45
|
+
"placeholder" in config.model.config &&
|
|
46
|
+
config.model.config.placeholder
|
|
47
|
+
? config.model.config.placeholder
|
|
48
|
+
: `*None*`;
|
|
49
|
+
|
|
50
|
+
const defaultValue =
|
|
51
|
+
"default_value" in config.model.config
|
|
52
|
+
? config.model.config.default_value
|
|
53
|
+
: undefined;
|
|
54
|
+
|
|
55
|
+
const apiIDPath = getAPIIDPath({
|
|
56
|
+
path: [...config.path, { id: config.id, model: config.model }],
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
writeFieldDocsDescription({
|
|
60
|
+
writer,
|
|
61
|
+
description: `${name} field in *${humanReadablePath}*`,
|
|
62
|
+
fieldType,
|
|
63
|
+
placeholder,
|
|
64
|
+
defaultValue,
|
|
65
|
+
apiIDPath,
|
|
66
|
+
documentationURL: getFieldDocumentationURL({ model: config.model }),
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { pascalCase } from "./pascalCase";
|
|
2
|
+
|
|
3
|
+
type BuildSharedSliceInterfaceNameConfig = {
|
|
4
|
+
id: string;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const buildSharedSliceInterfaceName = (
|
|
8
|
+
config: BuildSharedSliceInterfaceNameConfig,
|
|
9
|
+
): string => {
|
|
10
|
+
return pascalCase(`${config.id} Slice`);
|
|
11
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CustomTypeModel,
|
|
3
|
+
CustomTypeModelField,
|
|
4
|
+
CustomTypeModelSlice,
|
|
5
|
+
SharedSliceModel,
|
|
6
|
+
} from "@prismicio/types";
|
|
7
|
+
import { CustomTypeModelFieldType } from "@prismicio/types";
|
|
8
|
+
|
|
9
|
+
import { PathElement } from "../types";
|
|
10
|
+
import { isCustomTypeModelField } from "./isCustomTypeModelField";
|
|
11
|
+
import { isCustomTypeModelSlice } from "./isCustomTypeModelSlice";
|
|
12
|
+
import { isSharedSliceModel } from "./isSharedSliceModel";
|
|
13
|
+
|
|
14
|
+
type GetAPIIDPathConfig = {
|
|
15
|
+
path: [
|
|
16
|
+
PathElement<CustomTypeModel | SharedSliceModel>,
|
|
17
|
+
...PathElement<CustomTypeModelField | CustomTypeModelSlice>[]
|
|
18
|
+
];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const getAPIIDPath = (config: GetAPIIDPathConfig): string => {
|
|
22
|
+
return config.path
|
|
23
|
+
.map((element, i) => {
|
|
24
|
+
if (
|
|
25
|
+
isCustomTypeModelField(element.model) &&
|
|
26
|
+
(element.model.type === CustomTypeModelFieldType.Group ||
|
|
27
|
+
element.model.type === CustomTypeModelFieldType.Slices)
|
|
28
|
+
) {
|
|
29
|
+
return `${element.id}[]`;
|
|
30
|
+
} else {
|
|
31
|
+
if (element.id === "items") {
|
|
32
|
+
const previousElement = config.path[i - 1];
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
isCustomTypeModelSlice(previousElement.model) ||
|
|
36
|
+
isSharedSliceModel(previousElement.model)
|
|
37
|
+
) {
|
|
38
|
+
return `${element.id}[]`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return element.id;
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
.join(".");
|
|
46
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CustomTypeModelField } from "@prismicio/types";
|
|
2
|
+
|
|
3
|
+
import { FIELD_DOCUMENTATION_URLS } from "../constants";
|
|
4
|
+
|
|
5
|
+
type GetFieldDocumentationURLConfig = {
|
|
6
|
+
model: CustomTypeModelField;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const getFieldDocumentationURL = (
|
|
10
|
+
config: GetFieldDocumentationURLConfig,
|
|
11
|
+
): string => {
|
|
12
|
+
return FIELD_DOCUMENTATION_URLS[config.model.type];
|
|
13
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CustomTypeModel,
|
|
3
|
+
CustomTypeModelField,
|
|
4
|
+
CustomTypeModelSlice,
|
|
5
|
+
SharedSliceModel,
|
|
6
|
+
} from "@prismicio/types";
|
|
7
|
+
|
|
8
|
+
import { PathElement } from "../types";
|
|
9
|
+
import { getHumanReadableModelName } from "./getHumanReadableModelName";
|
|
10
|
+
|
|
11
|
+
type GetHumanReadableFieldPathConfig = {
|
|
12
|
+
path: [
|
|
13
|
+
PathElement<CustomTypeModel | SharedSliceModel>,
|
|
14
|
+
...PathElement<CustomTypeModelField | CustomTypeModelSlice>[]
|
|
15
|
+
];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getHumanReadableFieldPath = (
|
|
19
|
+
config: GetHumanReadableFieldPathConfig,
|
|
20
|
+
): string => {
|
|
21
|
+
return config.path
|
|
22
|
+
.map((element) => {
|
|
23
|
+
if (element.label) {
|
|
24
|
+
return element.label;
|
|
25
|
+
} else if (element.model) {
|
|
26
|
+
return getHumanReadableModelName({
|
|
27
|
+
id: element.id,
|
|
28
|
+
model: element.model,
|
|
29
|
+
});
|
|
30
|
+
} else {
|
|
31
|
+
return element.id;
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.join(" → ");
|
|
35
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { CustomTypeModelField } from "@prismicio/types";
|
|
2
|
+
import { CustomTypeModelLinkSelectType } from "@prismicio/types";
|
|
3
|
+
|
|
4
|
+
type GetFieldHumanReadableTypeConfig = {
|
|
5
|
+
model: CustomTypeModelField;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const getHumanReadableFieldType = (
|
|
9
|
+
config: GetFieldHumanReadableTypeConfig,
|
|
10
|
+
): string => {
|
|
11
|
+
switch (config.model.type) {
|
|
12
|
+
case "StructuredText": {
|
|
13
|
+
const isTitleField =
|
|
14
|
+
"single" in config.model.config &&
|
|
15
|
+
config.model.config.single
|
|
16
|
+
.split(",")
|
|
17
|
+
.every((blockType) => /heading/.test(blockType));
|
|
18
|
+
|
|
19
|
+
return isTitleField ? "Title" : "Rich Text";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
case "IntegrationFields": {
|
|
23
|
+
return `Integration Fields (Catalog: \`${config.model.config.catalog}\`)`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
case "Link": {
|
|
27
|
+
switch (config.model.config.select) {
|
|
28
|
+
case CustomTypeModelLinkSelectType.Document: {
|
|
29
|
+
return "Content Relationship";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
case CustomTypeModelLinkSelectType.Media: {
|
|
33
|
+
return "Link to Media";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
default: {
|
|
37
|
+
return "Link";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
case "Slices": {
|
|
43
|
+
return "Slice Zone";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
default: {
|
|
47
|
+
return config.model.type;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CustomTypeModel,
|
|
3
|
+
CustomTypeModelField,
|
|
4
|
+
CustomTypeModelSlice,
|
|
5
|
+
SharedSliceModel,
|
|
6
|
+
} from "@prismicio/types";
|
|
7
|
+
|
|
8
|
+
import { isCustomTypeModel } from "./isCustomTypeModel";
|
|
9
|
+
import { isCustomTypeModelField } from "./isCustomTypeModelField";
|
|
10
|
+
import { isCustomTypeModelSlice } from "./isCustomTypeModelSlice";
|
|
11
|
+
import { isSharedSliceModel } from "./isSharedSliceModel";
|
|
12
|
+
|
|
13
|
+
type GetModelHumanNameConfig = {
|
|
14
|
+
id: string;
|
|
15
|
+
model:
|
|
16
|
+
| CustomTypeModel
|
|
17
|
+
| SharedSliceModel
|
|
18
|
+
| CustomTypeModelField
|
|
19
|
+
| CustomTypeModelSlice;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const getHumanReadableModelName = (
|
|
23
|
+
config: GetModelHumanNameConfig,
|
|
24
|
+
): string => {
|
|
25
|
+
if (isCustomTypeModel(config.model)) {
|
|
26
|
+
return config.model.label;
|
|
27
|
+
} else if (isSharedSliceModel(config.model)) {
|
|
28
|
+
return config.model.name;
|
|
29
|
+
} else if (
|
|
30
|
+
isCustomTypeModelField(config.model) &&
|
|
31
|
+
"label" in config.model.config
|
|
32
|
+
) {
|
|
33
|
+
return config.model.config.label;
|
|
34
|
+
} else if (isCustomTypeModelSlice(config.model)) {
|
|
35
|
+
return config.model.fieldset;
|
|
36
|
+
} else {
|
|
37
|
+
// Slice Zone
|
|
38
|
+
return `Slice Zone (\`${config.id}\`)`;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as tsm from "ts-morph";
|
|
2
|
+
// import prettier from "prettier";
|
|
3
|
+
|
|
4
|
+
import { BLANK_LINE_IDENTIFIER } from "../constants";
|
|
5
|
+
|
|
6
|
+
export const getSourceFileText = (sourceFile: tsm.SourceFile): string => {
|
|
7
|
+
const text = sourceFile
|
|
8
|
+
.print()
|
|
9
|
+
.replace(new RegExp(BLANK_LINE_IDENTIFIER, "g"), "");
|
|
10
|
+
|
|
11
|
+
return text;
|
|
12
|
+
|
|
13
|
+
// return prettier.format(text, { parser: "typescript" });
|
|
14
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CustomTypeModelField } from "@prismicio/types";
|
|
2
|
+
|
|
3
|
+
export const isCustomTypeModelField = (
|
|
4
|
+
model: unknown,
|
|
5
|
+
): model is CustomTypeModelField => {
|
|
6
|
+
return (
|
|
7
|
+
typeof model === "object" &&
|
|
8
|
+
model !== null &&
|
|
9
|
+
"type" in model &&
|
|
10
|
+
"config" in model
|
|
11
|
+
);
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CustomTypeModelSlice } from "@prismicio/types";
|
|
2
|
+
|
|
3
|
+
export const isCustomTypeModelSlice = (
|
|
4
|
+
model: unknown,
|
|
5
|
+
): model is CustomTypeModelSlice => {
|
|
6
|
+
return (
|
|
7
|
+
typeof model === "object" &&
|
|
8
|
+
model !== null &&
|
|
9
|
+
"non-repeat" in model &&
|
|
10
|
+
"repeat" in model
|
|
11
|
+
);
|
|
12
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CodeBlockWriter } from "ts-morph";
|
|
2
|
+
|
|
3
|
+
type BuildFieldDocsConfig = {
|
|
4
|
+
writer: CodeBlockWriter;
|
|
5
|
+
description?: string;
|
|
6
|
+
fieldType?: string;
|
|
7
|
+
defaultValue?: string | boolean;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
apiIDPath?: string;
|
|
10
|
+
documentationURL?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const writeFieldDocsDescription = (
|
|
14
|
+
config: BuildFieldDocsConfig,
|
|
15
|
+
): void => {
|
|
16
|
+
if (config.description) {
|
|
17
|
+
config.writer.writeLine(config.description);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
config.writer.blankLineIfLastNot();
|
|
21
|
+
|
|
22
|
+
if (config.fieldType) {
|
|
23
|
+
config.writer.writeLine(`- **Field Type**: ${config.fieldType}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (config.placeholder) {
|
|
27
|
+
config.writer.writeLine(`- **Placeholder**: ${config.placeholder}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (config.defaultValue !== undefined) {
|
|
31
|
+
const stringifiedDefaultValue =
|
|
32
|
+
typeof config.defaultValue === "boolean"
|
|
33
|
+
? `${config.defaultValue}`
|
|
34
|
+
: config.defaultValue;
|
|
35
|
+
|
|
36
|
+
config.writer.writeLine(`- **Default Value**: ${stringifiedDefaultValue}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (config.apiIDPath) {
|
|
40
|
+
config.writer.writeLine(`- **API ID Path**: ${config.apiIDPath}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (config.documentationURL) {
|
|
44
|
+
config.writer.writeLine(`- **Documentation**: ${config.documentationURL}`);
|
|
45
|
+
}
|
|
46
|
+
};
|