@dereekb/dbx-cli 13.11.17 → 13.12.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/firebase-api-manifest/main.js +70 -9
- package/firebase-api-manifest/package.json +1 -1
- package/firestore-indexes/src/firestore-indexes-generate.d.ts +125 -0
- package/firestore-indexes/src/firestore-model-identity-resolver.d.ts +93 -0
- package/firestore-indexes/src/firestore-query-helpers.d.ts +108 -0
- package/firestore-indexes/src/generate-firestore-indexes-cli.d.ts +94 -0
- package/firestore-indexes/src/index.d.ts +7 -0
- package/firestore-indexes/src/model-firebase-index-analyze.d.ts +68 -0
- package/firestore-indexes/src/model-firebase-index-build-manifest.d.ts +123 -0
- package/firestore-indexes/src/model-firebase-index-extract.d.ts +246 -0
- package/firestore-indexes/src/model-firebase-index-runtime.d.ts +126 -0
- package/firestore-indexes/src/model-firebase-index-scan-config-schema.d.ts +58 -0
- package/firestore-indexes/src/model-firebase-index-schema.d.ts +366 -0
- package/generate-firestore-indexes/main.js +1 -1
- package/generate-firestore-indexes/package.json +1 -1
- package/generate-mcp-manifest/src/generate-mcp-manifest/main.d.ts +26 -0
- package/generate-mcp-manifest/src/generate-mcp-manifest/render.d.ts +38 -0
- package/generated/firebase-models.generated.d.ts +3 -0
- package/index.cjs.js +45234 -640
- package/index.esm.js +44941 -643
- package/lint-cache/main.js +19 -19
- package/lint-cache/package.json +2 -2
- package/manifest-extract/index.cjs.js +169 -4
- package/manifest-extract/index.esm.js +169 -4
- package/manifest-extract/package.json +1 -1
- package/manifest-extract/src/lib/types.d.ts +26 -1
- package/package.json +14 -10
- package/src/lib/index.d.ts +3 -0
- package/src/lib/manifest/types.d.ts +155 -0
- package/src/lib/mcp-scan/config/config-schema.d.ts +226 -0
- package/src/lib/mcp-scan/config/load-config.d.ts +63 -0
- package/src/lib/mcp-scan/index.d.ts +16 -0
- package/src/lib/mcp-scan/manifest/actions-loader.d.ts +49 -0
- package/src/lib/mcp-scan/manifest/actions-schema.d.ts +328 -0
- package/src/lib/mcp-scan/manifest/core-topics.d.ts +38 -0
- package/src/lib/mcp-scan/manifest/css-utilities-loader.d.ts +55 -0
- package/src/lib/mcp-scan/manifest/css-utilities-schema.d.ts +168 -0
- package/src/lib/mcp-scan/manifest/dbx-docs-ui-examples-loader.d.ts +33 -0
- package/src/lib/mcp-scan/manifest/dbx-docs-ui-examples-schema.d.ts +133 -0
- package/src/lib/mcp-scan/manifest/filters-loader.d.ts +61 -0
- package/src/lib/mcp-scan/manifest/filters-schema.d.ts +190 -0
- package/src/lib/mcp-scan/manifest/forge-fields-loader.d.ts +53 -0
- package/src/lib/mcp-scan/manifest/forge-fields-schema.d.ts +170 -0
- package/src/lib/mcp-scan/manifest/index.d.ts +43 -0
- package/src/lib/mcp-scan/manifest/load-actions-registry.d.ts +38 -0
- package/src/lib/mcp-scan/manifest/load-auth-registry.d.ts +82 -0
- package/src/lib/mcp-scan/manifest/load-css-utilities-registry.d.ts +67 -0
- package/src/lib/mcp-scan/manifest/load-dbx-docs-ui-examples-registry.d.ts +45 -0
- package/src/lib/mcp-scan/manifest/load-filters-registry.d.ts +69 -0
- package/src/lib/mcp-scan/manifest/load-forge-fields-registry.d.ts +70 -0
- package/src/lib/mcp-scan/manifest/load-model-firebase-index-registry.d.ts +61 -0
- package/src/lib/mcp-scan/manifest/load-model-snapshot-fields-registry.d.ts +74 -0
- package/src/lib/mcp-scan/manifest/load-pipes-registry.d.ts +69 -0
- package/src/lib/mcp-scan/manifest/load-registry.d.ts +76 -0
- package/src/lib/mcp-scan/manifest/load-tokens-registry.d.ts +69 -0
- package/src/lib/mcp-scan/manifest/load-ui-components-registry.d.ts +70 -0
- package/src/lib/mcp-scan/manifest/load-utils-registry.d.ts +73 -0
- package/src/lib/mcp-scan/manifest/loader.d.ts +120 -0
- package/src/lib/mcp-scan/manifest/manifest-loader-base.d.ts +130 -0
- package/src/lib/mcp-scan/manifest/model-firebase-index-loader.d.ts +53 -0
- package/src/lib/mcp-scan/manifest/model-snapshot-fields-loader.d.ts +54 -0
- package/src/lib/mcp-scan/manifest/model-snapshot-fields-schema.d.ts +127 -0
- package/src/lib/mcp-scan/manifest/pipes-loader.d.ts +54 -0
- package/src/lib/mcp-scan/manifest/pipes-schema.d.ts +125 -0
- package/src/lib/mcp-scan/manifest/semantic-types-schema.d.ts +108 -0
- package/src/lib/mcp-scan/manifest/tokens-loader.d.ts +55 -0
- package/src/lib/mcp-scan/manifest/tokens-schema.d.ts +116 -0
- package/src/lib/mcp-scan/manifest/ui-components-loader.d.ts +54 -0
- package/src/lib/mcp-scan/manifest/ui-components-schema.d.ts +149 -0
- package/src/lib/mcp-scan/manifest/utils-loader.d.ts +54 -0
- package/src/lib/mcp-scan/manifest/utils-schema.d.ts +120 -0
- package/src/lib/mcp-scan/registry/actions-runtime.d.ts +173 -0
- package/src/lib/mcp-scan/registry/archetypes.d.ts +235 -0
- package/src/lib/mcp-scan/registry/auth-builtin.d.ts +59 -0
- package/src/lib/mcp-scan/registry/auth-runtime.d.ts +343 -0
- package/src/lib/mcp-scan/registry/css-utilities-runtime.d.ts +133 -0
- package/src/lib/mcp-scan/registry/dbx-docs-ui-examples-runtime.d.ts +58 -0
- package/src/lib/mcp-scan/registry/downstream-models-runtime.d.ts +93 -0
- package/src/lib/mcp-scan/registry/filters-runtime.d.ts +128 -0
- package/src/lib/mcp-scan/registry/firebase-models.d.ts +387 -0
- package/src/lib/mcp-scan/registry/forge-fields.d.ts +101 -0
- package/src/lib/mcp-scan/registry/form-fields.d.ts +203 -0
- package/src/lib/mcp-scan/registry/index.d.ts +165 -0
- package/src/lib/mcp-scan/registry/model-snapshot-fields-runtime.d.ts +138 -0
- package/src/lib/mcp-scan/registry/pipes-runtime.d.ts +136 -0
- package/src/lib/mcp-scan/registry/reserved-model-folders.d.ts +29 -0
- package/src/lib/mcp-scan/registry/semantic-types.d.ts +81 -0
- package/src/lib/mcp-scan/registry/tokens-runtime.d.ts +96 -0
- package/src/lib/mcp-scan/registry/ui-components-runtime.d.ts +90 -0
- package/src/lib/mcp-scan/registry/utils-runtime.d.ts +136 -0
- package/src/lib/mcp-scan/scan/_jsdoc-tagged-export/extract-base.d.ts +245 -0
- package/src/lib/mcp-scan/scan/actions-build-manifest.d.ts +58 -0
- package/src/lib/mcp-scan/scan/actions-cli.d.ts +38 -0
- package/src/lib/mcp-scan/scan/actions-extract.d.ts +99 -0
- package/src/lib/mcp-scan/scan/actions-scan-config-schema.d.ts +42 -0
- package/src/lib/mcp-scan/scan/auth-extract.d.ts +120 -0
- package/src/lib/mcp-scan/scan/build-manifest.d.ts +76 -0
- package/src/lib/mcp-scan/scan/cli.d.ts +60 -0
- package/src/lib/mcp-scan/scan/css-utilities-build-manifest.d.ts +76 -0
- package/src/lib/mcp-scan/scan/css-utilities-cli.d.ts +36 -0
- package/src/lib/mcp-scan/scan/css-utilities-extract.d.ts +187 -0
- package/src/lib/mcp-scan/scan/css-utilities-scan-config-schema.d.ts +57 -0
- package/src/lib/mcp-scan/scan/dbx-docs-ui-examples-build-manifest.d.ts +68 -0
- package/src/lib/mcp-scan/scan/dbx-docs-ui-examples-cli.d.ts +20 -0
- package/src/lib/mcp-scan/scan/dbx-docs-ui-examples-extract.d.ts +160 -0
- package/src/lib/mcp-scan/scan/dbx-docs-ui-examples-scan-config-schema.d.ts +56 -0
- package/src/lib/mcp-scan/scan/discover-downstream-packages.d.ts +76 -0
- package/src/lib/mcp-scan/scan/discover-firebase-packages.d.ts +58 -0
- package/src/lib/mcp-scan/scan/extract-models/assemble.d.ts +105 -0
- package/src/lib/mcp-scan/scan/extract-models/collect-inherited.d.ts +22 -0
- package/src/lib/mcp-scan/scan/extract-models/find-converters.d.ts +19 -0
- package/src/lib/mcp-scan/scan/extract-models/find-enums.d.ts +19 -0
- package/src/lib/mcp-scan/scan/extract-models/find-identities.d.ts +25 -0
- package/src/lib/mcp-scan/scan/extract-models/find-interfaces.d.ts +31 -0
- package/src/lib/mcp-scan/scan/extract-models/find-model-groups.d.ts +21 -0
- package/src/lib/mcp-scan/scan/extract-models/find-service-factories.d.ts +19 -0
- package/src/lib/mcp-scan/scan/extract-models/find-sub-object-consts.d.ts +20 -0
- package/src/lib/mcp-scan/scan/extract-models/index.d.ts +74 -0
- package/src/lib/mcp-scan/scan/extract-models/infer-collection-kind.d.ts +22 -0
- package/src/lib/mcp-scan/scan/extract-models/service-factory-constants.d.ts +6 -0
- package/src/lib/mcp-scan/scan/extract-models/types.d.ts +171 -0
- package/src/lib/mcp-scan/scan/extract.d.ts +82 -0
- package/src/lib/mcp-scan/scan/filters-build-manifest.d.ts +78 -0
- package/src/lib/mcp-scan/scan/filters-cli.d.ts +37 -0
- package/src/lib/mcp-scan/scan/filters-extract.d.ts +101 -0
- package/src/lib/mcp-scan/scan/filters-scan-config-schema.d.ts +56 -0
- package/src/lib/mcp-scan/scan/forge-fields-build-manifest.d.ts +78 -0
- package/src/lib/mcp-scan/scan/forge-fields-cli.d.ts +37 -0
- package/src/lib/mcp-scan/scan/forge-fields-extract.d.ts +165 -0
- package/src/lib/mcp-scan/scan/forge-fields-scan-config-schema.d.ts +61 -0
- package/src/lib/mcp-scan/scan/index.d.ts +60 -0
- package/src/lib/mcp-scan/scan/model-firebase-index-cli.d.ts +22 -0
- package/src/lib/mcp-scan/scan/model-firebase-index-dispatcher-credit.d.ts +47 -0
- package/src/lib/mcp-scan/scan/model-firebase-index-reference-scan.d.ts +100 -0
- package/src/lib/mcp-scan/scan/model-snapshot-fields-build-manifest.d.ts +79 -0
- package/src/lib/mcp-scan/scan/model-snapshot-fields-cli.d.ts +37 -0
- package/src/lib/mcp-scan/scan/model-snapshot-fields-extract.d.ts +115 -0
- package/src/lib/mcp-scan/scan/model-snapshot-fields-scan-config-schema.d.ts +59 -0
- package/src/lib/mcp-scan/scan/pipes-build-manifest.d.ts +78 -0
- package/src/lib/mcp-scan/scan/pipes-cli.d.ts +37 -0
- package/src/lib/mcp-scan/scan/pipes-extract.d.ts +90 -0
- package/src/lib/mcp-scan/scan/pipes-scan-config-schema.d.ts +56 -0
- package/src/lib/mcp-scan/scan/scan-angular-io.d.ts +89 -0
- package/src/lib/mcp-scan/scan/scan-cli-base.d.ts +162 -0
- package/src/lib/mcp-scan/scan/scan-config-schema.d.ts +44 -0
- package/src/lib/mcp-scan/scan/ui-components-build-manifest.d.ts +78 -0
- package/src/lib/mcp-scan/scan/ui-components-cli.d.ts +37 -0
- package/src/lib/mcp-scan/scan/ui-components-extract.d.ts +124 -0
- package/src/lib/mcp-scan/scan/ui-components-scan-config-schema.d.ts +62 -0
- package/src/lib/mcp-scan/scan/utils-build-manifest.d.ts +78 -0
- package/src/lib/mcp-scan/scan/utils-cli.d.ts +37 -0
- package/src/lib/mcp-scan/scan/utils-extract.d.ts +103 -0
- package/src/lib/mcp-scan/scan/utils-scan-config-schema.d.ts +57 -0
- package/test/package.json +9 -9
- package/index.cjs.default.js +0 -1
- package/index.cjs.mjs +0 -2
package/lint-cache/main.js
CHANGED
|
@@ -495,30 +495,30 @@ function runQuery(cachePath, filters) {
|
|
|
495
495
|
throw new Error(`lint cache not found: ${cachePath} \u2014 run \`build\` first`);
|
|
496
496
|
}
|
|
497
497
|
const cache = JSON.parse(readFileSync4(cachePath, "utf8"));
|
|
498
|
-
const
|
|
499
|
-
const
|
|
500
|
-
const fileMatcher = fileNeedle && isGlobPattern(fileNeedle) ? globToRegExp2(fileNeedle) : null;
|
|
501
|
-
const messageNeedle = filters.message && filters.message.length > 0 ? filters.message.toLowerCase() : null;
|
|
502
|
-
const severity = filters.severity;
|
|
503
|
-
const matched = [];
|
|
504
|
-
for (const m of cache.messages) {
|
|
505
|
-
if (ruleSet && (m.ruleId == null || !ruleSet.has(m.ruleId))) continue;
|
|
506
|
-
if (severity && m.severity !== severity) continue;
|
|
507
|
-
if (fileNeedle) {
|
|
508
|
-
if (fileMatcher) {
|
|
509
|
-
if (!fileMatcher.test(m.filePath)) continue;
|
|
510
|
-
} else if (!m.filePath.includes(fileNeedle)) {
|
|
511
|
-
continue;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
if (messageNeedle && !m.message.toLowerCase().includes(messageNeedle)) continue;
|
|
515
|
-
matched.push(m);
|
|
516
|
-
}
|
|
498
|
+
const compiled = compileFilters(filters);
|
|
499
|
+
const matched = cache.messages.filter((m) => matchesFilters(m, compiled));
|
|
517
500
|
const totalMatched = matched.length;
|
|
518
501
|
const truncated = filters.limit != null && totalMatched > filters.limit;
|
|
519
502
|
const limited = filters.limit == null ? matched : matched.slice(0, filters.limit);
|
|
520
503
|
return { cache, matched: limited, totalMatched, truncated };
|
|
521
504
|
}
|
|
505
|
+
function compileFilters(filters) {
|
|
506
|
+
const ruleSet = filters.rule && filters.rule.length > 0 ? new Set(filters.rule) : null;
|
|
507
|
+
const fileNeedle = filters.file && filters.file.length > 0 ? filters.file : null;
|
|
508
|
+
const fileMatcher = fileNeedle && isGlobPattern(fileNeedle) ? globToRegExp2(fileNeedle) : null;
|
|
509
|
+
const messageNeedle = filters.message && filters.message.length > 0 ? filters.message.toLowerCase() : null;
|
|
510
|
+
return { ruleSet, severity: filters.severity ?? void 0, fileNeedle, fileMatcher, messageNeedle };
|
|
511
|
+
}
|
|
512
|
+
function matchesFilters(m, c) {
|
|
513
|
+
if (c.ruleSet && (m.ruleId == null || !c.ruleSet.has(m.ruleId))) return false;
|
|
514
|
+
if (c.severity && m.severity !== c.severity) return false;
|
|
515
|
+
if (c.fileNeedle && !matchesFile(m.filePath, c.fileNeedle, c.fileMatcher)) return false;
|
|
516
|
+
if (c.messageNeedle && !m.message.toLowerCase().includes(c.messageNeedle)) return false;
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
function matchesFile(filePath, needle, matcher) {
|
|
520
|
+
return matcher ? matcher.test(filePath) : filePath.includes(needle);
|
|
521
|
+
}
|
|
522
522
|
function isGlobPattern(s) {
|
|
523
523
|
return s.includes("*") || s.includes("?");
|
|
524
524
|
}
|
package/lint-cache/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli-lint-cache",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.12.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"devDependencies": {
|
|
7
|
-
"@dereekb/util": "13.
|
|
7
|
+
"@dereekb/util": "13.12.0",
|
|
8
8
|
"eslint": "10.4.0",
|
|
9
9
|
"yargs": "^18.0.0",
|
|
10
10
|
"@types/yargs": "^17.0.35"
|
|
@@ -7,7 +7,8 @@ var SUPPORTED_VERBS = new Set([
|
|
|
7
7
|
'read',
|
|
8
8
|
'update',
|
|
9
9
|
'delete',
|
|
10
|
-
'query'
|
|
10
|
+
'query',
|
|
11
|
+
'invoke'
|
|
11
12
|
]);
|
|
12
13
|
/**
|
|
13
14
|
* Walks a `<model>.api.ts` source and returns one {@link CrudEntry} per
|
|
@@ -500,6 +501,14 @@ function _object_spread(target) {
|
|
|
500
501
|
}
|
|
501
502
|
return target;
|
|
502
503
|
}
|
|
504
|
+
var READ_LEVEL_VALUES = new Set([
|
|
505
|
+
'system',
|
|
506
|
+
'owner',
|
|
507
|
+
'admin-only',
|
|
508
|
+
'permissions'
|
|
509
|
+
]);
|
|
510
|
+
var SERVICE_FACTORY_TAG = 'dbxModelServiceFactory';
|
|
511
|
+
var MODEL_TYPE_VALUE_PATTERN = /^[a-z][A-Za-z0-9_$]*$/;
|
|
503
512
|
/**
|
|
504
513
|
* TS utility/structural wrappers that don't change the field surface for
|
|
505
514
|
* inheritance walks — `Partial<T>`, `Required<T>`, `Readonly<T>`,
|
|
@@ -552,12 +561,14 @@ var OBJECT_FIELD_KEY = 'objectField';
|
|
|
552
561
|
var converters = readConverters(sourceFile);
|
|
553
562
|
var enums = readEnums(sourceFile);
|
|
554
563
|
var modelGroups = readModelGroups(sourceFile);
|
|
564
|
+
var serviceFactories = readServiceFactories(sourceFile);
|
|
555
565
|
return {
|
|
556
566
|
identities: identities,
|
|
557
567
|
interfaces: interfaces,
|
|
558
568
|
converters: converters,
|
|
559
569
|
enums: enums,
|
|
560
|
-
modelGroups: modelGroups
|
|
570
|
+
modelGroups: modelGroups,
|
|
571
|
+
serviceFactories: serviceFactories
|
|
561
572
|
};
|
|
562
573
|
}
|
|
563
574
|
function readIdentities(sourceFile) {
|
|
@@ -682,6 +693,7 @@ function readInterfaces(sourceFile) {
|
|
|
682
693
|
function buildInterface(decl) {
|
|
683
694
|
var jsDocs = decl.getJsDocs();
|
|
684
695
|
var hasDbxModelTag = jsDocsHaveTag(jsDocs, 'dbxModel');
|
|
696
|
+
var dbxModelRead = readDbxModelReadTag(jsDocs);
|
|
685
697
|
var extendsNames = decl.getExtends().map(resolveExtendsName);
|
|
686
698
|
var props = [];
|
|
687
699
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
@@ -718,13 +730,166 @@ function buildInterface(decl) {
|
|
|
718
730
|
}
|
|
719
731
|
}
|
|
720
732
|
}
|
|
721
|
-
return {
|
|
733
|
+
return _object_spread({
|
|
722
734
|
name: decl.getName(),
|
|
723
735
|
description: readJsDocDescription(jsDocs),
|
|
724
736
|
hasDbxModelTag: hasDbxModelTag,
|
|
725
737
|
extendsNames: extendsNames,
|
|
726
738
|
props: props
|
|
727
|
-
}
|
|
739
|
+
}, dbxModelRead === undefined ? {} : {
|
|
740
|
+
dbxModelRead: dbxModelRead
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
function readDbxModelReadTag(jsDocs) {
|
|
744
|
+
var result;
|
|
745
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
746
|
+
try {
|
|
747
|
+
for(var _iterator = jsDocs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
748
|
+
var doc = _step.value;
|
|
749
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
750
|
+
try {
|
|
751
|
+
for(var _iterator1 = doc.getTags()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
752
|
+
var tag = _step1.value;
|
|
753
|
+
var _tag_getCommentText;
|
|
754
|
+
if (tag.getTagName() !== 'dbxModelRead') continue;
|
|
755
|
+
if (result !== undefined) continue;
|
|
756
|
+
var raw = (_tag_getCommentText = tag.getCommentText()) === null || _tag_getCommentText === void 0 ? void 0 : _tag_getCommentText.trim();
|
|
757
|
+
if (raw === undefined || raw.length === 0) continue;
|
|
758
|
+
var firstToken = raw.split(/\s+/)[0];
|
|
759
|
+
if (READ_LEVEL_VALUES.has(firstToken)) {
|
|
760
|
+
result = firstToken;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
} catch (err) {
|
|
764
|
+
_didIteratorError1 = true;
|
|
765
|
+
_iteratorError1 = err;
|
|
766
|
+
} finally{
|
|
767
|
+
try {
|
|
768
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
769
|
+
_iterator1.return();
|
|
770
|
+
}
|
|
771
|
+
} finally{
|
|
772
|
+
if (_didIteratorError1) {
|
|
773
|
+
throw _iteratorError1;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
} catch (err) {
|
|
779
|
+
_didIteratorError = true;
|
|
780
|
+
_iteratorError = err;
|
|
781
|
+
} finally{
|
|
782
|
+
try {
|
|
783
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
784
|
+
_iterator.return();
|
|
785
|
+
}
|
|
786
|
+
} finally{
|
|
787
|
+
if (_didIteratorError) {
|
|
788
|
+
throw _iteratorError;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return result;
|
|
793
|
+
}
|
|
794
|
+
function readServiceFactories(sourceFile) {
|
|
795
|
+
var out = [];
|
|
796
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
797
|
+
try {
|
|
798
|
+
for(var _iterator = sourceFile.getVariableStatements()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
799
|
+
var statement = _step.value;
|
|
800
|
+
if (!statement.isExported()) continue;
|
|
801
|
+
var modelType = readServiceFactoryModelType(statement.getJsDocs());
|
|
802
|
+
if (modelType === undefined) continue;
|
|
803
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
804
|
+
try {
|
|
805
|
+
for(var _iterator1 = statement.getDeclarations()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
806
|
+
var decl = _step1.value;
|
|
807
|
+
out.push({
|
|
808
|
+
modelType: modelType,
|
|
809
|
+
exportName: decl.getName()
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
} catch (err) {
|
|
813
|
+
_didIteratorError1 = true;
|
|
814
|
+
_iteratorError1 = err;
|
|
815
|
+
} finally{
|
|
816
|
+
try {
|
|
817
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
818
|
+
_iterator1.return();
|
|
819
|
+
}
|
|
820
|
+
} finally{
|
|
821
|
+
if (_didIteratorError1) {
|
|
822
|
+
throw _iteratorError1;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
} catch (err) {
|
|
828
|
+
_didIteratorError = true;
|
|
829
|
+
_iteratorError = err;
|
|
830
|
+
} finally{
|
|
831
|
+
try {
|
|
832
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
833
|
+
_iterator.return();
|
|
834
|
+
}
|
|
835
|
+
} finally{
|
|
836
|
+
if (_didIteratorError) {
|
|
837
|
+
throw _iteratorError;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return out;
|
|
842
|
+
}
|
|
843
|
+
function readServiceFactoryModelType(jsDocs) {
|
|
844
|
+
var result;
|
|
845
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
846
|
+
try {
|
|
847
|
+
for(var _iterator = jsDocs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
848
|
+
var doc = _step.value;
|
|
849
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
850
|
+
try {
|
|
851
|
+
for(var _iterator1 = doc.getTags()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
852
|
+
var tag = _step1.value;
|
|
853
|
+
var _tag_getCommentText;
|
|
854
|
+
if (tag.getTagName() !== SERVICE_FACTORY_TAG) continue;
|
|
855
|
+
if (result !== undefined) continue;
|
|
856
|
+
var raw = (_tag_getCommentText = tag.getCommentText()) === null || _tag_getCommentText === void 0 ? void 0 : _tag_getCommentText.trim();
|
|
857
|
+
if (raw === undefined || raw.length === 0) continue;
|
|
858
|
+
var firstToken = raw.split(/\s+/)[0];
|
|
859
|
+
if (MODEL_TYPE_VALUE_PATTERN.test(firstToken)) {
|
|
860
|
+
result = firstToken;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
} catch (err) {
|
|
864
|
+
_didIteratorError1 = true;
|
|
865
|
+
_iteratorError1 = err;
|
|
866
|
+
} finally{
|
|
867
|
+
try {
|
|
868
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
869
|
+
_iterator1.return();
|
|
870
|
+
}
|
|
871
|
+
} finally{
|
|
872
|
+
if (_didIteratorError1) {
|
|
873
|
+
throw _iteratorError1;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
} catch (err) {
|
|
879
|
+
_didIteratorError = true;
|
|
880
|
+
_iteratorError = err;
|
|
881
|
+
} finally{
|
|
882
|
+
try {
|
|
883
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
884
|
+
_iterator.return();
|
|
885
|
+
}
|
|
886
|
+
} finally{
|
|
887
|
+
if (_didIteratorError) {
|
|
888
|
+
throw _iteratorError;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
return result;
|
|
728
893
|
}
|
|
729
894
|
/**
|
|
730
895
|
* Resolves an `extends` clause to the concrete ancestor interface name,
|
|
@@ -5,7 +5,8 @@ var SUPPORTED_VERBS = new Set([
|
|
|
5
5
|
'read',
|
|
6
6
|
'update',
|
|
7
7
|
'delete',
|
|
8
|
-
'query'
|
|
8
|
+
'query',
|
|
9
|
+
'invoke'
|
|
9
10
|
]);
|
|
10
11
|
/**
|
|
11
12
|
* Walks a `<model>.api.ts` source and returns one {@link CrudEntry} per
|
|
@@ -498,6 +499,14 @@ function _object_spread(target) {
|
|
|
498
499
|
}
|
|
499
500
|
return target;
|
|
500
501
|
}
|
|
502
|
+
var READ_LEVEL_VALUES = new Set([
|
|
503
|
+
'system',
|
|
504
|
+
'owner',
|
|
505
|
+
'admin-only',
|
|
506
|
+
'permissions'
|
|
507
|
+
]);
|
|
508
|
+
var SERVICE_FACTORY_TAG = 'dbxModelServiceFactory';
|
|
509
|
+
var MODEL_TYPE_VALUE_PATTERN = /^[a-z][A-Za-z0-9_$]*$/;
|
|
501
510
|
/**
|
|
502
511
|
* TS utility/structural wrappers that don't change the field surface for
|
|
503
512
|
* inheritance walks — `Partial<T>`, `Required<T>`, `Readonly<T>`,
|
|
@@ -550,12 +559,14 @@ var OBJECT_FIELD_KEY = 'objectField';
|
|
|
550
559
|
var converters = readConverters(sourceFile);
|
|
551
560
|
var enums = readEnums(sourceFile);
|
|
552
561
|
var modelGroups = readModelGroups(sourceFile);
|
|
562
|
+
var serviceFactories = readServiceFactories(sourceFile);
|
|
553
563
|
return {
|
|
554
564
|
identities: identities,
|
|
555
565
|
interfaces: interfaces,
|
|
556
566
|
converters: converters,
|
|
557
567
|
enums: enums,
|
|
558
|
-
modelGroups: modelGroups
|
|
568
|
+
modelGroups: modelGroups,
|
|
569
|
+
serviceFactories: serviceFactories
|
|
559
570
|
};
|
|
560
571
|
}
|
|
561
572
|
function readIdentities(sourceFile) {
|
|
@@ -680,6 +691,7 @@ function readInterfaces(sourceFile) {
|
|
|
680
691
|
function buildInterface(decl) {
|
|
681
692
|
var jsDocs = decl.getJsDocs();
|
|
682
693
|
var hasDbxModelTag = jsDocsHaveTag(jsDocs, 'dbxModel');
|
|
694
|
+
var dbxModelRead = readDbxModelReadTag(jsDocs);
|
|
683
695
|
var extendsNames = decl.getExtends().map(resolveExtendsName);
|
|
684
696
|
var props = [];
|
|
685
697
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
@@ -716,13 +728,166 @@ function buildInterface(decl) {
|
|
|
716
728
|
}
|
|
717
729
|
}
|
|
718
730
|
}
|
|
719
|
-
return {
|
|
731
|
+
return _object_spread({
|
|
720
732
|
name: decl.getName(),
|
|
721
733
|
description: readJsDocDescription(jsDocs),
|
|
722
734
|
hasDbxModelTag: hasDbxModelTag,
|
|
723
735
|
extendsNames: extendsNames,
|
|
724
736
|
props: props
|
|
725
|
-
}
|
|
737
|
+
}, dbxModelRead === undefined ? {} : {
|
|
738
|
+
dbxModelRead: dbxModelRead
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
function readDbxModelReadTag(jsDocs) {
|
|
742
|
+
var result;
|
|
743
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
744
|
+
try {
|
|
745
|
+
for(var _iterator = jsDocs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
746
|
+
var doc = _step.value;
|
|
747
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
748
|
+
try {
|
|
749
|
+
for(var _iterator1 = doc.getTags()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
750
|
+
var tag = _step1.value;
|
|
751
|
+
var _tag_getCommentText;
|
|
752
|
+
if (tag.getTagName() !== 'dbxModelRead') continue;
|
|
753
|
+
if (result !== undefined) continue;
|
|
754
|
+
var raw = (_tag_getCommentText = tag.getCommentText()) === null || _tag_getCommentText === void 0 ? void 0 : _tag_getCommentText.trim();
|
|
755
|
+
if (raw === undefined || raw.length === 0) continue;
|
|
756
|
+
var firstToken = raw.split(/\s+/)[0];
|
|
757
|
+
if (READ_LEVEL_VALUES.has(firstToken)) {
|
|
758
|
+
result = firstToken;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
} catch (err) {
|
|
762
|
+
_didIteratorError1 = true;
|
|
763
|
+
_iteratorError1 = err;
|
|
764
|
+
} finally{
|
|
765
|
+
try {
|
|
766
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
767
|
+
_iterator1.return();
|
|
768
|
+
}
|
|
769
|
+
} finally{
|
|
770
|
+
if (_didIteratorError1) {
|
|
771
|
+
throw _iteratorError1;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
} catch (err) {
|
|
777
|
+
_didIteratorError = true;
|
|
778
|
+
_iteratorError = err;
|
|
779
|
+
} finally{
|
|
780
|
+
try {
|
|
781
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
782
|
+
_iterator.return();
|
|
783
|
+
}
|
|
784
|
+
} finally{
|
|
785
|
+
if (_didIteratorError) {
|
|
786
|
+
throw _iteratorError;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return result;
|
|
791
|
+
}
|
|
792
|
+
function readServiceFactories(sourceFile) {
|
|
793
|
+
var out = [];
|
|
794
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
795
|
+
try {
|
|
796
|
+
for(var _iterator = sourceFile.getVariableStatements()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
797
|
+
var statement = _step.value;
|
|
798
|
+
if (!statement.isExported()) continue;
|
|
799
|
+
var modelType = readServiceFactoryModelType(statement.getJsDocs());
|
|
800
|
+
if (modelType === undefined) continue;
|
|
801
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
802
|
+
try {
|
|
803
|
+
for(var _iterator1 = statement.getDeclarations()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
804
|
+
var decl = _step1.value;
|
|
805
|
+
out.push({
|
|
806
|
+
modelType: modelType,
|
|
807
|
+
exportName: decl.getName()
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
} catch (err) {
|
|
811
|
+
_didIteratorError1 = true;
|
|
812
|
+
_iteratorError1 = err;
|
|
813
|
+
} finally{
|
|
814
|
+
try {
|
|
815
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
816
|
+
_iterator1.return();
|
|
817
|
+
}
|
|
818
|
+
} finally{
|
|
819
|
+
if (_didIteratorError1) {
|
|
820
|
+
throw _iteratorError1;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
} catch (err) {
|
|
826
|
+
_didIteratorError = true;
|
|
827
|
+
_iteratorError = err;
|
|
828
|
+
} finally{
|
|
829
|
+
try {
|
|
830
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
831
|
+
_iterator.return();
|
|
832
|
+
}
|
|
833
|
+
} finally{
|
|
834
|
+
if (_didIteratorError) {
|
|
835
|
+
throw _iteratorError;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
return out;
|
|
840
|
+
}
|
|
841
|
+
function readServiceFactoryModelType(jsDocs) {
|
|
842
|
+
var result;
|
|
843
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
844
|
+
try {
|
|
845
|
+
for(var _iterator = jsDocs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
846
|
+
var doc = _step.value;
|
|
847
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
848
|
+
try {
|
|
849
|
+
for(var _iterator1 = doc.getTags()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
850
|
+
var tag = _step1.value;
|
|
851
|
+
var _tag_getCommentText;
|
|
852
|
+
if (tag.getTagName() !== SERVICE_FACTORY_TAG) continue;
|
|
853
|
+
if (result !== undefined) continue;
|
|
854
|
+
var raw = (_tag_getCommentText = tag.getCommentText()) === null || _tag_getCommentText === void 0 ? void 0 : _tag_getCommentText.trim();
|
|
855
|
+
if (raw === undefined || raw.length === 0) continue;
|
|
856
|
+
var firstToken = raw.split(/\s+/)[0];
|
|
857
|
+
if (MODEL_TYPE_VALUE_PATTERN.test(firstToken)) {
|
|
858
|
+
result = firstToken;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
} catch (err) {
|
|
862
|
+
_didIteratorError1 = true;
|
|
863
|
+
_iteratorError1 = err;
|
|
864
|
+
} finally{
|
|
865
|
+
try {
|
|
866
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
867
|
+
_iterator1.return();
|
|
868
|
+
}
|
|
869
|
+
} finally{
|
|
870
|
+
if (_didIteratorError1) {
|
|
871
|
+
throw _iteratorError1;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
} catch (err) {
|
|
877
|
+
_didIteratorError = true;
|
|
878
|
+
_iteratorError = err;
|
|
879
|
+
} finally{
|
|
880
|
+
try {
|
|
881
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
882
|
+
_iterator.return();
|
|
883
|
+
}
|
|
884
|
+
} finally{
|
|
885
|
+
if (_didIteratorError) {
|
|
886
|
+
throw _iteratorError;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
return result;
|
|
726
891
|
}
|
|
727
892
|
/**
|
|
728
893
|
* Resolves an `extends` clause to the concrete ancestor interface name,
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* `dbx-cli-firebase-api-manifest` build CLI. Re-exported under
|
|
10
10
|
* `@dereekb/dbx-cli/manifest-extract`.
|
|
11
11
|
*/
|
|
12
|
-
export type CrudVerb = 'create' | 'read' | 'update' | 'delete' | 'query' | 'standalone';
|
|
12
|
+
export type CrudVerb = 'create' | 'read' | 'update' | 'delete' | 'query' | 'invoke' | 'standalone';
|
|
13
13
|
export interface CrudEntryDocField {
|
|
14
14
|
readonly name: string;
|
|
15
15
|
readonly typeText: string;
|
|
@@ -125,6 +125,11 @@ export interface ModelExtractionInterface {
|
|
|
125
125
|
readonly hasDbxModelTag: boolean;
|
|
126
126
|
readonly extendsNames: readonly string[];
|
|
127
127
|
readonly props: readonly ModelExtractionInterfaceProp[];
|
|
128
|
+
/**
|
|
129
|
+
* Closed-enum read posture from `@dbxModelRead <level>` (`system` / `owner` / `admin-only`
|
|
130
|
+
* / `permissions`). Absent when the interface omits the tag or declares an invalid value.
|
|
131
|
+
*/
|
|
132
|
+
readonly dbxModelRead?: 'system' | 'owner' | 'admin-only' | 'permissions';
|
|
128
133
|
}
|
|
129
134
|
/**
|
|
130
135
|
* One field inside a converter's `fields` map.
|
|
@@ -231,4 +236,24 @@ export interface ModelExtraction {
|
|
|
231
236
|
readonly converters: readonly ModelExtractionConverter[];
|
|
232
237
|
readonly enums: readonly ModelExtractionEnum[];
|
|
233
238
|
readonly modelGroups: readonly ModelExtractionGroup[];
|
|
239
|
+
/**
|
|
240
|
+
* `@dbxModelServiceFactory <modelType>`-tagged variable exports found in this file. The
|
|
241
|
+
* orchestrator joins these onto matching model entries by `modelType` so the runtime
|
|
242
|
+
* manifest can surface the implementing factory alongside each model.
|
|
243
|
+
*/
|
|
244
|
+
readonly serviceFactories: readonly ModelExtractionServiceFactory[];
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* One `@dbxModelServiceFactory <modelType>`-tagged variable export.
|
|
248
|
+
*/
|
|
249
|
+
export interface ModelExtractionServiceFactory {
|
|
250
|
+
/**
|
|
251
|
+
* Canonical model-type string from the tag value (camelCase, e.g. `guestbook`).
|
|
252
|
+
* Invalid values are silently dropped at scan time.
|
|
253
|
+
*/
|
|
254
|
+
readonly modelType: string;
|
|
255
|
+
/**
|
|
256
|
+
* Name of the exported binding (e.g. `guestbookFirebaseModelServiceFactory`).
|
|
257
|
+
*/
|
|
258
|
+
readonly exportName: string;
|
|
234
259
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.12.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"sideEffects": false,
|
|
5
6
|
"bin": {
|
|
6
7
|
"dbx-cli-generate-firebase-api-manifest": "firebase-api-manifest/main.js",
|
|
7
8
|
"dbx-cli-generate-firestore-indexes": "generate-firestore-indexes/main.js",
|
|
9
|
+
"dbx-cli-generate-mcp-manifest": "generate-mcp-manifest/main.js",
|
|
8
10
|
"dbx-cli-lint-cache": "lint-cache/main.js"
|
|
9
11
|
},
|
|
10
12
|
"exports": {
|
|
@@ -14,6 +16,9 @@
|
|
|
14
16
|
"./generate-firestore-indexes": {
|
|
15
17
|
"default": "./generate-firestore-indexes/main.js"
|
|
16
18
|
},
|
|
19
|
+
"./generate-mcp-manifest": {
|
|
20
|
+
"default": "./generate-mcp-manifest/main.js"
|
|
21
|
+
},
|
|
17
22
|
"./lint-cache": {
|
|
18
23
|
"default": "./lint-cache/main.js"
|
|
19
24
|
},
|
|
@@ -31,18 +36,17 @@
|
|
|
31
36
|
},
|
|
32
37
|
"./package.json": "./package.json",
|
|
33
38
|
".": {
|
|
34
|
-
"
|
|
35
|
-
"types": "./index.d.ts"
|
|
36
|
-
"import": "./index.cjs.mjs",
|
|
37
|
-
"default": "./index.cjs.js"
|
|
39
|
+
"import": "./index.esm.js",
|
|
40
|
+
"types": "./index.d.ts"
|
|
38
41
|
}
|
|
39
42
|
},
|
|
40
43
|
"peerDependencies": {
|
|
41
|
-
"@dereekb/date": "13.
|
|
42
|
-
"@dereekb/firebase": "13.
|
|
43
|
-
"@dereekb/nestjs": "13.
|
|
44
|
-
"@dereekb/util": "13.
|
|
44
|
+
"@dereekb/date": "13.12.0",
|
|
45
|
+
"@dereekb/firebase": "13.12.0",
|
|
46
|
+
"@dereekb/nestjs": "13.12.0",
|
|
47
|
+
"@dereekb/util": "13.12.0",
|
|
45
48
|
"arktype": "^2.2.0",
|
|
49
|
+
"ts-morph": "^21.0.0",
|
|
46
50
|
"yargs": "^18.0.0"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
@@ -50,6 +54,6 @@
|
|
|
50
54
|
"eslint": "10.4.0"
|
|
51
55
|
},
|
|
52
56
|
"module": "./index.esm.js",
|
|
53
|
-
"main": "./index.
|
|
57
|
+
"main": "./index.esm.js",
|
|
54
58
|
"types": "./index.d.ts"
|
|
55
59
|
}
|
package/src/lib/index.d.ts
CHANGED
|
@@ -6,7 +6,10 @@ export * from './context';
|
|
|
6
6
|
export * from './doctor';
|
|
7
7
|
export * from './env';
|
|
8
8
|
export * from './manifest';
|
|
9
|
+
export * from './mcp-scan';
|
|
9
10
|
export * from './middleware';
|
|
11
|
+
export * from './scan-helpers/scan-io.js';
|
|
12
|
+
export * from './scan-helpers/scan-extract-utils.js';
|
|
10
13
|
export * from './output';
|
|
11
14
|
export * from './runner';
|
|
12
15
|
export * from './util';
|