@angeloashmore/prismic-cli-poc 0.0.0-canary.2ff9563

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 (119) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +98 -0
  3. package/dist/index.mjs +1996 -0
  4. package/package.json +52 -0
  5. package/src/custom-type-add-field-boolean.ts +171 -0
  6. package/src/custom-type-add-field-color.ts +158 -0
  7. package/src/custom-type-add-field-date.ts +161 -0
  8. package/src/custom-type-add-field-embed.ts +158 -0
  9. package/src/custom-type-add-field-geo-point.ts +155 -0
  10. package/src/custom-type-add-field-image.ts +158 -0
  11. package/src/custom-type-add-field-key-text.ts +158 -0
  12. package/src/custom-type-add-field-link.ts +180 -0
  13. package/src/custom-type-add-field-number.ts +190 -0
  14. package/src/custom-type-add-field-rich-text.ts +181 -0
  15. package/src/custom-type-add-field-select.ts +164 -0
  16. package/src/custom-type-add-field-timestamp.ts +161 -0
  17. package/src/custom-type-add-field-uid.ts +158 -0
  18. package/src/custom-type-add-field.ts +111 -0
  19. package/src/custom-type-connect-slice.ts +221 -0
  20. package/src/custom-type-create.ts +92 -0
  21. package/src/custom-type-disconnect-slice.ts +179 -0
  22. package/src/custom-type-list.ts +110 -0
  23. package/src/custom-type-remove-field.ts +161 -0
  24. package/src/custom-type-remove.ts +126 -0
  25. package/src/custom-type-set-name.ts +128 -0
  26. package/src/custom-type-view.ts +118 -0
  27. package/src/custom-type.ts +85 -0
  28. package/src/index.ts +100 -0
  29. package/src/init.ts +62 -0
  30. package/src/lib/auth.ts +60 -0
  31. package/src/lib/config.ts +111 -0
  32. package/src/lib/file.ts +49 -0
  33. package/src/lib/json.ts +3 -0
  34. package/src/lib/request.ts +116 -0
  35. package/src/lib/slice.ts +112 -0
  36. package/src/lib/url.ts +25 -0
  37. package/src/locale-add.ts +116 -0
  38. package/src/locale-list.ts +107 -0
  39. package/src/locale-remove.ts +88 -0
  40. package/src/locale-set-default.ts +131 -0
  41. package/src/locale.ts +60 -0
  42. package/src/login.ts +143 -0
  43. package/src/logout.ts +36 -0
  44. package/src/page-type-add-field-boolean.ts +171 -0
  45. package/src/page-type-add-field-color.ts +158 -0
  46. package/src/page-type-add-field-date.ts +161 -0
  47. package/src/page-type-add-field-embed.ts +158 -0
  48. package/src/page-type-add-field-geo-point.ts +155 -0
  49. package/src/page-type-add-field-image.ts +158 -0
  50. package/src/page-type-add-field-key-text.ts +158 -0
  51. package/src/page-type-add-field-link.ts +180 -0
  52. package/src/page-type-add-field-number.ts +190 -0
  53. package/src/page-type-add-field-rich-text.ts +181 -0
  54. package/src/page-type-add-field-select.ts +164 -0
  55. package/src/page-type-add-field-timestamp.ts +161 -0
  56. package/src/page-type-add-field-uid.ts +158 -0
  57. package/src/page-type-add-field.ts +111 -0
  58. package/src/page-type-connect-slice.ts +221 -0
  59. package/src/page-type-create.ts +93 -0
  60. package/src/page-type-disconnect-slice.ts +179 -0
  61. package/src/page-type-list.ts +109 -0
  62. package/src/page-type-remove-field.ts +161 -0
  63. package/src/page-type-remove.ts +126 -0
  64. package/src/page-type-set-name.ts +128 -0
  65. package/src/page-type-set-repeatable.ts +137 -0
  66. package/src/page-type-view.ts +118 -0
  67. package/src/page-type.ts +90 -0
  68. package/src/preview-add.ts +126 -0
  69. package/src/preview-list.ts +106 -0
  70. package/src/preview-remove.ts +109 -0
  71. package/src/preview-set-name.ts +137 -0
  72. package/src/preview.ts +60 -0
  73. package/src/repo-create.ts +136 -0
  74. package/src/repo-list.ts +100 -0
  75. package/src/repo-set-name.ts +102 -0
  76. package/src/repo-view.ts +113 -0
  77. package/src/repo.ts +60 -0
  78. package/src/slice-add-field-boolean.ts +150 -0
  79. package/src/slice-add-field-color.ts +137 -0
  80. package/src/slice-add-field-date.ts +137 -0
  81. package/src/slice-add-field-embed.ts +137 -0
  82. package/src/slice-add-field-geo-point.ts +134 -0
  83. package/src/slice-add-field-image.ts +134 -0
  84. package/src/slice-add-field-key-text.ts +137 -0
  85. package/src/slice-add-field-link.ts +155 -0
  86. package/src/slice-add-field-number.ts +137 -0
  87. package/src/slice-add-field-rich-text.ts +160 -0
  88. package/src/slice-add-field-select.ts +143 -0
  89. package/src/slice-add-field-timestamp.ts +137 -0
  90. package/src/slice-add-field.ts +106 -0
  91. package/src/slice-add-variation.ts +137 -0
  92. package/src/slice-create.ts +129 -0
  93. package/src/slice-list-variations.ts +67 -0
  94. package/src/slice-list.ts +88 -0
  95. package/src/slice-remove-field.ts +117 -0
  96. package/src/slice-remove-variation.ts +108 -0
  97. package/src/slice-remove.ts +81 -0
  98. package/src/slice-rename.ts +112 -0
  99. package/src/slice-view.ts +77 -0
  100. package/src/slice.ts +90 -0
  101. package/src/sync.ts +309 -0
  102. package/src/token-create.ts +185 -0
  103. package/src/token-delete.ts +161 -0
  104. package/src/token-list.ts +212 -0
  105. package/src/token-set-name.ts +165 -0
  106. package/src/token.ts +60 -0
  107. package/src/webhook-add-header.ts +118 -0
  108. package/src/webhook-create.ts +152 -0
  109. package/src/webhook-disable.ts +109 -0
  110. package/src/webhook-enable.ts +132 -0
  111. package/src/webhook-list.ts +93 -0
  112. package/src/webhook-remove-header.ts +117 -0
  113. package/src/webhook-remove.ts +106 -0
  114. package/src/webhook-set-triggers.ts +148 -0
  115. package/src/webhook-status.ts +90 -0
  116. package/src/webhook-test.ts +106 -0
  117. package/src/webhook-view.ts +147 -0
  118. package/src/webhook.ts +95 -0
  119. package/src/whoami.ts +62 -0
@@ -0,0 +1,137 @@
1
+ import type { Number, SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { writeFile } from "node:fs/promises";
4
+ import { parseArgs } from "node:util";
5
+
6
+ import { stringify } from "./lib/json";
7
+ import { findSliceModel } from "./lib/slice";
8
+
9
+ const HELP = `
10
+ Add a number field to an existing slice.
11
+
12
+ USAGE
13
+ prismic slice add-field number <slice-id> <field-id> [flags]
14
+
15
+ ARGUMENTS
16
+ slice-id Slice identifier (required)
17
+ field-id Field identifier (required)
18
+
19
+ FLAGS
20
+ -v, --variation string Target variation (default: first variation)
21
+ -l, --label string Display label for the field
22
+ -p, --placeholder string Placeholder text
23
+ -h, --help Show help for command
24
+
25
+ EXAMPLES
26
+ prismic slice add-field number my_slice price
27
+ prismic slice add-field number product quantity --label "Quantity"
28
+ prismic slice add-field number stats count --variation "detailed"
29
+ `.trim();
30
+
31
+ export async function sliceAddFieldNumber(): Promise<void> {
32
+ const {
33
+ values: { help, variation, label, placeholder },
34
+ positionals: [sliceId, fieldId],
35
+ } = parseArgs({
36
+ args: process.argv.slice(5), // skip: node, script, "slice", "add-field", "number"
37
+ options: {
38
+ variation: { type: "string", short: "v" },
39
+ label: { type: "string", short: "l" },
40
+ placeholder: { type: "string", short: "p" },
41
+ help: { type: "boolean", short: "h" },
42
+ },
43
+ allowPositionals: true,
44
+ });
45
+
46
+ if (help) {
47
+ console.info(HELP);
48
+ return;
49
+ }
50
+
51
+ if (!sliceId) {
52
+ console.error("Missing required argument: slice-id\n");
53
+ console.error("Usage: prismic slice add-field number <slice-id> <field-id>");
54
+ process.exitCode = 1;
55
+ return;
56
+ }
57
+
58
+ if (!fieldId) {
59
+ console.error("Missing required argument: field-id\n");
60
+ console.error("Usage: prismic slice add-field number <slice-id> <field-id>");
61
+ process.exitCode = 1;
62
+ return;
63
+ }
64
+
65
+ // Find the slice model
66
+ const result = await findSliceModel(sliceId);
67
+ if (!result.ok) {
68
+ console.error(result.error);
69
+ process.exitCode = 1;
70
+ return;
71
+ }
72
+
73
+ const { model, modelPath } = result;
74
+
75
+ // Check for variations
76
+ if (model.variations.length === 0) {
77
+ console.error(`Slice "${sliceId}" has no variations.\n`);
78
+ console.error("Add a variation first before adding fields.");
79
+ process.exitCode = 1;
80
+ return;
81
+ }
82
+
83
+ // Find target variation
84
+ const targetVariation = variation
85
+ ? model.variations.find((v) => v.id === variation)
86
+ : model.variations[0];
87
+
88
+ if (!targetVariation) {
89
+ console.error(`Variation "${variation}" not found in slice "${sliceId}"\n`);
90
+ console.error(`Available variations: ${model.variations.map((v) => v.id).join(", ")}`);
91
+ process.exitCode = 1;
92
+ return;
93
+ }
94
+
95
+ // Initialize primary if it doesn't exist
96
+ if (!targetVariation.primary) {
97
+ targetVariation.primary = {};
98
+ }
99
+
100
+ // Check if field already exists in any variation
101
+ for (const v of model.variations) {
102
+ if (v.primary?.[fieldId]) {
103
+ console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
104
+ process.exitCode = 1;
105
+ return;
106
+ }
107
+ }
108
+
109
+ // Build field definition
110
+ const fieldDefinition: Number = {
111
+ type: "Number",
112
+ config: {
113
+ ...(label && { label }),
114
+ ...(placeholder && { placeholder }),
115
+ },
116
+ };
117
+
118
+ // Add field to variation
119
+ targetVariation.primary[fieldId] = fieldDefinition;
120
+
121
+ // Write updated model
122
+ try {
123
+ await writeFile(modelPath, stringify(model as SharedSlice));
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(
135
+ `Added field "${fieldId}" (Number) to "${targetVariation.id}" variation in ${sliceId}`,
136
+ );
137
+ }
@@ -0,0 +1,160 @@
1
+ import type { RichText, SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { writeFile } from "node:fs/promises";
4
+ import { parseArgs } from "node:util";
5
+
6
+ import { stringify } from "./lib/json";
7
+ import { findSliceModel } from "./lib/slice";
8
+
9
+ const HELP = `
10
+ Add a rich text field to an existing slice.
11
+
12
+ USAGE
13
+ prismic slice add-field rich-text <slice-id> <field-id> [flags]
14
+
15
+ ARGUMENTS
16
+ slice-id Slice identifier (required)
17
+ field-id Field identifier (required)
18
+
19
+ FLAGS
20
+ -v, --variation string Target variation (default: first variation)
21
+ -l, --label string Display label for the field
22
+ -p, --placeholder string Placeholder text
23
+ --single string Allowed block types for single-line (comma-separated)
24
+ --multi string Allowed block types for multi-line (comma-separated)
25
+ --allow-target-blank Allow opening links in new tab
26
+ -h, --help Show help for command
27
+
28
+ BLOCK TYPES
29
+ heading1, heading2, heading3, heading4, heading5, heading6,
30
+ paragraph, strong, em, preformatted, hyperlink, image, embed,
31
+ list-item, o-list-item, rtl
32
+
33
+ EXAMPLES
34
+ prismic slice add-field rich-text my_slice body
35
+ prismic slice add-field rich-text article content --multi "paragraph,heading2,heading3,strong,em,hyperlink"
36
+ prismic slice add-field rich-text hero tagline --single "heading1"
37
+ prismic slice add-field rich-text blog post --multi "paragraph,strong,em,hyperlink" --allow-target-blank
38
+ `.trim();
39
+
40
+ export async function sliceAddFieldRichText(): Promise<void> {
41
+ const {
42
+ values: {
43
+ help,
44
+ variation,
45
+ label,
46
+ placeholder,
47
+ single,
48
+ multi,
49
+ "allow-target-blank": allowTargetBlank,
50
+ },
51
+ positionals: [sliceId, fieldId],
52
+ } = parseArgs({
53
+ args: process.argv.slice(5), // skip: node, script, "slice", "add-field", "rich-text"
54
+ options: {
55
+ variation: { type: "string", short: "v" },
56
+ label: { type: "string", short: "l" },
57
+ placeholder: { type: "string", short: "p" },
58
+ single: { type: "string" },
59
+ multi: { type: "string" },
60
+ "allow-target-blank": { type: "boolean" },
61
+ help: { type: "boolean", short: "h" },
62
+ },
63
+ allowPositionals: true,
64
+ });
65
+
66
+ if (help) {
67
+ console.info(HELP);
68
+ return;
69
+ }
70
+
71
+ if (!sliceId) {
72
+ console.error("Missing required argument: slice-id\n");
73
+ console.error("Usage: prismic slice add-field rich-text <slice-id> <field-id>");
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+
78
+ if (!fieldId) {
79
+ console.error("Missing required argument: field-id\n");
80
+ console.error("Usage: prismic slice add-field rich-text <slice-id> <field-id>");
81
+ process.exitCode = 1;
82
+ return;
83
+ }
84
+
85
+ // Find the slice model
86
+ const result = await findSliceModel(sliceId);
87
+ if (!result.ok) {
88
+ console.error(result.error);
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+
93
+ const { model, modelPath } = result;
94
+
95
+ // Check for variations
96
+ if (model.variations.length === 0) {
97
+ console.error(`Slice "${sliceId}" has no variations.\n`);
98
+ console.error("Add a variation first before adding fields.");
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+
103
+ // Find target variation
104
+ const targetVariation = variation
105
+ ? model.variations.find((v) => v.id === variation)
106
+ : model.variations[0];
107
+
108
+ if (!targetVariation) {
109
+ console.error(`Variation "${variation}" not found in slice "${sliceId}"\n`);
110
+ console.error(`Available variations: ${model.variations.map((v) => v.id).join(", ")}`);
111
+ process.exitCode = 1;
112
+ return;
113
+ }
114
+
115
+ // Initialize primary if it doesn't exist
116
+ if (!targetVariation.primary) {
117
+ targetVariation.primary = {};
118
+ }
119
+
120
+ // Check if field already exists in any variation
121
+ for (const v of model.variations) {
122
+ if (v.primary?.[fieldId]) {
123
+ console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
124
+ process.exitCode = 1;
125
+ return;
126
+ }
127
+ }
128
+
129
+ // Build field definition
130
+ const fieldDefinition: RichText = {
131
+ type: "StructuredText",
132
+ config: {
133
+ ...(label && { label }),
134
+ ...(placeholder && { placeholder }),
135
+ ...(single && { single }),
136
+ ...(multi && { multi }),
137
+ ...(allowTargetBlank && { allowTargetBlank: true }),
138
+ },
139
+ };
140
+
141
+ // Add field to variation
142
+ targetVariation.primary[fieldId] = fieldDefinition;
143
+
144
+ // Write updated model
145
+ try {
146
+ await writeFile(modelPath, stringify(model as SharedSlice));
147
+ } catch (error) {
148
+ if (error instanceof Error) {
149
+ console.error(`Failed to update slice: ${error.message}`);
150
+ } else {
151
+ console.error("Failed to update slice");
152
+ }
153
+ process.exitCode = 1;
154
+ return;
155
+ }
156
+
157
+ console.info(
158
+ `Added field "${fieldId}" (StructuredText) to "${targetVariation.id}" variation in ${sliceId}`,
159
+ );
160
+ }
@@ -0,0 +1,143 @@
1
+ import type { Select, SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { writeFile } from "node:fs/promises";
4
+ import { parseArgs } from "node:util";
5
+
6
+ import { stringify } from "./lib/json";
7
+ import { findSliceModel } from "./lib/slice";
8
+
9
+ const HELP = `
10
+ Add a select (dropdown) field to an existing slice.
11
+
12
+ USAGE
13
+ prismic slice add-field select <slice-id> <field-id> [flags]
14
+
15
+ ARGUMENTS
16
+ slice-id Slice identifier (required)
17
+ field-id Field identifier (required)
18
+
19
+ FLAGS
20
+ -v, --variation string Target variation (default: first variation)
21
+ -l, --label string Display label for the field
22
+ -p, --placeholder string Placeholder text
23
+ --option string Add an option (can be used multiple times)
24
+ --default string Default selected value
25
+ -h, --help Show help for command
26
+
27
+ EXAMPLES
28
+ prismic slice add-field select my_slice layout --option "full" --option "sidebar"
29
+ prismic slice add-field select hero style --option "light" --option "dark" --default "light"
30
+ prismic slice add-field select product size --option "small" --option "medium" --option "large" --label "Size"
31
+ `.trim();
32
+
33
+ export async function sliceAddFieldSelect(): Promise<void> {
34
+ const {
35
+ values: { help, variation, label, placeholder, option, default: defaultValue },
36
+ positionals: [sliceId, fieldId],
37
+ } = parseArgs({
38
+ args: process.argv.slice(5), // skip: node, script, "slice", "add-field", "select"
39
+ options: {
40
+ variation: { type: "string", short: "v" },
41
+ label: { type: "string", short: "l" },
42
+ placeholder: { type: "string", short: "p" },
43
+ option: { type: "string", multiple: true },
44
+ default: { 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 (!sliceId) {
56
+ console.error("Missing required argument: slice-id\n");
57
+ console.error("Usage: prismic slice add-field select <slice-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 slice add-field select <slice-id> <field-id>");
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+
69
+ // Find the slice model
70
+ const result = await findSliceModel(sliceId);
71
+ if (!result.ok) {
72
+ console.error(result.error);
73
+ process.exitCode = 1;
74
+ return;
75
+ }
76
+
77
+ const { model, modelPath } = result;
78
+
79
+ // Check for variations
80
+ if (model.variations.length === 0) {
81
+ console.error(`Slice "${sliceId}" has no variations.\n`);
82
+ console.error("Add a variation first before adding fields.");
83
+ process.exitCode = 1;
84
+ return;
85
+ }
86
+
87
+ // Find target variation
88
+ const targetVariation = variation
89
+ ? model.variations.find((v) => v.id === variation)
90
+ : model.variations[0];
91
+
92
+ if (!targetVariation) {
93
+ console.error(`Variation "${variation}" not found in slice "${sliceId}"\n`);
94
+ console.error(`Available variations: ${model.variations.map((v) => v.id).join(", ")}`);
95
+ process.exitCode = 1;
96
+ return;
97
+ }
98
+
99
+ // Initialize primary if it doesn't exist
100
+ if (!targetVariation.primary) {
101
+ targetVariation.primary = {};
102
+ }
103
+
104
+ // Check if field already exists in any variation
105
+ for (const v of model.variations) {
106
+ if (v.primary?.[fieldId]) {
107
+ console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
108
+ process.exitCode = 1;
109
+ return;
110
+ }
111
+ }
112
+
113
+ // Build field definition
114
+ const fieldDefinition: Select = {
115
+ type: "Select",
116
+ config: {
117
+ ...(label && { label }),
118
+ ...(placeholder && { placeholder }),
119
+ ...(option && option.length > 0 && { options: option }),
120
+ ...(defaultValue && { default_value: defaultValue }),
121
+ },
122
+ };
123
+
124
+ // Add field to variation
125
+ targetVariation.primary[fieldId] = fieldDefinition;
126
+
127
+ // Write updated model
128
+ try {
129
+ await writeFile(modelPath, stringify(model as SharedSlice));
130
+ } catch (error) {
131
+ if (error instanceof Error) {
132
+ console.error(`Failed to update slice: ${error.message}`);
133
+ } else {
134
+ console.error("Failed to update slice");
135
+ }
136
+ process.exitCode = 1;
137
+ return;
138
+ }
139
+
140
+ console.info(
141
+ `Added field "${fieldId}" (Select) to "${targetVariation.id}" variation in ${sliceId}`,
142
+ );
143
+ }
@@ -0,0 +1,137 @@
1
+ import type { SharedSlice, Timestamp } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { writeFile } from "node:fs/promises";
4
+ import { parseArgs } from "node:util";
5
+
6
+ import { stringify } from "./lib/json";
7
+ import { findSliceModel } from "./lib/slice";
8
+
9
+ const HELP = `
10
+ Add a timestamp (date and time) field to an existing slice.
11
+
12
+ USAGE
13
+ prismic slice add-field timestamp <slice-id> <field-id> [flags]
14
+
15
+ ARGUMENTS
16
+ slice-id Slice identifier (required)
17
+ field-id Field identifier (required)
18
+
19
+ FLAGS
20
+ -v, --variation string Target variation (default: first variation)
21
+ -l, --label string Display label for the field
22
+ -p, --placeholder string Placeholder text
23
+ -h, --help Show help for command
24
+
25
+ EXAMPLES
26
+ prismic slice add-field timestamp my_slice created_at
27
+ prismic slice add-field timestamp event start_time --label "Event Start"
28
+ prismic slice add-field timestamp schedule meeting_time --variation "detailed"
29
+ `.trim();
30
+
31
+ export async function sliceAddFieldTimestamp(): Promise<void> {
32
+ const {
33
+ values: { help, variation, label, placeholder },
34
+ positionals: [sliceId, fieldId],
35
+ } = parseArgs({
36
+ args: process.argv.slice(5), // skip: node, script, "slice", "add-field", "timestamp"
37
+ options: {
38
+ variation: { type: "string", short: "v" },
39
+ label: { type: "string", short: "l" },
40
+ placeholder: { type: "string", short: "p" },
41
+ help: { type: "boolean", short: "h" },
42
+ },
43
+ allowPositionals: true,
44
+ });
45
+
46
+ if (help) {
47
+ console.info(HELP);
48
+ return;
49
+ }
50
+
51
+ if (!sliceId) {
52
+ console.error("Missing required argument: slice-id\n");
53
+ console.error("Usage: prismic slice add-field timestamp <slice-id> <field-id>");
54
+ process.exitCode = 1;
55
+ return;
56
+ }
57
+
58
+ if (!fieldId) {
59
+ console.error("Missing required argument: field-id\n");
60
+ console.error("Usage: prismic slice add-field timestamp <slice-id> <field-id>");
61
+ process.exitCode = 1;
62
+ return;
63
+ }
64
+
65
+ // Find the slice model
66
+ const result = await findSliceModel(sliceId);
67
+ if (!result.ok) {
68
+ console.error(result.error);
69
+ process.exitCode = 1;
70
+ return;
71
+ }
72
+
73
+ const { model, modelPath } = result;
74
+
75
+ // Check for variations
76
+ if (model.variations.length === 0) {
77
+ console.error(`Slice "${sliceId}" has no variations.\n`);
78
+ console.error("Add a variation first before adding fields.");
79
+ process.exitCode = 1;
80
+ return;
81
+ }
82
+
83
+ // Find target variation
84
+ const targetVariation = variation
85
+ ? model.variations.find((v) => v.id === variation)
86
+ : model.variations[0];
87
+
88
+ if (!targetVariation) {
89
+ console.error(`Variation "${variation}" not found in slice "${sliceId}"\n`);
90
+ console.error(`Available variations: ${model.variations.map((v) => v.id).join(", ")}`);
91
+ process.exitCode = 1;
92
+ return;
93
+ }
94
+
95
+ // Initialize primary if it doesn't exist
96
+ if (!targetVariation.primary) {
97
+ targetVariation.primary = {};
98
+ }
99
+
100
+ // Check if field already exists in any variation
101
+ for (const v of model.variations) {
102
+ if (v.primary?.[fieldId]) {
103
+ console.error(`Field "${fieldId}" already exists in variation "${v.id}"`);
104
+ process.exitCode = 1;
105
+ return;
106
+ }
107
+ }
108
+
109
+ // Build field definition
110
+ const fieldDefinition: Timestamp = {
111
+ type: "Timestamp",
112
+ config: {
113
+ ...(label && { label }),
114
+ ...(placeholder && { placeholder }),
115
+ },
116
+ };
117
+
118
+ // Add field to variation
119
+ targetVariation.primary[fieldId] = fieldDefinition;
120
+
121
+ // Write updated model
122
+ try {
123
+ await writeFile(modelPath, stringify(model as SharedSlice));
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(
135
+ `Added field "${fieldId}" (Timestamp) to "${targetVariation.id}" variation in ${sliceId}`,
136
+ );
137
+ }
@@ -0,0 +1,106 @@
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 { sliceAddFieldImage } from "./slice-add-field-image";
9
+ import { sliceAddFieldKeyText } from "./slice-add-field-key-text";
10
+ import { sliceAddFieldLink } from "./slice-add-field-link";
11
+ import { sliceAddFieldNumber } from "./slice-add-field-number";
12
+ import { sliceAddFieldRichText } from "./slice-add-field-rich-text";
13
+ import { sliceAddFieldSelect } from "./slice-add-field-select";
14
+ import { sliceAddFieldTimestamp } from "./slice-add-field-timestamp";
15
+
16
+ const HELP = `
17
+ Add a field to an existing slice.
18
+
19
+ USAGE
20
+ prismic slice add-field <field-type> <slice-id> <field-id> [flags]
21
+
22
+ FIELD TYPES
23
+ boolean Boolean toggle
24
+ color Color picker
25
+ date Date picker
26
+ embed Embed (oEmbed)
27
+ geo-point Geographic coordinates
28
+ image Image
29
+ key-text Single-line text
30
+ link Any link type
31
+ number Number
32
+ rich-text Rich text editor
33
+ select Dropdown select
34
+ timestamp Date and time
35
+
36
+ FLAGS
37
+ -h, --help Show help for command
38
+
39
+ LEARN MORE
40
+ Use \`prismic slice add-field <field-type> --help\` for more information.
41
+
42
+ EXAMPLES
43
+ prismic slice add-field key-text my_slice title --label "Title"
44
+ prismic slice add-field link my_slice cta --allow-text
45
+ prismic slice add-field rich-text my_slice body --multi "paragraph,heading2,strong,em"
46
+ prismic slice add-field select my_slice layout --option "full" --option "sidebar"
47
+ `.trim();
48
+
49
+ export async function sliceAddField(): Promise<void> {
50
+ const {
51
+ positionals: [fieldType],
52
+ } = parseArgs({
53
+ args: process.argv.slice(4), // skip: node, script, "slice", "add-field"
54
+ options: {
55
+ help: { type: "boolean", short: "h" },
56
+ },
57
+ allowPositionals: true,
58
+ strict: false,
59
+ });
60
+
61
+ switch (fieldType) {
62
+ case "boolean":
63
+ await sliceAddFieldBoolean();
64
+ break;
65
+ case "color":
66
+ await sliceAddFieldColor();
67
+ break;
68
+ case "date":
69
+ await sliceAddFieldDate();
70
+ break;
71
+ case "embed":
72
+ await sliceAddFieldEmbed();
73
+ break;
74
+ case "geo-point":
75
+ await sliceAddFieldGeoPoint();
76
+ break;
77
+ case "image":
78
+ await sliceAddFieldImage();
79
+ break;
80
+ case "key-text":
81
+ await sliceAddFieldKeyText();
82
+ break;
83
+ case "link":
84
+ await sliceAddFieldLink();
85
+ break;
86
+ case "number":
87
+ await sliceAddFieldNumber();
88
+ break;
89
+ case "rich-text":
90
+ await sliceAddFieldRichText();
91
+ break;
92
+ case "select":
93
+ await sliceAddFieldSelect();
94
+ break;
95
+ case "timestamp":
96
+ await sliceAddFieldTimestamp();
97
+ break;
98
+ default: {
99
+ if (fieldType) {
100
+ console.error(`Unknown field type: ${fieldType}\n`);
101
+ process.exitCode = 1;
102
+ }
103
+ console.info(HELP);
104
+ }
105
+ }
106
+ }