kz3-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -0
- package/dist/globalArgs-DdR7vgA6.mjs +34 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.mjs +2 -0
- package/dist/kz3-cli.d.mts +1 -0
- package/dist/kz3-cli.mjs +19 -0
- package/dist/load-kz-config-CMLz3_Tq.mjs +24 -0
- package/dist/main-DLy6TSIK.mjs +257 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# kz3-cli
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
|
|
5
|
+
```txt
|
|
6
|
+
|
|
7
|
+
USAGE kz3 [OPTIONS] preview
|
|
8
|
+
|
|
9
|
+
GLOBAL OPTIONS
|
|
10
|
+
--cwd Current working directory to resolve config and output from
|
|
11
|
+
-c, --configFile="kz.config" Path to kz config file (e.g. kz.config, kz3.config.ts)
|
|
12
|
+
--catalogUrl URL to the catalog JSON file
|
|
13
|
+
--debug Enable debug logging
|
|
14
|
+
--repo Catalog ID
|
|
15
|
+
|
|
16
|
+
COMMANDS
|
|
17
|
+
preview
|
|
18
|
+
preview dlp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Commands
|
|
22
|
+
|
|
23
|
+
### `preview`
|
|
24
|
+
|
|
25
|
+
The `preview` command has sub-commands to download the package for preview.
|
|
26
|
+
|
|
27
|
+
**Usage:**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
kz3-cli preview dlp [OPTIONS] <APPID>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Example: Basic
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
kz3-cli preview dlp --repo repo-id app-id
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The example command assumes that we have a `kz.config.ts` file in the current working directory with the following content:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { defineConfig } from "kz3-cli";
|
|
43
|
+
export default defineConfig({
|
|
44
|
+
registries: {
|
|
45
|
+
"repo-id": "http://localhost:3000/catalog.json",
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Example: Multiple Registries
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# `app-id` will be downloaded from the `github-1`
|
|
54
|
+
kz3-cli preview dlp --repo github-1 app-id
|
|
55
|
+
|
|
56
|
+
# `app-id` will be downloaded from the `repo-id`
|
|
57
|
+
kz3-cli preview dlp --repo repo-id app-id
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**kz.config.ts:**
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { defineConfig } from "kz3-cli";
|
|
64
|
+
export default defineConfig({
|
|
65
|
+
defaultRepo: "repo-id",
|
|
66
|
+
registries: {
|
|
67
|
+
"repo-id": "http://localhost:3000/catalog.json",
|
|
68
|
+
"github-1": "https://raw.githubusercontent.com/username/repo/branch/catalog.json",
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Catalog File
|
|
74
|
+
|
|
75
|
+
The catalog file is a JSON file that contains the metadata of the packages. The structure of the catalog file is as follows:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
[
|
|
79
|
+
{
|
|
80
|
+
"appName": "app-id",
|
|
81
|
+
"version": "1.0.0",
|
|
82
|
+
"url": "http://localhost:3000/app-id-1.0.0.tar.gz",
|
|
83
|
+
"provider": "http"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"appName": "app-id",
|
|
87
|
+
"version": "1.0.0",
|
|
88
|
+
"url": "https://gitlab.com/....../app-id-1.0.0.tar.gz",
|
|
89
|
+
"provider": "gitlab"
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Auth and Providers
|
|
95
|
+
|
|
96
|
+
Only supported is HTTP provider and Gitlab provider.
|
|
97
|
+
|
|
98
|
+
For Gitlab, the environment variable `KZ_AUTH` must be present for the cli to download the package. The value of `KZ_AUTH` should be a Gitlab Deploy Token that can read packages and files in the repository.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/globalArgs.ts
|
|
2
|
+
const dryRunArg = { dryRun: {
|
|
3
|
+
type: "boolean",
|
|
4
|
+
description: "Print the download URL without downloading"
|
|
5
|
+
} };
|
|
6
|
+
const globalArgs = {
|
|
7
|
+
cwd: {
|
|
8
|
+
type: "string",
|
|
9
|
+
description: "Current working directory to resolve config and output from"
|
|
10
|
+
},
|
|
11
|
+
configFile: {
|
|
12
|
+
type: "string",
|
|
13
|
+
alias: ["c"],
|
|
14
|
+
description: "Path to kz config file (e.g. kz.config, kz3.config.ts)",
|
|
15
|
+
default: "kz.config",
|
|
16
|
+
required: false
|
|
17
|
+
},
|
|
18
|
+
catalogUrl: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "URL to the catalog JSON file",
|
|
21
|
+
required: false
|
|
22
|
+
},
|
|
23
|
+
debug: {
|
|
24
|
+
type: "boolean",
|
|
25
|
+
description: "Enable debug logging"
|
|
26
|
+
},
|
|
27
|
+
repo: {
|
|
28
|
+
type: "string",
|
|
29
|
+
description: "Catalog ID",
|
|
30
|
+
required: false
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { globalArgs as n, dryRunArg as t };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { C12InputConfig, LoadConfigOptions } from "c12";
|
|
2
|
+
|
|
3
|
+
//#region src/util/load-kz-config.d.ts
|
|
4
|
+
interface Kz3Config {
|
|
5
|
+
defaultRepo?: string;
|
|
6
|
+
registries: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
interface Kz3LoadConfigOptions extends Pick<LoadConfigOptions, "configFile" | "cwd"> {}
|
|
9
|
+
type Kz3DefineConfigInput = (Kz3Config & {
|
|
10
|
+
extends?: never;
|
|
11
|
+
}) & C12InputConfig<Kz3Config>;
|
|
12
|
+
declare const defineConfig: (input: Kz3DefineConfigInput) => Kz3DefineConfigInput;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { type Kz3Config, type Kz3DefineConfigInput, type Kz3LoadConfigOptions, defineConfig };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/kz3-cli.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { n as globalArgs } from "./globalArgs-DdR7vgA6.mjs";
|
|
2
|
+
import { defineCommand, runMain } from "citty";
|
|
3
|
+
//#region bin/index.ts
|
|
4
|
+
const main = defineCommand({
|
|
5
|
+
meta: {
|
|
6
|
+
name: "kz3",
|
|
7
|
+
description: "KZ3 CLI"
|
|
8
|
+
},
|
|
9
|
+
subCommands: { preview: () => import("./main-DLy6TSIK.mjs").then((m) => m.default) },
|
|
10
|
+
args: { ...globalArgs }
|
|
11
|
+
});
|
|
12
|
+
try {
|
|
13
|
+
await runMain(main);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error("An error occurred:", error instanceof Error ? error.message : error);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { loadConfig } from "c12";
|
|
2
|
+
//#region src/util/load-kz-config.ts
|
|
3
|
+
async function loadKz3Config(options) {
|
|
4
|
+
const { config } = await loadConfig({
|
|
5
|
+
name: "kz",
|
|
6
|
+
dotenv: true,
|
|
7
|
+
...options
|
|
8
|
+
});
|
|
9
|
+
function getDefaultRepo() {
|
|
10
|
+
if (config.registries && Object.keys(config.registries).length === 1) return Object.values(config.registries)[0];
|
|
11
|
+
if (config.defaultRepo) if (config.registries && config.registries[config.defaultRepo]) return config.registries[config.defaultRepo];
|
|
12
|
+
else {
|
|
13
|
+
console.warn(`Warning: defaultRepo "${config.defaultRepo}" is not found in registries. Please check your config.`);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
...config,
|
|
19
|
+
getDefaultRepo
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const defineConfig = (input) => input;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { loadKz3Config as n, defineConfig as t };
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { n as loadKz3Config } from "./load-kz-config-CMLz3_Tq.mjs";
|
|
2
|
+
import { n as globalArgs, t as dryRunArg } from "./globalArgs-DdR7vgA6.mjs";
|
|
3
|
+
import { defineCommand } from "citty";
|
|
4
|
+
import path, { relative } from "node:path";
|
|
5
|
+
import fs, { mkdir } from "node:fs/promises";
|
|
6
|
+
import fs$1, { existsSync } from "node:fs";
|
|
7
|
+
import { pipeline } from "node:stream";
|
|
8
|
+
import { promisify } from "node:util";
|
|
9
|
+
import { extract } from "tar";
|
|
10
|
+
import "valid-filename";
|
|
11
|
+
import ejs from "ejs";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
//#region src/preview-module/core/providers.ts
|
|
14
|
+
/**
|
|
15
|
+
* Generic HTTP, with or without Basic Auth.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
const http = (url, options) => {
|
|
19
|
+
const requestHeaders = {};
|
|
20
|
+
const originalUrl = url;
|
|
21
|
+
let transformedUrl = url;
|
|
22
|
+
if (options.auth) requestHeaders["Authorization"] = `Basic ${options.auth}`;
|
|
23
|
+
if (options.token) transformedUrl = url.replace(":token", options.token);
|
|
24
|
+
return {
|
|
25
|
+
headers: requestHeaders,
|
|
26
|
+
originalUrl,
|
|
27
|
+
url: transformedUrl
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const gitlab = (url, options) => {
|
|
31
|
+
return {
|
|
32
|
+
url,
|
|
33
|
+
headers: { authorization: options.auth ? `Bearer ${options.auth}` : void 0 }
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const providers = {
|
|
37
|
+
http,
|
|
38
|
+
gitlab
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/util/download.ts
|
|
42
|
+
async function download(url, outFile, options = {}) {
|
|
43
|
+
const response = await sendDownloadRequest(url, { headers: options.requestHeaders });
|
|
44
|
+
if (response.status >= 400) throw new Error(`Failed to download from ${url}: HTTP ${response.status} ${response.statusText}`);
|
|
45
|
+
const outputStream = fs$1.createWriteStream(outFile);
|
|
46
|
+
await promisify(pipeline)(response.body, outputStream);
|
|
47
|
+
}
|
|
48
|
+
async function sendDownloadRequest(url, options) {
|
|
49
|
+
const result = await fetch(url, options).catch((error) => {
|
|
50
|
+
throw new Error(`Failed to download from ${url}: ${error.message}`, { cause: error });
|
|
51
|
+
});
|
|
52
|
+
if (result.status >= 400) throw new Error(`Failed to download from ${url}: HTTP ${result.status} ${result.statusText}`);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/util/common.ts
|
|
57
|
+
function toSafeFsName(str) {
|
|
58
|
+
return str.replace(/[^\da-z-.]/gi, "-");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fixes a template filename by replacing certain characters to comply with templating.
|
|
62
|
+
*
|
|
63
|
+
* - `_` becomes `.` (for dotfiles and folder names like `_git` -> `.git`)
|
|
64
|
+
* - `__` becomes literal `_` (used for escaping)
|
|
65
|
+
* - `.tmpl` extension is removed (used for template files that should not be rendered as-is for certain file extensions)
|
|
66
|
+
*
|
|
67
|
+
* @param filename filename or path-like
|
|
68
|
+
*/
|
|
69
|
+
function fixTemplateFilename(filename) {
|
|
70
|
+
const tmplFilesMap = {
|
|
71
|
+
".ts.tmpl": ".ts",
|
|
72
|
+
".js.tmpl": ".js"
|
|
73
|
+
};
|
|
74
|
+
const dots = (str) => {
|
|
75
|
+
return str.split(path.sep).map((part) => {
|
|
76
|
+
if (part.startsWith("__")) return part.replace(/^__/, "_");
|
|
77
|
+
else if (part.startsWith("_")) return part.replace(/^_/, ".");
|
|
78
|
+
return part;
|
|
79
|
+
}).join(path.sep);
|
|
80
|
+
};
|
|
81
|
+
const ext = Object.keys(tmplFilesMap).find((ext) => filename.endsWith(ext));
|
|
82
|
+
if (ext) return dots(filename.replace(ext, tmplFilesMap[ext]));
|
|
83
|
+
return dots(filename);
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/preview-module/core/download-dist.ts
|
|
87
|
+
async function downloadDistPackage(options) {
|
|
88
|
+
const { dryRun } = options;
|
|
89
|
+
const providerName = options.provider;
|
|
90
|
+
if (!providerName) throw new Error("Provider is required to download dist package");
|
|
91
|
+
const getProvider = providers[providerName];
|
|
92
|
+
if (!getProvider) throw new Error(`Unknown provider: ${providerName}`);
|
|
93
|
+
options.auth = process.env.KZ3_AUTH ?? options.auth;
|
|
94
|
+
const cwd = options.cwd || process.cwd();
|
|
95
|
+
const provider = await getProvider(options.registry, { auth: options.auth });
|
|
96
|
+
const appName = toSafeFsName(options.appName);
|
|
97
|
+
const tempDir = path.resolve(cwd, ".temp", appName);
|
|
98
|
+
const tarPath = path.resolve(tempDir, appName + ".tar.gz");
|
|
99
|
+
if (dryRun) console.log(`[Dry Run] mkdir ${path.dirname(tarPath)}`);
|
|
100
|
+
else await mkdir(path.dirname(tarPath), { recursive: true });
|
|
101
|
+
const startTime = Date.now();
|
|
102
|
+
if (dryRun) {
|
|
103
|
+
console.log(`[Dry Run] Downloading from ${provider.url} to ${tarPath}`);
|
|
104
|
+
console.log(`[Dry Run] With headers: ${JSON.stringify(provider.headers)}`);
|
|
105
|
+
} else await download(provider.url, tarPath, { requestHeaders: { ...provider.headers } }).catch((error) => {
|
|
106
|
+
if (!existsSync(tarPath)) throw error;
|
|
107
|
+
throw new Error(`Failed to download package`, { cause: error });
|
|
108
|
+
});
|
|
109
|
+
const durationMs = Date.now() - startTime;
|
|
110
|
+
console.debug(`Downloaded dist package in ${durationMs}ms`);
|
|
111
|
+
if (!existsSync(tarPath) && !dryRun) throw new Error(`Failed to download package: file not found at ${tarPath}`);
|
|
112
|
+
const extractDir = path.resolve(cwd, "apps", appName, "dist");
|
|
113
|
+
if (dryRun) console.log(`[Dry Run] Extracting ${relative(cwd, tarPath)} to ${relative(cwd, extractDir)}`);
|
|
114
|
+
else {
|
|
115
|
+
try {
|
|
116
|
+
await mkdir(extractDir, { recursive: true });
|
|
117
|
+
await extract({
|
|
118
|
+
file: tarPath,
|
|
119
|
+
cwd: extractDir,
|
|
120
|
+
strip: 1
|
|
121
|
+
});
|
|
122
|
+
} catch (error) {
|
|
123
|
+
throw new Error(`Failed to extract package`, { cause: error });
|
|
124
|
+
}
|
|
125
|
+
console.log(`Extracted package to ${extractDir}`);
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
outDir: extractDir,
|
|
129
|
+
tempPackageFile: tarPath,
|
|
130
|
+
tempPackageDir: tempDir,
|
|
131
|
+
url: provider.url
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/preview-module/core/catalog.ts
|
|
136
|
+
/**
|
|
137
|
+
* Loads the catalog from the given URL.
|
|
138
|
+
* The catalog is expected to be a JSON
|
|
139
|
+
*/
|
|
140
|
+
async function loadCatalogData(options) {
|
|
141
|
+
if (!options.url) throw new Error("Catalog URL is required to load catalog data");
|
|
142
|
+
const response = await fetch(options.url, {
|
|
143
|
+
method: "GET",
|
|
144
|
+
headers: { Accept: "application/json" }
|
|
145
|
+
});
|
|
146
|
+
if (response.status >= 400) throw new Error(`Failed to load catalog from ${options.url}: HTTP ${response.status} ${response.statusText}`);
|
|
147
|
+
const data = await response.json().catch((error) => {
|
|
148
|
+
throw new Error(`Failed to parse catalog JSON from ${options.url}: ${error.message}`, { cause: error });
|
|
149
|
+
});
|
|
150
|
+
if (!Array.isArray(data)) throw new Error(`Invalid catalog format from ${options.url}: expected an array of entries`);
|
|
151
|
+
return data;
|
|
152
|
+
}
|
|
153
|
+
async function getCatalogEntryByAppName(catalog, appName) {
|
|
154
|
+
const entry = catalog.find((entry) => entry.appName === appName);
|
|
155
|
+
if (!entry) throw new Error(`App "${appName}" was not found in the catalog`);
|
|
156
|
+
if (!entry.url) throw new Error(`Catalog entry for "${appName}" has no download URL`);
|
|
157
|
+
if (!providers[entry.provider]) throw new Error(`Unknown provider "${entry.provider}" for app "${appName}"`);
|
|
158
|
+
return entry;
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/preview-module/core/create-app.ts
|
|
162
|
+
/**
|
|
163
|
+
* Creates the files from a template.
|
|
164
|
+
*/
|
|
165
|
+
async function createApp(options) {
|
|
166
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
167
|
+
const templatePath = path.resolve(__dirname, "../template");
|
|
168
|
+
const renderTemplatePath = path.resolve(templatePath, "render");
|
|
169
|
+
const staticTemplatePath = path.resolve(templatePath, "static");
|
|
170
|
+
const appDir = path.resolve(options.cwd, "apps", options.appName);
|
|
171
|
+
if (!existsSync(templatePath)) {
|
|
172
|
+
console.error(`Template path does not exist: ${templatePath}`);
|
|
173
|
+
throw new Error(`Unable to retrieve template`);
|
|
174
|
+
}
|
|
175
|
+
const vfs = {};
|
|
176
|
+
const packageJsonTemplate = await fs.readFile(path.join(renderTemplatePath, "package.json"), "utf-8");
|
|
177
|
+
vfs["package.json"] = await ejs.render(packageJsonTemplate, { appName: options.appName }, { async: true });
|
|
178
|
+
console.log(`App Dir: ${appDir}`);
|
|
179
|
+
for (const [file, content] of Object.entries(vfs)) {
|
|
180
|
+
const filePath = path.join(appDir, file);
|
|
181
|
+
if (options.dryRun) {
|
|
182
|
+
console.log(`[Dry Run] Writing file ${path.relative(process.cwd(), filePath)}`);
|
|
183
|
+
continue;
|
|
184
|
+
} else {
|
|
185
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
186
|
+
await fs.writeFile(filePath, content, "utf-8");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const staticFiles = await fs.readdir(staticTemplatePath, { recursive: true });
|
|
190
|
+
for (const file of staticFiles) {
|
|
191
|
+
const staticFileDest = fixTemplateFilename(file);
|
|
192
|
+
if (options.dryRun) console.log(`[Dry Run] Copying static file from ${path.join(staticTemplatePath, file)} to ${path.join(appDir, staticFileDest)}`);
|
|
193
|
+
else await fs.copyFile(path.join(staticTemplatePath, file), path.join(appDir, staticFileDest));
|
|
194
|
+
}
|
|
195
|
+
return { outDir: appDir };
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/preview-module/main.ts
|
|
199
|
+
const previewModule = defineCommand({
|
|
200
|
+
meta: { name: "preview" },
|
|
201
|
+
subCommands: { dlp: defineCommand({
|
|
202
|
+
meta: {
|
|
203
|
+
name: "dlp",
|
|
204
|
+
description: "Download a preview distribution package"
|
|
205
|
+
},
|
|
206
|
+
args: {
|
|
207
|
+
appId: {
|
|
208
|
+
type: "positional",
|
|
209
|
+
required: true,
|
|
210
|
+
description: "Name of the app to download distribution for"
|
|
211
|
+
},
|
|
212
|
+
...dryRunArg,
|
|
213
|
+
...globalArgs
|
|
214
|
+
},
|
|
215
|
+
async run({ args }) {
|
|
216
|
+
args.debug && console.log(args);
|
|
217
|
+
const cwd = args.cwd || process.cwd();
|
|
218
|
+
const repo = args.repo;
|
|
219
|
+
const kzConfig = await loadKz3Config({
|
|
220
|
+
configFile: args.configFile,
|
|
221
|
+
cwd
|
|
222
|
+
});
|
|
223
|
+
const repoKey = kzConfig?.registries && Object.keys(kzConfig.registries).find((key) => key === repo);
|
|
224
|
+
const catalogFromConfig = repoKey ? kzConfig.registries[repoKey] : null;
|
|
225
|
+
if (!(args.catalogUrl || catalogFromConfig || kzConfig.getDefaultRepo())) {
|
|
226
|
+
console.error(`Error: Catalog URL not specified.`);
|
|
227
|
+
console.error(`Please provide a catalog URL using the "--catalog-url" argument, or define it in the kz config under registries then use --repo to specify which one to use.`);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
const catalog = await loadCatalogData({ url: args.catalogUrl });
|
|
231
|
+
if (catalog.length === 0) {
|
|
232
|
+
console.log("No entries found in the catalog");
|
|
233
|
+
process.exit(0);
|
|
234
|
+
}
|
|
235
|
+
const app = await getCatalogEntryByAppName(catalog, args.appId);
|
|
236
|
+
const downloadResult = await downloadDistPackage({
|
|
237
|
+
appName: app.appName,
|
|
238
|
+
registry: app.url,
|
|
239
|
+
provider: app.provider,
|
|
240
|
+
configFile: args.configFile,
|
|
241
|
+
dryRun: false,
|
|
242
|
+
cwd,
|
|
243
|
+
tempDir: ".temp"
|
|
244
|
+
});
|
|
245
|
+
console.log(`Package for "${app.appName}:${app.version}" downloaded to ${downloadResult.outDir}`);
|
|
246
|
+
const createAppResult = await createApp({
|
|
247
|
+
appName: app.appName,
|
|
248
|
+
cwd,
|
|
249
|
+
configFile: args.configFile,
|
|
250
|
+
dryRun: args.dryRun
|
|
251
|
+
});
|
|
252
|
+
console.log(`App config created at ${createAppResult.outDir}`);
|
|
253
|
+
}
|
|
254
|
+
}) }
|
|
255
|
+
});
|
|
256
|
+
//#endregion
|
|
257
|
+
export { previewModule as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kz3-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "kz3-cli",
|
|
5
|
+
"homepage": "https://github.com/hirameki-labs/discussion",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/hirameki-labs/discussion/issues"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Mark Terence Tiglao <github@markterence.me>",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/hirameki-labs/discussion.git"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"kz3": "./dist/kz3-cli.mjs"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": "./dist/index.mjs",
|
|
24
|
+
"./kz3-cli": "./dist/kz3-cli.mjs",
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@dotenvx/dotenvx": "^1.57.2",
|
|
32
|
+
"axios": "^1.13.6",
|
|
33
|
+
"c12": "4.0.0-beta.4",
|
|
34
|
+
"citty": "^0.2.1",
|
|
35
|
+
"ejs": "^5.0.1",
|
|
36
|
+
"tar": "^7.5.13",
|
|
37
|
+
"valid-filename": "^4.0.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/ejs": "^3.1.5",
|
|
41
|
+
"@types/node": "^24.12.0",
|
|
42
|
+
"@typescript/native-preview": "7.0.0-dev.20260316.1",
|
|
43
|
+
"bumpp": "^11.0.1",
|
|
44
|
+
"typescript": "^5.9.3",
|
|
45
|
+
"vite-plus": "^0.1.11"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "vp pack",
|
|
49
|
+
"dev": "vp pack --watch",
|
|
50
|
+
"test": "vp test",
|
|
51
|
+
"check": "vp check"
|
|
52
|
+
}
|
|
53
|
+
}
|