@prisma/cli 8.0.0-rc.1 → 8.0.0-rc.10-dev.80
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/README.md +25 -29
- package/dist/cli.js +14551 -16
- package/dist/{v8/sender.js → sender.js} +1 -1
- package/package.json +17 -18
- package/dist/adapters/git.js +0 -54
- package/dist/adapters/local-state.js +0 -155
- package/dist/auth/client.js +0 -30
- package/dist/auth/errors.js +0 -50
- package/dist/auth/guard.js +0 -39
- package/dist/auth/login.js +0 -471
- package/dist/auth/operations.js +0 -208
- package/dist/auth/recipient.js +0 -42
- package/dist/auth/token-storage.js +0 -439
- package/dist/auth/workspaces.js +0 -171
- package/dist/cli-command.js +0 -14
- package/dist/cli-name.js +0 -12
- package/dist/cli2.js +0 -136
- package/dist/command-arguments.js +0 -12
- package/dist/commands/agent/index.js +0 -60
- package/dist/commands/app/index.js +0 -350
- package/dist/commands/auth/index.js +0 -95
- package/dist/commands/branch/index.js +0 -27
- package/dist/commands/bucket/index.js +0 -123
- package/dist/commands/build/index.js +0 -29
- package/dist/commands/database/index.js +0 -249
- package/dist/commands/env.js +0 -99
- package/dist/commands/feedback/index.js +0 -20
- package/dist/commands/git/index.js +0 -36
- package/dist/commands/init/index.js +0 -33
- package/dist/commands/project/index.js +0 -118
- package/dist/commands/version/index.js +0 -18
- package/dist/controllers/agent-setup.js +0 -52
- package/dist/controllers/agent.js +0 -228
- package/dist/controllers/app-env-api.js +0 -55
- package/dist/controllers/app-env-file.js +0 -181
- package/dist/controllers/app-env.js +0 -502
- package/dist/controllers/app.js +0 -2508
- package/dist/controllers/auth.js +0 -124
- package/dist/controllers/branch.js +0 -92
- package/dist/controllers/bucket.js +0 -184
- package/dist/controllers/build.js +0 -88
- package/dist/controllers/database.js +0 -463
- package/dist/controllers/feedback.js +0 -90
- package/dist/controllers/init.js +0 -814
- package/dist/controllers/project.js +0 -892
- package/dist/controllers/select-prompt-port.js +0 -13
- package/dist/controllers/version.js +0 -12
- package/dist/errors.js +0 -102
- package/dist/lib/agent/cli-command.js +0 -20
- package/dist/lib/agent/constants.js +0 -12
- package/dist/lib/agent/package-manager.js +0 -99
- package/dist/lib/agent/setup-status.js +0 -83
- package/dist/lib/app/app-provider.js +0 -617
- package/dist/lib/app/branch-database-api.js +0 -102
- package/dist/lib/app/branch-database-deploy.js +0 -353
- package/dist/lib/app/branch-database.js +0 -234
- package/dist/lib/app/build-settings.js +0 -98
- package/dist/lib/app/build.js +0 -82
- package/dist/lib/app/bun-project.js +0 -45
- package/dist/lib/app/compute-config.js +0 -145
- package/dist/lib/app/deploy-output.js +0 -24
- package/dist/lib/app/deploy-plan.js +0 -59
- package/dist/lib/app/deploy-progress.js +0 -100
- package/dist/lib/app/domain-guidance.js +0 -14
- package/dist/lib/app/env-config.js +0 -67
- package/dist/lib/app/env-file.js +0 -82
- package/dist/lib/app/env-vars.js +0 -50
- package/dist/lib/app/local-dev.js +0 -109
- package/dist/lib/app/production-deploy-gate.js +0 -162
- package/dist/lib/app/read-branch.js +0 -30
- package/dist/lib/bucket/provider.js +0 -139
- package/dist/lib/database/provider.js +0 -385
- package/dist/lib/diagnostics.js +0 -16
- package/dist/lib/feedback.js +0 -15
- package/dist/lib/fs/home-path.js +0 -24
- package/dist/lib/git/local-branch.js +0 -53
- package/dist/lib/git/local-status.js +0 -57
- package/dist/lib/project/interactive-setup.js +0 -57
- package/dist/lib/project/local-pin.js +0 -200
- package/dist/lib/project/provider.js +0 -93
- package/dist/lib/project/resolution.js +0 -389
- package/dist/lib/project/setup.js +0 -138
- package/dist/lib/version.js +0 -56
- package/dist/lib/workspace-id.js +0 -18
- package/dist/output/patterns.js +0 -90
- package/dist/presenters/agent.js +0 -74
- package/dist/presenters/app-env.js +0 -265
- package/dist/presenters/app.js +0 -672
- package/dist/presenters/auth.js +0 -184
- package/dist/presenters/branch.js +0 -46
- package/dist/presenters/bucket.js +0 -174
- package/dist/presenters/database.js +0 -462
- package/dist/presenters/feedback.js +0 -26
- package/dist/presenters/init.js +0 -30
- package/dist/presenters/project.js +0 -268
- package/dist/presenters/verbose-context.js +0 -64
- package/dist/presenters/version.js +0 -29
- package/dist/shell/cli-command.js +0 -2
- package/dist/shell/command-meta.js +0 -923
- package/dist/shell/command-runner.js +0 -119
- package/dist/shell/diagnostics-output.js +0 -57
- package/dist/shell/global-flags.js +0 -37
- package/dist/shell/help.js +0 -90
- package/dist/shell/output.js +0 -144
- package/dist/shell/prompt.js +0 -48
- package/dist/shell/runtime.js +0 -38
- package/dist/shell/ui.js +0 -116
- package/dist/state-dir.js +0 -12
- package/dist/update-check.js +0 -248
- package/dist/v8/cli.js +0 -14699
package/dist/auth/recipient.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { getApiBaseUrl } from "./client.js";
|
|
2
|
-
import { FileTokenStorage } from "./token-storage.js";
|
|
3
|
-
import { createManagementApiSdk } from "@prisma/management-api-sdk";
|
|
4
|
-
//#region src/auth/recipient.ts
|
|
5
|
-
var RecipientSessionInvalidError = class extends Error {
|
|
6
|
-
constructor(workspaceRef) {
|
|
7
|
-
super(`The stored session for workspace "${workspaceRef}" could not be validated.`);
|
|
8
|
-
this.workspaceRef = workspaceRef;
|
|
9
|
-
this.name = "RecipientSessionInvalidError";
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Resolve a locally stored OAuth workspace session and return a validated
|
|
14
|
-
* access token for it, refreshing through the SDK when the stored token has
|
|
15
|
-
* expired. The active workspace pointer is never touched.
|
|
16
|
-
*
|
|
17
|
-
* Throws WorkspaceSelectionError when the ref does not match exactly one
|
|
18
|
-
* stored session, and RecipientSessionInvalidError when the session cannot
|
|
19
|
-
* be validated or refreshed.
|
|
20
|
-
*/
|
|
21
|
-
async function resolveRecipientWorkspaceSession(workspaceRef, env = process.env, signal) {
|
|
22
|
-
const workspace = await new FileTokenStorage(env, signal).resolveWorkspace(workspaceRef);
|
|
23
|
-
const pinnedStorage = new FileTokenStorage(env, signal, {
|
|
24
|
-
activateOnSetTokens: false,
|
|
25
|
-
lockSetTokens: false,
|
|
26
|
-
pinnedWorkspaceId: workspace.credentialWorkspaceId
|
|
27
|
-
});
|
|
28
|
-
if ((await createManagementApiSdk({
|
|
29
|
-
clientId: "cmm3lndn701oo0uefvxzo0ivw",
|
|
30
|
-
redirectUri: "http://localhost:0/auth/callback",
|
|
31
|
-
tokenStorage: pinnedStorage,
|
|
32
|
-
apiBaseUrl: getApiBaseUrl(env)
|
|
33
|
-
}).client.GET("/v1/workspaces", { signal })).error) throw new RecipientSessionInvalidError(workspaceRef);
|
|
34
|
-
const tokens = await pinnedStorage.getTokens();
|
|
35
|
-
if (!tokens) throw new RecipientSessionInvalidError(workspaceRef);
|
|
36
|
-
return {
|
|
37
|
-
workspace,
|
|
38
|
-
accessToken: tokens.accessToken
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { RecipientSessionInvalidError, resolveRecipientWorkspaceSession };
|
|
@@ -1,439 +0,0 @@
|
|
|
1
|
-
import { getAuthFilePath } from "./client.js";
|
|
2
|
-
import { sameWorkspaceId } from "../lib/workspace-id.js";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import fs from "node:fs/promises";
|
|
5
|
-
import { randomUUID } from "node:crypto";
|
|
6
|
-
import { CredentialsStore } from "@prisma/credentials-store";
|
|
7
|
-
//#region src/auth/token-storage.ts
|
|
8
|
-
const REFRESH_LOCK_RETRY_MS = 100;
|
|
9
|
-
const REFRESH_LOCK_STALE_MS = 3e4;
|
|
10
|
-
const REFRESH_LOCK_WAIT_TIMEOUT_MS = 25e3;
|
|
11
|
-
const EMPTY_AUTH_CONTEXT = {
|
|
12
|
-
activeWorkspaceId: null,
|
|
13
|
-
workspaces: {}
|
|
14
|
-
};
|
|
15
|
-
const UNKNOWN_WORKSPACE_NAME = "Unknown workspace";
|
|
16
|
-
function getAuthContextFilePath(authFilePath) {
|
|
17
|
-
const extension = path.extname(authFilePath);
|
|
18
|
-
if (!extension) return `${authFilePath}.context.json`;
|
|
19
|
-
return `${authFilePath.slice(0, -extension.length)}.context${extension}`;
|
|
20
|
-
}
|
|
21
|
-
function findLatestValidTokens(allCredentials) {
|
|
22
|
-
for (let i = allCredentials.length - 1; i >= 0; i -= 1) {
|
|
23
|
-
const credential = allCredentials[i];
|
|
24
|
-
if (!credential) continue;
|
|
25
|
-
if (typeof credential.workspaceId !== "string" || credential.workspaceId.length === 0 || typeof credential.token !== "string" || credential.token.length === 0 || typeof credential.refreshToken !== "string" || credential.refreshToken.length === 0) continue;
|
|
26
|
-
return {
|
|
27
|
-
workspaceId: credential.workspaceId,
|
|
28
|
-
accessToken: credential.token,
|
|
29
|
-
refreshToken: credential.refreshToken
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
function storedCredentialToTokens(credential) {
|
|
35
|
-
if (!credential) return null;
|
|
36
|
-
if (typeof credential.workspaceId !== "string" || credential.workspaceId.length === 0 || typeof credential.token !== "string" || credential.token.length === 0 || typeof credential.refreshToken !== "string" || credential.refreshToken.length === 0) return null;
|
|
37
|
-
return {
|
|
38
|
-
workspaceId: credential.workspaceId,
|
|
39
|
-
accessToken: credential.token,
|
|
40
|
-
refreshToken: credential.refreshToken
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
function findTokensForWorkspace(allCredentials, workspaceId) {
|
|
44
|
-
return storedCredentialToTokens(allCredentials.find((credential) => credential?.workspaceId === workspaceId)) ?? null;
|
|
45
|
-
}
|
|
46
|
-
function tokensEqual(a, b) {
|
|
47
|
-
return a?.workspaceId === b?.workspaceId && a?.accessToken === b?.accessToken && a?.refreshToken === b?.refreshToken;
|
|
48
|
-
}
|
|
49
|
-
function sleep(ms, signal) {
|
|
50
|
-
signal?.throwIfAborted();
|
|
51
|
-
return new Promise((resolve, reject) => {
|
|
52
|
-
const onAbort = () => {
|
|
53
|
-
clearTimeout(timeout);
|
|
54
|
-
reject(signal?.reason);
|
|
55
|
-
};
|
|
56
|
-
const timeout = setTimeout(() => {
|
|
57
|
-
signal?.removeEventListener("abort", onAbort);
|
|
58
|
-
resolve();
|
|
59
|
-
}, ms);
|
|
60
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
var FileTokenStorage = class {
|
|
64
|
-
credentialsStore;
|
|
65
|
-
authFilePath;
|
|
66
|
-
contextFilePath;
|
|
67
|
-
lockFilePath;
|
|
68
|
-
constructor(env = process.env, signal, options = {}) {
|
|
69
|
-
this.signal = signal;
|
|
70
|
-
this.options = options;
|
|
71
|
-
const authFilePath = getAuthFilePath(env);
|
|
72
|
-
this.authFilePath = authFilePath;
|
|
73
|
-
this.contextFilePath = getAuthContextFilePath(authFilePath);
|
|
74
|
-
this.credentialsStore = new CredentialsStore(authFilePath);
|
|
75
|
-
this.lockFilePath = `${authFilePath}.lock`;
|
|
76
|
-
}
|
|
77
|
-
async getTokens() {
|
|
78
|
-
this.signal?.throwIfAborted();
|
|
79
|
-
try {
|
|
80
|
-
const credentials = await this.readCredentialsFromDisk();
|
|
81
|
-
if (this.options.pinnedWorkspaceId) return findTokensForWorkspace(credentials, this.options.pinnedWorkspaceId);
|
|
82
|
-
const context = await this.readAuthContext();
|
|
83
|
-
if (context.state.activeWorkspaceId) return findTokensForWorkspace(credentials, context.state.activeWorkspaceId);
|
|
84
|
-
const latest = findLatestValidTokens(credentials);
|
|
85
|
-
if (!latest) return null;
|
|
86
|
-
if (!context.exists) {
|
|
87
|
-
await this.setActiveWorkspaceId(latest.workspaceId);
|
|
88
|
-
return latest;
|
|
89
|
-
}
|
|
90
|
-
return null;
|
|
91
|
-
} catch (_error) {
|
|
92
|
-
if (this.signal?.aborted) throw this.signal.reason;
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
async setTokens(tokens) {
|
|
97
|
-
if (this.options.lockSetTokens === false) {
|
|
98
|
-
await this.setTokensUnlocked(tokens);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
await this.withRefreshLock(() => this.setTokensUnlocked(tokens));
|
|
102
|
-
}
|
|
103
|
-
async setTokensUnlocked(tokens) {
|
|
104
|
-
this.signal?.throwIfAborted();
|
|
105
|
-
await this.credentialsStore.storeCredentials({
|
|
106
|
-
workspaceId: tokens.workspaceId,
|
|
107
|
-
token: tokens.accessToken,
|
|
108
|
-
refreshToken: tokens.refreshToken
|
|
109
|
-
});
|
|
110
|
-
this.signal?.throwIfAborted();
|
|
111
|
-
await this.rememberWorkspaceUnlocked(tokens.workspaceId, {
|
|
112
|
-
id: tokens.workspaceId,
|
|
113
|
-
name: tokens.workspaceId
|
|
114
|
-
});
|
|
115
|
-
await this.maybeActivateWorkspaceId(tokens.workspaceId);
|
|
116
|
-
}
|
|
117
|
-
async clearTokens() {
|
|
118
|
-
await this.withRefreshLock(() => this.clearTokensUnlocked());
|
|
119
|
-
}
|
|
120
|
-
async clearTokensUnlocked() {
|
|
121
|
-
this.signal?.throwIfAborted();
|
|
122
|
-
await fs.mkdir(path.dirname(this.authFilePath), { recursive: true });
|
|
123
|
-
this.signal?.throwIfAborted();
|
|
124
|
-
await fs.writeFile(this.authFilePath, `${JSON.stringify({ tokens: [] }, null, 2)}\n`, {
|
|
125
|
-
encoding: "utf8",
|
|
126
|
-
signal: this.signal
|
|
127
|
-
});
|
|
128
|
-
await this.clearAuthContext();
|
|
129
|
-
await this.credentialsStore.reloadCredentialsFromDisk();
|
|
130
|
-
this.signal?.throwIfAborted();
|
|
131
|
-
}
|
|
132
|
-
async clearTokensIfCurrent(tokens) {
|
|
133
|
-
this.signal?.throwIfAborted();
|
|
134
|
-
if (!tokensEqual(await this.getTokens(), tokens)) return;
|
|
135
|
-
await this.credentialsStore.deleteCredentials(tokens.workspaceId);
|
|
136
|
-
await this.removeRememberedWorkspace(tokens.workspaceId, { preserveActivePointer: true });
|
|
137
|
-
this.signal?.throwIfAborted();
|
|
138
|
-
}
|
|
139
|
-
async listWorkspaces() {
|
|
140
|
-
this.signal?.throwIfAborted();
|
|
141
|
-
const credentials = await this.readCredentialsFromDisk();
|
|
142
|
-
const context = await this.ensureMigratedAuthContext(credentials);
|
|
143
|
-
return this.workspacesFromState(credentials, context);
|
|
144
|
-
}
|
|
145
|
-
workspacesFromState(credentials, context) {
|
|
146
|
-
return credentials.map((credential) => storedCredentialToTokens(credential)).filter((tokens) => tokens !== null).map((tokens) => {
|
|
147
|
-
const cached = context.state.workspaces[tokens.workspaceId];
|
|
148
|
-
const id = typeof cached?.id === "string" && cached.id.trim().length > 0 ? cached.id.trim() : tokens.workspaceId;
|
|
149
|
-
const name = typeof cached?.name === "string" && cached.name.trim().length > 0 ? workspaceDisplayName(cached.name.trim(), tokens.workspaceId) : UNKNOWN_WORKSPACE_NAME;
|
|
150
|
-
const lastSeenAt = typeof cached?.lastSeenAt === "string" && cached.lastSeenAt.trim().length > 0 ? cached.lastSeenAt.trim() : null;
|
|
151
|
-
return {
|
|
152
|
-
id,
|
|
153
|
-
name,
|
|
154
|
-
credentialWorkspaceId: tokens.workspaceId,
|
|
155
|
-
active: context.state.activeWorkspaceId === tokens.workspaceId,
|
|
156
|
-
lastSeenAt
|
|
157
|
-
};
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
async listWorkspaceTokens() {
|
|
161
|
-
this.signal?.throwIfAborted();
|
|
162
|
-
return (await this.readCredentialsFromDisk()).map((credential) => storedCredentialToTokens(credential)).filter((tokens) => tokens !== null);
|
|
163
|
-
}
|
|
164
|
-
async useWorkspace(workspaceRef) {
|
|
165
|
-
return this.withRefreshLock(() => this.useWorkspaceUnlocked(workspaceRef));
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Resolve a workspace ref (id, credential workspace id, or cached name)
|
|
169
|
-
* against the locally stored sessions without changing the active
|
|
170
|
-
* workspace. Read-only counterpart of useWorkspace: it reads the auth
|
|
171
|
-
* context as-is and never runs the legacy-state migration, so it writes
|
|
172
|
-
* nothing.
|
|
173
|
-
*/
|
|
174
|
-
async resolveWorkspace(workspaceRef) {
|
|
175
|
-
const ref = workspaceRef.trim();
|
|
176
|
-
if (!ref) throw new WorkspaceSelectionError("missing");
|
|
177
|
-
this.signal?.throwIfAborted();
|
|
178
|
-
const credentials = await this.readCredentialsFromDisk();
|
|
179
|
-
const context = await this.readAuthContext();
|
|
180
|
-
const matches = this.workspacesFromState(credentials, context).filter((workspace) => workspaceMatchesRef(workspace, ref));
|
|
181
|
-
if (matches.length === 0) throw new WorkspaceSelectionError("not-found", ref);
|
|
182
|
-
if (matches.length > 1) throw new WorkspaceSelectionError("ambiguous", ref, matches);
|
|
183
|
-
return matches[0];
|
|
184
|
-
}
|
|
185
|
-
async useWorkspaceUnlocked(workspaceRef) {
|
|
186
|
-
const ref = workspaceRef.trim();
|
|
187
|
-
if (!ref) throw new WorkspaceSelectionError("missing");
|
|
188
|
-
const workspaces = await this.listWorkspaces();
|
|
189
|
-
const context = await this.readAuthContext();
|
|
190
|
-
const previous = workspaces.find((workspace) => workspace.credentialWorkspaceId === context.state.activeWorkspaceId) ?? null;
|
|
191
|
-
const matches = workspaces.filter((workspace) => workspaceMatchesRef(workspace, ref));
|
|
192
|
-
if (matches.length === 0) throw new WorkspaceSelectionError("not-found", ref);
|
|
193
|
-
if (matches.length > 1) throw new WorkspaceSelectionError("ambiguous", ref, matches);
|
|
194
|
-
const selected = matches[0];
|
|
195
|
-
await this.setActiveWorkspaceId(selected.credentialWorkspaceId);
|
|
196
|
-
return {
|
|
197
|
-
previous,
|
|
198
|
-
selected
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
async logoutWorkspace(workspaceRef) {
|
|
202
|
-
return this.withRefreshLock(() => this.logoutWorkspaceUnlocked(workspaceRef));
|
|
203
|
-
}
|
|
204
|
-
async logoutWorkspaceUnlocked(workspaceRef) {
|
|
205
|
-
const ref = workspaceRef.trim();
|
|
206
|
-
if (!ref) throw new WorkspaceSelectionError("missing");
|
|
207
|
-
const workspaces = await this.listWorkspaces();
|
|
208
|
-
const context = await this.readAuthContext();
|
|
209
|
-
const matches = workspaces.filter((workspace) => workspaceMatchesRef(workspace, ref));
|
|
210
|
-
if (matches.length === 0) throw new WorkspaceSelectionError("not-found", ref);
|
|
211
|
-
if (matches.length > 1) throw new WorkspaceSelectionError("ambiguous", ref, matches);
|
|
212
|
-
const workspace = matches[0];
|
|
213
|
-
const wasActive = context.state.activeWorkspaceId === workspace.credentialWorkspaceId;
|
|
214
|
-
await this.credentialsStore.deleteCredentials(workspace.credentialWorkspaceId);
|
|
215
|
-
this.signal?.throwIfAborted();
|
|
216
|
-
const remainingWorkspaces = workspaces.filter((candidate) => candidate.credentialWorkspaceId !== workspace.credentialWorkspaceId);
|
|
217
|
-
if (remainingWorkspaces.length === 0) {
|
|
218
|
-
await this.clearAuthContext();
|
|
219
|
-
return {
|
|
220
|
-
workspace,
|
|
221
|
-
wasActive,
|
|
222
|
-
activeWorkspace: null
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
delete context.state.workspaces[workspace.credentialWorkspaceId];
|
|
226
|
-
if (wasActive) context.state.activeWorkspaceId = null;
|
|
227
|
-
await this.writeAuthContext(context.state);
|
|
228
|
-
return {
|
|
229
|
-
workspace,
|
|
230
|
-
wasActive,
|
|
231
|
-
activeWorkspace: context.state.activeWorkspaceId === null ? null : remainingWorkspaces.find((candidate) => candidate.credentialWorkspaceId === context.state.activeWorkspaceId) ?? null
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
async rememberWorkspace(credentialWorkspaceId, workspace) {
|
|
235
|
-
await this.withRefreshLock(() => this.rememberWorkspaceUnlocked(credentialWorkspaceId, workspace));
|
|
236
|
-
}
|
|
237
|
-
async rememberWorkspaceUnlocked(credentialWorkspaceId, workspace) {
|
|
238
|
-
const context = await this.readAuthContext();
|
|
239
|
-
context.state.workspaces[credentialWorkspaceId] = {
|
|
240
|
-
id: workspace.id,
|
|
241
|
-
name: workspace.name,
|
|
242
|
-
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
243
|
-
};
|
|
244
|
-
await this.writeAuthContext(context.state);
|
|
245
|
-
}
|
|
246
|
-
async withRefreshLock(fn) {
|
|
247
|
-
const lockId = await this.acquireRefreshLock();
|
|
248
|
-
try {
|
|
249
|
-
return await fn();
|
|
250
|
-
} finally {
|
|
251
|
-
await this.releaseRefreshLock(lockId);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
async acquireRefreshLock() {
|
|
255
|
-
const lockId = randomUUID();
|
|
256
|
-
const startedAt = Date.now();
|
|
257
|
-
const retryMs = this.options.lockRetryMs ?? REFRESH_LOCK_RETRY_MS;
|
|
258
|
-
const waitTimeoutMs = this.options.lockWaitTimeoutMs ?? REFRESH_LOCK_WAIT_TIMEOUT_MS;
|
|
259
|
-
this.signal?.throwIfAborted();
|
|
260
|
-
await fs.mkdir(path.dirname(this.lockFilePath), { recursive: true });
|
|
261
|
-
while (true) {
|
|
262
|
-
this.signal?.throwIfAborted();
|
|
263
|
-
if (await this.tryCreateRefreshLock(lockId)) return lockId;
|
|
264
|
-
if (await this.releaseStaleRefreshLock()) continue;
|
|
265
|
-
this.throwIfRefreshLockWaitTimedOut(startedAt, waitTimeoutMs);
|
|
266
|
-
await sleep(retryMs, this.signal);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
async tryCreateRefreshLock(lockId) {
|
|
270
|
-
let lockFileCreated = false;
|
|
271
|
-
try {
|
|
272
|
-
const handle = await fs.open(this.lockFilePath, "wx");
|
|
273
|
-
lockFileCreated = true;
|
|
274
|
-
try {
|
|
275
|
-
this.signal?.throwIfAborted();
|
|
276
|
-
await handle.writeFile(lockId, { encoding: "utf8" });
|
|
277
|
-
this.signal?.throwIfAborted();
|
|
278
|
-
} finally {
|
|
279
|
-
await handle.close();
|
|
280
|
-
}
|
|
281
|
-
return true;
|
|
282
|
-
} catch (error) {
|
|
283
|
-
if (lockFileCreated) await fs.unlink(this.lockFilePath).catch(() => void 0);
|
|
284
|
-
if (error.code === "EEXIST") return false;
|
|
285
|
-
throw error;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
async releaseStaleRefreshLock() {
|
|
289
|
-
const staleLockId = await this.getStaleRefreshLockId();
|
|
290
|
-
if (!staleLockId) return false;
|
|
291
|
-
await this.releaseRefreshLock(staleLockId);
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
throwIfRefreshLockWaitTimedOut(startedAt, waitTimeoutMs) {
|
|
295
|
-
if (Date.now() - startedAt < waitTimeoutMs) return;
|
|
296
|
-
throw new RefreshLockTimeoutError(this.lockFilePath, waitTimeoutMs);
|
|
297
|
-
}
|
|
298
|
-
async getStaleRefreshLockId() {
|
|
299
|
-
this.signal?.throwIfAborted();
|
|
300
|
-
const lockId = await fs.readFile(this.lockFilePath, {
|
|
301
|
-
encoding: "utf8",
|
|
302
|
-
signal: this.signal
|
|
303
|
-
}).catch((error) => {
|
|
304
|
-
if (this.signal?.aborted) throw error;
|
|
305
|
-
return null;
|
|
306
|
-
});
|
|
307
|
-
if (lockId === null) return null;
|
|
308
|
-
this.signal?.throwIfAborted();
|
|
309
|
-
const stats = await fs.stat(this.lockFilePath).catch(() => null);
|
|
310
|
-
this.signal?.throwIfAborted();
|
|
311
|
-
if (!stats) return null;
|
|
312
|
-
const staleMs = this.options.lockStaleMs ?? REFRESH_LOCK_STALE_MS;
|
|
313
|
-
return Date.now() - stats.mtimeMs > staleMs ? lockId : null;
|
|
314
|
-
}
|
|
315
|
-
async releaseRefreshLock(lockId) {
|
|
316
|
-
if (await fs.readFile(this.lockFilePath, { encoding: "utf8" }).catch(() => null) !== lockId) return;
|
|
317
|
-
await fs.unlink(this.lockFilePath).catch(() => {});
|
|
318
|
-
}
|
|
319
|
-
async readCredentialsFromDisk() {
|
|
320
|
-
this.signal?.throwIfAborted();
|
|
321
|
-
await this.credentialsStore.reloadCredentialsFromDisk();
|
|
322
|
-
this.signal?.throwIfAborted();
|
|
323
|
-
return await this.credentialsStore.getCredentials();
|
|
324
|
-
}
|
|
325
|
-
async ensureMigratedAuthContext(credentials) {
|
|
326
|
-
const context = await this.readAuthContext();
|
|
327
|
-
if (context.state.activeWorkspaceId || context.exists) return context;
|
|
328
|
-
const latest = findLatestValidTokens(credentials);
|
|
329
|
-
if (!latest) return context;
|
|
330
|
-
context.state.activeWorkspaceId = latest.workspaceId;
|
|
331
|
-
context.state.workspaces[latest.workspaceId] ??= {
|
|
332
|
-
id: latest.workspaceId,
|
|
333
|
-
name: latest.workspaceId,
|
|
334
|
-
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
335
|
-
};
|
|
336
|
-
await this.writeAuthContext(context.state);
|
|
337
|
-
return {
|
|
338
|
-
exists: true,
|
|
339
|
-
state: context.state
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
async setActiveWorkspaceId(workspaceId) {
|
|
343
|
-
const context = await this.readAuthContext();
|
|
344
|
-
context.state.activeWorkspaceId = workspaceId;
|
|
345
|
-
context.state.workspaces[workspaceId] ??= {
|
|
346
|
-
id: workspaceId,
|
|
347
|
-
name: workspaceId,
|
|
348
|
-
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
349
|
-
};
|
|
350
|
-
await this.writeAuthContext(context.state);
|
|
351
|
-
}
|
|
352
|
-
async maybeActivateWorkspaceId(workspaceId) {
|
|
353
|
-
if (this.options.pinnedWorkspaceId) return;
|
|
354
|
-
const context = await this.readAuthContext();
|
|
355
|
-
if (this.options.activateOnSetTokens === false && context.exists && context.state.activeWorkspaceId && context.state.activeWorkspaceId !== workspaceId) return;
|
|
356
|
-
context.state.activeWorkspaceId = workspaceId;
|
|
357
|
-
context.state.workspaces[workspaceId] ??= {
|
|
358
|
-
id: workspaceId,
|
|
359
|
-
name: workspaceId,
|
|
360
|
-
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
361
|
-
};
|
|
362
|
-
await this.writeAuthContext(context.state);
|
|
363
|
-
}
|
|
364
|
-
async removeRememberedWorkspace(workspaceId, options) {
|
|
365
|
-
const context = await this.readAuthContext();
|
|
366
|
-
delete context.state.workspaces[workspaceId];
|
|
367
|
-
if (!options.preserveActivePointer && context.state.activeWorkspaceId === workspaceId) context.state.activeWorkspaceId = null;
|
|
368
|
-
await this.writeAuthContext(context.state);
|
|
369
|
-
}
|
|
370
|
-
async readAuthContext() {
|
|
371
|
-
this.signal?.throwIfAborted();
|
|
372
|
-
const raw = await fs.readFile(this.contextFilePath, {
|
|
373
|
-
encoding: "utf8",
|
|
374
|
-
signal: this.signal
|
|
375
|
-
}).catch((error) => {
|
|
376
|
-
if (this.signal?.aborted) throw error;
|
|
377
|
-
if (error.code === "ENOENT") return null;
|
|
378
|
-
throw error;
|
|
379
|
-
});
|
|
380
|
-
if (raw === null) return {
|
|
381
|
-
exists: false,
|
|
382
|
-
state: structuredClone(EMPTY_AUTH_CONTEXT)
|
|
383
|
-
};
|
|
384
|
-
try {
|
|
385
|
-
const parsed = JSON.parse(raw);
|
|
386
|
-
return {
|
|
387
|
-
exists: true,
|
|
388
|
-
state: {
|
|
389
|
-
activeWorkspaceId: typeof parsed.activeWorkspaceId === "string" && parsed.activeWorkspaceId.trim().length > 0 ? parsed.activeWorkspaceId.trim() : null,
|
|
390
|
-
workspaces: parsed.workspaces && typeof parsed.workspaces === "object" && !Array.isArray(parsed.workspaces) ? parsed.workspaces : {}
|
|
391
|
-
}
|
|
392
|
-
};
|
|
393
|
-
} catch {
|
|
394
|
-
return {
|
|
395
|
-
exists: false,
|
|
396
|
-
state: structuredClone(EMPTY_AUTH_CONTEXT)
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
async writeAuthContext(state) {
|
|
401
|
-
this.signal?.throwIfAborted();
|
|
402
|
-
await fs.mkdir(path.dirname(this.contextFilePath), { recursive: true });
|
|
403
|
-
this.signal?.throwIfAborted();
|
|
404
|
-
await fs.writeFile(this.contextFilePath, `${JSON.stringify(state, null, 2)}\n`, {
|
|
405
|
-
encoding: "utf8",
|
|
406
|
-
signal: this.signal
|
|
407
|
-
});
|
|
408
|
-
this.signal?.throwIfAborted();
|
|
409
|
-
}
|
|
410
|
-
async clearAuthContext() {
|
|
411
|
-
await fs.unlink(this.contextFilePath).catch((error) => {
|
|
412
|
-
if (error.code === "ENOENT") return;
|
|
413
|
-
throw error;
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
var WorkspaceSelectionError = class extends Error {
|
|
418
|
-
constructor(reason, workspaceRef, matches = []) {
|
|
419
|
-
super(reason);
|
|
420
|
-
this.reason = reason;
|
|
421
|
-
this.workspaceRef = workspaceRef;
|
|
422
|
-
this.matches = matches;
|
|
423
|
-
this.name = "WorkspaceSelectionError";
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
var RefreshLockTimeoutError = class extends Error {
|
|
427
|
-
constructor(lockFilePath, waitTimeoutMs) {
|
|
428
|
-
super(`Timed out waiting ${waitTimeoutMs}ms for auth refresh lock at ${lockFilePath}`);
|
|
429
|
-
this.name = "RefreshLockTimeoutError";
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
function workspaceMatchesRef(workspace, ref) {
|
|
433
|
-
return sameWorkspaceId(workspace.credentialWorkspaceId, ref) || sameWorkspaceId(workspace.id, ref) || workspace.name.toLowerCase() === ref.toLowerCase();
|
|
434
|
-
}
|
|
435
|
-
function workspaceDisplayName(name, credentialWorkspaceId) {
|
|
436
|
-
return name === credentialWorkspaceId ? UNKNOWN_WORKSPACE_NAME : name;
|
|
437
|
-
}
|
|
438
|
-
//#endregion
|
|
439
|
-
export { FileTokenStorage, WorkspaceSelectionError };
|
package/dist/auth/workspaces.js
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { CLIENT_ID, UNUSED_REDIRECT_URI, getApiBaseUrl } from "./client.js";
|
|
2
|
-
import { FileTokenStorage, WorkspaceSelectionError } from "./token-storage.js";
|
|
3
|
-
import { readAuthState } from "./operations.js";
|
|
4
|
-
import { workspaceAmbiguousError, workspaceNotAuthenticatedError, workspaceSwitchUnavailableError } from "./errors.js";
|
|
5
|
-
import { createManagementApiSdk } from "@prisma/management-api-sdk";
|
|
6
|
-
import { SERVICE_TOKEN_ENV_VAR } from "@prisma/cli-engine";
|
|
7
|
-
//#region src/auth/workspaces.ts
|
|
8
|
-
async function listAuthWorkspaces(context) {
|
|
9
|
-
const rawServiceToken = context.env[SERVICE_TOKEN_ENV_VAR];
|
|
10
|
-
const storage = new FileTokenStorage(context.env, context.signal);
|
|
11
|
-
const localWorkspaces = await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
|
|
12
|
-
if (rawServiceToken !== void 0) {
|
|
13
|
-
const authState = await readAuthState(context.env, context.signal);
|
|
14
|
-
return {
|
|
15
|
-
authSource: authState.authenticated ? "service_token" : "none",
|
|
16
|
-
activeWorkspace: authState.workspace,
|
|
17
|
-
workspaces: [...authState.workspace ? [{
|
|
18
|
-
...authState.workspace,
|
|
19
|
-
credentialWorkspaceId: null,
|
|
20
|
-
active: true,
|
|
21
|
-
source: "service_token",
|
|
22
|
-
switchable: false,
|
|
23
|
-
lastSeenAt: null
|
|
24
|
-
}] : [], ...localWorkspaces.map((workspace) => ({
|
|
25
|
-
...toAuthWorkspace(workspace),
|
|
26
|
-
credentialWorkspaceId: workspace.credentialWorkspaceId,
|
|
27
|
-
active: false,
|
|
28
|
-
source: "oauth",
|
|
29
|
-
switchable: false,
|
|
30
|
-
lastSeenAt: workspace.lastSeenAt
|
|
31
|
-
}))]
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
const active = localWorkspaces.find((workspace) => workspace.active) ?? null;
|
|
35
|
-
return {
|
|
36
|
-
authSource: localWorkspaces.length > 0 ? "oauth" : "none",
|
|
37
|
-
activeWorkspace: active ? toAuthWorkspace(active) : null,
|
|
38
|
-
workspaces: localWorkspaces.map((workspace) => ({
|
|
39
|
-
...toAuthWorkspace(workspace),
|
|
40
|
-
credentialWorkspaceId: workspace.credentialWorkspaceId,
|
|
41
|
-
active: workspace.active,
|
|
42
|
-
source: "oauth",
|
|
43
|
-
switchable: true,
|
|
44
|
-
lastSeenAt: workspace.lastSeenAt
|
|
45
|
-
}))
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
async function switchAuthWorkspace(context, workspaceRef) {
|
|
49
|
-
if (context.env[SERVICE_TOKEN_ENV_VAR] !== void 0) throw workspaceSwitchUnavailableError();
|
|
50
|
-
const storage = new FileTokenStorage(context.env, context.signal);
|
|
51
|
-
await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
|
|
52
|
-
try {
|
|
53
|
-
const result = await storage.useWorkspace(workspaceRef);
|
|
54
|
-
return {
|
|
55
|
-
previousWorkspace: result.previous ? toAuthWorkspace(result.previous) : null,
|
|
56
|
-
workspace: toAuthWorkspace(result.selected)
|
|
57
|
-
};
|
|
58
|
-
} catch (error) {
|
|
59
|
-
if (error instanceof WorkspaceSelectionError) {
|
|
60
|
-
if (error.reason === "ambiguous") throw workspaceAmbiguousError(error.workspaceRef ?? workspaceRef, error.matches.map((match) => ({
|
|
61
|
-
id: match.id,
|
|
62
|
-
name: match.name,
|
|
63
|
-
credentialWorkspaceId: match.credentialWorkspaceId
|
|
64
|
-
})));
|
|
65
|
-
throw workspaceNotAuthenticatedError(error.workspaceRef ?? workspaceRef);
|
|
66
|
-
}
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
async function logoutAuthWorkspace(context, workspaceRef) {
|
|
71
|
-
const storage = new FileTokenStorage(context.env, context.signal);
|
|
72
|
-
await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
|
|
73
|
-
try {
|
|
74
|
-
const result = await storage.logoutWorkspace(workspaceRef);
|
|
75
|
-
return {
|
|
76
|
-
workspace: toAuthWorkspace(result.workspace),
|
|
77
|
-
wasActive: result.wasActive,
|
|
78
|
-
activeWorkspace: result.activeWorkspace ? toAuthWorkspace(result.activeWorkspace) : null
|
|
79
|
-
};
|
|
80
|
-
} catch (error) {
|
|
81
|
-
if (error instanceof WorkspaceSelectionError) {
|
|
82
|
-
if (error.reason === "ambiguous") throw workspaceAmbiguousError(error.workspaceRef ?? workspaceRef, error.matches.map((match) => ({
|
|
83
|
-
id: match.id,
|
|
84
|
-
name: match.name,
|
|
85
|
-
credentialWorkspaceId: match.credentialWorkspaceId
|
|
86
|
-
})));
|
|
87
|
-
throw workspaceNotAuthenticatedError(error.workspaceRef ?? workspaceRef);
|
|
88
|
-
}
|
|
89
|
-
throw error;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
async function hydrateLocalAuthWorkspaces(context, storage, workspaces) {
|
|
93
|
-
const candidates = workspaces.filter(needsWorkspaceMetadataHydration);
|
|
94
|
-
if (candidates.length === 0) return workspaces;
|
|
95
|
-
const tokensByCredentialWorkspaceId = new Map((await storage.listWorkspaceTokens()).map((tokens) => [tokens.workspaceId, tokens]));
|
|
96
|
-
let nextWorkspaces = workspaces;
|
|
97
|
-
for (const workspace of candidates) {
|
|
98
|
-
const tokens = tokensByCredentialWorkspaceId.get(workspace.credentialWorkspaceId);
|
|
99
|
-
if (!tokens) continue;
|
|
100
|
-
const resolved = await resolveOAuthWorkspaceMetadata(context, tokens);
|
|
101
|
-
if (!resolved) continue;
|
|
102
|
-
await rememberResolvedWorkspaceMetadata(context, storage, tokens, resolved);
|
|
103
|
-
nextWorkspaces = nextWorkspaces.map((candidate) => candidate.credentialWorkspaceId === workspace.credentialWorkspaceId ? {
|
|
104
|
-
...candidate,
|
|
105
|
-
id: resolved.id,
|
|
106
|
-
name: resolved.name,
|
|
107
|
-
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
108
|
-
} : candidate);
|
|
109
|
-
}
|
|
110
|
-
return nextWorkspaces;
|
|
111
|
-
}
|
|
112
|
-
async function rememberResolvedWorkspaceMetadata(context, storage, tokens, resolved) {
|
|
113
|
-
try {
|
|
114
|
-
await storage.rememberWorkspace(tokens.workspaceId, resolved);
|
|
115
|
-
} catch {
|
|
116
|
-
context.signal?.throwIfAborted();
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function needsWorkspaceMetadataHydration(workspace) {
|
|
120
|
-
return workspace.id === workspace.credentialWorkspaceId || workspace.name === "Unknown workspace" || workspace.name === workspace.credentialWorkspaceId;
|
|
121
|
-
}
|
|
122
|
-
async function resolveOAuthWorkspaceMetadata(context, tokens) {
|
|
123
|
-
const sdk = createManagementApiSdk({
|
|
124
|
-
clientId: CLIENT_ID,
|
|
125
|
-
redirectUri: UNUSED_REDIRECT_URI,
|
|
126
|
-
tokenStorage: createSingleWorkspaceTokenStorage(new FileTokenStorage(context.env, context.signal, { activateOnSetTokens: false }), tokens),
|
|
127
|
-
apiBaseUrl: getApiBaseUrl(context.env)
|
|
128
|
-
});
|
|
129
|
-
try {
|
|
130
|
-
const { data } = await sdk.client.GET("/v1/workspaces/{id}", {
|
|
131
|
-
params: { path: { id: tokens.workspaceId } },
|
|
132
|
-
signal: context.signal
|
|
133
|
-
});
|
|
134
|
-
const id = stringOrNull(data?.data?.id) ?? tokens.workspaceId;
|
|
135
|
-
const name = stringOrNull(data?.data?.name) ?? id;
|
|
136
|
-
if (id === tokens.workspaceId && name === tokens.workspaceId) return null;
|
|
137
|
-
return {
|
|
138
|
-
id,
|
|
139
|
-
name
|
|
140
|
-
};
|
|
141
|
-
} catch {
|
|
142
|
-
context.signal?.throwIfAborted();
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
function createSingleWorkspaceTokenStorage(storage, initialTokens) {
|
|
147
|
-
let currentTokens = initialTokens;
|
|
148
|
-
return {
|
|
149
|
-
getTokens: async () => currentTokens,
|
|
150
|
-
setTokens: async (tokens) => {
|
|
151
|
-
currentTokens = tokens;
|
|
152
|
-
await storage.setTokens(tokens);
|
|
153
|
-
},
|
|
154
|
-
clearTokens: async () => {
|
|
155
|
-
const tokens = currentTokens;
|
|
156
|
-
currentTokens = null;
|
|
157
|
-
if (tokens) await storage.clearTokensIfCurrent(tokens);
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
function stringOrNull(value) {
|
|
162
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
163
|
-
}
|
|
164
|
-
function toAuthWorkspace(workspace) {
|
|
165
|
-
return {
|
|
166
|
-
id: workspace.id,
|
|
167
|
-
name: workspace.name
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
//#endregion
|
|
171
|
-
export { listAuthWorkspaces, logoutAuthWorkspace, switchAuthWorkspace };
|
package/dist/cli-command.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
//#region src/cli-command.ts
|
|
2
|
-
const PRISMA_CLI_PACKAGE_NAME = "@prisma/cli";
|
|
3
|
-
const PRISMA_CLI_PACKAGE_SPEC = `${PRISMA_CLI_PACKAGE_NAME}@latest`;
|
|
4
|
-
const DEFAULT_PRISMA_CLI_PACKAGE_RUNNER = ["npx", "-y"];
|
|
5
|
-
const PRISMA_CLI_BINARY = "prisma-cli";
|
|
6
|
-
function formatPrismaCliCommand(args, options = {}) {
|
|
7
|
-
return [...getPrismaCliCommandPrefix(options), ...args].join(" ");
|
|
8
|
-
}
|
|
9
|
-
function getPrismaCliCommandPrefix({ invocation = "package", packageRunner = DEFAULT_PRISMA_CLI_PACKAGE_RUNNER }) {
|
|
10
|
-
if (invocation === "binary") return [PRISMA_CLI_BINARY];
|
|
11
|
-
return [...packageRunner, PRISMA_CLI_PACKAGE_SPEC];
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
export { DEFAULT_PRISMA_CLI_PACKAGE_RUNNER, PRISMA_CLI_BINARY, PRISMA_CLI_PACKAGE_NAME, PRISMA_CLI_PACKAGE_SPEC, formatPrismaCliCommand };
|
package/dist/cli-name.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
//#region src/cli-name.ts
|
|
2
|
-
/**
|
|
3
|
-
* The CLI's user-facing identity, in one place. The npm package is
|
|
4
|
-
* "@prisma/cli" but the binary on PATH is "prisma-cli" (the S1
|
|
5
|
-
* convention) — every user-facing command string and notice consumes
|
|
6
|
-
* this constant rather than restating the name.
|
|
7
|
-
*/
|
|
8
|
-
const CLI_NAME = "prisma-cli";
|
|
9
|
-
/** The CLI docs page (also the update-check fallback instruction URL). */
|
|
10
|
-
const CLI_DOCS_URL = "https://www.prisma.io/docs/orm/tools/prisma-cli";
|
|
11
|
-
//#endregion
|
|
12
|
-
export { CLI_DOCS_URL, CLI_NAME };
|