prismic 0.0.0-pr.28.59bf330
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 +69 -0
- package/dist/builders-hKD4IrLX-DsO7BUQw.mjs +97 -0
- package/dist/dist-B11B2hHn.mjs +1 -0
- package/dist/dist-DT8CtumB.mjs +1 -0
- package/dist/framework-CfjEoVk0.mjs +17 -0
- package/dist/index.mjs +2537 -0
- package/dist/nextjs-9z7YrSnS.mjs +312 -0
- package/dist/nuxt-KoJ61G2q.mjs +59 -0
- package/dist/sveltekit-DjXKCG78.mjs +226 -0
- package/package.json +58 -0
- package/src/codegen-types.ts +82 -0
- package/src/codegen.ts +45 -0
- package/src/custom-type-add-field-boolean.ts +185 -0
- package/src/custom-type-add-field-color.ts +168 -0
- package/src/custom-type-add-field-date.ts +171 -0
- package/src/custom-type-add-field-embed.ts +168 -0
- package/src/custom-type-add-field-geo-point.ts +165 -0
- package/src/custom-type-add-field-group.ts +142 -0
- package/src/custom-type-add-field-image.ts +168 -0
- package/src/custom-type-add-field-key-text.ts +168 -0
- package/src/custom-type-add-field-link.ts +191 -0
- package/src/custom-type-add-field-number.ts +200 -0
- package/src/custom-type-add-field-rich-text.ts +192 -0
- package/src/custom-type-add-field-select.ts +174 -0
- package/src/custom-type-add-field-timestamp.ts +171 -0
- package/src/custom-type-add-field-uid.ts +151 -0
- package/src/custom-type-add-field.ts +116 -0
- package/src/custom-type-connect-slice.ts +178 -0
- package/src/custom-type-create.ts +98 -0
- package/src/custom-type-disconnect-slice.ts +134 -0
- package/src/custom-type-list.ts +110 -0
- package/src/custom-type-remove-field.ts +135 -0
- package/src/custom-type-remove.ts +103 -0
- package/src/custom-type-set-name.ts +102 -0
- package/src/custom-type-view.ts +118 -0
- package/src/custom-type.ts +85 -0
- package/src/docs-fetch.ts +146 -0
- package/src/docs-list.ts +131 -0
- package/src/docs.ts +54 -0
- package/src/env.d.ts +12 -0
- package/src/framework/index.ts +399 -0
- package/src/framework/nextjs.templates.ts +426 -0
- package/src/framework/nextjs.ts +216 -0
- package/src/framework/nuxt.templates.ts +74 -0
- package/src/framework/nuxt.ts +250 -0
- package/src/framework/sveltekit.templates.ts +278 -0
- package/src/framework/sveltekit.ts +241 -0
- package/src/index.ts +155 -0
- package/src/init.ts +173 -0
- package/src/lib/auth.ts +200 -0
- package/src/lib/browser.ts +11 -0
- package/src/lib/config.ts +111 -0
- package/src/lib/custom-types-api.ts +385 -0
- package/src/lib/field-path.ts +81 -0
- package/src/lib/file.ts +49 -0
- package/src/lib/json.ts +3 -0
- package/src/lib/packageJson.ts +35 -0
- package/src/lib/profile.ts +39 -0
- package/src/lib/request.ts +116 -0
- package/src/lib/segment.ts +145 -0
- package/src/lib/sentry.ts +63 -0
- package/src/lib/string.ts +10 -0
- package/src/lib/url.ts +31 -0
- package/src/locale-add.ts +116 -0
- package/src/locale-list.ts +107 -0
- package/src/locale-remove.ts +88 -0
- package/src/locale-set-default.ts +131 -0
- package/src/locale.ts +60 -0
- package/src/login.ts +45 -0
- package/src/logout.ts +36 -0
- package/src/page-type-add-field-boolean.ts +179 -0
- package/src/page-type-add-field-color.ts +165 -0
- package/src/page-type-add-field-date.ts +168 -0
- package/src/page-type-add-field-embed.ts +165 -0
- package/src/page-type-add-field-geo-point.ts +162 -0
- package/src/page-type-add-field-group.ts +139 -0
- package/src/page-type-add-field-image.ts +165 -0
- package/src/page-type-add-field-key-text.ts +165 -0
- package/src/page-type-add-field-link.ts +188 -0
- package/src/page-type-add-field-number.ts +197 -0
- package/src/page-type-add-field-rich-text.ts +189 -0
- package/src/page-type-add-field-select.ts +171 -0
- package/src/page-type-add-field-timestamp.ts +168 -0
- package/src/page-type-add-field-uid.ts +148 -0
- package/src/page-type-add-field.ts +116 -0
- package/src/page-type-connect-slice.ts +178 -0
- package/src/page-type-create.ts +128 -0
- package/src/page-type-disconnect-slice.ts +134 -0
- package/src/page-type-list.ts +109 -0
- package/src/page-type-remove-field.ts +135 -0
- package/src/page-type-remove.ts +103 -0
- package/src/page-type-set-name.ts +102 -0
- package/src/page-type-set-repeatable.ts +111 -0
- package/src/page-type-view.ts +118 -0
- package/src/page-type.ts +90 -0
- package/src/preview-add.ts +126 -0
- package/src/preview-get-simulator.ts +104 -0
- package/src/preview-list.ts +106 -0
- package/src/preview-remove-simulator.ts +80 -0
- package/src/preview-remove.ts +109 -0
- package/src/preview-set-name.ts +137 -0
- package/src/preview-set-simulator.ts +116 -0
- package/src/preview.ts +75 -0
- package/src/pull.ts +236 -0
- package/src/push.ts +409 -0
- package/src/repo-create.ts +175 -0
- package/src/repo-get-access.ts +86 -0
- package/src/repo-list.ts +100 -0
- package/src/repo-set-access.ts +100 -0
- package/src/repo-set-name.ts +102 -0
- package/src/repo-view.ts +113 -0
- package/src/repo.ts +70 -0
- package/src/slice-add-field-boolean.ts +219 -0
- package/src/slice-add-field-color.ts +205 -0
- package/src/slice-add-field-date.ts +205 -0
- package/src/slice-add-field-embed.ts +205 -0
- package/src/slice-add-field-geo-point.ts +202 -0
- package/src/slice-add-field-group.ts +170 -0
- package/src/slice-add-field-image.ts +202 -0
- package/src/slice-add-field-key-text.ts +205 -0
- package/src/slice-add-field-link.ts +224 -0
- package/src/slice-add-field-number.ts +205 -0
- package/src/slice-add-field-rich-text.ts +229 -0
- package/src/slice-add-field-select.ts +211 -0
- package/src/slice-add-field-timestamp.ts +205 -0
- package/src/slice-add-field.ts +111 -0
- package/src/slice-add-variation.ts +142 -0
- package/src/slice-create.ts +164 -0
- package/src/slice-list-variations.ts +71 -0
- package/src/slice-list.ts +60 -0
- package/src/slice-remove-field.ts +125 -0
- package/src/slice-remove-variation.ts +113 -0
- package/src/slice-remove.ts +92 -0
- package/src/slice-rename.ts +104 -0
- package/src/slice-set-screenshot.ts +239 -0
- package/src/slice-view.ts +83 -0
- package/src/slice.ts +95 -0
- package/src/status.ts +834 -0
- package/src/sync.ts +259 -0
- package/src/token-create.ts +203 -0
- package/src/token-delete.ts +182 -0
- package/src/token-list.ts +223 -0
- package/src/token-set-name.ts +193 -0
- package/src/token.ts +60 -0
- package/src/webhook-add-header.ts +118 -0
- package/src/webhook-create.ts +152 -0
- package/src/webhook-disable.ts +109 -0
- package/src/webhook-enable.ts +132 -0
- package/src/webhook-list.ts +93 -0
- package/src/webhook-remove-header.ts +117 -0
- package/src/webhook-remove.ts +106 -0
- package/src/webhook-set-triggers.ts +148 -0
- package/src/webhook-status.ts +90 -0
- package/src/webhook-test.ts +106 -0
- package/src/webhook-view.ts +147 -0
- package/src/webhook.ts +95 -0
- package/src/whoami.ts +62 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { parseArgs } from "node:util";
|
|
2
|
+
|
|
3
|
+
import { customTypeAddFieldBoolean } from "./custom-type-add-field-boolean";
|
|
4
|
+
import { customTypeAddFieldColor } from "./custom-type-add-field-color";
|
|
5
|
+
import { customTypeAddFieldDate } from "./custom-type-add-field-date";
|
|
6
|
+
import { customTypeAddFieldEmbed } from "./custom-type-add-field-embed";
|
|
7
|
+
import { customTypeAddFieldGeoPoint } from "./custom-type-add-field-geo-point";
|
|
8
|
+
import { customTypeAddFieldGroup } from "./custom-type-add-field-group";
|
|
9
|
+
import { customTypeAddFieldImage } from "./custom-type-add-field-image";
|
|
10
|
+
import { customTypeAddFieldKeyText } from "./custom-type-add-field-key-text";
|
|
11
|
+
import { customTypeAddFieldLink } from "./custom-type-add-field-link";
|
|
12
|
+
import { customTypeAddFieldNumber } from "./custom-type-add-field-number";
|
|
13
|
+
import { customTypeAddFieldRichText } from "./custom-type-add-field-rich-text";
|
|
14
|
+
import { customTypeAddFieldSelect } from "./custom-type-add-field-select";
|
|
15
|
+
import { customTypeAddFieldTimestamp } from "./custom-type-add-field-timestamp";
|
|
16
|
+
import { customTypeAddFieldUid } from "./custom-type-add-field-uid";
|
|
17
|
+
|
|
18
|
+
const HELP = `
|
|
19
|
+
Add a field to an existing custom type.
|
|
20
|
+
|
|
21
|
+
USAGE
|
|
22
|
+
prismic custom-type add-field <field-type> <type-id> <field-id> [flags]
|
|
23
|
+
|
|
24
|
+
FIELD TYPES
|
|
25
|
+
boolean Boolean toggle
|
|
26
|
+
color Color picker
|
|
27
|
+
date Date picker
|
|
28
|
+
embed Embed (oEmbed)
|
|
29
|
+
geo-point Geographic coordinates
|
|
30
|
+
group Repeatable group of fields
|
|
31
|
+
image Image
|
|
32
|
+
key-text Single-line text
|
|
33
|
+
link Any link type
|
|
34
|
+
number Number
|
|
35
|
+
rich-text Rich text editor
|
|
36
|
+
select Dropdown select
|
|
37
|
+
timestamp Date and time
|
|
38
|
+
uid Unique identifier
|
|
39
|
+
|
|
40
|
+
FLAGS
|
|
41
|
+
-h, --help Show help for command
|
|
42
|
+
|
|
43
|
+
LEARN MORE
|
|
44
|
+
Use \`prismic custom-type add-field <field-type> --help\` for more information.
|
|
45
|
+
|
|
46
|
+
EXAMPLES
|
|
47
|
+
prismic custom-type add-field key-text homepage meta_title --tab "SEO"
|
|
48
|
+
prismic custom-type add-field link homepage button --allow-text
|
|
49
|
+
prismic custom-type add-field rich-text homepage body --multi "paragraph,heading2,strong,em"
|
|
50
|
+
prismic custom-type add-field select homepage layout --option "full" --option "sidebar"
|
|
51
|
+
`.trim();
|
|
52
|
+
|
|
53
|
+
export async function customTypeAddField(): Promise<void> {
|
|
54
|
+
const {
|
|
55
|
+
positionals: [fieldType],
|
|
56
|
+
} = parseArgs({
|
|
57
|
+
args: process.argv.slice(4), // skip: node, script, "custom-type", "add-field"
|
|
58
|
+
options: {
|
|
59
|
+
help: { type: "boolean", short: "h" },
|
|
60
|
+
},
|
|
61
|
+
allowPositionals: true,
|
|
62
|
+
strict: false,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
switch (fieldType) {
|
|
66
|
+
case "boolean":
|
|
67
|
+
await customTypeAddFieldBoolean();
|
|
68
|
+
break;
|
|
69
|
+
case "color":
|
|
70
|
+
await customTypeAddFieldColor();
|
|
71
|
+
break;
|
|
72
|
+
case "date":
|
|
73
|
+
await customTypeAddFieldDate();
|
|
74
|
+
break;
|
|
75
|
+
case "embed":
|
|
76
|
+
await customTypeAddFieldEmbed();
|
|
77
|
+
break;
|
|
78
|
+
case "geo-point":
|
|
79
|
+
await customTypeAddFieldGeoPoint();
|
|
80
|
+
break;
|
|
81
|
+
case "group":
|
|
82
|
+
await customTypeAddFieldGroup();
|
|
83
|
+
break;
|
|
84
|
+
case "image":
|
|
85
|
+
await customTypeAddFieldImage();
|
|
86
|
+
break;
|
|
87
|
+
case "key-text":
|
|
88
|
+
await customTypeAddFieldKeyText();
|
|
89
|
+
break;
|
|
90
|
+
case "link":
|
|
91
|
+
await customTypeAddFieldLink();
|
|
92
|
+
break;
|
|
93
|
+
case "number":
|
|
94
|
+
await customTypeAddFieldNumber();
|
|
95
|
+
break;
|
|
96
|
+
case "rich-text":
|
|
97
|
+
await customTypeAddFieldRichText();
|
|
98
|
+
break;
|
|
99
|
+
case "select":
|
|
100
|
+
await customTypeAddFieldSelect();
|
|
101
|
+
break;
|
|
102
|
+
case "timestamp":
|
|
103
|
+
await customTypeAddFieldTimestamp();
|
|
104
|
+
break;
|
|
105
|
+
case "uid":
|
|
106
|
+
await customTypeAddFieldUid();
|
|
107
|
+
break;
|
|
108
|
+
default: {
|
|
109
|
+
if (fieldType) {
|
|
110
|
+
console.error(`Unknown field type: ${fieldType}\n`);
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
}
|
|
113
|
+
console.info(HELP);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CustomType,
|
|
3
|
+
DynamicSlices,
|
|
4
|
+
SharedSliceRef,
|
|
5
|
+
} from "@prismicio/types-internal/lib/customtypes";
|
|
6
|
+
|
|
7
|
+
import { parseArgs } from "node:util";
|
|
8
|
+
|
|
9
|
+
import { buildTypes } from "./codegen-types";
|
|
10
|
+
import { requireFramework } from "./framework";
|
|
11
|
+
|
|
12
|
+
const HELP = `
|
|
13
|
+
Connect a shared slice to a custom type's slice zone.
|
|
14
|
+
|
|
15
|
+
USAGE
|
|
16
|
+
prismic custom-type connect-slice <type-id> <slice-id> [flags]
|
|
17
|
+
|
|
18
|
+
ARGUMENTS
|
|
19
|
+
type-id Custom type identifier (required)
|
|
20
|
+
slice-id Slice identifier (required)
|
|
21
|
+
|
|
22
|
+
FLAGS
|
|
23
|
+
-z, --slice-zone string Target slice zone field ID (default: "slices")
|
|
24
|
+
--types string Output file for generated types (default: "prismicio-types.d.ts")
|
|
25
|
+
-h, --help Show help for command
|
|
26
|
+
|
|
27
|
+
EXAMPLES
|
|
28
|
+
prismic custom-type connect-slice homepage CallToAction
|
|
29
|
+
prismic custom-type connect-slice homepage CallToAction --slice-zone slices
|
|
30
|
+
prismic custom-type connect-slice article HeroSection -z body
|
|
31
|
+
`.trim();
|
|
32
|
+
|
|
33
|
+
export async function customTypeConnectSlice(): Promise<void> {
|
|
34
|
+
const {
|
|
35
|
+
values: { help, "slice-zone": sliceZoneId, types },
|
|
36
|
+
positionals: [typeId, sliceId],
|
|
37
|
+
} = parseArgs({
|
|
38
|
+
args: process.argv.slice(4), // skip: node, script, "custom-type", "connect-slice"
|
|
39
|
+
options: {
|
|
40
|
+
"slice-zone": { type: "string", short: "z" },
|
|
41
|
+
types: { type: "string" },
|
|
42
|
+
help: { type: "boolean", short: "h" },
|
|
43
|
+
},
|
|
44
|
+
allowPositionals: true,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (help) {
|
|
48
|
+
console.info(HELP);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!typeId) {
|
|
53
|
+
console.error("Missing required argument: type-id\n");
|
|
54
|
+
console.error("Usage: prismic custom-type connect-slice <type-id> <slice-id>");
|
|
55
|
+
process.exitCode = 1;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!sliceId) {
|
|
60
|
+
console.error("Missing required argument: slice-id\n");
|
|
61
|
+
console.error("Usage: prismic custom-type connect-slice <type-id> <slice-id>");
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const framework = await requireFramework();
|
|
67
|
+
if (!framework) return;
|
|
68
|
+
|
|
69
|
+
// Verify the slice exists
|
|
70
|
+
try {
|
|
71
|
+
await framework.readSlice(sliceId);
|
|
72
|
+
} catch {
|
|
73
|
+
console.error(`Slice not found: ${sliceId}`);
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Read the custom type model
|
|
79
|
+
let model: CustomType;
|
|
80
|
+
try {
|
|
81
|
+
model = await framework.readCustomType(typeId);
|
|
82
|
+
} catch {
|
|
83
|
+
console.error(`Custom type not found: ${typeId}\n\nCreate it first with: prismic custom-type create ${typeId}`);
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const targetSliceZoneId = sliceZoneId ?? "slices";
|
|
89
|
+
|
|
90
|
+
// Find existing slice zone or create a new one
|
|
91
|
+
let sliceZone: DynamicSlices | undefined;
|
|
92
|
+
let sliceZoneFieldId: string | undefined;
|
|
93
|
+
|
|
94
|
+
// Search all tabs for a Slices field matching the target ID
|
|
95
|
+
for (const [, tabFields] of Object.entries(model.json)) {
|
|
96
|
+
for (const [fieldId, field] of Object.entries(tabFields)) {
|
|
97
|
+
if ((field as { type?: string }).type === "Slices" && fieldId === targetSliceZoneId) {
|
|
98
|
+
sliceZone = field as DynamicSlices;
|
|
99
|
+
sliceZoneFieldId = fieldId;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (sliceZone) break;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Handle slice zone not found
|
|
107
|
+
if (!sliceZone) {
|
|
108
|
+
if (sliceZoneId) {
|
|
109
|
+
// User specified a slice zone that doesn't exist
|
|
110
|
+
console.error(`Slice zone "${sliceZoneId}" not found in custom type "${typeId}"`);
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Create a new slice zone in the first tab
|
|
116
|
+
const existingTabs = Object.keys(model.json);
|
|
117
|
+
const targetTab = existingTabs[0] ?? "Main";
|
|
118
|
+
|
|
119
|
+
// Initialize tab if it doesn't exist
|
|
120
|
+
if (!model.json[targetTab]) {
|
|
121
|
+
model.json[targetTab] = {};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const newSliceZone: DynamicSlices = {
|
|
125
|
+
type: "Slices",
|
|
126
|
+
fieldset: "Slice Zone",
|
|
127
|
+
config: {
|
|
128
|
+
choices: {},
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
model.json[targetTab][targetSliceZoneId] = newSliceZone;
|
|
133
|
+
sliceZone = newSliceZone;
|
|
134
|
+
sliceZoneFieldId = targetSliceZoneId;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Ensure config and choices exist
|
|
138
|
+
if (!sliceZone.config) {
|
|
139
|
+
sliceZone.config = { choices: {} };
|
|
140
|
+
}
|
|
141
|
+
if (!sliceZone.config.choices) {
|
|
142
|
+
sliceZone.config.choices = {};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Check if slice is already connected
|
|
146
|
+
if (sliceId in sliceZone.config.choices) {
|
|
147
|
+
console.info(
|
|
148
|
+
`Slice "${sliceId}" is already connected to slice zone "${sliceZoneFieldId}" in ${typeId}`,
|
|
149
|
+
);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Add the slice reference
|
|
154
|
+
const sliceRef: SharedSliceRef = { type: "SharedSlice" };
|
|
155
|
+
sliceZone.config.choices[sliceId] = sliceRef;
|
|
156
|
+
|
|
157
|
+
// Write updated model
|
|
158
|
+
try {
|
|
159
|
+
await framework.updateCustomType(model);
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (error instanceof Error) {
|
|
162
|
+
console.error(`Failed to update custom type: ${error.message}`);
|
|
163
|
+
} else {
|
|
164
|
+
console.error("Failed to update custom type");
|
|
165
|
+
}
|
|
166
|
+
process.exitCode = 1;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
console.info(`Connected slice "${sliceId}" to slice zone "${sliceZoneFieldId}" in ${typeId}`);
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
await buildTypes({ output: types });
|
|
174
|
+
console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { CustomType } from "@prismicio/types-internal/lib/customtypes";
|
|
2
|
+
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
import { pascalCase } from "change-case";
|
|
5
|
+
|
|
6
|
+
import { buildTypes } from "./codegen-types";
|
|
7
|
+
import { requireFramework } from "./framework";
|
|
8
|
+
|
|
9
|
+
const HELP = `
|
|
10
|
+
Create a new custom type in a Prismic repository.
|
|
11
|
+
|
|
12
|
+
USAGE
|
|
13
|
+
prismic custom-type create <id> [flags]
|
|
14
|
+
|
|
15
|
+
ARGUMENTS
|
|
16
|
+
id Custom type identifier (required)
|
|
17
|
+
|
|
18
|
+
FLAGS
|
|
19
|
+
-n, --name string Display name for the custom type
|
|
20
|
+
--single Create as a singleton (non-repeatable) type
|
|
21
|
+
--types string Output file for generated types (default: "prismicio-types.d.ts")
|
|
22
|
+
-h, --help Show help for command
|
|
23
|
+
|
|
24
|
+
LEARN MORE
|
|
25
|
+
Use \`prismic custom-type <command> --help\` for more information about a command.
|
|
26
|
+
`.trim();
|
|
27
|
+
|
|
28
|
+
export async function customTypeCreate(): Promise<void> {
|
|
29
|
+
const {
|
|
30
|
+
values: { help, name, single, types },
|
|
31
|
+
positionals: [id],
|
|
32
|
+
} = parseArgs({
|
|
33
|
+
args: process.argv.slice(4), // skip: node, script, "custom-type", "create"
|
|
34
|
+
options: {
|
|
35
|
+
name: { type: "string", short: "n" },
|
|
36
|
+
single: { type: "boolean" },
|
|
37
|
+
types: { type: "string" },
|
|
38
|
+
help: { type: "boolean", short: "h" },
|
|
39
|
+
},
|
|
40
|
+
allowPositionals: true,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (help) {
|
|
44
|
+
console.info(HELP);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!id) {
|
|
49
|
+
console.error("Missing required argument: id");
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const framework = await requireFramework();
|
|
55
|
+
if (!framework) return;
|
|
56
|
+
|
|
57
|
+
const model = {
|
|
58
|
+
id,
|
|
59
|
+
label: name ?? pascalCase(id),
|
|
60
|
+
repeatable: !single,
|
|
61
|
+
status: true,
|
|
62
|
+
format: "custom",
|
|
63
|
+
json: {
|
|
64
|
+
Main: single
|
|
65
|
+
? {}
|
|
66
|
+
: {
|
|
67
|
+
uid: {
|
|
68
|
+
type: "UID",
|
|
69
|
+
config: { label: "UID", placeholder: "" },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
await framework.createCustomType(model as CustomType);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (error instanceof Error) {
|
|
79
|
+
console.error(`Failed to create custom type: ${error.message}`);
|
|
80
|
+
} else {
|
|
81
|
+
console.error(`Failed to create custom type`);
|
|
82
|
+
}
|
|
83
|
+
process.exitCode = 1;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.info(`Created custom type "${id}"`);
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
await buildTypes({ output: types });
|
|
91
|
+
console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.info();
|
|
97
|
+
console.info("Next: Add fields with `prismic custom-type add-field`");
|
|
98
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { CustomType, DynamicSlices } from "@prismicio/types-internal/lib/customtypes";
|
|
2
|
+
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
|
|
5
|
+
import { buildTypes } from "./codegen-types";
|
|
6
|
+
import { requireFramework } from "./framework";
|
|
7
|
+
|
|
8
|
+
const HELP = `
|
|
9
|
+
Disconnect a shared slice from a custom type's slice zone.
|
|
10
|
+
|
|
11
|
+
USAGE
|
|
12
|
+
prismic custom-type disconnect-slice <type-id> <slice-id> [flags]
|
|
13
|
+
|
|
14
|
+
ARGUMENTS
|
|
15
|
+
type-id Custom type identifier (required)
|
|
16
|
+
slice-id Slice identifier (required)
|
|
17
|
+
|
|
18
|
+
FLAGS
|
|
19
|
+
-z, --slice-zone string Target slice zone field ID (default: "slices")
|
|
20
|
+
--types string Output file for generated types (default: "prismicio-types.d.ts")
|
|
21
|
+
-h, --help Show help for command
|
|
22
|
+
|
|
23
|
+
EXAMPLES
|
|
24
|
+
prismic custom-type disconnect-slice homepage CallToAction
|
|
25
|
+
prismic custom-type disconnect-slice homepage CallToAction --slice-zone slices
|
|
26
|
+
prismic custom-type disconnect-slice article HeroSection -z body
|
|
27
|
+
`.trim();
|
|
28
|
+
|
|
29
|
+
export async function customTypeDisconnectSlice(): Promise<void> {
|
|
30
|
+
const {
|
|
31
|
+
values: { help, "slice-zone": sliceZoneId, types },
|
|
32
|
+
positionals: [typeId, sliceId],
|
|
33
|
+
} = parseArgs({
|
|
34
|
+
args: process.argv.slice(4), // skip: node, script, "custom-type", "disconnect-slice"
|
|
35
|
+
options: {
|
|
36
|
+
"slice-zone": { type: "string", short: "z" },
|
|
37
|
+
types: { type: "string" },
|
|
38
|
+
help: { type: "boolean", short: "h" },
|
|
39
|
+
},
|
|
40
|
+
allowPositionals: true,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (help) {
|
|
44
|
+
console.info(HELP);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!typeId) {
|
|
49
|
+
console.error("Missing required argument: type-id\n");
|
|
50
|
+
console.error("Usage: prismic custom-type disconnect-slice <type-id> <slice-id>");
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!sliceId) {
|
|
56
|
+
console.error("Missing required argument: slice-id\n");
|
|
57
|
+
console.error("Usage: prismic custom-type disconnect-slice <type-id> <slice-id>");
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const framework = await requireFramework();
|
|
63
|
+
if (!framework) return;
|
|
64
|
+
|
|
65
|
+
let model: CustomType;
|
|
66
|
+
try {
|
|
67
|
+
model = await framework.readCustomType(typeId);
|
|
68
|
+
} catch {
|
|
69
|
+
console.error(`Custom type not found: ${typeId}\n\nCreate it first with: prismic custom-type create ${typeId}`);
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const targetSliceZoneId = sliceZoneId ?? "slices";
|
|
75
|
+
|
|
76
|
+
// Find existing slice zone
|
|
77
|
+
let sliceZone: DynamicSlices | undefined;
|
|
78
|
+
let sliceZoneFieldId: string | undefined;
|
|
79
|
+
|
|
80
|
+
// Search all tabs for a Slices field matching the target ID
|
|
81
|
+
for (const [, tabFields] of Object.entries(model.json)) {
|
|
82
|
+
for (const [fieldId, field] of Object.entries(tabFields)) {
|
|
83
|
+
if ((field as { type?: string }).type === "Slices" && fieldId === targetSliceZoneId) {
|
|
84
|
+
sliceZone = field as DynamicSlices;
|
|
85
|
+
sliceZoneFieldId = fieldId;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (sliceZone) break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Slice zone must exist for disconnect
|
|
93
|
+
if (!sliceZone) {
|
|
94
|
+
console.error(`Slice zone "${targetSliceZoneId}" not found in custom type "${typeId}"`);
|
|
95
|
+
process.exitCode = 1;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Check if slice is connected
|
|
100
|
+
if (!sliceZone.config?.choices || !(sliceId in sliceZone.config.choices)) {
|
|
101
|
+
console.error(
|
|
102
|
+
`Slice "${sliceId}" is not connected to slice zone "${sliceZoneFieldId}" in ${typeId}`,
|
|
103
|
+
);
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Remove the slice reference
|
|
109
|
+
delete sliceZone.config.choices[sliceId];
|
|
110
|
+
|
|
111
|
+
// Write updated model
|
|
112
|
+
try {
|
|
113
|
+
await framework.updateCustomType(model);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
if (error instanceof Error) {
|
|
116
|
+
console.error(`Failed to update custom type: ${error.message}`);
|
|
117
|
+
} else {
|
|
118
|
+
console.error("Failed to update custom type");
|
|
119
|
+
}
|
|
120
|
+
process.exitCode = 1;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
console.info(
|
|
125
|
+
`Disconnected slice "${sliceId}" from slice zone "${sliceZoneFieldId}" in ${typeId}`,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
await buildTypes({ output: types });
|
|
130
|
+
console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import * as v from "valibot";
|
|
4
|
+
|
|
5
|
+
import { findUpward } from "./lib/file";
|
|
6
|
+
|
|
7
|
+
const HELP = `
|
|
8
|
+
List all custom types in a Prismic project.
|
|
9
|
+
|
|
10
|
+
USAGE
|
|
11
|
+
prismic custom-type list [flags]
|
|
12
|
+
|
|
13
|
+
FLAGS
|
|
14
|
+
--json Output as JSON
|
|
15
|
+
-h, --help Show help for command
|
|
16
|
+
|
|
17
|
+
EXAMPLES
|
|
18
|
+
prismic custom-type list
|
|
19
|
+
prismic custom-type list --json
|
|
20
|
+
`.trim();
|
|
21
|
+
|
|
22
|
+
const CustomTypeSchema = v.object({
|
|
23
|
+
id: v.string(),
|
|
24
|
+
label: v.string(),
|
|
25
|
+
repeatable: v.boolean(),
|
|
26
|
+
status: v.boolean(),
|
|
27
|
+
format: v.optional(v.string()),
|
|
28
|
+
json: v.record(v.string(), v.record(v.string(), v.unknown())),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export async function customTypeList(): Promise<void> {
|
|
32
|
+
const {
|
|
33
|
+
values: { help, json },
|
|
34
|
+
} = parseArgs({
|
|
35
|
+
args: process.argv.slice(4), // skip: node, script, "custom-type", "list"
|
|
36
|
+
options: {
|
|
37
|
+
json: { type: "boolean" },
|
|
38
|
+
help: { type: "boolean", short: "h" },
|
|
39
|
+
},
|
|
40
|
+
allowPositionals: true,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (help) {
|
|
44
|
+
console.info(HELP);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const projectRoot = await findUpward("package.json");
|
|
49
|
+
if (!projectRoot) {
|
|
50
|
+
console.error("Could not find project root (no package.json found)");
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const customTypesDirectory = new URL("customtypes/", projectRoot);
|
|
56
|
+
|
|
57
|
+
let entries: string[];
|
|
58
|
+
try {
|
|
59
|
+
entries = (await readdir(customTypesDirectory, {
|
|
60
|
+
withFileTypes: false,
|
|
61
|
+
})) as unknown as string[];
|
|
62
|
+
} catch {
|
|
63
|
+
if (json) {
|
|
64
|
+
console.info(JSON.stringify([]));
|
|
65
|
+
} else {
|
|
66
|
+
console.info("No custom types found.");
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const customTypes: { id: string; label: string; repeatable: boolean }[] = [];
|
|
72
|
+
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
const modelPath = new URL(`${entry}/index.json`, customTypesDirectory);
|
|
75
|
+
try {
|
|
76
|
+
const contents = await readFile(modelPath, "utf8");
|
|
77
|
+
const parsed = JSON.parse(contents);
|
|
78
|
+
const result = v.safeParse(CustomTypeSchema, parsed);
|
|
79
|
+
// Custom types have format !== "page" (either "custom" or undefined)
|
|
80
|
+
if (result.success && result.output.format !== "page") {
|
|
81
|
+
customTypes.push({
|
|
82
|
+
id: result.output.id,
|
|
83
|
+
label: result.output.label,
|
|
84
|
+
repeatable: result.output.repeatable,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
} catch {
|
|
88
|
+
// Skip directories without valid index.json
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (customTypes.length === 0) {
|
|
93
|
+
if (json) {
|
|
94
|
+
console.info(JSON.stringify([]));
|
|
95
|
+
} else {
|
|
96
|
+
console.info("No custom types found.");
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (json) {
|
|
102
|
+
console.info(JSON.stringify(customTypes, null, 2));
|
|
103
|
+
} else {
|
|
104
|
+
console.info("ID\tLABEL\tTYPE");
|
|
105
|
+
for (const customType of customTypes) {
|
|
106
|
+
const typeLabel = customType.repeatable ? "repeatable" : "singleton";
|
|
107
|
+
console.info(`${customType.id}\t${customType.label}\t${typeLabel}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|