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,175 @@
1
+ import { parseArgs } from "node:util";
2
+
3
+ import { isAuthenticated, readHost } from "./lib/auth";
4
+ import { createConfig, readConfig, updateConfig } from "./lib/config";
5
+ import { getClientSetupAnchor, getDocsPath, getFramework } from "./framework";
6
+ import { stringify } from "./lib/json";
7
+ import { ForbiddenRequestError, request } from "./lib/request";
8
+ import { getRepoUrl } from "./lib/url";
9
+
10
+ const HELP = `
11
+ Create a new Prismic repository.
12
+
13
+ Creates prismic.config.json in the current directory. If a config file already
14
+ exists, use --replace to update it with the new repository.
15
+
16
+ USAGE
17
+ prismic repo create <domain> [flags]
18
+
19
+ ARGUMENTS
20
+ domain Repository domain (required). Must be at least 4 characters,
21
+ start and end with alphanumeric, and contain only alphanumerics and hyphens.
22
+
23
+ FLAGS
24
+ -n, --name string Display name for the repository (defaults to domain)
25
+ --no-config Skip creating or updating prismic.config.json
26
+ --replace Replace existing repositoryName in prismic.config.json
27
+ -h, --help Show help for command
28
+
29
+ LEARN MORE
30
+ Use \`prismic repo <command> --help\` for more information about a command.
31
+ `.trim();
32
+
33
+ const DOMAIN_REGEX = /^[a-zA-Z0-9][-a-zA-Z0-9]{2,}[a-zA-Z0-9]$/;
34
+
35
+ export async function repoCreate(): Promise<void> {
36
+ const {
37
+ values: { help, name, "no-config": noConfig, replace },
38
+ positionals: [domain],
39
+ } = parseArgs({
40
+ args: process.argv.slice(4), // skip: node, script, "repo", "create"
41
+ options: {
42
+ help: { type: "boolean", short: "h" },
43
+ name: { type: "string", short: "n" },
44
+ "no-config": { type: "boolean" },
45
+ replace: { type: "boolean" },
46
+ },
47
+ allowPositionals: true,
48
+ });
49
+
50
+ if (help) {
51
+ console.info(HELP);
52
+ return;
53
+ }
54
+
55
+ if (!domain) {
56
+ console.error("Missing required argument: domain");
57
+ process.exitCode = 1;
58
+ return;
59
+ }
60
+
61
+ if (!DOMAIN_REGEX.test(domain)) {
62
+ console.error("Invalid domain format.");
63
+ console.error(
64
+ "Must be at least 4 characters, start and end with alphanumeric, and contain only alphanumerics and hyphens.",
65
+ );
66
+ process.exitCode = 1;
67
+ return;
68
+ }
69
+
70
+ const authenticated = await isAuthenticated();
71
+ if (!authenticated) {
72
+ handleUnauthenticated();
73
+ return;
74
+ }
75
+
76
+ // Check existing config before repo creation (unless --no-config)
77
+ const existingConfig = await readConfig();
78
+ if (!noConfig && existingConfig.ok && !replace) {
79
+ console.error(`This project already has a repository: ${existingConfig.config.repositoryName}`);
80
+ console.error("Use --replace to replace it, or --no-config to skip config creation.");
81
+ process.exitCode = 1;
82
+ return;
83
+ }
84
+
85
+ // Check if domain is available
86
+ const available = await checkDomainAvailable(domain);
87
+ if (!available.ok) {
88
+ if (available.error instanceof ForbiddenRequestError) {
89
+ handleUnauthenticated();
90
+ } else {
91
+ console.error(`Failed to check domain availability: ${stringify(available.error)}`);
92
+ process.exitCode = 1;
93
+ }
94
+ return;
95
+ }
96
+ if (!available.value) {
97
+ console.error(`Repository name "${domain}" is already taken.`);
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+
102
+ const response = await createRepository(domain, name);
103
+ if (!response.ok) {
104
+ if (response.error instanceof ForbiddenRequestError) {
105
+ handleUnauthenticated();
106
+ } else {
107
+ console.error(`Failed to create repository: ${stringify(response.error)}`);
108
+ process.exitCode = 1;
109
+ }
110
+ return;
111
+ }
112
+
113
+ // Create or update config after successful repo creation
114
+ if (!noConfig) {
115
+ if (existingConfig.ok) {
116
+ const result = await updateConfig({ repositoryName: domain });
117
+ if (result.ok) {
118
+ console.info("Updated prismic.config.json");
119
+ } else {
120
+ console.warn("Could not update prismic.config.json: " + result.error.message);
121
+ }
122
+ } else {
123
+ const result = await createConfig({ repositoryName: domain });
124
+ if (result.ok) {
125
+ console.info("Created prismic.config.json");
126
+ } else {
127
+ console.warn("Could not create prismic.config.json: " + result.error.message);
128
+ }
129
+ }
130
+ }
131
+
132
+ console.info(`Repository created: ${domain}`);
133
+ console.info(`URL: ${await getRepoUrl(domain)}`);
134
+
135
+ // Print framework-specific next steps
136
+ const framework = await getFramework();
137
+ if (framework) {
138
+ const docsPath = getDocsPath(framework.id);
139
+ const anchor = getClientSetupAnchor(framework.id);
140
+ const clientFile = await framework.getClientFilePath();
141
+ const fileDesc = clientFile ? `creating ${clientFile}` : "configuring Prismic";
142
+ console.info();
143
+ console.info(`Next: Run \`prismic docs fetch ${docsPath}${anchor}\` for instructions on ${fileDesc}`);
144
+ }
145
+ }
146
+
147
+ async function checkDomainAvailable(domain: string) {
148
+ const url = new URL(`/app/dashboard/repositories/${domain}/exists`, await readHost());
149
+ const response = await request<string>(url);
150
+ if (!response.ok) {
151
+ return response;
152
+ }
153
+ // Endpoint returns "false" when repository exists, "true" when available
154
+ return { ok: true as const, value: response.value === "true" };
155
+ }
156
+
157
+ async function createRepository(domain: string, name = domain) {
158
+ const url = new URL("/app/dashboard/repositories", await readHost());
159
+ return await request(url, {
160
+ method: "POST",
161
+ body: {
162
+ domain,
163
+ name,
164
+ framework: "next",
165
+ plan: "personal",
166
+ usageIntent: "Exploring Prismic's features for future projects.",
167
+ usageIntentIndex: 0,
168
+ },
169
+ });
170
+ }
171
+
172
+ function handleUnauthenticated() {
173
+ console.error("Not logged in. Run `prismic login` first.");
174
+ process.exitCode = 1;
175
+ }
@@ -0,0 +1,86 @@
1
+ import { parseArgs } from "node:util";
2
+ import * as v from "valibot";
3
+
4
+ import { isAuthenticated } from "./lib/auth";
5
+ import { safeGetRepositoryFromConfig } from "./lib/config";
6
+ import { stringify } from "./lib/json";
7
+ import { ForbiddenRequestError, request } from "./lib/request";
8
+ import { getRepoUrl } from "./lib/url";
9
+
10
+ const SyncStateSchema = v.object({
11
+ repository: v.object({
12
+ api_access: v.string(),
13
+ }),
14
+ });
15
+
16
+ const HELP = `
17
+ Get the Content API access level of a Prismic repository.
18
+
19
+ By default, this command reads the repository from prismic.config.json at the
20
+ project root.
21
+
22
+ USAGE
23
+ prismic repo get-access [flags]
24
+
25
+ FLAGS
26
+ -r, --repo string Repository domain
27
+ -h, --help Show help for command
28
+
29
+ LEARN MORE
30
+ Use \`prismic <command> <subcommand> --help\` for more information about a command.
31
+ `.trim();
32
+
33
+ export async function repoGetAccess(): Promise<void> {
34
+ const {
35
+ values: { help, repo = await safeGetRepositoryFromConfig() },
36
+ } = parseArgs({
37
+ args: process.argv.slice(4), // skip: node, script, "repo", "get-access"
38
+ options: {
39
+ repo: { type: "string", short: "r" },
40
+ help: { type: "boolean", short: "h" },
41
+ },
42
+ allowPositionals: true,
43
+ });
44
+
45
+ if (help) {
46
+ console.info(HELP);
47
+ return;
48
+ }
49
+
50
+ if (!repo) {
51
+ console.error("Missing prismic.config.json or --repo option");
52
+ process.exitCode = 1;
53
+ return;
54
+ }
55
+
56
+ const authenticated = await isAuthenticated();
57
+ if (!authenticated) {
58
+ handleUnauthenticated();
59
+ return;
60
+ }
61
+
62
+ const response = await getRepositoryAccess(repo);
63
+ if (!response.ok) {
64
+ if (response.error instanceof ForbiddenRequestError) {
65
+ handleUnauthenticated();
66
+ } else {
67
+ console.error(`Failed to get repository access: ${stringify(response.value)}`);
68
+ process.exitCode = 1;
69
+ }
70
+ return;
71
+ }
72
+
73
+ console.info(response.value.repository.api_access);
74
+ }
75
+
76
+ async function getRepositoryAccess(domain: string) {
77
+ const repoUrl = await getRepoUrl(domain);
78
+ const url = new URL("syncState", repoUrl);
79
+
80
+ return await request(url, { schema: SyncStateSchema });
81
+ }
82
+
83
+ function handleUnauthenticated() {
84
+ console.error("Not logged in. Run `prismic login` first.");
85
+ process.exitCode = 1;
86
+ }
@@ -0,0 +1,100 @@
1
+ import { parseArgs } from "node:util";
2
+ import * as v from "valibot";
3
+
4
+ import { isAuthenticated } from "./lib/auth";
5
+ import { stringify } from "./lib/json";
6
+ import { ForbiddenRequestError, request } from "./lib/request";
7
+ import { getRepoUrl, getUserServiceUrl } from "./lib/url";
8
+
9
+ const HELP = `
10
+ List all Prismic repositories.
11
+
12
+ USAGE
13
+ prismic repo list [flags]
14
+
15
+ FLAGS
16
+ --json Output as JSON
17
+ -h, --help Show help for command
18
+
19
+ LEARN MORE
20
+ Use \`prismic repo <command> --help\` for more information about a command.
21
+ `.trim();
22
+
23
+ const ProfileSchema = v.object({
24
+ repositories: v.array(
25
+ v.object({
26
+ domain: v.string(),
27
+ name: v.optional(v.string()),
28
+ role: v.string(),
29
+ }),
30
+ ),
31
+ });
32
+
33
+ export async function repoList(): Promise<void> {
34
+ const {
35
+ values: { help, json },
36
+ } = parseArgs({
37
+ args: process.argv.slice(4), // skip: node, script, "repo", "list"
38
+ options: {
39
+ help: { type: "boolean", short: "h" },
40
+ json: { type: "boolean" },
41
+ },
42
+ });
43
+
44
+ if (help) {
45
+ console.info(HELP);
46
+ return;
47
+ }
48
+
49
+ const authenticated = await isAuthenticated();
50
+ if (!authenticated) {
51
+ handleUnauthenticated();
52
+ return;
53
+ }
54
+
55
+ const response = await fetchProfile();
56
+ if (!response.ok) {
57
+ if (response.error instanceof ForbiddenRequestError) {
58
+ handleUnauthenticated();
59
+ } else {
60
+ console.error(`Failed to fetch repositories: ${stringify(response.value)}`);
61
+ process.exitCode = 1;
62
+ }
63
+ return;
64
+ }
65
+
66
+ const repos = response.value.repositories;
67
+
68
+ if (json) {
69
+ const output = await Promise.all(
70
+ repos.map(async (repo) => ({
71
+ domain: repo.domain,
72
+ name: repo.name || null,
73
+ role: repo.role,
74
+ url: (await getRepoUrl(repo.domain)).toString(),
75
+ })),
76
+ );
77
+ console.info(stringify(output));
78
+ return;
79
+ }
80
+
81
+ if (repos.length === 0) {
82
+ console.info("No repositories found.");
83
+ return;
84
+ }
85
+
86
+ for (const repo of repos) {
87
+ const name = repo.name || "(no name)";
88
+ console.info(`${repo.domain} ${name} ${repo.role}`);
89
+ }
90
+ }
91
+
92
+ async function fetchProfile(): ReturnType<typeof request<v.InferOutput<typeof ProfileSchema>>> {
93
+ const url = new URL("profile", await getUserServiceUrl());
94
+ return await request(url, { schema: ProfileSchema });
95
+ }
96
+
97
+ function handleUnauthenticated() {
98
+ console.error("Not logged in. Run `prismic login` first.");
99
+ process.exitCode = 1;
100
+ }
@@ -0,0 +1,100 @@
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 VALID_LEVELS = ["private", "public", "open"] as const;
10
+
11
+ const HELP = `
12
+ Set the Content API access level of a Prismic repository.
13
+
14
+ By default, this command reads the repository from prismic.config.json at the
15
+ project root.
16
+
17
+ USAGE
18
+ prismic repo set-access <level> [flags]
19
+
20
+ ARGUMENTS
21
+ <level> The access level to set (private, public, open)
22
+
23
+ FLAGS
24
+ -r, --repo string Repository domain
25
+ -h, --help Show help for command
26
+
27
+ LEARN MORE
28
+ Use \`prismic <command> <subcommand> --help\` for more information about a command.
29
+ `.trim();
30
+
31
+ export async function repoSetAccess(): Promise<void> {
32
+ const {
33
+ values: { help, repo = await safeGetRepositoryFromConfig() },
34
+ positionals: [level],
35
+ } = parseArgs({
36
+ args: process.argv.slice(4), // skip: node, script, "repo", "set-access"
37
+ options: {
38
+ repo: { type: "string", short: "r" },
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 (!level) {
50
+ console.error("Missing required argument: <level>");
51
+ process.exitCode = 1;
52
+ return;
53
+ }
54
+
55
+ if (!VALID_LEVELS.includes(level as (typeof VALID_LEVELS)[number])) {
56
+ console.error(`Invalid access level: ${level}. Must be one of: ${VALID_LEVELS.join(", ")}`);
57
+ process.exitCode = 1;
58
+ return;
59
+ }
60
+
61
+ if (!repo) {
62
+ console.error("Missing prismic.config.json or --repo option");
63
+ process.exitCode = 1;
64
+ return;
65
+ }
66
+
67
+ const authenticated = await isAuthenticated();
68
+ if (!authenticated) {
69
+ handleUnauthenticated();
70
+ return;
71
+ }
72
+
73
+ const response = await setRepositoryAccess(repo, level);
74
+ if (!response.ok) {
75
+ if (response.error instanceof ForbiddenRequestError) {
76
+ handleUnauthenticated();
77
+ } else {
78
+ console.error(`Failed to set repository access: ${stringify(response.value)}`);
79
+ process.exitCode = 1;
80
+ }
81
+ return;
82
+ }
83
+
84
+ console.info(`Repository access set to: ${level}`);
85
+ }
86
+
87
+ async function setRepositoryAccess(domain: string, level: string) {
88
+ const repoUrl = await getRepoUrl(domain);
89
+ const url = new URL("settings/security/apiaccess", repoUrl);
90
+
91
+ return await request(url, {
92
+ method: "POST",
93
+ body: { api_access: level },
94
+ });
95
+ }
96
+
97
+ function handleUnauthenticated() {
98
+ console.error("Not logged in. Run `prismic login` first.");
99
+ process.exitCode = 1;
100
+ }
@@ -0,0 +1,102 @@
1
+ import { parseArgs } from "node:util";
2
+ import * as v from "valibot";
3
+
4
+ import { isAuthenticated } from "./lib/auth";
5
+ import { safeGetRepositoryFromConfig } from "./lib/config";
6
+ import { stringify } from "./lib/json";
7
+ import { ForbiddenRequestError, request } from "./lib/request";
8
+ import { getRepoUrl } from "./lib/url";
9
+
10
+ const HELP = `
11
+ Set the display name of a Prismic repository.
12
+
13
+ By default, this command reads the repository from prismic.config.json at the
14
+ project root.
15
+
16
+ USAGE
17
+ prismic repo set-name <name> [flags]
18
+
19
+ ARGUMENTS
20
+ <name> The new display name for the repository
21
+
22
+ FLAGS
23
+ -r, --repo string Repository domain
24
+ -h, --help Show help for command
25
+
26
+ LEARN MORE
27
+ Use \`prismic <command> <subcommand> --help\` for more information about a command.
28
+ `.trim();
29
+
30
+ export async function repoSetName(): Promise<void> {
31
+ const {
32
+ values: { help, repo = await safeGetRepositoryFromConfig() },
33
+ positionals: [displayName],
34
+ } = parseArgs({
35
+ args: process.argv.slice(4), // skip: node, script, "repo", "set-name"
36
+ options: {
37
+ repo: { type: "string", short: "r" },
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 (!displayName) {
49
+ console.error("Missing required argument: <name>");
50
+ process.exitCode = 1;
51
+ return;
52
+ }
53
+
54
+ if (!repo) {
55
+ console.error("Missing prismic.config.json or --repo option");
56
+ process.exitCode = 1;
57
+ return;
58
+ }
59
+
60
+ const authenticated = await isAuthenticated();
61
+ if (!authenticated) {
62
+ handleUnauthenticated();
63
+ return;
64
+ }
65
+
66
+ const response = await setRepositoryName(repo, displayName);
67
+ if (!response.ok) {
68
+ if (response.error instanceof ForbiddenRequestError) {
69
+ handleUnauthenticated();
70
+ } else if (v.isValiError(response.error)) {
71
+ console.error(
72
+ `Failed to set repository name: Invalid response: ${stringify(response.error.issues)}`,
73
+ );
74
+ process.exitCode = 1;
75
+ } else {
76
+ console.error(`Failed to set repository name: ${stringify(response.value)}`);
77
+ process.exitCode = 1;
78
+ }
79
+ return;
80
+ }
81
+
82
+ console.info(`Repository name set to: ${response.value.repository.name}`);
83
+ }
84
+
85
+ async function setRepositoryName(domain: string, displayName: string) {
86
+ const repoUrl = await getRepoUrl(domain);
87
+ const url = new URL("app/settings/repository", repoUrl);
88
+
89
+ const formData = new FormData();
90
+ formData.set("displayname", displayName);
91
+
92
+ return await request(url, {
93
+ method: "POST",
94
+ body: formData,
95
+ schema: v.object({ repository: v.object({ name: v.string() }) }),
96
+ });
97
+ }
98
+
99
+ function handleUnauthenticated() {
100
+ console.error("Not logged in. Run `prismic login` first.");
101
+ process.exitCode = 1;
102
+ }
@@ -0,0 +1,113 @@
1
+ import { exec } from "node:child_process";
2
+ import { parseArgs } from "node:util";
3
+ import * as v from "valibot";
4
+
5
+ import { isAuthenticated } from "./lib/auth";
6
+ import { safeGetRepositoryFromConfig } from "./lib/config";
7
+ import { stringify } from "./lib/json";
8
+ import { ForbiddenRequestError, request } from "./lib/request";
9
+ import { getRepoUrl, getUserServiceUrl } from "./lib/url";
10
+
11
+ const HELP = `
12
+ View a Prismic repository.
13
+
14
+ By default, this command reads the repository from prismic.config.json at the
15
+ project root.
16
+
17
+ USAGE
18
+ prismic repo view [flags]
19
+
20
+ FLAGS
21
+ -w, --web Open repository in browser
22
+ -r, --repo string Repository domain
23
+ -h, --help Show help for command
24
+
25
+ LEARN MORE
26
+ Use \`prismic <command> <subcommand> --help\` for more information about a command.
27
+ `.trim();
28
+
29
+ const ProfileSchema = v.object({
30
+ repositories: v.array(
31
+ v.object({
32
+ domain: v.string(),
33
+ name: v.optional(v.string()),
34
+ }),
35
+ ),
36
+ });
37
+
38
+ export async function repoView(): Promise<void> {
39
+ const {
40
+ values: { help, repo = await safeGetRepositoryFromConfig(), web },
41
+ } = parseArgs({
42
+ args: process.argv.slice(4), // skip: node, script, "repo", "view"
43
+ options: {
44
+ web: { type: "boolean", short: "w" },
45
+ repo: { type: "string", short: "r" },
46
+ help: { type: "boolean", short: "h" },
47
+ },
48
+ });
49
+
50
+ if (help) {
51
+ console.info(HELP);
52
+ return;
53
+ }
54
+
55
+ if (!repo) {
56
+ console.error("Missing prismic.config.json or --repo option");
57
+ process.exitCode = 1;
58
+ return;
59
+ }
60
+
61
+ const repoUrl = await getRepoUrl(repo);
62
+
63
+ if (web) {
64
+ openInBrowser(repoUrl.toString());
65
+ console.info(`Opening ${repoUrl}`);
66
+ return;
67
+ }
68
+
69
+ const authenticated = await isAuthenticated();
70
+ if (!authenticated) {
71
+ handleUnauthenticated();
72
+ return;
73
+ }
74
+
75
+ const response = await fetchProfile();
76
+ if (!response.ok) {
77
+ if (response.error instanceof ForbiddenRequestError) {
78
+ handleUnauthenticated();
79
+ } else {
80
+ console.error(`Failed to fetch repository info: ${stringify(response.value)}`);
81
+ process.exitCode = 1;
82
+ }
83
+ return;
84
+ }
85
+
86
+ const repoData = response.value.repositories.find((r) => r.domain === repo);
87
+ if (!repoData) {
88
+ console.error(`Repository not found: ${repo}`);
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+
93
+ const name = repoData.name || "(no name)";
94
+ console.info(`Name: ${name}`);
95
+ console.info(`URL: ${repoUrl}`);
96
+ }
97
+
98
+ async function fetchProfile(): ReturnType<typeof request<v.InferOutput<typeof ProfileSchema>>> {
99
+ const url = new URL("profile", await getUserServiceUrl());
100
+ return await request(url, { schema: ProfileSchema });
101
+ }
102
+
103
+ function openInBrowser(url: string): void {
104
+ const cmd =
105
+ process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
106
+
107
+ exec(`${cmd} "${url}"`);
108
+ }
109
+
110
+ function handleUnauthenticated() {
111
+ console.error("Not logged in. Run `prismic login` first.");
112
+ process.exitCode = 1;
113
+ }