@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 { 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, pascalCase } from "./lib/slice";
8
+
9
+ const HELP = `
10
+ Add a new variation to a slice.
11
+
12
+ USAGE
13
+ prismic slice add-variation <slice-id> <variation-id> [flags]
14
+
15
+ ARGUMENTS
16
+ slice-id Slice identifier (required)
17
+ variation-id New variation identifier (required)
18
+
19
+ FLAGS
20
+ --name string Display name for the variation
21
+ --copy-from string Copy fields from an existing variation
22
+ -h, --help Show help for command
23
+
24
+ EXAMPLES
25
+ prismic slice add-variation MySlice withImage
26
+ prismic slice add-variation MySlice withImage --name "With Image"
27
+ prismic slice add-variation MySlice withImage --copy-from default
28
+ `.trim();
29
+
30
+ export async function sliceAddVariation(): Promise<void> {
31
+ const {
32
+ values: { help, name, "copy-from": copyFrom },
33
+ positionals: [sliceId, variationId],
34
+ } = parseArgs({
35
+ args: process.argv.slice(4), // skip: node, script, "slice", "add-variation"
36
+ options: {
37
+ name: { type: "string" },
38
+ "copy-from": { type: "string" },
39
+ help: { type: "boolean", short: "h" },
40
+ },
41
+ allowPositionals: true,
42
+ });
43
+
44
+ if (help) {
45
+ console.info(HELP);
46
+ return;
47
+ }
48
+
49
+ if (!sliceId) {
50
+ console.error("Missing required argument: slice-id\n");
51
+ console.error(
52
+ "Usage: prismic slice add-variation <slice-id> <variation-id>",
53
+ );
54
+ process.exitCode = 1;
55
+ return;
56
+ }
57
+
58
+ if (!variationId) {
59
+ console.error("Missing required argument: variation-id\n");
60
+ console.error(
61
+ "Usage: prismic slice add-variation <slice-id> <variation-id>",
62
+ );
63
+ process.exitCode = 1;
64
+ return;
65
+ }
66
+
67
+ const result = await findSliceModel(sliceId);
68
+ if (!result.ok) {
69
+ console.error(result.error);
70
+ process.exitCode = 1;
71
+ return;
72
+ }
73
+
74
+ const { model, modelPath } = result;
75
+
76
+ // Check if variation already exists
77
+ if (model.variations.some((v) => v.id === variationId)) {
78
+ console.error(`Variation "${variationId}" already exists in slice "${sliceId}"`);
79
+ process.exitCode = 1;
80
+ return;
81
+ }
82
+
83
+ // Build new variation
84
+ let newVariation: SharedSlice["variations"][number];
85
+
86
+ if (copyFrom) {
87
+ const sourceVariation = model.variations.find((v) => v.id === copyFrom);
88
+ if (!sourceVariation) {
89
+ console.error(`Source variation not found: ${copyFrom}`);
90
+ console.error(
91
+ `Available variations: ${model.variations.map((v) => v.id).join(", ")}`,
92
+ );
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 writeFile(modelPath, stringify(updatedModel 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 variation "${variationId}" to slice "${sliceId}"`,
136
+ );
137
+ }
@@ -0,0 +1,129 @@
1
+ import type { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
4
+ import { parseArgs } from "node:util";
5
+ import * as v from "valibot";
6
+
7
+ import { exists, findUpward } from "./lib/file";
8
+ import { stringify } from "./lib/json";
9
+
10
+ const HELP = `
11
+ Create a new slice in a Prismic project.
12
+
13
+ USAGE
14
+ prismic slice create <id> [flags]
15
+
16
+ ARGUMENTS
17
+ id Slice identifier (required)
18
+
19
+ FLAGS
20
+ -n, --name string Display name for the slice
21
+ -h, --help Show help for command
22
+
23
+ LEARN MORE
24
+ Use \`prismic slice <command> --help\` for more information about a command.
25
+ `.trim();
26
+
27
+ export async function sliceCreate(): Promise<void> {
28
+ const {
29
+ values: { help, name },
30
+ positionals: [id],
31
+ } = parseArgs({
32
+ args: process.argv.slice(4), // skip: node, script, "slice", "create"
33
+ options: {
34
+ name: { type: "string", short: "n" },
35
+ help: { type: "boolean", short: "h" },
36
+ },
37
+ allowPositionals: true,
38
+ });
39
+
40
+ if (help) {
41
+ console.info(HELP);
42
+ return;
43
+ }
44
+
45
+ if (!id) {
46
+ console.error("Missing required argument: id");
47
+ process.exitCode = 1;
48
+ return;
49
+ }
50
+
51
+ const model: SharedSlice = {
52
+ id,
53
+ type: "SharedSlice",
54
+ name: name ?? pascalCase(id),
55
+ description: "",
56
+ variations: [
57
+ {
58
+ id: "default",
59
+ name: "Default",
60
+ description: "Default",
61
+ imageUrl: "",
62
+ docURL: "",
63
+ version: "initial",
64
+ primary: {},
65
+ items: {},
66
+ },
67
+ ],
68
+ };
69
+
70
+ const slicesDirectory = await getSlicesDirectory();
71
+ const sliceDirectory = new URL(pascalCase(model.name) + "/", slicesDirectory);
72
+ const modelPath = new URL("model.json", sliceDirectory);
73
+
74
+ try {
75
+ await mkdir(new URL(".", modelPath), { recursive: true });
76
+ await writeFile(modelPath, stringify(model));
77
+ } catch (error) {
78
+ if (error instanceof Error) {
79
+ console.error(`Failed to create slice: ${error.message}`);
80
+ } else {
81
+ console.error(`Failed to create slice`);
82
+ }
83
+ process.exitCode = 1;
84
+ return;
85
+ }
86
+
87
+ console.info(`Created slice at ${modelPath.href}`);
88
+ }
89
+
90
+ async function getSlicesDirectory(): Promise<URL> {
91
+ const framework = await detectFramework();
92
+ const projectRoot = await findUpward("package.json");
93
+ switch (framework) {
94
+ case "next": {
95
+ const hasSrcDir = await exists(new URL("src", projectRoot));
96
+ if (hasSrcDir) return new URL("src/slices/", projectRoot);
97
+ }
98
+ case "nuxt": {
99
+ const hasAppDir = await exists(new URL("app", projectRoot));
100
+ if (hasAppDir) return new URL("app/slices/", projectRoot);
101
+ }
102
+ case "sveltekit": {
103
+ return new URL("src/slices/", projectRoot);
104
+ }
105
+ }
106
+ return new URL("slices/", projectRoot);
107
+ }
108
+
109
+ const PackageJsonSchema = v.object({
110
+ dependencies: v.optional(v.record(v.string(), v.string())),
111
+ });
112
+
113
+ type Framework = "next" | "nuxt" | "sveltekit";
114
+
115
+ async function detectFramework(): Promise<Framework | undefined> {
116
+ const packageJsonPath = await findUpward("package.json");
117
+ if (!packageJsonPath) return;
118
+ try {
119
+ const contents = await readFile(packageJsonPath, "utf8");
120
+ const { dependencies = {} } = v.parse(PackageJsonSchema, JSON.parse(contents));
121
+ if ("next" in dependencies) return "next";
122
+ if ("nuxt" in dependencies) return "nuxt";
123
+ if ("@sveltejs/kit" in dependencies) return "sveltekit";
124
+ } catch {}
125
+ }
126
+
127
+ function pascalCase(input: string): string {
128
+ return input.toLowerCase().replace(/(^|[-_\s]+)(.)?/g, (_, __, c) => c?.toUpperCase() ?? "");
129
+ }
@@ -0,0 +1,67 @@
1
+ import { parseArgs } from "node:util";
2
+
3
+ import { findSliceModel } from "./lib/slice";
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 result = await findSliceModel(sliceId);
49
+ if (!result.ok) {
50
+ console.error(result.error);
51
+ process.exitCode = 1;
52
+ return;
53
+ }
54
+
55
+ const { model } = result;
56
+ const variations = model.variations.map((v) => ({ id: v.id, name: v.name }));
57
+
58
+ if (json) {
59
+ console.info(JSON.stringify(variations, null, 2));
60
+ return;
61
+ }
62
+
63
+ console.info("ID\tNAME");
64
+ for (const variation of variations) {
65
+ console.info(`${variation.id}\t${variation.name}`);
66
+ }
67
+ }
@@ -0,0 +1,88 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { parseArgs } from "node:util";
3
+ import * as v from "valibot";
4
+
5
+ import { getSlicesDirectory, SharedSliceSchema } from "./lib/slice";
6
+
7
+ const HELP = `
8
+ List all slices in a Prismic project.
9
+
10
+ USAGE
11
+ prismic slice list [flags]
12
+
13
+ FLAGS
14
+ --json Output as JSON
15
+ -h, --help Show help for command
16
+
17
+ EXAMPLES
18
+ prismic slice list
19
+ prismic slice list --json
20
+ `.trim();
21
+
22
+ export async function sliceList(): Promise<void> {
23
+ const {
24
+ values: { help, json },
25
+ } = parseArgs({
26
+ args: process.argv.slice(4), // skip: node, script, "slice", "list"
27
+ options: {
28
+ json: { type: "boolean" },
29
+ help: { type: "boolean", short: "h" },
30
+ },
31
+ allowPositionals: true,
32
+ });
33
+
34
+ if (help) {
35
+ console.info(HELP);
36
+ return;
37
+ }
38
+
39
+ const slicesDirectory = await getSlicesDirectory();
40
+
41
+ let entries: string[];
42
+ try {
43
+ entries = (await readdir(slicesDirectory, {
44
+ withFileTypes: false,
45
+ })) as unknown as string[];
46
+ } catch {
47
+ if (json) {
48
+ console.info(JSON.stringify([]));
49
+ } else {
50
+ console.info("No slices found.");
51
+ }
52
+ return;
53
+ }
54
+
55
+ const slices: { id: string; name: string }[] = [];
56
+
57
+ for (const entry of entries) {
58
+ const modelPath = new URL(`${entry}/model.json`, slicesDirectory);
59
+ try {
60
+ const contents = await readFile(modelPath, "utf8");
61
+ const parsed = JSON.parse(contents);
62
+ const result = v.safeParse(SharedSliceSchema, parsed);
63
+ if (result.success) {
64
+ slices.push({ id: result.output.id, name: result.output.name });
65
+ }
66
+ } catch {
67
+ // Skip directories without valid model.json
68
+ }
69
+ }
70
+
71
+ if (slices.length === 0) {
72
+ if (json) {
73
+ console.info(JSON.stringify([]));
74
+ } else {
75
+ console.info("No slices found.");
76
+ }
77
+ return;
78
+ }
79
+
80
+ if (json) {
81
+ console.info(JSON.stringify(slices, null, 2));
82
+ } else {
83
+ console.info("ID\tNAME");
84
+ for (const slice of slices) {
85
+ console.info(`${slice.id}\t${slice.name}`);
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,117 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import { parseArgs } from "node:util";
3
+
4
+ import { stringify } from "./lib/json";
5
+ import { findSliceModel } from "./lib/slice";
6
+
7
+ const HELP = `
8
+ Remove a field from a slice variation.
9
+
10
+ USAGE
11
+ prismic slice remove-field <slice-id> <field-id> [flags]
12
+
13
+ ARGUMENTS
14
+ slice-id Slice identifier (required)
15
+ field-id Field identifier (required)
16
+
17
+ FLAGS
18
+ --variation string Target variation (default: "default")
19
+ --zone string Field zone: "primary" or "items" (default: "primary")
20
+ -h, --help Show help for command
21
+
22
+ EXAMPLES
23
+ prismic slice remove-field MySlice title
24
+ prismic slice remove-field MySlice title --variation withImage
25
+ prismic slice remove-field MySlice item_title --zone items
26
+ `.trim();
27
+
28
+ export async function sliceRemoveField(): Promise<void> {
29
+ const {
30
+ values: { help, variation, zone },
31
+ positionals: [sliceId, fieldId],
32
+ } = parseArgs({
33
+ args: process.argv.slice(4), // skip: node, script, "slice", "remove-field"
34
+ options: {
35
+ variation: { type: "string", default: "default" },
36
+ zone: { type: "string", default: "primary" },
37
+ help: { type: "boolean", short: "h" },
38
+ },
39
+ allowPositionals: true,
40
+ });
41
+
42
+ if (help) {
43
+ console.info(HELP);
44
+ return;
45
+ }
46
+
47
+ if (!sliceId) {
48
+ console.error("Missing required argument: slice-id\n");
49
+ console.error("Usage: prismic slice remove-field <slice-id> <field-id>");
50
+ process.exitCode = 1;
51
+ return;
52
+ }
53
+
54
+ if (!fieldId) {
55
+ console.error("Missing required argument: field-id\n");
56
+ console.error("Usage: prismic slice remove-field <slice-id> <field-id>");
57
+ process.exitCode = 1;
58
+ return;
59
+ }
60
+
61
+ if (zone !== "primary" && zone !== "items") {
62
+ console.error(`Invalid zone: ${zone}. Must be "primary" or "items".`);
63
+ process.exitCode = 1;
64
+ return;
65
+ }
66
+
67
+ const result = await findSliceModel(sliceId);
68
+ if (!result.ok) {
69
+ console.error(result.error);
70
+ process.exitCode = 1;
71
+ return;
72
+ }
73
+
74
+ const { model, modelPath } = result;
75
+
76
+ // Find the variation
77
+ const targetVariation = model.variations.find((v) => v.id === variation);
78
+ if (!targetVariation) {
79
+ console.error(`Variation not found: ${variation}`);
80
+ console.error(
81
+ `Available variations: ${model.variations.map((v) => v.id).join(", ")}`,
82
+ );
83
+ process.exitCode = 1;
84
+ return;
85
+ }
86
+
87
+ // Check if field exists
88
+ const zoneFields =
89
+ zone === "primary" ? targetVariation.primary : targetVariation.items;
90
+ if (!zoneFields || !(fieldId in zoneFields)) {
91
+ console.error(
92
+ `Field "${fieldId}" not found in ${zone} zone of variation "${variation}"`,
93
+ );
94
+ process.exitCode = 1;
95
+ return;
96
+ }
97
+
98
+ // Remove the field
99
+ delete zoneFields[fieldId];
100
+
101
+ // Write updated model
102
+ try {
103
+ await writeFile(modelPath, stringify(model));
104
+ } catch (error) {
105
+ if (error instanceof Error) {
106
+ console.error(`Failed to update slice: ${error.message}`);
107
+ } else {
108
+ console.error("Failed to update slice");
109
+ }
110
+ process.exitCode = 1;
111
+ return;
112
+ }
113
+
114
+ console.info(
115
+ `Removed field "${fieldId}" from ${zone} zone in variation "${variation}" of slice "${sliceId}"`,
116
+ );
117
+ }
@@ -0,0 +1,108 @@
1
+ import type { 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
+ Remove a variation from a slice.
11
+
12
+ USAGE
13
+ prismic slice remove-variation <slice-id> <variation-id> [flags]
14
+
15
+ ARGUMENTS
16
+ slice-id Slice identifier (required)
17
+ variation-id Variation to remove (required)
18
+
19
+ FLAGS
20
+ -h, --help Show help for command
21
+
22
+ EXAMPLES
23
+ prismic slice remove-variation MySlice withImage
24
+ `.trim();
25
+
26
+ export async function sliceRemoveVariation(): Promise<void> {
27
+ const {
28
+ values: { help },
29
+ positionals: [sliceId, variationId],
30
+ } = parseArgs({
31
+ args: process.argv.slice(4), // skip: node, script, "slice", "remove-variation"
32
+ options: {
33
+ help: { type: "boolean", short: "h" },
34
+ },
35
+ allowPositionals: true,
36
+ });
37
+
38
+ if (help) {
39
+ console.info(HELP);
40
+ return;
41
+ }
42
+
43
+ if (!sliceId) {
44
+ console.error("Missing required argument: slice-id\n");
45
+ console.error(
46
+ "Usage: prismic slice remove-variation <slice-id> <variation-id>",
47
+ );
48
+ process.exitCode = 1;
49
+ return;
50
+ }
51
+
52
+ if (!variationId) {
53
+ console.error("Missing required argument: variation-id\n");
54
+ console.error(
55
+ "Usage: prismic slice remove-variation <slice-id> <variation-id>",
56
+ );
57
+ process.exitCode = 1;
58
+ return;
59
+ }
60
+
61
+ const result = await findSliceModel(sliceId);
62
+ if (!result.ok) {
63
+ console.error(result.error);
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+
68
+ const { model, modelPath } = result;
69
+
70
+ // Check if variation exists
71
+ const variationExists = model.variations.some((v) => v.id === variationId);
72
+ if (!variationExists) {
73
+ console.error(`Variation not found: ${variationId}`);
74
+ console.error(
75
+ `Available variations: ${model.variations.map((v) => v.id).join(", ")}`,
76
+ );
77
+ process.exitCode = 1;
78
+ return;
79
+ }
80
+
81
+ // Prevent removing the last variation
82
+ if (model.variations.length === 1) {
83
+ console.error("Cannot remove the last variation from a slice.");
84
+ process.exitCode = 1;
85
+ return;
86
+ }
87
+
88
+ // Remove the variation
89
+ const updatedModel = {
90
+ ...model,
91
+ variations: model.variations.filter((v) => v.id !== variationId),
92
+ };
93
+
94
+ // Write updated model
95
+ try {
96
+ await writeFile(modelPath, stringify(updatedModel as SharedSlice));
97
+ } catch (error) {
98
+ if (error instanceof Error) {
99
+ console.error(`Failed to update slice: ${error.message}`);
100
+ } else {
101
+ console.error("Failed to update slice");
102
+ }
103
+ process.exitCode = 1;
104
+ return;
105
+ }
106
+
107
+ console.info(`Removed variation "${variationId}" from slice "${sliceId}"`);
108
+ }