ninedeploy 0.3.4 → 0.5.1
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/commands/branding.d.ts +31 -0
- package/dist/commands/branding.d.ts.map +1 -0
- package/dist/commands/branding.js +48 -0
- package/dist/commands/branding.js.map +1 -0
- package/dist/commands/buildCache.d.ts +27 -0
- package/dist/commands/buildCache.d.ts.map +1 -0
- package/dist/commands/buildCache.js +46 -0
- package/dist/commands/buildCache.js.map +1 -0
- package/dist/commands/certificates.d.ts +15 -0
- package/dist/commands/certificates.d.ts.map +1 -0
- package/dist/commands/certificates.js +57 -0
- package/dist/commands/certificates.js.map +1 -0
- package/dist/commands/communityTemplates.d.ts +24 -0
- package/dist/commands/communityTemplates.d.ts.map +1 -0
- package/dist/commands/communityTemplates.js +79 -0
- package/dist/commands/communityTemplates.js.map +1 -0
- package/dist/commands/configPresets.d.ts +51 -0
- package/dist/commands/configPresets.d.ts.map +1 -0
- package/dist/commands/configPresets.js +166 -0
- package/dist/commands/configPresets.js.map +1 -0
- package/dist/commands/domains.d.ts +70 -0
- package/dist/commands/domains.d.ts.map +1 -0
- package/dist/commands/domains.js +97 -0
- package/dist/commands/domains.js.map +1 -0
- package/dist/commands/egress.d.ts +43 -0
- package/dist/commands/egress.d.ts.map +1 -0
- package/dist/commands/egress.js +80 -0
- package/dist/commands/egress.js.map +1 -0
- package/dist/commands/emailTemplates.d.ts +19 -0
- package/dist/commands/emailTemplates.d.ts.map +1 -0
- package/dist/commands/emailTemplates.js +86 -0
- package/dist/commands/emailTemplates.js.map +1 -0
- package/dist/commands/housekeeping.d.ts +24 -0
- package/dist/commands/housekeeping.d.ts.map +1 -1
- package/dist/commands/housekeeping.js +62 -1
- package/dist/commands/housekeeping.js.map +1 -1
- package/dist/commands/logs.d.ts +15 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +58 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/manage.d.ts +45 -0
- package/dist/commands/manage.d.ts.map +1 -1
- package/dist/commands/manage.js +153 -0
- package/dist/commands/manage.js.map +1 -1
- package/dist/commands/manifest.d.ts +12 -6
- package/dist/commands/manifest.d.ts.map +1 -1
- package/dist/commands/manifest.js +87 -12
- package/dist/commands/manifest.js.map +1 -1
- package/dist/commands/metrics.d.ts +37 -0
- package/dist/commands/metrics.d.ts.map +1 -0
- package/dist/commands/metrics.js +43 -0
- package/dist/commands/metrics.js.map +1 -0
- package/dist/commands/misc.d.ts +35 -0
- package/dist/commands/misc.d.ts.map +1 -1
- package/dist/commands/misc.js +135 -1
- package/dist/commands/misc.js.map +1 -1
- package/dist/commands/notifications.d.ts +59 -0
- package/dist/commands/notifications.d.ts.map +1 -0
- package/dist/commands/notifications.js +157 -0
- package/dist/commands/notifications.js.map +1 -0
- package/dist/commands/pgbouncer.d.ts +17 -0
- package/dist/commands/pgbouncer.d.ts.map +1 -0
- package/dist/commands/pgbouncer.js +46 -0
- package/dist/commands/pgbouncer.js.map +1 -0
- package/dist/commands/plugins.d.ts +3 -0
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +20 -1
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/services.d.ts +14 -0
- package/dist/commands/services.d.ts.map +1 -1
- package/dist/commands/services.js +29 -0
- package/dist/commands/services.js.map +1 -1
- package/dist/commands/sso.d.ts +31 -0
- package/dist/commands/sso.d.ts.map +1 -0
- package/dist/commands/sso.js +77 -0
- package/dist/commands/sso.js.map +1 -0
- package/dist/commands/templates.d.ts +22 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/templates.js +122 -0
- package/dist/commands/templates.js.map +1 -0
- package/dist/commands/token.d.ts +10 -0
- package/dist/commands/token.d.ts.map +1 -1
- package/dist/commands/token.js +24 -1
- package/dist/commands/token.js.map +1 -1
- package/dist/index.js +292 -9
- package/dist/index.js.map +1 -1
- package/dist/lib/format.d.ts.map +1 -1
- package/dist/lib/format.js +19 -3
- package/dist/lib/format.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ninedeploy branding {get,set}` — Sprint 4, Gap G-30.
|
|
3
|
+
*
|
|
4
|
+
* Operator-side wrapper around the four branding fields the panel
|
|
5
|
+
* can override: `logoUrl`, `primaryColor`, `supportEmail`,
|
|
6
|
+
* `footerHtml`. The CLI is the canonical way to set them when
|
|
7
|
+
* provisioning a fresh instance (the panel is the read path; the
|
|
8
|
+
* CLI is the write path operators actually use at the terminal).
|
|
9
|
+
*/
|
|
10
|
+
import type { NineDeployClient } from '../client.js';
|
|
11
|
+
export interface BrandingStatus {
|
|
12
|
+
logoUrl: string | null;
|
|
13
|
+
primaryColor: string | null;
|
|
14
|
+
supportEmail: string | null;
|
|
15
|
+
footerHtml: string | null;
|
|
16
|
+
}
|
|
17
|
+
export interface BrandingSetOptions {
|
|
18
|
+
logoUrl?: string;
|
|
19
|
+
primaryColor?: string;
|
|
20
|
+
supportEmail?: string;
|
|
21
|
+
footerHtml?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
24
|
+
export declare function brandingGet(client: NineDeployClient): Promise<BrandingStatus>;
|
|
25
|
+
export declare function brandingGetAction(client: NineDeployClient): Promise<void>;
|
|
26
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
27
|
+
export declare function brandingSet(client: NineDeployClient, opts?: BrandingSetOptions): Promise<{
|
|
28
|
+
ok: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
export declare function brandingSetAction(client: NineDeployClient, opts?: BrandingSetOptions): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=branding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../../src/commands/branding.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,8EAA8E;AAC9E,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAEnF;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/E;AAID,8EAA8E;AAC9E,wBAAsB,WAAW,CAC/B,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC,CAU1B;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAYf"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { error, header, info, success } from '../lib/format.js';
|
|
2
|
+
// ── `ninedeploy branding get` ─────────────────────────────────────────────
|
|
3
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
4
|
+
export async function brandingGet(client) {
|
|
5
|
+
return await client.branding.get();
|
|
6
|
+
}
|
|
7
|
+
export async function brandingGetAction(client) {
|
|
8
|
+
header('Branding');
|
|
9
|
+
let result;
|
|
10
|
+
try {
|
|
11
|
+
result = await brandingGet(client);
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
error(err instanceof Error ? err.message : String(err));
|
|
15
|
+
process.exitCode = 1;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
info(`logoUrl: ${result.logoUrl ?? '(default)'}`);
|
|
19
|
+
info(`primaryColor: ${result.primaryColor ?? '(default)'}`);
|
|
20
|
+
info(`supportEmail: ${result.supportEmail ?? '(default)'}`);
|
|
21
|
+
info(`footerHtml: ${result.footerHtml ? `${result.footerHtml.length} chars` : '(default)'}`);
|
|
22
|
+
}
|
|
23
|
+
// ── `ninedeploy branding set` ─────────────────────────────────────────────
|
|
24
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
25
|
+
export async function brandingSet(client, opts = {}) {
|
|
26
|
+
if (opts.logoUrl === undefined &&
|
|
27
|
+
opts.primaryColor === undefined &&
|
|
28
|
+
opts.supportEmail === undefined &&
|
|
29
|
+
opts.footerHtml === undefined) {
|
|
30
|
+
throw new Error('At least one of --logo-url, --primary-color, --support-email, --footer-html is required');
|
|
31
|
+
}
|
|
32
|
+
return await client.branding.set(opts);
|
|
33
|
+
}
|
|
34
|
+
export async function brandingSetAction(client, opts = {}) {
|
|
35
|
+
header('Branding set');
|
|
36
|
+
let result;
|
|
37
|
+
try {
|
|
38
|
+
result = await brandingSet(client, opts);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
error(err instanceof Error ? err.message : String(err));
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
success(`Branding updated (${Object.keys(opts).filter((k) => opts[k] !== undefined).join(', ')})`);
|
|
46
|
+
void result;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=branding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branding.js","sourceRoot":"","sources":["../../src/commands/branding.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAgBhE,6EAA6E;AAE7E,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAwB;IACxD,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAwB;IAC9D,MAAM,CAAC,UAAU,CAAC,CAAC;IACnB,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,IAAI,CAAC,iBAAiB,MAAM,CAAC,OAAO,IAAI,WAAW,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,iBAAiB,MAAM,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,iBAAiB,MAAM,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,iBAAiB,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACjG,CAAC;AAED,6EAA6E;AAE7E,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAwB,EACxB,IAAI,GAAuB,EAAE;IAE7B,IACE,IAAI,CAAC,OAAO,KAAK,SAAS;QAC1B,IAAI,CAAC,YAAY,KAAK,SAAS;QAC/B,IAAI,CAAC,YAAY,KAAK,SAAS;QAC/B,IAAI,CAAC,UAAU,KAAK,SAAS,EAC7B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAwB,EACxB,IAAI,GAAuB,EAAE;IAE7B,MAAM,CAAC,cAAc,CAAC,CAAC;IACvB,IAAI,MAA+C,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,OAAO,CAAC,qBAAqB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAA6B,CAAC,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/H,KAAK,MAAM,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ninedeploy build-cache stats` — Sprint 3, Gap G-01, PR-A.
|
|
3
|
+
*
|
|
4
|
+
* Operator-side view of the build cache plugin. The plugin is the
|
|
5
|
+
* source of truth (it owns the schema and the cache registration);
|
|
6
|
+
* this module is just a thin CLI surface that calls the same HTTP
|
|
7
|
+
* endpoint the panel will use, so the values an operator sees here
|
|
8
|
+
* are the same values the deploy pipeline will read.
|
|
9
|
+
*/
|
|
10
|
+
import type { NineDeployClient } from '../client.js';
|
|
11
|
+
export interface BuildCacheBackendStats {
|
|
12
|
+
name: string;
|
|
13
|
+
entries: number;
|
|
14
|
+
totalBytes: number;
|
|
15
|
+
hits: number;
|
|
16
|
+
misses: number;
|
|
17
|
+
stores: number;
|
|
18
|
+
evictions: number;
|
|
19
|
+
}
|
|
20
|
+
export interface BuildCacheStats {
|
|
21
|
+
backends: BuildCacheBackendStats[];
|
|
22
|
+
totals: Omit<BuildCacheBackendStats, 'name'>;
|
|
23
|
+
}
|
|
24
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
25
|
+
export declare function buildCacheStats(client: NineDeployClient): Promise<BuildCacheStats>;
|
|
26
|
+
export declare function buildCacheStatsAction(client: NineDeployClient): Promise<void>;
|
|
27
|
+
//# sourceMappingURL=buildCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildCache.d.ts","sourceRoot":"","sources":["../../src/commands/buildCache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;CAC9C;AAID,8EAA8E;AAC9E,wBAAsB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAExF;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BnF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { error, header, info, success } from '../lib/format.js';
|
|
2
|
+
// ── `ninedeploy build-cache stats` ────────────────────────────────────────
|
|
3
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
4
|
+
export async function buildCacheStats(client) {
|
|
5
|
+
return await client.buildCache.stats();
|
|
6
|
+
}
|
|
7
|
+
export async function buildCacheStatsAction(client) {
|
|
8
|
+
header('Build cache stats');
|
|
9
|
+
let result;
|
|
10
|
+
try {
|
|
11
|
+
result = await buildCacheStats(client);
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
error(err instanceof Error ? err.message : String(err));
|
|
15
|
+
process.exitCode = 1;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (result.backends.length === 0) {
|
|
19
|
+
info('No build-cache backends are registered. PR-A ships the inline driver; install one via Settings → Plugins.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
for (const b of result.backends) {
|
|
23
|
+
info(`Backend: ${b.name}`);
|
|
24
|
+
info(` entries: ${b.entries}`);
|
|
25
|
+
info(` bytes: ${b.totalBytes}`);
|
|
26
|
+
info(` hits: ${b.hits}`);
|
|
27
|
+
info(` misses: ${b.misses}`);
|
|
28
|
+
info(` stores: ${b.stores}`);
|
|
29
|
+
info(` evictions: ${b.evictions}`);
|
|
30
|
+
}
|
|
31
|
+
info('Totals:');
|
|
32
|
+
info(` entries: ${result.totals.entries}`);
|
|
33
|
+
info(` bytes: ${result.totals.totalBytes}`);
|
|
34
|
+
info(` hits: ${result.totals.hits}`);
|
|
35
|
+
info(` misses: ${result.totals.misses}`);
|
|
36
|
+
info(` stores: ${result.totals.stores}`);
|
|
37
|
+
info(` evictions: ${result.totals.evictions}`);
|
|
38
|
+
success(`Done. Hit rate: ${hitRate(result.totals)}%`);
|
|
39
|
+
}
|
|
40
|
+
function hitRate(t) {
|
|
41
|
+
const total = t.hits + t.misses;
|
|
42
|
+
if (total === 0)
|
|
43
|
+
return '0.0';
|
|
44
|
+
return ((t.hits / total) * 100).toFixed(1);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=buildCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildCache.js","sourceRoot":"","sources":["../../src/commands/buildCache.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAiBhE,6EAA6E;AAE7E,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAwB;IAC5D,OAAO,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAAwB;IAClE,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC5B,IAAI,MAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC,2GAA2G,CAAC,CAAC;QAClH,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3B,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,gBAAgB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,gBAAgB,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,CAAC;IAChB,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,mBAAmB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,OAAO,CAAC,CAAmC;IAClD,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9B,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ninedeploy certificates {list,expiring}` — G-15 cert
|
|
3
|
+
* inventory CLI. The server-side surface is in
|
|
4
|
+
* `lib/certificateInventory.ts`; the CLI is a thin
|
|
5
|
+
* renderer around `client.traefik.{certificateInventory,
|
|
6
|
+
* expiringCertificates}`.
|
|
7
|
+
*/
|
|
8
|
+
import type { NineDeployClient } from '../client.js';
|
|
9
|
+
export declare function certificatesList(client: NineDeployClient, opts?: {
|
|
10
|
+
threshold?: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
export declare function certificatesExpiring(client: NineDeployClient, opts?: {
|
|
13
|
+
days?: string;
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=certificates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificates.d.ts","sourceRoot":"","sources":["../../src/commands/certificates.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAmBrD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { c, error, header, info, spinner, table } from '../lib/format.js';
|
|
2
|
+
const num = (v, usage) => {
|
|
3
|
+
const n = Number(v);
|
|
4
|
+
if (!n) {
|
|
5
|
+
error(usage);
|
|
6
|
+
throw new Error(usage);
|
|
7
|
+
}
|
|
8
|
+
return n;
|
|
9
|
+
};
|
|
10
|
+
const STATUS_COLOR = {
|
|
11
|
+
valid: c.green,
|
|
12
|
+
'expiring-soon': c.yellow,
|
|
13
|
+
expired: c.red,
|
|
14
|
+
unknown: c.dim,
|
|
15
|
+
};
|
|
16
|
+
export async function certificatesList(client, opts = {}) {
|
|
17
|
+
const threshold = opts.threshold ? num(opts.threshold, 'Usage: --threshold <days>') : 30;
|
|
18
|
+
const report = await spinner('Reading inventory', () => client.traefik.certificateInventory({ threshold }));
|
|
19
|
+
header('Certificate inventory');
|
|
20
|
+
info(`Total: ${report.summary.total}`);
|
|
21
|
+
info(`Valid: ${c.green(String(report.summary.valid))}`);
|
|
22
|
+
info(`Expiring: ${c.yellow(String(report.summary.expiringSoon))} (within ${report.summary.expiringThresholdDays}d)`);
|
|
23
|
+
if (report.summary.expired > 0) {
|
|
24
|
+
info(`Expired: ${c.red(String(report.summary.expired))}`);
|
|
25
|
+
}
|
|
26
|
+
info(`Fetched: ${new Date(report.summary.fetchedAt).toLocaleString()}`);
|
|
27
|
+
if (report.certificates.length === 0) {
|
|
28
|
+
info('No certificates registered yet.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console.log();
|
|
32
|
+
table(report.certificates.map((cert) => ({
|
|
33
|
+
host: cert.host,
|
|
34
|
+
status: (STATUS_COLOR[cert.status] ?? c.dim)(cert.status),
|
|
35
|
+
daysToExpiry: cert.daysToExpiry != null ? String(cert.daysToExpiry) : c.dim('—'),
|
|
36
|
+
expiresAt: cert.notAfter ? new Date(cert.notAfter).toLocaleString() : c.dim('—'),
|
|
37
|
+
autoRenew: cert.autoRenew ? 'yes' : c.dim('no'),
|
|
38
|
+
})), ['host', 'status', 'daysToExpiry', 'expiresAt', 'autoRenew']);
|
|
39
|
+
}
|
|
40
|
+
export async function certificatesExpiring(client, opts = {}) {
|
|
41
|
+
const days = opts.days ? num(opts.days, 'Usage: --days <days>') : 30;
|
|
42
|
+
const res = await spinner('Reading inventory', () => client.traefik.expiringCertificates({ days }));
|
|
43
|
+
header(`Certificates expiring within ${days} days`);
|
|
44
|
+
info(`Count: ${res.count}`);
|
|
45
|
+
if (res.count === 0) {
|
|
46
|
+
info('(none)');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log();
|
|
50
|
+
table(res.certificates.map((cert) => ({
|
|
51
|
+
host: cert.host,
|
|
52
|
+
status: (STATUS_COLOR[cert.status] ?? c.dim)(cert.status),
|
|
53
|
+
daysToExpiry: cert.daysToExpiry != null ? String(cert.daysToExpiry) : c.dim('—'),
|
|
54
|
+
expiresAt: cert.notAfter ? new Date(cert.notAfter).toLocaleString() : c.dim('—'),
|
|
55
|
+
})), ['host', 'status', 'daysToExpiry', 'expiresAt']);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=certificates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificates.js","sourceRoot":"","sources":["../../src/commands/certificates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ninedeploy templates community {list,import,remove}` —
|
|
3
|
+
* G-13 community template contribution.
|
|
4
|
+
*
|
|
5
|
+
* The CLI is a thin renderer around
|
|
6
|
+
* `client.templates.community.{list,import,remove}`. The
|
|
7
|
+
* import command accepts `-` to read from stdin so a
|
|
8
|
+
* `curl -s https://.../template.json | ninedeploy
|
|
9
|
+
* templates community import -` pipeline lands the
|
|
10
|
+
* upstream contribution without writing it to disk
|
|
11
|
+
* first.
|
|
12
|
+
*/
|
|
13
|
+
import type { NineDeployClient } from '../client.js';
|
|
14
|
+
export declare function communityTemplatesList(client: NineDeployClient): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* `ninedeploy templates community import <file>` — the
|
|
17
|
+
* path can be `-` for stdin, in which case the CLI
|
|
18
|
+
* reads until EOF.
|
|
19
|
+
*/
|
|
20
|
+
export declare function communityTemplatesImport(client: NineDeployClient, path: string, opts?: {
|
|
21
|
+
replace?: boolean;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
export declare function communityTemplatesRemove(client: NineDeployClient, idStr: string): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=communityTemplates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"communityTemplates.d.ts","sourceRoot":"","sources":["../../src/commands/communityTemplates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIrD,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BpF;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAerG"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { c, error, header, info, spinner, success, table } from '../lib/format.js';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
export async function communityTemplatesList(client) {
|
|
4
|
+
const res = await spinner('Reading community catalog', () => client.templates.community.list());
|
|
5
|
+
header('Community templates');
|
|
6
|
+
info(`Entries: ${res.entries.length}`);
|
|
7
|
+
info(`Total size: ${res.totalBytes} bytes`);
|
|
8
|
+
if (res.entries.length === 0) {
|
|
9
|
+
info('(no community templates)');
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
console.log();
|
|
13
|
+
table(res.entries.map((e) => ({
|
|
14
|
+
id: e.id,
|
|
15
|
+
name: e.template.name,
|
|
16
|
+
category: e.template.category,
|
|
17
|
+
bytes: e.bytes,
|
|
18
|
+
})), ['id', 'name', 'category', 'bytes']);
|
|
19
|
+
}
|
|
20
|
+
if (res.errors.length > 0) {
|
|
21
|
+
console.log();
|
|
22
|
+
info(c.yellow(`Parse errors: ${res.errors.length}`));
|
|
23
|
+
for (const err of res.errors) {
|
|
24
|
+
console.log(` ${c.red('✗')} ${err.file}: ${err.error}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `ninedeploy templates community import <file>` — the
|
|
30
|
+
* path can be `-` for stdin, in which case the CLI
|
|
31
|
+
* reads until EOF.
|
|
32
|
+
*/
|
|
33
|
+
export async function communityTemplatesImport(client, path, opts = {}) {
|
|
34
|
+
if (!path) {
|
|
35
|
+
error('Usage: ninedeploy templates community import <file> [- | path.json]');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
let content;
|
|
39
|
+
if (path === '-') {
|
|
40
|
+
const chunks = [];
|
|
41
|
+
for await (const chunk of process.stdin)
|
|
42
|
+
chunks.push(chunk);
|
|
43
|
+
content = Buffer.concat(chunks).toString('utf8');
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
try {
|
|
47
|
+
content = await readFile(path, 'utf8');
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
error(`Failed to read ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const res = await spinner('Validating + importing', () => client.templates.community.import(content, { replace: opts.replace }));
|
|
56
|
+
success(`Imported ${res.id} (${res.bytes} bytes, file: ${res.file}).`);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
error(err instanceof Error ? err.message : String(err));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function communityTemplatesRemove(client, idStr) {
|
|
63
|
+
if (!idStr) {
|
|
64
|
+
error('Usage: ninedeploy templates community remove <id>');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const res = await spinner('Removing', () => client.templates.community.remove(idStr));
|
|
69
|
+
if (!res.removed) {
|
|
70
|
+
error(`Community template "${idStr}" not found.`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
success(`Removed ${idStr}.`);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
error(err instanceof Error ? err.message : String(err));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=communityTemplates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"communityTemplates.js","sourceRoot":"","sources":["../../src/commands/communityTemplates.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAwB;IACnE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAChG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAC9B,IAAI,CAAC,eAAe,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,IAAI,CAAC,eAAe,GAAG,CAAC,UAAU,QAAQ,CAAC,CAAC;IAC5C,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,KAAK,CACH,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;YACrB,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ;YAC7B,KAAK,EAAE,CAAC,CAAC,KAAK;SACf,CAAC,CAAC,EACH,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CACpC,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAwB,EACxB,IAAY,EACZ,IAAI,GAA0B,EAAE;IAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IACD,IAAI,OAAe,CAAC;IACpB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;QACtE,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,kBAAkB,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrF,OAAO;QACT,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,wBAAwB,EAAE,GAAG,EAAE,CACvD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CACtE,CAAC;QACF,OAAO,CAAC,YAAY,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,KAAK,iBAAiB,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;IACzE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAwB,EAAE,KAAa;IACpF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,CAAC,mDAAmD,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,CAAC,uBAAuB,KAAK,cAAc,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QACD,OAAO,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { NineDeployClient } from '../client.js';
|
|
2
|
+
export interface ConfigPresetRegisterOptions {
|
|
3
|
+
/** Path to a JSON file holding the preset's values. */
|
|
4
|
+
file?: string;
|
|
5
|
+
/** Inline description (free text, max 500 chars). */
|
|
6
|
+
description?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
9
|
+
export declare function configPresetList(client: NineDeployClient): Promise<{
|
|
10
|
+
presets: string[];
|
|
11
|
+
}>;
|
|
12
|
+
export declare function configPresetListAction(client: NineDeployClient): Promise<void>;
|
|
13
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
14
|
+
export declare function configPresetGet(client: NineDeployClient, id: string): Promise<{
|
|
15
|
+
id: string;
|
|
16
|
+
description: string | null;
|
|
17
|
+
values: Record<string, unknown>;
|
|
18
|
+
createdAt: string;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function configPresetGetAction(client: NineDeployClient, id: string): Promise<void>;
|
|
21
|
+
/** Pure entry point — reads the file, parses JSON, posts to the server. */
|
|
22
|
+
export declare function configPresetRegister(client: NineDeployClient, id: string, opts?: ConfigPresetRegisterOptions): Promise<{
|
|
23
|
+
ok: boolean;
|
|
24
|
+
id: string;
|
|
25
|
+
keyCount: number;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function configPresetRegisterAction(client: NineDeployClient, id: string, opts?: ConfigPresetRegisterOptions): Promise<void>;
|
|
28
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
29
|
+
export declare function configPresetApply(client: NineDeployClient, id: string, opts?: {
|
|
30
|
+
override?: Record<string, unknown>;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
ok: boolean;
|
|
33
|
+
id: string;
|
|
34
|
+
keyCount: number;
|
|
35
|
+
failureCount?: number;
|
|
36
|
+
failures?: Array<{
|
|
37
|
+
key: string;
|
|
38
|
+
status: 'failed';
|
|
39
|
+
reason?: string;
|
|
40
|
+
}>;
|
|
41
|
+
}>;
|
|
42
|
+
export declare function configPresetApplyAction(client: NineDeployClient, id: string, opts?: {
|
|
43
|
+
override?: Record<string, unknown>;
|
|
44
|
+
}): Promise<void>;
|
|
45
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
46
|
+
export declare function configPresetRemove(client: NineDeployClient, id: string): Promise<{
|
|
47
|
+
ok: boolean;
|
|
48
|
+
id: string;
|
|
49
|
+
}>;
|
|
50
|
+
export declare function configPresetRemoveAction(client: NineDeployClient, id: string): Promise<void>;
|
|
51
|
+
//# sourceMappingURL=configPresets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configPresets.d.ts","sourceRoot":"","sources":["../../src/commands/configPresets.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,WAAW,2BAA2B;IAC1C,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,8EAA8E;AAC9E,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAE/F;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAepF;AAID,8EAA8E;AAC9E,wBAAsB,eAAe,CACnC,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC;IACT,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAED;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe/F;AAID,2EAA2E;AAC3E,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,2BAAgC,GACrC,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBxD;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,2BAAgC,GACrC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAID,8EAA8E;AAC9E,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAO,GAChD,OAAO,CAAC;IACT,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE,CAAC,CAED;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAO,GAChD,OAAO,CAAC,IAAI,CAAC,CAuBf;AAID,8EAA8E;AAC9E,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAEtC;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlG"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ninedeploy config-preset {list,get,register,apply,remove}` — Sprint 3, Gap G-23, PR-A.
|
|
3
|
+
*
|
|
4
|
+
* A preset is a named bundle of `configCenter` writes an operator can
|
|
5
|
+
* register once and apply to a fresh instance with one call. The CLI
|
|
6
|
+
* is the operator-side counterpart of the kernel plugin (which owns
|
|
7
|
+
* the schema) and the HTTP surface (which is the actual apply engine).
|
|
8
|
+
*
|
|
9
|
+
* Split:
|
|
10
|
+
* - `list` and `get` are read-only — they hit `GET /v1/config-presets`
|
|
11
|
+
* and `GET /v1/config-presets/:id` and pretty-print the result.
|
|
12
|
+
* - `register <id>` reads a JSON values object from `--file` (or
|
|
13
|
+
* stdin) and POSTs it. A future PR will let the panel also
|
|
14
|
+
* register via the UI; today the CLI is the only registration
|
|
15
|
+
* path because the schema is intentionally a thin wrapper.
|
|
16
|
+
* - `apply <id>` is the one-shot "I just want it to work" command.
|
|
17
|
+
* The body is empty unless the operator wants to override a
|
|
18
|
+
* single value for this call only (handy for smoke tests).
|
|
19
|
+
* - `remove <id>` unregisters. It does NOT undo the apply — the
|
|
20
|
+
* values are still in configCenter. Re-running the preset
|
|
21
|
+
* later would write the same values back; that is the entire
|
|
22
|
+
* point of a registry.
|
|
23
|
+
*/
|
|
24
|
+
import { readFileSync } from 'node:fs';
|
|
25
|
+
import { resolve } from 'node:path';
|
|
26
|
+
import { error, header, info, success } from '../lib/format.js';
|
|
27
|
+
// ── `ninedeploy config-preset list` ────────────────────────────────────────
|
|
28
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
29
|
+
export async function configPresetList(client) {
|
|
30
|
+
return await client.configPresets.list();
|
|
31
|
+
}
|
|
32
|
+
export async function configPresetListAction(client) {
|
|
33
|
+
header('Config presets');
|
|
34
|
+
let result;
|
|
35
|
+
try {
|
|
36
|
+
result = await configPresetList(client);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
error(err instanceof Error ? err.message : String(err));
|
|
40
|
+
process.exitCode = 1;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (result.presets.length === 0) {
|
|
44
|
+
info('No presets are registered. Run `ninedeploy config-preset register <id> --file <path>`.');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
for (const name of result.presets)
|
|
48
|
+
info(`• ${name}`);
|
|
49
|
+
}
|
|
50
|
+
// ── `ninedeploy config-preset get <id>` ────────────────────────────────────
|
|
51
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
52
|
+
export async function configPresetGet(client, id) {
|
|
53
|
+
return await client.configPresets.get(id);
|
|
54
|
+
}
|
|
55
|
+
export async function configPresetGetAction(client, id) {
|
|
56
|
+
header(`Config preset: ${id}`);
|
|
57
|
+
let result;
|
|
58
|
+
try {
|
|
59
|
+
result = await configPresetGet(client, id);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
error(err instanceof Error ? err.message : String(err));
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (result.description)
|
|
67
|
+
info(result.description);
|
|
68
|
+
info(`${Object.keys(result.values).length} key(s) in this preset:`);
|
|
69
|
+
for (const [key, value] of Object.entries(result.values)) {
|
|
70
|
+
info(` ${key} = ${JSON.stringify(value)}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ── `ninedeploy config-preset register <id>` ──────────────────────────────
|
|
74
|
+
/** Pure entry point — reads the file, parses JSON, posts to the server. */
|
|
75
|
+
export async function configPresetRegister(client, id, opts = {}) {
|
|
76
|
+
if (!opts.file) {
|
|
77
|
+
throw new Error('--file <path> is required (a JSON object of key → value pairs)');
|
|
78
|
+
}
|
|
79
|
+
const filePath = resolve(opts.file);
|
|
80
|
+
const raw = readFileSync(filePath, 'utf8');
|
|
81
|
+
let values;
|
|
82
|
+
try {
|
|
83
|
+
values = JSON.parse(raw);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
throw new Error(`Invalid JSON in ${opts.file}: ${err instanceof Error ? err.message : String(err)}`);
|
|
87
|
+
}
|
|
88
|
+
if (!values || typeof values !== 'object' || Array.isArray(values)) {
|
|
89
|
+
throw new Error(`${opts.file} must contain a JSON object (key → value)`);
|
|
90
|
+
}
|
|
91
|
+
return await client.configPresets.register({
|
|
92
|
+
id,
|
|
93
|
+
description: opts.description,
|
|
94
|
+
values: values,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
export async function configPresetRegisterAction(client, id, opts = {}) {
|
|
98
|
+
header('Config preset register');
|
|
99
|
+
if (!id) {
|
|
100
|
+
error('Usage: ninedeploy config-preset register <id> --file <path> [--description <text>]');
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
let result;
|
|
105
|
+
try {
|
|
106
|
+
result = await configPresetRegister(client, id, opts);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
error(err instanceof Error ? err.message : String(err));
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
success(`Registered preset "${result.id}" with ${result.keyCount} key(s)`);
|
|
114
|
+
}
|
|
115
|
+
// ── `ninedeploy config-preset apply <id>` ──────────────────────────────────
|
|
116
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
117
|
+
export async function configPresetApply(client, id, opts = {}) {
|
|
118
|
+
return await client.configPresets.apply(id, opts);
|
|
119
|
+
}
|
|
120
|
+
export async function configPresetApplyAction(client, id, opts = {}) {
|
|
121
|
+
header('Config preset apply');
|
|
122
|
+
if (!id) {
|
|
123
|
+
error('Usage: ninedeploy config-preset apply <id> [--override <json>]');
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
let result;
|
|
128
|
+
try {
|
|
129
|
+
result = await configPresetApply(client, id, opts);
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
error(err instanceof Error ? err.message : String(err));
|
|
133
|
+
process.exitCode = 1;
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (!result.ok) {
|
|
137
|
+
error(`Preset "${result.id}" applied with ${result.failureCount ?? 0} failure(s) of ${result.keyCount} key(s)`);
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
success(`Applied preset "${result.id}" — ${result.keyCount} key(s) written`);
|
|
142
|
+
}
|
|
143
|
+
// ── `ninedeploy config-preset remove <id>` ─────────────────────────────────
|
|
144
|
+
/** Pure entry point — same shape used by the CLI action and the unit test. */
|
|
145
|
+
export async function configPresetRemove(client, id) {
|
|
146
|
+
return await client.configPresets.remove(id);
|
|
147
|
+
}
|
|
148
|
+
export async function configPresetRemoveAction(client, id) {
|
|
149
|
+
header('Config preset remove');
|
|
150
|
+
if (!id) {
|
|
151
|
+
error('Usage: ninedeploy config-preset remove <id>');
|
|
152
|
+
process.exitCode = 1;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
let result;
|
|
156
|
+
try {
|
|
157
|
+
result = await configPresetRemove(client, id);
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
error(err instanceof Error ? err.message : String(err));
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
success(`Removed preset "${result.id}" (live configCenter values are unchanged)`);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=configPresets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configPresets.js","sourceRoot":"","sources":["../../src/commands/configPresets.ts"],"names":[],"mappings":"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"}
|