@kittl/cli 0.0.1 → 0.0.2
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/LICENSE +201 -0
- package/README.md +15 -105
- package/dist/chunk-3BPIJLS7.js +51 -0
- package/dist/chunk-3BPIJLS7.js.map +1 -0
- package/dist/{chunk-4ISWSLZ5.js → chunk-637YZAKM.js} +3 -3
- package/dist/chunk-637YZAKM.js.map +1 -0
- package/dist/chunk-EKU4DKQK.js +20 -0
- package/dist/chunk-EKU4DKQK.js.map +1 -0
- package/dist/chunk-GJPVFQRF.js +98 -0
- package/dist/chunk-GJPVFQRF.js.map +1 -0
- package/dist/{chunk-JGD3QFQS.js → chunk-TK44DTSK.js} +280 -70
- package/dist/chunk-TK44DTSK.js.map +1 -0
- package/dist/chunk-XU2ZHSRY.js +143 -0
- package/dist/chunk-XU2ZHSRY.js.map +1 -0
- package/dist/commands/app/init.js +699 -0
- package/dist/commands/app/init.js.map +1 -0
- package/dist/commands/app/release.js +125 -0
- package/dist/commands/app/release.js.map +1 -0
- package/dist/commands/app/update.js +45 -0
- package/dist/commands/app/update.js.map +1 -0
- package/dist/commands/app/upload.js +419 -5
- package/dist/commands/app/upload.js.map +1 -1
- package/dist/commands/auth/login.js +13 -68
- package/dist/commands/auth/login.js.map +1 -1
- package/dist/commands/auth/logout.js +1 -1
- package/dist/commands/auth/logout.js.map +1 -1
- package/dist/commands/auth/whoami.js +2 -2
- package/dist/commands/whoami.js +2 -2
- package/package.json +4 -1
- package/dist/chunk-4ISWSLZ5.js.map +0 -1
- package/dist/chunk-JGD3QFQS.js.map +0 -1
- package/dist/commands/app/create.js +0 -16
- package/dist/commands/app/create.js.map +0 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
API_CONFIG,
|
|
3
|
+
CLI_CONFIG,
|
|
4
|
+
parseJsonObjectFromFile
|
|
5
|
+
} from "./chunk-TK44DTSK.js";
|
|
6
|
+
|
|
7
|
+
// src/core/error.ts
|
|
8
|
+
import { isAxiosError } from "axios";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
function isSystemError(err, code) {
|
|
11
|
+
return err instanceof Error && "code" in err && err.code === code;
|
|
12
|
+
}
|
|
13
|
+
function formatZodErrorSummary(error) {
|
|
14
|
+
return error.issues.map((issue) => {
|
|
15
|
+
const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
16
|
+
return `${path}: ${issue.message}`;
|
|
17
|
+
}).join("; ");
|
|
18
|
+
}
|
|
19
|
+
function formatHttpClientError(error) {
|
|
20
|
+
const apiBaseUrl = API_CONFIG.baseUrl;
|
|
21
|
+
const loginHint = "Run `kittl auth login` (or `kittl-dev auth login` when developing the CLI).";
|
|
22
|
+
const zodHint = "The response did not match what this CLI expects: wrong environment, API version, or an incompatible server.";
|
|
23
|
+
if (error instanceof z.ZodError) {
|
|
24
|
+
return `Unexpected response (${formatZodErrorSummary(error)}). ${zodHint}`;
|
|
25
|
+
}
|
|
26
|
+
if (!isAxiosError(error)) {
|
|
27
|
+
return error instanceof Error ? error.message : String(error);
|
|
28
|
+
}
|
|
29
|
+
const status = error.response?.status;
|
|
30
|
+
const data = error.response?.data;
|
|
31
|
+
const message = typeof data?.message === "string" ? data.message : typeof data?.error === "string" ? data.error : error.message;
|
|
32
|
+
if (status === 401) {
|
|
33
|
+
return [
|
|
34
|
+
`Unauthorized (401): ${apiBaseUrl} rejected this access token.`,
|
|
35
|
+
"Your saved session may be for another environment, expired, or missing access.",
|
|
36
|
+
`Sign in again: ${loginHint}`,
|
|
37
|
+
"If you customize API or auth endpoints, use values that belong to the same Kittl app and environment."
|
|
38
|
+
].join("\n");
|
|
39
|
+
}
|
|
40
|
+
if (status === 403) {
|
|
41
|
+
return `Forbidden (403). ${message}`;
|
|
42
|
+
}
|
|
43
|
+
if (status === 404) {
|
|
44
|
+
return `Not found (404): wrong URL or missing route. ${message}`;
|
|
45
|
+
}
|
|
46
|
+
if (status === 400) {
|
|
47
|
+
return `Bad request (400). ${message}`;
|
|
48
|
+
}
|
|
49
|
+
if (status != null) {
|
|
50
|
+
return `Request failed (${status}). ${message}`;
|
|
51
|
+
}
|
|
52
|
+
if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
|
|
53
|
+
return `${error.message} (${error.code}). Check the API address and your network connection.`;
|
|
54
|
+
}
|
|
55
|
+
return message || "Request failed (no response). Check the API address and your connection.";
|
|
56
|
+
}
|
|
57
|
+
function formatExtensionReadyForReviewHttpError(error) {
|
|
58
|
+
if (isAxiosError(error) && error.response?.status === 404) {
|
|
59
|
+
return [
|
|
60
|
+
"No draft extension version is available to submit (404).",
|
|
61
|
+
"There is no DRAFT for this extension to move to review, it may already be in review or published, or you still need to create the draft.",
|
|
62
|
+
"Try: `kittl app update` to push your manifest draft, `kittl app upload` for build output, then `kittl app release` again.",
|
|
63
|
+
"Confirm `.kittl/config.json` points at the right extension, or run `kittl app init` if this project is not linked yet."
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
return formatHttpClientError(error);
|
|
67
|
+
}
|
|
68
|
+
function formatExtensionArtifactUploadError(error) {
|
|
69
|
+
const base = formatHttpClientError(error);
|
|
70
|
+
if (!isAxiosError(error) || error.response?.status !== 400) {
|
|
71
|
+
return base;
|
|
72
|
+
}
|
|
73
|
+
return [
|
|
74
|
+
base,
|
|
75
|
+
"",
|
|
76
|
+
"If the extension draft was submitted for review, wait for approval or follow your organization's process.",
|
|
77
|
+
"If you need a fresh draft, try: `kittl app update`"
|
|
78
|
+
].join("\n");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/core/internal.config.ts
|
|
82
|
+
import { access, mkdir, writeFile } from "node:fs/promises";
|
|
83
|
+
import { join, normalize } from "node:path";
|
|
84
|
+
import { z as z2 } from "zod";
|
|
85
|
+
var internalConfigSchema = z2.object({
|
|
86
|
+
developerOrganizationId: z2.string().min(1),
|
|
87
|
+
extensionId: z2.string().min(1)
|
|
88
|
+
});
|
|
89
|
+
function internalConfigPath(cwd) {
|
|
90
|
+
return normalize(join(cwd, CLI_CONFIG.configDir, CLI_CONFIG.configFileName));
|
|
91
|
+
}
|
|
92
|
+
async function internalConfigExists(cwd) {
|
|
93
|
+
try {
|
|
94
|
+
await access(internalConfigPath(cwd));
|
|
95
|
+
return true;
|
|
96
|
+
} catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function readInternalConfig(cwd) {
|
|
101
|
+
const path = internalConfigPath(cwd);
|
|
102
|
+
let obj;
|
|
103
|
+
try {
|
|
104
|
+
obj = await parseJsonObjectFromFile(path);
|
|
105
|
+
} catch (e) {
|
|
106
|
+
if (isSystemError(e, "ENOENT")) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Missing Kittl config at ${path}. Run \`kittl app init\` in this directory first.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
throw e;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
return internalConfigSchema.parse(obj);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
if (e instanceof z2.ZodError) {
|
|
117
|
+
throw new Error(`${path} is invalid. config file is malformed.`);
|
|
118
|
+
}
|
|
119
|
+
throw e;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function writeInternalConfig(cwd, data) {
|
|
123
|
+
const path = internalConfigPath(cwd);
|
|
124
|
+
const parsed = internalConfigSchema.parse(data);
|
|
125
|
+
const body = `${JSON.stringify(parsed, null, 2)}
|
|
126
|
+
`;
|
|
127
|
+
await mkdir(join(cwd, CLI_CONFIG.configDir), { recursive: true });
|
|
128
|
+
await writeFile(path, body, "utf8");
|
|
129
|
+
return path;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export {
|
|
133
|
+
isSystemError,
|
|
134
|
+
formatZodErrorSummary,
|
|
135
|
+
formatHttpClientError,
|
|
136
|
+
formatExtensionReadyForReviewHttpError,
|
|
137
|
+
formatExtensionArtifactUploadError,
|
|
138
|
+
internalConfigPath,
|
|
139
|
+
internalConfigExists,
|
|
140
|
+
readInternalConfig,
|
|
141
|
+
writeInternalConfig
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=chunk-XU2ZHSRY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/error.ts","../src/core/internal.config.ts"],"sourcesContent":["/**\n * Shared error helpers: Node errno checks, Zod/HTTP formatting for CLI output.\n */\n\nimport { isAxiosError } from 'axios';\nimport { type ZodError, z } from 'zod';\nimport { API_CONFIG } from '../constants';\n\n// os error checking\nexport function isSystemError(\n err: unknown,\n code: string,\n): err is NodeJS.ErrnoException {\n return (\n err instanceof Error &&\n 'code' in err &&\n (err as NodeJS.ErrnoException).code === code\n );\n}\n\n// zod error formatting\nexport function formatZodErrorSummary(error: ZodError): string {\n return error.issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : '(root)';\n return `${path}: ${issue.message}`;\n })\n .join('; ');\n}\n\n/**\n * Turn Axios / Zod failures into a single string for `this.error` or logging.\n */\nexport function formatHttpClientError(error: unknown): string {\n const apiBaseUrl = API_CONFIG.baseUrl;\n const loginHint =\n 'Run `kittl auth login` (or `kittl-dev auth login` when developing the CLI).';\n const zodHint =\n 'The response did not match what this CLI expects: wrong environment, API version, or an incompatible server.';\n\n if (error instanceof z.ZodError) {\n return `Unexpected response (${formatZodErrorSummary(error)}). ${zodHint}`;\n }\n if (!isAxiosError(error)) {\n return error instanceof Error ? error.message : String(error);\n }\n const status = error.response?.status;\n const data = error.response?.data as Record<string, unknown> | undefined;\n const message =\n typeof data?.message === 'string'\n ? data.message\n : typeof data?.error === 'string'\n ? data.error\n : error.message;\n if (status === 401) {\n return [\n `Unauthorized (401): ${apiBaseUrl} rejected this access token.`,\n 'Your saved session may be for another environment, expired, or missing access.',\n `Sign in again: ${loginHint}`,\n 'If you customize API or auth endpoints, use values that belong to the same Kittl app and environment.',\n ].join('\\n');\n }\n if (status === 403) {\n return `Forbidden (403). ${message}`;\n }\n if (status === 404) {\n return `Not found (404): wrong URL or missing route. ${message}`;\n }\n if (status === 400) {\n return `Bad request (400). ${message}`;\n }\n if (status != null) {\n return `Request failed (${status}). ${message}`;\n }\n if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {\n return `${error.message} (${error.code}). Check the API address and your network connection.`;\n }\n return (\n message ||\n 'Request failed (no response). Check the API address and your connection.'\n );\n}\n\n/**\n * For `app release`: when POST /versions/review/ready returns 404 (no draft, etc.),\n * show fixed guidance instead of the generic 404 line; otherwise {@link formatHttpClientError}.\n */\nexport function formatExtensionReadyForReviewHttpError(error: unknown): string {\n if (isAxiosError(error) && error.response?.status === 404) {\n return [\n 'No draft extension version is available to submit (404).',\n 'There is no DRAFT for this extension to move to review, it may already be in review or published, or you still need to create the draft.',\n 'Try: `kittl app update` to push your manifest draft, `kittl app upload` for build output, then `kittl app release` again.',\n 'Confirm `.kittl/config.json` points at the right extension, or run `kittl app init` if this project is not linked yet.',\n ].join('\\n');\n }\n return formatHttpClientError(error);\n}\n\n/**\n * For `app upload`: when artifact upload returns 400,\n * append draft/review hints after the base message; otherwise {@link formatHttpClientError}.\n */\nexport function formatExtensionArtifactUploadError(error: unknown): string {\n const base = formatHttpClientError(error);\n if (!isAxiosError(error) || error.response?.status !== 400) {\n return base;\n }\n return [\n base,\n '',\n \"If the extension draft was submitted for review, wait for approval or follow your organization's process.\",\n 'If you need a fresh draft, try: `kittl app update`',\n ].join('\\n');\n}\n","import { access, mkdir, writeFile } from 'node:fs/promises';\nimport { join, normalize } from 'node:path';\nimport { z } from 'zod';\nimport { CLI_CONFIG } from '../constants';\nimport { isSystemError } from './error';\nimport { parseJsonObjectFromFile } from './utils';\n\nexport const internalConfigSchema = z.object({\n developerOrganizationId: z.string().min(1),\n extensionId: z.string().min(1),\n});\n\nexport type InternalConfig = z.infer<typeof internalConfigSchema>;\n\nexport function internalConfigPath(cwd: string): string {\n return normalize(join(cwd, CLI_CONFIG.configDir, CLI_CONFIG.configFileName));\n}\n\nexport async function internalConfigExists(cwd: string): Promise<boolean> {\n try {\n await access(internalConfigPath(cwd));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readInternalConfig(cwd: string): Promise<InternalConfig> {\n const path = internalConfigPath(cwd);\n let obj: Record<string, unknown>;\n try {\n obj = await parseJsonObjectFromFile(path);\n } catch (e) {\n if (isSystemError(e, 'ENOENT')) {\n throw new Error(\n `Missing Kittl config at ${path}. Run \\`kittl app init\\` in this directory first.`,\n );\n }\n throw e;\n }\n try {\n return internalConfigSchema.parse(obj);\n } catch (e) {\n if (e instanceof z.ZodError) {\n throw new Error(`${path} is invalid. config file is malformed.`);\n }\n throw e;\n }\n}\n\nexport async function writeInternalConfig(\n cwd: string,\n data: InternalConfig,\n): Promise<string> {\n const path = internalConfigPath(cwd);\n const parsed = internalConfigSchema.parse(data);\n const body = `${JSON.stringify(parsed, null, 2)}\\n`;\n await mkdir(join(cwd, CLI_CONFIG.configDir), { recursive: true });\n await writeFile(path, body, 'utf8');\n return path;\n}\n"],"mappings":"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","names":["z","z"]}
|