@angeloashmore/prismic-cli-poc 0.0.0-canary.1d36cd8

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 (131) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +98 -0
  3. package/dist/index.mjs +2548 -0
  4. package/package.json +53 -0
  5. package/src/codegen-types.ts +82 -0
  6. package/src/codegen.ts +45 -0
  7. package/src/custom-type-add-field-boolean.ts +192 -0
  8. package/src/custom-type-add-field-color.ts +177 -0
  9. package/src/custom-type-add-field-date.ts +180 -0
  10. package/src/custom-type-add-field-embed.ts +177 -0
  11. package/src/custom-type-add-field-geo-point.ts +174 -0
  12. package/src/custom-type-add-field-image.ts +177 -0
  13. package/src/custom-type-add-field-key-text.ts +177 -0
  14. package/src/custom-type-add-field-link.ts +201 -0
  15. package/src/custom-type-add-field-number.ts +209 -0
  16. package/src/custom-type-add-field-rich-text.ts +202 -0
  17. package/src/custom-type-add-field-select.ts +192 -0
  18. package/src/custom-type-add-field-timestamp.ts +180 -0
  19. package/src/custom-type-add-field-uid.ts +177 -0
  20. package/src/custom-type-add-field.ts +111 -0
  21. package/src/custom-type-connect-slice.ts +220 -0
  22. package/src/custom-type-create.ts +118 -0
  23. package/src/custom-type-disconnect-slice.ts +177 -0
  24. package/src/custom-type-list.ts +110 -0
  25. package/src/custom-type-remove-field.ts +177 -0
  26. package/src/custom-type-remove.ts +144 -0
  27. package/src/custom-type-set-name.ts +144 -0
  28. package/src/custom-type-view.ts +118 -0
  29. package/src/custom-type.ts +85 -0
  30. package/src/index.ts +127 -0
  31. package/src/init.ts +64 -0
  32. package/src/lib/auth.ts +83 -0
  33. package/src/lib/config.ts +111 -0
  34. package/src/lib/custom-types-api.ts +438 -0
  35. package/src/lib/file.ts +49 -0
  36. package/src/lib/framework.ts +143 -0
  37. package/src/lib/json.ts +3 -0
  38. package/src/lib/request.ts +116 -0
  39. package/src/lib/slice.ts +115 -0
  40. package/src/lib/string.ts +6 -0
  41. package/src/lib/url.ts +25 -0
  42. package/src/locale-add.ts +116 -0
  43. package/src/locale-list.ts +107 -0
  44. package/src/locale-remove.ts +88 -0
  45. package/src/locale-set-default.ts +131 -0
  46. package/src/locale.ts +60 -0
  47. package/src/login.ts +152 -0
  48. package/src/logout.ts +36 -0
  49. package/src/page-type-add-field-boolean.ts +192 -0
  50. package/src/page-type-add-field-color.ts +177 -0
  51. package/src/page-type-add-field-date.ts +180 -0
  52. package/src/page-type-add-field-embed.ts +177 -0
  53. package/src/page-type-add-field-geo-point.ts +174 -0
  54. package/src/page-type-add-field-image.ts +177 -0
  55. package/src/page-type-add-field-key-text.ts +177 -0
  56. package/src/page-type-add-field-link.ts +201 -0
  57. package/src/page-type-add-field-number.ts +209 -0
  58. package/src/page-type-add-field-rich-text.ts +202 -0
  59. package/src/page-type-add-field-select.ts +192 -0
  60. package/src/page-type-add-field-timestamp.ts +180 -0
  61. package/src/page-type-add-field-uid.ts +177 -0
  62. package/src/page-type-add-field.ts +111 -0
  63. package/src/page-type-connect-slice.ts +220 -0
  64. package/src/page-type-create.ts +142 -0
  65. package/src/page-type-disconnect-slice.ts +177 -0
  66. package/src/page-type-list.ts +109 -0
  67. package/src/page-type-remove-field.ts +177 -0
  68. package/src/page-type-remove.ts +144 -0
  69. package/src/page-type-set-name.ts +144 -0
  70. package/src/page-type-set-repeatable.ts +153 -0
  71. package/src/page-type-view.ts +118 -0
  72. package/src/page-type.ts +90 -0
  73. package/src/preview-add.ts +126 -0
  74. package/src/preview-get-simulator.ts +104 -0
  75. package/src/preview-list.ts +106 -0
  76. package/src/preview-remove-simulator.ts +80 -0
  77. package/src/preview-remove.ts +109 -0
  78. package/src/preview-set-name.ts +137 -0
  79. package/src/preview-set-simulator.ts +116 -0
  80. package/src/preview.ts +75 -0
  81. package/src/pull.ts +247 -0
  82. package/src/push.ts +405 -0
  83. package/src/repo-create.ts +136 -0
  84. package/src/repo-get-access.ts +86 -0
  85. package/src/repo-list.ts +100 -0
  86. package/src/repo-set-access.ts +100 -0
  87. package/src/repo-set-name.ts +102 -0
  88. package/src/repo-view.ts +113 -0
  89. package/src/repo.ts +70 -0
  90. package/src/slice-add-field-boolean.ts +173 -0
  91. package/src/slice-add-field-color.ts +158 -0
  92. package/src/slice-add-field-date.ts +158 -0
  93. package/src/slice-add-field-embed.ts +158 -0
  94. package/src/slice-add-field-geo-point.ts +155 -0
  95. package/src/slice-add-field-image.ts +155 -0
  96. package/src/slice-add-field-key-text.ts +158 -0
  97. package/src/slice-add-field-link.ts +178 -0
  98. package/src/slice-add-field-number.ts +158 -0
  99. package/src/slice-add-field-rich-text.ts +183 -0
  100. package/src/slice-add-field-select.ts +173 -0
  101. package/src/slice-add-field-timestamp.ts +158 -0
  102. package/src/slice-add-field.ts +106 -0
  103. package/src/slice-add-variation.ts +145 -0
  104. package/src/slice-create.ts +148 -0
  105. package/src/slice-list-variations.ts +67 -0
  106. package/src/slice-list.ts +88 -0
  107. package/src/slice-remove-field.ts +128 -0
  108. package/src/slice-remove-variation.ts +118 -0
  109. package/src/slice-remove.ts +97 -0
  110. package/src/slice-rename.ts +128 -0
  111. package/src/slice-view.ts +77 -0
  112. package/src/slice.ts +90 -0
  113. package/src/status.ts +733 -0
  114. package/src/token-create.ts +203 -0
  115. package/src/token-delete.ts +182 -0
  116. package/src/token-list.ts +223 -0
  117. package/src/token-set-name.ts +193 -0
  118. package/src/token.ts +60 -0
  119. package/src/webhook-add-header.ts +118 -0
  120. package/src/webhook-create.ts +152 -0
  121. package/src/webhook-disable.ts +109 -0
  122. package/src/webhook-enable.ts +132 -0
  123. package/src/webhook-list.ts +93 -0
  124. package/src/webhook-remove-header.ts +117 -0
  125. package/src/webhook-remove.ts +106 -0
  126. package/src/webhook-set-triggers.ts +148 -0
  127. package/src/webhook-status.ts +90 -0
  128. package/src/webhook-test.ts +106 -0
  129. package/src/webhook-view.ts +147 -0
  130. package/src/webhook.ts +95 -0
  131. package/src/whoami.ts +62 -0
@@ -0,0 +1,116 @@
1
+ import { parseArgs } from "node:util";
2
+
3
+ import { isAuthenticated } from "./lib/auth";
4
+ import { safeGetRepositoryFromConfig } from "./lib/config";
5
+ import { stringify } from "./lib/json";
6
+ import { ForbiddenRequestError, request } from "./lib/request";
7
+ import { getRepoUrl } from "./lib/url";
8
+
9
+ const HELP = `
10
+ Set the slice simulator URL for a Prismic repository.
11
+
12
+ If the URL pathname does not end with /slice-simulator, it is appended
13
+ automatically.
14
+
15
+ By default, this command reads the repository from prismic.config.json at the
16
+ project root.
17
+
18
+ USAGE
19
+ prismic preview set-simulator <url> [flags]
20
+
21
+ ARGUMENTS
22
+ <url> Simulator URL (e.g. https://example.com/slice-simulator)
23
+
24
+ FLAGS
25
+ -r, --repo string Repository domain
26
+ -h, --help Show help for command
27
+
28
+ EXAMPLES
29
+ prismic preview set-simulator https://my-site.com
30
+ prismic preview set-simulator http://localhost:3000/slice-simulator
31
+
32
+ LEARN MORE
33
+ Use \`prismic <command> <subcommand> --help\` for more information about a command.
34
+ `.trim();
35
+
36
+ export async function previewSetSimulator(): Promise<void> {
37
+ const {
38
+ values: { help, repo = await safeGetRepositoryFromConfig() },
39
+ positionals: [urlArg],
40
+ } = parseArgs({
41
+ args: process.argv.slice(4), // skip: node, script, "preview", "set-simulator"
42
+ options: {
43
+ repo: { type: "string", short: "r" },
44
+ help: { type: "boolean", short: "h" },
45
+ },
46
+ allowPositionals: true,
47
+ });
48
+
49
+ if (help) {
50
+ console.info(HELP);
51
+ return;
52
+ }
53
+
54
+ if (!urlArg) {
55
+ console.error("Missing required argument: <url>");
56
+ process.exitCode = 1;
57
+ return;
58
+ }
59
+
60
+ if (!repo) {
61
+ console.error("Missing prismic.config.json or --repo option");
62
+ process.exitCode = 1;
63
+ return;
64
+ }
65
+
66
+ const authenticated = await isAuthenticated();
67
+ if (!authenticated) {
68
+ handleUnauthenticated();
69
+ return;
70
+ }
71
+
72
+ const simulatorUrl = normalizeSimulatorUrl(urlArg);
73
+ if (!simulatorUrl) {
74
+ console.error(`Invalid URL: ${urlArg}`);
75
+ process.exitCode = 1;
76
+ return;
77
+ }
78
+
79
+ const response = await setSimulatorUrl(repo, simulatorUrl);
80
+ if (!response.ok) {
81
+ if (response.error instanceof ForbiddenRequestError) {
82
+ handleUnauthenticated();
83
+ } else {
84
+ console.error(`Failed to set simulator URL: ${stringify(response.value)}`);
85
+ process.exitCode = 1;
86
+ }
87
+ return;
88
+ }
89
+
90
+ console.info(`Simulator URL set: ${simulatorUrl}`);
91
+ }
92
+
93
+ export function normalizeSimulatorUrl(url: string): string | undefined {
94
+ try {
95
+ const parsed = new URL(url);
96
+ if (!parsed.pathname.endsWith("/slice-simulator")) {
97
+ parsed.pathname = parsed.pathname.replace(/\/+$/, "") + "/slice-simulator";
98
+ }
99
+ return parsed.toString();
100
+ } catch {
101
+ return undefined;
102
+ }
103
+ }
104
+
105
+ async function setSimulatorUrl(repo: string, simulatorUrl: string) {
106
+ const url = new URL("/core/repository", await getRepoUrl(repo));
107
+ return await request(url, {
108
+ method: "PATCH",
109
+ body: { simulator_url: simulatorUrl },
110
+ });
111
+ }
112
+
113
+ function handleUnauthenticated() {
114
+ console.error("Not logged in. Run `prismic login` first.");
115
+ process.exitCode = 1;
116
+ }
package/src/preview.ts ADDED
@@ -0,0 +1,75 @@
1
+ import { parseArgs } from "node:util";
2
+
3
+ import { previewAdd } from "./preview-add";
4
+ import { previewGetSimulator } from "./preview-get-simulator";
5
+ import { previewList } from "./preview-list";
6
+ import { previewRemove } from "./preview-remove";
7
+ import { previewRemoveSimulator } from "./preview-remove-simulator";
8
+ import { previewSetName } from "./preview-set-name";
9
+ import { previewSetSimulator } from "./preview-set-simulator";
10
+
11
+ const HELP = `
12
+ Manage preview configurations in a Prismic repository.
13
+
14
+ USAGE
15
+ prismic preview <command> [flags]
16
+
17
+ COMMANDS
18
+ add Add a preview configuration
19
+ list List preview configurations
20
+ remove Remove a preview configuration
21
+ set-name Update a preview's name
22
+ set-simulator Set the slice simulator URL
23
+ get-simulator Show the slice simulator URL
24
+ remove-simulator Remove the slice simulator URL
25
+
26
+ FLAGS
27
+ -h, --help Show help for command
28
+
29
+ LEARN MORE
30
+ Use \`prismic preview <command> --help\` for more information about a command.
31
+ `.trim();
32
+
33
+ export async function preview(): Promise<void> {
34
+ const {
35
+ positionals: [subcommand],
36
+ } = parseArgs({
37
+ args: process.argv.slice(3), // skip: node, script, "preview"
38
+ options: {
39
+ help: { type: "boolean", short: "h" },
40
+ },
41
+ allowPositionals: true,
42
+ strict: false,
43
+ });
44
+
45
+ switch (subcommand) {
46
+ case "add":
47
+ await previewAdd();
48
+ break;
49
+ case "list":
50
+ await previewList();
51
+ break;
52
+ case "remove":
53
+ await previewRemove();
54
+ break;
55
+ case "set-name":
56
+ await previewSetName();
57
+ break;
58
+ case "set-simulator":
59
+ await previewSetSimulator();
60
+ break;
61
+ case "get-simulator":
62
+ await previewGetSimulator();
63
+ break;
64
+ case "remove-simulator":
65
+ await previewRemoveSimulator();
66
+ break;
67
+ default: {
68
+ if (subcommand) {
69
+ console.error(`Unknown preview subcommand: ${subcommand}\n`);
70
+ process.exitCode = 1;
71
+ }
72
+ console.info(HELP);
73
+ }
74
+ }
75
+ }
package/src/pull.ts ADDED
@@ -0,0 +1,247 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { parseArgs } from "node:util";
3
+
4
+ import { buildTypes } from "./codegen-types";
5
+ import { isAuthenticated } from "./lib/auth";
6
+ import { safeGetRepositoryFromConfig } from "./lib/config";
7
+ import { fetchRemoteCustomTypes, fetchRemoteSlices } from "./lib/custom-types-api";
8
+ import { findUpward } from "./lib/file";
9
+ import { stringify } from "./lib/json";
10
+ import { getSlicesDirectory, pascalCase } from "./lib/slice";
11
+
12
+ const HELP = `
13
+ Pull custom types and slices from Prismic to local files.
14
+
15
+ By default, this command reads the repository from prismic.config.json at the
16
+ project root.
17
+
18
+ USAGE
19
+ prismic pull [flags]
20
+
21
+ Types are generated by default after changes. Use --no-types to skip.
22
+
23
+ FLAGS
24
+ -r, --repo string Repository domain
25
+ --dry-run Show what would be pulled without writing files
26
+ --types-only Only pull custom types
27
+ --slices-only Only pull slices
28
+ --json Output as JSON
29
+ --types string Output file for generated types (default: "prismicio-types.d.ts")
30
+ --no-types Skip type generation
31
+ -h, --help Show help for command
32
+
33
+ EXAMPLES
34
+ prismic pull
35
+ prismic pull --repo my-repo
36
+ prismic pull --dry-run
37
+ prismic pull --types-only
38
+ `.trim();
39
+
40
+ export async function pull(): Promise<void> {
41
+ const {
42
+ values: {
43
+ help,
44
+ repo = await safeGetRepositoryFromConfig(),
45
+ "dry-run": dryRun,
46
+ "types-only": typesOnly,
47
+ "slices-only": slicesOnly,
48
+ json,
49
+ types,
50
+ "no-types": noTypes,
51
+ },
52
+ } = parseArgs({
53
+ args: process.argv.slice(3), // skip: node, script, "pull"
54
+ options: {
55
+ repo: { type: "string", short: "r" },
56
+ "dry-run": { type: "boolean" },
57
+ "types-only": { type: "boolean" },
58
+ "slices-only": { type: "boolean" },
59
+ json: { type: "boolean" },
60
+ types: { type: "string" },
61
+ "no-types": { type: "boolean" },
62
+ help: { type: "boolean", short: "h" },
63
+ },
64
+ allowPositionals: false,
65
+ });
66
+
67
+ if (help) {
68
+ console.info(HELP);
69
+ return;
70
+ }
71
+
72
+ if (!repo) {
73
+ console.error("Missing prismic.config.json or --repo option");
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+
78
+ // Check authentication
79
+ if (!(await isAuthenticated())) {
80
+ console.error("Not logged in. Run `prismic login` first.");
81
+ process.exitCode = 1;
82
+ return;
83
+ }
84
+
85
+ if (!json) {
86
+ console.info(`Pulling from repository: ${repo}\n`);
87
+ }
88
+
89
+ // Fetch remote data in parallel
90
+ const shouldFetchTypes = !slicesOnly;
91
+ const shouldFetchSlices = !typesOnly;
92
+
93
+ const [customTypesResult, slicesResult] = await Promise.all([
94
+ shouldFetchTypes
95
+ ? fetchRemoteCustomTypes(repo)
96
+ : Promise.resolve({ ok: true, value: [] } as const),
97
+ shouldFetchSlices ? fetchRemoteSlices(repo) : Promise.resolve({ ok: true, value: [] } as const),
98
+ ]);
99
+
100
+ if (!customTypesResult.ok) {
101
+ console.error(`Failed to fetch custom types: ${customTypesResult.error}`);
102
+ process.exitCode = 1;
103
+ return;
104
+ }
105
+
106
+ if (!slicesResult.ok) {
107
+ console.error(`Failed to fetch slices: ${slicesResult.error}`);
108
+ process.exitCode = 1;
109
+ return;
110
+ }
111
+
112
+ const customTypes = customTypesResult.value;
113
+ const slices = slicesResult.value;
114
+
115
+ if (!json) {
116
+ if (shouldFetchTypes) {
117
+ console.info(`Fetching custom types... ${customTypes.length} types`);
118
+ }
119
+ if (shouldFetchSlices) {
120
+ console.info(`Fetching slices... ${slices.length} slices`);
121
+ }
122
+ }
123
+
124
+ // Dry run - just show what would be pulled
125
+ if (dryRun) {
126
+ if (json) {
127
+ console.info(stringify({ customTypes, slices }));
128
+ } else {
129
+ console.info("");
130
+ if (shouldFetchTypes && customTypes.length > 0) {
131
+ console.info("Would write custom types:");
132
+ for (const ct of customTypes) {
133
+ console.info(` customtypes/${ct.id}/index.json`);
134
+ }
135
+ }
136
+ if (shouldFetchSlices && slices.length > 0) {
137
+ const slicesDir = await getSlicesDirectory();
138
+ const relativeSlicesDir = getRelativePath(slicesDir);
139
+ console.info("Would write slices:");
140
+ for (const slice of slices) {
141
+ console.info(` ${relativeSlicesDir}${pascalCase(slice.name)}/model.json`);
142
+ }
143
+ }
144
+ console.info(
145
+ `\nDry run complete: ${customTypes.length} custom types, ${slices.length} slices`,
146
+ );
147
+ }
148
+ return;
149
+ }
150
+
151
+ // Find project root
152
+ const projectRoot = await findUpward("package.json");
153
+ if (!projectRoot) {
154
+ console.error("Could not find project root (no package.json found)");
155
+ process.exitCode = 1;
156
+ return;
157
+ }
158
+ const projectDir = new URL(".", projectRoot);
159
+
160
+ const writtenTypes: string[] = [];
161
+ const writtenSlices: string[] = [];
162
+
163
+ // Write custom types
164
+ if (shouldFetchTypes && customTypes.length > 0) {
165
+ if (!json) {
166
+ console.info("\nWriting custom types:");
167
+ }
168
+ const customTypesDir = new URL("customtypes/", projectDir);
169
+
170
+ for (const ct of customTypes) {
171
+ const typeDir = new URL(`${ct.id}/`, customTypesDir);
172
+ const modelPath = new URL("index.json", typeDir);
173
+
174
+ try {
175
+ await mkdir(typeDir, { recursive: true });
176
+ await writeFile(modelPath, stringify(ct));
177
+ const relativePath = `customtypes/${ct.id}/index.json`;
178
+ writtenTypes.push(relativePath);
179
+ if (!json) {
180
+ console.info(` ${relativePath}`);
181
+ }
182
+ } catch (error) {
183
+ console.error(
184
+ `Failed to write custom type ${ct.id}: ${error instanceof Error ? error.message : error}`,
185
+ );
186
+ process.exitCode = 1;
187
+ return;
188
+ }
189
+ }
190
+ }
191
+
192
+ // Write slices
193
+ if (shouldFetchSlices && slices.length > 0) {
194
+ if (!json) {
195
+ console.info("\nWriting slices:");
196
+ }
197
+ const slicesDir = await getSlicesDirectory();
198
+
199
+ for (const slice of slices) {
200
+ const sliceDir = new URL(`${pascalCase(slice.name)}/`, slicesDir);
201
+ const modelPath = new URL("model.json", sliceDir);
202
+
203
+ try {
204
+ await mkdir(sliceDir, { recursive: true });
205
+ await writeFile(modelPath, stringify(slice));
206
+ const relativePath = `${getRelativePath(slicesDir)}${pascalCase(slice.name)}/model.json`;
207
+ writtenSlices.push(relativePath);
208
+ if (!json) {
209
+ console.info(` ${relativePath}`);
210
+ }
211
+ } catch (error) {
212
+ console.error(
213
+ `Failed to write slice ${slice.name}: ${error instanceof Error ? error.message : error}`,
214
+ );
215
+ process.exitCode = 1;
216
+ return;
217
+ }
218
+ }
219
+ }
220
+
221
+ // Output summary
222
+ if (json) {
223
+ console.info(stringify({ writtenTypes, writtenSlices }));
224
+ } else {
225
+ console.info(
226
+ `\nPull complete: ${writtenTypes.length} custom types, ${writtenSlices.length} slices`,
227
+ );
228
+ }
229
+
230
+ if (!json && !noTypes) {
231
+ try {
232
+ await buildTypes({ output: types });
233
+ console.info(`Updated types in ${types ?? "prismicio-types.d.ts"}`);
234
+ } catch (error) {
235
+ console.warn(`Could not generate types: ${error instanceof Error ? error.message : error}`);
236
+ }
237
+ }
238
+ }
239
+
240
+ function getRelativePath(url: URL): string {
241
+ const cwd = process.cwd();
242
+ const path = url.pathname;
243
+ if (path.startsWith(cwd)) {
244
+ return path.slice(cwd.length + 1);
245
+ }
246
+ return path;
247
+ }