@observeone/cli 1.28.0 → 1.30.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 +2 -1
- package/dist/README.md +2 -1
- package/dist/commands/ai-check/delete.d.ts.map +1 -1
- package/dist/commands/ai-check/delete.js +13 -15
- package/dist/commands/ai-check/delete.js.map +1 -1
- package/dist/commands/api-key.d.ts.map +1 -1
- package/dist/commands/api-key.js +12 -1
- package/dist/commands/api-key.js.map +1 -1
- package/dist/commands/apply.d.ts +8 -0
- package/dist/commands/apply.d.ts.map +1 -1
- package/dist/commands/apply.js +34 -0
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/incident.d.ts.map +1 -1
- package/dist/commands/incident.js +12 -0
- package/dist/commands/incident.js.map +1 -1
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +10 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/runs-command.d.ts +1 -1
- package/dist/commands/runs-command.d.ts.map +1 -1
- package/dist/commands/runs-command.js +4 -8
- package/dist/commands/runs-command.js.map +1 -1
- package/dist/commands/suite/generate.d.ts.map +1 -1
- package/dist/commands/suite/generate.js +9 -10
- package/dist/commands/suite/generate.js.map +1 -1
- package/dist/commands/suite/run.d.ts.map +1 -1
- package/dist/commands/suite/run.js +3 -1
- package/dist/commands/suite/run.js.map +1 -1
- package/dist/commands/suite/secrets.d.ts.map +1 -1
- package/dist/commands/suite/secrets.js +16 -5
- package/dist/commands/suite/secrets.js.map +1 -1
- package/dist/commands/suite/toggle-public.d.ts.map +1 -1
- package/dist/commands/suite/toggle-public.js +16 -1
- package/dist/commands/suite/toggle-public.js.map +1 -1
- package/dist/commands/suite/vars.d.ts +20 -2
- package/dist/commands/suite/vars.d.ts.map +1 -1
- package/dist/commands/suite/vars.js +52 -8
- package/dist/commands/suite/vars.js.map +1 -1
- package/dist/commands/suite/wait.d.ts.map +1 -1
- package/dist/commands/suite/wait.js +6 -4
- package/dist/commands/suite/wait.js.map +1 -1
- package/dist/commands/validate.d.ts +13 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +65 -0
- package/dist/commands/validate.js.map +1 -1
- package/dist/interfaces/api-client.interface.d.ts +3 -3
- package/dist/interfaces/config.interface.d.ts +2 -0
- package/dist/interfaces/config.interface.d.ts.map +1 -1
- package/dist/package.json +1 -1
- package/dist/services/api-client.service.d.ts +12 -3
- package/dist/services/api-client.service.d.ts.map +1 -1
- package/dist/services/api-client.service.js +44 -1
- package/dist/services/api-client.service.js.map +1 -1
- package/dist/services/config.service.d.ts +3 -0
- package/dist/services/config.service.d.ts.map +1 -1
- package/dist/services/config.service.js +31 -4
- package/dist/services/config.service.js.map +1 -1
- package/dist/services/sse-client.service.d.ts +13 -5
- package/dist/services/sse-client.service.d.ts.map +1 -1
- package/dist/services/sse-client.service.js +56 -8
- package/dist/services/sse-client.service.js.map +1 -1
- package/dist/utils/cli-input.d.ts +1 -1
- package/dist/utils/cli-input.d.ts.map +1 -1
- package/dist/utils/cli-input.js +5 -5
- package/dist/utils/cli-input.js.map +1 -1
- package/dist/utils/host-allowlist.d.ts +19 -0
- package/dist/utils/host-allowlist.d.ts.map +1 -0
- package/dist/utils/host-allowlist.js +35 -0
- package/dist/utils/host-allowlist.js.map +1 -0
- package/dist/utils/schemas.d.ts.map +1 -1
- package/dist/utils/schemas.js +5 -4
- package/dist/utils/schemas.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAWtE,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAWtE,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAoKT"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, Option } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import ora from 'ora';
|
|
4
|
-
import {
|
|
4
|
+
import { resolveVars } from './vars.js';
|
|
5
5
|
import { suiteStatusColor } from './formatters.js';
|
|
6
6
|
function extractPlannedFiles(planMarkdown) {
|
|
7
7
|
const matches = [
|
|
@@ -16,8 +16,8 @@ export function createSuiteGenerateCommand(_configService, apiClient, outputServ
|
|
|
16
16
|
.option('--name <name>', 'Suite name (default: derived from URL hostname)')
|
|
17
17
|
.option('--cron <expr>', 'Cron schedule (e.g. "0 */6 * * *"). Omit for manual only.')
|
|
18
18
|
.option('--max-tests <n>', 'Max tests to generate (1-30, default: 10)', '10')
|
|
19
|
-
.option('--var <KEY=VALUE>', 'Variable/credential (repeatable)', (v, prev) => [...prev, v], [])
|
|
20
|
-
.option('--var-file <path>', 'Load variables from
|
|
19
|
+
.option('--var <KEY[=VALUE]>', 'Variable/credential (repeatable). Omit =VALUE (e.g. --var API_TOKEN) to be prompted securely.', (v, prev) => [...prev, v], [])
|
|
20
|
+
.option('--var-file <path>', 'Load variables from an uncommitted .env file (safer than inline values)')
|
|
21
21
|
.option('--allow-form-submit', 'Allow AI agents to submit non-auth forms')
|
|
22
22
|
.option('--plan-only', 'Stop after the planning phase; do not generate test scripts')
|
|
23
23
|
.addOption(new Option('-w, --wait', 'Deprecated: test generation is now the default').hideHelp())
|
|
@@ -26,6 +26,8 @@ Examples:
|
|
|
26
26
|
$ obs suite generate https://example.com
|
|
27
27
|
$ obs suite generate https://example.com --name "Smoke Tests" --max-tests 5
|
|
28
28
|
$ obs suite generate https://example.com --cron "0 */6 * * *"
|
|
29
|
+
$ obs suite generate https://example.com --var API_TOKEN # prompts for the secret (masked)
|
|
30
|
+
$ obs suite generate https://example.com --var-file .env.secrets
|
|
29
31
|
`)
|
|
30
32
|
.action(async (url, options) => {
|
|
31
33
|
const isJson = process.env.OBS_JSON_OUTPUT === 'true';
|
|
@@ -35,13 +37,10 @@ Examples:
|
|
|
35
37
|
try {
|
|
36
38
|
const hostname = new URL(url.startsWith('http') ? url : `https://${url}`).hostname;
|
|
37
39
|
const suiteName = options.name || hostname;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
throw new Error(e.message);
|
|
44
|
-
}
|
|
40
|
+
const secrets = await resolveVars(options.var, options.varFile, {
|
|
41
|
+
isJson,
|
|
42
|
+
outputError: (msg) => outputService.error(msg),
|
|
43
|
+
});
|
|
45
44
|
const payload = {
|
|
46
45
|
target_url: url,
|
|
47
46
|
suite_name: suiteName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/commands/suite/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/commands/suite/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAwDT"}
|
|
@@ -10,6 +10,7 @@ export function createSuiteRunCommand(_configService, apiClient, outputService)
|
|
|
10
10
|
.option('--tests <ids>', 'Comma-separated list of test IDs to run')
|
|
11
11
|
.action(async (id, options) => {
|
|
12
12
|
const isJson = process.env.OBS_JSON_OUTPUT === 'true';
|
|
13
|
+
let spinner = null;
|
|
13
14
|
try {
|
|
14
15
|
const testIds = options.tests ? options.tests.split(',').map((s) => s.trim()) : undefined;
|
|
15
16
|
const { execution_id } = await apiClient.runSuite(id, testIds);
|
|
@@ -28,7 +29,7 @@ export function createSuiteRunCommand(_configService, apiClient, outputService)
|
|
|
28
29
|
console.log(chalk.bold(`\n Running suite...`));
|
|
29
30
|
console.log(chalk.gray('─'.repeat(56)));
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
+
spinner = isJson ? null : ora({ text: 'Running...', stream: process.stdout }).start();
|
|
32
33
|
const started = Date.now();
|
|
33
34
|
const done = await apiClient.pollSuiteExecution(id, execution_id);
|
|
34
35
|
const elapsed = ((Date.now() - started) / 1000).toFixed(0);
|
|
@@ -43,6 +44,7 @@ export function createSuiteRunCommand(_configService, apiClient, outputService)
|
|
|
43
44
|
process.exit(allPassed ? 0 : 1);
|
|
44
45
|
}
|
|
45
46
|
catch (err) {
|
|
47
|
+
spinner?.stop();
|
|
46
48
|
const msg = err.message || 'Failed to run suite';
|
|
47
49
|
if (isJson) {
|
|
48
50
|
outputService.formatJsonOutput({ status: 'ERROR', error: { message: msg } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/suite/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,UAAU,qBAAqB,CACnC,cAA8B,EAC9B,SAAoB,EACpB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB,WAAW,CAAC,2BAA2B,CAAC;SACxC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;SAC5B,MAAM,CAAC,YAAY,EAAE,oCAAoC,CAAC;SAC1D,MAAM,CAAC,eAAe,EAAE,yCAAyC,CAAC;SAClE,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,OAA2C,EAAE,EAAE;QACxE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1F,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAE/D,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAClB,IAAI,MAAM,EAAE,CAAC;oBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;gBACnD,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;oBAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,YAAY,EAAE,CAAC,CAAC,CAAC;oBAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iCAAiC,EAAE,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC;gBACnF,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;YAED,
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/suite/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,UAAU,qBAAqB,CACnC,cAA8B,EAC9B,SAAoB,EACpB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB,WAAW,CAAC,2BAA2B,CAAC;SACxC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;SAC5B,MAAM,CAAC,YAAY,EAAE,oCAAoC,CAAC;SAC1D,MAAM,CAAC,eAAe,EAAE,yCAAyC,CAAC;SAClE,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,OAA2C,EAAE,EAAE;QACxE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;QACtD,IAAI,OAAO,GAAkC,IAAI,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1F,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAE/D,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAClB,IAAI,MAAM,EAAE,CAAC;oBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;gBACnD,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;oBAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,YAAY,EAAE,CAAC,CAAC,CAAC;oBAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iCAAiC,EAAE,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC;gBACnF,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;YAED,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YACtF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE3B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAE3D,OAAO,EAAE,IAAI,EAAE,CAAC;YAEhB,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;YAC1E,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,EAAE,IAAI,EAAE,CAAC;YAChB,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,IAAI,qBAAqB,CAAC;YAC5D,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/E,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAwDT"}
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import {
|
|
3
|
+
import { resolveVars } from './vars.js';
|
|
4
4
|
export function createSuiteSecretsCommand(_configService, apiClient, outputService) {
|
|
5
5
|
return new Command('secrets')
|
|
6
|
-
.description('Update credentials/variables for a suite'
|
|
6
|
+
.description('Update credentials/variables for a suite. Pass --var KEY (no value) to be ' +
|
|
7
|
+
'prompted securely (masked) instead of putting secrets on the command line, ' +
|
|
8
|
+
'or load them from an uncommitted file with --var-file.')
|
|
7
9
|
.argument('<id>', 'Suite ID')
|
|
8
|
-
.option('--var <KEY=VALUE>', 'Variable/credential (repeatable)', (v, prev) => [...prev, v], [])
|
|
9
|
-
.option('--var-file <path>', 'Load variables from
|
|
10
|
+
.option('--var <KEY[=VALUE]>', 'Variable/credential (repeatable). Omit =VALUE (e.g. --var API_TOKEN) to be prompted securely.', (v, prev) => [...prev, v], [])
|
|
11
|
+
.option('--var-file <path>', 'Load variables from an uncommitted .env file (safer than inline values)')
|
|
12
|
+
.addHelpText('after', `
|
|
13
|
+
Examples:
|
|
14
|
+
$ obs suite secrets 42 --var API_TOKEN # prompts for the value (masked)
|
|
15
|
+
$ obs suite secrets 42 --var-file .env.secrets # never touches shell history
|
|
16
|
+
$ obs suite secrets 42 --var REGION=us-east # inline (lands in shell history)
|
|
17
|
+
`)
|
|
10
18
|
.action(async (id, options) => {
|
|
11
19
|
const isJson = process.env.OBS_JSON_OUTPUT === 'true';
|
|
12
20
|
try {
|
|
13
|
-
const secrets =
|
|
21
|
+
const secrets = await resolveVars(options.var, options.varFile, {
|
|
22
|
+
isJson,
|
|
23
|
+
outputError: (msg) => outputService.error(msg),
|
|
24
|
+
});
|
|
14
25
|
if (!secrets || Object.keys(secrets).length === 0) {
|
|
15
26
|
throw new Error('Provide at least one --var KEY=VALUE or --var-file');
|
|
16
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../src/commands/suite/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../src/commands/suite/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,UAAU,yBAAyB,CACvC,cAA8B,EAC9B,SAAoB,EACpB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B,WAAW,CACV,4EAA4E;QAC1E,6EAA6E;QAC7E,wDAAwD,CAC3D;SACA,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;SAC5B,MAAM,CACL,qBAAqB,EACrB,+FAA+F,EAC/F,CAAC,CAAC,EAAE,IAAc,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,EACnC,EAAc,CACf;SACA,MAAM,CACL,mBAAmB,EACnB,yEAAyE,CAC1E;SACA,WAAW,CACV,OAAO,EACP;;;;;CAKL,CACI;SACA,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,OAA4C,EAAE,EAAE;QACzE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE;gBAC9D,MAAM;gBACN,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC;aAC/C,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACxE,CAAC;YAED,MAAM,SAAS,CAAC,kBAAkB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAEhD,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;gBACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,IAAI,gCAAgC,CAAC;YACvE,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/E,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-public.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/toggle-public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"toggle-public.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/toggle-public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,CA8CT"}
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
+
import { requireConfirmation } from '../../utils/confirm.js';
|
|
3
4
|
export function createSuiteTogglePublicCommand(_configService, apiClient, outputService) {
|
|
4
5
|
return new Command('toggle-public')
|
|
5
6
|
.description('Toggle public visibility of a suite')
|
|
6
7
|
.argument('<id>', 'Suite ID')
|
|
7
|
-
.
|
|
8
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
9
|
+
.action(async (id, options) => {
|
|
8
10
|
const isJson = process.env.OBS_JSON_OUTPUT === 'true';
|
|
9
11
|
try {
|
|
10
12
|
// Fetch current state to toggle
|
|
11
13
|
const suite = await apiClient.getSuite(id);
|
|
12
14
|
const newPublic = !suite.is_public;
|
|
15
|
+
// Making a suite public can expose its test credentials and internal
|
|
16
|
+
// URLs, so gate that direction behind an explicit confirmation.
|
|
17
|
+
if (newPublic) {
|
|
18
|
+
const confirmed = await requireConfirmation(`Make suite ${id} PUBLIC? Its test credentials and internal URLs may be exposed.`, {
|
|
19
|
+
yes: options.yes,
|
|
20
|
+
isJson,
|
|
21
|
+
outputError: (msg) => outputService.error(msg),
|
|
22
|
+
});
|
|
23
|
+
if (!confirmed) {
|
|
24
|
+
console.log(chalk.gray(' Toggle cancelled.'));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
13
28
|
const result = await apiClient.toggleSuitePublic(id, newPublic);
|
|
14
29
|
if (isJson) {
|
|
15
30
|
outputService.formatJsonOutput({ suite: result });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-public.js","sourceRoot":"","sources":["../../../src/commands/suite/toggle-public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"toggle-public.js","sourceRoot":"","sources":["../../../src/commands/suite/toggle-public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,UAAU,8BAA8B,CAC5C,cAA8B,EAC9B,SAAoB,EACpB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;SAChC,WAAW,CAAC,qCAAqC,CAAC;SAClD,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;SAC5B,MAAM,CAAC,WAAW,EAAE,0BAA0B,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,OAA0B,EAAE,EAAE;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;QACtD,IAAI,CAAC;YACH,gCAAgC;YAChC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC3C,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;YAEnC,qEAAqE;YACrE,gEAAgE;YAChE,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,SAAS,GAAG,MAAM,mBAAmB,CACzC,cAAc,EAAE,iEAAiE,EACjF;oBACE,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,MAAM;oBACN,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC;iBAC/C,CACF,CAAC;gBACF,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;oBAC9C,OAAO;gBACT,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,iBAAiB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAChE,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBAClD,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,MAAM,KAAK,CAAC,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,IAAI,mCAAmC,CAAC;YAC1E,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/E,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,4 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Split `--var` flags into values supplied inline (`KEY=VALUE`) and bare keys
|
|
3
|
+
* (`KEY` with no `=value`) that must be prompted for securely. Keeping secret
|
|
4
|
+
* values off the command line avoids leaking them into shell history, `ps`, and
|
|
5
|
+
* /proc/<pid>/cmdline.
|
|
6
|
+
*/
|
|
7
|
+
export declare function partitionVarFlags(vars: string[]): {
|
|
8
|
+
resolved: Record<string, string>;
|
|
9
|
+
needsPrompt: string[];
|
|
10
|
+
};
|
|
2
11
|
export declare function parseVarFile(filePath: string): Record<string, string>;
|
|
3
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Resolve suite variables from (in increasing precedence): a `--var-file`,
|
|
14
|
+
* inline `--var KEY=VALUE` flags, and finally masked prompts for any bare
|
|
15
|
+
* `--var KEY` flags. Prompting is refused in non-interactive contexts
|
|
16
|
+
* (non-TTY or JSON output) to avoid hangs and corrupting JSON payloads.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveVars(varFlags: string[], varFile: string | undefined, opts: {
|
|
19
|
+
isJson?: boolean | undefined;
|
|
20
|
+
outputError: (msg: string) => void;
|
|
21
|
+
}): Promise<Record<string, string> | undefined>;
|
|
4
22
|
//# sourceMappingURL=vars.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vars.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/vars.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vars.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/vars.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IACjD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAiBA;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAarE;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GACzE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CA6B7C"}
|
|
@@ -1,16 +1,35 @@
|
|
|
1
1
|
import { readFileSync } from 'fs';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
2
3
|
function normalizeKey(key) {
|
|
3
4
|
return key.trim().toUpperCase().replace(/\s+/g, '_');
|
|
4
5
|
}
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Split `--var` flags into values supplied inline (`KEY=VALUE`) and bare keys
|
|
8
|
+
* (`KEY` with no `=value`) that must be prompted for securely. Keeping secret
|
|
9
|
+
* values off the command line avoids leaking them into shell history, `ps`, and
|
|
10
|
+
* /proc/<pid>/cmdline.
|
|
11
|
+
*/
|
|
12
|
+
export function partitionVarFlags(vars) {
|
|
13
|
+
const resolved = {};
|
|
14
|
+
const needsPrompt = [];
|
|
7
15
|
for (const v of vars) {
|
|
8
16
|
const idx = v.indexOf('=');
|
|
9
|
-
if (idx === -1)
|
|
10
|
-
|
|
11
|
-
|
|
17
|
+
if (idx === -1) {
|
|
18
|
+
// Bare `--var KEY`: value omitted on purpose, prompt for it (masked).
|
|
19
|
+
const key = normalizeKey(v);
|
|
20
|
+
if (!key)
|
|
21
|
+
throw new Error(`Invalid --var format: "${v}". Key cannot be empty`);
|
|
22
|
+
if (!needsPrompt.includes(key))
|
|
23
|
+
needsPrompt.push(key);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const key = normalizeKey(v.slice(0, idx));
|
|
27
|
+
if (!key)
|
|
28
|
+
throw new Error(`Invalid --var format: "${v}". Key cannot be empty`);
|
|
29
|
+
resolved[key] = v.slice(idx + 1);
|
|
30
|
+
}
|
|
12
31
|
}
|
|
13
|
-
return
|
|
32
|
+
return { resolved, needsPrompt };
|
|
14
33
|
}
|
|
15
34
|
export function parseVarFile(filePath) {
|
|
16
35
|
const content = readFileSync(filePath, 'utf8');
|
|
@@ -28,11 +47,36 @@ export function parseVarFile(filePath) {
|
|
|
28
47
|
}
|
|
29
48
|
return result;
|
|
30
49
|
}
|
|
31
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Resolve suite variables from (in increasing precedence): a `--var-file`,
|
|
52
|
+
* inline `--var KEY=VALUE` flags, and finally masked prompts for any bare
|
|
53
|
+
* `--var KEY` flags. Prompting is refused in non-interactive contexts
|
|
54
|
+
* (non-TTY or JSON output) to avoid hangs and corrupting JSON payloads.
|
|
55
|
+
*/
|
|
56
|
+
export async function resolveVars(varFlags, varFile, opts) {
|
|
32
57
|
const result = {};
|
|
33
58
|
if (varFile)
|
|
34
59
|
Object.assign(result, parseVarFile(varFile));
|
|
35
|
-
|
|
60
|
+
const { resolved, needsPrompt } = partitionVarFlags(varFlags);
|
|
61
|
+
Object.assign(result, resolved);
|
|
62
|
+
if (needsPrompt.length > 0) {
|
|
63
|
+
if (!process.stdin.isTTY || opts.isJson) {
|
|
64
|
+
opts.outputError('A secret value prompt is required but cannot run non-interactively. ' +
|
|
65
|
+
'Pass --var KEY=VALUE or --var-file <path> instead.');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
for (const key of needsPrompt) {
|
|
69
|
+
const { value } = await inquirer.prompt([
|
|
70
|
+
{
|
|
71
|
+
type: 'password',
|
|
72
|
+
name: 'value',
|
|
73
|
+
mask: '*',
|
|
74
|
+
message: `Value for ${key} (input hidden):`,
|
|
75
|
+
},
|
|
76
|
+
]);
|
|
77
|
+
result[key] = value;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
36
80
|
return Object.keys(result).length > 0 ? result : undefined;
|
|
37
81
|
}
|
|
38
82
|
//# sourceMappingURL=vars.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vars.js","sourceRoot":"","sources":["../../../src/commands/suite/vars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"vars.js","sourceRoot":"","sources":["../../../src/commands/suite/vars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAI9C,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,sEAAsE;YACtE,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,wBAAwB,CAAC,CAAC;YAC/E,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,wBAAwB,CAAC,CAAC;YAC/E,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QACzB,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAkB,EAClB,OAA2B,EAC3B,IAA0E;IAE1E,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,OAAO;QAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IAE1D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEhC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,CAAC,WAAW,CACd,sEAAsE;gBACpE,oDAAoD,CACvD,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;gBACtC;oBACE,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,GAAG;oBACT,OAAO,EAAE,aAAa,GAAG,kBAAkB;iBAC5C;aACF,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,GAAG,KAAe,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../../src/commands/suite/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAqCT"}
|
|
@@ -9,11 +9,12 @@ export function createSuiteWaitCommand(_configService, apiClient, outputService)
|
|
|
9
9
|
.argument('<executionId>', 'Execution ID')
|
|
10
10
|
.action(async (id, executionId) => {
|
|
11
11
|
const isJson = process.env.OBS_JSON_OUTPUT === 'true';
|
|
12
|
+
const spinner = ora({
|
|
13
|
+
text: 'Waiting for execution to complete...',
|
|
14
|
+
stream: process.stdout,
|
|
15
|
+
});
|
|
12
16
|
try {
|
|
13
|
-
|
|
14
|
-
text: 'Waiting for execution to complete...',
|
|
15
|
-
stream: process.stdout,
|
|
16
|
-
}).start();
|
|
17
|
+
spinner.start();
|
|
17
18
|
const done = await apiClient.pollSuiteExecution(id, executionId);
|
|
18
19
|
spinner.stop();
|
|
19
20
|
if (isJson) {
|
|
@@ -26,6 +27,7 @@ export function createSuiteWaitCommand(_configService, apiClient, outputService)
|
|
|
26
27
|
process.exit(allPassed ? 0 : 1);
|
|
27
28
|
}
|
|
28
29
|
catch (err) {
|
|
30
|
+
spinner.stop();
|
|
29
31
|
const msg = err.message || 'Failed to wait for suite execution';
|
|
30
32
|
if (isJson) {
|
|
31
33
|
outputService.formatJsonOutput({ status: 'ERROR', error: { message: msg } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../../../src/commands/suite/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,UAAU,sBAAsB,CACpC,cAA8B,EAC9B,SAAoB,EACpB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,sDAAsD,CAAC;SACnE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;SAC5B,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,WAAmB,EAAE,EAAE;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;QACtD,
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../../../src/commands/suite/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,UAAU,sBAAsB,CACpC,cAA8B,EAC9B,SAAoB,EACpB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,sDAAsD,CAAC;SACnE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;SAC5B,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,WAAmB,EAAE,EAAE;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;QACtD,MAAM,OAAO,GAAG,GAAG,CAAC;YAClB,IAAI,EAAE,sCAAsC;YAC5C,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,OAAO,CAAC,KAAK,EAAE,CAAC;YAEhB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;YAEjE,OAAO,CAAC,IAAI,EAAE,CAAC;YAEf,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;YAC1E,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,IAAI,oCAAoC,CAAC;YAC3E,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/E,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;YACvC,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { IOutputService } from '../interfaces/output.interface.js';
|
|
3
|
+
/**
|
|
4
|
+
* Enforce field TYPES and ENUM membership for a resource file, beyond the
|
|
5
|
+
* required-present checks. Types are inferred from the resource template; enums
|
|
6
|
+
* come from `fieldMetadata.choices`. Fields absent from the template (and
|
|
7
|
+
* without choices) carry no type info and pass through untouched, so exported
|
|
8
|
+
* keys like `id`/`created_at` and template-less flags (e.g. `regions`) are fine.
|
|
9
|
+
*
|
|
10
|
+
* Enum membership is case-sensitive against the declared choices: files should
|
|
11
|
+
* use the exact casing the schema emits (e.g. `"GET"`, `"HIGH"`, `"email"`).
|
|
12
|
+
*
|
|
13
|
+
* Returns a list of human-readable error strings (empty when valid).
|
|
14
|
+
*/
|
|
15
|
+
export declare function validateAgainstSchema(resource: string, obj: Record<string, unknown>): string[];
|
|
3
16
|
export declare function createValidateCommand(outputService: IOutputService): Command;
|
|
4
17
|
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAgBnE;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CA+B9F;AAED,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,cAAc,GAAG,OAAO,CA4D5E"}
|
|
@@ -1,6 +1,61 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { readFileSync, existsSync } from 'fs';
|
|
3
3
|
import { resolveSchema, resourceNames } from '../utils/schemas.js';
|
|
4
|
+
/** JSON value type, collapsing integer/float to a single 'number' bucket. */
|
|
5
|
+
function valueType(value) {
|
|
6
|
+
if (Array.isArray(value))
|
|
7
|
+
return 'array';
|
|
8
|
+
if (value === null)
|
|
9
|
+
return 'null';
|
|
10
|
+
const t = typeof value;
|
|
11
|
+
if (t === 'number')
|
|
12
|
+
return 'number';
|
|
13
|
+
if (t === 'boolean')
|
|
14
|
+
return 'boolean';
|
|
15
|
+
if (t === 'string')
|
|
16
|
+
return 'string';
|
|
17
|
+
return 'object';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Enforce field TYPES and ENUM membership for a resource file, beyond the
|
|
21
|
+
* required-present checks. Types are inferred from the resource template; enums
|
|
22
|
+
* come from `fieldMetadata.choices`. Fields absent from the template (and
|
|
23
|
+
* without choices) carry no type info and pass through untouched, so exported
|
|
24
|
+
* keys like `id`/`created_at` and template-less flags (e.g. `regions`) are fine.
|
|
25
|
+
*
|
|
26
|
+
* Enum membership is case-sensitive against the declared choices: files should
|
|
27
|
+
* use the exact casing the schema emits (e.g. `"GET"`, `"HIGH"`, `"email"`).
|
|
28
|
+
*
|
|
29
|
+
* Returns a list of human-readable error strings (empty when valid).
|
|
30
|
+
*/
|
|
31
|
+
export function validateAgainstSchema(resource, obj) {
|
|
32
|
+
const schema = resolveSchema(resource);
|
|
33
|
+
if (!schema)
|
|
34
|
+
return [];
|
|
35
|
+
const errors = [];
|
|
36
|
+
const meta = schema.fieldMetadata ?? {};
|
|
37
|
+
for (const [field, value] of Object.entries(obj)) {
|
|
38
|
+
// Skip absent/null — required-present handles missing keys; a null clears.
|
|
39
|
+
if (value === undefined || value === null)
|
|
40
|
+
continue;
|
|
41
|
+
const choices = meta[field]?.choices;
|
|
42
|
+
if (choices && typeof value === 'string' && !choices.includes(value)) {
|
|
43
|
+
errors.push(`Field "${field}" must be one of: ${choices.join(', ')} (got ${JSON.stringify(value)})`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (field in schema.template) {
|
|
47
|
+
const expected = valueType(schema.template[field]);
|
|
48
|
+
// A template null carries no type constraint.
|
|
49
|
+
if (expected === 'null')
|
|
50
|
+
continue;
|
|
51
|
+
const actual = valueType(value);
|
|
52
|
+
if (actual !== expected) {
|
|
53
|
+
errors.push(`Field "${field}" must be of type ${expected} (got ${actual})`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return errors;
|
|
58
|
+
}
|
|
4
59
|
export function createValidateCommand(outputService) {
|
|
5
60
|
return new Command('validate')
|
|
6
61
|
.description('Validate a resource JSON file against the expected schema')
|
|
@@ -38,6 +93,16 @@ export function createValidateCommand(outputService) {
|
|
|
38
93
|
}
|
|
39
94
|
process.exit(1);
|
|
40
95
|
}
|
|
96
|
+
const typeErrors = validateAgainstSchema(options.resource, data);
|
|
97
|
+
if (typeErrors.length > 0) {
|
|
98
|
+
if (isJson) {
|
|
99
|
+
outputService.formatJsonOutput({ valid: false, errors: typeErrors });
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
outputService.error(`Validation failed:\n - ${typeErrors.join('\n - ')}`);
|
|
103
|
+
}
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
41
106
|
if (isJson) {
|
|
42
107
|
outputService.formatJsonOutput({ valid: true, resource: options.resource });
|
|
43
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,7 +51,7 @@ export interface IApiClient {
|
|
|
51
51
|
alert_on_failure: boolean;
|
|
52
52
|
message: string;
|
|
53
53
|
}>;
|
|
54
|
-
getUrlMonitorRuns(id:
|
|
54
|
+
getUrlMonitorRuns(id: string, limit?: number): Promise<ResourceRun[]>;
|
|
55
55
|
getApiChecks(): Promise<ApiCheck[]>;
|
|
56
56
|
listApiChecks(query?: ListQueryOptions): Promise<PaginatedListResult<ApiCheck>>;
|
|
57
57
|
getApiCheck(id: string): Promise<ApiCheck>;
|
|
@@ -63,7 +63,7 @@ export interface IApiClient {
|
|
|
63
63
|
alert_on_failure: boolean;
|
|
64
64
|
message: string;
|
|
65
65
|
}>;
|
|
66
|
-
getApiCheckRuns(id:
|
|
66
|
+
getApiCheckRuns(id: string, limit?: number): Promise<ResourceRun[]>;
|
|
67
67
|
getHeartbeats(): Promise<Heartbeat[]>;
|
|
68
68
|
listHeartbeats(query?: ListQueryOptions): Promise<PaginatedListResult<Heartbeat>>;
|
|
69
69
|
getHeartbeat(id: string): Promise<Heartbeat>;
|
|
@@ -76,7 +76,7 @@ export interface IApiClient {
|
|
|
76
76
|
message: string;
|
|
77
77
|
}>;
|
|
78
78
|
resetHeartbeat(id: string): Promise<Heartbeat>;
|
|
79
|
-
getHeartbeatRuns(id:
|
|
79
|
+
getHeartbeatRuns(id: string, limit?: number): Promise<HeartbeatPing[]>;
|
|
80
80
|
getAlertChannels(): Promise<AlertChannel[]>;
|
|
81
81
|
getAlertChannel(id: string): Promise<AlertChannel>;
|
|
82
82
|
createAlertChannel(data: Partial<AlertChannel>): Promise<AlertChannel>;
|
|
@@ -9,6 +9,8 @@ export interface IConfigService {
|
|
|
9
9
|
setApiUrl(url: string): void;
|
|
10
10
|
setApiKey(key: string): void;
|
|
11
11
|
clearApiKey(): void;
|
|
12
|
+
clearLocalApiKey(): void;
|
|
13
|
+
hasEnvApiKey(): boolean;
|
|
12
14
|
getProjectConfig(): ProjectConfig;
|
|
13
15
|
setProjectConfig(config: ProjectConfig): void;
|
|
14
16
|
getDefaultOptions(): Required<DefaultOptions>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/config.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,IAAI,MAAM,CAAC;IACpB,SAAS,IAAI,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,IAAI,IAAI,CAAC;IACpB,gBAAgB,IAAI,aAAa,CAAC;IAClC,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C,iBAAiB,IAAI,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC9C,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACjD,aAAa,IAAI,OAAO,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,aAAa,IAAI,MAAM,CAAC;IACxB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC"}
|
|
1
|
+
{"version":3,"file":"config.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/config.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,IAAI,MAAM,CAAC;IACpB,SAAS,IAAI,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,IAAI,IAAI,CAAC;IACpB,gBAAgB,IAAI,IAAI,CAAC;IACzB,YAAY,IAAI,OAAO,CAAC;IACxB,gBAAgB,IAAI,aAAa,CAAC;IAClC,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C,iBAAiB,IAAI,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC9C,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACjD,aAAa,IAAI,OAAO,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,aAAa,IAAI,MAAM,CAAC;IACxB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC"}
|