@dereekb/dbx-cli 13.15.0 → 13.17.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/eslint/index.cjs.default.js +1 -0
- package/eslint/index.cjs.js +1050 -0
- package/eslint/index.cjs.mjs +2 -0
- package/eslint/index.d.ts +1 -0
- package/eslint/index.esm.js +1046 -0
- package/eslint/package.json +25 -0
- package/eslint/rollup.alias-internal.config.d.ts +11 -0
- package/eslint/src/index.d.ts +1 -0
- package/eslint/src/lib/index.d.ts +2 -0
- package/eslint/src/lib/plugin.d.ts +22 -0
- package/eslint/src/lib/valid-dbx-route-model-tags.rule.d.ts +59 -0
- package/firebase-api-manifest/main.js +318 -228
- package/firebase-api-manifest/package.json +3 -3
- package/generate-firestore-indexes/main.js +37 -24
- package/generate-firestore-indexes/package.json +2 -2
- package/generate-mcp-manifest/main.js +57 -39
- package/generate-mcp-manifest/package.json +3 -3
- package/generate-route-manifest/main.js +1137 -0
- package/generate-route-manifest/package.json +10 -0
- package/index.cjs.js +4847 -1953
- package/index.esm.js +4827 -1954
- package/lint-cache/package.json +2 -2
- package/manifest-extract/index.cjs.js +175 -240
- package/manifest-extract/index.esm.js +174 -239
- package/manifest-extract/package.json +9 -4
- package/package.json +16 -6
- package/src/lib/index.d.ts +2 -0
- package/src/lib/manifest/types.d.ts +53 -0
- package/src/lib/mcp-scan/manifest/package-root.d.ts +17 -0
- package/src/lib/mcp-scan/manifest/tokens-schema.d.ts +5 -4
- package/src/lib/mcp-scan/scan/extract-models/assemble.d.ts +17 -0
- package/src/lib/route/component-resolve.d.ts +48 -0
- package/src/lib/route/index.d.ts +18 -0
- package/src/lib/route/route-build-tree.d.ts +31 -0
- package/src/lib/route/route-extract.d.ts +46 -0
- package/src/lib/route/route-load-tree.d.ts +17 -0
- package/src/lib/route/route-manifest.d.ts +132 -0
- package/src/lib/route/route-model-tag.d.ts +89 -0
- package/src/lib/route/route-models-extract.d.ts +22 -0
- package/src/lib/route/route-resolve-sources.d.ts +39 -0
- package/src/lib/route/route-types.d.ts +136 -0
- package/src/lib/route/url-match.d.ts +116 -0
- package/src/lib/scan-helpers/firestore-model-extract-utils.d.ts +43 -0
- package/test/index.cjs.js +1 -1
- package/test/index.esm.js +1 -1
- package/test/package.json +9 -9
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli-firebase-api-manifest",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.17.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"ts-morph": "^21.0.0"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"@dereekb/dbx-cli": "13.
|
|
11
|
-
"@dereekb/util": "13.
|
|
10
|
+
"@dereekb/dbx-cli": "13.17.0",
|
|
11
|
+
"@dereekb/util": "13.17.0",
|
|
12
12
|
"prettier": "3.8.3"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -5,14 +5,14 @@ const require = __createRequire(import.meta.url);
|
|
|
5
5
|
// packages/dbx-cli/generate-firestore-indexes/package.json
|
|
6
6
|
var package_default = {
|
|
7
7
|
name: "@dereekb/dbx-cli-generate-firestore-indexes",
|
|
8
|
-
version: "13.
|
|
8
|
+
version: "13.17.0",
|
|
9
9
|
private: true,
|
|
10
10
|
type: "module",
|
|
11
11
|
devDependencies: {
|
|
12
12
|
eslint: "10.4.0"
|
|
13
13
|
},
|
|
14
14
|
peerDependencies: {
|
|
15
|
-
"@dereekb/dbx-cli": "13.
|
|
15
|
+
"@dereekb/dbx-cli": "13.17.0"
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -2109,38 +2109,51 @@ function parseArgv(argv) {
|
|
|
2109
2109
|
return { component, output, check, json, help, error };
|
|
2110
2110
|
}
|
|
2111
2111
|
async function readExistingIndexes(input) {
|
|
2112
|
+
const text = await readExistingIndexesText(input);
|
|
2113
|
+
let result2;
|
|
2114
|
+
if (text !== void 0) {
|
|
2115
|
+
result2 = parseExistingIndexesJson(text, input.outputAbs, input.stderr);
|
|
2116
|
+
}
|
|
2117
|
+
return result2;
|
|
2118
|
+
}
|
|
2119
|
+
async function readExistingIndexesText(input) {
|
|
2112
2120
|
const { outputAbs, readFile, stderr } = input;
|
|
2113
|
-
let text
|
|
2114
|
-
let readFailed = false;
|
|
2121
|
+
let text;
|
|
2115
2122
|
try {
|
|
2116
2123
|
text = await readFile(outputAbs);
|
|
2117
2124
|
} catch (err) {
|
|
2118
|
-
readFailed = true;
|
|
2119
2125
|
const code = err.code;
|
|
2120
2126
|
if (code !== "ENOENT") {
|
|
2121
2127
|
stderr(`generate-firestore-indexes: could not read existing ${outputAbs}: ${err instanceof Error ? err.message : String(err)}`);
|
|
2122
2128
|
}
|
|
2129
|
+
text = void 0;
|
|
2123
2130
|
}
|
|
2131
|
+
return text;
|
|
2132
|
+
}
|
|
2133
|
+
function parseExistingIndexesJson(text, outputAbs, stderr) {
|
|
2124
2134
|
let result2;
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2135
|
+
let parsed;
|
|
2136
|
+
let parseFailed = false;
|
|
2137
|
+
try {
|
|
2138
|
+
parsed = JSON.parse(text);
|
|
2139
|
+
} catch (err) {
|
|
2140
|
+
parseFailed = true;
|
|
2141
|
+
stderr(`generate-firestore-indexes: existing ${outputAbs} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
2142
|
+
}
|
|
2143
|
+
if (!parseFailed) {
|
|
2144
|
+
result2 = coerceFirestoreIndexesJson(parsed, outputAbs, stderr);
|
|
2145
|
+
}
|
|
2146
|
+
return result2;
|
|
2147
|
+
}
|
|
2148
|
+
function coerceFirestoreIndexesJson(parsed, outputAbs, stderr) {
|
|
2149
|
+
let result2;
|
|
2150
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
2151
|
+
stderr(`generate-firestore-indexes: existing ${outputAbs} top-level value is not an object`);
|
|
2152
|
+
} else {
|
|
2153
|
+
const raw = parsed;
|
|
2154
|
+
const indexes = Array.isArray(raw.indexes) ? raw.indexes : [];
|
|
2155
|
+
const fieldOverrides = Array.isArray(raw.fieldOverrides) ? raw.fieldOverrides : [];
|
|
2156
|
+
result2 = { indexes, fieldOverrides };
|
|
2144
2157
|
}
|
|
2145
2158
|
return result2;
|
|
2146
2159
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli-generate-firestore-indexes",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.17.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"eslint": "10.4.0"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"@dereekb/dbx-cli": "13.
|
|
10
|
+
"@dereekb/dbx-cli": "13.17.0"
|
|
11
11
|
}
|
|
12
12
|
}
|
|
@@ -725,9 +725,7 @@ var EMPTY_ROLE_CONST_RESOLUTION = { roles: [], unresolved: [] };
|
|
|
725
725
|
function resolveRoleConstByName(name, ctx) {
|
|
726
726
|
let result;
|
|
727
727
|
const scalar = ctx.knownRoles.get(name);
|
|
728
|
-
if (scalar
|
|
729
|
-
result = { roles: [scalar], unresolved: [] };
|
|
730
|
-
} else {
|
|
728
|
+
if (scalar === void 0) {
|
|
731
729
|
const arrayExpr = ctx.localArrayRoles.get(name);
|
|
732
730
|
if (arrayExpr === void 0) {
|
|
733
731
|
result = { roles: [], unresolved: [name] };
|
|
@@ -738,6 +736,8 @@ function resolveRoleConstByName(name, ctx) {
|
|
|
738
736
|
nextSeen.add(name);
|
|
739
737
|
result = resolveRoleArrayLiteral(arrayExpr, { ...ctx, seen: nextSeen });
|
|
740
738
|
}
|
|
739
|
+
} else {
|
|
740
|
+
result = { roles: [scalar], unresolved: [] };
|
|
741
741
|
}
|
|
742
742
|
return result;
|
|
743
743
|
}
|
|
@@ -1015,53 +1015,67 @@ function renderMcpManifest(input, now = /* @__PURE__ */ new Date()) {
|
|
|
1015
1015
|
const warnings = [];
|
|
1016
1016
|
const errors = [];
|
|
1017
1017
|
const seenNames = /* @__PURE__ */ new Map();
|
|
1018
|
+
const segments = buildSegmentMap(input.modelManifest);
|
|
1019
|
+
const toolEntries = input.apiManifest.filter((entry) => entry.verb !== "standalone");
|
|
1020
|
+
const nameCounts = countToolNames(toolEntries, segments);
|
|
1021
|
+
for (const entry of toolEntries) {
|
|
1022
|
+
registerToolEntry({ entry, segments, nameCounts, tools, seenNames, warnings, errors });
|
|
1023
|
+
}
|
|
1024
|
+
const models = input.modelManifest != null && input.modelManifest.length > 0 ? input.modelManifest.map(projectModelEntry) : void 0;
|
|
1025
|
+
const enums = input.enumManifest != null && Object.keys(input.enumManifest).length > 0 ? input.enumManifest : void 0;
|
|
1026
|
+
const auth = input.auth == null ? void 0 : projectAuthSection(input.auth.registry, input.auth.app);
|
|
1027
|
+
const base = { version: MCP_MANIFEST_VERSION, generatedAt: now.toISOString(), tools };
|
|
1028
|
+
const manifest = {
|
|
1029
|
+
...base,
|
|
1030
|
+
...models == null ? {} : { models },
|
|
1031
|
+
...enums == null ? {} : { enums },
|
|
1032
|
+
...auth == null ? {} : { auth }
|
|
1033
|
+
};
|
|
1034
|
+
return { manifest, warnings, errors };
|
|
1035
|
+
}
|
|
1036
|
+
function buildSegmentMap(modelManifest) {
|
|
1018
1037
|
const segments = /* @__PURE__ */ new Map();
|
|
1019
|
-
if (
|
|
1020
|
-
for (const model of
|
|
1038
|
+
if (modelManifest != null) {
|
|
1039
|
+
for (const model of modelManifest) {
|
|
1021
1040
|
if (model.mcpToolNameSegment != null && model.mcpToolNameSegment.length > 0) {
|
|
1022
1041
|
segments.set(model.modelType, model.mcpToolNameSegment);
|
|
1023
1042
|
}
|
|
1024
1043
|
}
|
|
1025
1044
|
}
|
|
1026
|
-
|
|
1045
|
+
return segments;
|
|
1046
|
+
}
|
|
1047
|
+
function countToolNames(toolEntries, segments) {
|
|
1027
1048
|
const nameCounts = /* @__PURE__ */ new Map();
|
|
1028
1049
|
for (const entry of toolEntries) {
|
|
1029
1050
|
const segment = segments.get(entry.model) ?? entry.model;
|
|
1030
1051
|
const baseName = buildMcpToolName(segment, entry.verb, entry.specifier);
|
|
1031
1052
|
nameCounts.set(baseName, (nameCounts.get(baseName) ?? 0) + 1);
|
|
1032
1053
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1054
|
+
return nameCounts;
|
|
1055
|
+
}
|
|
1056
|
+
function registerToolEntry(input) {
|
|
1057
|
+
const { entry, segments, nameCounts, tools, seenNames, warnings, errors } = input;
|
|
1058
|
+
const key = mcpManifestKey(entry.model, entry.verb, entry.specifier);
|
|
1059
|
+
tools[key] = buildToolEntry(entry);
|
|
1060
|
+
const segment = segments.get(entry.model) ?? entry.model;
|
|
1061
|
+
const baseName = buildMcpToolName(segment, entry.verb, entry.specifier);
|
|
1062
|
+
const clashes = (nameCounts.get(baseName) ?? 0) > 1;
|
|
1063
|
+
const toolName = clashes ? buildDisambiguatedMcpToolName(segment, entry.verb, entry.specifier) : baseName;
|
|
1064
|
+
if (toolName !== baseName) {
|
|
1065
|
+
warnings.push(`Tool name "${baseName}" is produced by more than one entry; re-derived as "${toolName}" (${key}) with the abbreviated call type to disambiguate.`);
|
|
1066
|
+
}
|
|
1067
|
+
const validation = validateMcpToolName(toolName);
|
|
1068
|
+
if (validation.level === "error") {
|
|
1069
|
+
errors.push(`Tool name "${toolName}" is ${validation.length} chars, over the ${MCP_TOOL_NAME_MAX_LENGTH}-char MCP cap (${key}). Shorten the model/specifier, set a per-model mcpToolNameSegment, or hide the tool.`);
|
|
1070
|
+
} else if (validation.level === "warn") {
|
|
1071
|
+
warnings.push(`Tool name "${toolName}" is ${validation.length} chars, over the ${MCP_TOOL_NAME_WARN_LENGTH}-char soft limit (${key}).`);
|
|
1072
|
+
}
|
|
1073
|
+
const priorKey = seenNames.get(toolName);
|
|
1074
|
+
if (priorKey == null) {
|
|
1075
|
+
seenNames.set(toolName, key);
|
|
1076
|
+
} else {
|
|
1077
|
+
warnings.push(`Tool name "${toolName}" is still produced by more than one entry (${priorKey} and ${key}) after disambiguation; one shadows the other unless hidden or renamed at runtime.`);
|
|
1055
1078
|
}
|
|
1056
|
-
const models = input.modelManifest != null && input.modelManifest.length > 0 ? input.modelManifest.map(projectModelEntry) : void 0;
|
|
1057
|
-
const auth = input.auth == null ? void 0 : projectAuthSection(input.auth.registry, input.auth.app);
|
|
1058
|
-
const base = { version: MCP_MANIFEST_VERSION, generatedAt: now.toISOString(), tools };
|
|
1059
|
-
const manifest = {
|
|
1060
|
-
...base,
|
|
1061
|
-
...models == null ? {} : { models },
|
|
1062
|
-
...auth == null ? {} : { auth }
|
|
1063
|
-
};
|
|
1064
|
-
return { manifest, warnings, errors };
|
|
1065
1079
|
}
|
|
1066
1080
|
function projectAuthSection(registry, appSlug) {
|
|
1067
1081
|
const primary = registry.findApp(appSlug);
|
|
@@ -1300,8 +1314,9 @@ Expected output of \`nx run <cli>:generate-api-manifest\`.`);
|
|
|
1300
1314
|
writeFileSync(tmpPath, serialized);
|
|
1301
1315
|
renameSync(tmpPath, outputPath);
|
|
1302
1316
|
const modelCount = manifest.models?.length ?? 0;
|
|
1317
|
+
const enumCount = manifest.enums == null ? 0 : Object.keys(manifest.enums).length;
|
|
1303
1318
|
const authCount = manifest.auth?.claims.length ?? 0;
|
|
1304
|
-
console.log(`[wrote] ${relative2(WORKSPACE_ROOT, outputPath)} \u2014 ${Object.keys(manifest.tools).length} tools, ${modelCount} models, ${authCount} auth claims`);
|
|
1319
|
+
console.log(`[wrote] ${relative2(WORKSPACE_ROOT, outputPath)} \u2014 ${Object.keys(manifest.tools).length} tools, ${modelCount} models, ${enumCount} enums, ${authCount} auth claims`);
|
|
1305
1320
|
}
|
|
1306
1321
|
async function maybeLoadAuth(flags) {
|
|
1307
1322
|
if (flags.app == null || flags.claimsInputs.length === 0) {
|
|
@@ -1330,7 +1345,10 @@ async function loadManifest(path) {
|
|
|
1330
1345
|
const namedModel = Object.entries(loaded).find(([key]) => key.endsWith("_MODEL_MANIFEST"));
|
|
1331
1346
|
const modelManifestValue = namedModel?.[1];
|
|
1332
1347
|
const modelManifest = Array.isArray(modelManifestValue) ? modelManifestValue : void 0;
|
|
1333
|
-
|
|
1348
|
+
const namedEnum = Object.entries(loaded).find(([key]) => key.endsWith("_ENUM_MANIFEST"));
|
|
1349
|
+
const enumManifestValue = namedEnum?.[1];
|
|
1350
|
+
const enumManifest = enumManifestValue != null && typeof enumManifestValue === "object" && !Array.isArray(enumManifestValue) ? enumManifestValue : void 0;
|
|
1351
|
+
return { apiManifest, modelManifest, enumManifest };
|
|
1334
1352
|
}
|
|
1335
1353
|
function loadTsconfigPathAliases() {
|
|
1336
1354
|
const tsconfigPath = resolve(WORKSPACE_ROOT, "tsconfig.base.json");
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli-generate-mcp-manifest",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.17.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"@dereekb/dbx-cli": "13.
|
|
8
|
-
"@dereekb/model": "13.
|
|
7
|
+
"@dereekb/dbx-cli": "13.17.0",
|
|
8
|
+
"@dereekb/model": "13.17.0",
|
|
9
9
|
"arktype": "^2.2.0",
|
|
10
10
|
"jiti": "2.6.1"
|
|
11
11
|
}
|