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.
- package/dist/{builders-hKD4IrLX-ClhMQQkN.mjs → builders-hKD4IrLX-BrpqCAS2.mjs} +1 -1
- package/dist/index.mjs +115 -101
- package/dist/nextjs-HiDO_p-p.mjs +318 -0
- package/dist/nuxt-CDrqbn0o.mjs +59 -0
- package/dist/string-BUjs_2AH.mjs +7 -0
- package/dist/{sveltekit-BMDXAfYz.mjs → sveltekit-Qx8xJZOd.mjs} +45 -35
- package/package.json +1 -1
- package/src/adapters/index.ts +177 -0
- package/src/{frameworks → adapters}/nextjs.templates.ts +102 -102
- package/src/adapters/nextjs.ts +211 -0
- package/src/adapters/nuxt.ts +232 -0
- package/src/adapters/sveltekit.ts +226 -0
- package/src/clients/core.ts +104 -0
- package/src/clients/wroom.ts +111 -0
- package/src/commands/init.ts +57 -69
- package/src/commands/login.ts +12 -29
- package/src/commands/logout.ts +8 -28
- package/src/commands/preview-add.ts +57 -0
- package/src/commands/preview-list.ts +54 -0
- package/src/commands/preview-remove.ts +51 -0
- package/src/commands/preview-set-simulator.ts +60 -0
- package/src/commands/preview.ts +28 -0
- package/src/commands/sync.ts +49 -87
- package/src/commands/webhook-create.ts +89 -0
- package/src/commands/webhook-disable.ts +60 -0
- package/src/commands/webhook-enable.ts +60 -0
- package/src/commands/webhook-list.ts +43 -0
- package/src/commands/webhook-remove.ts +52 -0
- package/src/commands/webhook-set-triggers.ts +93 -0
- package/src/commands/webhook-view.ts +65 -0
- package/src/commands/webhook.ts +43 -0
- package/src/commands/whoami.ts +7 -28
- package/src/config.ts +2 -11
- package/src/index.ts +122 -105
- package/src/lib/command.ts +188 -0
- package/src/lib/file.ts +13 -1
- package/src/lib/packageJson.ts +70 -1
- package/src/lib/segment.ts +26 -30
- package/src/project.ts +54 -0
- package/dist/frameworks-DtGBrEuY.mjs +0 -17
- package/dist/nextjs-2qjzSaQI.mjs +0 -312
- package/dist/nuxt-DKsgbqpV.mjs +0 -59
- package/src/frameworks/index.ts +0 -398
- package/src/frameworks/nextjs.ts +0 -211
- package/src/frameworks/nuxt.ts +0 -252
- package/src/frameworks/sveltekit.ts +0 -234
- /package/src/{frameworks → adapters}/nuxt.templates.ts +0 -0
- /package/src/{frameworks → adapters}/sveltekit.templates.ts +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
|
|
3
|
+
import { request } from "../lib/request";
|
|
4
|
+
|
|
5
|
+
const PreviewSchema = z.object({
|
|
6
|
+
id: z.string(),
|
|
7
|
+
label: z.string(),
|
|
8
|
+
url: z.string(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const GetPreviewsResponseSchema = z.object({
|
|
12
|
+
results: z.array(PreviewSchema),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type Preview = z.infer<typeof PreviewSchema>;
|
|
16
|
+
|
|
17
|
+
export async function getPreviews(config: {
|
|
18
|
+
repo: string;
|
|
19
|
+
token: string | undefined;
|
|
20
|
+
host: string;
|
|
21
|
+
}): Promise<Preview[]> {
|
|
22
|
+
const { repo, token, host } = config;
|
|
23
|
+
const url = new URL(
|
|
24
|
+
"core/repository/preview_configs",
|
|
25
|
+
getCoreBaseUrl(repo, host),
|
|
26
|
+
);
|
|
27
|
+
const response = await request(url, {
|
|
28
|
+
credentials: { "prismic-auth": token },
|
|
29
|
+
schema: GetPreviewsResponseSchema,
|
|
30
|
+
});
|
|
31
|
+
return response.results;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function addPreview(
|
|
35
|
+
previewConfig: {
|
|
36
|
+
name: string;
|
|
37
|
+
websiteURL: string;
|
|
38
|
+
resolverPath: string | undefined;
|
|
39
|
+
},
|
|
40
|
+
config: { repo: string; token: string | undefined; host: string },
|
|
41
|
+
): Promise<void> {
|
|
42
|
+
const { repo, token, host } = config;
|
|
43
|
+
const url = new URL("previews/new", getCoreBaseUrl(repo, host));
|
|
44
|
+
await request(url, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
body: {
|
|
47
|
+
name: previewConfig.name,
|
|
48
|
+
websiteURL: previewConfig.websiteURL,
|
|
49
|
+
resolverPath: previewConfig.resolverPath,
|
|
50
|
+
},
|
|
51
|
+
credentials: { "prismic-auth": token },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function removePreview(
|
|
56
|
+
id: string,
|
|
57
|
+
config: { repo: string; token: string | undefined; host: string },
|
|
58
|
+
): Promise<void> {
|
|
59
|
+
const { repo, token, host } = config;
|
|
60
|
+
const url = new URL(
|
|
61
|
+
`previews/delete/${id}`,
|
|
62
|
+
getCoreBaseUrl(repo, host),
|
|
63
|
+
);
|
|
64
|
+
await request(url, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
body: {},
|
|
67
|
+
credentials: { "prismic-auth": token },
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const RepositoryResponseSchema = z.object({
|
|
72
|
+
simulator_url: z.optional(z.string()),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
export async function getSimulatorUrl(config: {
|
|
76
|
+
repo: string;
|
|
77
|
+
token: string | undefined;
|
|
78
|
+
host: string;
|
|
79
|
+
}): Promise<string | undefined> {
|
|
80
|
+
const { repo, token, host } = config;
|
|
81
|
+
const url = new URL("core/repository", getCoreBaseUrl(repo, host));
|
|
82
|
+
const response = await request(url, {
|
|
83
|
+
credentials: { "prismic-auth": token },
|
|
84
|
+
schema: RepositoryResponseSchema,
|
|
85
|
+
});
|
|
86
|
+
return response.simulator_url;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function setSimulatorUrl(
|
|
90
|
+
simulatorUrl: string,
|
|
91
|
+
config: { repo: string; token: string | undefined; host: string },
|
|
92
|
+
): Promise<void> {
|
|
93
|
+
const { repo, token, host } = config;
|
|
94
|
+
const url = new URL("core/repository", getCoreBaseUrl(repo, host));
|
|
95
|
+
await request(url, {
|
|
96
|
+
method: "PATCH",
|
|
97
|
+
body: { simulator_url: simulatorUrl },
|
|
98
|
+
credentials: { "prismic-auth": token },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getCoreBaseUrl(repo: string, host: string): URL {
|
|
103
|
+
return new URL(`https://${repo}.${host}/`);
|
|
104
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
|
|
3
|
+
import { request } from "../lib/request";
|
|
4
|
+
|
|
5
|
+
const WebhookTriggersSchema = z.object({
|
|
6
|
+
documentsPublished: z.boolean(),
|
|
7
|
+
documentsUnpublished: z.boolean(),
|
|
8
|
+
releasesCreated: z.boolean(),
|
|
9
|
+
releasesUpdated: z.boolean(),
|
|
10
|
+
tagsCreated: z.boolean(),
|
|
11
|
+
tagsDeleted: z.boolean(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const WEBHOOK_TRIGGERS = Object.keys(WebhookTriggersSchema.shape);
|
|
15
|
+
|
|
16
|
+
const WebhookSchema = z.object({
|
|
17
|
+
config: z.extend(WebhookTriggersSchema, {
|
|
18
|
+
_id: z.string(),
|
|
19
|
+
url: z.string(),
|
|
20
|
+
active: z.boolean(),
|
|
21
|
+
name: z.nullable(z.string()),
|
|
22
|
+
secret: z.nullable(z.string()),
|
|
23
|
+
headers: z.record(z.string(), z.string()),
|
|
24
|
+
}),
|
|
25
|
+
});
|
|
26
|
+
type Webhook = z.infer<typeof WebhookSchema>;
|
|
27
|
+
|
|
28
|
+
export async function getWebhooks(config: {
|
|
29
|
+
repo: string;
|
|
30
|
+
token: string | undefined;
|
|
31
|
+
host: string;
|
|
32
|
+
}): Promise<Webhook[]> {
|
|
33
|
+
const { repo, token, host } = config;
|
|
34
|
+
const wroomUrl = getWroomUrl(repo, host);
|
|
35
|
+
const url = new URL("app/settings/webhooks", wroomUrl);
|
|
36
|
+
const response = await request(url, {
|
|
37
|
+
credentials: { "prismic-auth": token },
|
|
38
|
+
schema: z.array(WebhookSchema),
|
|
39
|
+
});
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function createWebhook(
|
|
44
|
+
webhookConfig: Omit<Webhook["config"], "_id" | "active" | "headers">,
|
|
45
|
+
config: { repo: string; token: string | undefined; host: string },
|
|
46
|
+
): Promise<void> {
|
|
47
|
+
const { repo, token, host } = config;
|
|
48
|
+
const wroomUrl = getWroomUrl(repo, host);
|
|
49
|
+
const url = new URL(`app/settings/webhooks/create`, wroomUrl);
|
|
50
|
+
const body = new FormData();
|
|
51
|
+
body.set("url", webhookConfig.url);
|
|
52
|
+
body.set("name", webhookConfig.name ?? "");
|
|
53
|
+
body.set("secret", webhookConfig.secret ?? "");
|
|
54
|
+
body.set("headers", JSON.stringify({}));
|
|
55
|
+
body.set("active", "on");
|
|
56
|
+
body.set("documentsPublished", webhookConfig.documentsPublished.toString());
|
|
57
|
+
body.set("documentsUnpublished", webhookConfig.documentsUnpublished.toString());
|
|
58
|
+
body.set("releasesCreated", webhookConfig.releasesCreated.toString());
|
|
59
|
+
body.set("releasesUpdated", webhookConfig.releasesUpdated.toString());
|
|
60
|
+
body.set("tagsCreated", webhookConfig.tagsCreated.toString());
|
|
61
|
+
body.set("tagsDeleted", webhookConfig.tagsDeleted.toString());
|
|
62
|
+
await request(url, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
body,
|
|
65
|
+
credentials: { "prismic-auth": token },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function updateWebhook(
|
|
70
|
+
id: string,
|
|
71
|
+
webhookConfig: Omit<Webhook["config"], "_id">,
|
|
72
|
+
config: { repo: string; token: string | undefined; host: string },
|
|
73
|
+
): Promise<void> {
|
|
74
|
+
const { repo, token, host } = config;
|
|
75
|
+
const wroomUrl = getWroomUrl(repo, host);
|
|
76
|
+
const url = new URL(`app/settings/webhooks/${id}`, wroomUrl);
|
|
77
|
+
const body = new FormData();
|
|
78
|
+
body.set("url", webhookConfig.url);
|
|
79
|
+
body.set("name", webhookConfig.name ?? "");
|
|
80
|
+
body.set("secret", webhookConfig.secret ?? "");
|
|
81
|
+
body.set("headers", JSON.stringify(webhookConfig.headers ?? {}));
|
|
82
|
+
body.set("active", webhookConfig.active ? "on" : "off");
|
|
83
|
+
body.set("documentsPublished", webhookConfig.documentsPublished.toString());
|
|
84
|
+
body.set("documentsUnpublished", webhookConfig.documentsUnpublished.toString());
|
|
85
|
+
body.set("releasesCreated", webhookConfig.releasesCreated.toString());
|
|
86
|
+
body.set("releasesUpdated", webhookConfig.releasesUpdated.toString());
|
|
87
|
+
body.set("tagsCreated", webhookConfig.tagsCreated.toString());
|
|
88
|
+
body.set("tagsDeleted", webhookConfig.tagsDeleted.toString());
|
|
89
|
+
await request(url, {
|
|
90
|
+
method: "POST",
|
|
91
|
+
body,
|
|
92
|
+
credentials: { "prismic-auth": token },
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function deleteWebhook(
|
|
97
|
+
id: string,
|
|
98
|
+
config: { repo: string; token: string | undefined; host: string },
|
|
99
|
+
): Promise<void> {
|
|
100
|
+
const { repo, token, host } = config;
|
|
101
|
+
const wroomUrl = getWroomUrl(repo, host);
|
|
102
|
+
const url = new URL(`app/settings/webhooks/${id}/delete`, wroomUrl);
|
|
103
|
+
await request(url, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
credentials: { "prismic-auth": token },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function getWroomUrl(repo: string, host: string): URL {
|
|
110
|
+
return new URL(`https://${repo}.${host}/`);
|
|
111
|
+
}
|
package/src/commands/init.ts
CHANGED
|
@@ -1,66 +1,58 @@
|
|
|
1
|
-
import { parseArgs } from "node:util";
|
|
2
|
-
|
|
3
1
|
import type { Profile } from "../clients/user";
|
|
4
2
|
|
|
3
|
+
import { getAdapter } from "../adapters";
|
|
5
4
|
import { createLoginSession, getHost, getToken } from "../auth";
|
|
6
5
|
import { getProfile } from "../clients/user";
|
|
7
6
|
import {
|
|
8
7
|
createConfig,
|
|
9
8
|
deleteLegacySliceMachineConfig,
|
|
10
9
|
InvalidLegacySliceMachineConfig,
|
|
10
|
+
MissingPrismicConfig,
|
|
11
11
|
readConfig,
|
|
12
12
|
readLegacySliceMachineConfig,
|
|
13
13
|
UnknownProjectRoot,
|
|
14
14
|
} from "../config";
|
|
15
|
-
import { getFramework } from "../frameworks";
|
|
16
15
|
import { openBrowser } from "../lib/browser";
|
|
17
16
|
import { generateAndWriteTypes } from "../lib/codegen";
|
|
17
|
+
import { CommandError, createCommand, type CommandConfig } from "../lib/command";
|
|
18
|
+
import { installDependencies } from "../lib/packageJson";
|
|
18
19
|
import { ForbiddenRequestError, UnauthorizedRequestError } from "../lib/request";
|
|
20
|
+
import { findProjectRoot } from "../project";
|
|
19
21
|
import { syncCustomTypes, syncSlices } from "./sync";
|
|
20
22
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
EXAMPLES
|
|
36
|
-
prismic init --repo my-repo
|
|
37
|
-
|
|
38
|
-
LEARN MORE
|
|
39
|
-
Use \`prismic <command> --help\` for more information about a command.
|
|
40
|
-
`.trim();
|
|
41
|
-
|
|
42
|
-
export async function init(): Promise<void> {
|
|
43
|
-
const { values } = parseArgs({
|
|
44
|
-
args: process.argv.slice(3),
|
|
45
|
-
options: {
|
|
46
|
-
help: { type: "boolean", short: "h" },
|
|
47
|
-
repo: { type: "string", short: "r" },
|
|
48
|
-
"no-browser": { type: "boolean" },
|
|
23
|
+
const config = {
|
|
24
|
+
name: "prismic init",
|
|
25
|
+
description: `
|
|
26
|
+
Initialize a Prismic project by creating a prismic.config.json file.
|
|
27
|
+
|
|
28
|
+
Detects the project framework, installs dependencies, and syncs models
|
|
29
|
+
from Prismic. If a slicemachine.config.json exists, it will be migrated.
|
|
30
|
+
`,
|
|
31
|
+
options: {
|
|
32
|
+
repo: { type: "string", short: "r", description: "Repository name" },
|
|
33
|
+
"no-browser": {
|
|
34
|
+
type: "boolean",
|
|
35
|
+
description: "Skip opening the browser automatically during login",
|
|
49
36
|
},
|
|
50
|
-
}
|
|
37
|
+
},
|
|
38
|
+
} satisfies CommandConfig;
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
40
|
+
export default createCommand(config, async ({ values }) => {
|
|
41
|
+
const { repo: explicitRepo, "no-browser": noBrowser } = values;
|
|
56
42
|
|
|
57
43
|
// Check for existing prismic.config.json
|
|
58
44
|
try {
|
|
59
45
|
await readConfig();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
} catch {
|
|
46
|
+
throw new CommandError(
|
|
47
|
+
"A prismic.config.json file exists. This project is already initialized.",
|
|
48
|
+
);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
if (error instanceof MissingPrismicConfig) {
|
|
51
|
+
// No config found — proceed with initialization.
|
|
52
|
+
} else {
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
64
56
|
|
|
65
57
|
// Load legacy slicemachine.config.json
|
|
66
58
|
let legacySliceMachineConfig;
|
|
@@ -72,11 +64,9 @@ export async function init(): Promise<void> {
|
|
|
72
64
|
}
|
|
73
65
|
}
|
|
74
66
|
|
|
75
|
-
const repo =
|
|
67
|
+
const repo = explicitRepo ?? legacySliceMachineConfig?.repositoryName;
|
|
76
68
|
if (!repo) {
|
|
77
|
-
|
|
78
|
-
process.exitCode = 1;
|
|
79
|
-
return;
|
|
69
|
+
throw new CommandError("Missing required flag: --repo");
|
|
80
70
|
}
|
|
81
71
|
|
|
82
72
|
// Validate repo membership
|
|
@@ -90,7 +80,7 @@ export async function init(): Promise<void> {
|
|
|
90
80
|
console.info("Not logged in. Starting login...");
|
|
91
81
|
const { email } = await createLoginSession({
|
|
92
82
|
onReady: (url) => {
|
|
93
|
-
if (
|
|
83
|
+
if (noBrowser) {
|
|
94
84
|
console.info(`Open this URL to log in: ${url}`);
|
|
95
85
|
} else {
|
|
96
86
|
console.info("Opening browser to complete login...");
|
|
@@ -109,19 +99,12 @@ export async function init(): Promise<void> {
|
|
|
109
99
|
|
|
110
100
|
const repoMeta = profile.repositories.find((repository) => repository.domain === repo);
|
|
111
101
|
if (!repoMeta) {
|
|
112
|
-
|
|
102
|
+
throw new CommandError(
|
|
113
103
|
`Repository "${repo}" not found in your account. Check the name or request access to the repository.`,
|
|
114
104
|
);
|
|
115
|
-
process.exitCode = 1;
|
|
116
|
-
return;
|
|
117
105
|
}
|
|
118
106
|
|
|
119
|
-
const
|
|
120
|
-
if (!framework) {
|
|
121
|
-
console.error("No supported framework found (Next.js, Nuxt, or SvelteKit required)");
|
|
122
|
-
process.exitCode = 1;
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
107
|
+
const adapter = await getAdapter();
|
|
125
108
|
|
|
126
109
|
// Create prismic.config.json
|
|
127
110
|
try {
|
|
@@ -131,14 +114,11 @@ export async function init(): Promise<void> {
|
|
|
131
114
|
});
|
|
132
115
|
} catch (error) {
|
|
133
116
|
if (error instanceof UnknownProjectRoot) {
|
|
134
|
-
|
|
117
|
+
throw new CommandError(
|
|
135
118
|
"Could not find a package.json file. Run this command from a project directory.",
|
|
136
119
|
);
|
|
137
|
-
} else {
|
|
138
|
-
console.error("Failed to create config file.");
|
|
139
120
|
}
|
|
140
|
-
|
|
141
|
-
return;
|
|
121
|
+
throw new CommandError("Failed to create prismic.config.json.");
|
|
142
122
|
}
|
|
143
123
|
|
|
144
124
|
if (legacySliceMachineConfig) {
|
|
@@ -149,23 +129,31 @@ export async function init(): Promise<void> {
|
|
|
149
129
|
}
|
|
150
130
|
|
|
151
131
|
// Install dependencies and create framework files
|
|
152
|
-
await
|
|
132
|
+
await adapter.initProject();
|
|
133
|
+
|
|
134
|
+
// Run package manager install
|
|
135
|
+
try {
|
|
136
|
+
console.info("Installing dependencies...");
|
|
137
|
+
await installDependencies();
|
|
138
|
+
} catch {
|
|
139
|
+
console.warn(
|
|
140
|
+
"Could not install dependencies automatically. Please install them manually (i.e. `npm install`).",
|
|
141
|
+
);
|
|
142
|
+
}
|
|
153
143
|
|
|
154
144
|
// Sync models from remote
|
|
155
|
-
await syncSlices(repo,
|
|
156
|
-
await syncCustomTypes(repo,
|
|
145
|
+
await syncSlices(repo, adapter);
|
|
146
|
+
await syncCustomTypes(repo, adapter);
|
|
157
147
|
|
|
158
148
|
// Generate TypeScript types from synced models
|
|
159
|
-
const slices = await
|
|
160
|
-
const customTypes = await
|
|
161
|
-
const projectRoot = await
|
|
149
|
+
const slices = await adapter.getSlices();
|
|
150
|
+
const customTypes = await adapter.getCustomTypes();
|
|
151
|
+
const projectRoot = await findProjectRoot();
|
|
162
152
|
await generateAndWriteTypes({
|
|
163
153
|
customTypes: customTypes.map((customType) => customType.model),
|
|
164
154
|
slices: slices.map((slice) => slice.model),
|
|
165
155
|
projectRoot,
|
|
166
156
|
});
|
|
167
157
|
|
|
168
|
-
console.info(
|
|
169
|
-
|
|
170
|
-
);
|
|
171
|
-
}
|
|
158
|
+
console.info(`\nInitialized Prismic for repository "${repo}".`);
|
|
159
|
+
});
|
package/src/commands/login.ts
CHANGED
|
@@ -1,39 +1,22 @@
|
|
|
1
1
|
import { exec } from "node:child_process";
|
|
2
|
-
import { parseArgs } from "node:util";
|
|
3
2
|
|
|
4
3
|
import { createLoginSession } from "../auth";
|
|
4
|
+
import { createCommand, type CommandConfig } from "../lib/command";
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const config = {
|
|
7
|
+
name: "prismic login",
|
|
8
|
+
description: "Log in to Prismic via browser.",
|
|
9
|
+
options: {
|
|
10
|
+
"no-browser": { type: "boolean", description: "Skip opening the browser automatically" },
|
|
11
|
+
},
|
|
12
|
+
} satisfies CommandConfig;
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
FLAGS
|
|
13
|
-
--no-browser Skip opening the browser automatically
|
|
14
|
-
-h, --help Show help for command
|
|
15
|
-
|
|
16
|
-
LEARN MORE
|
|
17
|
-
Use \`prismic <command> --help\` for more information about a command.
|
|
18
|
-
`.trim();
|
|
19
|
-
|
|
20
|
-
export async function login(): Promise<void> {
|
|
21
|
-
const { values } = parseArgs({
|
|
22
|
-
args: process.argv.slice(3),
|
|
23
|
-
options: {
|
|
24
|
-
help: { type: "boolean", short: "h" },
|
|
25
|
-
"no-browser": { type: "boolean" },
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
if (values.help) {
|
|
30
|
-
console.info(HELP);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
14
|
+
export default createCommand(config, async ({ values }) => {
|
|
15
|
+
const { "no-browser": noBrowser } = values;
|
|
33
16
|
|
|
34
17
|
const { email } = await createLoginSession({
|
|
35
18
|
onReady: (url) => {
|
|
36
|
-
if (
|
|
19
|
+
if (noBrowser) {
|
|
37
20
|
console.info(`Open this URL to log in: ${url}`);
|
|
38
21
|
} else {
|
|
39
22
|
console.info("Opening browser to complete login...");
|
|
@@ -44,7 +27,7 @@ export async function login(): Promise<void> {
|
|
|
44
27
|
});
|
|
45
28
|
|
|
46
29
|
console.info(`Logged in to Prismic as ${email}`);
|
|
47
|
-
}
|
|
30
|
+
});
|
|
48
31
|
|
|
49
32
|
function openBrowser(url: URL): void {
|
|
50
33
|
const cmd =
|
package/src/commands/logout.ts
CHANGED
|
@@ -1,36 +1,16 @@
|
|
|
1
|
-
import { parseArgs } from "node:util";
|
|
2
|
-
|
|
3
1
|
import { logout as baseLogout } from "../auth";
|
|
2
|
+
import { CommandError, createCommand, type CommandConfig } from "../lib/command";
|
|
4
3
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
prismic logout [flags]
|
|
10
|
-
|
|
11
|
-
FLAGS
|
|
12
|
-
-h, --help Show help for command
|
|
13
|
-
|
|
14
|
-
LEARN MORE
|
|
15
|
-
Use \`prismic <command> --help\` for more information about a command.
|
|
16
|
-
`.trim();
|
|
17
|
-
|
|
18
|
-
export async function logout(): Promise<void> {
|
|
19
|
-
const { values } = parseArgs({
|
|
20
|
-
args: process.argv.slice(3),
|
|
21
|
-
options: { help: { type: "boolean", short: "h" } },
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
if (values.help) {
|
|
25
|
-
console.info(HELP);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
4
|
+
const config = {
|
|
5
|
+
name: "prismic logout",
|
|
6
|
+
description: "Log out of Prismic.",
|
|
7
|
+
} satisfies CommandConfig;
|
|
28
8
|
|
|
9
|
+
export default createCommand(config, async () => {
|
|
29
10
|
const ok = await baseLogout();
|
|
30
11
|
if (ok) {
|
|
31
12
|
console.info("Logged out of Prismic");
|
|
32
13
|
} else {
|
|
33
|
-
|
|
34
|
-
process.exitCode = 1;
|
|
14
|
+
throw new CommandError("Logout failed. You can log out manually by deleting the file.");
|
|
35
15
|
}
|
|
36
|
-
}
|
|
16
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getHost, getToken } from "../auth";
|
|
2
|
+
import { addPreview } from "../clients/core";
|
|
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 preview add",
|
|
9
|
+
description: `
|
|
10
|
+
Add a preview configuration to a Prismic repository.
|
|
11
|
+
|
|
12
|
+
By default, this command reads the repository from prismic.config.json at the
|
|
13
|
+
project root.
|
|
14
|
+
`,
|
|
15
|
+
positionals: {
|
|
16
|
+
url: { description: "Preview URL (e.g. https://example.com/api/preview)" },
|
|
17
|
+
},
|
|
18
|
+
options: {
|
|
19
|
+
name: { type: "string", short: "n", description: "Display name (defaults to hostname)" },
|
|
20
|
+
repo: { type: "string", short: "r", description: "Repository domain" },
|
|
21
|
+
},
|
|
22
|
+
} satisfies CommandConfig;
|
|
23
|
+
|
|
24
|
+
export default createCommand(config, async ({ positionals, values }) => {
|
|
25
|
+
const [previewUrl] = positionals;
|
|
26
|
+
const { repo = await getRepositoryName(), name } = values;
|
|
27
|
+
|
|
28
|
+
if (!previewUrl) {
|
|
29
|
+
throw new CommandError("Missing required argument: <url>");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let parsed: URL;
|
|
33
|
+
try {
|
|
34
|
+
parsed = new URL(previewUrl);
|
|
35
|
+
} catch {
|
|
36
|
+
throw new CommandError(`Invalid URL: ${previewUrl}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const displayName = name || parsed.hostname;
|
|
40
|
+
const websiteURL = `${parsed.protocol}//${parsed.host}`;
|
|
41
|
+
const resolverPath = parsed.pathname === "/" ? undefined : parsed.pathname;
|
|
42
|
+
|
|
43
|
+
const token = await getToken();
|
|
44
|
+
const host = await getHost();
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
await addPreview({ name: displayName, websiteURL, resolverPath }, { repo, token, host });
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error instanceof UnknownRequestError) {
|
|
50
|
+
const message = await error.text();
|
|
51
|
+
throw new CommandError(`Failed to add preview: ${message}`);
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.info(`Preview added: ${previewUrl}`);
|
|
57
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getHost, getToken } from "../auth";
|
|
2
|
+
import { getPreviews, getSimulatorUrl } from "../clients/core";
|
|
3
|
+
import { createCommand, type CommandConfig } from "../lib/command";
|
|
4
|
+
import { stringify } from "../lib/json";
|
|
5
|
+
import { getRepositoryName } from "../project";
|
|
6
|
+
|
|
7
|
+
const config = {
|
|
8
|
+
name: "prismic preview list",
|
|
9
|
+
description: `
|
|
10
|
+
List all preview configurations in a Prismic repository.
|
|
11
|
+
|
|
12
|
+
By default, this command reads the repository from prismic.config.json at the
|
|
13
|
+
project root.
|
|
14
|
+
`,
|
|
15
|
+
options: {
|
|
16
|
+
json: { type: "boolean", description: "Output as JSON" },
|
|
17
|
+
repo: { type: "string", short: "r", description: "Repository domain" },
|
|
18
|
+
},
|
|
19
|
+
} satisfies CommandConfig;
|
|
20
|
+
|
|
21
|
+
export default createCommand(config, async ({ values }) => {
|
|
22
|
+
const { repo = await getRepositoryName(), json } = values;
|
|
23
|
+
|
|
24
|
+
const token = await getToken();
|
|
25
|
+
const host = await getHost();
|
|
26
|
+
|
|
27
|
+
const [previews, simulatorUrl] = await Promise.all([
|
|
28
|
+
getPreviews({ repo, token, host }),
|
|
29
|
+
getSimulatorUrl({ repo, token, host }),
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
if (json) {
|
|
33
|
+
console.info(
|
|
34
|
+
stringify({
|
|
35
|
+
previews,
|
|
36
|
+
simulatorUrl: simulatorUrl ?? null,
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (previews.length === 0 && !simulatorUrl) {
|
|
43
|
+
console.info("No preview configurations found.");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for (const preview of previews) {
|
|
48
|
+
console.info(`${preview.url} ${preview.label}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (simulatorUrl) {
|
|
52
|
+
console.info(`\nSimulator: ${simulatorUrl}`);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getHost, getToken } from "../auth";
|
|
2
|
+
import { getPreviews, removePreview } from "../clients/core";
|
|
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 preview remove",
|
|
9
|
+
description: `
|
|
10
|
+
Remove a preview configuration from a Prismic repository.
|
|
11
|
+
|
|
12
|
+
By default, this command reads the repository from prismic.config.json at the
|
|
13
|
+
project root.
|
|
14
|
+
`,
|
|
15
|
+
positionals: {
|
|
16
|
+
url: { description: "Preview URL to remove" },
|
|
17
|
+
},
|
|
18
|
+
options: {
|
|
19
|
+
repo: { type: "string", short: "r", description: "Repository domain" },
|
|
20
|
+
},
|
|
21
|
+
} satisfies CommandConfig;
|
|
22
|
+
|
|
23
|
+
export default createCommand(config, async ({ positionals, values }) => {
|
|
24
|
+
const [previewUrl] = positionals;
|
|
25
|
+
const { repo = await getRepositoryName() } = values;
|
|
26
|
+
|
|
27
|
+
if (!previewUrl) {
|
|
28
|
+
throw new CommandError("Missing required argument: <url>");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const token = await getToken();
|
|
32
|
+
const host = await getHost();
|
|
33
|
+
|
|
34
|
+
const previews = await getPreviews({ repo, token, host });
|
|
35
|
+
const preview = previews.find((p) => p.url === previewUrl);
|
|
36
|
+
if (!preview) {
|
|
37
|
+
throw new CommandError(`Preview not found: ${previewUrl}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
await removePreview(preview.id, { repo, token, host });
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (error instanceof UnknownRequestError) {
|
|
44
|
+
const message = await error.text();
|
|
45
|
+
throw new CommandError(`Failed to remove preview: ${message}`);
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
console.info(`Preview removed: ${previewUrl}`);
|
|
51
|
+
});
|