@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";
|
|
@@ -90,6 +91,15 @@ export async function pageTypeAddFieldTimestamp(): 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 pageTypeAddFieldTimestamp(): 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: Timestamp = {
|
|
150
151
|
type: "Timestamp",
|
|
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 pageTypeAddFieldTimestamp(): Promise<void> {
|
|
|
171
201
|
return;
|
|
172
202
|
}
|
|
173
203
|
|
|
174
|
-
|
|
204
|
+
if (fieldPath.type === "nested") {
|
|
205
|
+
console.info(`Added field "${fieldPath.nestedFieldId}" (Timestamp) to group "${fieldPath.groupId}" in ${typeId}`);
|
|
206
|
+
} else {
|
|
207
|
+
console.info(`Added field "${fieldId}" (Timestamp) to "${targetTab}" tab in ${typeId}`);
|
|
208
|
+
}
|
|
175
209
|
|
|
176
210
|
try {
|
|
177
211
|
await buildTypes({ output: types });
|
|
@@ -187,7 +221,7 @@ export async function pageTypeAddFieldTimestamp(): 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 { 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,22 @@ export async function pageTypeAddFieldUid(): 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
|
+
|
|
101
|
+
// UID fields cannot be nested in groups
|
|
102
|
+
if (fieldPath.type === "nested") {
|
|
103
|
+
console.error("UID fields cannot be nested inside groups");
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
91
108
|
// Find the page type file
|
|
92
109
|
const projectRoot = await findUpward("package.json");
|
|
93
110
|
if (!projectRoot) {
|
|
@@ -184,7 +201,7 @@ export async function pageTypeAddFieldUid(): Promise<void> {
|
|
|
184
201
|
if (frameworkInfo?.framework) {
|
|
185
202
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
186
203
|
console.info(
|
|
187
|
-
` Run \`prismic docs ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
204
|
+
` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
|
|
188
205
|
);
|
|
189
206
|
}
|
|
190
207
|
}
|
|
@@ -5,6 +5,7 @@ import { pageTypeAddFieldColor } from "./page-type-add-field-color";
|
|
|
5
5
|
import { pageTypeAddFieldDate } from "./page-type-add-field-date";
|
|
6
6
|
import { pageTypeAddFieldEmbed } from "./page-type-add-field-embed";
|
|
7
7
|
import { pageTypeAddFieldGeoPoint } from "./page-type-add-field-geo-point";
|
|
8
|
+
import { pageTypeAddFieldGroup } from "./page-type-add-field-group";
|
|
8
9
|
import { pageTypeAddFieldImage } from "./page-type-add-field-image";
|
|
9
10
|
import { pageTypeAddFieldKeyText } from "./page-type-add-field-key-text";
|
|
10
11
|
import { pageTypeAddFieldLink } from "./page-type-add-field-link";
|
|
@@ -26,6 +27,7 @@ FIELD TYPES
|
|
|
26
27
|
date Date picker
|
|
27
28
|
embed Embed (oEmbed)
|
|
28
29
|
geo-point Geographic coordinates
|
|
30
|
+
group Repeatable group of fields
|
|
29
31
|
image Image
|
|
30
32
|
key-text Single-line text
|
|
31
33
|
link Any link type
|
|
@@ -76,6 +78,9 @@ export async function pageTypeAddField(): Promise<void> {
|
|
|
76
78
|
case "geo-point":
|
|
77
79
|
await pageTypeAddFieldGeoPoint();
|
|
78
80
|
break;
|
|
81
|
+
case "group":
|
|
82
|
+
await pageTypeAddFieldGroup();
|
|
83
|
+
break;
|
|
79
84
|
case "image":
|
|
80
85
|
await pageTypeAddFieldImage();
|
|
81
86
|
break;
|
package/src/page-type-create.ts
CHANGED
|
@@ -151,7 +151,7 @@ export async function pageTypeCreate(): Promise<void> {
|
|
|
151
151
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
152
152
|
const anchor = getWritePageComponentsAnchor(frameworkInfo.framework);
|
|
153
153
|
console.info(
|
|
154
|
-
` Run \`prismic docs ${docsPath}${anchor}\` to learn how to implement a page file`,
|
|
154
|
+
` Run \`prismic docs fetch ${docsPath}${anchor}\` to learn how to implement a page file`,
|
|
155
155
|
);
|
|
156
156
|
}
|
|
157
157
|
}
|
package/src/repo-create.ts
CHANGED
|
@@ -102,6 +102,23 @@ export async function repoCreate(): Promise<void> {
|
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
// Check if domain is available
|
|
106
|
+
const available = await checkDomainAvailable(domain);
|
|
107
|
+
if (!available.ok) {
|
|
108
|
+
if (available.error instanceof ForbiddenRequestError) {
|
|
109
|
+
handleUnauthenticated();
|
|
110
|
+
} else {
|
|
111
|
+
console.error(`Failed to check domain availability: ${stringify(available.error)}`);
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (!available.value) {
|
|
117
|
+
console.error(`Repository name "${domain}" is already taken.`);
|
|
118
|
+
process.exitCode = 1;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
105
122
|
const response = await createRepository(domain, name);
|
|
106
123
|
if (!response.ok) {
|
|
107
124
|
if (response.error instanceof ForbiddenRequestError) {
|
|
@@ -143,8 +160,18 @@ export async function repoCreate(): Promise<void> {
|
|
|
143
160
|
const clientFile = getClientFilePath(frameworkInfo);
|
|
144
161
|
const fileDesc = clientFile ? `creating ${clientFile}` : "configuring Prismic";
|
|
145
162
|
console.info();
|
|
146
|
-
console.info(`Next: Run \`prismic docs ${docsPath}${anchor}\` for instructions on ${fileDesc}`);
|
|
163
|
+
console.info(`Next: Run \`prismic docs fetch ${docsPath}${anchor}\` for instructions on ${fileDesc}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function checkDomainAvailable(domain: string) {
|
|
168
|
+
const url = new URL(`/app/dashboard/repositories/${domain}/exists`, await readHost());
|
|
169
|
+
const response = await request<string>(url);
|
|
170
|
+
if (!response.ok) {
|
|
171
|
+
return response;
|
|
147
172
|
}
|
|
173
|
+
// Endpoint returns "false" when repository exists, "true" when available
|
|
174
|
+
return { ok: true as const, value: response.value === "true" };
|
|
148
175
|
}
|
|
149
176
|
|
|
150
177
|
async function createRepository(domain: string, name = domain) {
|
|
@@ -4,6 +4,7 @@ import { writeFile } from "node:fs/promises";
|
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
5
|
|
|
6
6
|
import { buildTypes } from "./codegen-types";
|
|
7
|
+
import { findGroupInVariation, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
|
|
7
8
|
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
8
9
|
import { stringify } from "./lib/json";
|
|
9
10
|
import { findSliceModel } from "./lib/slice";
|
|
@@ -101,6 +102,15 @@ export async function sliceAddFieldBoolean(): Promise<void> {
|
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
// Parse and validate field path
|
|
106
|
+
const fieldPath = parseFieldPath(fieldId);
|
|
107
|
+
const pathValidation = validateNestedFieldPath(fieldPath);
|
|
108
|
+
if (!pathValidation.ok) {
|
|
109
|
+
console.error(pathValidation.error);
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
104
114
|
// Find the slice model
|
|
105
115
|
const result = await findSliceModel(sliceId);
|
|
106
116
|
if (!result.ok) {
|
|
@@ -136,28 +146,55 @@ export async function sliceAddFieldBoolean(): Promise<void> {
|
|
|
136
146
|
targetVariation.primary = {};
|
|
137
147
|
}
|
|
138
148
|
|
|
139
|
-
// Check if field already exists in any variation
|
|
140
|
-
for (const v of model.variations) {
|
|
141
|
-
if (v.primary?.[fieldId]) {
|
|
142
|
-
console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
|
|
143
|
-
process.exitCode = 1;
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
149
|
// Build field definition
|
|
149
150
|
const fieldDefinition: BooleanField = {
|
|
150
151
|
type: "Boolean",
|
|
151
152
|
config: {
|
|
152
|
-
label: label ?? humanReadable(fieldId),
|
|
153
|
+
label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
|
|
153
154
|
...(defaultValue && { default_value: true }),
|
|
154
155
|
...(trueLabel && { placeholder_true: trueLabel }),
|
|
155
156
|
...(falseLabel && { placeholder_false: falseLabel }),
|
|
156
157
|
},
|
|
157
158
|
};
|
|
158
159
|
|
|
159
|
-
// Add field to variation
|
|
160
|
-
|
|
160
|
+
// Add field to variation (with nested field support)
|
|
161
|
+
if (fieldPath.type === "nested") {
|
|
162
|
+
const groupResult = findGroupInVariation(targetVariation.primary, fieldPath.groupId, targetVariation.id);
|
|
163
|
+
if (!groupResult.ok) {
|
|
164
|
+
console.error(groupResult.error);
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// Check if nested field already exists
|
|
169
|
+
if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
|
|
170
|
+
console.error(
|
|
171
|
+
`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`,
|
|
172
|
+
);
|
|
173
|
+
process.exitCode = 1;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
|
|
177
|
+
} else {
|
|
178
|
+
// Check if field already exists in any variation (at top level or in groups)
|
|
179
|
+
for (const v of model.variations) {
|
|
180
|
+
if (v.primary?.[fieldId]) {
|
|
181
|
+
console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
|
|
182
|
+
process.exitCode = 1;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// Also check inside groups
|
|
186
|
+
for (const [groupFieldId, groupField] of Object.entries(v.primary ?? {})) {
|
|
187
|
+
if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
|
|
188
|
+
console.error(
|
|
189
|
+
`Field "${fieldId}" already exists in group "${groupFieldId}" in variation "${v.id}"`,
|
|
190
|
+
);
|
|
191
|
+
process.exitCode = 1;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
targetVariation.primary[fieldId] = fieldDefinition;
|
|
197
|
+
}
|
|
161
198
|
|
|
162
199
|
// Write updated model
|
|
163
200
|
try {
|
|
@@ -172,9 +209,15 @@ export async function sliceAddFieldBoolean(): Promise<void> {
|
|
|
172
209
|
return;
|
|
173
210
|
}
|
|
174
211
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
212
|
+
if (fieldPath.type === "nested") {
|
|
213
|
+
console.info(
|
|
214
|
+
`Added field "${fieldPath.nestedFieldId}" (Boolean) to group "${fieldPath.groupId}" in ${sliceId}`,
|
|
215
|
+
);
|
|
216
|
+
} else {
|
|
217
|
+
console.info(
|
|
218
|
+
`Added field "${fieldId}" (Boolean) to "${targetVariation.id}" variation in ${sliceId}`,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
178
221
|
|
|
179
222
|
try {
|
|
180
223
|
await buildTypes({ output: types });
|
|
@@ -191,7 +234,7 @@ export async function sliceAddFieldBoolean(): Promise<void> {
|
|
|
191
234
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
192
235
|
const anchor = getWriteComponentsAnchor(frameworkInfo.framework);
|
|
193
236
|
console.info(
|
|
194
|
-
` Run \`prismic docs ${docsPath}${anchor}\` to learn how to implement the slice's component`,
|
|
237
|
+
` Run \`prismic docs fetch ${docsPath}${anchor}\` to learn how to implement the slice's component`,
|
|
195
238
|
);
|
|
196
239
|
}
|
|
197
240
|
}
|
|
@@ -4,6 +4,7 @@ import { writeFile } from "node:fs/promises";
|
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
5
|
|
|
6
6
|
import { buildTypes } from "./codegen-types";
|
|
7
|
+
import { findGroupInVariation, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
|
|
7
8
|
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
8
9
|
import { stringify } from "./lib/json";
|
|
9
10
|
import { findSliceModel } from "./lib/slice";
|
|
@@ -89,6 +90,15 @@ export async function sliceAddFieldColor(): Promise<void> {
|
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
// Parse and validate field path
|
|
94
|
+
const fieldPath = parseFieldPath(fieldId);
|
|
95
|
+
const pathValidation = validateNestedFieldPath(fieldPath);
|
|
96
|
+
if (!pathValidation.ok) {
|
|
97
|
+
console.error(pathValidation.error);
|
|
98
|
+
process.exitCode = 1;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
// Find the slice model
|
|
93
103
|
const result = await findSliceModel(sliceId);
|
|
94
104
|
if (!result.ok) {
|
|
@@ -124,26 +134,53 @@ export async function sliceAddFieldColor(): Promise<void> {
|
|
|
124
134
|
targetVariation.primary = {};
|
|
125
135
|
}
|
|
126
136
|
|
|
127
|
-
// Check if field already exists in any variation
|
|
128
|
-
for (const v of model.variations) {
|
|
129
|
-
if (v.primary?.[fieldId]) {
|
|
130
|
-
console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
|
|
131
|
-
process.exitCode = 1;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
137
|
// Build field definition
|
|
137
138
|
const fieldDefinition: Color = {
|
|
138
139
|
type: "Color",
|
|
139
140
|
config: {
|
|
140
|
-
label: label ?? humanReadable(fieldId),
|
|
141
|
+
label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
|
|
141
142
|
...(placeholder && { placeholder }),
|
|
142
143
|
},
|
|
143
144
|
};
|
|
144
145
|
|
|
145
|
-
// Add field to variation
|
|
146
|
-
|
|
146
|
+
// Add field to variation (with nested field support)
|
|
147
|
+
if (fieldPath.type === "nested") {
|
|
148
|
+
const groupResult = findGroupInVariation(targetVariation.primary, fieldPath.groupId, targetVariation.id);
|
|
149
|
+
if (!groupResult.ok) {
|
|
150
|
+
console.error(groupResult.error);
|
|
151
|
+
process.exitCode = 1;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
// Check if nested field already exists
|
|
155
|
+
if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
|
|
156
|
+
console.error(
|
|
157
|
+
`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`,
|
|
158
|
+
);
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
|
|
163
|
+
} else {
|
|
164
|
+
// Check if field already exists in any variation (at top level or in groups)
|
|
165
|
+
for (const v of model.variations) {
|
|
166
|
+
if (v.primary?.[fieldId]) {
|
|
167
|
+
console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
// Also check inside groups
|
|
172
|
+
for (const [groupFieldId, groupField] of Object.entries(v.primary ?? {})) {
|
|
173
|
+
if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
|
|
174
|
+
console.error(
|
|
175
|
+
`Field "${fieldId}" already exists in group "${groupFieldId}" in variation "${v.id}"`,
|
|
176
|
+
);
|
|
177
|
+
process.exitCode = 1;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
targetVariation.primary[fieldId] = fieldDefinition;
|
|
183
|
+
}
|
|
147
184
|
|
|
148
185
|
// Write updated model
|
|
149
186
|
try {
|
|
@@ -158,9 +195,15 @@ export async function sliceAddFieldColor(): Promise<void> {
|
|
|
158
195
|
return;
|
|
159
196
|
}
|
|
160
197
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
198
|
+
if (fieldPath.type === "nested") {
|
|
199
|
+
console.info(
|
|
200
|
+
`Added field "${fieldPath.nestedFieldId}" (Color) to group "${fieldPath.groupId}" in ${sliceId}`,
|
|
201
|
+
);
|
|
202
|
+
} else {
|
|
203
|
+
console.info(
|
|
204
|
+
`Added field "${fieldId}" (Color) to "${targetVariation.id}" variation in ${sliceId}`,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
164
207
|
|
|
165
208
|
try {
|
|
166
209
|
await buildTypes({ output: types });
|
|
@@ -177,7 +220,7 @@ export async function sliceAddFieldColor(): Promise<void> {
|
|
|
177
220
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
178
221
|
const anchor = getWriteComponentsAnchor(frameworkInfo.framework);
|
|
179
222
|
console.info(
|
|
180
|
-
` Run \`prismic docs ${docsPath}${anchor}\` to learn how to implement the slice's component`,
|
|
223
|
+
` Run \`prismic docs fetch ${docsPath}${anchor}\` to learn how to implement the slice's component`,
|
|
181
224
|
);
|
|
182
225
|
}
|
|
183
226
|
}
|
|
@@ -4,6 +4,7 @@ import { writeFile } from "node:fs/promises";
|
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
5
|
|
|
6
6
|
import { buildTypes } from "./codegen-types";
|
|
7
|
+
import { findGroupInVariation, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
|
|
7
8
|
import { type Framework, detectFrameworkInfo } from "./lib/framework";
|
|
8
9
|
import { stringify } from "./lib/json";
|
|
9
10
|
import { findSliceModel } from "./lib/slice";
|
|
@@ -89,6 +90,15 @@ export async function sliceAddFieldDate(): Promise<void> {
|
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
// Parse and validate field path
|
|
94
|
+
const fieldPath = parseFieldPath(fieldId);
|
|
95
|
+
const pathValidation = validateNestedFieldPath(fieldPath);
|
|
96
|
+
if (!pathValidation.ok) {
|
|
97
|
+
console.error(pathValidation.error);
|
|
98
|
+
process.exitCode = 1;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
// Find the slice model
|
|
93
103
|
const result = await findSliceModel(sliceId);
|
|
94
104
|
if (!result.ok) {
|
|
@@ -124,26 +134,53 @@ export async function sliceAddFieldDate(): Promise<void> {
|
|
|
124
134
|
targetVariation.primary = {};
|
|
125
135
|
}
|
|
126
136
|
|
|
127
|
-
// Check if field already exists in any variation
|
|
128
|
-
for (const v of model.variations) {
|
|
129
|
-
if (v.primary?.[fieldId]) {
|
|
130
|
-
console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
|
|
131
|
-
process.exitCode = 1;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
137
|
// Build field definition
|
|
137
138
|
const fieldDefinition: DateField = {
|
|
138
139
|
type: "Date",
|
|
139
140
|
config: {
|
|
140
|
-
label: label ?? humanReadable(fieldId),
|
|
141
|
+
label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
|
|
141
142
|
...(placeholder && { placeholder }),
|
|
142
143
|
},
|
|
143
144
|
};
|
|
144
145
|
|
|
145
|
-
// Add field to variation
|
|
146
|
-
|
|
146
|
+
// Add field to variation (with nested field support)
|
|
147
|
+
if (fieldPath.type === "nested") {
|
|
148
|
+
const groupResult = findGroupInVariation(targetVariation.primary, fieldPath.groupId, targetVariation.id);
|
|
149
|
+
if (!groupResult.ok) {
|
|
150
|
+
console.error(groupResult.error);
|
|
151
|
+
process.exitCode = 1;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
// Check if nested field already exists
|
|
155
|
+
if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
|
|
156
|
+
console.error(
|
|
157
|
+
`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`,
|
|
158
|
+
);
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
|
|
163
|
+
} else {
|
|
164
|
+
// Check if field already exists in any variation (at top level or in groups)
|
|
165
|
+
for (const v of model.variations) {
|
|
166
|
+
if (v.primary?.[fieldId]) {
|
|
167
|
+
console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
// Also check inside groups
|
|
172
|
+
for (const [groupFieldId, groupField] of Object.entries(v.primary ?? {})) {
|
|
173
|
+
if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
|
|
174
|
+
console.error(
|
|
175
|
+
`Field "${fieldId}" already exists in group "${groupFieldId}" in variation "${v.id}"`,
|
|
176
|
+
);
|
|
177
|
+
process.exitCode = 1;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
targetVariation.primary[fieldId] = fieldDefinition;
|
|
183
|
+
}
|
|
147
184
|
|
|
148
185
|
// Write updated model
|
|
149
186
|
try {
|
|
@@ -158,9 +195,15 @@ export async function sliceAddFieldDate(): Promise<void> {
|
|
|
158
195
|
return;
|
|
159
196
|
}
|
|
160
197
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
198
|
+
if (fieldPath.type === "nested") {
|
|
199
|
+
console.info(
|
|
200
|
+
`Added field "${fieldPath.nestedFieldId}" (Date) to group "${fieldPath.groupId}" in ${sliceId}`,
|
|
201
|
+
);
|
|
202
|
+
} else {
|
|
203
|
+
console.info(
|
|
204
|
+
`Added field "${fieldId}" (Date) to "${targetVariation.id}" variation in ${sliceId}`,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
164
207
|
|
|
165
208
|
try {
|
|
166
209
|
await buildTypes({ output: types });
|
|
@@ -177,7 +220,7 @@ export async function sliceAddFieldDate(): Promise<void> {
|
|
|
177
220
|
const docsPath = getDocsPath(frameworkInfo.framework);
|
|
178
221
|
const anchor = getWriteComponentsAnchor(frameworkInfo.framework);
|
|
179
222
|
console.info(
|
|
180
|
-
` Run \`prismic docs ${docsPath}${anchor}\` to learn how to implement the slice's component`,
|
|
223
|
+
` Run \`prismic docs fetch ${docsPath}${anchor}\` to learn how to implement the slice's component`,
|
|
181
224
|
);
|
|
182
225
|
}
|
|
183
226
|
}
|