@xemahq/xema 0.3.0 → 0.5.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 +50 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +21 -3
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/dist.d.ts +3 -0
- package/dist/commands/dist.d.ts.map +1 -0
- package/dist/commands/dist.js +142 -0
- package/dist/commands/dist.js.map +1 -0
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +39 -5
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +192 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +30 -4
- package/dist/commands/status.js.map +1 -1
- package/dist/runtime/config/init-presets.d.ts +37 -0
- package/dist/runtime/config/init-presets.d.ts.map +1 -0
- package/dist/runtime/config/init-presets.js +145 -0
- package/dist/runtime/config/init-presets.js.map +1 -0
- package/dist/runtime/distribution/available-biome.d.ts +10 -0
- package/dist/runtime/distribution/available-biome.d.ts.map +1 -0
- package/dist/runtime/distribution/available-biome.js +51 -0
- package/dist/runtime/distribution/available-biome.js.map +1 -0
- package/dist/runtime/distribution/compose.d.ts +22 -0
- package/dist/runtime/distribution/compose.d.ts.map +1 -0
- package/dist/runtime/distribution/compose.js +50 -0
- package/dist/runtime/distribution/compose.js.map +1 -0
- package/dist/runtime/paths.d.ts +3 -1
- package/dist/runtime/paths.d.ts.map +1 -1
- package/dist/runtime/paths.js +37 -0
- package/dist/runtime/paths.js.map +1 -1
- package/dist/runtime/runner/helm-cli.d.ts +20 -0
- package/dist/runtime/runner/helm-cli.d.ts.map +1 -0
- package/dist/runtime/runner/helm-cli.js +58 -0
- package/dist/runtime/runner/helm-cli.js.map +1 -0
- package/dist/runtime/runner/helm-runner.d.ts +1 -2
- package/dist/runtime/runner/helm-runner.d.ts.map +1 -1
- package/dist/runtime/runner/helm-runner.js +11 -24
- package/dist/runtime/runner/helm-runner.js.map +1 -1
- package/dist/runtime/sources/kinds/git.d.ts +4 -0
- package/dist/runtime/sources/kinds/git.d.ts.map +1 -1
- package/dist/runtime/sources/kinds/git.js +12 -7
- package/dist/runtime/sources/kinds/git.js.map +1 -1
- package/examples/01-local-monolith.yaml +1 -1
- package/examples/02-local-container-full.yaml +1 -1
- package/examples/03-byo-infra.yaml +1 -1
- package/examples/05-appliance-helm.yaml +1 -1
- package/examples/06-biome-sources.yaml +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -46,6 +46,26 @@ lifecycle (restart, health, resource limits) to the substrate beneath it
|
|
|
46
46
|
npm i -g @xemahq/xema
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
## Scaffold a config — `xema init`
|
|
50
|
+
|
|
51
|
+
Generate a `xema.config.yaml` tailored to your scenario. Run it with no flags for
|
|
52
|
+
a short interactive wizard, or `--preset` / `--yes` for scripted use:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
xema init # interactive wizard
|
|
56
|
+
xema init --preset local-container --yes # full local stack in containers
|
|
57
|
+
xema init --preset local-monolith # lowest-RAM single native process
|
|
58
|
+
xema init --preset byo-infra # bring-your-own Postgres/Keycloak/object-store
|
|
59
|
+
xema init --preset appliance # Kubernetes via Helm
|
|
60
|
+
# --edition <id> picks a distribution edition (offered from xema-distributions);
|
|
61
|
+
# --web enables the host shell; --output <path>; --force to overwrite.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The wizard asks your scenario, the distribution **edition** (the real editions
|
|
65
|
+
defined by `xema-distributions`), and — for BYO/monolith — your infra URLs. Every
|
|
66
|
+
generated config is validated against the schema before it's written, so it can
|
|
67
|
+
never be one `xema up` would reject.
|
|
68
|
+
|
|
49
69
|
## Launch the platform
|
|
50
70
|
|
|
51
71
|
```bash
|
|
@@ -173,6 +193,36 @@ What a biome *does* (services, skills, capabilities, agents) is wholly open —
|
|
|
173
193
|
only the bundle *shape* is standardized, so every author builds the same way and
|
|
174
194
|
any source resolves the same way.
|
|
175
195
|
|
|
196
|
+
## Compose a distribution — `xema dist build`
|
|
197
|
+
|
|
198
|
+
Build **your own platform**: take a base edition's first-party biomes and add
|
|
199
|
+
the ones you bring (your git repos / workspace dirs). The composition is
|
|
200
|
+
validated by the real distribution resolver (dependency closure + trust +
|
|
201
|
+
operator rules), then written as a distribution + a launch config:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
xema dist build --id acme-platform --base oss \
|
|
205
|
+
--git acme=https://github.com/acme/xema-biomes.git \
|
|
206
|
+
--source local=./my-biomes \
|
|
207
|
+
--config-out acme.config.yaml
|
|
208
|
+
# or read sources from an existing config: --config xema.config.yaml
|
|
209
|
+
# --no-allow-third-party rejects non-first-party biomes (default: allowed)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
It writes `~/.xema/distributions/<id>/{xema-distribution.json,distribution.lock.json}`
|
|
213
|
+
(the composed recipe + resolved record) and, with `--config-out`, a
|
|
214
|
+
`xema.config.yaml` (base edition + your sources). Then:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
xema dev --config acme.config.yaml # native — your biomes run from source
|
|
218
|
+
xema up --edition acme-platform # first-party biomes by edition (your composition)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Your composed distribution also shows up as an edition in `xema init` and
|
|
222
|
+
`xema up --edition <id>`. User biomes are `third-party` by origin and launch via
|
|
223
|
+
the source registry (which resolves their source roots); building container
|
|
224
|
+
images for your own biomes is a separate step.
|
|
225
|
+
|
|
176
226
|
## Author biomes & run capabilities
|
|
177
227
|
|
|
178
228
|
```bash
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,wBAAgB,YAAY,IAAI,OAAO,CA4BtC;AAED,wBAAsB,IAAI,CAAC,IAAI,GAAE,aAAa,CAAC,MAAM,CAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpF"}
|
package/dist/cli.js
CHANGED
|
@@ -9,10 +9,12 @@ const commander_1 = require("commander");
|
|
|
9
9
|
const apply_1 = require("./commands/apply");
|
|
10
10
|
const biome_1 = require("./commands/biome");
|
|
11
11
|
const dev_1 = require("./commands/dev");
|
|
12
|
+
const dist_1 = require("./commands/dist");
|
|
12
13
|
const doctor_1 = require("./commands/doctor");
|
|
13
14
|
const down_1 = require("./commands/down");
|
|
14
15
|
const export_1 = require("./commands/export");
|
|
15
16
|
const import_1 = require("./commands/import");
|
|
17
|
+
const init_1 = require("./commands/init");
|
|
16
18
|
const logs_1 = require("./commands/logs");
|
|
17
19
|
const objects_1 = require("./commands/objects");
|
|
18
20
|
const plan_1 = require("./commands/plan");
|
|
@@ -38,11 +40,13 @@ function buildProgram() {
|
|
|
38
40
|
.version(CLI_VERSION, '-v, --version', 'print the CLI version')
|
|
39
41
|
.showHelpAfterError(true)
|
|
40
42
|
.configureHelp({ sortSubcommands: true });
|
|
43
|
+
(0, init_1.registerCommand)(program);
|
|
41
44
|
(0, up_1.registerCommand)(program);
|
|
42
45
|
(0, down_1.registerCommand)(program);
|
|
43
46
|
(0, status_1.registerCommand)(program);
|
|
44
47
|
(0, logs_1.registerCommand)(program);
|
|
45
48
|
(0, dev_1.registerCommand)(program);
|
|
49
|
+
(0, dist_1.registerCommand)(program);
|
|
46
50
|
(0, serve_1.registerCommand)(program);
|
|
47
51
|
(0, biome_1.registerCommand)(program);
|
|
48
52
|
(0, plan_1.registerCommand)(program);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BzC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+BtD"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerCommand = registerCommand;
|
|
4
4
|
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
5
6
|
const node_path_1 = require("node:path");
|
|
6
7
|
const env_defaults_1 = require("../dev/env-defaults");
|
|
7
8
|
const infra_preflight_1 = require("../dev/infra-preflight");
|
|
@@ -41,8 +42,15 @@ function registerCommand(program) {
|
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
function reexecUnderWatch(services, opts) {
|
|
44
|
-
const
|
|
45
|
-
|
|
45
|
+
const srcEntry = (0, node_path_1.join)(__dirname, '..', '..', 'src', 'cli.ts');
|
|
46
|
+
if (!(0, node_fs_1.existsSync)(srcEntry)) {
|
|
47
|
+
(0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.MissingDependency, 'xema dev --watch needs a source checkout — it boots src/cli.ts via tsx (no ' +
|
|
48
|
+
`prebuild). Source entry not found at ${srcEntry}. For an installed binary ` +
|
|
49
|
+
'run a plain `xema dev` (boots from dist, no hot-reload).');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const tsxCli = resolveTsxCli();
|
|
53
|
+
const args = [tsxCli, 'watch', srcEntry, 'dev', ...services];
|
|
46
54
|
if (opts.edition) {
|
|
47
55
|
args.push('--edition', opts.edition);
|
|
48
56
|
}
|
|
@@ -55,7 +63,7 @@ function reexecUnderWatch(services, opts) {
|
|
|
55
63
|
if (opts.skipPreflight) {
|
|
56
64
|
args.push('--skip-preflight');
|
|
57
65
|
}
|
|
58
|
-
console.log('xema dev --watch —
|
|
66
|
+
console.log('xema dev --watch — booting from src via tsx; any .ts change restarts. Ctrl+C to stop.');
|
|
59
67
|
const child = (0, node_child_process_1.spawn)(process.execPath, args, {
|
|
60
68
|
stdio: 'inherit',
|
|
61
69
|
env: { ...process.env, [WATCH_CHILD_ENV]: '1', NODE_OPTIONS: watchNodeOptions() },
|
|
@@ -64,6 +72,16 @@ function reexecUnderWatch(services, opts) {
|
|
|
64
72
|
process.exit(code ?? 0);
|
|
65
73
|
});
|
|
66
74
|
}
|
|
75
|
+
function resolveTsxCli() {
|
|
76
|
+
try {
|
|
77
|
+
return require.resolve('tsx/cli');
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
(0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.MissingDependency, 'xema dev --watch requires the `tsx` dependency, but it could not be resolved. ' +
|
|
81
|
+
'Reinstall dependencies (`pnpm install`) and retry.');
|
|
82
|
+
throw new Error('unreachable');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
67
85
|
function watchNodeOptions() {
|
|
68
86
|
const existing = process.env.NODE_OPTIONS ?? '';
|
|
69
87
|
if (existing.includes('--conditions=xema-source')) {
|
package/dist/commands/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dist.d.ts","sourceRoot":"","sources":["../../src/commands/dist.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BzC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6BtD"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCommand = registerCommand;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_os_1 = require("node:os");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const yaml_1 = require("yaml");
|
|
8
|
+
const exit_codes_1 = require("../lib/exit-codes");
|
|
9
|
+
const loader_1 = require("../runtime/config/loader");
|
|
10
|
+
const compose_1 = require("../runtime/distribution/compose");
|
|
11
|
+
const paths_1 = require("../runtime/paths");
|
|
12
|
+
const credentials_1 = require("../runtime/sources/credentials");
|
|
13
|
+
const git_1 = require("../runtime/sources/kinds/git");
|
|
14
|
+
const schema_1 = require("../runtime/sources/schema");
|
|
15
|
+
const DEFAULT_BASE = 'oss';
|
|
16
|
+
const DEFAULT_OUT_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), '.xema', 'distributions');
|
|
17
|
+
function collect(value, previous) {
|
|
18
|
+
return [...previous, value];
|
|
19
|
+
}
|
|
20
|
+
function registerCommand(program) {
|
|
21
|
+
const dist = program.command('dist').summary('Compose a distribution (build your own platform)');
|
|
22
|
+
dist
|
|
23
|
+
.command('build')
|
|
24
|
+
.summary('Compose a distribution from a base edition + your own biomes')
|
|
25
|
+
.description('Seed a base edition (--base) with its first-party biomes, add your own ' +
|
|
26
|
+
'biomes from git/workspace sources (--git / --source, or a --config ' +
|
|
27
|
+
'sources: block), resolve + validate the whole set with the distribution ' +
|
|
28
|
+
'resolver, and write the distribution (xema-distribution.json + ' +
|
|
29
|
+
'distribution.lock.json) plus a launch xema.config.yaml.')
|
|
30
|
+
.requiredOption('--id <name>', 'Id for the composed distribution (kebab-case)')
|
|
31
|
+
.option('--base <edition>', `Base edition to extend (default: ${DEFAULT_BASE})`)
|
|
32
|
+
.option('--git <name=url>', 'Add a git biome source (repeatable)', collect, [])
|
|
33
|
+
.option('--source <name=path>', 'Add a local biome dir / workspace (repeatable)', collect, [])
|
|
34
|
+
.option('--config <path>', 'Read additional biome sources from a xema.config.yaml')
|
|
35
|
+
.option('--no-allow-third-party', 'Reject third-party (user) biomes (first-party only)')
|
|
36
|
+
.option('--out-dir <dir>', `Where to write the distribution (default: ${DEFAULT_OUT_DIR})`)
|
|
37
|
+
.option('--config-out <path>', 'Also write a launch xema.config.yaml referencing it')
|
|
38
|
+
.action((opts) => {
|
|
39
|
+
try {
|
|
40
|
+
runDistBuild(opts);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
44
|
+
(0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.GenericError, `xema dist build failed: ${message}`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function runDistBuild(opts) {
|
|
49
|
+
const id = opts.id;
|
|
50
|
+
if (id === undefined || !/^[a-z][a-z0-9-]*$/.test(id)) {
|
|
51
|
+
return (0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.ConfigurationError, `--id must be lowercase kebab-case (got "${String(id)}").`);
|
|
52
|
+
}
|
|
53
|
+
const base = opts.base ?? DEFAULT_BASE;
|
|
54
|
+
const log = (line) => console.log(` ${line}`);
|
|
55
|
+
const specs = [
|
|
56
|
+
...(opts.git ?? []).map((s) => gitSpecFrom(s)),
|
|
57
|
+
...(opts.source ?? []).map((s) => workspaceSpecFrom(s)),
|
|
58
|
+
...sourcesFromConfig(opts.config),
|
|
59
|
+
];
|
|
60
|
+
const credentials = new credentials_1.CredentialResolver();
|
|
61
|
+
const userSources = specs.map((spec) => resolveSourceRoot(spec, credentials, log));
|
|
62
|
+
const allowThirdParty = opts.allowThirdParty !== false;
|
|
63
|
+
console.log(`xema dist build — composing "${id}" from base "${base}"`);
|
|
64
|
+
console.log('-'.repeat(60));
|
|
65
|
+
const result = (0, compose_1.composeDistribution)({
|
|
66
|
+
id,
|
|
67
|
+
baseEdition: base,
|
|
68
|
+
userSources,
|
|
69
|
+
allowThirdParty,
|
|
70
|
+
resolvedAt: new Date().toISOString(),
|
|
71
|
+
});
|
|
72
|
+
const outDir = (0, node_path_1.resolve)(process.cwd(), opts.outDir ?? DEFAULT_OUT_DIR, id);
|
|
73
|
+
(0, node_fs_1.mkdirSync)(outDir, { recursive: true });
|
|
74
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(outDir, 'xema-distribution.json'), `${JSON.stringify(result.definition, null, 2)}\n`, 'utf8');
|
|
75
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(outDir, 'distribution.lock.json'), `${JSON.stringify(result.lock, null, 2)}\n`, 'utf8');
|
|
76
|
+
if (opts.configOut !== undefined) {
|
|
77
|
+
const configPath = (0, node_path_1.resolve)(process.cwd(), opts.configOut);
|
|
78
|
+
(0, node_fs_1.writeFileSync)(configPath, renderLaunchConfig(base, specs), 'utf8');
|
|
79
|
+
}
|
|
80
|
+
console.log('');
|
|
81
|
+
console.log(`✓ Composed "${id}": ${String(result.lock.biomes.length)} biome(s) ` +
|
|
82
|
+
`(${String(result.baseBiomeCount)} base + ${String(result.userBiomeCount)} user` +
|
|
83
|
+
`${result.overridden.length > 0 ? `, ${String(result.overridden.length)} overridden` : ''}).`);
|
|
84
|
+
console.log(` distribution → ${outDir}/`);
|
|
85
|
+
if (opts.configOut !== undefined) {
|
|
86
|
+
console.log(` launch config → ${(0, node_path_1.resolve)(process.cwd(), opts.configOut)}`);
|
|
87
|
+
console.log('');
|
|
88
|
+
console.log(`Next: xema dev --config ${opts.configOut} (native — user biomes run from source)`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(`Next: xema up --edition ${id} (add a launch config with --config-out for your git biomes)`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function resolveSourceRoot(spec, credentials, log) {
|
|
96
|
+
if (spec.kind === schema_1.SourceKind.Workspace) {
|
|
97
|
+
const root = spec.root !== undefined ? (0, node_path_1.resolve)(process.cwd(), spec.root) : (0, paths_1.findMonorepoRoot)();
|
|
98
|
+
if (root === null) {
|
|
99
|
+
return (0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.ConfigurationError, `source "${spec.name}": no root (not in a monorepo and no path given).`);
|
|
100
|
+
}
|
|
101
|
+
return { name: spec.name, root };
|
|
102
|
+
}
|
|
103
|
+
if (spec.kind === schema_1.SourceKind.Git) {
|
|
104
|
+
log(`cloning ${spec.url}${spec.ref !== undefined ? `@${spec.ref}` : ''} …`);
|
|
105
|
+
return { name: spec.name, root: (0, git_1.checkoutGitSource)(spec, credentials, log) };
|
|
106
|
+
}
|
|
107
|
+
return (0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.ConfigurationError, `source "${spec.name}" (${spec.kind}) can't seed a composition — use workspace or git ` +
|
|
108
|
+
`(npm/oci are install-time).`);
|
|
109
|
+
}
|
|
110
|
+
function gitSpecFrom(raw) {
|
|
111
|
+
const { name, value } = splitNameValue(raw, '--git');
|
|
112
|
+
return { name, kind: schema_1.SourceKind.Git, url: value };
|
|
113
|
+
}
|
|
114
|
+
function workspaceSpecFrom(raw) {
|
|
115
|
+
const { name, value } = splitNameValue(raw, '--source');
|
|
116
|
+
return { name, kind: schema_1.SourceKind.Workspace, root: value };
|
|
117
|
+
}
|
|
118
|
+
function splitNameValue(raw, flag) {
|
|
119
|
+
const eq = raw.indexOf('=');
|
|
120
|
+
if (eq <= 0) {
|
|
121
|
+
return (0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.ConfigurationError, `${flag} expects <name>=<value>, got "${raw}".`);
|
|
122
|
+
}
|
|
123
|
+
return { name: raw.slice(0, eq).trim(), value: raw.slice(eq + 1).trim() };
|
|
124
|
+
}
|
|
125
|
+
function sourcesFromConfig(configPath) {
|
|
126
|
+
if (configPath === undefined) {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
const loaded = (0, loader_1.loadXemaConfig)({ explicit: configPath });
|
|
130
|
+
return loaded.config.sources.filter((s) => s.kind === schema_1.SourceKind.Workspace || s.kind === schema_1.SourceKind.Git);
|
|
131
|
+
}
|
|
132
|
+
function renderLaunchConfig(baseEdition, sources) {
|
|
133
|
+
const config = {
|
|
134
|
+
edition: baseEdition,
|
|
135
|
+
app: { substrate: 'native' },
|
|
136
|
+
sources,
|
|
137
|
+
};
|
|
138
|
+
const header = '# xema.config.yaml — generated by `xema dist build`\n' +
|
|
139
|
+
`# Base edition "${baseEdition}" + your biome sources (launched natively from source).\n\n`;
|
|
140
|
+
return header + (0, yaml_1.stringify)(config, { aliasDuplicateObjects: false });
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=dist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dist.js","sourceRoot":"","sources":["../../src/commands/dist.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBzC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoBtD"}
|
package/dist/commands/down.js
CHANGED
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerCommand = registerCommand;
|
|
4
4
|
const exit_codes_1 = require("../lib/exit-codes");
|
|
5
|
+
const loader_1 = require("../runtime/config/loader");
|
|
5
6
|
const schema_1 = require("../runtime/config/schema");
|
|
6
7
|
const docker_cli_1 = require("../runtime/runner/docker-cli");
|
|
8
|
+
const helm_cli_1 = require("../runtime/runner/helm-cli");
|
|
7
9
|
function registerCommand(program) {
|
|
8
10
|
program
|
|
9
11
|
.command('down')
|
|
10
|
-
.summary('Stop everything xema up started (container substrate)')
|
|
11
|
-
.description('Stop + remove
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
|
|
12
|
+
.summary('Stop everything xema up started (container or helm substrate)')
|
|
13
|
+
.description('Stop + remove everything the launcher started, per the configured substrate. ' +
|
|
14
|
+
'Container: remove launcher-owned containers (services + managed infra); ' +
|
|
15
|
+
'--purge also deletes named data volumes. Helm: uninstall every release in ' +
|
|
16
|
+
'the namespace (XEMA_NAMESPACE, default "xema").')
|
|
17
|
+
.option('--config <path>', 'Path to xema.config.yaml (selects the substrate)')
|
|
18
|
+
.option('--purge', 'Also delete persistent data volumes (DESTRUCTIVE; container substrate)')
|
|
15
19
|
.action(async (opts) => {
|
|
16
20
|
try {
|
|
17
21
|
await runDown(opts);
|
|
@@ -23,6 +27,36 @@ function registerCommand(program) {
|
|
|
23
27
|
});
|
|
24
28
|
}
|
|
25
29
|
async function runDown(opts) {
|
|
30
|
+
const { config } = (0, loader_1.loadXemaConfig)({ explicit: opts.config });
|
|
31
|
+
if (config.app.substrate === schema_1.Substrate.Helm) {
|
|
32
|
+
await runHelmDown(opts);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
await runContainerDown(opts);
|
|
36
|
+
}
|
|
37
|
+
async function runHelmDown(opts) {
|
|
38
|
+
const helm = new helm_cli_1.HelmCli();
|
|
39
|
+
if (!(await helm.available())) {
|
|
40
|
+
console.log('helm is not reachable — nothing to uninstall.');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const releases = await helm.listReleases();
|
|
44
|
+
if (releases.length === 0) {
|
|
45
|
+
console.log(`No Helm releases found in namespace "${helm.namespace}".`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log(`Uninstalling ${String(releases.length)} release(s) from "${helm.namespace}"...`);
|
|
49
|
+
for (const release of releases) {
|
|
50
|
+
await helm.uninstall(release);
|
|
51
|
+
console.log(` uninstalled ${release}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (opts.purge) {
|
|
55
|
+
console.log('Note: --purge does not delete Kubernetes PersistentVolumeClaims. Persistent ' +
|
|
56
|
+
'data is retained; remove PVCs with `kubectl delete pvc` if intended.');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function runContainerDown(opts) {
|
|
26
60
|
const docker = new docker_cli_1.DockerCli();
|
|
27
61
|
if (!(await docker.available())) {
|
|
28
62
|
console.log('No container runtime reachable — nothing to stop (native services stop with `xema up`).');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"down.js","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"down.js","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":";;AAuBA,0CAoBC;AA3CD,kDAA8D;AAC9D,qDAA0D;AAC1D,qDAAqE;AACrE,6DAAyD;AACzD,yDAAqD;AAmBrD,SAAgB,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,OAAO,CAAC,+DAA+D,CAAC;SACxE,WAAW,CACV,+EAA+E;QAC7E,0EAA0E;QAC1E,4EAA4E;QAC5E,iDAAiD,CACpD;SACA,MAAM,CAAC,iBAAiB,EAAE,kDAAkD,CAAC;SAC7E,MAAM,CAAC,SAAS,EAAE,wEAAwE,CAAC;SAC3F,MAAM,CAAC,KAAK,EAAE,IAAiB,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAA,qBAAQ,EAAC,4BAAe,CAAC,YAAY,EAAE,qBAAqB,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAAiB;IACtC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,uBAAc,EAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,kBAAS,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAGD,KAAK,UAAU,WAAW,CAAC,IAAiB;IAC1C,MAAM,IAAI,GAAG,IAAI,kBAAO,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC3C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;IAC1E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,qBAAqB,IAAI,CAAC,SAAS,MAAM,CAAC,CAAC;QAC9F,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAGf,OAAO,CAAC,GAAG,CACT,8EAA8E;YAC5E,sEAAsE,CACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAGD,KAAK,UAAU,gBAAgB,CAAC,IAAiB;IAC/C,MAAM,MAAM,GAAG,IAAI,sBAAS,EAAE,CAAC;IAC/B,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,yFAAyF,CAAC,CAAC;QACvG,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;IACrD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACrE,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,uBAAc,CAAC,EAAE,CAAC;YACtD,MAAM,MAAM,GAAG,QAAQ,SAAS,OAAO,CAAC;YACxC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBzC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuBtD"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCommand = registerCommand;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const promises_1 = require("node:readline/promises");
|
|
7
|
+
const yaml_1 = require("yaml");
|
|
8
|
+
const exit_codes_1 = require("../lib/exit-codes");
|
|
9
|
+
const init_presets_1 = require("../runtime/config/init-presets");
|
|
10
|
+
const paths_1 = require("../runtime/paths");
|
|
11
|
+
const DEFAULT_OUTPUT = 'xema.config.yaml';
|
|
12
|
+
const DEFAULT_PRESET = init_presets_1.InitPreset.LocalContainer;
|
|
13
|
+
function registerCommand(program) {
|
|
14
|
+
program
|
|
15
|
+
.command('init')
|
|
16
|
+
.summary('Scaffold a xema.config.yaml (interactive or --preset)')
|
|
17
|
+
.description('Create a xema.config.yaml. Run with no flags for an interactive wizard ' +
|
|
18
|
+
`over the real scenarios (${init_presets_1.INIT_PRESETS.join(', ')}), or pass --preset ` +
|
|
19
|
+
'<name> (+ --yes) to generate one non-interactively.')
|
|
20
|
+
.option('--preset <name>', `One of: ${init_presets_1.INIT_PRESETS.join(' | ')}`)
|
|
21
|
+
.option('--output <path>', `Output path (default: ${DEFAULT_OUTPUT})`)
|
|
22
|
+
.option('--edition <id>', 'Distribution edition (default: oss)')
|
|
23
|
+
.option('--web', 'Enable the web host shell (where the preset supports it)')
|
|
24
|
+
.option('--yes', 'Non-interactive: accept defaults (preset defaults to local-container)')
|
|
25
|
+
.option('--force', 'Overwrite an existing config file')
|
|
26
|
+
.action(async (opts) => {
|
|
27
|
+
try {
|
|
28
|
+
await runInit(opts);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
32
|
+
(0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.GenericError, `xema init failed: ${message}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async function runInit(opts) {
|
|
37
|
+
const outputPath = (0, node_path_1.resolve)(process.cwd(), opts.output ?? DEFAULT_OUTPUT);
|
|
38
|
+
if ((0, node_fs_1.existsSync)(outputPath) && opts.force !== true) {
|
|
39
|
+
return (0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.ConfigurationError, `${outputPath} already exists. Pass --force to overwrite, or --output <path> to write elsewhere.`);
|
|
40
|
+
}
|
|
41
|
+
const resolved = await resolvePresetAndInputs(opts);
|
|
42
|
+
warnIfUnknownEdition(resolved.inputs.edition);
|
|
43
|
+
const config = (0, init_presets_1.buildPresetConfig)(resolved.preset, resolved.inputs);
|
|
44
|
+
const meta = init_presets_1.PRESET_METAS[resolved.preset];
|
|
45
|
+
(0, node_fs_1.writeFileSync)(outputPath, renderConfigFile(resolved.preset, config), 'utf8');
|
|
46
|
+
console.log('');
|
|
47
|
+
console.log(`✓ Wrote ${outputPath} (${meta.label})`);
|
|
48
|
+
console.log('');
|
|
49
|
+
console.log('Next steps:');
|
|
50
|
+
if (meta.needsExternalInfra) {
|
|
51
|
+
console.log(' 1. Make sure your infra is running (or run `xema doctor --infra`).');
|
|
52
|
+
console.log(` 2. ${meta.nextStep}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log(` • ${meta.nextStep}`);
|
|
56
|
+
}
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log('Tune it later: infra modes (managed | external <url> | disabled), app.substrate,');
|
|
59
|
+
console.log('app.include, and a `sources:` block for extra biome registries (see `xema doctor --sources`).');
|
|
60
|
+
}
|
|
61
|
+
async function resolvePresetAndInputs(opts) {
|
|
62
|
+
if (opts.preset !== undefined) {
|
|
63
|
+
const preset = (0, init_presets_1.parseInitPreset)(opts.preset);
|
|
64
|
+
if (preset === null) {
|
|
65
|
+
return (0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.ConfigurationError, `Unknown --preset "${opts.preset}". Valid: ${init_presets_1.INIT_PRESETS.join(', ')}.`);
|
|
66
|
+
}
|
|
67
|
+
return { preset, inputs: inputsFromFlags(opts) };
|
|
68
|
+
}
|
|
69
|
+
if (opts.yes === true) {
|
|
70
|
+
return { preset: DEFAULT_PRESET, inputs: inputsFromFlags(opts) };
|
|
71
|
+
}
|
|
72
|
+
if (process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
|
|
73
|
+
return (0, exit_codes_1.exitWith)(exit_codes_1.XemaCliExitCode.ConfigurationError, 'Not a TTY — cannot run the interactive wizard. Pass --preset <name> ' +
|
|
74
|
+
`(${init_presets_1.INIT_PRESETS.join(' | ')}) or --yes.`);
|
|
75
|
+
}
|
|
76
|
+
return runWizard(opts);
|
|
77
|
+
}
|
|
78
|
+
function warnIfUnknownEdition(edition) {
|
|
79
|
+
const available = (0, paths_1.listAvailableEditions)();
|
|
80
|
+
if (available.length > 0 && !available.includes(edition)) {
|
|
81
|
+
console.log(`⚠ edition "${edition}" is not among the known distributions ` +
|
|
82
|
+
`(${available.join(', ')}); \`xema up\` will fail unless its lock is provided ` +
|
|
83
|
+
`via --lock / XEMA_DISTRIBUTION_LOCK_PATH.`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function inputsFromFlags(opts) {
|
|
87
|
+
return {
|
|
88
|
+
edition: opts.edition ?? 'oss',
|
|
89
|
+
web: opts.web === true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function runWizard(opts) {
|
|
93
|
+
const rl = (0, promises_1.createInterface)({ input: process.stdin, output: process.stdout });
|
|
94
|
+
try {
|
|
95
|
+
console.log('xema init — scaffold a xema.config.yaml');
|
|
96
|
+
console.log('-'.repeat(50));
|
|
97
|
+
const presets = init_presets_1.INIT_PRESETS;
|
|
98
|
+
const choice = await promptChoice(rl, 'What are you setting up?', presets.map((p) => {
|
|
99
|
+
const m = init_presets_1.PRESET_METAS[p];
|
|
100
|
+
return { label: m.label, hint: m.description };
|
|
101
|
+
}));
|
|
102
|
+
const preset = presets[choice] ?? DEFAULT_PRESET;
|
|
103
|
+
const meta = init_presets_1.PRESET_METAS[preset];
|
|
104
|
+
const edition = await promptEdition(rl, opts.edition ?? 'oss');
|
|
105
|
+
let urls = {};
|
|
106
|
+
if (meta.needsExternalInfra) {
|
|
107
|
+
console.log('');
|
|
108
|
+
console.log('External infrastructure URLs (press Enter to accept the local default):');
|
|
109
|
+
urls = await promptExternalInfra(rl, preset);
|
|
110
|
+
}
|
|
111
|
+
let web = opts.web === true;
|
|
112
|
+
if (meta.supportsWeb) {
|
|
113
|
+
web = await promptYesNo(rl, 'Start the web host shell?', false);
|
|
114
|
+
}
|
|
115
|
+
return { preset, inputs: { edition, web, ...urls } };
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
rl.close();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function promptExternalInfra(rl, preset) {
|
|
122
|
+
const out = {};
|
|
123
|
+
out.postgresUrl = await promptText(rl, ' Postgres URL', init_presets_1.DEFAULT_LOCAL_URLS.postgres);
|
|
124
|
+
if (preset === init_presets_1.InitPreset.LocalMonolith) {
|
|
125
|
+
out.redisUrl = await promptText(rl, ' Redis URL', init_presets_1.DEFAULT_LOCAL_URLS.redis);
|
|
126
|
+
}
|
|
127
|
+
out.keycloakUrl = await promptText(rl, ' Keycloak URL', init_presets_1.DEFAULT_LOCAL_URLS.keycloak);
|
|
128
|
+
out.keycloakRealm = await promptText(rl, ' Keycloak realm', init_presets_1.DEFAULT_LOCAL_URLS.keycloakRealm);
|
|
129
|
+
if (preset === init_presets_1.InitPreset.ByoInfra) {
|
|
130
|
+
out.objectStoreUrl = await promptText(rl, ' Object-store URL', init_presets_1.DEFAULT_LOCAL_URLS.objectStore);
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
async function promptChoice(rl, question, items) {
|
|
135
|
+
console.log('');
|
|
136
|
+
console.log(question);
|
|
137
|
+
items.forEach((item, i) => {
|
|
138
|
+
console.log(` ${String(i + 1)}) ${item.label}`);
|
|
139
|
+
if (item.hint !== undefined) {
|
|
140
|
+
console.log(` ${item.hint}`);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
for (;;) {
|
|
144
|
+
const raw = (await rl.question(`Choice [1-${String(items.length)}] (1): `)).trim();
|
|
145
|
+
if (raw.length === 0) {
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
const n = Number.parseInt(raw, 10);
|
|
149
|
+
if (Number.isInteger(n) && n >= 1 && n <= items.length) {
|
|
150
|
+
return n - 1;
|
|
151
|
+
}
|
|
152
|
+
console.log(` Please enter a number between 1 and ${String(items.length)}.`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function promptEdition(rl, def) {
|
|
156
|
+
const available = (0, paths_1.listAvailableEditions)();
|
|
157
|
+
if (available.length === 0) {
|
|
158
|
+
return promptText(rl, 'Distribution edition', def);
|
|
159
|
+
}
|
|
160
|
+
const ordered = available.includes(def) ? [def, ...available.filter((e) => e !== def)] : [def, ...available];
|
|
161
|
+
const idx = await promptChoice(rl, 'Distribution edition (defined by xema-distributions)', ordered.map((e) => ({ label: e })));
|
|
162
|
+
return ordered[idx] ?? def;
|
|
163
|
+
}
|
|
164
|
+
async function promptText(rl, question, def) {
|
|
165
|
+
const raw = (await rl.question(`${question} (${def}): `)).trim();
|
|
166
|
+
return raw.length > 0 ? raw : def;
|
|
167
|
+
}
|
|
168
|
+
async function promptYesNo(rl, question, def) {
|
|
169
|
+
const suffix = def ? '(Y/n)' : '(y/N)';
|
|
170
|
+
const raw = (await rl.question(`${question} ${suffix}: `)).trim().toLowerCase();
|
|
171
|
+
if (raw.length === 0) {
|
|
172
|
+
return def;
|
|
173
|
+
}
|
|
174
|
+
return raw === 'y' || raw === 'yes';
|
|
175
|
+
}
|
|
176
|
+
function renderConfigFile(preset, config) {
|
|
177
|
+
const meta = init_presets_1.PRESET_METAS[preset];
|
|
178
|
+
const header = [
|
|
179
|
+
'# xema.config.yaml',
|
|
180
|
+
`# Generated by \`xema init\` — preset: ${preset}`,
|
|
181
|
+
`# ${meta.description}`,
|
|
182
|
+
'#',
|
|
183
|
+
`# Next: ${meta.nextStep}`,
|
|
184
|
+
'# Infra modes: managed (launcher runs it) | external (give a url) | disabled.',
|
|
185
|
+
'# Full annotated reference + more scenarios:',
|
|
186
|
+
'# https://github.com/xema-dev/xema-cli/tree/main/apps/xema-cli/examples',
|
|
187
|
+
'',
|
|
188
|
+
'',
|
|
189
|
+
].join('\n');
|
|
190
|
+
return header + (0, yaml_1.stringify)(config, { aliasDuplicateObjects: false });
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=init.js.map
|