prismic 1.1.0 → 1.2.0

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 (48) hide show
  1. package/dist/{builders-hKD4IrLX-ClhMQQkN.mjs → builders-hKD4IrLX-BrpqCAS2.mjs} +1 -1
  2. package/dist/index.mjs +115 -101
  3. package/dist/nextjs-HiDO_p-p.mjs +318 -0
  4. package/dist/nuxt-CDrqbn0o.mjs +59 -0
  5. package/dist/string-BUjs_2AH.mjs +7 -0
  6. package/dist/{sveltekit-BMDXAfYz.mjs → sveltekit-Qx8xJZOd.mjs} +45 -35
  7. package/package.json +1 -1
  8. package/src/adapters/index.ts +177 -0
  9. package/src/{frameworks → adapters}/nextjs.templates.ts +102 -102
  10. package/src/adapters/nextjs.ts +211 -0
  11. package/src/adapters/nuxt.ts +232 -0
  12. package/src/adapters/sveltekit.ts +226 -0
  13. package/src/clients/core.ts +104 -0
  14. package/src/clients/wroom.ts +111 -0
  15. package/src/commands/init.ts +57 -69
  16. package/src/commands/login.ts +12 -29
  17. package/src/commands/logout.ts +8 -28
  18. package/src/commands/preview-add.ts +57 -0
  19. package/src/commands/preview-list.ts +54 -0
  20. package/src/commands/preview-remove.ts +51 -0
  21. package/src/commands/preview-set-simulator.ts +60 -0
  22. package/src/commands/preview.ts +28 -0
  23. package/src/commands/sync.ts +49 -87
  24. package/src/commands/webhook-create.ts +89 -0
  25. package/src/commands/webhook-disable.ts +60 -0
  26. package/src/commands/webhook-enable.ts +60 -0
  27. package/src/commands/webhook-list.ts +43 -0
  28. package/src/commands/webhook-remove.ts +52 -0
  29. package/src/commands/webhook-set-triggers.ts +93 -0
  30. package/src/commands/webhook-view.ts +65 -0
  31. package/src/commands/webhook.ts +43 -0
  32. package/src/commands/whoami.ts +7 -28
  33. package/src/config.ts +2 -11
  34. package/src/index.ts +122 -105
  35. package/src/lib/command.ts +188 -0
  36. package/src/lib/file.ts +13 -1
  37. package/src/lib/packageJson.ts +70 -1
  38. package/src/lib/segment.ts +26 -30
  39. package/src/project.ts +54 -0
  40. package/dist/frameworks-DtGBrEuY.mjs +0 -17
  41. package/dist/nextjs-2qjzSaQI.mjs +0 -312
  42. package/dist/nuxt-DKsgbqpV.mjs +0 -59
  43. package/src/frameworks/index.ts +0 -398
  44. package/src/frameworks/nextjs.ts +0 -211
  45. package/src/frameworks/nuxt.ts +0 -252
  46. package/src/frameworks/sveltekit.ts +0 -234
  47. /package/src/{frameworks → adapters}/nuxt.templates.ts +0 -0
  48. /package/src/{frameworks → adapters}/sveltekit.templates.ts +0 -0
@@ -0,0 +1,93 @@
1
+ import { getHost, getToken } from "../auth";
2
+ import { getWebhooks, updateWebhook, WEBHOOK_TRIGGERS } from "../clients/wroom";
3
+ import { CommandError, createCommand, type CommandConfig } from "../lib/command";
4
+ import { UnknownRequestError } from "../lib/request";
5
+ import { getRepositoryName } from "../project";
6
+
7
+ const config = {
8
+ name: "prismic webhook set-triggers",
9
+ description: `
10
+ Update which events trigger a webhook.
11
+
12
+ By default, this command reads the repository from prismic.config.json at the
13
+ project root.
14
+ `,
15
+ positionals: {
16
+ url: { description: "Webhook URL" },
17
+ },
18
+ options: {
19
+ trigger: {
20
+ type: "string",
21
+ multiple: true,
22
+ short: "t",
23
+ description: "Trigger events (can be repeated, at least one required)",
24
+ },
25
+ repo: { type: "string", short: "r", description: "Repository domain" },
26
+ },
27
+ sections: {
28
+ TRIGGERS: `
29
+ documentsPublished When documents are published
30
+ documentsUnpublished When documents are unpublished
31
+ releasesCreated When a release is created
32
+ releasesUpdated When a release is edited or deleted
33
+ tagsCreated When a tag is created
34
+ tagsDeleted When a tag is deleted
35
+ `,
36
+ },
37
+ } satisfies CommandConfig;
38
+
39
+ export default createCommand(config, async ({ positionals, values }) => {
40
+ const [webhookUrl] = positionals;
41
+ const { repo = await getRepositoryName(), trigger = [] } = values;
42
+
43
+ if (!webhookUrl) {
44
+ throw new CommandError("Missing required argument: <url>");
45
+ }
46
+
47
+ if (trigger.length === 0) {
48
+ throw new CommandError("Missing required option: --trigger");
49
+ }
50
+
51
+ // Validate triggers
52
+ for (const t of trigger) {
53
+ if (!WEBHOOK_TRIGGERS.includes(t)) {
54
+ throw new CommandError(
55
+ `Invalid trigger: ${t}\nValid triggers: ${WEBHOOK_TRIGGERS.join(", ")}`,
56
+ );
57
+ }
58
+ }
59
+
60
+ const token = await getToken();
61
+ const host = await getHost();
62
+ const webhooks = await getWebhooks({ repo, token, host });
63
+ const webhook = webhooks.find((w) => w.config.url === webhookUrl);
64
+ if (!webhook) {
65
+ throw new CommandError(`Webhook not found: ${webhookUrl}`);
66
+ }
67
+
68
+ const id = webhook.config._id;
69
+
70
+ try {
71
+ await updateWebhook(
72
+ id,
73
+ {
74
+ ...webhook.config,
75
+ documentsPublished: trigger.includes("documentsPublished"),
76
+ documentsUnpublished: trigger.includes("documentsUnpublished"),
77
+ releasesCreated: trigger.includes("releasesCreated"),
78
+ releasesUpdated: trigger.includes("releasesUpdated"),
79
+ tagsCreated: trigger.includes("tagsCreated"),
80
+ tagsDeleted: trigger.includes("tagsDeleted"),
81
+ },
82
+ { repo, token, host },
83
+ );
84
+ } catch (error) {
85
+ if (error instanceof UnknownRequestError) {
86
+ const message = await error.text();
87
+ throw new CommandError(`Failed to update webhook triggers: ${message}`);
88
+ }
89
+ throw error;
90
+ }
91
+
92
+ console.info(`Webhook triggers updated: ${trigger.join(", ")}`);
93
+ });
@@ -0,0 +1,65 @@
1
+ import { getHost, getToken } from "../auth";
2
+ import { getWebhooks, WEBHOOK_TRIGGERS } from "../clients/wroom";
3
+ import { CommandError, createCommand, type CommandConfig } from "../lib/command";
4
+ import { getRepositoryName } from "../project";
5
+
6
+ const config = {
7
+ name: "prismic webhook view",
8
+ description: `
9
+ View details of a webhook in a Prismic repository.
10
+
11
+ By default, this command reads the repository from prismic.config.json at the
12
+ project root.
13
+ `,
14
+ positionals: {
15
+ url: { description: "Webhook URL" },
16
+ },
17
+ options: {
18
+ repo: { type: "string", short: "r", description: "Repository domain" },
19
+ },
20
+ } satisfies CommandConfig;
21
+
22
+ export default createCommand(config, async ({ positionals, values }) => {
23
+ const [webhookUrl] = positionals;
24
+ const { repo = await getRepositoryName() } = values;
25
+
26
+ if (!webhookUrl) {
27
+ throw new CommandError("Missing required argument: <url>");
28
+ }
29
+
30
+ const token = await getToken();
31
+ const host = await getHost();
32
+ const webhooks = await getWebhooks({ repo, token, host });
33
+
34
+ const webhook = webhooks.find((webhook) => webhook.config.url === webhookUrl);
35
+ if (!webhook) {
36
+ throw new CommandError(`Webhook not found: ${webhookUrl}`);
37
+ }
38
+
39
+ const { config: webhookConfig } = webhook;
40
+
41
+ console.info(`URL: ${webhookConfig.url}`);
42
+ console.info(`Name: ${webhookConfig.name || "(none)"}`);
43
+ console.info(`Status: ${webhookConfig.active ? "enabled" : "disabled"}`);
44
+ console.info(`Secret: ${webhookConfig.secret ? "(set)" : "(none)"}`);
45
+
46
+ // Show triggers
47
+ const enabledTriggers: string[] = [];
48
+ for (const trigger of WEBHOOK_TRIGGERS) {
49
+ if (webhookConfig[trigger as keyof typeof webhookConfig]) {
50
+ enabledTriggers.push(trigger);
51
+ }
52
+ }
53
+ console.info(`Triggers: ${enabledTriggers.length > 0 ? enabledTriggers.join(", ") : "(none)"}`);
54
+
55
+ // Show headers
56
+ const headerKeys = Object.keys(webhookConfig.headers);
57
+ if (headerKeys.length > 0) {
58
+ console.info("Headers:");
59
+ for (const [key, value] of Object.entries(webhookConfig.headers)) {
60
+ console.info(` ${key}: ${value}`);
61
+ }
62
+ } else {
63
+ console.info("Headers: (none)");
64
+ }
65
+ });
@@ -0,0 +1,43 @@
1
+ import { createCommandRouter } from "../lib/command";
2
+ import webhookCreate from "./webhook-create";
3
+ import webhookDisable from "./webhook-disable";
4
+ import webhookEnable from "./webhook-enable";
5
+ import webhookList from "./webhook-list";
6
+ import webhookRemove from "./webhook-remove";
7
+ import webhookSetTriggers from "./webhook-set-triggers";
8
+ import webhookView from "./webhook-view";
9
+
10
+ export default createCommandRouter({
11
+ name: "prismic webhook",
12
+ description: "Manage webhooks in a Prismic repository.",
13
+ commands: {
14
+ list: {
15
+ handler: webhookList,
16
+ description: "List all webhooks",
17
+ },
18
+ create: {
19
+ handler: webhookCreate,
20
+ description: "Create a new webhook",
21
+ },
22
+ view: {
23
+ handler: webhookView,
24
+ description: "View webhook details",
25
+ },
26
+ remove: {
27
+ handler: webhookRemove,
28
+ description: "Delete a webhook",
29
+ },
30
+ enable: {
31
+ handler: webhookEnable,
32
+ description: "Enable a webhook",
33
+ },
34
+ disable: {
35
+ handler: webhookDisable,
36
+ description: "Disable a webhook",
37
+ },
38
+ "set-triggers": {
39
+ handler: webhookSetTriggers,
40
+ description: "Update webhook triggers",
41
+ },
42
+ },
43
+ });
@@ -1,37 +1,16 @@
1
- import { parseArgs } from "node:util";
2
-
3
1
  import { getHost, getToken } from "../auth";
4
2
  import { getProfile } from "../clients/user";
3
+ import { createCommand, type CommandConfig } from "../lib/command";
5
4
 
6
- const HELP = `
7
- Show the currently logged in user.
8
-
9
- USAGE
10
- prismic whoami [flags]
11
-
12
- FLAGS
13
- -h, --help Show help for command
14
-
15
- LEARN MORE
16
- Use \`prismic <command> --help\` for more information about a command.
17
- `.trim();
18
-
19
- export async function whoami(): Promise<void> {
20
- const {
21
- values: { help },
22
- } = parseArgs({
23
- args: process.argv.slice(3),
24
- options: { help: { type: "boolean", short: "h" } },
25
- });
26
-
27
- if (help) {
28
- console.info(HELP);
29
- return;
30
- }
5
+ const config = {
6
+ name: "prismic whoami",
7
+ description: "Show the currently logged in user.",
8
+ } satisfies CommandConfig;
31
9
 
10
+ export default createCommand(config, async () => {
32
11
  const token = await getToken();
33
12
  const host = await getHost();
34
13
  const profile = await getProfile({ token, host });
35
14
 
36
15
  console.info(profile.email);
37
- }
16
+ });
package/src/config.ts CHANGED
@@ -26,15 +26,6 @@ export async function createConfig(config: Config): Promise<URL> {
26
26
  return suggestedConfigPath;
27
27
  }
28
28
 
29
- export async function safeGetRepositoryFromConfig(): Promise<string | undefined> {
30
- try {
31
- const config = await readConfig();
32
- return config.repositoryName;
33
- } catch {
34
- return undefined;
35
- }
36
- }
37
-
38
29
  export async function readConfig(): Promise<Config> {
39
30
  const configPath = await findConfigPath();
40
31
  try {
@@ -68,7 +59,7 @@ export async function updateConfig(updates: Partial<Config>): Promise<Config> {
68
59
  return updatedConfig;
69
60
  }
70
61
 
71
- async function findConfigPath(): Promise<URL> {
62
+ export async function findConfigPath(): Promise<URL> {
72
63
  const configPath = await findUpward(CONFIG_FILENAME, { stop: "package.json" });
73
64
  if (!configPath) throw new MissingPrismicConfig();
74
65
  return configPath;
@@ -79,7 +70,7 @@ export class MissingPrismicConfig extends Error {
79
70
  message = `Could not find a ${CONFIG_FILENAME} file.`;
80
71
  }
81
72
 
82
- async function findSuggestedConfigPath() {
73
+ export async function findSuggestedConfigPath(): Promise<URL> {
83
74
  try {
84
75
  const packageJsonPath = await findPackageJson();
85
76
  const suggestedConfigPath = new URL(CONFIG_FILENAME, packageJsonPath);
package/src/index.ts CHANGED
@@ -3,15 +3,18 @@
3
3
  import { parseArgs } from "node:util";
4
4
 
5
5
  import packageJson from "../package.json" with { type: "json" };
6
+ import { getAdapter, NoSupportedFrameworkError } from "./adapters";
6
7
  import { getHost, refreshToken } from "./auth";
7
8
  import { getProfile } from "./clients/user";
8
- import { init } from "./commands/init";
9
- import { login } from "./commands/login";
10
- import { logout } from "./commands/logout";
11
- import { sync } from "./commands/sync";
12
- import { whoami } from "./commands/whoami";
13
- import { InvalidPrismicConfig, MissingPrismicConfig, safeGetRepositoryFromConfig } from "./config";
14
- import { getFramework } from "./frameworks";
9
+ import init from "./commands/init";
10
+ import login from "./commands/login";
11
+ import logout from "./commands/logout";
12
+ import preview from "./commands/preview";
13
+ import sync from "./commands/sync";
14
+ import webhook from "./commands/webhook";
15
+ import whoami from "./commands/whoami";
16
+ import { InvalidPrismicConfig, MissingPrismicConfig } from "./config";
17
+ import { CommandError, createCommandRouter } from "./lib/command";
15
18
  import { ForbiddenRequestError, UnauthorizedRequestError } from "./lib/request";
16
19
  import {
17
20
  initSegment,
@@ -27,124 +30,138 @@ import {
27
30
  sentrySetUser,
28
31
  setupSentry,
29
32
  } from "./lib/sentry";
30
-
31
- const HELP = `
32
- Prismic CLI for managing repositories and configurations.
33
-
34
- USAGE
35
- prismic <command> [flags]
36
-
37
- COMMANDS
38
- init Initialize a Prismic project
39
- sync Sync types and slices from Prismic
40
- login Log in to Prismic
41
- logout Log out of Prismic
42
- whoami Show the currently logged in user
43
-
44
- FLAGS
45
- -v, --version Show CLI version
46
- -h, --help Show help for command
47
-
48
- LEARN MORE
49
- Use \`prismic <command> --help\` for more information about a command.
50
- `.trim();
51
-
52
- const UNTRACKED_COMMANDS = new Set(["login", "logout", "whoami", "sync"]);
53
- const SKIP_REFRESH_COMMANDS = new Set(["login", "logout"]);
54
-
55
- const {
56
- positionals,
57
- values: { version, help },
58
- } = parseArgs({
59
- options: {
60
- help: { type: "boolean", short: "h" },
61
- version: { type: "boolean", short: "v" },
33
+ import { safeGetRepositoryName } from "./project";
34
+
35
+ const UNTRACKED_COMMANDS = ["login", "logout", "whoami", "sync"];
36
+ const SKIP_REFRESH_COMMANDS = ["login", "logout"];
37
+
38
+ const router = createCommandRouter({
39
+ name: "prismic",
40
+ description: "Prismic CLI for managing repositories and configurations.",
41
+ commands: {
42
+ init: {
43
+ handler: init,
44
+ description: "Initialize a Prismic project",
45
+ },
46
+ sync: {
47
+ handler: sync,
48
+ description: "Sync types and slices from Prismic",
49
+ },
50
+ preview: {
51
+ handler: preview,
52
+ description: "Manage preview configurations",
53
+ },
54
+ webhook: {
55
+ handler: webhook,
56
+ description: "Manage webhooks",
57
+ },
58
+ login: {
59
+ handler: login,
60
+ description: "Log in to Prismic",
61
+ },
62
+ logout: {
63
+ handler: logout,
64
+ description: "Log out of Prismic",
65
+ },
66
+ whoami: {
67
+ handler: whoami,
68
+ description: "Show the currently logged in user",
69
+ },
62
70
  },
63
- allowPositionals: true,
64
- strict: false,
65
71
  });
66
72
 
67
- setupSentry();
68
- await initSegment();
73
+ await main();
74
+
75
+ async function main(): Promise<void> {
76
+ let {
77
+ positionals: [command],
78
+ values: { version, help, repo = await safeGetRepositoryName() },
79
+ } = parseArgs({
80
+ options: {
81
+ version: { type: "boolean", short: "v" },
82
+ help: { type: "boolean", short: "h" },
83
+ repo: { type: "string", short: "r" },
84
+ },
85
+ allowPositionals: true,
86
+ strict: false,
87
+ });
88
+
89
+ if (version) {
90
+ console.info(packageJson.version);
91
+ return;
92
+ }
69
93
 
70
- if (version) {
71
- console.info(packageJson.version);
72
- } else {
73
- const command = positionals[0];
94
+ if (typeof repo !== "string") repo = "";
74
95
 
75
- const repository = await safeGetRepositoryFromConfig();
76
- if (repository) {
77
- segmentSetRepository(repository);
78
- sentrySetTag("repository", repository);
79
- sentrySetContext("Repository Data", { name: repository });
80
- }
96
+ if (!help) {
97
+ setupSentry();
98
+ await initSegment();
81
99
 
82
- const framework = await getFramework();
83
- if (framework) {
84
- sentrySetTag("framework", framework.id);
85
- }
100
+ if (repo) {
101
+ segmentSetRepository(repo);
102
+ sentrySetTag("repository", repo);
103
+ sentrySetContext("Repository Data", { name: repo });
104
+ }
86
105
 
87
- if (command && !help && !SKIP_REFRESH_COMMANDS.has(command)) {
88
- // Refreesh the token and identify the user in the background.
89
- refreshToken()
90
- .then(async (token) => {
91
- if (!token) return;
92
- const host = await getHost();
93
- const profile = await getProfile({ token, host });
94
- segmentIdentify({ shortId: profile.shortId, intercomHash: profile.intercomHash });
95
- sentrySetUser({ id: profile.shortId });
96
- })
97
- .catch(() => {});
98
- }
106
+ try {
107
+ const adapter = await getAdapter();
108
+ sentrySetTag("framework", adapter.id);
109
+ } catch {
110
+ // noop - it's okay if we can't set the framework
111
+ }
112
+
113
+ if (command && !SKIP_REFRESH_COMMANDS.includes(command)) {
114
+ // Refresh the token and identify the user in the background.
115
+ refreshToken()
116
+ .then(async (token) => {
117
+ if (!token) return;
118
+ const host = await getHost();
119
+ const profile = await getProfile({ token, host });
120
+ segmentIdentify({ shortId: profile.shortId, intercomHash: profile.intercomHash });
121
+ sentrySetUser({ id: profile.shortId });
122
+ })
123
+ .catch(() => {});
124
+ }
99
125
 
100
- if (command && !UNTRACKED_COMMANDS.has(command)) {
101
- segmentTrackStart(command, { repository });
126
+ if (command && !UNTRACKED_COMMANDS.includes(command)) {
127
+ segmentTrackStart(command);
128
+ }
102
129
  }
103
130
 
104
131
  try {
105
- switch (command) {
106
- case "init":
107
- await init();
108
- break;
109
- case "sync":
110
- await sync();
111
- break;
112
- case "login":
113
- await login();
114
- break;
115
- case "logout":
116
- await logout();
117
- break;
118
- case "whoami":
119
- await whoami();
120
- break;
121
- default: {
122
- if (command) {
123
- console.error(`Unknown command: ${command}`);
124
- process.exitCode = 1;
125
- }
126
- console.info(HELP);
127
- }
128
- }
132
+ await router();
129
133
 
130
- if (command && !UNTRACKED_COMMANDS.has(command)) {
131
- segmentTrackEnd(command, process.exitCode !== 1);
134
+ if (command && !UNTRACKED_COMMANDS.includes(command)) {
135
+ segmentTrackEnd(command);
132
136
  }
133
137
  } catch (error) {
134
- if (command && !UNTRACKED_COMMANDS.has(command)) {
135
- segmentTrackEnd(command, false, error);
136
- }
137
138
  process.exitCode = 1;
138
139
 
140
+ if (!UNTRACKED_COMMANDS.includes(command)) {
141
+ segmentTrackEnd(command, { error });
142
+ }
143
+
144
+ if (error instanceof CommandError || error instanceof NoSupportedFrameworkError) {
145
+ console.error(error.message);
146
+ return;
147
+ }
148
+
139
149
  if (error instanceof UnauthorizedRequestError || error instanceof ForbiddenRequestError) {
140
150
  console.error("Not logged in. Run `prismic login` first.");
141
- } else if (error instanceof InvalidPrismicConfig) {
151
+ return;
152
+ }
153
+
154
+ if (error instanceof InvalidPrismicConfig) {
142
155
  console.error(`${error.message} Run \`prismic init\` to re-create a config.`);
143
- } else if (error instanceof MissingPrismicConfig) {
156
+ return;
157
+ }
158
+
159
+ if (error instanceof MissingPrismicConfig) {
144
160
  console.error(`${error.message} Run \`prismic init\` to create a config.`);
145
- } else {
146
- await sentryCaptureError(error);
147
- throw error;
161
+ return;
148
162
  }
163
+
164
+ await sentryCaptureError(error);
165
+ throw error;
149
166
  }
150
167
  }