@angeloashmore/prismic-cli-poc 0.0.0-canary.fe51fbb → 0.0.0-pr.10.032f7ef
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.mjs +229 -136
- package/package.json +1 -1
- package/src/custom-type-add-field-boolean.ts +49 -12
- package/src/custom-type-add-field-color.ts +46 -12
- package/src/custom-type-add-field-date.ts +46 -12
- package/src/custom-type-add-field-embed.ts +46 -12
- package/src/custom-type-add-field-geo-point.ts +46 -12
- package/src/custom-type-add-field-group.ts +179 -0
- package/src/custom-type-add-field-image.ts +46 -12
- package/src/custom-type-add-field-key-text.ts +46 -12
- package/src/custom-type-add-field-link.ts +46 -12
- package/src/custom-type-add-field-number.ts +46 -12
- package/src/custom-type-add-field-rich-text.ts +46 -12
- package/src/custom-type-add-field-select.ts +46 -12
- package/src/custom-type-add-field-timestamp.ts +46 -12
- package/src/custom-type-add-field-uid.ts +17 -0
- package/src/custom-type-add-field.ts +5 -0
- package/src/docs-fetch.ts +146 -0
- package/src/docs-list.ts +131 -0
- package/src/docs.ts +26 -121
- package/src/index.ts +1 -1
- package/src/lib/field-path.ts +81 -0
- package/src/page-type-add-field-boolean.ts +47 -13
- package/src/page-type-add-field-color.ts +47 -13
- package/src/page-type-add-field-date.ts +47 -13
- package/src/page-type-add-field-embed.ts +47 -13
- package/src/page-type-add-field-geo-point.ts +47 -13
- package/src/page-type-add-field-group.ts +198 -0
- package/src/page-type-add-field-image.ts +47 -13
- package/src/page-type-add-field-key-text.ts +47 -13
- package/src/page-type-add-field-link.ts +47 -13
- package/src/page-type-add-field-number.ts +47 -13
- package/src/page-type-add-field-rich-text.ts +47 -13
- package/src/page-type-add-field-select.ts +47 -13
- package/src/page-type-add-field-timestamp.ts +47 -13
- package/src/page-type-add-field-uid.ts +18 -1
- package/src/page-type-add-field.ts +5 -0
- package/src/page-type-create.ts +1 -1
- package/src/repo-create.ts +28 -1
- package/src/slice-add-field-boolean.ts +59 -16
- package/src/slice-add-field-color.ts +59 -16
- package/src/slice-add-field-date.ts +59 -16
- package/src/slice-add-field-embed.ts +59 -16
- package/src/slice-add-field-geo-point.ts +59 -16
- package/src/slice-add-field-group.ts +191 -0
- package/src/slice-add-field-image.ts +59 -16
- package/src/slice-add-field-key-text.ts +59 -16
- package/src/slice-add-field-link.ts +59 -16
- package/src/slice-add-field-number.ts +59 -16
- package/src/slice-add-field-rich-text.ts +59 -16
- package/src/slice-add-field-select.ts +59 -16
- package/src/slice-add-field-timestamp.ts +59 -16
- package/src/slice-add-field.ts +5 -0
- package/src/status.ts +1 -1
|
@@ -6,6 +6,7 @@ import * as v from "valibot";
|
|
|
6
6
|
|
|
7
7
|
import { buildTypes } from "./codegen-types";
|
|
8
8
|
import { findUpward } from "./lib/file";
|
|
9
|
+
import { findGroupInTab, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
|
|
9
10
|
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
10
11
|
import { stringify } from "./lib/json";
|
|
11
12
|
import { humanReadable } from "./lib/string";
|
|
@@ -88,6 +89,15 @@ export async function pageTypeAddFieldColor(): Promise<void> {
|
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
// Parse and validate field path
|
|
93
|
+
const fieldPath = parseFieldPath(fieldId);
|
|
94
|
+
const pathValidation = validateNestedFieldPath(fieldPath);
|
|
95
|
+
if (!pathValidation.ok) {
|
|
96
|
+
console.error(pathValidation.error);
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
91
101
|
// Find the page type file
|
|
92
102
|
const projectRoot = await findUpward("package.json");
|
|
93
103
|
if (!projectRoot) {
|
|
@@ -134,26 +144,46 @@ export async function pageTypeAddFieldColor(): Promise<void> {
|
|
|
134
144
|
model.json[targetTab] = {};
|
|
135
145
|
}
|
|
136
146
|
|
|
137
|
-
// Check if field already exists in any tab
|
|
138
|
-
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
139
|
-
if (tabFields[fieldId]) {
|
|
140
|
-
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
141
|
-
process.exitCode = 1;
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
147
|
// Build field definition
|
|
147
148
|
const fieldDefinition: Color = {
|
|
148
149
|
type: "Color",
|
|
149
150
|
config: {
|
|
150
|
-
label: label ?? humanReadable(fieldId),
|
|
151
|
+
label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
|
|
151
152
|
...(placeholder && { placeholder }),
|
|
152
153
|
},
|
|
153
154
|
};
|
|
154
155
|
|
|
155
156
|
// Add field to model
|
|
156
|
-
|
|
157
|
+
if (fieldPath.type === "nested") {
|
|
158
|
+
const groupResult = findGroupInTab(model.json[targetTab], fieldPath.groupId, targetTab);
|
|
159
|
+
if (!groupResult.ok) {
|
|
160
|
+
console.error(groupResult.error);
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
|
|
165
|
+
console.error(`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`);
|
|
166
|
+
process.exitCode = 1;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
|
|
170
|
+
} else {
|
|
171
|
+
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
172
|
+
if (tabFields[fieldId]) {
|
|
173
|
+
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
174
|
+
process.exitCode = 1;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
for (const [groupFieldId, groupField] of Object.entries(tabFields)) {
|
|
178
|
+
if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
|
|
179
|
+
console.error(`Field "${fieldId}" already exists in group "${groupFieldId}" in tab "${tabName}"`);
|
|
180
|
+
process.exitCode = 1;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
model.json[targetTab][fieldId] = fieldDefinition;
|
|
186
|
+
}
|
|
157
187
|
|
|
158
188
|
// Write updated model
|
|
159
189
|
try {
|
|
@@ -168,7 +198,11 @@ export async function pageTypeAddFieldColor(): Promise<void> {
|
|
|
168
198
|
return;
|
|
169
199
|
}
|
|
170
200
|
|
|
171
|
-
|
|
201
|
+
if (fieldPath.type === "nested") {
|
|
202
|
+
console.info(`Added field "${fieldPath.nestedFieldId}" (Color) to group "${fieldPath.groupId}" in ${typeId}`);
|
|
203
|
+
} else {
|
|
204
|
+
console.info(`Added field "${fieldId}" (Color) to "${targetTab}" tab in ${typeId}`);
|
|
205
|
+
}
|
|
172
206
|
|
|
173
207
|
try {
|
|
174
208
|
await buildTypes({ output: types });
|
|
@@ -184,7 +218,7 @@ export async function pageTypeAddFieldColor(): Promise<void> {
|
|
|
184
218
|
if (frameworkInfo?.framework) {
|
|
185
219
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
186
220
|
console.info(
|
|
187
|
-
` Run \`prismic docs ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
221
|
+
` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
188
222
|
);
|
|
189
223
|
}
|
|
190
224
|
}
|
|
@@ -6,6 +6,7 @@ import * as v from "valibot";
|
|
|
6
6
|
|
|
7
7
|
import { buildTypes } from "./codegen-types";
|
|
8
8
|
import { findUpward } from "./lib/file";
|
|
9
|
+
import { findGroupInTab, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
|
|
9
10
|
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
10
11
|
import { stringify } from "./lib/json";
|
|
11
12
|
import { humanReadable } from "./lib/string";
|
|
@@ -90,6 +91,15 @@ export async function pageTypeAddFieldDate(): Promise<void> {
|
|
|
90
91
|
return;
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
// Parse and validate field path
|
|
95
|
+
const fieldPath = parseFieldPath(fieldId);
|
|
96
|
+
const pathValidation = validateNestedFieldPath(fieldPath);
|
|
97
|
+
if (!pathValidation.ok) {
|
|
98
|
+
console.error(pathValidation.error);
|
|
99
|
+
process.exitCode = 1;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
93
103
|
// Find the page type file
|
|
94
104
|
const projectRoot = await findUpward("package.json");
|
|
95
105
|
if (!projectRoot) {
|
|
@@ -136,27 +146,47 @@ export async function pageTypeAddFieldDate(): Promise<void> {
|
|
|
136
146
|
model.json[targetTab] = {};
|
|
137
147
|
}
|
|
138
148
|
|
|
139
|
-
// Check if field already exists in any tab
|
|
140
|
-
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
141
|
-
if (tabFields[fieldId]) {
|
|
142
|
-
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
143
|
-
process.exitCode = 1;
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
149
|
// Build field definition
|
|
149
150
|
const fieldDefinition: DateField = {
|
|
150
151
|
type: "Date",
|
|
151
152
|
config: {
|
|
152
|
-
label: label ?? humanReadable(fieldId),
|
|
153
|
+
label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
|
|
153
154
|
...(placeholder && { placeholder }),
|
|
154
155
|
...(defaultValue && { default: defaultValue }),
|
|
155
156
|
},
|
|
156
157
|
};
|
|
157
158
|
|
|
158
159
|
// Add field to model
|
|
159
|
-
|
|
160
|
+
if (fieldPath.type === "nested") {
|
|
161
|
+
const groupResult = findGroupInTab(model.json[targetTab], fieldPath.groupId, targetTab);
|
|
162
|
+
if (!groupResult.ok) {
|
|
163
|
+
console.error(groupResult.error);
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
|
|
168
|
+
console.error(`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`);
|
|
169
|
+
process.exitCode = 1;
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
|
|
173
|
+
} else {
|
|
174
|
+
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
175
|
+
if (tabFields[fieldId]) {
|
|
176
|
+
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
177
|
+
process.exitCode = 1;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
for (const [groupFieldId, groupField] of Object.entries(tabFields)) {
|
|
181
|
+
if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
|
|
182
|
+
console.error(`Field "${fieldId}" already exists in group "${groupFieldId}" in tab "${tabName}"`);
|
|
183
|
+
process.exitCode = 1;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
model.json[targetTab][fieldId] = fieldDefinition;
|
|
189
|
+
}
|
|
160
190
|
|
|
161
191
|
// Write updated model
|
|
162
192
|
try {
|
|
@@ -171,7 +201,11 @@ export async function pageTypeAddFieldDate(): Promise<void> {
|
|
|
171
201
|
return;
|
|
172
202
|
}
|
|
173
203
|
|
|
174
|
-
|
|
204
|
+
if (fieldPath.type === "nested") {
|
|
205
|
+
console.info(`Added field "${fieldPath.nestedFieldId}" (Date) to group "${fieldPath.groupId}" in ${typeId}`);
|
|
206
|
+
} else {
|
|
207
|
+
console.info(`Added field "${fieldId}" (Date) to "${targetTab}" tab in ${typeId}`);
|
|
208
|
+
}
|
|
175
209
|
|
|
176
210
|
try {
|
|
177
211
|
await buildTypes({ output: types });
|
|
@@ -187,7 +221,7 @@ export async function pageTypeAddFieldDate(): Promise<void> {
|
|
|
187
221
|
if (frameworkInfo?.framework) {
|
|
188
222
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
189
223
|
console.info(
|
|
190
|
-
` Run \`prismic docs ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
224
|
+
` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
191
225
|
);
|
|
192
226
|
}
|
|
193
227
|
}
|
|
@@ -6,6 +6,7 @@ import * as v from "valibot";
|
|
|
6
6
|
|
|
7
7
|
import { buildTypes } from "./codegen-types";
|
|
8
8
|
import { findUpward } from "./lib/file";
|
|
9
|
+
import { findGroupInTab, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
|
|
9
10
|
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
10
11
|
import { stringify } from "./lib/json";
|
|
11
12
|
import { humanReadable } from "./lib/string";
|
|
@@ -88,6 +89,15 @@ export async function pageTypeAddFieldEmbed(): Promise<void> {
|
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
// Parse and validate field path
|
|
93
|
+
const fieldPath = parseFieldPath(fieldId);
|
|
94
|
+
const pathValidation = validateNestedFieldPath(fieldPath);
|
|
95
|
+
if (!pathValidation.ok) {
|
|
96
|
+
console.error(pathValidation.error);
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
91
101
|
// Find the page type file
|
|
92
102
|
const projectRoot = await findUpward("package.json");
|
|
93
103
|
if (!projectRoot) {
|
|
@@ -134,26 +144,46 @@ export async function pageTypeAddFieldEmbed(): Promise<void> {
|
|
|
134
144
|
model.json[targetTab] = {};
|
|
135
145
|
}
|
|
136
146
|
|
|
137
|
-
// Check if field already exists in any tab
|
|
138
|
-
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
139
|
-
if (tabFields[fieldId]) {
|
|
140
|
-
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
141
|
-
process.exitCode = 1;
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
147
|
// Build field definition
|
|
147
148
|
const fieldDefinition: Embed = {
|
|
148
149
|
type: "Embed",
|
|
149
150
|
config: {
|
|
150
|
-
label: label ?? humanReadable(fieldId),
|
|
151
|
+
label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
|
|
151
152
|
...(placeholder && { placeholder }),
|
|
152
153
|
},
|
|
153
154
|
};
|
|
154
155
|
|
|
155
156
|
// Add field to model
|
|
156
|
-
|
|
157
|
+
if (fieldPath.type === "nested") {
|
|
158
|
+
const groupResult = findGroupInTab(model.json[targetTab], fieldPath.groupId, targetTab);
|
|
159
|
+
if (!groupResult.ok) {
|
|
160
|
+
console.error(groupResult.error);
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
|
|
165
|
+
console.error(`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`);
|
|
166
|
+
process.exitCode = 1;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
|
|
170
|
+
} else {
|
|
171
|
+
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
172
|
+
if (tabFields[fieldId]) {
|
|
173
|
+
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
174
|
+
process.exitCode = 1;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
for (const [groupFieldId, groupField] of Object.entries(tabFields)) {
|
|
178
|
+
if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
|
|
179
|
+
console.error(`Field "${fieldId}" already exists in group "${groupFieldId}" in tab "${tabName}"`);
|
|
180
|
+
process.exitCode = 1;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
model.json[targetTab][fieldId] = fieldDefinition;
|
|
186
|
+
}
|
|
157
187
|
|
|
158
188
|
// Write updated model
|
|
159
189
|
try {
|
|
@@ -168,7 +198,11 @@ export async function pageTypeAddFieldEmbed(): Promise<void> {
|
|
|
168
198
|
return;
|
|
169
199
|
}
|
|
170
200
|
|
|
171
|
-
|
|
201
|
+
if (fieldPath.type === "nested") {
|
|
202
|
+
console.info(`Added field "${fieldPath.nestedFieldId}" (Embed) to group "${fieldPath.groupId}" in ${typeId}`);
|
|
203
|
+
} else {
|
|
204
|
+
console.info(`Added field "${fieldId}" (Embed) to "${targetTab}" tab in ${typeId}`);
|
|
205
|
+
}
|
|
172
206
|
|
|
173
207
|
try {
|
|
174
208
|
await buildTypes({ output: types });
|
|
@@ -184,7 +218,7 @@ export async function pageTypeAddFieldEmbed(): Promise<void> {
|
|
|
184
218
|
if (frameworkInfo?.framework) {
|
|
185
219
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
186
220
|
console.info(
|
|
187
|
-
` Run \`prismic docs ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
221
|
+
` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
188
222
|
);
|
|
189
223
|
}
|
|
190
224
|
}
|
|
@@ -6,6 +6,7 @@ import * as v from "valibot";
|
|
|
6
6
|
|
|
7
7
|
import { buildTypes } from "./codegen-types";
|
|
8
8
|
import { findUpward } from "./lib/file";
|
|
9
|
+
import { findGroupInTab, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
|
|
9
10
|
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
10
11
|
import { stringify } from "./lib/json";
|
|
11
12
|
import { humanReadable } from "./lib/string";
|
|
@@ -86,6 +87,15 @@ export async function pageTypeAddFieldGeoPoint(): Promise<void> {
|
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
// Parse and validate field path
|
|
91
|
+
const fieldPath = parseFieldPath(fieldId);
|
|
92
|
+
const pathValidation = validateNestedFieldPath(fieldPath);
|
|
93
|
+
if (!pathValidation.ok) {
|
|
94
|
+
console.error(pathValidation.error);
|
|
95
|
+
process.exitCode = 1;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
89
99
|
// Find the page type file
|
|
90
100
|
const projectRoot = await findUpward("package.json");
|
|
91
101
|
if (!projectRoot) {
|
|
@@ -132,25 +142,45 @@ export async function pageTypeAddFieldGeoPoint(): Promise<void> {
|
|
|
132
142
|
model.json[targetTab] = {};
|
|
133
143
|
}
|
|
134
144
|
|
|
135
|
-
// Check if field already exists in any tab
|
|
136
|
-
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
137
|
-
if (tabFields[fieldId]) {
|
|
138
|
-
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
139
|
-
process.exitCode = 1;
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
145
|
// Build field definition
|
|
145
146
|
const fieldDefinition: GeoPoint = {
|
|
146
147
|
type: "GeoPoint",
|
|
147
148
|
config: {
|
|
148
|
-
label: label ?? humanReadable(fieldId),
|
|
149
|
+
label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
|
|
149
150
|
},
|
|
150
151
|
};
|
|
151
152
|
|
|
152
153
|
// Add field to model
|
|
153
|
-
|
|
154
|
+
if (fieldPath.type === "nested") {
|
|
155
|
+
const groupResult = findGroupInTab(model.json[targetTab], fieldPath.groupId, targetTab);
|
|
156
|
+
if (!groupResult.ok) {
|
|
157
|
+
console.error(groupResult.error);
|
|
158
|
+
process.exitCode = 1;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
|
|
162
|
+
console.error(`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`);
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
|
|
167
|
+
} else {
|
|
168
|
+
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
169
|
+
if (tabFields[fieldId]) {
|
|
170
|
+
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
171
|
+
process.exitCode = 1;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
for (const [groupFieldId, groupField] of Object.entries(tabFields)) {
|
|
175
|
+
if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
|
|
176
|
+
console.error(`Field "${fieldId}" already exists in group "${groupFieldId}" in tab "${tabName}"`);
|
|
177
|
+
process.exitCode = 1;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
model.json[targetTab][fieldId] = fieldDefinition;
|
|
183
|
+
}
|
|
154
184
|
|
|
155
185
|
// Write updated model
|
|
156
186
|
try {
|
|
@@ -165,7 +195,11 @@ export async function pageTypeAddFieldGeoPoint(): Promise<void> {
|
|
|
165
195
|
return;
|
|
166
196
|
}
|
|
167
197
|
|
|
168
|
-
|
|
198
|
+
if (fieldPath.type === "nested") {
|
|
199
|
+
console.info(`Added field "${fieldPath.nestedFieldId}" (GeoPoint) to group "${fieldPath.groupId}" in ${typeId}`);
|
|
200
|
+
} else {
|
|
201
|
+
console.info(`Added field "${fieldId}" (GeoPoint) to "${targetTab}" tab in ${typeId}`);
|
|
202
|
+
}
|
|
169
203
|
|
|
170
204
|
try {
|
|
171
205
|
await buildTypes({ output: types });
|
|
@@ -181,7 +215,7 @@ export async function pageTypeAddFieldGeoPoint(): Promise<void> {
|
|
|
181
215
|
if (frameworkInfo?.framework) {
|
|
182
216
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
183
217
|
console.info(
|
|
184
|
-
` Run \`prismic docs ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
218
|
+
` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
185
219
|
);
|
|
186
220
|
}
|
|
187
221
|
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type { CustomType, Group } from "@prismicio/types-internal/lib/customtypes";
|
|
2
|
+
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
import * as v from "valibot";
|
|
6
|
+
|
|
7
|
+
import { buildTypes } from "./codegen-types";
|
|
8
|
+
import { findUpward } from "./lib/file";
|
|
9
|
+
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
10
|
+
import { stringify } from "./lib/json";
|
|
11
|
+
import { humanReadable } from "./lib/string";
|
|
12
|
+
|
|
13
|
+
const HELP = `
|
|
14
|
+
Add a group field to an existing page type.
|
|
15
|
+
|
|
16
|
+
USAGE
|
|
17
|
+
prismic page-type add-field group <type-id> <field-id> [flags]
|
|
18
|
+
|
|
19
|
+
ARGUMENTS
|
|
20
|
+
type-id Page type identifier (required)
|
|
21
|
+
field-id Field identifier (required)
|
|
22
|
+
|
|
23
|
+
FLAGS
|
|
24
|
+
-t, --tab string Target tab (default: first existing tab, or "Main")
|
|
25
|
+
-l, --label string Display label for the field (inferred from field-id if omitted)
|
|
26
|
+
--non-repeatable Make this a non-repeating group (default: repeatable)
|
|
27
|
+
--types string Output file for generated types (default: "prismicio-types.d.ts")
|
|
28
|
+
-h, --help Show help for command
|
|
29
|
+
|
|
30
|
+
EXAMPLES
|
|
31
|
+
prismic page-type add-field group homepage buttons
|
|
32
|
+
prismic page-type add-field group article authors --non-repeatable
|
|
33
|
+
prismic page-type add-field group product variants --tab "Content"
|
|
34
|
+
`.trim();
|
|
35
|
+
|
|
36
|
+
const CustomTypeSchema = v.object({
|
|
37
|
+
id: v.string(),
|
|
38
|
+
label: v.string(),
|
|
39
|
+
repeatable: v.boolean(),
|
|
40
|
+
status: v.boolean(),
|
|
41
|
+
format: v.string(),
|
|
42
|
+
json: v.record(v.string(), v.record(v.string(), v.unknown())),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
function getDocsPath(framework: Framework): string {
|
|
46
|
+
switch (framework) {
|
|
47
|
+
case "next":
|
|
48
|
+
return "nextjs/with-cli";
|
|
49
|
+
case "nuxt":
|
|
50
|
+
return "nuxt/with-cli";
|
|
51
|
+
case "sveltekit":
|
|
52
|
+
return "sveltekit/with-cli";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function pageTypeAddFieldGroup(): Promise<void> {
|
|
57
|
+
const {
|
|
58
|
+
values: { help, tab, label, "non-repeatable": nonRepeatable, types },
|
|
59
|
+
positionals: [typeId, fieldId],
|
|
60
|
+
} = parseArgs({
|
|
61
|
+
args: process.argv.slice(5), // skip: node, script, "page-type", "add-field", "group"
|
|
62
|
+
options: {
|
|
63
|
+
tab: { type: "string", short: "t" },
|
|
64
|
+
label: { type: "string", short: "l" },
|
|
65
|
+
"non-repeatable": { type: "boolean" },
|
|
66
|
+
types: { type: "string" },
|
|
67
|
+
help: { type: "boolean", short: "h" },
|
|
68
|
+
},
|
|
69
|
+
allowPositionals: true,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (help) {
|
|
73
|
+
console.info(HELP);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!typeId) {
|
|
78
|
+
console.error("Missing required argument: type-id\n");
|
|
79
|
+
console.error("Usage: prismic page-type add-field group <type-id> <field-id>");
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!fieldId) {
|
|
85
|
+
console.error("Missing required argument: field-id\n");
|
|
86
|
+
console.error("Usage: prismic page-type add-field group <type-id> <field-id>");
|
|
87
|
+
process.exitCode = 1;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Groups cannot be nested
|
|
92
|
+
if (fieldId.includes(".")) {
|
|
93
|
+
console.error("Groups cannot be nested inside other groups");
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Find the page type file
|
|
99
|
+
const projectRoot = await findUpward("package.json");
|
|
100
|
+
if (!projectRoot) {
|
|
101
|
+
console.error("Could not find project root (no package.json found)");
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const modelPath = new URL(`customtypes/${typeId}/index.json`, projectRoot);
|
|
107
|
+
|
|
108
|
+
// Read and parse the model
|
|
109
|
+
let model: CustomType;
|
|
110
|
+
try {
|
|
111
|
+
const contents = await readFile(modelPath, "utf8");
|
|
112
|
+
const result = v.safeParse(CustomTypeSchema, JSON.parse(contents));
|
|
113
|
+
if (!result.success) {
|
|
114
|
+
console.error(`Invalid page type model: ${modelPath.href}`);
|
|
115
|
+
process.exitCode = 1;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
model = result.output as CustomType;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
121
|
+
console.error(`Page type not found: ${typeId}\n`);
|
|
122
|
+
console.error(`Create it first with: prismic page-type create ${typeId}`);
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (error instanceof Error) {
|
|
127
|
+
console.error(`Failed to read page type: ${error.message}`);
|
|
128
|
+
} else {
|
|
129
|
+
console.error("Failed to read page type");
|
|
130
|
+
}
|
|
131
|
+
process.exitCode = 1;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Determine target tab
|
|
136
|
+
const existingTabs = Object.keys(model.json);
|
|
137
|
+
const targetTab = tab ?? existingTabs[0] ?? "Main";
|
|
138
|
+
|
|
139
|
+
// Initialize tab if it doesn't exist
|
|
140
|
+
if (!model.json[targetTab]) {
|
|
141
|
+
model.json[targetTab] = {};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Check if field already exists in any tab
|
|
145
|
+
for (const [tabName, tabFields] of Object.entries(model.json)) {
|
|
146
|
+
if (tabFields[fieldId]) {
|
|
147
|
+
console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Build field definition
|
|
154
|
+
const fieldDefinition: Group = {
|
|
155
|
+
type: "Group",
|
|
156
|
+
config: {
|
|
157
|
+
label: label ?? humanReadable(fieldId),
|
|
158
|
+
repeat: !nonRepeatable,
|
|
159
|
+
fields: {},
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Add field to model
|
|
164
|
+
model.json[targetTab][fieldId] = fieldDefinition;
|
|
165
|
+
|
|
166
|
+
// Write updated model
|
|
167
|
+
try {
|
|
168
|
+
await writeFile(modelPath, stringify(model));
|
|
169
|
+
} catch (error) {
|
|
170
|
+
if (error instanceof Error) {
|
|
171
|
+
console.error(`Failed to update page type: ${error.message}`);
|
|
172
|
+
} else {
|
|
173
|
+
console.error("Failed to update page type");
|
|
174
|
+
}
|
|
175
|
+
process.exitCode = 1;
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.info(`Added field "${fieldId}" (Group) to "${targetTab}" tab in ${typeId}`);
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
await buildTypes({ output: types });
|
|
183
|
+
console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
console.info();
|
|
189
|
+
console.info(`Next: Add fields to the group with \`prismic page-type add-field <type> ${typeId} ${fieldId}.<field-id>\``);
|
|
190
|
+
|
|
191
|
+
const frameworkInfo = await detectFrameworkInfo();
|
|
192
|
+
if (frameworkInfo?.framework) {
|
|
193
|
+
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
194
|
+
console.info(
|
|
195
|
+
` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|