@orgloop/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/LICENSE.md +21 -0
- package/dist/commands/add.d.ts +8 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +363 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/apply.d.ts +9 -0
- package/dist/commands/apply.d.ts.map +1 -0
- package/dist/commands/apply.js +289 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/doctor.d.ts +45 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +346 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/env.d.ts +23 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +230 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/hook.d.ts +16 -0
- package/dist/commands/hook.d.ts.map +1 -0
- package/dist/commands/hook.js +80 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/init.d.ts +42 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +532 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +8 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +177 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/install-service.d.ts +8 -0
- package/dist/commands/install-service.d.ts.map +1 -0
- package/dist/commands/install-service.js +182 -0
- package/dist/commands/install-service.js.map +1 -0
- package/dist/commands/logs.d.ts +8 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +197 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/plan.d.ts +9 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +200 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/routes.d.ts +37 -0
- package/dist/commands/routes.d.ts.map +1 -0
- package/dist/commands/routes.js +167 -0
- package/dist/commands/routes.js.map +1 -0
- package/dist/commands/service.d.ts +9 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +178 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +176 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +8 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +102 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/test.d.ts +8 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +236 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/validate.d.ts +33 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +501 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/version.d.ts +8 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +42 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +169 -0
- package/dist/config.js.map +1 -0
- package/dist/env-metadata.d.ts +12 -0
- package/dist/env-metadata.d.ts.map +1 -0
- package/dist/env-metadata.js +39 -0
- package/dist/env-metadata.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/module-resolver.d.ts +42 -0
- package/dist/module-resolver.d.ts.map +1 -0
- package/dist/module-resolver.js +134 -0
- package/dist/module-resolver.js.map +1 -0
- package/dist/output.d.ts +36 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +142 -0
- package/dist/output.js.map +1 -0
- package/dist/resolve-connectors.d.ts +27 -0
- package/dist/resolve-connectors.d.ts.map +1 -0
- package/dist/resolve-connectors.js +94 -0
- package/dist/resolve-connectors.js.map +1 -0
- package/package.json +51 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loading for the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Loads orgloop.yaml from --config flag or current directory,
|
|
5
|
+
* resolves environment variables, merges with user defaults.
|
|
6
|
+
*/
|
|
7
|
+
import { access, readFile, readdir } from 'node:fs/promises';
|
|
8
|
+
import { homedir } from 'node:os';
|
|
9
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
10
|
+
import yaml from 'js-yaml';
|
|
11
|
+
import { resolveModules } from './module-resolver.js';
|
|
12
|
+
// ─── Env var substitution ────────────────────────────────────────────────────
|
|
13
|
+
function substituteEnvVars(value) {
|
|
14
|
+
if (typeof value === 'string') {
|
|
15
|
+
return value.replace(/\$\{([^}]+)\}/g, (_match, varName) => {
|
|
16
|
+
const envVal = process.env[varName];
|
|
17
|
+
if (envVal === undefined) {
|
|
18
|
+
throw new Error(`Environment variable "${varName}" is not set`);
|
|
19
|
+
}
|
|
20
|
+
return envVal;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
return value.map(substituteEnvVars);
|
|
25
|
+
}
|
|
26
|
+
if (value !== null && typeof value === 'object') {
|
|
27
|
+
const result = {};
|
|
28
|
+
for (const [k, v] of Object.entries(value)) {
|
|
29
|
+
result[k] = substituteEnvVars(v);
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
// ─── YAML loader ─────────────────────────────────────────────────────────────
|
|
36
|
+
async function loadYaml(filePath) {
|
|
37
|
+
const content = await readFile(filePath, 'utf-8');
|
|
38
|
+
const parsed = yaml.load(content);
|
|
39
|
+
return substituteEnvVars(parsed);
|
|
40
|
+
}
|
|
41
|
+
async function fileExists(filePath) {
|
|
42
|
+
try {
|
|
43
|
+
await access(filePath);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve the config file path.
|
|
52
|
+
* Priority: --config flag > ./orgloop.yaml > error.
|
|
53
|
+
*/
|
|
54
|
+
export function resolveConfigPath(configPath) {
|
|
55
|
+
if (configPath) {
|
|
56
|
+
return isAbsolute(configPath) ? configPath : resolve(process.cwd(), configPath);
|
|
57
|
+
}
|
|
58
|
+
return resolve(process.cwd(), 'orgloop.yaml');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Load and resolve the full OrgLoop configuration from YAML files.
|
|
62
|
+
*/
|
|
63
|
+
export async function loadCliConfig(options = {}) {
|
|
64
|
+
const configPath = resolveConfigPath(options.configPath);
|
|
65
|
+
if (!(await fileExists(configPath))) {
|
|
66
|
+
throw new Error(`Configuration file not found: ${configPath}\nRun \`orgloop init\` to create a new project, or use --config to specify a path.`);
|
|
67
|
+
}
|
|
68
|
+
const basePath = resolve(configPath, '..');
|
|
69
|
+
const project = await loadYaml(configPath);
|
|
70
|
+
// Load connector files
|
|
71
|
+
const sources = [];
|
|
72
|
+
const actors = [];
|
|
73
|
+
for (const file of project.connectors ?? []) {
|
|
74
|
+
const filePath = isAbsolute(file) ? file : resolve(basePath, file);
|
|
75
|
+
if (await fileExists(filePath)) {
|
|
76
|
+
const data = await loadYaml(filePath);
|
|
77
|
+
if (data?.sources)
|
|
78
|
+
sources.push(...data.sources);
|
|
79
|
+
if (data?.actors)
|
|
80
|
+
actors.push(...data.actors);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Load transform files
|
|
84
|
+
const transforms = [];
|
|
85
|
+
for (const file of project.transforms ?? []) {
|
|
86
|
+
const filePath = isAbsolute(file) ? file : resolve(basePath, file);
|
|
87
|
+
if (await fileExists(filePath)) {
|
|
88
|
+
const data = await loadYaml(filePath);
|
|
89
|
+
if (data?.transforms)
|
|
90
|
+
transforms.push(...data.transforms);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Load logger files
|
|
94
|
+
const loggers = [];
|
|
95
|
+
for (const file of project.loggers ?? []) {
|
|
96
|
+
const filePath = isAbsolute(file) ? file : resolve(basePath, file);
|
|
97
|
+
if (await fileExists(filePath)) {
|
|
98
|
+
const data = await loadYaml(filePath);
|
|
99
|
+
if (data?.loggers)
|
|
100
|
+
loggers.push(...data.loggers);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Auto-discover route files from routes/ directory
|
|
104
|
+
const routes = [];
|
|
105
|
+
const routesDir = resolve(basePath, 'routes');
|
|
106
|
+
if (await fileExists(routesDir)) {
|
|
107
|
+
try {
|
|
108
|
+
const files = await readdir(routesDir);
|
|
109
|
+
for (const file of files.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))) {
|
|
110
|
+
const filePath = resolve(routesDir, file);
|
|
111
|
+
const data = await loadYaml(filePath);
|
|
112
|
+
if (data?.routes) {
|
|
113
|
+
// Resolve prompt_file paths relative to route YAML
|
|
114
|
+
for (const route of data.routes) {
|
|
115
|
+
if (route.with?.prompt_file) {
|
|
116
|
+
route.with.prompt_file = resolve(routesDir, route.with.prompt_file);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
routes.push(...data.routes);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// routes dir not readable, skip
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Merge with user defaults (~/.orgloop/config.yaml)
|
|
128
|
+
const userConfigPath = join(homedir(), '.orgloop', 'config.yaml');
|
|
129
|
+
let userDefaults = {};
|
|
130
|
+
if (await fileExists(userConfigPath)) {
|
|
131
|
+
try {
|
|
132
|
+
userDefaults = (await loadYaml(userConfigPath)) ?? {};
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// ignore user config errors
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Resolve modules and merge their routes
|
|
139
|
+
if (project.modules?.length) {
|
|
140
|
+
const moduleResult = await resolveModules(project.modules, basePath);
|
|
141
|
+
routes.push(...moduleResult.routes);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
project: {
|
|
145
|
+
name: project.metadata.name,
|
|
146
|
+
description: project.metadata.description,
|
|
147
|
+
},
|
|
148
|
+
sources,
|
|
149
|
+
actors,
|
|
150
|
+
routes,
|
|
151
|
+
transforms,
|
|
152
|
+
loggers,
|
|
153
|
+
defaults: {
|
|
154
|
+
...(userDefaults.defaults ?? {}),
|
|
155
|
+
...(project.defaults ?? {}),
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Load the raw ProjectConfig (for validation/display without full resolution).
|
|
161
|
+
*/
|
|
162
|
+
export async function loadProjectConfig(configPath) {
|
|
163
|
+
const resolved = resolveConfigPath(configPath);
|
|
164
|
+
if (!(await fileExists(resolved))) {
|
|
165
|
+
throw new Error(`Configuration file not found: ${resolved}`);
|
|
166
|
+
}
|
|
167
|
+
return loadYaml(resolved);
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared environment variable metadata for DX surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Provides per-variable descriptions and help URLs so that CLI commands
|
|
5
|
+
* (env, apply, validate) can show actionable guidance for missing vars.
|
|
6
|
+
*/
|
|
7
|
+
export interface EnvVarMeta {
|
|
8
|
+
description: string;
|
|
9
|
+
help_url?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function getEnvVarMeta(name: string): EnvVarMeta | undefined;
|
|
12
|
+
//# sourceMappingURL=env-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-metadata.d.ts","sourceRoot":"","sources":["../src/env-metadata.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,UAAU;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAgCD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAElE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared environment variable metadata for DX surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Provides per-variable descriptions and help URLs so that CLI commands
|
|
5
|
+
* (env, apply, validate) can show actionable guidance for missing vars.
|
|
6
|
+
*/
|
|
7
|
+
const ENV_VAR_METADATA = {
|
|
8
|
+
GITHUB_TOKEN: {
|
|
9
|
+
description: 'GitHub personal access token with repo scope',
|
|
10
|
+
help_url: 'https://github.com/settings/tokens/new?scopes=repo',
|
|
11
|
+
},
|
|
12
|
+
GITHUB_REPO: {
|
|
13
|
+
description: 'GitHub repository in owner/repo format',
|
|
14
|
+
},
|
|
15
|
+
LINEAR_API_KEY: {
|
|
16
|
+
description: 'Linear API key for reading issues and comments',
|
|
17
|
+
help_url: 'https://linear.app/settings/api',
|
|
18
|
+
},
|
|
19
|
+
LINEAR_TEAM_KEY: {
|
|
20
|
+
description: 'Linear team key',
|
|
21
|
+
},
|
|
22
|
+
OPENCLAW_WEBHOOK_TOKEN: {
|
|
23
|
+
description: 'OpenClaw webhook authentication token',
|
|
24
|
+
help_url: 'https://openclaw.com/docs/webhooks',
|
|
25
|
+
},
|
|
26
|
+
OPENCLAW_AGENT_ID: {
|
|
27
|
+
description: 'OpenClaw agent ID',
|
|
28
|
+
},
|
|
29
|
+
SLACK_WEBHOOK_URL: {
|
|
30
|
+
description: 'Slack incoming webhook URL',
|
|
31
|
+
},
|
|
32
|
+
PAGERDUTY_WEBHOOK_URL: {
|
|
33
|
+
description: 'PagerDuty webhook URL',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export function getEnvVarMeta(name) {
|
|
37
|
+
return ENV_VAR_METADATA[name];
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=env-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-metadata.js","sourceRoot":"","sources":["../src/env-metadata.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,gBAAgB,GAA+B;IACpD,YAAY,EAAE;QACb,WAAW,EAAE,8CAA8C;QAC3D,QAAQ,EAAE,oDAAoD;KAC9D;IACD,WAAW,EAAE;QACZ,WAAW,EAAE,wCAAwC;KACrD;IACD,cAAc,EAAE;QACf,WAAW,EAAE,gDAAgD;QAC7D,QAAQ,EAAE,iCAAiC;KAC3C;IACD,eAAe,EAAE;QAChB,WAAW,EAAE,iBAAiB;KAC9B;IACD,sBAAsB,EAAE;QACvB,WAAW,EAAE,uCAAuC;QACpD,QAAQ,EAAE,oCAAoC;KAC9C;IACD,iBAAiB,EAAE;QAClB,WAAW,EAAE,mBAAmB;KAChC;IACD,iBAAiB,EAAE;QAClB,WAAW,EAAE,4BAA4B;KACzC;IACD,qBAAqB,EAAE;QACtB,WAAW,EAAE,uBAAuB;KACpC;CACD,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,IAAY;IACzC,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OrgLoop CLI — Organization as Code runtime.
|
|
4
|
+
*
|
|
5
|
+
* Entry point that sets up Commander.js with all commands and global flags.
|
|
6
|
+
*/
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
import { dirname, resolve } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { registerAddCommand } from './commands/add.js';
|
|
12
|
+
import { registerApplyCommand } from './commands/apply.js';
|
|
13
|
+
import { registerDoctorCommand } from './commands/doctor.js';
|
|
14
|
+
import { registerEnvCommand } from './commands/env.js';
|
|
15
|
+
import { registerHookCommand } from './commands/hook.js';
|
|
16
|
+
import { registerInitCommand } from './commands/init.js';
|
|
17
|
+
import { registerInspectCommand } from './commands/inspect.js';
|
|
18
|
+
import { registerInstallServiceCommand } from './commands/install-service.js';
|
|
19
|
+
import { registerLogsCommand } from './commands/logs.js';
|
|
20
|
+
import { registerPlanCommand } from './commands/plan.js';
|
|
21
|
+
import { registerRoutesCommand } from './commands/routes.js';
|
|
22
|
+
import { registerServiceCommand } from './commands/service.js';
|
|
23
|
+
import { registerStatusCommand } from './commands/status.js';
|
|
24
|
+
import { registerStopCommand } from './commands/stop.js';
|
|
25
|
+
import { registerTestCommand } from './commands/test.js';
|
|
26
|
+
import { registerValidateCommand } from './commands/validate.js';
|
|
27
|
+
import { registerVersionCommand } from './commands/version.js';
|
|
28
|
+
import { setJsonMode, setQuietMode, setVerboseMode } from './output.js';
|
|
29
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
30
|
+
async function getVersion() {
|
|
31
|
+
try {
|
|
32
|
+
const pkgPath = resolve(__dirname, '..', 'package.json');
|
|
33
|
+
const content = await readFile(pkgPath, 'utf-8');
|
|
34
|
+
const pkg = JSON.parse(content);
|
|
35
|
+
return pkg.version;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return '0.0.0';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function main() {
|
|
42
|
+
const version = await getVersion();
|
|
43
|
+
const program = new Command();
|
|
44
|
+
program
|
|
45
|
+
.name('orgloop')
|
|
46
|
+
.description('OrgLoop — Organization as Code runtime')
|
|
47
|
+
.version(version, '-V, --version-flag', 'Print version number')
|
|
48
|
+
.option('-c, --config <path>', 'Path to orgloop.yaml')
|
|
49
|
+
.option('-w, --workspace <name>', 'Workspace name', 'default')
|
|
50
|
+
.option('-v, --verbose', 'Verbose output')
|
|
51
|
+
.option('--json', 'Output as JSON (for scripting)')
|
|
52
|
+
.option('--quiet', 'Errors only')
|
|
53
|
+
.hook('preAction', (thisCommand) => {
|
|
54
|
+
const opts = thisCommand.opts();
|
|
55
|
+
if (opts.json)
|
|
56
|
+
setJsonMode(true);
|
|
57
|
+
if (opts.verbose)
|
|
58
|
+
setVerboseMode(true);
|
|
59
|
+
if (opts.quiet)
|
|
60
|
+
setQuietMode(true);
|
|
61
|
+
});
|
|
62
|
+
// Register all commands
|
|
63
|
+
registerInitCommand(program);
|
|
64
|
+
registerValidateCommand(program);
|
|
65
|
+
registerEnvCommand(program);
|
|
66
|
+
registerDoctorCommand(program);
|
|
67
|
+
registerHookCommand(program);
|
|
68
|
+
registerPlanCommand(program);
|
|
69
|
+
registerApplyCommand(program);
|
|
70
|
+
registerStopCommand(program);
|
|
71
|
+
registerStatusCommand(program);
|
|
72
|
+
registerLogsCommand(program);
|
|
73
|
+
registerTestCommand(program);
|
|
74
|
+
registerVersionCommand(program);
|
|
75
|
+
registerRoutesCommand(program);
|
|
76
|
+
registerAddCommand(program);
|
|
77
|
+
registerInspectCommand(program);
|
|
78
|
+
registerInstallServiceCommand(program);
|
|
79
|
+
registerServiceCommand(program);
|
|
80
|
+
await program.parseAsync(process.argv);
|
|
81
|
+
}
|
|
82
|
+
main().catch((err) => {
|
|
83
|
+
console.error('Fatal error:', err instanceof Error ? err.message : String(err));
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAExE,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,KAAK,UAAU,UAAU;IACxB,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAwB,CAAC;QACvD,OAAO,GAAG,CAAC,OAAO,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,OAAO,CAAC;IAChB,CAAC;AACF,CAAC;AAED,KAAK,UAAU,IAAI;IAClB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IAEnC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACL,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,wCAAwC,CAAC;SACrD,OAAO,CAAC,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,CAAC;SAC9D,MAAM,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;SACrD,MAAM,CAAC,wBAAwB,EAAE,gBAAgB,EAAE,SAAS,CAAC;SAC7D,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;SACzC,MAAM,CAAC,QAAQ,EAAE,gCAAgC,CAAC;SAClD,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;SAChC,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI;YAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,OAAO;YAAE,cAAc,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,KAAK;YAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEJ,wBAAwB;IACxB,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACvC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACpB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACtB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module resolution — loads installed modules, expands templates, returns routes.
|
|
3
|
+
*
|
|
4
|
+
* Modules are a config-time concept. The engine never sees modules — only
|
|
5
|
+
* concrete routes after expansion. This resolver bridges the gap.
|
|
6
|
+
*/
|
|
7
|
+
import type { ModuleManifest, RouteDefinition } from '@orgloop/sdk';
|
|
8
|
+
/** An installed module entry from orgloop.yaml */
|
|
9
|
+
export interface InstalledModuleEntry {
|
|
10
|
+
package: string;
|
|
11
|
+
params: Record<string, string | number | boolean>;
|
|
12
|
+
}
|
|
13
|
+
/** Result of resolving a single module */
|
|
14
|
+
export interface ResolvedModule {
|
|
15
|
+
manifest: ModuleManifest;
|
|
16
|
+
routes: RouteDefinition[];
|
|
17
|
+
modulePath: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a module package to a filesystem path.
|
|
21
|
+
*
|
|
22
|
+
* Supports:
|
|
23
|
+
* - Workspace packages: `@orgloop/module-engineering` → resolved via require.resolve
|
|
24
|
+
* - Local paths: `./modules/engineering` → resolved relative to basePath
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveModulePath(pkg: string, basePath: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Load and validate a module manifest from a directory.
|
|
29
|
+
*/
|
|
30
|
+
export declare function loadModuleManifest(modulePath: string): Promise<ModuleManifest>;
|
|
31
|
+
/**
|
|
32
|
+
* Load route templates from a module and expand them with params.
|
|
33
|
+
*/
|
|
34
|
+
export declare function expandModuleRoutes(modulePath: string, manifest: ModuleManifest, params: Record<string, string | number | boolean>): Promise<RouteDefinition[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve all modules from orgloop.yaml and return their expanded routes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveModules(modules: InstalledModuleEntry[], basePath: string): Promise<{
|
|
39
|
+
routes: RouteDefinition[];
|
|
40
|
+
resolved: ResolvedModule[];
|
|
41
|
+
}>;
|
|
42
|
+
//# sourceMappingURL=module-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-resolver.d.ts","sourceRoot":"","sources":["../src/module-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAA0B,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQ5F,kDAAkD;AAClD,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAClD;AAED,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA0BvE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAyBpF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACvC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAC/C,OAAO,CAAC,eAAe,EAAE,CAAC,CAkD5B;AAED;;GAEG;AACH,wBAAsB,cAAc,CACnC,OAAO,EAAE,oBAAoB,EAAE,EAC/B,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAcpE"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module resolution — loads installed modules, expands templates, returns routes.
|
|
3
|
+
*
|
|
4
|
+
* Modules are a config-time concept. The engine never sees modules — only
|
|
5
|
+
* concrete routes after expansion. This resolver bridges the gap.
|
|
6
|
+
*/
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
9
|
+
import { expandTemplateDeep, moduleManifestSchema } from '@orgloop/sdk';
|
|
10
|
+
import AjvModule from 'ajv';
|
|
11
|
+
import yaml from 'js-yaml';
|
|
12
|
+
const Ajv = AjvModule.default ?? AjvModule;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a module package to a filesystem path.
|
|
15
|
+
*
|
|
16
|
+
* Supports:
|
|
17
|
+
* - Workspace packages: `@orgloop/module-engineering` → resolved via require.resolve
|
|
18
|
+
* - Local paths: `./modules/engineering` → resolved relative to basePath
|
|
19
|
+
*/
|
|
20
|
+
export function resolveModulePath(pkg, basePath) {
|
|
21
|
+
// Local path (starts with . or /)
|
|
22
|
+
if (pkg.startsWith('.') || pkg.startsWith('/')) {
|
|
23
|
+
return isAbsolute(pkg) ? pkg : resolve(basePath, pkg);
|
|
24
|
+
}
|
|
25
|
+
// npm/workspace package — try to resolve via Node's module resolution
|
|
26
|
+
try {
|
|
27
|
+
const resolved = import.meta.resolve?.(`${pkg}/orgloop-module.yaml`);
|
|
28
|
+
if (resolved) {
|
|
29
|
+
// import.meta.resolve returns a file:// URL
|
|
30
|
+
const filePath = new URL(resolved).pathname;
|
|
31
|
+
return dirname(filePath);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Fall through
|
|
36
|
+
}
|
|
37
|
+
// Fallback: try common monorepo locations
|
|
38
|
+
const candidates = [
|
|
39
|
+
resolve(basePath, 'node_modules', pkg),
|
|
40
|
+
resolve(basePath, '..', 'modules', pkg.replace(/^@orgloop\/module-/, '')),
|
|
41
|
+
];
|
|
42
|
+
// Return first candidate (existence will be checked by caller)
|
|
43
|
+
return candidates[0];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Load and validate a module manifest from a directory.
|
|
47
|
+
*/
|
|
48
|
+
export async function loadModuleManifest(modulePath) {
|
|
49
|
+
const manifestPath = join(modulePath, 'orgloop-module.yaml');
|
|
50
|
+
let content;
|
|
51
|
+
try {
|
|
52
|
+
content = await readFile(manifestPath, 'utf-8');
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new Error(`Module manifest not found: ${manifestPath}\nEnsure the module package contains an orgloop-module.yaml file.`);
|
|
56
|
+
}
|
|
57
|
+
const parsed = yaml.load(content);
|
|
58
|
+
// Validate against schema
|
|
59
|
+
const ajv = new Ajv({ allErrors: true });
|
|
60
|
+
const validate = ajv.compile(moduleManifestSchema);
|
|
61
|
+
if (!validate(parsed)) {
|
|
62
|
+
const errors = (validate.errors ?? [])
|
|
63
|
+
.map((e) => `${e.instancePath || '/'}: ${e.message}`)
|
|
64
|
+
.join(', ');
|
|
65
|
+
throw new Error(`Invalid module manifest at ${manifestPath}: ${errors}`);
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Load route templates from a module and expand them with params.
|
|
71
|
+
*/
|
|
72
|
+
export async function expandModuleRoutes(modulePath, manifest, params) {
|
|
73
|
+
const templatePath = join(modulePath, 'templates', 'routes.yaml');
|
|
74
|
+
let content;
|
|
75
|
+
try {
|
|
76
|
+
content = await readFile(templatePath, 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Module has no route templates — that's fine
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
// Build expansion context, applying defaults for missing params
|
|
83
|
+
const resolvedParams = {};
|
|
84
|
+
for (const paramDef of manifest.parameters ?? []) {
|
|
85
|
+
if (params[paramDef.name] !== undefined) {
|
|
86
|
+
resolvedParams[paramDef.name] = params[paramDef.name];
|
|
87
|
+
}
|
|
88
|
+
else if (paramDef.default !== undefined) {
|
|
89
|
+
resolvedParams[paramDef.name] = paramDef.default;
|
|
90
|
+
}
|
|
91
|
+
else if (paramDef.required) {
|
|
92
|
+
throw new Error(`Missing required parameter "${paramDef.name}" for module "${manifest.metadata.name}"`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const context = {
|
|
96
|
+
module: {
|
|
97
|
+
name: manifest.metadata.name,
|
|
98
|
+
path: modulePath,
|
|
99
|
+
},
|
|
100
|
+
params: resolvedParams,
|
|
101
|
+
};
|
|
102
|
+
// Expand the template content string first (handles {{ }} in YAML values)
|
|
103
|
+
const expandedYaml = content.replace(/\{\{\s*([^}]+?)\s*\}\}/g, (_match, expr) => {
|
|
104
|
+
const parts = expr.split('.');
|
|
105
|
+
if (parts.length !== 2)
|
|
106
|
+
return _match;
|
|
107
|
+
const [namespace, key] = parts;
|
|
108
|
+
if (namespace === 'module') {
|
|
109
|
+
return String(context.module[key] ?? _match);
|
|
110
|
+
}
|
|
111
|
+
if (namespace === 'params') {
|
|
112
|
+
return String(context.params[key] ?? _match);
|
|
113
|
+
}
|
|
114
|
+
return _match;
|
|
115
|
+
});
|
|
116
|
+
const parsed = yaml.load(expandedYaml);
|
|
117
|
+
return parsed?.routes ?? [];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Resolve all modules from orgloop.yaml and return their expanded routes.
|
|
121
|
+
*/
|
|
122
|
+
export async function resolveModules(modules, basePath) {
|
|
123
|
+
const allRoutes = [];
|
|
124
|
+
const resolved = [];
|
|
125
|
+
for (const mod of modules) {
|
|
126
|
+
const modulePath = resolveModulePath(mod.package, basePath);
|
|
127
|
+
const manifest = await loadModuleManifest(modulePath);
|
|
128
|
+
const routes = await expandModuleRoutes(modulePath, manifest, mod.params);
|
|
129
|
+
allRoutes.push(...routes);
|
|
130
|
+
resolved.push({ manifest, routes, modulePath });
|
|
131
|
+
}
|
|
132
|
+
return { routes: allRoutes, resolved };
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=module-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-resolver.js","sourceRoot":"","sources":["../src/module-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,SAAS,MAAM,KAAK,CAAC;AAE5B,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC;AAe3C;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,QAAgB;IAC9D,kCAAkC;IAClC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,sEAAsE;IACtE,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,GAAG,sBAAsB,CAAC,CAAC;QACrE,IAAI,QAAQ,EAAE,CAAC;YACd,4CAA4C;YAC5C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;YAC5C,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,eAAe;IAChB,CAAC;IAED,0CAA0C;IAC1C,MAAM,UAAU,GAAG;QAClB,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,CAAC;QACtC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;KACzE,CAAC;IAEF,+DAA+D;IAC/D,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAE7D,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CACd,8BAA8B,YAAY,mEAAmE,CAC7G,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAY,CAAC;IAE7C,0BAA0B;IAC1B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;aACpC,GAAG,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACjE,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,YAAY,KAAK,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,MAAwB,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,UAAkB,EAClB,QAAwB,EACxB,MAAiD;IAEjD,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IAElE,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACR,8CAA8C;QAC9C,OAAO,EAAE,CAAC;IACX,CAAC;IAED,gEAAgE;IAChE,MAAM,cAAc,GAA8C,EAAE,CAAC;IACrE,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;QAClD,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACzC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvD,CAAC;aAAM,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3C,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;QAClD,CAAC;aAAM,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACd,+BAA+B,QAAQ,CAAC,IAAI,iBAAiB,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CACtF,CAAC;QACH,CAAC;IACF,CAAC;IAED,MAAM,OAAO,GAA2B;QACvC,MAAM,EAAE;YACP,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI;YAC5B,IAAI,EAAE,UAAU;SAChB;QACD,MAAM,EAAE,cAAc;KACtB,CAAC;IAEF,0EAA0E;IAC1E,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE;QACxF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QACtC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;QAC/B,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAA6C,CAAC,IAAI,MAAM,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAA0C,CAAC;IAEhF,OAAO,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,OAA+B,EAC/B,QAAgB;IAEhB,MAAM,SAAS,GAAsB,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAqB,EAAE,CAAC;IAEtC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAE1E,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities for the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Provides colored output, table formatting, JSON mode,
|
|
5
|
+
* quiet mode, and spinner support.
|
|
6
|
+
*/
|
|
7
|
+
import { type Ora } from 'ora';
|
|
8
|
+
export declare function setJsonMode(enabled: boolean): void;
|
|
9
|
+
export declare function setQuietMode(enabled: boolean): void;
|
|
10
|
+
export declare function setVerboseMode(enabled: boolean): void;
|
|
11
|
+
export declare function isJsonMode(): boolean;
|
|
12
|
+
export declare function info(message: string): void;
|
|
13
|
+
export declare function success(message: string): void;
|
|
14
|
+
export declare function error(message: string): void;
|
|
15
|
+
export declare function warn(message: string): void;
|
|
16
|
+
export declare function verbose(message: string): void;
|
|
17
|
+
export declare function blank(): void;
|
|
18
|
+
export declare function heading(text: string): void;
|
|
19
|
+
export declare function subheading(text: string): void;
|
|
20
|
+
export declare function planAdd(text: string): void;
|
|
21
|
+
export declare function planChange(text: string): void;
|
|
22
|
+
export declare function planUnchanged(text: string): void;
|
|
23
|
+
export declare function planRemove(text: string): void;
|
|
24
|
+
export declare function json(data: unknown): void;
|
|
25
|
+
export interface TableColumn {
|
|
26
|
+
header: string;
|
|
27
|
+
key: string;
|
|
28
|
+
width?: number;
|
|
29
|
+
align?: 'left' | 'right';
|
|
30
|
+
}
|
|
31
|
+
export declare function table(columns: TableColumn[], rows: Record<string, string>[]): void;
|
|
32
|
+
export declare function spinner(text: string): Ora;
|
|
33
|
+
export declare function validPass(file: string, description: string): void;
|
|
34
|
+
export declare function validFail(file: string, description: string): void;
|
|
35
|
+
export declare function validWarn(file: string, description: string): void;
|
|
36
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAQpC,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAElD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEnD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAErD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAID,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG1C;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG7C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG3C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG1C;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG7C;AAED,wBAAgB,KAAK,IAAI,IAAI,CAG5B;AAID,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG1C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG7C;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG1C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG7C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGhD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG7C;AAID,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAExC;AAID,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CA4BlF;AAID,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAMzC;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAGjE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAGjE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAGjE"}
|