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,168 @@
1
+ import type { CustomType, Timestamp } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { parseArgs } from "node:util";
4
+
5
+ import { buildTypes } from "./codegen-types";
6
+ import { findGroupInTab, isGroupField, parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
7
+ import { getDocsPath, requireFramework } from "./framework";
8
+ import { humanReadable } from "./lib/string";
9
+
10
+ const HELP = `
11
+ Add a timestamp (date and time) field to an existing page type.
12
+
13
+ USAGE
14
+ prismic page-type add-field timestamp <type-id> <field-id> [flags]
15
+
16
+ ARGUMENTS
17
+ type-id Page type identifier (required)
18
+ field-id Field identifier (required)
19
+
20
+ FLAGS
21
+ -t, --tab string Target tab (default: first existing tab, or "Main")
22
+ -l, --label string Display label for the field (inferred from field-id if omitted)
23
+ -p, --placeholder string Placeholder text
24
+ --default string Default timestamp value (ISO 8601 format)
25
+ --types string Output file for generated types (default: "prismicio-types.d.ts")
26
+ -h, --help Show help for command
27
+
28
+ EXAMPLES
29
+ prismic page-type add-field timestamp homepage event_time
30
+ prismic page-type add-field timestamp event start --tab "Schedule"
31
+ prismic page-type add-field timestamp article published_at --label "Published At"
32
+ `.trim();
33
+
34
+
35
+ export async function pageTypeAddFieldTimestamp(): Promise<void> {
36
+ const {
37
+ values: { help, tab, label, placeholder, default: defaultValue, types },
38
+ positionals: [typeId, fieldId],
39
+ } = parseArgs({
40
+ args: process.argv.slice(5), // skip: node, script, "page-type", "add-field", "timestamp"
41
+ options: {
42
+ tab: { type: "string", short: "t" },
43
+ label: { type: "string", short: "l" },
44
+ placeholder: { type: "string", short: "p" },
45
+ default: { type: "string" },
46
+ types: { type: "string" },
47
+ help: { type: "boolean", short: "h" },
48
+ },
49
+ allowPositionals: true,
50
+ });
51
+
52
+ if (help) {
53
+ console.info(HELP);
54
+ return;
55
+ }
56
+
57
+ if (!typeId) {
58
+ console.error("Missing required argument: type-id\n");
59
+ console.error("Usage: prismic page-type add-field timestamp <type-id> <field-id>");
60
+ process.exitCode = 1;
61
+ return;
62
+ }
63
+
64
+ if (!fieldId) {
65
+ console.error("Missing required argument: field-id\n");
66
+ console.error("Usage: prismic page-type add-field timestamp <type-id> <field-id>");
67
+ process.exitCode = 1;
68
+ return;
69
+ }
70
+
71
+ // Parse and validate field path
72
+ const fieldPath = parseFieldPath(fieldId);
73
+ const pathValidation = validateNestedFieldPath(fieldPath);
74
+ if (!pathValidation.ok) {
75
+ console.error(pathValidation.error);
76
+ process.exitCode = 1;
77
+ return;
78
+ }
79
+
80
+ const framework = await requireFramework();
81
+ if (!framework) return;
82
+
83
+ let model: CustomType;
84
+ try {
85
+ model = await framework.readCustomType(typeId);
86
+ } catch {
87
+ console.error(`Page type not found: ${typeId}\n\nCreate it first with: prismic page-type create ${typeId}`);
88
+ process.exitCode = 1;
89
+ return;
90
+ }
91
+
92
+ // Determine target tab
93
+ const existingTabs = Object.keys(model.json);
94
+ const targetTab = tab ?? existingTabs[0] ?? "Main";
95
+
96
+ // Initialize tab if it doesn't exist
97
+ if (!model.json[targetTab]) {
98
+ model.json[targetTab] = {};
99
+ }
100
+
101
+ // Build field definition
102
+ const fieldDefinition: Timestamp = {
103
+ type: "Timestamp",
104
+ config: {
105
+ label: label ?? humanReadable(fieldPath.type === "nested" ? fieldPath.nestedFieldId : fieldId),
106
+ ...(placeholder && { placeholder }),
107
+ ...(defaultValue && { default: defaultValue }),
108
+ },
109
+ };
110
+
111
+ // Add field to model
112
+ if (fieldPath.type === "nested") {
113
+ const groupResult = findGroupInTab(model.json[targetTab], fieldPath.groupId, targetTab);
114
+ if (!groupResult.ok) {
115
+ console.error(groupResult.error);
116
+ process.exitCode = 1;
117
+ return;
118
+ }
119
+ if (groupResult.group.config.fields[fieldPath.nestedFieldId]) {
120
+ console.error(`Field "${fieldPath.nestedFieldId}" already exists in group "${fieldPath.groupId}"`);
121
+ process.exitCode = 1;
122
+ return;
123
+ }
124
+ groupResult.group.config.fields[fieldPath.nestedFieldId] = fieldDefinition;
125
+ } else {
126
+ for (const [tabName, tabFields] of Object.entries(model.json)) {
127
+ if (tabFields[fieldId]) {
128
+ console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
129
+ process.exitCode = 1;
130
+ return;
131
+ }
132
+ for (const [groupFieldId, groupField] of Object.entries(tabFields)) {
133
+ if (isGroupField(groupField) && groupField.config.fields[fieldId]) {
134
+ console.error(`Field "${fieldId}" already exists in group "${groupFieldId}" in tab "${tabName}"`);
135
+ process.exitCode = 1;
136
+ return;
137
+ }
138
+ }
139
+ }
140
+ model.json[targetTab][fieldId] = fieldDefinition;
141
+ }
142
+
143
+ // Write updated model
144
+ await framework.updateCustomType(model);
145
+
146
+ if (fieldPath.type === "nested") {
147
+ console.info(`Added field "${fieldPath.nestedFieldId}" (Timestamp) to group "${fieldPath.groupId}" in ${typeId}`);
148
+ } else {
149
+ console.info(`Added field "${fieldId}" (Timestamp) to "${targetTab}" tab in ${typeId}`);
150
+ }
151
+
152
+ try {
153
+ await buildTypes({ output: types });
154
+ console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
155
+ } catch (error) {
156
+ console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
157
+ }
158
+
159
+ console.info();
160
+ console.info("Next: Add more fields with `prismic page-type add-field`");
161
+
162
+ if (framework) {
163
+ const docsPath = getDocsPath(framework.id);
164
+ console.info(
165
+ ` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
166
+ );
167
+ }
168
+ }
@@ -0,0 +1,148 @@
1
+ import type { CustomType, UID } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { parseArgs } from "node:util";
4
+
5
+ import { buildTypes } from "./codegen-types";
6
+ import { parseFieldPath, validateNestedFieldPath } from "./lib/field-path";
7
+ import { getDocsPath, requireFramework } from "./framework";
8
+ import { humanReadable } from "./lib/string";
9
+
10
+ const HELP = `
11
+ Add a UID (unique identifier) field to an existing page type.
12
+
13
+ USAGE
14
+ prismic page-type add-field uid <type-id> <field-id> [flags]
15
+
16
+ ARGUMENTS
17
+ type-id Page type identifier (required)
18
+ field-id Field identifier (required)
19
+
20
+ FLAGS
21
+ -t, --tab string Target tab (default: first existing tab, or "Main")
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 page-type add-field uid page uid
29
+ prismic page-type add-field uid article slug --label "URL Slug"
30
+ prismic page-type add-field uid product sku --placeholder "Enter unique SKU"
31
+ `.trim();
32
+
33
+
34
+ export async function pageTypeAddFieldUid(): Promise<void> {
35
+ const {
36
+ values: { help, tab, label, placeholder, types },
37
+ positionals: [typeId, fieldId],
38
+ } = parseArgs({
39
+ args: process.argv.slice(5), // skip: node, script, "page-type", "add-field", "uid"
40
+ options: {
41
+ tab: { type: "string", short: "t" },
42
+ label: { type: "string", short: "l" },
43
+ placeholder: { type: "string", short: "p" },
44
+ types: { type: "string" },
45
+ help: { type: "boolean", short: "h" },
46
+ },
47
+ allowPositionals: true,
48
+ });
49
+
50
+ if (help) {
51
+ console.info(HELP);
52
+ return;
53
+ }
54
+
55
+ if (!typeId) {
56
+ console.error("Missing required argument: type-id\n");
57
+ console.error("Usage: prismic page-type add-field uid <type-id> <field-id>");
58
+ process.exitCode = 1;
59
+ return;
60
+ }
61
+
62
+ if (!fieldId) {
63
+ console.error("Missing required argument: field-id\n");
64
+ console.error("Usage: prismic page-type add-field uid <type-id> <field-id>");
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+
69
+ // Parse and validate field path
70
+ const fieldPath = parseFieldPath(fieldId);
71
+ const pathValidation = validateNestedFieldPath(fieldPath);
72
+ if (!pathValidation.ok) {
73
+ console.error(pathValidation.error);
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+
78
+ // UID fields cannot be nested in groups
79
+ if (fieldPath.type === "nested") {
80
+ console.error("UID fields cannot be nested inside groups");
81
+ process.exitCode = 1;
82
+ return;
83
+ }
84
+
85
+ const framework = await requireFramework();
86
+ if (!framework) return;
87
+
88
+ let model: CustomType;
89
+ try {
90
+ model = await framework.readCustomType(typeId);
91
+ } catch {
92
+ console.error(`Page type not found: ${typeId}\n\nCreate it first with: prismic page-type create ${typeId}`);
93
+ process.exitCode = 1;
94
+ return;
95
+ }
96
+
97
+ // Determine target tab
98
+ const existingTabs = Object.keys(model.json);
99
+ const targetTab = tab ?? existingTabs[0] ?? "Main";
100
+
101
+ // Initialize tab if it doesn't exist
102
+ if (!model.json[targetTab]) {
103
+ model.json[targetTab] = {};
104
+ }
105
+
106
+ // Check if field already exists in any tab
107
+ for (const [tabName, tabFields] of Object.entries(model.json)) {
108
+ if (tabFields[fieldId]) {
109
+ console.error(`Field "${fieldId}" already exists in tab "${tabName}"`);
110
+ process.exitCode = 1;
111
+ return;
112
+ }
113
+ }
114
+
115
+ // Build field definition
116
+ const fieldDefinition: UID = {
117
+ type: "UID",
118
+ config: {
119
+ label: label ?? humanReadable(fieldId),
120
+ ...(placeholder && { placeholder }),
121
+ },
122
+ };
123
+
124
+ // Add field to model
125
+ model.json[targetTab][fieldId] = fieldDefinition;
126
+
127
+ // Write updated model
128
+ await framework.updateCustomType(model);
129
+
130
+ console.info(`Added field "${fieldId}" (UID) to "${targetTab}" tab in ${typeId}`);
131
+
132
+ try {
133
+ await buildTypes({ output: types });
134
+ console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
135
+ } catch (error) {
136
+ console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
137
+ }
138
+
139
+ console.info();
140
+ console.info("Next: Add more fields with `prismic page-type add-field`");
141
+
142
+ if (framework) {
143
+ const docsPath = getDocsPath(framework.id);
144
+ console.info(
145
+ ` Run \`prismic docs fetch ${docsPath}#write-page-components\` to learn how to implement a page file`,
146
+ );
147
+ }
148
+ }
@@ -0,0 +1,116 @@
1
+ import { parseArgs } from "node:util";
2
+
3
+ import { pageTypeAddFieldBoolean } from "./page-type-add-field-boolean";
4
+ import { pageTypeAddFieldColor } from "./page-type-add-field-color";
5
+ import { pageTypeAddFieldDate } from "./page-type-add-field-date";
6
+ import { pageTypeAddFieldEmbed } from "./page-type-add-field-embed";
7
+ import { pageTypeAddFieldGeoPoint } from "./page-type-add-field-geo-point";
8
+ import { pageTypeAddFieldGroup } from "./page-type-add-field-group";
9
+ import { pageTypeAddFieldImage } from "./page-type-add-field-image";
10
+ import { pageTypeAddFieldKeyText } from "./page-type-add-field-key-text";
11
+ import { pageTypeAddFieldLink } from "./page-type-add-field-link";
12
+ import { pageTypeAddFieldNumber } from "./page-type-add-field-number";
13
+ import { pageTypeAddFieldRichText } from "./page-type-add-field-rich-text";
14
+ import { pageTypeAddFieldSelect } from "./page-type-add-field-select";
15
+ import { pageTypeAddFieldTimestamp } from "./page-type-add-field-timestamp";
16
+ import { pageTypeAddFieldUid } from "./page-type-add-field-uid";
17
+
18
+ const HELP = `
19
+ Add a field to an existing page type.
20
+
21
+ USAGE
22
+ prismic page-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 page-type add-field <field-type> --help\` for more information.
45
+
46
+ EXAMPLES
47
+ prismic page-type add-field key-text homepage meta_title --tab "SEO"
48
+ prismic page-type add-field link homepage button --allow-text
49
+ prismic page-type add-field rich-text homepage body --multi "paragraph,heading2,strong,em"
50
+ prismic page-type add-field select homepage layout --option "full" --option "sidebar"
51
+ `.trim();
52
+
53
+ export async function pageTypeAddField(): Promise<void> {
54
+ const {
55
+ positionals: [fieldType],
56
+ } = parseArgs({
57
+ args: process.argv.slice(4), // skip: node, script, "page-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 pageTypeAddFieldBoolean();
68
+ break;
69
+ case "color":
70
+ await pageTypeAddFieldColor();
71
+ break;
72
+ case "date":
73
+ await pageTypeAddFieldDate();
74
+ break;
75
+ case "embed":
76
+ await pageTypeAddFieldEmbed();
77
+ break;
78
+ case "geo-point":
79
+ await pageTypeAddFieldGeoPoint();
80
+ break;
81
+ case "group":
82
+ await pageTypeAddFieldGroup();
83
+ break;
84
+ case "image":
85
+ await pageTypeAddFieldImage();
86
+ break;
87
+ case "key-text":
88
+ await pageTypeAddFieldKeyText();
89
+ break;
90
+ case "link":
91
+ await pageTypeAddFieldLink();
92
+ break;
93
+ case "number":
94
+ await pageTypeAddFieldNumber();
95
+ break;
96
+ case "rich-text":
97
+ await pageTypeAddFieldRichText();
98
+ break;
99
+ case "select":
100
+ await pageTypeAddFieldSelect();
101
+ break;
102
+ case "timestamp":
103
+ await pageTypeAddFieldTimestamp();
104
+ break;
105
+ case "uid":
106
+ await pageTypeAddFieldUid();
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 page type's slice zone.
14
+
15
+ USAGE
16
+ prismic page-type connect-slice <type-id> <slice-id> [flags]
17
+
18
+ ARGUMENTS
19
+ type-id Page 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 page-type connect-slice homepage CallToAction
29
+ prismic page-type connect-slice homepage CallToAction --slice-zone slices
30
+ prismic page-type connect-slice article HeroSection -z body
31
+ `.trim();
32
+
33
+ export async function pageTypeConnectSlice(): 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, "page-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 page-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 page-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}\n\nCreate it first with: prismic slice create ${sliceId}`);
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+
78
+ // Read the page type model
79
+ let model: CustomType;
80
+ try {
81
+ model = await framework.readCustomType(typeId);
82
+ } catch {
83
+ console.error(`Page type not found: ${typeId}\n\nCreate it first with: prismic page-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 page 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 page type: ${error.message}`);
163
+ } else {
164
+ console.error("Failed to update page 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
+ }