sonamu 0.10.13 → 0.11.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/dist/ai/agents/agent.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +3 -2
- package/dist/api/validator.d.ts.map +1 -1
- package/dist/auth/audit-log/events.d.ts.map +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +3 -3
- package/dist/auth/knex-adapter.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/admin.d.ts +4 -4
- package/dist/auth/plugins/wrappers/admin.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/anonymous.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/api-key.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/organization.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/passkey.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/phone-number.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/sso.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/two-factor.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/username.d.ts.map +1 -1
- package/dist/bin/build-config.d.ts +10 -0
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +130 -6
- package/dist/bin/fixture.d.ts +7 -4
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +161 -13
- package/dist/bin/test-command.d.ts +7 -0
- package/dist/bin/test-command.d.ts.map +1 -1
- package/dist/bin/test-command.js +18 -4
- package/dist/bin/typecheck-web.d.ts +2 -0
- package/dist/bin/typecheck-web.d.ts.map +1 -0
- package/dist/bin/typecheck-web.js +36 -0
- package/dist/cache/decorator.d.ts.map +1 -1
- package/dist/cache/drivers.d.ts.map +1 -1
- package/dist/cache-control/cache-control.d.ts.map +1 -1
- package/dist/compress/compress.d.ts.map +1 -1
- package/dist/cone/cone-generator.js +1 -1
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.types.d.ts +0 -1
- package/dist/database/base-model.types.d.ts.map +1 -1
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/puri-subset.types.d.ts +0 -1
- package/dist/database/puri-subset.types.d.ts.map +1 -1
- package/dist/database/puri-wrapper.d.ts +0 -1
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri.d.ts +0 -1
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.types.d.ts +0 -1
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/dict/en.d.ts +58 -58
- package/dist/dict/en.d.ts.map +1 -1
- package/dist/dict/ko.d.ts +58 -58
- package/dist/dict/ko.d.ts.map +1 -1
- package/dist/dict/rc-keys.d.ts.map +1 -1
- package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
- package/dist/dict/sonamu-dictionary.js +2 -2
- package/dist/dict/utils.d.ts.map +1 -1
- package/dist/entity/entity-manager.d.ts +115 -113
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +25 -19
- package/dist/entity/entity-template-cone.d.ts +4 -4
- package/dist/entity/entity.d.ts +6 -1
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +8 -3
- package/dist/env.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/filter/types.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/logger/configure.d.ts +10 -1
- package/dist/logger/configure.d.ts.map +1 -1
- package/dist/logger/configure.js +30 -5
- package/dist/migration/migrator.d.ts +12 -1
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +77 -30
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/naite/messaging-types.d.ts +0 -1
- package/dist/naite/messaging-types.d.ts.map +1 -1
- package/dist/naite/naite-reporter.d.ts +0 -1
- package/dist/naite/naite-reporter.d.ts.map +1 -1
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/storage/base-file.d.ts.map +1 -1
- package/dist/storage/buffered-file.d.ts.map +1 -1
- package/dist/storage/drivers.d.ts.map +1 -1
- package/dist/storage/s3-driver.d.ts.map +1 -1
- package/dist/storage/storage-manager.d.ts.map +1 -1
- package/dist/storage/uploaded-file.d.ts.map +1 -1
- package/dist/stream/ws-audience-resolver.d.ts.map +1 -1
- package/dist/stream/ws-audience.d.ts.map +1 -1
- package/dist/stream/ws-cluster-bus.d.ts.map +1 -1
- package/dist/stream/ws-delivery.d.ts.map +1 -1
- package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
- package/dist/stream/ws-presence-store.d.ts.map +1 -1
- package/dist/stream/ws-registry.d.ts.map +1 -1
- package/dist/stream/ws-telemetry-memory.d.ts.map +1 -1
- package/dist/stream/ws-telemetry.d.ts.map +1 -1
- package/dist/stream/ws.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +2 -2
- package/dist/syncer/file-patterns.d.ts +17 -17
- package/dist/syncer/filesystem-dependencies.js +1 -1
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/tasks/step-wrapper.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/template/implementations/entity.template.d.ts +2 -2
- package/dist/template/implementations/entity.template.d.ts.map +1 -1
- package/dist/template/implementations/entry-server.template.d.ts +2 -2
- package/dist/template/implementations/entry-server.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.d.ts +2 -2
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.d.ts +2 -2
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.d.ts +2 -2
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/http_validators.template.d.ts +2 -2
- package/dist/template/implementations/http_validators.template.d.ts.map +1 -1
- package/dist/template/implementations/init_types.template.d.ts +2 -2
- package/dist/template/implementations/init_types.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.d.ts +2 -2
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model_test.template.d.ts +2 -2
- package/dist/template/implementations/model_test.template.d.ts.map +1 -1
- package/dist/template/implementations/queries.template.d.ts +2 -2
- package/dist/template/implementations/queries.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.d.ts +2 -2
- package/dist/template/implementations/sd.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.js +1 -1
- package/dist/template/implementations/services.template.d.ts +2 -2
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.d.ts +3 -3
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.d.ts +2 -2
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.d.ts +2 -2
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/template-manager.d.ts.map +1 -1
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/data-explorer.d.ts +2 -2
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
- package/dist/testing/faker-mappings.d.ts.map +1 -1
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +1 -1
- package/dist/testing/fixture-loader.d.ts.map +1 -1
- package/dist/testing/fixture-manager.d.ts +4 -0
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +99 -25
- package/dist/testing/naite-vitest-reporter.d.ts.map +1 -1
- package/dist/testing/parallel-db-manager.d.ts.map +1 -1
- package/dist/tooling/__tests__/helpers/sonamu-test-root.d.ts +10 -0
- package/dist/tooling/__tests__/helpers/sonamu-test-root.d.ts.map +1 -0
- package/dist/tooling/__tests__/helpers/sonamu-test-root.js +42 -0
- package/dist/tooling/cdd-service.d.ts +87 -0
- package/dist/tooling/cdd-service.d.ts.map +1 -0
- package/dist/tooling/cdd-service.js +215 -0
- package/dist/tooling/cli-tooling.d.ts +11 -0
- package/dist/tooling/cli-tooling.d.ts.map +1 -0
- package/dist/tooling/cli-tooling.js +901 -0
- package/dist/tooling/fixture-service.d.ts +29 -0
- package/dist/tooling/fixture-service.d.ts.map +1 -0
- package/dist/tooling/fixture-service.js +53 -0
- package/dist/tooling/index.d.ts +2 -0
- package/dist/tooling/index.d.ts.map +1 -0
- package/dist/tooling/index.js +2 -0
- package/dist/tooling/test-run-client.d.ts +27 -0
- package/dist/tooling/test-run-client.d.ts.map +1 -0
- package/dist/tooling/test-run-client.js +120 -0
- package/dist/tsdown.api.config.js +48 -0
- package/dist/types/types.d.ts +527 -527
- package/dist/types/types.d.ts.map +1 -1
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/utils/formatter.d.ts +6 -0
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +42 -11
- package/dist/utils/model.d.ts +1 -1
- package/dist/vector/chunking.d.ts.map +1 -1
- package/dist/vector/embedding.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/api/sonamu.ts +2 -1
- package/src/auth/index.ts +1 -1
- package/src/bin/__tests__/zod-compiler-build.test.ts +67 -0
- package/src/bin/build-config.ts +151 -5
- package/src/bin/fixture.ts +204 -21
- package/src/bin/test-command.ts +27 -4
- package/src/bin/typecheck-web.ts +56 -0
- package/src/dict/sonamu-dictionary.ts +1 -1
- package/src/entity/__tests__/entity-manager-autoload.contract.test.ts +55 -0
- package/src/entity/__tests__/entity-manager-explicit-root-registration.contract.test.ts +107 -0
- package/src/entity/entity-manager.ts +31 -19
- package/src/entity/entity.ts +7 -2
- package/src/logger/__tests__/configure.test.ts +33 -0
- package/src/logger/configure.ts +45 -3
- package/src/migration/__tests__/migrator.test.ts +51 -0
- package/src/migration/migrator.ts +103 -34
- package/src/syncer/api-parser.ts +1 -1
- package/src/testing/fixture-manager.ts +124 -32
- package/src/tooling/__tests__/cdd-rule-bootstrap.contract.test.ts +118 -0
- package/src/tooling/__tests__/cli-tooling-auth.contract.test.ts +72 -0
- package/src/tooling/__tests__/cli-tooling-cone-locale.contract.test.ts +150 -0
- package/src/tooling/__tests__/cli-tooling-entity-patch.contract.test.ts +131 -0
- package/src/tooling/__tests__/cli-tooling-fixture-transfer.contract.test.ts +255 -0
- package/src/tooling/__tests__/cli-tooling-i18n-update.contract.test.ts +104 -0
- package/src/tooling/__tests__/cli-tooling-scaffold.contract.test.ts +86 -0
- package/src/tooling/__tests__/cli-tooling-stub-practice.contract.test.ts +147 -0
- package/src/tooling/__tests__/default-cdd-adapter.contract.test.ts +73 -0
- package/src/tooling/__tests__/helpers/sonamu-test-root.ts +42 -0
- package/src/tooling/__tests__/test-run-client-config.contract.test.ts +154 -0
- package/src/tooling/cdd-service.ts +256 -0
- package/src/tooling/cli-tooling.ts +937 -0
- package/src/tooling/fixture-service.ts +72 -0
- package/src/tooling/index.ts +1 -0
- package/src/tooling/test-run-client.ts +196 -0
- package/src/utils/__tests__/formatter-bin.test.ts +99 -0
- package/src/utils/formatter.ts +74 -10
- package/tsdown.api.config.ts +8 -10
- package/bin/cli.js +0 -75
- package/dist/bin/cli.d.ts +0 -2
- package/dist/bin/cli.d.ts.map +0 -1
- package/dist/bin/cli.js +0 -956
- package/src/bin/cli.ts +0 -1166
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Sonamu, init_sonamu } from "../../../api/sonamu.js";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
//#region src/tooling/__tests__/helpers/sonamu-test-root.ts
|
|
6
|
+
init_sonamu();
|
|
7
|
+
const createdWorkspaces = [];
|
|
8
|
+
let capturedSnapshot = null;
|
|
9
|
+
let capturedInitialized = false;
|
|
10
|
+
/**
|
|
11
|
+
* 임시 api root를 만들어 Sonamu singleton의 공개 setter로 주입합니다.
|
|
12
|
+
*
|
|
13
|
+
* tooling 연산은 `Sonamu.isInitialized`가 참이면 초기화를 건너뛰므로,
|
|
14
|
+
* 실제 DB/설정 없이 파일 경로 기반 동작만 검증할 수 있습니다.
|
|
15
|
+
*/
|
|
16
|
+
async function attachSonamuTestRoot() {
|
|
17
|
+
const workspace = await mkdtemp(path.join(os.tmpdir(), "sonamu-tooling-"));
|
|
18
|
+
createdWorkspaces.push(workspace);
|
|
19
|
+
const apiRootPath = path.join(workspace, "api");
|
|
20
|
+
await mkdir(path.join(apiRootPath, "src", "application"), { recursive: true });
|
|
21
|
+
capturedSnapshot ??= Sonamu.captureTestingSnapshot();
|
|
22
|
+
capturedInitialized = Sonamu.isInitialized;
|
|
23
|
+
Sonamu.apiRootPath = apiRootPath;
|
|
24
|
+
Sonamu.isInitialized = true;
|
|
25
|
+
return apiRootPath;
|
|
26
|
+
}
|
|
27
|
+
/** 주입한 Sonamu 상태를 되돌리고 임시 디렉터리를 정리합니다. */
|
|
28
|
+
async function detachSonamuTestRoot() {
|
|
29
|
+
if (capturedSnapshot !== null) {
|
|
30
|
+
Sonamu.restoreTestingSnapshot(capturedSnapshot);
|
|
31
|
+
capturedSnapshot = null;
|
|
32
|
+
}
|
|
33
|
+
Sonamu.isInitialized = capturedInitialized;
|
|
34
|
+
await Promise.all(createdWorkspaces.splice(0).map((workspace) => rm(workspace, {
|
|
35
|
+
recursive: true,
|
|
36
|
+
force: true
|
|
37
|
+
})));
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { attachSonamuTestRoot, detachSonamuTestRoot };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LXRlc3Qtcm9vdC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdG9vbGluZy9fX3Rlc3RzX18vaGVscGVycy9zb25hbXUtdGVzdC1yb290LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1rZGlyLCBta2R0ZW1wLCBybSB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcblxuaW1wb3J0IHsgU29uYW11LCB0eXBlIFNvbmFtdVRlc3RpbmdTbmFwc2hvdCB9IGZyb20gXCIuLi8uLi8uLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyB0eXBlIEFic29sdXRlUGF0aCB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9wYXRoLXV0aWxzXCI7XG5cbmNvbnN0IGNyZWF0ZWRXb3Jrc3BhY2VzOiBzdHJpbmdbXSA9IFtdO1xubGV0IGNhcHR1cmVkU25hcHNob3Q6IFNvbmFtdVRlc3RpbmdTbmFwc2hvdCB8IG51bGwgPSBudWxsO1xubGV0IGNhcHR1cmVkSW5pdGlhbGl6ZWQgPSBmYWxzZTtcblxuLyoqXG4gKiDsnoTsi5wgYXBpIHJvb3Trpbwg66eM65Ok7Ja0IFNvbmFtdSBzaW5nbGV0b27snZgg6rO16rCcIHNldHRlcuuhnCDso7zsnoXtlanri4jri6QuXG4gKlxuICogdG9vbGluZyDsl7DsgrDsnYAgYFNvbmFtdS5pc0luaXRpYWxpemVkYOqwgCDssLjsnbTrqbQg7LSI6riw7ZmU66W8IOqxtOuEiOubsOuvgOuhnCxcbiAqIOyLpOygnCBEQi/shKTsoJUg7JeG7J20IO2MjOydvCDqsr3roZwg6riw67CYIOuPmeyekeunjCDqsoDspp3tlaAg7IiYIOyeiOyKteuLiOuLpC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF0dGFjaFNvbmFtdVRlc3RSb290KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHdvcmtzcGFjZSA9IGF3YWl0IG1rZHRlbXAocGF0aC5qb2luKG9zLnRtcGRpcigpLCBcInNvbmFtdS10b29saW5nLVwiKSk7XG4gIGNyZWF0ZWRXb3Jrc3BhY2VzLnB1c2god29ya3NwYWNlKTtcbiAgY29uc3QgYXBpUm9vdFBhdGggPSBwYXRoLmpvaW4od29ya3NwYWNlLCBcImFwaVwiKTtcbiAgYXdhaXQgbWtkaXIocGF0aC5qb2luKGFwaVJvb3RQYXRoLCBcInNyY1wiLCBcImFwcGxpY2F0aW9uXCIpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBjYXB0dXJlZFNuYXBzaG90ID8/PSBTb25hbXUuY2FwdHVyZVRlc3RpbmdTbmFwc2hvdCgpO1xuICBjYXB0dXJlZEluaXRpYWxpemVkID0gU29uYW11LmlzSW5pdGlhbGl6ZWQ7XG4gIC8vIFNBRkVUWTogbWtkdGVtcOqwgCDrsJjtmZjtlZwg7KCI64yAIOqyveuhnOunjCDso7zsnoXtlanri4jri6QuXG4gIFNvbmFtdS5hcGlSb290UGF0aCA9IGFwaVJvb3RQYXRoIGFzIEFic29sdXRlUGF0aDtcbiAgU29uYW11LmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICByZXR1cm4gYXBpUm9vdFBhdGg7XG59XG5cbi8qKiDso7zsnoXtlZwgU29uYW11IOyDge2DnOulvCDrkJjrj4zrpqzqs6Ag7J6E7IucIOuUlOugie2EsOumrOulvCDsoJXrpqztlanri4jri6QuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGV0YWNoU29uYW11VGVzdFJvb3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChjYXB0dXJlZFNuYXBzaG90ICE9PSBudWxsKSB7XG4gICAgU29uYW11LnJlc3RvcmVUZXN0aW5nU25hcHNob3QoY2FwdHVyZWRTbmFwc2hvdCk7XG4gICAgY2FwdHVyZWRTbmFwc2hvdCA9IG51bGw7XG4gIH1cbiAgU29uYW11LmlzSW5pdGlhbGl6ZWQgPSBjYXB0dXJlZEluaXRpYWxpemVkO1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBjcmVhdGVkV29ya3NwYWNlcy5zcGxpY2UoMCkubWFwKCh3b3Jrc3BhY2UpID0+IHJtKHdvcmtzcGFjZSwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pKSxcbiAgKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7WUFJd0U7QUFHeEUsTUFBTSxvQkFBOEIsQ0FBQztBQUNyQyxJQUFJLG1CQUFpRDtBQUNyRCxJQUFJLHNCQUFzQjs7Ozs7OztBQVExQixlQUFzQix1QkFBd0M7Q0FDNUQsTUFBTSxZQUFZLE1BQU0sUUFBUSxLQUFLLEtBQUssR0FBRyxPQUFPLEdBQUcsaUJBQWlCLENBQUM7Q0FDekUsa0JBQWtCLEtBQUssU0FBUztDQUNoQyxNQUFNLGNBQWMsS0FBSyxLQUFLLFdBQVcsS0FBSztDQUM5QyxNQUFNLE1BQU0sS0FBSyxLQUFLLGFBQWEsT0FBTyxhQUFhLEdBQUcsRUFBRSxXQUFXLEtBQUssQ0FBQztDQUU3RSxxQkFBcUIsT0FBTyx1QkFBdUI7Q0FDbkQsc0JBQXNCLE9BQU87Q0FFN0IsT0FBTyxjQUFjO0NBQ3JCLE9BQU8sZ0JBQWdCO0NBQ3ZCLE9BQU87QUFDVDs7QUFHQSxlQUFzQix1QkFBc0M7Q0FDMUQsSUFBSSxxQkFBcUIsTUFBTTtFQUM3QixPQUFPLHVCQUF1QixnQkFBZ0I7RUFDOUMsbUJBQW1CO0NBQ3JCO0NBQ0EsT0FBTyxnQkFBZ0I7Q0FDdkIsTUFBTSxRQUFRLElBQ1osa0JBQWtCLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxjQUFjLEdBQUcsV0FBVztFQUFFLFdBQVc7RUFBTSxPQUFPO0NBQUssQ0FBQyxDQUFDLENBQ2hHO0FBQ0YifQ==
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as defaultFs from "node:fs/promises";
|
|
2
|
+
type CddFileSystem = Pick<typeof defaultFs, "lstat" | "mkdir" | "open" | "opendir" | "realpath">;
|
|
3
|
+
export declare function createDefaultCddToolingAdapter({ contractRoot, fs, }: {
|
|
4
|
+
contractRoot: string;
|
|
5
|
+
fs?: CddFileSystem;
|
|
6
|
+
}): {
|
|
7
|
+
read(input: {
|
|
8
|
+
path: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
content: string;
|
|
11
|
+
fileType: "contract";
|
|
12
|
+
}>;
|
|
13
|
+
rules(): Promise<{
|
|
14
|
+
rules: {
|
|
15
|
+
key: string;
|
|
16
|
+
path: string;
|
|
17
|
+
description: string;
|
|
18
|
+
ruleCount: number;
|
|
19
|
+
}[];
|
|
20
|
+
}>;
|
|
21
|
+
showRule(input: {
|
|
22
|
+
ruleId: string;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
description?: string;
|
|
25
|
+
rules?: Array<{
|
|
26
|
+
id: string;
|
|
27
|
+
when: string;
|
|
28
|
+
instruction: string;
|
|
29
|
+
examples?: string[];
|
|
30
|
+
}>;
|
|
31
|
+
key: string;
|
|
32
|
+
path: string;
|
|
33
|
+
}>;
|
|
34
|
+
addRule(input: {
|
|
35
|
+
ruleKey: string;
|
|
36
|
+
id: string;
|
|
37
|
+
when: string;
|
|
38
|
+
text: string;
|
|
39
|
+
examples?: string[];
|
|
40
|
+
dryRun: boolean;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
dryRun: true;
|
|
43
|
+
rule: {
|
|
44
|
+
ruleKey: string;
|
|
45
|
+
id: string;
|
|
46
|
+
when: string;
|
|
47
|
+
text: string;
|
|
48
|
+
};
|
|
49
|
+
} | {
|
|
50
|
+
description?: string;
|
|
51
|
+
rules?: Array<{
|
|
52
|
+
id: string;
|
|
53
|
+
when: string;
|
|
54
|
+
instruction: string;
|
|
55
|
+
examples?: string[];
|
|
56
|
+
}>;
|
|
57
|
+
dryRun?: undefined;
|
|
58
|
+
rule?: undefined;
|
|
59
|
+
key: string;
|
|
60
|
+
path: string;
|
|
61
|
+
}>;
|
|
62
|
+
addAcceptanceCriterion(input: {
|
|
63
|
+
document: string;
|
|
64
|
+
text: string;
|
|
65
|
+
dryRun: boolean;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
operation: "addAcceptanceCriterion";
|
|
68
|
+
input: {
|
|
69
|
+
document: string;
|
|
70
|
+
text: string;
|
|
71
|
+
dryRun: boolean;
|
|
72
|
+
};
|
|
73
|
+
dryRun: boolean;
|
|
74
|
+
document?: undefined;
|
|
75
|
+
text?: undefined;
|
|
76
|
+
applied?: undefined;
|
|
77
|
+
} | {
|
|
78
|
+
dryRun?: undefined;
|
|
79
|
+
operation?: undefined;
|
|
80
|
+
input?: undefined;
|
|
81
|
+
document: string;
|
|
82
|
+
text: string;
|
|
83
|
+
applied: true;
|
|
84
|
+
}>;
|
|
85
|
+
};
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=cdd-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdd-service.d.ts","sourceRoot":"","sources":["../../src/tooling/cdd-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAC;AAG9C,KAAK,aAAa,GAAG,IAAI,CAAC,OAAO,SAAS,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,CAAC;AA8KjG,wBAAgB,8BAA8B,CAAC,EAC7C,YAAY,EACZ,EAAc,GACf,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,aAAa,CAAC;CACpB;IAIS,IAAI,QAAQ;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;;kBAC0B,UAAU;;IAEhE,KAAK;;;;;;;;IAyBL,QAAQ,QAAQ;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE;sBA1E5B,MAAM;gBACZ,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;;;;IAiF7E,OAAO,QAAQ;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,MAAM,EAAE,OAAO,CAAC;KACjB;;;;;;;;;sBAzFW,MAAM;gBACZ,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;;;;;;IAwG7E,sBAAsB,QAAQ;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;mBAE/D,wBAAwB;;sBAFA,MAAM;kBAAQ,MAAM;oBAAU,OAAO;;;;;;;;;;;;;;EAQxF"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import * as defaultFs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
//#region src/tooling/cdd-service.ts
|
|
5
|
+
function invalidCddPath(relativePath, cause) {
|
|
6
|
+
return Object.assign(/* @__PURE__ */ new Error(`CDD 경로가 contract 밖을 참조합니다: ${relativePath}`), {
|
|
7
|
+
code: "INVALID_CDD_PATH",
|
|
8
|
+
cause
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function isWithin(root, target) {
|
|
12
|
+
const relative = path.relative(root, target);
|
|
13
|
+
return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== "..";
|
|
14
|
+
}
|
|
15
|
+
async function nearestExistingPath(fs, target) {
|
|
16
|
+
let candidate = target;
|
|
17
|
+
while (true) try {
|
|
18
|
+
await fs.lstat(candidate);
|
|
19
|
+
return candidate;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
if (error.code !== "ENOENT") throw error;
|
|
22
|
+
const parent = path.dirname(candidate);
|
|
23
|
+
if (parent === candidate) throw error;
|
|
24
|
+
candidate = parent;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function createCddFileOperation({ contractRoot, fs = defaultFs }) {
|
|
28
|
+
async function resolveBoundary(relativePath) {
|
|
29
|
+
const [canonicalRoot, configuredRoot] = await Promise.all([fs.realpath(contractRoot), Promise.resolve(path.resolve(contractRoot))]);
|
|
30
|
+
const target = path.resolve(configuredRoot, relativePath);
|
|
31
|
+
if (!isWithin(configuredRoot, target)) throw invalidCddPath(relativePath);
|
|
32
|
+
return {
|
|
33
|
+
canonicalRoot,
|
|
34
|
+
target
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async function assertCanonicalPath(canonicalRoot, target, relativePath) {
|
|
38
|
+
const canonicalTarget = await fs.realpath(target);
|
|
39
|
+
if (!isWithin(canonicalRoot, canonicalTarget)) throw invalidCddPath(relativePath);
|
|
40
|
+
return canonicalTarget;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
async readDirectory(relativePath) {
|
|
44
|
+
const { canonicalRoot, target } = await resolveBoundary(relativePath);
|
|
45
|
+
const canonicalTarget = await assertCanonicalPath(canonicalRoot, target, relativePath);
|
|
46
|
+
let directory;
|
|
47
|
+
try {
|
|
48
|
+
directory = await fs.opendir(target);
|
|
49
|
+
if (await assertCanonicalPath(canonicalRoot, target, relativePath) !== canonicalTarget) throw invalidCddPath(relativePath);
|
|
50
|
+
const entries = [];
|
|
51
|
+
while (true) {
|
|
52
|
+
const entry = await directory.read();
|
|
53
|
+
if (entry === null) return entries;
|
|
54
|
+
entries.push(entry);
|
|
55
|
+
}
|
|
56
|
+
} finally {
|
|
57
|
+
await directory?.close();
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
async read(relativePath) {
|
|
61
|
+
const { canonicalRoot, target } = await resolveBoundary(relativePath);
|
|
62
|
+
const canonicalTarget = await assertCanonicalPath(canonicalRoot, target, relativePath);
|
|
63
|
+
let handle;
|
|
64
|
+
try {
|
|
65
|
+
handle = await fs.open(target, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
66
|
+
if (await assertCanonicalPath(canonicalRoot, target, relativePath) !== canonicalTarget) throw invalidCddPath(relativePath);
|
|
67
|
+
return await handle.readFile("utf8");
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error.code === "ELOOP") throw invalidCddPath(relativePath, error);
|
|
70
|
+
throw error;
|
|
71
|
+
} finally {
|
|
72
|
+
await handle?.close();
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
async write(relativePath, contents) {
|
|
76
|
+
const { canonicalRoot, target } = await resolveBoundary(relativePath);
|
|
77
|
+
const existing = await nearestExistingPath(fs, target);
|
|
78
|
+
const canonicalExisting = await assertCanonicalPath(canonicalRoot, existing, relativePath);
|
|
79
|
+
const targetExists = existing === target;
|
|
80
|
+
if (!targetExists) {
|
|
81
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
82
|
+
await assertCanonicalPath(canonicalRoot, path.dirname(target), relativePath);
|
|
83
|
+
}
|
|
84
|
+
let handle;
|
|
85
|
+
try {
|
|
86
|
+
const flags = targetExists ? constants.O_WRONLY | constants.O_NOFOLLOW : constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW;
|
|
87
|
+
handle = await fs.open(target, flags, 438);
|
|
88
|
+
const canonicalTarget = await assertCanonicalPath(canonicalRoot, target, relativePath);
|
|
89
|
+
if (!isWithin(canonicalRoot, canonicalTarget) || targetExists && canonicalTarget !== canonicalExisting) throw invalidCddPath(relativePath);
|
|
90
|
+
await handle.truncate(0);
|
|
91
|
+
await handle.writeFile(contents, "utf8");
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (error.code === "ELOOP") throw invalidCddPath(relativePath, error);
|
|
94
|
+
throw error;
|
|
95
|
+
} finally {
|
|
96
|
+
await handle?.close();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function parseCddRules(contents) {
|
|
102
|
+
try {
|
|
103
|
+
return JSON.parse(contents);
|
|
104
|
+
} catch (cause) {
|
|
105
|
+
throw Object.assign(/* @__PURE__ */ new Error("CDD rules JSON is malformed"), {
|
|
106
|
+
code: "INVALID_CDD_RULES",
|
|
107
|
+
exitCode: 2,
|
|
108
|
+
cause
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 규칙 문서를 읽되, 아직 파일이 없으면 빈 문서로 취급합니다.
|
|
114
|
+
*
|
|
115
|
+
* 첫 규칙 등록 시 rules 디렉터리와 파일이 없는 상태를 부트스트랩하기 위한 처리이며,
|
|
116
|
+
* 깨진 JSON은 그대로 INVALID_CDD_RULES로 실패시켜 덮어쓰기를 막습니다.
|
|
117
|
+
*/
|
|
118
|
+
async function readCddRuleDocument(files, relativePath) {
|
|
119
|
+
try {
|
|
120
|
+
return parseCddRules(await files.read(relativePath));
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error.code === "ENOENT") return {};
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function createDefaultCddToolingAdapter({ contractRoot, fs = defaultFs }) {
|
|
127
|
+
const files = createCddFileOperation({
|
|
128
|
+
contractRoot,
|
|
129
|
+
fs
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
async read(input) {
|
|
133
|
+
return {
|
|
134
|
+
content: await files.read(input.path),
|
|
135
|
+
fileType: "contract"
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
async rules() {
|
|
139
|
+
let entries;
|
|
140
|
+
try {
|
|
141
|
+
entries = await files.readDirectory("rules");
|
|
142
|
+
} catch (error) {
|
|
143
|
+
if (error.code === "ENOENT") return { rules: [] };
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
const rules = [];
|
|
147
|
+
for (const entry of entries) {
|
|
148
|
+
if (!entry.isFile() || !entry.name.endsWith(".rules.json")) continue;
|
|
149
|
+
const key = entry.name.replace(/\.rules\.json$/, "");
|
|
150
|
+
const relativePath = `rules/${entry.name}`;
|
|
151
|
+
const document = parseCddRules(await files.read(relativePath));
|
|
152
|
+
rules.push({
|
|
153
|
+
key,
|
|
154
|
+
path: relativePath,
|
|
155
|
+
description: document.description ?? "",
|
|
156
|
+
ruleCount: document.rules?.length ?? 0
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return { rules };
|
|
160
|
+
},
|
|
161
|
+
async showRule(input) {
|
|
162
|
+
const relativePath = `rules/${input.ruleId}.rules.json`;
|
|
163
|
+
return {
|
|
164
|
+
key: input.ruleId,
|
|
165
|
+
path: relativePath,
|
|
166
|
+
...parseCddRules(await files.read(relativePath))
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
async addRule(input) {
|
|
170
|
+
const rule = {
|
|
171
|
+
ruleKey: input.ruleKey,
|
|
172
|
+
id: input.id,
|
|
173
|
+
when: input.when,
|
|
174
|
+
text: input.text
|
|
175
|
+
};
|
|
176
|
+
if (input.dryRun) return {
|
|
177
|
+
dryRun: true,
|
|
178
|
+
rule
|
|
179
|
+
};
|
|
180
|
+
const relativePath = `rules/${input.ruleKey}.rules.json`;
|
|
181
|
+
const document = await readCddRuleDocument(files, relativePath);
|
|
182
|
+
document.rules ??= [];
|
|
183
|
+
document.rules.push({
|
|
184
|
+
id: input.id,
|
|
185
|
+
when: input.when,
|
|
186
|
+
instruction: input.text,
|
|
187
|
+
examples: input.examples ?? []
|
|
188
|
+
});
|
|
189
|
+
await files.write(relativePath, `${JSON.stringify(document, null, 2)}\n`);
|
|
190
|
+
return {
|
|
191
|
+
key: input.ruleKey,
|
|
192
|
+
path: relativePath,
|
|
193
|
+
...document
|
|
194
|
+
};
|
|
195
|
+
},
|
|
196
|
+
async addAcceptanceCriterion(input) {
|
|
197
|
+
if (input.dryRun) return {
|
|
198
|
+
operation: "addAcceptanceCriterion",
|
|
199
|
+
input,
|
|
200
|
+
dryRun: true
|
|
201
|
+
};
|
|
202
|
+
const contents = await files.read(input.document);
|
|
203
|
+
await files.write(input.document, `${contents}\n- ${input.text}\n`);
|
|
204
|
+
return {
|
|
205
|
+
document: input.document,
|
|
206
|
+
text: input.text,
|
|
207
|
+
applied: true
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
export { createDefaultCddToolingAdapter };
|
|
214
|
+
|
|
215
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RkLXNlcnZpY2UuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rvb2xpbmcvY2RkLXNlcnZpY2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29uc3RhbnRzIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCAqIGFzIGRlZmF1bHRGcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG50eXBlIENkZEZpbGVTeXN0ZW0gPSBQaWNrPHR5cGVvZiBkZWZhdWx0RnMsIFwibHN0YXRcIiB8IFwibWtkaXJcIiB8IFwib3BlblwiIHwgXCJvcGVuZGlyXCIgfCBcInJlYWxwYXRoXCI+O1xuXG5mdW5jdGlvbiBpbnZhbGlkQ2RkUGF0aChyZWxhdGl2ZVBhdGg6IHN0cmluZywgY2F1c2U/OiB1bmtub3duKTogRXJyb3Ige1xuICByZXR1cm4gT2JqZWN0LmFzc2lnbihuZXcgRXJyb3IoYENERCDqsr3roZzqsIAgY29udHJhY3Qg67CW7J2EIOywuOyhsO2VqeuLiOuLpDogJHtyZWxhdGl2ZVBhdGh9YCksIHtcbiAgICBjb2RlOiBcIklOVkFMSURfQ0REX1BBVEhcIixcbiAgICBjYXVzZSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzV2l0aGluKHJvb3Q6IHN0cmluZywgdGFyZ2V0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgcmVsYXRpdmUgPSBwYXRoLnJlbGF0aXZlKHJvb3QsIHRhcmdldCk7XG4gIHJldHVybiByZWxhdGl2ZSA9PT0gXCJcIiB8fCAoIXJlbGF0aXZlLnN0YXJ0c1dpdGgoYC4uJHtwYXRoLnNlcH1gKSAmJiByZWxhdGl2ZSAhPT0gXCIuLlwiKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbmVhcmVzdEV4aXN0aW5nUGF0aChmczogQ2RkRmlsZVN5c3RlbSwgdGFyZ2V0OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBsZXQgY2FuZGlkYXRlID0gdGFyZ2V0O1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5sc3RhdChjYW5kaWRhdGUpO1xuICAgICAgcmV0dXJuIGNhbmRpZGF0ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gU0FGRVRZOiBub2RlOmZzIGxzdGF0IOyLpO2MqOydmCBjb2Rl66eMIOydveyWtCDqsr3roZwg67aA7J6s66W8IOq1rOu2hO2VqeuLiOuLpC5cbiAgICAgIGlmICgoZXJyb3IgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlICE9PSBcIkVOT0VOVFwiKSB0aHJvdyBlcnJvcjtcbiAgICAgIGNvbnN0IHBhcmVudCA9IHBhdGguZGlybmFtZShjYW5kaWRhdGUpO1xuICAgICAgaWYgKHBhcmVudCA9PT0gY2FuZGlkYXRlKSB0aHJvdyBlcnJvcjtcbiAgICAgIGNhbmRpZGF0ZSA9IHBhcmVudDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2RkRmlsZU9wZXJhdGlvbih7XG4gIGNvbnRyYWN0Um9vdCxcbiAgZnMgPSBkZWZhdWx0RnMsXG59OiB7XG4gIGNvbnRyYWN0Um9vdDogc3RyaW5nO1xuICBmcz86IENkZEZpbGVTeXN0ZW07XG59KSB7XG4gIGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVCb3VuZGFyeShyZWxhdGl2ZVBhdGg6IHN0cmluZykge1xuICAgIGNvbnN0IFtjYW5vbmljYWxSb290LCBjb25maWd1cmVkUm9vdF0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICBmcy5yZWFscGF0aChjb250cmFjdFJvb3QpLFxuICAgICAgUHJvbWlzZS5yZXNvbHZlKHBhdGgucmVzb2x2ZShjb250cmFjdFJvb3QpKSxcbiAgICBdKTtcbiAgICBjb25zdCB0YXJnZXQgPSBwYXRoLnJlc29sdmUoY29uZmlndXJlZFJvb3QsIHJlbGF0aXZlUGF0aCk7XG4gICAgaWYgKCFpc1dpdGhpbihjb25maWd1cmVkUm9vdCwgdGFyZ2V0KSkgdGhyb3cgaW52YWxpZENkZFBhdGgocmVsYXRpdmVQYXRoKTtcbiAgICByZXR1cm4geyBjYW5vbmljYWxSb290LCB0YXJnZXQgfTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGFzc2VydENhbm9uaWNhbFBhdGgoXG4gICAgY2Fub25pY2FsUm9vdDogc3RyaW5nLFxuICAgIHRhcmdldDogc3RyaW5nLFxuICAgIHJlbGF0aXZlUGF0aDogc3RyaW5nLFxuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGNhbm9uaWNhbFRhcmdldCA9IGF3YWl0IGZzLnJlYWxwYXRoKHRhcmdldCk7XG4gICAgaWYgKCFpc1dpdGhpbihjYW5vbmljYWxSb290LCBjYW5vbmljYWxUYXJnZXQpKSB0aHJvdyBpbnZhbGlkQ2RkUGF0aChyZWxhdGl2ZVBhdGgpO1xuICAgIHJldHVybiBjYW5vbmljYWxUYXJnZXQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIHJlYWREaXJlY3RvcnkocmVsYXRpdmVQYXRoOiBzdHJpbmcpIHtcbiAgICAgIGNvbnN0IHsgY2Fub25pY2FsUm9vdCwgdGFyZ2V0IH0gPSBhd2FpdCByZXNvbHZlQm91bmRhcnkocmVsYXRpdmVQYXRoKTtcbiAgICAgIGNvbnN0IGNhbm9uaWNhbFRhcmdldCA9IGF3YWl0IGFzc2VydENhbm9uaWNhbFBhdGgoY2Fub25pY2FsUm9vdCwgdGFyZ2V0LCByZWxhdGl2ZVBhdGgpO1xuICAgICAgbGV0IGRpcmVjdG9yeTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGRpcmVjdG9yeSA9IGF3YWl0IGZzLm9wZW5kaXIodGFyZ2V0KTtcbiAgICAgICAgY29uc3QgcmVjaGVja2VkVGFyZ2V0ID0gYXdhaXQgYXNzZXJ0Q2Fub25pY2FsUGF0aChjYW5vbmljYWxSb290LCB0YXJnZXQsIHJlbGF0aXZlUGF0aCk7XG4gICAgICAgIGlmIChyZWNoZWNrZWRUYXJnZXQgIT09IGNhbm9uaWNhbFRhcmdldCkgdGhyb3cgaW52YWxpZENkZFBhdGgocmVsYXRpdmVQYXRoKTtcbiAgICAgICAgY29uc3QgZW50cmllcyA9IFtdO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIGNvbnN0IGVudHJ5ID0gYXdhaXQgZGlyZWN0b3J5LnJlYWQoKTtcbiAgICAgICAgICBpZiAoZW50cnkgPT09IG51bGwpIHJldHVybiBlbnRyaWVzO1xuICAgICAgICAgIGVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGRpcmVjdG9yeT8uY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIHJlYWQocmVsYXRpdmVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgY29uc3QgeyBjYW5vbmljYWxSb290LCB0YXJnZXQgfSA9IGF3YWl0IHJlc29sdmVCb3VuZGFyeShyZWxhdGl2ZVBhdGgpO1xuICAgICAgY29uc3QgY2Fub25pY2FsVGFyZ2V0ID0gYXdhaXQgYXNzZXJ0Q2Fub25pY2FsUGF0aChjYW5vbmljYWxSb290LCB0YXJnZXQsIHJlbGF0aXZlUGF0aCk7XG4gICAgICBsZXQgaGFuZGxlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8g7LWc7KKFIHN5bWxpbmvrpbwg65Sw65286rCA7KeAIOyViuydgCBkZXNjcmlwdG9y66W8IOyXsCDrkqQg7Iuk7KCcIOqyveuhnOulvCDri6Tsi5wg7ZmV7J247ZWp64uI64ukLlxuICAgICAgICBoYW5kbGUgPSBhd2FpdCBmcy5vcGVuKHRhcmdldCwgY29uc3RhbnRzLk9fUkRPTkxZIHwgY29uc3RhbnRzLk9fTk9GT0xMT1cpO1xuICAgICAgICBjb25zdCByZWNoZWNrZWRUYXJnZXQgPSBhd2FpdCBhc3NlcnRDYW5vbmljYWxQYXRoKGNhbm9uaWNhbFJvb3QsIHRhcmdldCwgcmVsYXRpdmVQYXRoKTtcbiAgICAgICAgaWYgKHJlY2hlY2tlZFRhcmdldCAhPT0gY2Fub25pY2FsVGFyZ2V0KSB0aHJvdyBpbnZhbGlkQ2RkUGF0aChyZWxhdGl2ZVBhdGgpO1xuICAgICAgICByZXR1cm4gYXdhaXQgaGFuZGxlLnJlYWRGaWxlKFwidXRmOFwiKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIFNBRkVUWTogbm9kZTpmcyBvcGVuIOyLpO2MqOydmCBjb2Rl66eMIOydveyWtCBzeW1saW5rIOqxsOu2gOulvCDsoJXqt5ztmZTtlanri4jri6QuXG4gICAgICAgIGlmICgoZXJyb3IgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlID09PSBcIkVMT09QXCIpIHtcbiAgICAgICAgICB0aHJvdyBpbnZhbGlkQ2RkUGF0aChyZWxhdGl2ZVBhdGgsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGhhbmRsZT8uY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgd3JpdGUocmVsYXRpdmVQYXRoOiBzdHJpbmcsIGNvbnRlbnRzOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IHsgY2Fub25pY2FsUm9vdCwgdGFyZ2V0IH0gPSBhd2FpdCByZXNvbHZlQm91bmRhcnkocmVsYXRpdmVQYXRoKTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgbmVhcmVzdEV4aXN0aW5nUGF0aChmcywgdGFyZ2V0KTtcbiAgICAgIGNvbnN0IGNhbm9uaWNhbEV4aXN0aW5nID0gYXdhaXQgYXNzZXJ0Q2Fub25pY2FsUGF0aChjYW5vbmljYWxSb290LCBleGlzdGluZywgcmVsYXRpdmVQYXRoKTtcbiAgICAgIGNvbnN0IHRhcmdldEV4aXN0cyA9IGV4aXN0aW5nID09PSB0YXJnZXQ7XG5cbiAgICAgIGlmICghdGFyZ2V0RXhpc3RzKSB7XG4gICAgICAgIGF3YWl0IGZzLm1rZGlyKHBhdGguZGlybmFtZSh0YXJnZXQpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgYXdhaXQgYXNzZXJ0Q2Fub25pY2FsUGF0aChjYW5vbmljYWxSb290LCBwYXRoLmRpcm5hbWUodGFyZ2V0KSwgcmVsYXRpdmVQYXRoKTtcbiAgICAgIH1cblxuICAgICAgbGV0IGhhbmRsZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIOqygOymnSDsoIQgdHJ1bmNhdGXrpbwg7ZS87ZWY6rOgIOyDiCDtjIzsnbzsnYAg67Cw7YOA7KCB7Jy866GcIOyDneyEse2VqeuLiOuLpC5cbiAgICAgICAgY29uc3QgZmxhZ3MgPSB0YXJnZXRFeGlzdHNcbiAgICAgICAgICA/IGNvbnN0YW50cy5PX1dST05MWSB8IGNvbnN0YW50cy5PX05PRk9MTE9XXG4gICAgICAgICAgOiBjb25zdGFudHMuT19XUk9OTFkgfCBjb25zdGFudHMuT19DUkVBVCB8IGNvbnN0YW50cy5PX0VYQ0wgfCBjb25zdGFudHMuT19OT0ZPTExPVztcbiAgICAgICAgaGFuZGxlID0gYXdhaXQgZnMub3Blbih0YXJnZXQsIGZsYWdzLCAwbzY2Nik7XG4gICAgICAgIGNvbnN0IGNhbm9uaWNhbFRhcmdldCA9IGF3YWl0IGFzc2VydENhbm9uaWNhbFBhdGgoY2Fub25pY2FsUm9vdCwgdGFyZ2V0LCByZWxhdGl2ZVBhdGgpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWlzV2l0aGluKGNhbm9uaWNhbFJvb3QsIGNhbm9uaWNhbFRhcmdldCkgfHxcbiAgICAgICAgICAodGFyZ2V0RXhpc3RzICYmIGNhbm9uaWNhbFRhcmdldCAhPT0gY2Fub25pY2FsRXhpc3RpbmcpXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IGludmFsaWRDZGRQYXRoKHJlbGF0aXZlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgaGFuZGxlLnRydW5jYXRlKDApO1xuICAgICAgICBhd2FpdCBoYW5kbGUud3JpdGVGaWxlKGNvbnRlbnRzLCBcInV0ZjhcIik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBTQUZFVFk6IG5vZGU6ZnMgb3BlbiDsi6TtjKjsnZggY29kZeunjCDsnb3slrQgc3ltbGluayDqsbDrtoDrpbwg7KCV6rec7ZmU7ZWp64uI64ukLlxuICAgICAgICBpZiAoKGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gXCJFTE9PUFwiKSB7XG4gICAgICAgICAgdGhyb3cgaW52YWxpZENkZFBhdGgocmVsYXRpdmVQYXRoLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBoYW5kbGU/LmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxudHlwZSBDZGRSdWxlRG9jdW1lbnQgPSB7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBydWxlcz86IEFycmF5PHsgaWQ6IHN0cmluZzsgd2hlbjogc3RyaW5nOyBpbnN0cnVjdGlvbjogc3RyaW5nOyBleGFtcGxlcz86IHN0cmluZ1tdIH0+O1xufTtcblxuZnVuY3Rpb24gcGFyc2VDZGRSdWxlcyhjb250ZW50czogc3RyaW5nKTogQ2RkUnVsZURvY3VtZW50IHtcbiAgdHJ5IHtcbiAgICAvLyBTQUZFVFk6IENERCDqt5zsuZkg7IaM67mEIOyngOygkOydgCDshKDtg50g7ZWE65Oc66eMIOydveqzoCDrsLDsl7Qg67aA7J6s66W8IOq4sOuzuOqwkuycvOuhnCDsspjrpqztlanri4jri6QuXG4gICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudHMpIGFzIENkZFJ1bGVEb2N1bWVudDtcbiAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICB0aHJvdyBPYmplY3QuYXNzaWduKG5ldyBFcnJvcihcIkNERCBydWxlcyBKU09OIGlzIG1hbGZvcm1lZFwiKSwge1xuICAgICAgY29kZTogXCJJTlZBTElEX0NERF9SVUxFU1wiLFxuICAgICAgZXhpdENvZGU6IDIsXG4gICAgICBjYXVzZSxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIOq3nOy5mSDrrLjshJzrpbwg7J2965CYLCDslYTsp4Eg7YyM7J287J20IOyXhuycvOuptCDruYgg66y47ISc66GcIOy3qOq4ie2VqeuLiOuLpC5cbiAqXG4gKiDssqsg6rec7LmZIOuTseuhnSDsi5wgcnVsZXMg65SU66CJ7YSw66as7JmAIO2MjOydvOydtCDsl4bripQg7IOB7YOc66W8IOu2gO2KuOyKpO2KuOueqe2VmOq4sCDsnITtlZwg7LKY66as7J2066mwLFxuICog6rmo7KeEIEpTT07snYAg6re464yA66GcIElOVkFMSURfQ0REX1JVTEVT66GcIOyLpO2MqOyLnOy8nCDrja7slrTsk7DquLDrpbwg66eJ7Iq164uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiByZWFkQ2RkUnVsZURvY3VtZW50KFxuICBmaWxlczogeyByZWFkKHJlbGF0aXZlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IH0sXG4gIHJlbGF0aXZlUGF0aDogc3RyaW5nLFxuKTogUHJvbWlzZTxDZGRSdWxlRG9jdW1lbnQ+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcGFyc2VDZGRSdWxlcyhhd2FpdCBmaWxlcy5yZWFkKHJlbGF0aXZlUGF0aCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vIFNBRkVUWTogbm9kZTpmcyDsnb3quLAg7Iuk7Yyo7J2YIGNvZGXrp4wg7J297Ja0IOq3nOy5mSDrrLjshJwg67aA7J6s66W8IOq1rOu2hO2VqeuLiOuLpC5cbiAgICBpZiAoKGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gXCJFTk9FTlRcIikgcmV0dXJuIHt9O1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEZWZhdWx0Q2RkVG9vbGluZ0FkYXB0ZXIoe1xuICBjb250cmFjdFJvb3QsXG4gIGZzID0gZGVmYXVsdEZzLFxufToge1xuICBjb250cmFjdFJvb3Q6IHN0cmluZztcbiAgZnM/OiBDZGRGaWxlU3lzdGVtO1xufSkge1xuICBjb25zdCBmaWxlcyA9IGNyZWF0ZUNkZEZpbGVPcGVyYXRpb24oeyBjb250cmFjdFJvb3QsIGZzIH0pO1xuXG4gIHJldHVybiB7XG4gICAgYXN5bmMgcmVhZChpbnB1dDogeyBwYXRoOiBzdHJpbmcgfSkge1xuICAgICAgcmV0dXJuIHsgY29udGVudDogYXdhaXQgZmlsZXMucmVhZChpbnB1dC5wYXRoKSwgZmlsZVR5cGU6IFwiY29udHJhY3RcIiBhcyBjb25zdCB9O1xuICAgIH0sXG4gICAgYXN5bmMgcnVsZXMoKSB7XG4gICAgICBsZXQgZW50cmllcztcbiAgICAgIHRyeSB7XG4gICAgICAgIGVudHJpZXMgPSBhd2FpdCBmaWxlcy5yZWFkRGlyZWN0b3J5KFwicnVsZXNcIik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBTQUZFVFk6IG5vZGU6ZnMg65SU66CJ7YSw66asIOyhsO2ajCDsi6TtjKjsnZggY29kZeunjCDsnb3slrQg6rec7LmZIOuUlOugie2EsOumrCDrtoDsnqzrpbwg6rWs67aE7ZWp64uI64ukLlxuICAgICAgICBpZiAoKGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gXCJFTk9FTlRcIikgcmV0dXJuIHsgcnVsZXM6IFtdIH07XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBydWxlcyA9IFtdO1xuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgIGlmICghZW50cnkuaXNGaWxlKCkgfHwgIWVudHJ5Lm5hbWUuZW5kc1dpdGgoXCIucnVsZXMuanNvblwiKSkgY29udGludWU7XG4gICAgICAgIGNvbnN0IGtleSA9IGVudHJ5Lm5hbWUucmVwbGFjZSgvXFwucnVsZXNcXC5qc29uJC8sIFwiXCIpO1xuICAgICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBgcnVsZXMvJHtlbnRyeS5uYW1lfWA7XG4gICAgICAgIGNvbnN0IGRvY3VtZW50ID0gcGFyc2VDZGRSdWxlcyhhd2FpdCBmaWxlcy5yZWFkKHJlbGF0aXZlUGF0aCkpO1xuICAgICAgICBydWxlcy5wdXNoKHtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgcGF0aDogcmVsYXRpdmVQYXRoLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBkb2N1bWVudC5kZXNjcmlwdGlvbiA/PyBcIlwiLFxuICAgICAgICAgIHJ1bGVDb3VudDogZG9jdW1lbnQucnVsZXM/Lmxlbmd0aCA/PyAwLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IHJ1bGVzIH07XG4gICAgfSxcbiAgICBhc3luYyBzaG93UnVsZShpbnB1dDogeyBydWxlSWQ6IHN0cmluZyB9KSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBgcnVsZXMvJHtpbnB1dC5ydWxlSWR9LnJ1bGVzLmpzb25gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2V5OiBpbnB1dC5ydWxlSWQsXG4gICAgICAgIHBhdGg6IHJlbGF0aXZlUGF0aCxcbiAgICAgICAgLi4ucGFyc2VDZGRSdWxlcyhhd2FpdCBmaWxlcy5yZWFkKHJlbGF0aXZlUGF0aCkpLFxuICAgICAgfTtcbiAgICB9LFxuICAgIGFzeW5jIGFkZFJ1bGUoaW5wdXQ6IHtcbiAgICAgIHJ1bGVLZXk6IHN0cmluZztcbiAgICAgIGlkOiBzdHJpbmc7XG4gICAgICB3aGVuOiBzdHJpbmc7XG4gICAgICB0ZXh0OiBzdHJpbmc7XG4gICAgICBleGFtcGxlcz86IHN0cmluZ1tdO1xuICAgICAgZHJ5UnVuOiBib29sZWFuO1xuICAgIH0pIHtcbiAgICAgIGNvbnN0IHJ1bGUgPSB7IHJ1bGVLZXk6IGlucHV0LnJ1bGVLZXksIGlkOiBpbnB1dC5pZCwgd2hlbjogaW5wdXQud2hlbiwgdGV4dDogaW5wdXQudGV4dCB9O1xuICAgICAgaWYgKGlucHV0LmRyeVJ1bikgcmV0dXJuIHsgZHJ5UnVuOiB0cnVlIGFzIGNvbnN0LCBydWxlIH07XG5cbiAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGBydWxlcy8ke2lucHV0LnJ1bGVLZXl9LnJ1bGVzLmpzb25gO1xuICAgICAgY29uc3QgZG9jdW1lbnQgPSBhd2FpdCByZWFkQ2RkUnVsZURvY3VtZW50KGZpbGVzLCByZWxhdGl2ZVBhdGgpO1xuICAgICAgZG9jdW1lbnQucnVsZXMgPz89IFtdO1xuICAgICAgZG9jdW1lbnQucnVsZXMucHVzaCh7XG4gICAgICAgIGlkOiBpbnB1dC5pZCxcbiAgICAgICAgd2hlbjogaW5wdXQud2hlbixcbiAgICAgICAgaW5zdHJ1Y3Rpb246IGlucHV0LnRleHQsXG4gICAgICAgIGV4YW1wbGVzOiBpbnB1dC5leGFtcGxlcyA/PyBbXSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgZmlsZXMud3JpdGUocmVsYXRpdmVQYXRoLCBgJHtKU09OLnN0cmluZ2lmeShkb2N1bWVudCwgbnVsbCwgMil9XFxuYCk7XG4gICAgICByZXR1cm4geyBrZXk6IGlucHV0LnJ1bGVLZXksIHBhdGg6IHJlbGF0aXZlUGF0aCwgLi4uZG9jdW1lbnQgfTtcbiAgICB9LFxuICAgIGFzeW5jIGFkZEFjY2VwdGFuY2VDcml0ZXJpb24oaW5wdXQ6IHsgZG9jdW1lbnQ6IHN0cmluZzsgdGV4dDogc3RyaW5nOyBkcnlSdW46IGJvb2xlYW4gfSkge1xuICAgICAgaWYgKGlucHV0LmRyeVJ1bilcbiAgICAgICAgcmV0dXJuIHsgb3BlcmF0aW9uOiBcImFkZEFjY2VwdGFuY2VDcml0ZXJpb25cIiBhcyBjb25zdCwgaW5wdXQsIGRyeVJ1bjogdHJ1ZSB9O1xuICAgICAgY29uc3QgY29udGVudHMgPSBhd2FpdCBmaWxlcy5yZWFkKGlucHV0LmRvY3VtZW50KTtcbiAgICAgIGF3YWl0IGZpbGVzLndyaXRlKGlucHV0LmRvY3VtZW50LCBgJHtjb250ZW50c31cXG4tICR7aW5wdXQudGV4dH1cXG5gKTtcbiAgICAgIHJldHVybiB7IGRvY3VtZW50OiBpbnB1dC5kb2N1bWVudCwgdGV4dDogaW5wdXQudGV4dCwgYXBwbGllZDogdHJ1ZSBhcyBjb25zdCB9O1xuICAgIH0sXG4gIH07XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7QUFNQSxTQUFTLGVBQWUsY0FBc0IsT0FBd0I7Q0FDcEUsT0FBTyxPQUFPLHVCQUFPLElB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
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const jsonValueSchema: z.ZodJSONSchema;
|
|
3
|
+
type CommandValue = z.infer<typeof jsonValueSchema> | undefined;
|
|
4
|
+
type CommandInput = Record<string, CommandValue>;
|
|
5
|
+
type ToolingResult = object | string | number | boolean | null | void | AsyncIterable<object>;
|
|
6
|
+
type ToolingOperation = (input: CommandInput) => ToolingResult | Promise<ToolingResult>;
|
|
7
|
+
type ToolingGroup = Record<string, ToolingOperation>;
|
|
8
|
+
export type CliToolingOperations = Record<string, ToolingGroup>;
|
|
9
|
+
export declare const tooling: CliToolingOperations;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=cli-tooling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-tooling.d.ts","sourceRoot":"","sources":["../../src/tooling/cli-tooling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,eAAe,iBAAW,CAAC;AACjC,KAAK,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,GAAG,SAAS,CAAC;AAChE,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACjD,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAC9F,KAAK,gBAAgB,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;AACxF,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AACrD,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AA+4BhE,eAAO,MAAM,OAAO,EAAE,oBAUrB,CAAC"}
|