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,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
+ }