neon 8.11.1 → 8.11.3
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 +1 -1
- package/dist/_chunks/api-GbEaBZJ5.js +388 -0
- package/dist/_chunks/api_keys-CNnnugbQ.js +281 -0
- package/dist/_chunks/ask-DVwy0eUL.js +155 -0
- package/dist/_chunks/auth-CIUtXByB.js +495 -0
- package/dist/_chunks/bootstrap-wPZWa1sT.js +499 -0
- package/dist/_chunks/branches-BNa1xX1L.js +460 -0
- package/dist/_chunks/bucket-BCdryTkD.js +409 -0
- package/dist/_chunks/checkout-CXIOydqZ.js +348 -0
- package/dist/_chunks/claim-DqAvAvDm.js +473 -0
- package/dist/_chunks/config-BH_qRHiG.js +1113 -0
- package/dist/_chunks/connection_string-DB4awPzZ.js +154 -0
- package/dist/_chunks/credentials-BSjE9fRR.js +146 -0
- package/dist/_chunks/data_api-Djxj5ZQD.js +263 -0
- package/dist/_chunks/databases-Dok4wru7.js +84 -0
- package/dist/_chunks/deploy-D7B0Xfjg.js +33 -0
- package/dist/_chunks/dev-CSvxAecE.js +945 -0
- package/dist/_chunks/diff-DhxxbdQE.js +178 -0
- package/dist/_chunks/docs-CrVybkTP.js +197 -0
- package/dist/_chunks/env-5HS5qQGd.js +284 -0
- package/dist/_chunks/feedback-CMayyTa8.js +88 -0
- package/dist/_chunks/functions-Q0zuvtnk.js +464 -0
- package/dist/_chunks/git-H32TNt6M.js +356 -0
- package/dist/_chunks/init-BkA6RilG.js +111 -0
- package/dist/_chunks/inspect-g0wekylj.js +90 -0
- package/dist/_chunks/ip_allow-5lLFvIuE.js +106 -0
- package/dist/_chunks/link-BgtkOBws.js +936 -0
- package/dist/_chunks/logs-DWkpjzIH.js +291 -0
- package/dist/_chunks/mcp-Bo-7TKc7.js +253 -0
- package/dist/_chunks/neon_auth-CBs1_3qu.js +822 -0
- package/dist/_chunks/open-CX3BT3Tp.js +33 -0
- package/dist/_chunks/operations-D4I-AxVs.js +37 -0
- package/dist/_chunks/orgs-xGfANwHQ.js +52 -0
- package/dist/_chunks/plugins-DqD7BDO1.js +169 -0
- package/dist/_chunks/profile-yXOiKk9R.js +672 -0
- package/dist/_chunks/projects-BwI2Uo0z.js +439 -0
- package/dist/_chunks/psql-BM-doe8e.js +64 -0
- package/dist/_chunks/realtime-BRqIyGR-.js +79 -0
- package/dist/_chunks/roles-B4w3YT_7.js +79 -0
- package/dist/_chunks/set_context-DbrwoImy.js +38 -0
- package/dist/_chunks/skills-DyiBXKS3.js +255 -0
- package/dist/_chunks/snapshots-RJBzW8GM.js +338 -0
- package/dist/_chunks/status-DV8Z2kw3.js +44 -0
- package/dist/_chunks/triggers-BrRo1z4b.js +302 -0
- package/dist/_chunks/user-dlOGXbX9.js +60 -0
- package/dist/_chunks/vpc_endpoints-CNb0YfMo.js +105 -0
- package/dist/auth_recovery.js +1 -1
- package/dist/commands/api.js +1 -388
- package/dist/commands/api_keys.js +1 -281
- package/dist/commands/ask.js +1 -155
- package/dist/commands/auth.js +1 -495
- package/dist/commands/bootstrap.js +1 -499
- package/dist/commands/branches.js +1 -460
- package/dist/commands/bucket.js +1 -409
- package/dist/commands/checkout.js +1 -348
- package/dist/commands/claim.js +1 -473
- package/dist/commands/config.js +1 -1113
- package/dist/commands/connection_string.js +1 -154
- package/dist/commands/credentials.js +1 -146
- package/dist/commands/data_api.js +1 -263
- package/dist/commands/databases.js +1 -84
- package/dist/commands/deploy.js +1 -33
- package/dist/commands/dev.js +1 -945
- package/dist/commands/diff.js +1 -178
- package/dist/commands/docs.js +1 -197
- package/dist/commands/env.js +1 -284
- package/dist/commands/feedback.js +1 -88
- package/dist/commands/functions.js +1 -464
- package/dist/commands/functions_new.js +1 -1
- package/dist/commands/git.js +1 -356
- package/dist/commands/index.js +45 -45
- package/dist/commands/init.js +1 -111
- package/dist/commands/inspect.js +1 -90
- package/dist/commands/ip_allow.js +1 -106
- package/dist/commands/link.js +1 -936
- package/dist/commands/logs.js +1 -291
- package/dist/commands/mcp.js +1 -253
- package/dist/commands/neon_auth.js +1 -822
- package/dist/commands/open.js +1 -33
- package/dist/commands/operations.js +1 -37
- package/dist/commands/orgs.js +1 -52
- package/dist/commands/plugins.js +1 -169
- package/dist/commands/profile.js +1 -672
- package/dist/commands/projects.js +1 -439
- package/dist/commands/psql.js +1 -64
- package/dist/commands/realtime.js +1 -79
- package/dist/commands/roles.js +1 -79
- package/dist/commands/set_context.js +1 -38
- package/dist/commands/skills.js +1 -255
- package/dist/commands/snapshots.js +1 -338
- package/dist/commands/status.js +1 -44
- package/dist/commands/subscribe.js +1 -1
- package/dist/commands/triggers.js +1 -302
- package/dist/commands/user.js +1 -60
- package/dist/commands/vpc_endpoints.js +1 -105
- package/dist/functions/registry.js +29 -151
- package/dist/functions/source.js +42 -2
- package/dist/index.js +1 -1
- package/dist/init/auth.js +3 -3
- package/dist/init/link.js +2 -2
- package/dist/init/run.js +3 -3
- package/dist/init/tooling.js +3 -3
- package/dist/mcp/mint.js +1 -1
- package/dist/test_utils/registry.js +1 -2
- package/package.json +9 -7
package/dist/commands/claim.js
CHANGED
|
@@ -1,473 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { isCi } from "../env.js";
|
|
3
|
-
import { log } from "../log.js";
|
|
4
|
-
import { getApiClient } from "../api.js";
|
|
5
|
-
import { applyContext, contextBranch, readContextFile } from "../context.js";
|
|
6
|
-
import { t as credentialInputs } from "../_chunks/auth_selection-YX5_KZgD.js";
|
|
7
|
-
import { ClaimableClient, ClaimableServiceError } from "../claimable/api.js";
|
|
8
|
-
import { assertionHasExpired, listClaimableCredentials, readClaimableCredentials, readLinkedClaimableCredentials, removeClaimableCredentials, writeClaimableCredentials } from "../claimable/state.js";
|
|
9
|
-
import { NEON_SERVICES, deprecatedServiceMessage, parseServices, servicesFlagValue, servicesOption } from "../neon_services.js";
|
|
10
|
-
import { claimableDataApiCreateBody, declaredClaimableNeonServices, isClaimableService } from "../config_services.js";
|
|
11
|
-
import { projectConfigPath } from "../project.js";
|
|
12
|
-
import { resolveEnvFilePath } from "../env_file.js";
|
|
13
|
-
import { writer } from "../writer.js";
|
|
14
|
-
import { noPassthrough } from "../utils/flags.js";
|
|
15
|
-
import { pull } from "./env.js";
|
|
16
|
-
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
17
|
-
import open from "open";
|
|
18
|
-
import prompts from "prompts";
|
|
19
|
-
import { loadConfigFromFile } from "@neon/config-runtime";
|
|
20
|
-
//#region src/commands/claim.ts
|
|
21
|
-
var claim_exports = /* @__PURE__ */ __exportAll({
|
|
22
|
-
CLAIM_CREATE_FIELDS: () => CLAIM_CREATE_FIELDS,
|
|
23
|
-
CLAIM_LIST_FIELDS: () => CLAIM_LIST_FIELDS,
|
|
24
|
-
aliases: () => aliases,
|
|
25
|
-
builder: () => builder,
|
|
26
|
-
claimCreateFields: () => claimCreateFields,
|
|
27
|
-
claimableCapabilities: () => claimableCapabilities,
|
|
28
|
-
command: () => command,
|
|
29
|
-
create: () => create,
|
|
30
|
-
describe: () => describe,
|
|
31
|
-
handler: () => handler
|
|
32
|
-
});
|
|
33
|
-
const CLAIMABLE_SERVICES = NEON_SERVICES.filter(isClaimableService);
|
|
34
|
-
const CAPABILITY_FOR_SERVICE = {
|
|
35
|
-
postgres: "postgres",
|
|
36
|
-
auth: "auth",
|
|
37
|
-
"data-api": "data_api",
|
|
38
|
-
functions: "functions",
|
|
39
|
-
"object-storage": "storage",
|
|
40
|
-
"ai-gateway": "ai_gateway"
|
|
41
|
-
};
|
|
42
|
-
const CAPABILITY_ORDER = [
|
|
43
|
-
"postgres",
|
|
44
|
-
"data_api",
|
|
45
|
-
"auth",
|
|
46
|
-
"storage",
|
|
47
|
-
"functions",
|
|
48
|
-
"ai_gateway"
|
|
49
|
-
];
|
|
50
|
-
const SERVICE_FOR_CAPABILITY = {
|
|
51
|
-
postgres: "postgres",
|
|
52
|
-
auth: "auth",
|
|
53
|
-
data_api: "data-api",
|
|
54
|
-
functions: "functions",
|
|
55
|
-
storage: "object-storage",
|
|
56
|
-
ai_gateway: "ai-gateway"
|
|
57
|
-
};
|
|
58
|
-
const isClaimableCapability = (value) => value in SERVICE_FOR_CAPABILITY;
|
|
59
|
-
const cliServiceName = (capability) => isClaimableCapability(capability) ? SERVICE_FOR_CAPABILITY[capability] : capability;
|
|
60
|
-
const claimableCapabilities = (services) => {
|
|
61
|
-
const requested = /* @__PURE__ */ new Set(["postgres"]);
|
|
62
|
-
for (const service of services) requested.add(CAPABILITY_FOR_SERVICE[service]);
|
|
63
|
-
return CAPABILITY_ORDER.filter((capability) => requested.has(capability));
|
|
64
|
-
};
|
|
65
|
-
const loadCreatePolicy = async (explicitPath, contextFile) => {
|
|
66
|
-
const path = explicitPath ?? projectConfigPath(contextFile ? { contextFile } : {});
|
|
67
|
-
if (!path) return void 0;
|
|
68
|
-
const { config } = await loadConfigFromFile({ path });
|
|
69
|
-
return {
|
|
70
|
-
path,
|
|
71
|
-
config
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
const removeFileIfPresent = (path) => {
|
|
75
|
-
try {
|
|
76
|
-
unlinkSync(path);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") return;
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
const failureMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
83
|
-
const CLAIM_LIST_FIELDS = [
|
|
84
|
-
"project_id",
|
|
85
|
-
"branch_id",
|
|
86
|
-
"state",
|
|
87
|
-
"project_expires_at",
|
|
88
|
-
"origin"
|
|
89
|
-
];
|
|
90
|
-
const CLAIM_CREATE_FIELDS = [
|
|
91
|
-
"project_id",
|
|
92
|
-
"branch_id",
|
|
93
|
-
"region_id",
|
|
94
|
-
"state",
|
|
95
|
-
"project_expires_at",
|
|
96
|
-
"granted_capabilities",
|
|
97
|
-
"denied_capabilities",
|
|
98
|
-
"env_file"
|
|
99
|
-
];
|
|
100
|
-
const claimCreateFields = (denied) => CLAIM_CREATE_FIELDS.filter((field) => field !== "denied_capabilities" || denied.length > 0);
|
|
101
|
-
const command = "claim";
|
|
102
|
-
const aliases = ["claimable"];
|
|
103
|
-
const describe = "Create and claim temporary Neon projects";
|
|
104
|
-
const builder = (argv) => argv.usage("$0 claim <sub-command> [options]").option("claimable-host", {
|
|
105
|
-
describe: "Claimable Neon service origin",
|
|
106
|
-
type: "string",
|
|
107
|
-
default: process.env.CLAIMABLE_NEON_HOST ?? "https://claimable.neon.tech",
|
|
108
|
-
hidden: true
|
|
109
|
-
}).command("create", "Create a temporary Neon project without an account", (y) => y.option("service", servicesOption({
|
|
110
|
-
key: "service",
|
|
111
|
-
allowed: CLAIMABLE_SERVICES,
|
|
112
|
-
describe: "Services to request for the claimable project",
|
|
113
|
-
also: "Postgres is always included. Services unavailable before claim are recorded and reported."
|
|
114
|
-
})).option("region-id", {
|
|
115
|
-
describe: "Region ID for the new project (e.g. aws-eu-central-1). Defaults to aws-us-east-2",
|
|
116
|
-
type: "string"
|
|
117
|
-
}).option("file", {
|
|
118
|
-
describe: "Target dotenv file. Defaults to an existing .env, otherwise .env.local",
|
|
119
|
-
type: "string"
|
|
120
|
-
}).option("config", {
|
|
121
|
-
describe: "Path to neon.ts for registration and the bundled env pull. Defaults to the neon.ts in the project directory (next to .neon, or cwd without one)",
|
|
122
|
-
type: "string"
|
|
123
|
-
}).option("env-pull", {
|
|
124
|
-
describe: "Write the same Neon env vars `env pull` would",
|
|
125
|
-
type: "boolean",
|
|
126
|
-
default: true
|
|
127
|
-
}).strict().check(noPassthrough("claim create")), async (args) => {
|
|
128
|
-
const rawServices = servicesFlagValue(args.service);
|
|
129
|
-
const services = rawServices ? parseServices(rawServices, {
|
|
130
|
-
allowed: CLAIMABLE_SERVICES,
|
|
131
|
-
flag: "--service",
|
|
132
|
-
onDeprecated: (used, canonical) => log.warning(deprecatedServiceMessage(used, canonical))
|
|
133
|
-
}) : [];
|
|
134
|
-
const policy = await loadCreatePolicy(typeof args.config === "string" ? args.config : void 0, typeof args.contextFile === "string" ? args.contextFile : void 0);
|
|
135
|
-
const configuredServices = policy ? declaredClaimableNeonServices(policy.config) : [];
|
|
136
|
-
const dataApi = policy ? claimableDataApiCreateBody(policy.config) : void 0;
|
|
137
|
-
await create({
|
|
138
|
-
...args,
|
|
139
|
-
services: [.../* @__PURE__ */ new Set([...services, ...configuredServices])],
|
|
140
|
-
...policy ? { config: policy.path } : {},
|
|
141
|
-
...dataApi ? { dataApi } : {}
|
|
142
|
-
});
|
|
143
|
-
}).command("status [project-id]", "Show a claimable project's lifecycle and claim status", (y) => y.positional("project-id", {
|
|
144
|
-
describe: "Project from `neon claim list`. Defaults to the project linked in this directory",
|
|
145
|
-
type: "string"
|
|
146
|
-
}).strict().check(noPassthrough("claim status")), async (args) => await status(args)).command("accept [project-id]", "Create a claim code and open the URL where a human signs in and takes the project", (y) => y.positional("project-id", {
|
|
147
|
-
describe: "Project from `neon claim list`. Defaults to the project linked in this directory",
|
|
148
|
-
type: "string"
|
|
149
|
-
}).option("open", {
|
|
150
|
-
describe: "Open the verification URL in a browser",
|
|
151
|
-
type: "boolean",
|
|
152
|
-
default: true
|
|
153
|
-
}).strict().check(noPassthrough("claim accept")), async (args) => await accept(args)).command("list", "List claimable projects saved on this machine", (y) => y.strict().check(noPassthrough("claim list")), async (args) => list(args)).command("delete [project-id]", "Permanently delete an unclaimed project, or drop a local record that can no longer reach the service", (y) => y.positional("project-id", {
|
|
154
|
-
describe: "Project from `neon claim list`. Defaults to the project linked in this directory",
|
|
155
|
-
type: "string"
|
|
156
|
-
}).option("yes", {
|
|
157
|
-
alias: "y",
|
|
158
|
-
describe: "Skip the confirmation prompt",
|
|
159
|
-
type: "boolean",
|
|
160
|
-
default: false
|
|
161
|
-
}).strict().check(noPassthrough("claim delete")), async (args) => await deleteProject(args));
|
|
162
|
-
const handler = (_args) => {};
|
|
163
|
-
const rejectExplicitAccountCredential = (props) => {
|
|
164
|
-
if (credentialInputs().apiKeyFlag.trim() !== "" || props.profile?.trim()) throw new Error("Claimable Neon does not use a Neon account credential. Remove --api-key or --profile.");
|
|
165
|
-
};
|
|
166
|
-
const resolveTarget = (props) => {
|
|
167
|
-
rejectExplicitAccountCredential(props);
|
|
168
|
-
const requested = props.projectId?.trim();
|
|
169
|
-
const context = readContextFile(props.contextFile);
|
|
170
|
-
if (requested) {
|
|
171
|
-
const credentials = readClaimableCredentials(props.configDir, requested);
|
|
172
|
-
if (credentials === null) throw new Error(`The identity assertion for ${requested} is missing. The project cannot be managed from this machine; claim it through its existing verification URL or run \`neon link\` after it is claimed.`);
|
|
173
|
-
return {
|
|
174
|
-
projectId: requested,
|
|
175
|
-
credentials,
|
|
176
|
-
client: new ClaimableClient(credentials.origin),
|
|
177
|
-
contextMatches: context.projectId === requested
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
const linked = readLinkedClaimableCredentials(props.configDir, context);
|
|
181
|
-
if (linked === null) throw new Error("This directory is not linked to a claimable project. Pass a project id from `neon claim list`, or run `neon claim create` first.");
|
|
182
|
-
return {
|
|
183
|
-
projectId: linked.projectId,
|
|
184
|
-
credentials: linked,
|
|
185
|
-
client: new ClaimableClient(linked.origin),
|
|
186
|
-
contextMatches: true
|
|
187
|
-
};
|
|
188
|
-
};
|
|
189
|
-
const requireLiveIdentity = (credentials) => {
|
|
190
|
-
if (assertionHasExpired(credentials)) throw new Error(`The identity assertion for ${credentials.projectId} has expired. Run \`neon claim delete ${credentials.projectId} --yes\` to drop the local record.`);
|
|
191
|
-
};
|
|
192
|
-
const isUnusableIdentity = (error) => error instanceof ClaimableServiceError && (error.code === "invalid_grant" || error.code === "project_expired" || error.code === "not_found");
|
|
193
|
-
const clearLocalRecord = (props, projectId, contextMatches) => {
|
|
194
|
-
removeClaimableCredentials(props.configDir, projectId);
|
|
195
|
-
if (contextMatches && existsSync(props.contextFile)) applyContext(props.contextFile, {});
|
|
196
|
-
};
|
|
197
|
-
const create = async (props) => {
|
|
198
|
-
rejectExplicitAccountCredential(props);
|
|
199
|
-
const existing = readContextFile(props.contextFile);
|
|
200
|
-
if (existing.projectId || existing.orgId) throw new Error(`${props.contextFile} already links this directory to a Neon project. Run \`neon claim create\` from an unlinked directory.`);
|
|
201
|
-
const contextFileExisted = existsSync(props.contextFile);
|
|
202
|
-
const cwd = props.cwd ?? process.cwd();
|
|
203
|
-
const envFile = props.envPull ? resolveEnvFilePath({
|
|
204
|
-
cwd,
|
|
205
|
-
contextFile: props.contextFile
|
|
206
|
-
}, props.file) : void 0;
|
|
207
|
-
const envFileExisted = envFile ? existsSync(envFile) : false;
|
|
208
|
-
const previousEnv = envFileExisted && envFile ? readFileSync(envFile) : void 0;
|
|
209
|
-
const client = new ClaimableClient(props.claimableHost);
|
|
210
|
-
const registration = await client.register({
|
|
211
|
-
capabilities: claimableCapabilities(props.services ?? []),
|
|
212
|
-
source: "neon_cli",
|
|
213
|
-
...props.regionId !== void 0 ? { regionId: props.regionId } : {},
|
|
214
|
-
...props.dataApi ? { dataApi: props.dataApi } : {}
|
|
215
|
-
});
|
|
216
|
-
const stored = {
|
|
217
|
-
version: 1,
|
|
218
|
-
origin: client.origin,
|
|
219
|
-
registrationId: registration.registrationId,
|
|
220
|
-
projectId: registration.project.id,
|
|
221
|
-
branchId: registration.project.branchId,
|
|
222
|
-
identityAssertion: registration.identityAssertion,
|
|
223
|
-
expiresAt: registration.project.expiresAt,
|
|
224
|
-
assertionExpires: registration.assertionExpires
|
|
225
|
-
};
|
|
226
|
-
let localStateWritten = false;
|
|
227
|
-
let contextWritten = false;
|
|
228
|
-
let envWriteAttempted = false;
|
|
229
|
-
let accessToken;
|
|
230
|
-
try {
|
|
231
|
-
writeClaimableCredentials(props.configDir, stored);
|
|
232
|
-
localStateWritten = true;
|
|
233
|
-
applyContext(props.contextFile, {
|
|
234
|
-
projectId: registration.project.id,
|
|
235
|
-
branch: registration.project.branchId
|
|
236
|
-
});
|
|
237
|
-
contextWritten = true;
|
|
238
|
-
const token = await client.exchange(registration.identityAssertion);
|
|
239
|
-
accessToken = token.accessToken;
|
|
240
|
-
if (envFile) {
|
|
241
|
-
const apiHost = `${client.origin}/v1`;
|
|
242
|
-
const apiClient = props.apiClient ?? getApiClient({
|
|
243
|
-
apiKey: token.accessToken,
|
|
244
|
-
apiHost
|
|
245
|
-
});
|
|
246
|
-
envWriteAttempted = true;
|
|
247
|
-
if ((await pull({
|
|
248
|
-
apiClient,
|
|
249
|
-
apiKey: token.accessToken,
|
|
250
|
-
apiHost,
|
|
251
|
-
configDir: props.configDir,
|
|
252
|
-
contextFile: props.contextFile,
|
|
253
|
-
output: props.output,
|
|
254
|
-
projectId: registration.project.id,
|
|
255
|
-
branch: registration.project.branchId,
|
|
256
|
-
cwd,
|
|
257
|
-
file: props.file,
|
|
258
|
-
...props.config ? { config: props.config } : {},
|
|
259
|
-
...props.runtimeApi ? { runtimeApi: props.runtimeApi } : {}
|
|
260
|
-
})).status === "empty") throw new Error("No Neon env variables were pulled for this claimable project.");
|
|
261
|
-
}
|
|
262
|
-
const granted = registration.capabilities.filter((decision) => decision.granted).map((decision) => cliServiceName(decision.capability));
|
|
263
|
-
const denied = registration.capabilities.filter((decision) => !decision.granted).map((decision) => ({
|
|
264
|
-
capability: cliServiceName(decision.capability),
|
|
265
|
-
reason: decision.reason,
|
|
266
|
-
message: decision.message
|
|
267
|
-
}));
|
|
268
|
-
writer(props).end({
|
|
269
|
-
project_id: registration.project.id,
|
|
270
|
-
branch_id: registration.project.branchId,
|
|
271
|
-
region_id: registration.project.regionId,
|
|
272
|
-
state: "unclaimed",
|
|
273
|
-
project_expires_at: registration.project.expiresAt,
|
|
274
|
-
granted_capabilities: granted,
|
|
275
|
-
denied_capabilities: denied,
|
|
276
|
-
...envFile ? { env_file: envFile } : {}
|
|
277
|
-
}, {
|
|
278
|
-
fields: claimCreateFields(denied),
|
|
279
|
-
renderColumns: { denied_capabilities: (row) => row.denied_capabilities.map((decision) => `${decision.capability}: ${decision.message}`).join(", ") }
|
|
280
|
-
});
|
|
281
|
-
} catch (error) {
|
|
282
|
-
let remoteDeleted = false;
|
|
283
|
-
try {
|
|
284
|
-
const cleanupToken = accessToken ?? (await client.exchange(registration.identityAssertion)).accessToken;
|
|
285
|
-
await client.deleteProject(registration.project.id, cleanupToken);
|
|
286
|
-
remoteDeleted = true;
|
|
287
|
-
} catch (cleanupError) {
|
|
288
|
-
log.error("Claimable project %s could not be cleaned up after create failed: %s", registration.project.id, failureMessage(cleanupError));
|
|
289
|
-
if (localStateWritten && contextWritten) log.error("Retry cleanup with `neon claim delete --yes` from this directory.");
|
|
290
|
-
}
|
|
291
|
-
if (remoteDeleted) try {
|
|
292
|
-
if (localStateWritten) removeClaimableCredentials(props.configDir, registration.project.id);
|
|
293
|
-
if (contextWritten) {
|
|
294
|
-
if (contextFileExisted) applyContext(props.contextFile, existing);
|
|
295
|
-
else removeFileIfPresent(props.contextFile);
|
|
296
|
-
}
|
|
297
|
-
if (envWriteAttempted && envFile) {
|
|
298
|
-
if (envFileExisted && previousEnv) writeFileSync(envFile, previousEnv);
|
|
299
|
-
else removeFileIfPresent(envFile);
|
|
300
|
-
}
|
|
301
|
-
} catch (rollbackError) {
|
|
302
|
-
log.error("Project cleanup succeeded, but local rollback failed: %s", failureMessage(rollbackError));
|
|
303
|
-
}
|
|
304
|
-
throw error;
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
const status = async (props) => {
|
|
308
|
-
const { projectId, credentials, client, contextMatches } = resolveTarget(props);
|
|
309
|
-
if (assertionHasExpired(credentials)) {
|
|
310
|
-
writer(props).end({
|
|
311
|
-
project_id: projectId,
|
|
312
|
-
state: "expired",
|
|
313
|
-
reconciled: false,
|
|
314
|
-
project_expires_at: credentials.expiresAt
|
|
315
|
-
}, { fields: [
|
|
316
|
-
"project_id",
|
|
317
|
-
"state",
|
|
318
|
-
"reconciled",
|
|
319
|
-
"project_expires_at"
|
|
320
|
-
] });
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
try {
|
|
324
|
-
const token = await client.exchange(credentials.identityAssertion);
|
|
325
|
-
let claimState = "unclaimed";
|
|
326
|
-
let reconciled = false;
|
|
327
|
-
let claimExpiresAt;
|
|
328
|
-
try {
|
|
329
|
-
const claim = await client.claimStatus(projectId, token.accessToken);
|
|
330
|
-
claimState = claim.state;
|
|
331
|
-
reconciled = claim.reconciled;
|
|
332
|
-
claimExpiresAt = claim.expiresAt;
|
|
333
|
-
} catch (error) {
|
|
334
|
-
if (!(error instanceof ClaimableServiceError) || error.code !== "not_found") throw error;
|
|
335
|
-
}
|
|
336
|
-
if (reconciled) finishClaimedContext(props, projectId, contextMatches);
|
|
337
|
-
writer(props).end({
|
|
338
|
-
project_id: projectId,
|
|
339
|
-
state: claimState,
|
|
340
|
-
reconciled,
|
|
341
|
-
project_expires_at: credentials.expiresAt,
|
|
342
|
-
...claimExpiresAt ? { claim_expires_at: claimExpiresAt } : {}
|
|
343
|
-
}, { fields: [
|
|
344
|
-
"project_id",
|
|
345
|
-
"state",
|
|
346
|
-
"reconciled",
|
|
347
|
-
"project_expires_at",
|
|
348
|
-
"claim_expires_at"
|
|
349
|
-
] });
|
|
350
|
-
} catch (error) {
|
|
351
|
-
if (error instanceof ClaimableServiceError && error.code === "project_claimed") {
|
|
352
|
-
finishClaimedContext(props, projectId, contextMatches);
|
|
353
|
-
writer(props).end({
|
|
354
|
-
project_id: projectId,
|
|
355
|
-
state: "claimed",
|
|
356
|
-
reconciled: true
|
|
357
|
-
}, { fields: [
|
|
358
|
-
"project_id",
|
|
359
|
-
"state",
|
|
360
|
-
"reconciled"
|
|
361
|
-
] });
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
if (isUnusableIdentity(error)) {
|
|
365
|
-
writer(props).end({
|
|
366
|
-
project_id: projectId,
|
|
367
|
-
state: "expired",
|
|
368
|
-
reconciled: false,
|
|
369
|
-
project_expires_at: credentials.expiresAt
|
|
370
|
-
}, { fields: [
|
|
371
|
-
"project_id",
|
|
372
|
-
"state",
|
|
373
|
-
"reconciled",
|
|
374
|
-
"project_expires_at"
|
|
375
|
-
] });
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
throw error;
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
const accept = async (props) => {
|
|
382
|
-
const { projectId, credentials, client } = resolveTarget(props);
|
|
383
|
-
requireLiveIdentity(credentials);
|
|
384
|
-
const token = await client.exchange(credentials.identityAssertion);
|
|
385
|
-
const claim = await client.createClaim(projectId, token.accessToken);
|
|
386
|
-
writer(props).end({
|
|
387
|
-
project_id: projectId,
|
|
388
|
-
user_code: claim.userCode,
|
|
389
|
-
verification_url: claim.verificationUriComplete,
|
|
390
|
-
expires_in_seconds: claim.expiresIn
|
|
391
|
-
}, { fields: [
|
|
392
|
-
"project_id",
|
|
393
|
-
"user_code",
|
|
394
|
-
"verification_url",
|
|
395
|
-
"expires_in_seconds"
|
|
396
|
-
] });
|
|
397
|
-
if (props.open && !isCi()) open(claim.verificationUriComplete).catch(() => {
|
|
398
|
-
log.info("Could not open a browser. Open %s", claim.verificationUriComplete);
|
|
399
|
-
});
|
|
400
|
-
else if (props.open) log.info("Browser opening is disabled in CI. Open %s", claim.verificationUriComplete);
|
|
401
|
-
};
|
|
402
|
-
const list = (props) => {
|
|
403
|
-
rejectExplicitAccountCredential(props);
|
|
404
|
-
const projects = listClaimableCredentials(props.configDir).map((item) => {
|
|
405
|
-
const projectMs = Date.parse(item.expiresAt);
|
|
406
|
-
const projectExpired = Number.isFinite(projectMs) && projectMs <= Date.now();
|
|
407
|
-
return {
|
|
408
|
-
project_id: item.projectId,
|
|
409
|
-
branch_id: item.branchId,
|
|
410
|
-
state: assertionHasExpired(item) || projectExpired ? "expired" : "unclaimed",
|
|
411
|
-
project_expires_at: item.expiresAt,
|
|
412
|
-
origin: item.origin
|
|
413
|
-
};
|
|
414
|
-
});
|
|
415
|
-
writer(props).end(projects, {
|
|
416
|
-
fields: CLAIM_LIST_FIELDS,
|
|
417
|
-
emptyMessage: "No Claimable Neon projects are saved on this machine."
|
|
418
|
-
});
|
|
419
|
-
};
|
|
420
|
-
const deleteProject = async (props) => {
|
|
421
|
-
const { projectId, credentials, client, contextMatches } = resolveTarget(props);
|
|
422
|
-
if (!props.yes) {
|
|
423
|
-
if (isCi() || !process.stdin.isTTY) throw new Error("Deleting a claimable project requires confirmation. Re-run interactively or pass --yes.");
|
|
424
|
-
const { proceed } = await prompts({
|
|
425
|
-
type: "confirm",
|
|
426
|
-
name: "proceed",
|
|
427
|
-
message: `Permanently delete ${projectId}?`,
|
|
428
|
-
initial: false
|
|
429
|
-
});
|
|
430
|
-
if (!proceed) {
|
|
431
|
-
log.info("Claimable project was not deleted.");
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
if (assertionHasExpired(credentials)) {
|
|
436
|
-
clearLocalRecord(props, projectId, contextMatches);
|
|
437
|
-
writer(props).end({
|
|
438
|
-
project_id: projectId,
|
|
439
|
-
state: "cleared"
|
|
440
|
-
}, { fields: ["project_id", "state"] });
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
try {
|
|
444
|
-
const token = await client.exchange(credentials.identityAssertion);
|
|
445
|
-
await client.deleteProject(projectId, token.accessToken);
|
|
446
|
-
} catch (error) {
|
|
447
|
-
if (!isUnusableIdentity(error)) throw error;
|
|
448
|
-
clearLocalRecord(props, projectId, contextMatches);
|
|
449
|
-
writer(props).end({
|
|
450
|
-
project_id: projectId,
|
|
451
|
-
state: "cleared"
|
|
452
|
-
}, { fields: ["project_id", "state"] });
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
clearLocalRecord(props, projectId, contextMatches);
|
|
456
|
-
writer(props).end({
|
|
457
|
-
project_id: projectId,
|
|
458
|
-
state: "deleted"
|
|
459
|
-
}, { fields: ["project_id", "state"] });
|
|
460
|
-
};
|
|
461
|
-
const finishClaimedContext = (props, projectId, contextMatches) => {
|
|
462
|
-
removeClaimableCredentials(props.configDir, projectId);
|
|
463
|
-
if (contextMatches && existsSync(props.contextFile)) {
|
|
464
|
-
const context = readContextFile(props.contextFile);
|
|
465
|
-
applyContext(props.contextFile, {
|
|
466
|
-
projectId: context.projectId,
|
|
467
|
-
...contextBranch(context) ? { branch: contextBranch(context) } : {}
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
log.info("Dropped the local identity assertion. The next command needs `neon login` or `neon link`.");
|
|
471
|
-
};
|
|
472
|
-
//#endregion
|
|
473
|
-
export { CLAIM_CREATE_FIELDS, CLAIM_LIST_FIELDS, aliases, builder, claimCreateFields, claimableCapabilities, command, create, describe, handler, claim_exports as t };
|
|
1
|
+
export { t as CLAIM_CREATE_FIELDS, n as CLAIM_LIST_FIELDS, r as aliases, i as builder, a as claimCreateFields, s as claimableCapabilities, c as command, l as create, u as describe, d as handler } from "../_chunks/claim-DqAvAvDm.js";
|