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.
Files changed (158) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +69 -0
  3. package/dist/builders-hKD4IrLX-DsO7BUQw.mjs +97 -0
  4. package/dist/dist-B11B2hHn.mjs +1 -0
  5. package/dist/dist-DT8CtumB.mjs +1 -0
  6. package/dist/framework-CfjEoVk0.mjs +17 -0
  7. package/dist/index.mjs +2537 -0
  8. package/dist/nextjs-9z7YrSnS.mjs +312 -0
  9. package/dist/nuxt-KoJ61G2q.mjs +59 -0
  10. package/dist/sveltekit-DjXKCG78.mjs +226 -0
  11. package/package.json +58 -0
  12. package/src/codegen-types.ts +82 -0
  13. package/src/codegen.ts +45 -0
  14. package/src/custom-type-add-field-boolean.ts +185 -0
  15. package/src/custom-type-add-field-color.ts +168 -0
  16. package/src/custom-type-add-field-date.ts +171 -0
  17. package/src/custom-type-add-field-embed.ts +168 -0
  18. package/src/custom-type-add-field-geo-point.ts +165 -0
  19. package/src/custom-type-add-field-group.ts +142 -0
  20. package/src/custom-type-add-field-image.ts +168 -0
  21. package/src/custom-type-add-field-key-text.ts +168 -0
  22. package/src/custom-type-add-field-link.ts +191 -0
  23. package/src/custom-type-add-field-number.ts +200 -0
  24. package/src/custom-type-add-field-rich-text.ts +192 -0
  25. package/src/custom-type-add-field-select.ts +174 -0
  26. package/src/custom-type-add-field-timestamp.ts +171 -0
  27. package/src/custom-type-add-field-uid.ts +151 -0
  28. package/src/custom-type-add-field.ts +116 -0
  29. package/src/custom-type-connect-slice.ts +178 -0
  30. package/src/custom-type-create.ts +98 -0
  31. package/src/custom-type-disconnect-slice.ts +134 -0
  32. package/src/custom-type-list.ts +110 -0
  33. package/src/custom-type-remove-field.ts +135 -0
  34. package/src/custom-type-remove.ts +103 -0
  35. package/src/custom-type-set-name.ts +102 -0
  36. package/src/custom-type-view.ts +118 -0
  37. package/src/custom-type.ts +85 -0
  38. package/src/docs-fetch.ts +146 -0
  39. package/src/docs-list.ts +131 -0
  40. package/src/docs.ts +54 -0
  41. package/src/env.d.ts +12 -0
  42. package/src/framework/index.ts +399 -0
  43. package/src/framework/nextjs.templates.ts +426 -0
  44. package/src/framework/nextjs.ts +216 -0
  45. package/src/framework/nuxt.templates.ts +74 -0
  46. package/src/framework/nuxt.ts +250 -0
  47. package/src/framework/sveltekit.templates.ts +278 -0
  48. package/src/framework/sveltekit.ts +241 -0
  49. package/src/index.ts +155 -0
  50. package/src/init.ts +173 -0
  51. package/src/lib/auth.ts +200 -0
  52. package/src/lib/browser.ts +11 -0
  53. package/src/lib/config.ts +111 -0
  54. package/src/lib/custom-types-api.ts +385 -0
  55. package/src/lib/field-path.ts +81 -0
  56. package/src/lib/file.ts +49 -0
  57. package/src/lib/json.ts +3 -0
  58. package/src/lib/packageJson.ts +35 -0
  59. package/src/lib/profile.ts +39 -0
  60. package/src/lib/request.ts +116 -0
  61. package/src/lib/segment.ts +145 -0
  62. package/src/lib/sentry.ts +63 -0
  63. package/src/lib/string.ts +10 -0
  64. package/src/lib/url.ts +31 -0
  65. package/src/locale-add.ts +116 -0
  66. package/src/locale-list.ts +107 -0
  67. package/src/locale-remove.ts +88 -0
  68. package/src/locale-set-default.ts +131 -0
  69. package/src/locale.ts +60 -0
  70. package/src/login.ts +45 -0
  71. package/src/logout.ts +36 -0
  72. package/src/page-type-add-field-boolean.ts +179 -0
  73. package/src/page-type-add-field-color.ts +165 -0
  74. package/src/page-type-add-field-date.ts +168 -0
  75. package/src/page-type-add-field-embed.ts +165 -0
  76. package/src/page-type-add-field-geo-point.ts +162 -0
  77. package/src/page-type-add-field-group.ts +139 -0
  78. package/src/page-type-add-field-image.ts +165 -0
  79. package/src/page-type-add-field-key-text.ts +165 -0
  80. package/src/page-type-add-field-link.ts +188 -0
  81. package/src/page-type-add-field-number.ts +197 -0
  82. package/src/page-type-add-field-rich-text.ts +189 -0
  83. package/src/page-type-add-field-select.ts +171 -0
  84. package/src/page-type-add-field-timestamp.ts +168 -0
  85. package/src/page-type-add-field-uid.ts +148 -0
  86. package/src/page-type-add-field.ts +116 -0
  87. package/src/page-type-connect-slice.ts +178 -0
  88. package/src/page-type-create.ts +128 -0
  89. package/src/page-type-disconnect-slice.ts +134 -0
  90. package/src/page-type-list.ts +109 -0
  91. package/src/page-type-remove-field.ts +135 -0
  92. package/src/page-type-remove.ts +103 -0
  93. package/src/page-type-set-name.ts +102 -0
  94. package/src/page-type-set-repeatable.ts +111 -0
  95. package/src/page-type-view.ts +118 -0
  96. package/src/page-type.ts +90 -0
  97. package/src/preview-add.ts +126 -0
  98. package/src/preview-get-simulator.ts +104 -0
  99. package/src/preview-list.ts +106 -0
  100. package/src/preview-remove-simulator.ts +80 -0
  101. package/src/preview-remove.ts +109 -0
  102. package/src/preview-set-name.ts +137 -0
  103. package/src/preview-set-simulator.ts +116 -0
  104. package/src/preview.ts +75 -0
  105. package/src/pull.ts +236 -0
  106. package/src/push.ts +409 -0
  107. package/src/repo-create.ts +175 -0
  108. package/src/repo-get-access.ts +86 -0
  109. package/src/repo-list.ts +100 -0
  110. package/src/repo-set-access.ts +100 -0
  111. package/src/repo-set-name.ts +102 -0
  112. package/src/repo-view.ts +113 -0
  113. package/src/repo.ts +70 -0
  114. package/src/slice-add-field-boolean.ts +219 -0
  115. package/src/slice-add-field-color.ts +205 -0
  116. package/src/slice-add-field-date.ts +205 -0
  117. package/src/slice-add-field-embed.ts +205 -0
  118. package/src/slice-add-field-geo-point.ts +202 -0
  119. package/src/slice-add-field-group.ts +170 -0
  120. package/src/slice-add-field-image.ts +202 -0
  121. package/src/slice-add-field-key-text.ts +205 -0
  122. package/src/slice-add-field-link.ts +224 -0
  123. package/src/slice-add-field-number.ts +205 -0
  124. package/src/slice-add-field-rich-text.ts +229 -0
  125. package/src/slice-add-field-select.ts +211 -0
  126. package/src/slice-add-field-timestamp.ts +205 -0
  127. package/src/slice-add-field.ts +111 -0
  128. package/src/slice-add-variation.ts +142 -0
  129. package/src/slice-create.ts +164 -0
  130. package/src/slice-list-variations.ts +71 -0
  131. package/src/slice-list.ts +60 -0
  132. package/src/slice-remove-field.ts +125 -0
  133. package/src/slice-remove-variation.ts +113 -0
  134. package/src/slice-remove.ts +92 -0
  135. package/src/slice-rename.ts +104 -0
  136. package/src/slice-set-screenshot.ts +239 -0
  137. package/src/slice-view.ts +83 -0
  138. package/src/slice.ts +95 -0
  139. package/src/status.ts +834 -0
  140. package/src/sync.ts +259 -0
  141. package/src/token-create.ts +203 -0
  142. package/src/token-delete.ts +182 -0
  143. package/src/token-list.ts +223 -0
  144. package/src/token-set-name.ts +193 -0
  145. package/src/token.ts +60 -0
  146. package/src/webhook-add-header.ts +118 -0
  147. package/src/webhook-create.ts +152 -0
  148. package/src/webhook-disable.ts +109 -0
  149. package/src/webhook-enable.ts +132 -0
  150. package/src/webhook-list.ts +93 -0
  151. package/src/webhook-remove-header.ts +117 -0
  152. package/src/webhook-remove.ts +106 -0
  153. package/src/webhook-set-triggers.ts +148 -0
  154. package/src/webhook-status.ts +90 -0
  155. package/src/webhook-test.ts +106 -0
  156. package/src/webhook-view.ts +147 -0
  157. package/src/webhook.ts +95 -0
  158. package/src/whoami.ts +62 -0
@@ -0,0 +1,205 @@
1
+ import type { SharedSlice, Timestamp } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { parseArgs } from "node:util";
4
+
5
+ import { buildTypes } from "./codegen-types";
6
+ import { findGroupInVariation, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
7
+ import { getDocsPath, getWriteComponentsAnchor, requireFramework } from "./framework";
8
+ import { humanReadable } from "./lib/string";
9
+
10
+ const HELP = `
11
+ Add a timestamp (date and time) field to an existing slice.
12
+
13
+ USAGE
14
+ prismic slice add-field timestamp <slice-id> <field-id> [flags]
15
+
16
+ ARGUMENTS
17
+ slice-id Slice identifier (required)
18
+ field-id Field identifier (required)
19
+
20
+ FLAGS
21
+ -v, --variation string Target variation (default: first variation)
22
+ -l, --label string Display label for the field (inferred from field-id if omitted)
23
+ -p, --placeholder string Placeholder text
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 slice add-field timestamp my_slice created_at
29
+ prismic slice add-field timestamp event start_time --label "Event Start"
30
+ prismic slice add-field timestamp schedule meeting_time --variation "detailed"
31
+ `.trim();
32
+
33
+
34
+
35
+ export async function sliceAddFieldTimestamp(): Promise<void> {
36
+ const {
37
+ values: { help, variation, label, placeholder, types },
38
+ positionals: [sliceId, fieldId],
39
+ } = parseArgs({
40
+ args: process.argv.slice(5), // skip: node, script, "slice", "add-field", "timestamp"
41
+ options: {
42
+ variation: { type: "string", short: "v" },
43
+ label: { type: "string", short: "l" },
44
+ placeholder: { type: "string", short: "p" },
45
+ types: { type: "string" },
46
+ help: { type: "boolean", short: "h" },
47
+ },
48
+ allowPositionals: true,
49
+ });
50
+
51
+ if (help) {
52
+ console.info(HELP);
53
+ return;
54
+ }
55
+
56
+ if (!sliceId) {
57
+ console.error("Missing required argument: slice-id\n");
58
+ console.error("Usage: prismic slice add-field timestamp <slice-id> <field-id>");
59
+ process.exitCode = 1;
60
+ return;
61
+ }
62
+
63
+ if (!fieldId) {
64
+ console.error("Missing required argument: field-id\n");
65
+ console.error("Usage: prismic slice add-field timestamp <slice-id> <field-id>");
66
+ process.exitCode = 1;
67
+ return;
68
+ }
69
+
70
+ // Parse and validate field path
71
+ const fieldPath = parseFieldPath(fieldId);
72
+ const pathValidation = validateNestedFieldPath(fieldPath);
73
+ if (!pathValidation.ok) {
74
+ console.error(pathValidation.error);
75
+ process.exitCode = 1;
76
+ return;
77
+ }
78
+
79
+ // Find the slice model
80
+ const framework = await requireFramework();
81
+ if (!framework) return;
82
+
83
+ let model: SharedSlice;
84
+ try {
85
+ model = await framework.readSlice(sliceId);
86
+ } catch {
87
+ console.error(`Slice not found: ${sliceId}\n\nCreate it first with: prismic slice create ${sliceId}`);
88
+ process.exitCode = 1;
89
+ return;
90
+ }
91
+
92
+ // Check for variations
93
+ if (model.variations.length === 0) {
94
+ console.error(`Slice "${sliceId}" has no variations.\n`);
95
+ console.error("Add a variation first before adding fields.");
96
+ process.exitCode = 1;
97
+ return;
98
+ }
99
+
100
+ // Find target variation
101
+ const targetVariation = variation
102
+ ? model.variations.find((v) => v.id === variation)
103
+ : model.variations[0];
104
+
105
+ if (!targetVariation) {
106
+ console.error(`Variation "${variation}" not found in slice "${sliceId}"\n`);
107
+ console.error(`Available variations: ${model.variations.map((v) => v.id).join(", ")}`);
108
+ process.exitCode = 1;
109
+ return;
110
+ }
111
+
112
+ // Initialize primary if it doesn't exist
113
+ if (!targetVariation.primary) {
114
+ targetVariation.primary = {};
115
+ }
116
+
117
+ // Build field definition
118
+ const fieldDefinition: Timestamp = {
119
+ type: "Timestamp",
120
+ config: {
121
+ label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
122
+ ...(placeholder && { placeholder }),
123
+ },
124
+ };
125
+
126
+ // Add field to variation (with nested field support)
127
+ if (fieldPath.type === "nested") {
128
+ const groupResult = findGroupInVariation(targetVariation.primary, fieldPath.groupId, targetVariation.id);
129
+ if (!groupResult.ok) {
130
+ console.error(groupResult.error);
131
+ process.exitCode = 1;
132
+ return;
133
+ }
134
+ // Check if nested field already exists
135
+ if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
136
+ console.error(
137
+ `Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`,
138
+ );
139
+ process.exitCode = 1;
140
+ return;
141
+ }
142
+ groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
143
+ } else {
144
+ // Check if field already exists in any variation (at top level or in groups)
145
+ for (const v of model.variations) {
146
+ if (v.primary?.[fieldId]) {
147
+ console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
148
+ process.exitCode = 1;
149
+ return;
150
+ }
151
+ // Also check inside groups
152
+ for (const [groupFieldId, groupField] of Object.entries(v.primary ?? {})) {
153
+ if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
154
+ console.error(
155
+ `Field "${fieldId}" already exists in group "${groupFieldId}" in variation "${v.id}"`,
156
+ );
157
+ process.exitCode = 1;
158
+ return;
159
+ }
160
+ }
161
+ }
162
+ targetVariation.primary[fieldId] = fieldDefinition;
163
+ }
164
+
165
+ // Write updated model
166
+ try {
167
+ await framework.updateSlice(model);
168
+ } catch (error) {
169
+ if (error instanceof Error) {
170
+ console.error(`Failed to update slice: ${error.message}`);
171
+ } else {
172
+ console.error("Failed to update slice");
173
+ }
174
+ process.exitCode = 1;
175
+ return;
176
+ }
177
+
178
+ if (fieldPath.type === "nested") {
179
+ console.info(
180
+ `Added field "${fieldPath.nestedFieldId}" (Timestamp) to group "${fieldPath.groupId}" in ${sliceId}`,
181
+ );
182
+ } else {
183
+ console.info(
184
+ `Added field "${fieldId}" (Timestamp) to "${targetVariation.id}" variation in ${sliceId}`,
185
+ );
186
+ }
187
+
188
+ try {
189
+ await buildTypes({ output: types });
190
+ console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
191
+ } catch (error) {
192
+ console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
193
+ }
194
+
195
+ console.info();
196
+ console.info("Next: Add more fields with `prismic slice add-field`");
197
+
198
+ if (framework) {
199
+ const docsPath = getDocsPath(framework.id);
200
+ const anchor = getWriteComponentsAnchor(framework.id);
201
+ console.info(
202
+ ` Run \`prismic docs fetch ${docsPath}${anchor}\` to learn how to implement the slice's component`,
203
+ );
204
+ }
205
+ }
@@ -0,0 +1,111 @@
1
+ import { parseArgs } from "node:util";
2
+
3
+ import { sliceAddFieldBoolean } from "./slice-add-field-boolean";
4
+ import { sliceAddFieldColor } from "./slice-add-field-color";
5
+ import { sliceAddFieldDate } from "./slice-add-field-date";
6
+ import { sliceAddFieldEmbed } from "./slice-add-field-embed";
7
+ import { sliceAddFieldGeoPoint } from "./slice-add-field-geo-point";
8
+ import { sliceAddFieldGroup } from "./slice-add-field-group";
9
+ import { sliceAddFieldImage } from "./slice-add-field-image";
10
+ import { sliceAddFieldKeyText } from "./slice-add-field-key-text";
11
+ import { sliceAddFieldLink } from "./slice-add-field-link";
12
+ import { sliceAddFieldNumber } from "./slice-add-field-number";
13
+ import { sliceAddFieldRichText } from "./slice-add-field-rich-text";
14
+ import { sliceAddFieldSelect } from "./slice-add-field-select";
15
+ import { sliceAddFieldTimestamp } from "./slice-add-field-timestamp";
16
+
17
+ const HELP = `
18
+ Add a field to an existing slice.
19
+
20
+ USAGE
21
+ prismic slice add-field <field-type> <slice-id> <field-id> [flags]
22
+
23
+ FIELD TYPES
24
+ boolean Boolean toggle
25
+ color Color picker
26
+ date Date picker
27
+ embed Embed (oEmbed)
28
+ geo-point Geographic coordinates
29
+ group Repeatable group of fields
30
+ image Image
31
+ key-text Single-line text
32
+ link Any link type
33
+ number Number
34
+ rich-text Rich text editor
35
+ select Dropdown select
36
+ timestamp Date and time
37
+
38
+ FLAGS
39
+ -h, --help Show help for command
40
+
41
+ LEARN MORE
42
+ Use \`prismic slice add-field <field-type> --help\` for more information.
43
+
44
+ EXAMPLES
45
+ prismic slice add-field key-text my_slice title --label "Title"
46
+ prismic slice add-field link my_slice cta --allow-text
47
+ prismic slice add-field rich-text my_slice body --multi "paragraph,heading2,strong,em"
48
+ prismic slice add-field select my_slice layout --option "full" --option "sidebar"
49
+ `.trim();
50
+
51
+ export async function sliceAddField(): Promise<void> {
52
+ const {
53
+ positionals: [fieldType],
54
+ } = parseArgs({
55
+ args: process.argv.slice(4), // skip: node, script, "slice", "add-field"
56
+ options: {
57
+ help: { type: "boolean", short: "h" },
58
+ },
59
+ allowPositionals: true,
60
+ strict: false,
61
+ });
62
+
63
+ switch (fieldType) {
64
+ case "boolean":
65
+ await sliceAddFieldBoolean();
66
+ break;
67
+ case "color":
68
+ await sliceAddFieldColor();
69
+ break;
70
+ case "date":
71
+ await sliceAddFieldDate();
72
+ break;
73
+ case "embed":
74
+ await sliceAddFieldEmbed();
75
+ break;
76
+ case "geo-point":
77
+ await sliceAddFieldGeoPoint();
78
+ break;
79
+ case "group":
80
+ await sliceAddFieldGroup();
81
+ break;
82
+ case "image":
83
+ await sliceAddFieldImage();
84
+ break;
85
+ case "key-text":
86
+ await sliceAddFieldKeyText();
87
+ break;
88
+ case "link":
89
+ await sliceAddFieldLink();
90
+ break;
91
+ case "number":
92
+ await sliceAddFieldNumber();
93
+ break;
94
+ case "rich-text":
95
+ await sliceAddFieldRichText();
96
+ break;
97
+ case "select":
98
+ await sliceAddFieldSelect();
99
+ break;
100
+ case "timestamp":
101
+ await sliceAddFieldTimestamp();
102
+ break;
103
+ default: {
104
+ if (fieldType) {
105
+ console.error(`Unknown field type: ${fieldType}\n`);
106
+ process.exitCode = 1;
107
+ }
108
+ console.info(HELP);
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,142 @@
1
+ import type { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { parseArgs } from "node:util";
4
+
5
+ import { pascalCase } from "change-case";
6
+
7
+ import { buildTypes } from "./codegen-types";
8
+ import { requireFramework } from "./framework";
9
+
10
+ const HELP = `
11
+ Add a new variation to a slice.
12
+
13
+ USAGE
14
+ prismic slice add-variation <slice-id> <variation-id> [flags]
15
+
16
+ ARGUMENTS
17
+ slice-id Slice identifier (required)
18
+ variation-id New variation identifier (required)
19
+
20
+ FLAGS
21
+ --name string Display name for the variation
22
+ --copy-from string Copy fields from an existing variation
23
+ --types string Output file for generated types (default: "prismicio-types.d.ts")
24
+ -h, --help Show help for command
25
+
26
+ EXAMPLES
27
+ prismic slice add-variation MySlice withImage
28
+ prismic slice add-variation MySlice withImage --name "With Image"
29
+ prismic slice add-variation MySlice withImage --copy-from default
30
+ `.trim();
31
+
32
+ export async function sliceAddVariation(): Promise<void> {
33
+ const {
34
+ values: { help, name, "copy-from": copyFrom, types },
35
+ positionals: [sliceId, variationId],
36
+ } = parseArgs({
37
+ args: process.argv.slice(4), // skip: node, script, "slice", "add-variation"
38
+ options: {
39
+ name: { type: "string" },
40
+ "copy-from": { type: "string" },
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 (!sliceId) {
53
+ console.error("Missing required argument: slice-id\n");
54
+ console.error("Usage: prismic slice add-variation <slice-id> <variation-id>");
55
+ process.exitCode = 1;
56
+ return;
57
+ }
58
+
59
+ if (!variationId) {
60
+ console.error("Missing required argument: variation-id\n");
61
+ console.error("Usage: prismic slice add-variation <slice-id> <variation-id>");
62
+ process.exitCode = 1;
63
+ return;
64
+ }
65
+
66
+ const framework = await requireFramework();
67
+ if (!framework) return;
68
+
69
+ let model: SharedSlice;
70
+ try {
71
+ model = await framework.readSlice(sliceId);
72
+ } catch {
73
+ console.error(`Slice not found: ${sliceId}\n\nCreate it first with: prismic slice create ${sliceId}`);
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+
78
+ // Check if variation already exists
79
+ if (model.variations.some((v) => v.id === variationId)) {
80
+ console.error(`Variation "${variationId}" already exists in slice "${sliceId}"`);
81
+ process.exitCode = 1;
82
+ return;
83
+ }
84
+
85
+ // Build new variation
86
+ let newVariation: SharedSlice["variations"][number];
87
+
88
+ if (copyFrom) {
89
+ const sourceVariation = model.variations.find((v) => v.id === copyFrom);
90
+ if (!sourceVariation) {
91
+ console.error(`Source variation not found: ${copyFrom}`);
92
+ console.error(`Available variations: ${model.variations.map((v) => v.id).join(", ")}`);
93
+ process.exitCode = 1;
94
+ return;
95
+ }
96
+
97
+ newVariation = {
98
+ ...structuredClone(sourceVariation),
99
+ id: variationId,
100
+ name: name ?? pascalCase(variationId),
101
+ };
102
+ } else {
103
+ newVariation = {
104
+ id: variationId,
105
+ name: name ?? pascalCase(variationId),
106
+ description: variationId,
107
+ imageUrl: "",
108
+ docURL: "",
109
+ version: "initial",
110
+ primary: {},
111
+ items: {},
112
+ };
113
+ }
114
+
115
+ // Add variation to model
116
+ const updatedModel = {
117
+ ...model,
118
+ variations: [...model.variations, newVariation],
119
+ };
120
+
121
+ // Write updated model
122
+ try {
123
+ await framework.updateSlice(updatedModel);
124
+ } catch (error) {
125
+ if (error instanceof Error) {
126
+ console.error(`Failed to update slice: ${error.message}`);
127
+ } else {
128
+ console.error("Failed to update slice");
129
+ }
130
+ process.exitCode = 1;
131
+ return;
132
+ }
133
+
134
+ console.info(`Added variation "${variationId}" to slice "${sliceId}"`);
135
+
136
+ try {
137
+ await buildTypes({ output: types });
138
+ console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
139
+ } catch (error) {
140
+ console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
141
+ }
142
+ }
@@ -0,0 +1,164 @@
1
+ import type { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { readFile } from "node:fs/promises";
4
+ import { parseArgs } from "node:util";
5
+
6
+ import { buildTypes } from "./codegen-types";
7
+ import { isAuthenticated } from "./lib/auth";
8
+ import { safeGetRepositoryFromConfig } from "./lib/config";
9
+ import { requireFramework } from "./framework";
10
+ import { uploadScreenshot } from "./slice-set-screenshot";
11
+
12
+ const HELP = `
13
+ Create a new slice in a Prismic project.
14
+
15
+ USAGE
16
+ prismic slice create <id> [flags]
17
+
18
+ ARGUMENTS
19
+ id Slice identifier (required)
20
+
21
+ FLAGS
22
+ -n, --name string Display name for the slice
23
+ --screenshot string Path to screenshot image for default variation
24
+ -r, --repo string Repository name (required for screenshot)
25
+ --types string Output file for generated types (default: "prismicio-types.d.ts")
26
+ -h, --help Show help for command
27
+
28
+ LEARN MORE
29
+ Use \`prismic slice <command> --help\` for more information about a command.
30
+ `.trim();
31
+
32
+ export async function sliceCreate(): Promise<void> {
33
+ const {
34
+ values: { help, name, types, screenshot, repo: repoFlag },
35
+ positionals: [id],
36
+ } = parseArgs({
37
+ args: process.argv.slice(4), // skip: node, script, "slice", "create"
38
+ options: {
39
+ name: { type: "string", short: "n" },
40
+ screenshot: { type: "string" },
41
+ repo: { type: "string", short: "r" },
42
+ types: { type: "string" },
43
+ help: { type: "boolean", short: "h" },
44
+ },
45
+ allowPositionals: true,
46
+ });
47
+
48
+ if (help) {
49
+ console.info(HELP);
50
+ return;
51
+ }
52
+
53
+ if (!id) {
54
+ console.error("Missing required argument: id");
55
+ process.exitCode = 1;
56
+ return;
57
+ }
58
+
59
+ const framework = await requireFramework();
60
+ if (!framework) return;
61
+
62
+ // Handle screenshot upload if provided
63
+ let screenshotUrl: string | undefined;
64
+ if (screenshot) {
65
+ // Check authentication
66
+ const authenticated = await isAuthenticated();
67
+ if (!authenticated) {
68
+ console.error("You must be logged in to upload a screenshot.");
69
+ console.error("Run `prismic login` to authenticate.");
70
+ process.exitCode = 1;
71
+ return;
72
+ }
73
+
74
+ // Resolve repository
75
+ const repo = repoFlag ?? (await safeGetRepositoryFromConfig());
76
+ if (!repo) {
77
+ console.error("Could not determine repository for screenshot upload.");
78
+ console.error("Use --repo flag or run from a directory with prismic.config.json");
79
+ process.exitCode = 1;
80
+ return;
81
+ }
82
+
83
+ // Read and upload the screenshot
84
+ let imageData: Buffer;
85
+ try {
86
+ imageData = await readFile(screenshot);
87
+ } catch (error) {
88
+ if (error instanceof Error) {
89
+ console.error(`Failed to read screenshot file: ${error.message}`);
90
+ } else {
91
+ console.error("Failed to read screenshot file");
92
+ }
93
+ process.exitCode = 1;
94
+ return;
95
+ }
96
+
97
+ try {
98
+ screenshotUrl = await uploadScreenshot({
99
+ data: imageData,
100
+ repo,
101
+ sliceId: id,
102
+ variationId: "default",
103
+ filename: screenshot,
104
+ });
105
+ } catch (error) {
106
+ if (error instanceof Error) {
107
+ console.error(`Failed to upload screenshot: ${error.message}`);
108
+ } else {
109
+ console.error("Failed to upload screenshot");
110
+ }
111
+ process.exitCode = 1;
112
+ return;
113
+ }
114
+ }
115
+
116
+ const { pascalCase } = await import("change-case");
117
+
118
+ const model: SharedSlice = {
119
+ id,
120
+ type: "SharedSlice",
121
+ name: name ?? pascalCase(id),
122
+ description: "",
123
+ variations: [
124
+ {
125
+ id: "default",
126
+ name: "Default",
127
+ description: "Default",
128
+ imageUrl: screenshotUrl ?? "",
129
+ docURL: "",
130
+ version: "initial",
131
+ primary: {},
132
+ items: {},
133
+ },
134
+ ],
135
+ };
136
+
137
+ const library = await framework.getDefaultSliceLibrary();
138
+
139
+ try {
140
+ const { modelPath } = await framework.createSlice(
141
+ model,
142
+ library,
143
+ );
144
+ console.info(`Created slice at ${modelPath.href}`);
145
+ } catch (error) {
146
+ if (error instanceof Error) {
147
+ console.error(`Failed to create slice: ${error.message}`);
148
+ } else {
149
+ console.error(`Failed to create slice`);
150
+ }
151
+ process.exitCode = 1;
152
+ return;
153
+ }
154
+
155
+ try {
156
+ await buildTypes({ output: types, framework });
157
+ console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
158
+ } catch (error) {
159
+ console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
160
+ }
161
+
162
+ console.info();
163
+ console.info("Next: Add fields with `prismic slice add-field`");
164
+ }
@@ -0,0 +1,71 @@
1
+ import { parseArgs } from "node:util";
2
+
3
+ import { requireFramework } from "./framework";
4
+
5
+ const HELP = `
6
+ List all variations for a slice.
7
+
8
+ USAGE
9
+ prismic slice list-variations <slice-id> [flags]
10
+
11
+ ARGUMENTS
12
+ slice-id Slice identifier (required)
13
+
14
+ FLAGS
15
+ --json Output as JSON
16
+ -h, --help Show help for command
17
+
18
+ EXAMPLES
19
+ prismic slice list-variations MySlice
20
+ prismic slice list-variations MySlice --json
21
+ `.trim();
22
+
23
+ export async function sliceListVariations(): Promise<void> {
24
+ const {
25
+ values: { help, json },
26
+ positionals: [sliceId],
27
+ } = parseArgs({
28
+ args: process.argv.slice(4), // skip: node, script, "slice", "list-variations"
29
+ options: {
30
+ json: { type: "boolean" },
31
+ help: { type: "boolean", short: "h" },
32
+ },
33
+ allowPositionals: true,
34
+ });
35
+
36
+ if (help) {
37
+ console.info(HELP);
38
+ return;
39
+ }
40
+
41
+ if (!sliceId) {
42
+ console.error("Missing required argument: slice-id\n");
43
+ console.error("Usage: prismic slice list-variations <slice-id>");
44
+ process.exitCode = 1;
45
+ return;
46
+ }
47
+
48
+ const framework = await requireFramework();
49
+ if (!framework) return;
50
+
51
+ let model;
52
+ try {
53
+ model = await framework.readSlice(sliceId);
54
+ } catch {
55
+ console.error(`Slice not found: ${sliceId}\n\nCreate it first with: prismic slice create ${sliceId}`);
56
+ process.exitCode = 1;
57
+ return;
58
+ }
59
+
60
+ const variations = model.variations.map((v) => ({ id: v.id, name: v.name }));
61
+
62
+ if (json) {
63
+ console.info(JSON.stringify(variations, null, 2));
64
+ return;
65
+ }
66
+
67
+ console.info("ID\tNAME");
68
+ for (const variation of variations) {
69
+ console.info(`${variation.id}\t${variation.name}`);
70
+ }
71
+ }