@zuplo/cli 6.69.1 → 6.69.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/dist/__tests__/integration/info.integration.test.d.ts +2 -0
- package/dist/__tests__/integration/info.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/info.integration.test.js +246 -0
- package/dist/__tests__/integration/info.integration.test.js.map +1 -0
- package/dist/__tests__/integration/jest-mocks-setup.js +6 -1
- package/dist/__tests__/integration/jest-mocks-setup.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/cmds/info.d.ts +9 -0
- package/dist/cmds/info.d.ts.map +1 -0
- package/dist/cmds/info.js +19 -0
- package/dist/cmds/info.js.map +1 -0
- package/dist/cmds/project/index.d.ts.map +1 -1
- package/dist/cmds/project/index.js +2 -1
- package/dist/cmds/project/index.js.map +1 -1
- package/dist/cmds/project/info.d.ts +10 -0
- package/dist/cmds/project/info.d.ts.map +1 -0
- package/dist/cmds/project/info.js +50 -0
- package/dist/cmds/project/info.js.map +1 -0
- package/dist/common/middleware/authentication.d.ts +5 -2
- package/dist/common/middleware/authentication.d.ts.map +1 -1
- package/dist/common/middleware/authentication.js +27 -20
- package/dist/common/middleware/authentication.js.map +1 -1
- package/dist/common/read-linked-config.d.ts +1 -0
- package/dist/common/read-linked-config.d.ts.map +1 -1
- package/dist/common/read-linked-config.js +1 -0
- package/dist/common/read-linked-config.js.map +1 -1
- package/dist/common/read-linked-config.test.js +15 -0
- package/dist/common/read-linked-config.test.js.map +1 -1
- package/dist/project/info/handler.d.ts +7 -0
- package/dist/project/info/handler.d.ts.map +1 -0
- package/dist/project/info/handler.js +109 -0
- package/dist/project/info/handler.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/types/index.d.ts +0 -1
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/node_modules/uuid/dist/cjs/v35.js +3 -0
- package/node_modules/uuid/dist/cjs/v6.js +3 -0
- package/node_modules/uuid/dist/cjs-browser/v35.js +3 -0
- package/node_modules/uuid/dist/cjs-browser/v6.js +3 -0
- package/node_modules/uuid/dist/esm/v35.js +3 -0
- package/node_modules/uuid/dist/esm/v6.js +3 -0
- package/node_modules/uuid/dist/esm-browser/v35.js +3 -0
- package/node_modules/uuid/dist/esm-browser/v6.js +3 -0
- package/node_modules/uuid/package.json +1 -1
- package/package.json +6 -6
|
@@ -15,28 +15,35 @@ Please provide an API key using one of the following methods:
|
|
|
15
15
|
|
|
16
16
|
You can create an API key at: https://portal.zuplo.com`);
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let token = await getAuthToken();
|
|
24
|
-
if (!token) {
|
|
25
|
-
if (!isInteractiveTerminal()) {
|
|
26
|
-
return failNonInteractive();
|
|
18
|
+
function makeAuthenticate(opts) {
|
|
19
|
+
return async function authenticate(argv) {
|
|
20
|
+
if (argv["api-key"]) {
|
|
21
|
+
Object.assign(argv, { authToken: argv["api-key"] });
|
|
22
|
+
return;
|
|
27
23
|
}
|
|
28
|
-
|
|
29
|
-
message: "You are not authenticated. Would you like to log in?",
|
|
30
|
-
});
|
|
31
|
-
if (!result) {
|
|
32
|
-
return fail();
|
|
33
|
-
}
|
|
34
|
-
await login();
|
|
35
|
-
token = await getAuthToken();
|
|
24
|
+
let token = await getAuthToken();
|
|
36
25
|
if (!token) {
|
|
37
|
-
|
|
26
|
+
if (!isInteractiveTerminal()) {
|
|
27
|
+
return failNonInteractive();
|
|
28
|
+
}
|
|
29
|
+
if (!opts.promptToLogin) {
|
|
30
|
+
return fail();
|
|
31
|
+
}
|
|
32
|
+
const result = await confirm({
|
|
33
|
+
message: "You are not authenticated. Would you like to log in?",
|
|
34
|
+
});
|
|
35
|
+
if (!result) {
|
|
36
|
+
return fail();
|
|
37
|
+
}
|
|
38
|
+
await login();
|
|
39
|
+
token = await getAuthToken();
|
|
40
|
+
if (!token) {
|
|
41
|
+
return fail();
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
Object.assign(argv, { authToken: token });
|
|
45
|
+
};
|
|
41
46
|
}
|
|
47
|
+
export const authenticate = makeAuthenticate({ promptToLogin: true });
|
|
48
|
+
export const authenticateNoPrompt = makeAuthenticate({ promptToLogin: false });
|
|
42
49
|
//# sourceMappingURL=authentication.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../../src/common/middleware/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,oCAAoC,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,KAAK,UAAU,IAAI;IACjB,MAAM,oCAAoC,CACxC,oFAAoF,CACrF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,MAAM,oCAAoC,CACxC;;;;;;uDAMmD,CACpD,CAAC;AACJ,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../../src/common/middleware/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,oCAAoC,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,KAAK,UAAU,IAAI;IACjB,MAAM,oCAAoC,CACxC,oFAAoF,CACrF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,MAAM,oCAAoC,CACxC;;;;;;uDAMmD,CACpD,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAgC;IACxD,OAAO,KAAK,UAAU,YAAY,CAAC,IAA4B;QAC7D,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,IAAI,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;YAEX,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;gBAC7B,OAAO,kBAAkB,EAAE,CAAC;YAC9B,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;gBAC3B,OAAO,EAAE,sDAAsD;aAChE,CAAC,CAAC;YAGH,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YAGD,MAAM,KAAK,EAAE,CAAC;YAGd,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAGD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC","sourcesContent":["import { confirm } from \"@inquirer/prompts\";\nimport { login } from \"../../login/login.js\";\nimport { getAuthToken } from \"../../login/tokens.js\";\nimport { printCriticalFailureToConsoleAndExit } from \"../output.js\";\nimport { isInteractiveTerminal } from \"../terminal.js\";\n\nasync function fail() {\n await printCriticalFailureToConsoleAndExit(\n `You are not authenticated. Please run \\`zuplo login\\` to log in or set an api key.`\n );\n}\n\nasync function failNonInteractive() {\n await printCriticalFailureToConsoleAndExit(\n `Authentication required. This command requires an API key when running in non-interactive mode (e.g., CI/CD).\n\nPlease provide an API key using one of the following methods:\n 1. Pass the --api-key (or --apikey) flag: zuplo <command> --api-key YOUR_API_KEY\n 2. Set the environment variable: ZUPLO_API_KEY=YOUR_API_KEY\n\nYou can create an API key at: https://portal.zuplo.com`\n );\n}\n\nfunction makeAuthenticate(opts: { promptToLogin: boolean }) {\n return async function authenticate(argv: { \"api-key\"?: string }) {\n if (argv[\"api-key\"]) {\n Object.assign(argv, { authToken: argv[\"api-key\"] });\n return;\n }\n\n let token = await getAuthToken();\n\n if (!token) {\n // Check if we're in a non-interactive environment\n if (!isInteractiveTerminal()) {\n return failNonInteractive();\n }\n\n if (!opts.promptToLogin) {\n return fail();\n }\n\n const result = await confirm({\n message: \"You are not authenticated. Would you like to log in?\",\n });\n\n // IF the user said no, then return an error\n if (!result) {\n return fail();\n }\n\n // Login\n await login();\n\n // Validate the login again\n token = await getAuthToken();\n if (!token) {\n return fail();\n }\n }\n\n // Assign the token to the args\n Object.assign(argv, { authToken: token });\n };\n}\n\nexport const authenticate = makeAuthenticate({ promptToLogin: true });\nexport const authenticateNoPrompt = makeAuthenticate({ promptToLogin: false });\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-linked-config.d.ts","sourceRoot":"","sources":["../../src/common/read-linked-config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"read-linked-config.d.ts","sourceRoot":"","sources":["../../src/common/read-linked-config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAOrD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,YAAY,CAAC,CAuBxB;AAMD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GAAG,IAAI,CAE1E;AAQD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAmB1E"}
|
|
@@ -20,6 +20,7 @@ export async function readLinkedConfig(argv) {
|
|
|
20
20
|
config = {
|
|
21
21
|
accountName: parsed["ZUPLO_ACCOUNT_NAME"] || undefined,
|
|
22
22
|
projectName: parsed["ZUPLO_PROJECT_NAME"] || undefined,
|
|
23
|
+
environmentType: parsed["ZUPLO_ENVIRONMENT_TYPE"] || undefined,
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-linked-config.js","sourceRoot":"","sources":["../../src/common/read-linked-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"read-linked-config.js","sourceRoot":"","sources":["../../src/common/read-linked-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAQtD,MAAM,uBAAuB,GAAG,cAAc,CAAC;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAOrD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAEtC;IACC,IAAI,IAAI,CAAC,uBAAuB,CAAC,KAAK,SAAS,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,uBAAuB,CAAiB,CAAC;IACvD,CAAC;IACD,MAAM,GAAG,GAAI,IAAI,CAAC,GAA0B,IAAI,GAAG,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC,CAAC;IAC7D,IAAI,MAAoB,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,GAAG;YACP,WAAW,EAAE,MAAM,CAAC,oBAAoB,CAAC,IAAI,SAAS;YACtD,WAAW,EAAE,MAAM,CAAC,oBAAoB,CAAC,IAAI,SAAS;YACtD,eAAe,EAAE,MAAM,CAAC,wBAAwB,CAAC,IAAI,SAAS;SAC/D,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,8CAA8C,CAAC,CAAC;QACtE,CAAC;QACD,MAAM,GAAG,EAAE,CAAC;IACd,CAAC;IACD,IAAI,CAAC,uBAAuB,CAAC,GAAG,MAAM,CAAC;IACvC,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD,MAAM,UAAU,mBAAmB,CAAC,IAAgC;IAClE,IAAI,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;AACnC,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACnB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,QAAQ,CAAC,GAAG,OAAO,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YAC1C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC/C,OAAO,CAAC,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,IAAI,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport readline from \"node:readline\";\nimport dotenv from \"dotenv\";\nimport { ZUPLO_SYSTEM_ENV_VAR } from \"./constants.js\";\nimport { logger } from \"./logger.js\";\nimport { isInteractiveTerminal } from \"./terminal.js\";\n\nexport interface LinkedConfig {\n accountName?: string;\n projectName?: string;\n environmentType?: string;\n}\n\nconst LINKED_CONFIG_CACHE_KEY = \"linkedConfig\";\nexport const USE_LINKED_DETAILS = \"useLinkedDetails\";\n\n/**\n * Reads the linked project configuration from `.env.zuplo` if it exists.\n * Caches the result on argv to avoid reading the file multiple times per command.\n * Returns an empty object if the file is missing or cannot be parsed.\n */\nexport async function readLinkedConfig(argv: {\n [key: string]: unknown;\n}): Promise<LinkedConfig> {\n if (argv[LINKED_CONFIG_CACHE_KEY] !== undefined) {\n return argv[LINKED_CONFIG_CACHE_KEY] as LinkedConfig;\n }\n const dir = (argv.dir as string | undefined) ?? \".\";\n const envFilePath = join(resolve(dir), ZUPLO_SYSTEM_ENV_VAR);\n let config: LinkedConfig;\n try {\n const content = await readFile(envFilePath, \"utf-8\");\n const parsed = dotenv.parse(content);\n config = {\n accountName: parsed[\"ZUPLO_ACCOUNT_NAME\"] || undefined,\n projectName: parsed[\"ZUPLO_PROJECT_NAME\"] || undefined,\n environmentType: parsed[\"ZUPLO_ENVIRONMENT_TYPE\"] || undefined,\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.trace(error, \"Failed to read linked config from .env.zuplo\");\n }\n config = {};\n }\n argv[LINKED_CONFIG_CACHE_KEY] = config;\n return config;\n}\n\n/**\n * Middleware that prevents downstream middlewares from using linked config values.\n * Used by commands (e.g. link) that always re-prompt from scratch.\n */\nexport function ignoreLinkedDetails(argv: { [key: string]: unknown }): void {\n argv[USE_LINKED_DETAILS] = false;\n}\n\n/**\n * Prompts the user with a Y/n question using plain readline output.\n * Avoids @inquirer/prompts cursor management which conflicts with ora spinners.\n * Returns true immediately in non-interactive terminals. Callers should check\n * isInteractiveTerminal() and skip this call entirely when possible.\n */\nexport async function confirmLinkedValue(message: string): Promise<boolean> {\n if (!isInteractiveTerminal()) {\n return true;\n }\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.on(\"SIGINT\", () => {\n rl.close();\n process.exit(1);\n });\n rl.question(`${message} [Y/n] `, (answer) => {\n rl.close();\n const normalized = answer.trim().toLowerCase();\n resolve(normalized !== \"n\" && normalized !== \"no\");\n });\n });\n}\n"]}
|
|
@@ -25,6 +25,21 @@ describe("readLinkedConfig", () => {
|
|
|
25
25
|
assert.deepStrictEqual(result, {
|
|
26
26
|
accountName: "my-account",
|
|
27
27
|
projectName: "my-project",
|
|
28
|
+
environmentType: undefined,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it("returns environmentType when ZUPLO_ENVIRONMENT_TYPE is present", async () => {
|
|
32
|
+
await writeFile(join(testDir, ".env.zuplo"), [
|
|
33
|
+
"ZUPLO_ACCOUNT_NAME=my-account",
|
|
34
|
+
"ZUPLO_PROJECT_NAME=my-project",
|
|
35
|
+
"ZUPLO_ENVIRONMENT_TYPE=production",
|
|
36
|
+
].join("\n"), "utf-8");
|
|
37
|
+
const argv = { dir: testDir };
|
|
38
|
+
const result = await readLinkedConfig(argv);
|
|
39
|
+
assert.deepStrictEqual(result, {
|
|
40
|
+
accountName: "my-account",
|
|
41
|
+
projectName: "my-project",
|
|
42
|
+
environmentType: "production",
|
|
28
43
|
});
|
|
29
44
|
});
|
|
30
45
|
it("returns undefined for fields that are missing from the file", async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-linked-config.test.js","sourceRoot":"","sources":["../../src/common/read-linked-config.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert\";\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport readline from \"node:readline\";\nimport { afterEach, beforeEach, describe, it, mock } from \"node:test\";\nimport {\n confirmLinkedValue,\n readLinkedConfig,\n USE_LINKED_DETAILS,\n} from \"./read-linked-config.js\";\n\ndescribe(\"readLinkedConfig\", () => {\n let testDir: string;\n\n beforeEach(async () => {\n testDir = await mkdtemp(join(tmpdir(), \"zuplo-read-linked-config-test-\"));\n });\n\n afterEach(async () => {\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"returns empty object when .env.zuplo does not exist\", async () => {\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {});\n });\n\n it(\"returns both fields when all are present\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n [\"ZUPLO_ACCOUNT_NAME=my-account\", \"ZUPLO_PROJECT_NAME=my-project\"].join(\n \"\\n\"\n ),\n \"utf-8\"\n );\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {\n accountName: \"my-account\",\n projectName: \"my-project\",\n });\n });\n\n it(\"returns undefined for fields that are missing from the file\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n \"ZUPLO_ACCOUNT_NAME=my-account\\n\",\n \"utf-8\"\n );\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.strictEqual(result.accountName, \"my-account\");\n assert.strictEqual(result.projectName, undefined);\n });\n\n it(\"returns undefined for fields set to empty string\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n 'ZUPLO_ACCOUNT_NAME=\\nZUPLO_PROJECT_NAME=\"\"\\n',\n \"utf-8\"\n );\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.strictEqual(result.accountName, undefined);\n assert.strictEqual(result.projectName, undefined);\n });\n\n it(\"caches the result on argv so the file is only read once\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n \"ZUPLO_ACCOUNT_NAME=my-account\\n\",\n \"utf-8\"\n );\n const argv: { [key: string]: unknown } = { dir: testDir };\n\n const first = await readLinkedConfig(argv);\n // Delete the file — a second call must return the cached value, not throw\n await rm(join(testDir, \".env.zuplo\"));\n const second = await readLinkedConfig(argv);\n\n assert.strictEqual(first, second); // same object reference\n assert.strictEqual(second.accountName, \"my-account\");\n });\n\n it(\"returns empty object and does not throw on a malformed file\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n \"THIS IS NOT VALID\\x00ENV\\n\",\n \"utf-8\"\n );\n const argv = { dir: testDir };\n // dotenv silently skips lines it cannot parse, so no throw is expected\n const result = await readLinkedConfig(argv);\n assert.ok(typeof result === \"object\");\n });\n\n it(\"defaults dir to '.' when argv.dir is not set\", async () => {\n // Use testDir so the test is not sensitive to whether .env.zuplo exists in the process CWD\n const argv: { [key: string]: unknown } = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {});\n });\n});\n\ndescribe(\"confirmLinkedValue\", () => {\n let originalStdinIsTTY: PropertyDescriptor | undefined;\n let originalStdoutIsTTY: PropertyDescriptor | undefined;\n let originalCI: string | undefined;\n let hadCI: boolean;\n\n beforeEach(() => {\n originalStdinIsTTY = Object.getOwnPropertyDescriptor(\n process.stdin,\n \"isTTY\"\n );\n originalStdoutIsTTY = Object.getOwnPropertyDescriptor(\n process.stdout,\n \"isTTY\"\n );\n hadCI = Object.hasOwn(process.env, \"CI\");\n originalCI = process.env.CI;\n // Clear CI so isInteractiveTerminal() doesn't short-circuit the readline path\n // in CI environments (e.g. GitHub Actions sets CI=true automatically).\n delete process.env.CI;\n });\n\n afterEach(() => {\n mock.restoreAll();\n if (originalStdinIsTTY) {\n Object.defineProperty(process.stdin, \"isTTY\", originalStdinIsTTY);\n } else {\n delete (process.stdin as { isTTY?: boolean }).isTTY;\n }\n if (originalStdoutIsTTY) {\n Object.defineProperty(process.stdout, \"isTTY\", originalStdoutIsTTY);\n } else {\n delete (process.stdout as { isTTY?: boolean }).isTTY;\n }\n if (hadCI) {\n process.env.CI = originalCI;\n } else {\n delete process.env.CI;\n }\n });\n\n it(\"returns true immediately without prompting in non-interactive terminals\", async () => {\n // Make isInteractiveTerminal() return false by setting stdin to non-TTY.\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: false,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: false,\n configurable: true,\n });\n // readline must not be touched — if it were, the test would hang.\n const result = await confirmLinkedValue(\"Use linked account 'foo'?\");\n assert.strictEqual(result, true);\n });\n\n it(\"returns true when user enters 'y'\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"y\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n true\n );\n });\n\n it(\"returns true when user enters 'Y' (case-insensitive)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"Y\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n true\n );\n });\n\n it(\"returns true when user presses Enter (empty input — default yes)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n true\n );\n });\n\n it(\"returns false when user enters 'n'\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"n\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"returns false when user enters 'N' (case-insensitive)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"N\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"returns false when user enters 'no'\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"no\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"returns false when user enters 'NO' (case-insensitive)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"NO\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"exits the process when SIGINT is emitted on the readline interface\", () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n\n const exitStub = mock.method(process, \"exit\", () => {\n throw new Error(\"process.exit called\");\n });\n\n let sigintEmitter: (() => void) | undefined;\n mock.method(readline, \"createInterface\", () => ({\n on: (event: string, handler: () => void) => {\n if (event === \"SIGINT\") sigintEmitter = handler;\n },\n question: () => {\n /* never resolves */\n },\n close: mock.fn(),\n }));\n\n // Start the prompt — it won't resolve (question callback never fires)\n void confirmLinkedValue(\"Use linked account 'foo'?\");\n\n // Emitting SIGINT calls process.exit(1) synchronously; our mock throws to intercept it\n assert.throws(() => sigintEmitter!(), /process\\.exit called/);\n assert.strictEqual(exitStub.mock.calls[0].arguments[0], 1);\n });\n});\n\ndescribe(\"USE_LINKED_DETAILS\", () => {\n let testDir: string;\n\n beforeEach(async () => {\n testDir = await mkdtemp(join(tmpdir(), \"zuplo-use-linked-details-test-\"));\n });\n\n afterEach(async () => {\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"is exported and has the expected value\", () => {\n assert.strictEqual(USE_LINKED_DETAILS, \"useLinkedDetails\");\n });\n\n it(\"setting it to false on argv does not collide with the internal cache key\", async () => {\n // The useLinkedDetails key must not collide with the internal cache key so that\n // readLinkedConfig continues to work even when useLinkedDetails is false.\n const argv: { [key: string]: unknown } = {\n dir: testDir,\n [USE_LINKED_DETAILS]: false,\n };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {});\n });\n});\n\n/**\n * Helper: stub readline.createInterface so that the `question` callback is\n * called synchronously with `answer`, simulating user input.\n */\nfunction stubReadlineAnswer(answer: string) {\n mock.method(readline, \"createInterface\", () => ({\n on: () => {\n /* ignore SIGINT in these tests */\n },\n question: (_prompt: string, callback: (a: string) => void) => {\n callback(answer);\n },\n close: mock.fn(),\n }));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"read-linked-config.test.js","sourceRoot":"","sources":["../../src/common/read-linked-config.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert\";\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport readline from \"node:readline\";\nimport { afterEach, beforeEach, describe, it, mock } from \"node:test\";\nimport {\n confirmLinkedValue,\n readLinkedConfig,\n USE_LINKED_DETAILS,\n} from \"./read-linked-config.js\";\n\ndescribe(\"readLinkedConfig\", () => {\n let testDir: string;\n\n beforeEach(async () => {\n testDir = await mkdtemp(join(tmpdir(), \"zuplo-read-linked-config-test-\"));\n });\n\n afterEach(async () => {\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"returns empty object when .env.zuplo does not exist\", async () => {\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {});\n });\n\n it(\"returns both fields when all are present\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n [\"ZUPLO_ACCOUNT_NAME=my-account\", \"ZUPLO_PROJECT_NAME=my-project\"].join(\n \"\\n\"\n ),\n \"utf-8\"\n );\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {\n accountName: \"my-account\",\n projectName: \"my-project\",\n environmentType: undefined,\n });\n });\n\n it(\"returns environmentType when ZUPLO_ENVIRONMENT_TYPE is present\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n [\n \"ZUPLO_ACCOUNT_NAME=my-account\",\n \"ZUPLO_PROJECT_NAME=my-project\",\n \"ZUPLO_ENVIRONMENT_TYPE=production\",\n ].join(\"\\n\"),\n \"utf-8\"\n );\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {\n accountName: \"my-account\",\n projectName: \"my-project\",\n environmentType: \"production\",\n });\n });\n\n it(\"returns undefined for fields that are missing from the file\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n \"ZUPLO_ACCOUNT_NAME=my-account\\n\",\n \"utf-8\"\n );\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.strictEqual(result.accountName, \"my-account\");\n assert.strictEqual(result.projectName, undefined);\n });\n\n it(\"returns undefined for fields set to empty string\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n 'ZUPLO_ACCOUNT_NAME=\\nZUPLO_PROJECT_NAME=\"\"\\n',\n \"utf-8\"\n );\n const argv = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.strictEqual(result.accountName, undefined);\n assert.strictEqual(result.projectName, undefined);\n });\n\n it(\"caches the result on argv so the file is only read once\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n \"ZUPLO_ACCOUNT_NAME=my-account\\n\",\n \"utf-8\"\n );\n const argv: { [key: string]: unknown } = { dir: testDir };\n\n const first = await readLinkedConfig(argv);\n // Delete the file — a second call must return the cached value, not throw\n await rm(join(testDir, \".env.zuplo\"));\n const second = await readLinkedConfig(argv);\n\n assert.strictEqual(first, second); // same object reference\n assert.strictEqual(second.accountName, \"my-account\");\n });\n\n it(\"returns empty object and does not throw on a malformed file\", async () => {\n await writeFile(\n join(testDir, \".env.zuplo\"),\n \"THIS IS NOT VALID\\x00ENV\\n\",\n \"utf-8\"\n );\n const argv = { dir: testDir };\n // dotenv silently skips lines it cannot parse, so no throw is expected\n const result = await readLinkedConfig(argv);\n assert.ok(typeof result === \"object\");\n });\n\n it(\"defaults dir to '.' when argv.dir is not set\", async () => {\n // Use testDir so the test is not sensitive to whether .env.zuplo exists in the process CWD\n const argv: { [key: string]: unknown } = { dir: testDir };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {});\n });\n});\n\ndescribe(\"confirmLinkedValue\", () => {\n let originalStdinIsTTY: PropertyDescriptor | undefined;\n let originalStdoutIsTTY: PropertyDescriptor | undefined;\n let originalCI: string | undefined;\n let hadCI: boolean;\n\n beforeEach(() => {\n originalStdinIsTTY = Object.getOwnPropertyDescriptor(\n process.stdin,\n \"isTTY\"\n );\n originalStdoutIsTTY = Object.getOwnPropertyDescriptor(\n process.stdout,\n \"isTTY\"\n );\n hadCI = Object.hasOwn(process.env, \"CI\");\n originalCI = process.env.CI;\n // Clear CI so isInteractiveTerminal() doesn't short-circuit the readline path\n // in CI environments (e.g. GitHub Actions sets CI=true automatically).\n delete process.env.CI;\n });\n\n afterEach(() => {\n mock.restoreAll();\n if (originalStdinIsTTY) {\n Object.defineProperty(process.stdin, \"isTTY\", originalStdinIsTTY);\n } else {\n delete (process.stdin as { isTTY?: boolean }).isTTY;\n }\n if (originalStdoutIsTTY) {\n Object.defineProperty(process.stdout, \"isTTY\", originalStdoutIsTTY);\n } else {\n delete (process.stdout as { isTTY?: boolean }).isTTY;\n }\n if (hadCI) {\n process.env.CI = originalCI;\n } else {\n delete process.env.CI;\n }\n });\n\n it(\"returns true immediately without prompting in non-interactive terminals\", async () => {\n // Make isInteractiveTerminal() return false by setting stdin to non-TTY.\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: false,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: false,\n configurable: true,\n });\n // readline must not be touched — if it were, the test would hang.\n const result = await confirmLinkedValue(\"Use linked account 'foo'?\");\n assert.strictEqual(result, true);\n });\n\n it(\"returns true when user enters 'y'\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"y\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n true\n );\n });\n\n it(\"returns true when user enters 'Y' (case-insensitive)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"Y\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n true\n );\n });\n\n it(\"returns true when user presses Enter (empty input — default yes)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n true\n );\n });\n\n it(\"returns false when user enters 'n'\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"n\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"returns false when user enters 'N' (case-insensitive)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"N\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"returns false when user enters 'no'\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"no\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"returns false when user enters 'NO' (case-insensitive)\", async () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n stubReadlineAnswer(\"NO\");\n assert.strictEqual(\n await confirmLinkedValue(\"Use linked account 'foo'?\"),\n false\n );\n });\n\n it(\"exits the process when SIGINT is emitted on the readline interface\", () => {\n Object.defineProperty(process.stdin, \"isTTY\", {\n value: true,\n configurable: true,\n });\n Object.defineProperty(process.stdout, \"isTTY\", {\n value: true,\n configurable: true,\n });\n\n const exitStub = mock.method(process, \"exit\", () => {\n throw new Error(\"process.exit called\");\n });\n\n let sigintEmitter: (() => void) | undefined;\n mock.method(readline, \"createInterface\", () => ({\n on: (event: string, handler: () => void) => {\n if (event === \"SIGINT\") sigintEmitter = handler;\n },\n question: () => {\n /* never resolves */\n },\n close: mock.fn(),\n }));\n\n // Start the prompt — it won't resolve (question callback never fires)\n void confirmLinkedValue(\"Use linked account 'foo'?\");\n\n // Emitting SIGINT calls process.exit(1) synchronously; our mock throws to intercept it\n assert.throws(() => sigintEmitter!(), /process\\.exit called/);\n assert.strictEqual(exitStub.mock.calls[0].arguments[0], 1);\n });\n});\n\ndescribe(\"USE_LINKED_DETAILS\", () => {\n let testDir: string;\n\n beforeEach(async () => {\n testDir = await mkdtemp(join(tmpdir(), \"zuplo-use-linked-details-test-\"));\n });\n\n afterEach(async () => {\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"is exported and has the expected value\", () => {\n assert.strictEqual(USE_LINKED_DETAILS, \"useLinkedDetails\");\n });\n\n it(\"setting it to false on argv does not collide with the internal cache key\", async () => {\n // The useLinkedDetails key must not collide with the internal cache key so that\n // readLinkedConfig continues to work even when useLinkedDetails is false.\n const argv: { [key: string]: unknown } = {\n dir: testDir,\n [USE_LINKED_DETAILS]: false,\n };\n const result = await readLinkedConfig(argv);\n assert.deepStrictEqual(result, {});\n });\n});\n\n/**\n * Helper: stub readline.createInterface so that the `question` callback is\n * called synchronously with `answer`, simulating user input.\n */\nfunction stubReadlineAnswer(answer: string) {\n mock.method(readline, \"createInterface\", () => ({\n on: () => {\n /* ignore SIGINT in these tests */\n },\n question: (_prompt: string, callback: (a: string) => void) => {\n callback(answer);\n },\n close: mock.fn(),\n }));\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/project/info/handler.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAQD,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,iBAyIzC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { logger } from "../../common/logger.js";
|
|
2
|
+
import { printCriticalFailureToConsoleAndExit, printResultToConsoleAndExitGracefully, printWarningToConsole, textOrJson, } from "../../common/output.js";
|
|
3
|
+
import { readLinkedConfig } from "../../common/read-linked-config.js";
|
|
4
|
+
import settings from "../../common/settings.js";
|
|
5
|
+
const PORTAL_BASE_URL = "https://portal.zuplo.com";
|
|
6
|
+
export async function info(argv) {
|
|
7
|
+
const lines = [];
|
|
8
|
+
const linked = await readLinkedConfig(argv);
|
|
9
|
+
if (!linked.accountName || !linked.projectName) {
|
|
10
|
+
lines.push("No project linked. Run `zuplo link` to connect a project.");
|
|
11
|
+
await printResultToConsoleAndExitGracefully(lines.join("\n"));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const account = linked.accountName;
|
|
15
|
+
const project = linked.projectName;
|
|
16
|
+
let projectData;
|
|
17
|
+
let fetchFailed = false;
|
|
18
|
+
let response;
|
|
19
|
+
try {
|
|
20
|
+
const projectsUrl = new URL(`${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/projects`);
|
|
21
|
+
projectsUrl.searchParams.set("accountName", account);
|
|
22
|
+
response = await fetch(projectsUrl, {
|
|
23
|
+
method: "GET",
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: `Bearer ${argv.authToken}`,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
logger.debug(error, "Failed to fetch project details");
|
|
31
|
+
fetchFailed = true;
|
|
32
|
+
}
|
|
33
|
+
if (response?.status === 401) {
|
|
34
|
+
let body = "<unavailable>";
|
|
35
|
+
try {
|
|
36
|
+
body = await response.text();
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
logger.debug(error, "Failed to read response body");
|
|
40
|
+
}
|
|
41
|
+
logger.debug({
|
|
42
|
+
status: response.status,
|
|
43
|
+
statusText: response.statusText,
|
|
44
|
+
response: textOrJson(body),
|
|
45
|
+
}, "Failed to fetch project details");
|
|
46
|
+
const message = argv["api-key"]
|
|
47
|
+
? "The provided --api-key was rejected. Check that it is valid and not expired, or run `zuplo login` to authenticate interactively."
|
|
48
|
+
: "Your saved credentials were rejected. They may be expired — run `zuplo login` to re-authenticate, or pass a valid --api-key.";
|
|
49
|
+
await printCriticalFailureToConsoleAndExit(message);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (response?.ok) {
|
|
53
|
+
try {
|
|
54
|
+
const body = (await response.json());
|
|
55
|
+
if (!Array.isArray(body.data)) {
|
|
56
|
+
throw new Error("Projects API response did not include a data array");
|
|
57
|
+
}
|
|
58
|
+
logger.debug({ projects: body.data, linkedProject: project }, "Projects API response");
|
|
59
|
+
projectData = body.data.find((p) => p.name === project);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
logger.debug(error, "Failed to parse project details response");
|
|
63
|
+
fetchFailed = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (response) {
|
|
67
|
+
let body = "<unavailable>";
|
|
68
|
+
try {
|
|
69
|
+
body = await response.text();
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
logger.debug(error, "Failed to read response body");
|
|
73
|
+
}
|
|
74
|
+
logger.debug({
|
|
75
|
+
status: response.status,
|
|
76
|
+
statusText: response.statusText,
|
|
77
|
+
response: textOrJson(body),
|
|
78
|
+
}, "Failed to fetch project details");
|
|
79
|
+
if (response.status >= 400 && response.status < 500) {
|
|
80
|
+
await printCriticalFailureToConsoleAndExit(`The Zuplo API returned ${response.status} ${response.statusText}. Verify the account "${account}" and your credentials.`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
fetchFailed = true;
|
|
84
|
+
}
|
|
85
|
+
lines.push(`Project: ${project}`);
|
|
86
|
+
lines.push(`Account: ${account}`);
|
|
87
|
+
lines.push(`Portal: ${PORTAL_BASE_URL}/${account}/${project}`);
|
|
88
|
+
if (linked.environmentType) {
|
|
89
|
+
lines.push(`Environment Type: ${linked.environmentType}`);
|
|
90
|
+
}
|
|
91
|
+
const projectNotFound = !fetchFailed && response?.ok === true && !projectData;
|
|
92
|
+
if (!fetchFailed && !projectNotFound) {
|
|
93
|
+
const sourceControlSettingsUrl = `${PORTAL_BASE_URL}/${account}/${project}/settings/source-control-settings`;
|
|
94
|
+
if (projectData?.sourceRepoUrl) {
|
|
95
|
+
lines.push(`Source Control: ${projectData.sourceRepoUrl}`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
lines.push(`Source Control: none, connect at ${sourceControlSettingsUrl}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (fetchFailed) {
|
|
102
|
+
printWarningToConsole("Unable to fetch project details, some information may be missing");
|
|
103
|
+
}
|
|
104
|
+
else if (projectNotFound) {
|
|
105
|
+
printWarningToConsole(`Project "${project}" was not found in account "${account}". Run \`zuplo link\` to link a project.`);
|
|
106
|
+
}
|
|
107
|
+
await printResultToConsoleAndExitGracefully(lines.join("\n"));
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/project/info/handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { logger } from \"../../common/logger.js\";\nimport {\n printCriticalFailureToConsoleAndExit,\n printResultToConsoleAndExitGracefully,\n printWarningToConsole,\n textOrJson,\n} from \"../../common/output.js\";\nimport { readLinkedConfig } from \"../../common/read-linked-config.js\";\nimport settings from \"../../common/settings.js\";\n\nconst PORTAL_BASE_URL = \"https://portal.zuplo.com\";\n\nexport interface Arguments extends Record<string, unknown> {\n authToken: string;\n \"api-key\"?: string;\n dir?: string;\n}\n\ninterface ProjectListItem {\n name: string;\n sourceRepoUrl: string | null;\n sourceControlProvider: string;\n}\n\nexport async function info(argv: Arguments) {\n const lines: string[] = [];\n\n // 1. Read linked config from .env.zuplo\n const linked = await readLinkedConfig(argv);\n\n // If no linked project, show guidance and exit\n if (!linked.accountName || !linked.projectName) {\n lines.push(\"No project linked. Run `zuplo link` to connect a project.\");\n await printResultToConsoleAndExitGracefully(lines.join(\"\\n\"));\n return;\n }\n\n const account = linked.accountName;\n const project = linked.projectName;\n\n // 2. Fetch project details from the projects list API for source control info\n let projectData: ProjectListItem | undefined;\n let fetchFailed = false;\n let response: Response | undefined;\n try {\n const projectsUrl = new URL(\n `${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/projects`\n );\n projectsUrl.searchParams.set(\"accountName\", account);\n response = await fetch(projectsUrl, {\n method: \"GET\",\n headers: {\n // biome-ignore lint/style/useNamingConvention: External API property\n Authorization: `Bearer ${argv.authToken}`,\n },\n });\n } catch (error) {\n logger.debug(error, \"Failed to fetch project details\");\n fetchFailed = true;\n }\n\n if (response?.status === 401) {\n let body = \"<unavailable>\";\n try {\n body = await response.text();\n } catch (error) {\n logger.debug(error, \"Failed to read response body\");\n }\n logger.debug(\n {\n status: response.status,\n statusText: response.statusText,\n response: textOrJson(body),\n },\n \"Failed to fetch project details\"\n );\n const message = argv[\"api-key\"]\n ? \"The provided --api-key was rejected. Check that it is valid and not expired, or run `zuplo login` to authenticate interactively.\"\n : \"Your saved credentials were rejected. They may be expired — run `zuplo login` to re-authenticate, or pass a valid --api-key.\";\n await printCriticalFailureToConsoleAndExit(message);\n return;\n }\n\n if (response?.ok) {\n try {\n const body = (await response.json()) as {\n data?: ProjectListItem[];\n };\n if (!Array.isArray(body.data)) {\n throw new Error(\"Projects API response did not include a data array\");\n }\n logger.debug(\n { projects: body.data, linkedProject: project },\n \"Projects API response\"\n );\n projectData = body.data.find((p) => p.name === project);\n } catch (error) {\n logger.debug(error, \"Failed to parse project details response\");\n fetchFailed = true;\n }\n } else if (response) {\n let body = \"<unavailable>\";\n try {\n body = await response.text();\n } catch (error) {\n logger.debug(error, \"Failed to read response body\");\n }\n logger.debug(\n {\n status: response.status,\n statusText: response.statusText,\n response: textOrJson(body),\n },\n \"Failed to fetch project details\"\n );\n // Treat 4xx (other than 401) as hard errors — they indicate a problem the\n // user must fix (bad account, missing permission, rate limit). 5xx falls\n // through to a transient warn+fallback below.\n if (response.status >= 400 && response.status < 500) {\n await printCriticalFailureToConsoleAndExit(\n `The Zuplo API returned ${response.status} ${response.statusText}. Verify the account \"${account}\" and your credentials.`\n );\n return;\n }\n fetchFailed = true;\n }\n\n // 3. Build the output\n lines.push(`Project: ${project}`);\n lines.push(`Account: ${account}`);\n lines.push(`Portal: ${PORTAL_BASE_URL}/${account}/${project}`);\n\n if (linked.environmentType) {\n lines.push(`Environment Type: ${linked.environmentType}`);\n }\n\n const projectNotFound = !fetchFailed && response?.ok === true && !projectData;\n\n // Source control info — only show when we successfully found the project\n if (!fetchFailed && !projectNotFound) {\n const sourceControlSettingsUrl = `${PORTAL_BASE_URL}/${account}/${project}/settings/source-control-settings`;\n if (projectData?.sourceRepoUrl) {\n lines.push(`Source Control: ${projectData.sourceRepoUrl}`);\n } else {\n lines.push(\n `Source Control: none, connect at ${sourceControlSettingsUrl}`\n );\n }\n }\n\n if (fetchFailed) {\n printWarningToConsole(\n \"Unable to fetch project details, some information may be missing\"\n );\n } else if (projectNotFound) {\n printWarningToConsole(\n `Project \"${project}\" was not found in account \"${account}\". Run \\`zuplo link\\` to link a project.`\n );\n }\n\n await printResultToConsoleAndExitGracefully(lines.join(\"\\n\"));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/cli.ts","../src/internal.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/outdated.test.ts","../src/__tests__/populate.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/__tests__/integration/custom-domain.integration.test.ts","../src/__tests__/integration/delete.integration.test.ts","../src/__tests__/integration/deploy.integration.test.ts","../src/__tests__/integration/get-project-param.integration.test.ts","../src/__tests__/integration/jest-mocks-setup.ts","../src/__tests__/integration/jest-setup.ts","../src/__tests__/integration/link.integration.test.ts","../src/__tests__/integration/linked-config-cascade.integration.test.ts","../src/__tests__/integration/list.integration.test.ts","../src/__tests__/integration/test-utils.ts","../src/__tests__/integration/tunnel.integration.test.ts","../src/__tests__/integration/variable.integration.test.ts","../src/__tests__/integration/whoami.integration.test.ts","../src/build/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/docs.ts","../src/cmds/editor.ts","../src/cmds/init.ts","../src/cmds/link.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/test.ts","../src/cmds/whoami.ts","../src/cmds/custom-domain/create.ts","../src/cmds/custom-domain/delete.ts","../src/cmds/custom-domain/index.ts","../src/cmds/custom-domain/list.ts","../src/cmds/custom-domain/update.ts","../src/cmds/mtls-certificates/create.ts","../src/cmds/mtls-certificates/delete.ts","../src/cmds/mtls-certificates/describe.ts","../src/cmds/mtls-certificates/disable.ts","../src/cmds/mtls-certificates/index.ts","../src/cmds/mtls-certificates/list.ts","../src/cmds/mtls-certificates/update.ts","../src/cmds/open-api/convert.ts","../src/cmds/open-api/index.ts","../src/cmds/open-api/merge.ts","../src/cmds/open-api/overlay.ts","../src/cmds/project/create.ts","../src/cmds/project/index.ts","../src/cmds/proxies/create.ts","../src/cmds/proxies/delete.ts","../src/cmds/proxies/describe.ts","../src/cmds/proxies/index.ts","../src/cmds/proxies/update.ts","../src/cmds/source/import-openapi.ts","../src/cmds/source/index.ts","../src/cmds/source/migrate.ts","../src/cmds/source/upgrade.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/constants.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/populate.ts","../src/common/read-linked-config.test.ts","../src/common/read-linked-config.ts","../src/common/runner.ts","../src/common/settings.ts","../src/common/terminal.test.ts","../src/common/terminal.ts","../src/common/worker-output.ts","../src/common/analytics/lib.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/get-account-param.ts","../src/common/middleware/get-environment-param.ts","../src/common/middleware/get-project-param.ts","../src/common/middleware/logging.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/middleware/validate-fleet.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/branch.ts","../src/common/utils/ports.ts","../src/common/utils/prefixed-output.ts","../src/common/utils/pretty-print-environment-prompt.test.ts","../src/common/utils/pretty-print-environment-prompt.ts","../src/common/utils/stringify-config.test.ts","../src/common/utils/stringify-config.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/argument-validators.spec.ts","../src/common/validators/argument-validators.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/custom-domain/models.ts","../src/custom-domain/create/handler.ts","../src/custom-domain/delete/handler.ts","../src/custom-domain/list/handler.ts","../src/custom-domain/update/handler.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.local-registry.test.ts","../src/deploy/archive.test.ts","../src/deploy/archive.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/docs/handler.ts","../src/editor/handler.ts","../src/editor/e2e/editor.spec.ts","../src/init/handler.ts","../src/link/handler.ts","../src/list/handler.ts","../src/login/login.ts","../src/login/tokens.ts","../src/mtls-certificates/models.ts","../src/mtls-certificates/create/handler.ts","../src/mtls-certificates/delete/handler.ts","../src/mtls-certificates/describe/handler.ts","../src/mtls-certificates/disable/handler.ts","../src/mtls-certificates/list/handler.ts","../src/mtls-certificates/update/handler.ts","../src/open-api/convert/handler.spec.ts","../src/open-api/convert/handler.ts","../src/open-api/merge/handler.spec.ts","../src/open-api/merge/handler.ts","../src/open-api/overlay/handler.spec.ts","../src/open-api/overlay/handler.ts","../src/project/create/handler.ts","../src/proxies/models.ts","../src/proxies/create/handler.ts","../src/proxies/delete/handler.ts","../src/proxies/describe/handler.ts","../src/proxies/update/handler.ts","../src/source/migrate/dev-portal/handler.ts","../src/source/migrate/dev-portal/types.ts","../src/source/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.ts","../src/test/test-files.test.ts","../src/test/test-files.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts","../src/whoami/handler.ts"],"version":"5.8.2"}
|
|
1
|
+
{"root":["../src/cli.ts","../src/internal.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/outdated.test.ts","../src/__tests__/populate.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/__tests__/integration/custom-domain.integration.test.ts","../src/__tests__/integration/delete.integration.test.ts","../src/__tests__/integration/deploy.integration.test.ts","../src/__tests__/integration/get-project-param.integration.test.ts","../src/__tests__/integration/info.integration.test.ts","../src/__tests__/integration/jest-mocks-setup.ts","../src/__tests__/integration/jest-setup.ts","../src/__tests__/integration/link.integration.test.ts","../src/__tests__/integration/linked-config-cascade.integration.test.ts","../src/__tests__/integration/list.integration.test.ts","../src/__tests__/integration/test-utils.ts","../src/__tests__/integration/tunnel.integration.test.ts","../src/__tests__/integration/variable.integration.test.ts","../src/__tests__/integration/whoami.integration.test.ts","../src/build/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/docs.ts","../src/cmds/editor.ts","../src/cmds/info.ts","../src/cmds/init.ts","../src/cmds/link.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/test.ts","../src/cmds/whoami.ts","../src/cmds/custom-domain/create.ts","../src/cmds/custom-domain/delete.ts","../src/cmds/custom-domain/index.ts","../src/cmds/custom-domain/list.ts","../src/cmds/custom-domain/update.ts","../src/cmds/mtls-certificates/create.ts","../src/cmds/mtls-certificates/delete.ts","../src/cmds/mtls-certificates/describe.ts","../src/cmds/mtls-certificates/disable.ts","../src/cmds/mtls-certificates/index.ts","../src/cmds/mtls-certificates/list.ts","../src/cmds/mtls-certificates/update.ts","../src/cmds/open-api/convert.ts","../src/cmds/open-api/index.ts","../src/cmds/open-api/merge.ts","../src/cmds/open-api/overlay.ts","../src/cmds/project/create.ts","../src/cmds/project/index.ts","../src/cmds/project/info.ts","../src/cmds/proxies/create.ts","../src/cmds/proxies/delete.ts","../src/cmds/proxies/describe.ts","../src/cmds/proxies/index.ts","../src/cmds/proxies/update.ts","../src/cmds/source/import-openapi.ts","../src/cmds/source/index.ts","../src/cmds/source/migrate.ts","../src/cmds/source/upgrade.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/constants.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/populate.ts","../src/common/read-linked-config.test.ts","../src/common/read-linked-config.ts","../src/common/runner.ts","../src/common/settings.ts","../src/common/terminal.test.ts","../src/common/terminal.ts","../src/common/worker-output.ts","../src/common/analytics/lib.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/get-account-param.ts","../src/common/middleware/get-environment-param.ts","../src/common/middleware/get-project-param.ts","../src/common/middleware/logging.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/middleware/validate-fleet.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/branch.ts","../src/common/utils/ports.ts","../src/common/utils/prefixed-output.ts","../src/common/utils/pretty-print-environment-prompt.test.ts","../src/common/utils/pretty-print-environment-prompt.ts","../src/common/utils/stringify-config.test.ts","../src/common/utils/stringify-config.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/argument-validators.spec.ts","../src/common/validators/argument-validators.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/custom-domain/models.ts","../src/custom-domain/create/handler.ts","../src/custom-domain/delete/handler.ts","../src/custom-domain/list/handler.ts","../src/custom-domain/update/handler.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.local-registry.test.ts","../src/deploy/archive.test.ts","../src/deploy/archive.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/docs/handler.ts","../src/editor/handler.ts","../src/editor/e2e/editor.spec.ts","../src/init/handler.ts","../src/link/handler.ts","../src/list/handler.ts","../src/login/login.ts","../src/login/tokens.ts","../src/mtls-certificates/models.ts","../src/mtls-certificates/create/handler.ts","../src/mtls-certificates/delete/handler.ts","../src/mtls-certificates/describe/handler.ts","../src/mtls-certificates/disable/handler.ts","../src/mtls-certificates/list/handler.ts","../src/mtls-certificates/update/handler.ts","../src/open-api/convert/handler.spec.ts","../src/open-api/convert/handler.ts","../src/open-api/merge/handler.spec.ts","../src/open-api/merge/handler.ts","../src/open-api/overlay/handler.spec.ts","../src/open-api/overlay/handler.ts","../src/project/create/handler.ts","../src/project/info/handler.ts","../src/proxies/models.ts","../src/proxies/create/handler.ts","../src/proxies/delete/handler.ts","../src/proxies/describe/handler.ts","../src/proxies/update/handler.ts","../src/source/migrate/dev-portal/handler.ts","../src/source/migrate/dev-portal/types.ts","../src/source/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.ts","../src/test/test-files.test.ts","../src/test/test-files.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts","../src/whoami/handler.ts"],"version":"5.8.2"}
|