@dereekb/dbx-components-mcp 13.11.5 → 13.11.7
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/dbx-components-mcp.js +589 -291
- package/generated/dereekb-dbx-web.css-utilities.mcp.generated.json +72 -7
- package/generated/dereekb-dbx-web.ui-components.mcp.generated.json +9 -9
- package/generated/dereekb-demo.dbx-docs-ui-examples.mcp.generated.json +58 -0
- package/generated/rule-catalog.generated.json +38 -2
- package/package.json +11 -11
package/dbx-components-mcp.js
CHANGED
|
@@ -5,7 +5,7 @@ const require = __createRequire(import.meta.url);
|
|
|
5
5
|
// packages/dbx-components-mcp/package.json
|
|
6
6
|
var package_default = {
|
|
7
7
|
name: "@dereekb/dbx-components-mcp",
|
|
8
|
-
version: "13.11.
|
|
8
|
+
version: "13.11.7",
|
|
9
9
|
type: "module",
|
|
10
10
|
bin: {
|
|
11
11
|
"dbx-components-mcp": "dbx-components-mcp.js"
|
|
@@ -20,20 +20,20 @@ var package_default = {
|
|
|
20
20
|
"@angular/core": "21.2.11",
|
|
21
21
|
"@angular/forms": "21.2.11",
|
|
22
22
|
"@angular/material": "^21.2.9",
|
|
23
|
-
"@dereekb/dbx-cli": "13.11.
|
|
24
|
-
"@dereekb/dbx-core": "13.11.
|
|
25
|
-
"@dereekb/dbx-firebase": "13.11.
|
|
26
|
-
"@dereekb/dbx-form": "13.11.
|
|
27
|
-
"@dereekb/dbx-web": "13.11.
|
|
28
|
-
"@dereekb/firebase": "13.11.
|
|
29
|
-
"@dereekb/firebase-server": "13.11.
|
|
30
|
-
"@dereekb/rxjs": "13.11.
|
|
31
|
-
"@dereekb/util": "13.11.
|
|
23
|
+
"@dereekb/dbx-cli": "13.11.7",
|
|
24
|
+
"@dereekb/dbx-core": "13.11.7",
|
|
25
|
+
"@dereekb/dbx-firebase": "13.11.7",
|
|
26
|
+
"@dereekb/dbx-form": "13.11.7",
|
|
27
|
+
"@dereekb/dbx-web": "13.11.7",
|
|
28
|
+
"@dereekb/firebase": "13.11.7",
|
|
29
|
+
"@dereekb/firebase-server": "13.11.7",
|
|
30
|
+
"@dereekb/rxjs": "13.11.7",
|
|
31
|
+
"@dereekb/util": "13.11.7",
|
|
32
32
|
"@uirouter/angular": "21.0.0",
|
|
33
33
|
rxjs: "^7.8.2"
|
|
34
34
|
},
|
|
35
35
|
devDependencies: {
|
|
36
|
-
"@dereekb/model": "13.11.
|
|
36
|
+
"@dereekb/model": "13.11.7"
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
|
|
@@ -8239,9 +8239,11 @@ function readFieldEntries(fields) {
|
|
|
8239
8239
|
}
|
|
8240
8240
|
|
|
8241
8241
|
// packages/dbx-components-mcp/src/scan/extract-models/find-enums.ts
|
|
8242
|
-
import { Node as
|
|
8242
|
+
import { Node as Node9, SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
8243
8243
|
|
|
8244
8244
|
// packages/dbx-components-mcp/src/scan/extract-models/find-interfaces.ts
|
|
8245
|
+
import { Node as Node8 } from "ts-morph";
|
|
8246
|
+
var PASSTHROUGH_TYPE_WRAPPERS = /* @__PURE__ */ new Set(["Partial", "Required", "Readonly", "NonNullable", "MaybeMap", "Pick", "Omit"]);
|
|
8245
8247
|
function findInterfaces(sf) {
|
|
8246
8248
|
const out = [];
|
|
8247
8249
|
for (const decl of sf.getInterfaces()) {
|
|
@@ -8253,7 +8255,7 @@ function findInterfaces(sf) {
|
|
|
8253
8255
|
function buildInterface(decl) {
|
|
8254
8256
|
const tags = readInterfaceTags(decl.getJsDocs());
|
|
8255
8257
|
const description = readDescription(decl.getJsDocs());
|
|
8256
|
-
const extendsNames = decl.getExtends().map(
|
|
8258
|
+
const extendsNames = decl.getExtends().map(resolveExtendsName);
|
|
8257
8259
|
const props = [];
|
|
8258
8260
|
for (const prop of decl.getProperties()) {
|
|
8259
8261
|
const propJsDocs = prop.getJsDocs();
|
|
@@ -8277,6 +8279,39 @@ function buildInterface(decl) {
|
|
|
8277
8279
|
props
|
|
8278
8280
|
};
|
|
8279
8281
|
}
|
|
8282
|
+
function resolveExtendsName(expr) {
|
|
8283
|
+
const head = expr.getExpression().getText();
|
|
8284
|
+
let result = head;
|
|
8285
|
+
if (PASSTHROUGH_TYPE_WRAPPERS.has(head)) {
|
|
8286
|
+
const typeArgs = expr.getTypeArguments();
|
|
8287
|
+
if (typeArgs.length > 0) {
|
|
8288
|
+
const peeled = peelTypeNode(typeArgs[0]);
|
|
8289
|
+
if (peeled !== void 0) {
|
|
8290
|
+
result = peeled;
|
|
8291
|
+
}
|
|
8292
|
+
}
|
|
8293
|
+
}
|
|
8294
|
+
return result;
|
|
8295
|
+
}
|
|
8296
|
+
function peelTypeNode(node) {
|
|
8297
|
+
let current = node;
|
|
8298
|
+
while (Node8.isParenthesizedTypeNode(current)) {
|
|
8299
|
+
current = current.getTypeNode();
|
|
8300
|
+
}
|
|
8301
|
+
let result;
|
|
8302
|
+
if (Node8.isTypeReference(current)) {
|
|
8303
|
+
const name = current.getTypeName().getText();
|
|
8304
|
+
if (PASSTHROUGH_TYPE_WRAPPERS.has(name)) {
|
|
8305
|
+
const inner = current.getTypeArguments();
|
|
8306
|
+
if (inner.length > 0) {
|
|
8307
|
+
result = peelTypeNode(inner[0]);
|
|
8308
|
+
}
|
|
8309
|
+
} else {
|
|
8310
|
+
result = name;
|
|
8311
|
+
}
|
|
8312
|
+
}
|
|
8313
|
+
return result;
|
|
8314
|
+
}
|
|
8280
8315
|
function readInterfaceTags(jsDocs) {
|
|
8281
8316
|
let dbxModel = false;
|
|
8282
8317
|
for (const jsDoc of jsDocs) {
|
|
@@ -8354,14 +8389,14 @@ function buildEnum(decl) {
|
|
|
8354
8389
|
if (initializer === void 0) {
|
|
8355
8390
|
value = auto;
|
|
8356
8391
|
auto = value + 1;
|
|
8357
|
-
} else if (
|
|
8392
|
+
} else if (Node9.isStringLiteral(initializer) || Node9.isNoSubstitutionTemplateLiteral(initializer)) {
|
|
8358
8393
|
value = initializer.getLiteralText();
|
|
8359
|
-
} else if (
|
|
8394
|
+
} else if (Node9.isNumericLiteral(initializer)) {
|
|
8360
8395
|
value = Number(initializer.getLiteralText());
|
|
8361
8396
|
auto = value + 1;
|
|
8362
|
-
} else if (
|
|
8397
|
+
} else if (Node9.isPrefixUnaryExpression(initializer)) {
|
|
8363
8398
|
const inner = initializer.getOperand();
|
|
8364
|
-
if (
|
|
8399
|
+
if (Node9.isNumericLiteral(inner)) {
|
|
8365
8400
|
const raw = Number(inner.getLiteralText());
|
|
8366
8401
|
value = initializer.getOperatorToken() === SyntaxKind3.MinusToken ? -raw : raw;
|
|
8367
8402
|
auto = value + 1;
|
|
@@ -8381,7 +8416,7 @@ function buildEnum(decl) {
|
|
|
8381
8416
|
}
|
|
8382
8417
|
|
|
8383
8418
|
// packages/dbx-components-mcp/src/scan/extract-models/find-identities.ts
|
|
8384
|
-
import { Node as
|
|
8419
|
+
import { Node as Node10 } from "ts-morph";
|
|
8385
8420
|
var FUNCTION_NAME2 = "firestoreModelIdentity";
|
|
8386
8421
|
function findIdentities(sf) {
|
|
8387
8422
|
const out = [];
|
|
@@ -8389,7 +8424,7 @@ function findIdentities(sf) {
|
|
|
8389
8424
|
if (!statement.isExported()) continue;
|
|
8390
8425
|
for (const decl of statement.getDeclarations()) {
|
|
8391
8426
|
const initializer = decl.getInitializer();
|
|
8392
|
-
if (!initializer || !
|
|
8427
|
+
if (!initializer || !Node10.isCallExpression(initializer)) continue;
|
|
8393
8428
|
if (initializer.getExpression().getText() !== FUNCTION_NAME2) continue;
|
|
8394
8429
|
const parsed = parseIdentityCall(initializer.getArguments());
|
|
8395
8430
|
if (parsed) {
|
|
@@ -8426,14 +8461,14 @@ function parseIdentityCall(args) {
|
|
|
8426
8461
|
}
|
|
8427
8462
|
function stringLiteralValue(node) {
|
|
8428
8463
|
let result;
|
|
8429
|
-
if (
|
|
8464
|
+
if (Node10.isStringLiteral(node) || Node10.isNoSubstitutionTemplateLiteral(node)) {
|
|
8430
8465
|
result = node.getLiteralText();
|
|
8431
8466
|
}
|
|
8432
8467
|
return result;
|
|
8433
8468
|
}
|
|
8434
8469
|
function identifierName(node) {
|
|
8435
8470
|
let result;
|
|
8436
|
-
if (
|
|
8471
|
+
if (Node10.isIdentifier(node)) {
|
|
8437
8472
|
result = node.getText();
|
|
8438
8473
|
}
|
|
8439
8474
|
return result;
|
|
@@ -14244,7 +14279,15 @@ function createListAppTool(config) {
|
|
|
14244
14279
|
}
|
|
14245
14280
|
|
|
14246
14281
|
// packages/dbx-components-mcp/src/tools/model-validate/extract.ts
|
|
14247
|
-
import { Node as
|
|
14282
|
+
import { Node as Node11, Project as Project4, SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
14283
|
+
|
|
14284
|
+
// packages/dbx-components-mcp/src/tools/model-validate/types.ts
|
|
14285
|
+
var MAX_FIELD_NAME_LENGTH = 5;
|
|
14286
|
+
var ROOT_MODEL_ORDER = ["identity", "interface", "rolesType", "documentClass", "converter", "referenceFn", "collectionType", "collectionFn"];
|
|
14287
|
+
var SUBCOLLECTION_MODEL_ORDER = ["identity", "interface", "rolesType", "documentClass", "converter", "referenceFn", "collectionType", "collectionFactoryType", "collectionFn", "referenceGroupFn", "collectionGroupType", "collectionGroupFn"];
|
|
14288
|
+
var SUB_OBJECT_FACTORY_NAMES = ["firestoreSubObject", "firestoreObjectArray", "firestoreMap"];
|
|
14289
|
+
|
|
14290
|
+
// packages/dbx-components-mcp/src/tools/model-validate/extract.ts
|
|
14248
14291
|
function extractFile(source) {
|
|
14249
14292
|
const project = new Project4({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
|
|
14250
14293
|
const sourceFile = project.createSourceFile(source.name, source.text, { overwrite: true });
|
|
@@ -14254,16 +14297,56 @@ function extractFile(source) {
|
|
|
14254
14297
|
const firstModelLine = identities.length > 0 ? Math.min(...identities.map((i) => i.line)) : void 0;
|
|
14255
14298
|
const models = identities.map((identity) => extractModel(sourceFile, identity));
|
|
14256
14299
|
const dataInterfaces = findDataInterfaces(sourceFile, groupInterface);
|
|
14300
|
+
const subObjectCalls = findSubObjectFactoryCalls(sourceFile);
|
|
14257
14301
|
const result = {
|
|
14258
14302
|
name: source.name,
|
|
14259
14303
|
groupInterface,
|
|
14260
14304
|
groupTypes,
|
|
14261
14305
|
firstModelLine,
|
|
14262
14306
|
models,
|
|
14263
|
-
dataInterfaces
|
|
14307
|
+
dataInterfaces,
|
|
14308
|
+
subObjectCalls
|
|
14264
14309
|
};
|
|
14265
14310
|
return result;
|
|
14266
14311
|
}
|
|
14312
|
+
function findSubObjectFactoryCalls(sourceFile) {
|
|
14313
|
+
const out = [];
|
|
14314
|
+
const factorySet = new Set(SUB_OBJECT_FACTORY_NAMES);
|
|
14315
|
+
for (const call of sourceFile.getDescendantsOfKind(SyntaxKind4.CallExpression)) {
|
|
14316
|
+
const expr = call.getExpression();
|
|
14317
|
+
if (!Node11.isIdentifier(expr)) {
|
|
14318
|
+
continue;
|
|
14319
|
+
}
|
|
14320
|
+
const factoryName = expr.getText();
|
|
14321
|
+
if (!factorySet.has(factoryName)) {
|
|
14322
|
+
continue;
|
|
14323
|
+
}
|
|
14324
|
+
const typeArgs = call.getTypeArguments();
|
|
14325
|
+
if (typeArgs.length === 0) {
|
|
14326
|
+
continue;
|
|
14327
|
+
}
|
|
14328
|
+
const typeArgName = readTypeReferenceIdentifier(typeArgs[0]);
|
|
14329
|
+
if (!typeArgName) {
|
|
14330
|
+
continue;
|
|
14331
|
+
}
|
|
14332
|
+
out.push({
|
|
14333
|
+
factoryName,
|
|
14334
|
+
typeArgName,
|
|
14335
|
+
line: call.getStartLineNumber()
|
|
14336
|
+
});
|
|
14337
|
+
}
|
|
14338
|
+
return out;
|
|
14339
|
+
}
|
|
14340
|
+
function readTypeReferenceIdentifier(typeNode) {
|
|
14341
|
+
if (!Node11.isTypeReference(typeNode)) {
|
|
14342
|
+
return void 0;
|
|
14343
|
+
}
|
|
14344
|
+
const nameNode = typeNode.getTypeName();
|
|
14345
|
+
if (!Node11.isIdentifier(nameNode)) {
|
|
14346
|
+
return void 0;
|
|
14347
|
+
}
|
|
14348
|
+
return nameNode.getText();
|
|
14349
|
+
}
|
|
14267
14350
|
function findDataInterfaces(sourceFile, groupInterface) {
|
|
14268
14351
|
const out = [];
|
|
14269
14352
|
const groupName = groupInterface?.name;
|
|
@@ -14274,7 +14357,8 @@ function findDataInterfaces(sourceFile, groupInterface) {
|
|
|
14274
14357
|
}
|
|
14275
14358
|
const fields = extractInterfaceFields(iface);
|
|
14276
14359
|
const dbxModelTag = readDbxModelTag(iface.getJsDocs());
|
|
14277
|
-
|
|
14360
|
+
const dbxModelSubObjectTag = readDbxModelSubObjectTag(iface.getJsDocs());
|
|
14361
|
+
out.push({ name, line: iface.getStartLineNumber(), dbxModelTag, dbxModelSubObjectTag, fields });
|
|
14278
14362
|
}
|
|
14279
14363
|
return out;
|
|
14280
14364
|
}
|
|
@@ -14344,6 +14428,17 @@ function readDbxModelTag(jsDocs) {
|
|
|
14344
14428
|
}
|
|
14345
14429
|
return result;
|
|
14346
14430
|
}
|
|
14431
|
+
function readDbxModelSubObjectTag(jsDocs) {
|
|
14432
|
+
let result = false;
|
|
14433
|
+
for (const jsDoc of jsDocs) {
|
|
14434
|
+
for (const tag of jsDoc.getTags()) {
|
|
14435
|
+
if (tag.getTagName() === "dbxModelSubObject") {
|
|
14436
|
+
result = true;
|
|
14437
|
+
}
|
|
14438
|
+
}
|
|
14439
|
+
}
|
|
14440
|
+
return result;
|
|
14441
|
+
}
|
|
14347
14442
|
function readDbxModelVariableTag(jsDocs) {
|
|
14348
14443
|
let result;
|
|
14349
14444
|
for (const jsDoc of jsDocs) {
|
|
@@ -14383,7 +14478,7 @@ function extractIdentityRefs(alias) {
|
|
|
14383
14478
|
if (!typeNode) {
|
|
14384
14479
|
return refs;
|
|
14385
14480
|
}
|
|
14386
|
-
if (
|
|
14481
|
+
if (Node11.isTypeQuery(typeNode)) {
|
|
14387
14482
|
refs.push(typeNode.getExprName().getText());
|
|
14388
14483
|
}
|
|
14389
14484
|
const typeofNodes = typeNode.getDescendantsOfKind(SyntaxKind4.TypeQuery);
|
|
@@ -14397,7 +14492,7 @@ function findIdentities2(sourceFile) {
|
|
|
14397
14492
|
for (const statement of sourceFile.getVariableStatements()) {
|
|
14398
14493
|
for (const decl of statement.getDeclarations()) {
|
|
14399
14494
|
const initializer = decl.getInitializer();
|
|
14400
|
-
if (!initializer || !
|
|
14495
|
+
if (!initializer || !Node11.isCallExpression(initializer)) {
|
|
14401
14496
|
continue;
|
|
14402
14497
|
}
|
|
14403
14498
|
if (initializer.getExpression().getText() !== "firestoreModelIdentity") {
|
|
@@ -14433,7 +14528,7 @@ function parseIdentityArgs(args) {
|
|
|
14433
14528
|
}
|
|
14434
14529
|
if (args.length === 3) {
|
|
14435
14530
|
const [parentNode, nameNode, prefixNode] = args;
|
|
14436
|
-
const parentRef =
|
|
14531
|
+
const parentRef = Node11.isIdentifier(parentNode) ? parentNode.getText() : void 0;
|
|
14437
14532
|
const result2 = {
|
|
14438
14533
|
parentIdentityRef: parentRef,
|
|
14439
14534
|
collectionName: stringLiteralValue2(nameNode),
|
|
@@ -14448,7 +14543,7 @@ function stringLiteralValue2(node) {
|
|
|
14448
14543
|
if (!node) {
|
|
14449
14544
|
return void 0;
|
|
14450
14545
|
}
|
|
14451
|
-
if (
|
|
14546
|
+
if (Node11.isStringLiteral(node) || Node11.isNoSubstitutionTemplateLiteral(node)) {
|
|
14452
14547
|
return node.getLiteralText();
|
|
14453
14548
|
}
|
|
14454
14549
|
return void 0;
|
|
@@ -14509,7 +14604,7 @@ function detectFactoryCallKind(sourceFile, factoryFnName) {
|
|
|
14509
14604
|
const calls = fn.getDescendantsOfKind(SyntaxKind4.CallExpression);
|
|
14510
14605
|
for (const call of calls) {
|
|
14511
14606
|
const expr = call.getExpression();
|
|
14512
|
-
if (!
|
|
14607
|
+
if (!Node11.isPropertyAccessExpression(expr)) {
|
|
14513
14608
|
continue;
|
|
14514
14609
|
}
|
|
14515
14610
|
const name = expr.getName();
|
|
@@ -15100,6 +15195,16 @@ var RULE_CATALOG = [
|
|
|
15100
15195
|
whenItDoesNotApply: "When the rename was intentional (rare \u2014 usually a copy-paste).",
|
|
15101
15196
|
canonicalFix: "Update the getter body to return the matching identity constant."
|
|
15102
15197
|
},
|
|
15198
|
+
{
|
|
15199
|
+
code: "MODEL_FIELD_LONG_NAME_EQUALS_NAME",
|
|
15200
|
+
source: "dbx_model_validate",
|
|
15201
|
+
severity: "warning",
|
|
15202
|
+
title: "A persisted field's `@dbxModelVariable <longName>` tag value matches the field's short name verbatim, defeating the tag's purpose (the long name should be the field's unabbreviated camelCase variable name)",
|
|
15203
|
+
whatItFlags: "A persisted field's `@dbxModelVariable <longName>` tag value matches the field's short name verbatim, defeating the tag's purpose (the long name should be the field's unabbreviated camelCase variable name).",
|
|
15204
|
+
whenItApplies: "Every field on a `@dbxModel` interface or on a `@dbxModelSubObject`-tagged embedded sub-object interface where `@dbxModelVariable` is present and its value equals the field's name (e.g. field `h` tagged `@dbxModelVariable h`, field `ub` tagged `@dbxModelVariable ub`). The tag must always carry the unabbreviated form so the catalog and decoder surface a meaningful long name.",
|
|
15205
|
+
whenItDoesNotApply: "Fields whose name is already the unabbreviated camelCase form (e.g. `name`, `email`, `id`, `at`) \u2014 add those to `dbx-mcp.config.json` `modelValidate.ignoredFieldNames` to silence the warning workspace-wide.",
|
|
15206
|
+
canonicalFix: "Replace the tag value with the field's unabbreviated camelCase variable name (e.g. `@dbxModelVariable h` \u2192 `@dbxModelVariable hours`, `@dbxModelVariable ub` \u2192 `@dbxModelVariable usedBudget`). To exempt fields whose long name legitimately equals the short name, add them to `modelValidate.ignoredFieldNames`."
|
|
15207
|
+
},
|
|
15103
15208
|
{
|
|
15104
15209
|
code: "MODEL_FIELD_MISSING_JSDOC",
|
|
15105
15210
|
source: "dbx_model_validate",
|
|
@@ -15116,8 +15221,8 @@ var RULE_CATALOG = [
|
|
|
15116
15221
|
severity: "warning",
|
|
15117
15222
|
title: "A persisted field is missing its `@dbxModelVariable <name>` JSDoc tag",
|
|
15118
15223
|
whatItFlags: "A persisted field is missing its `@dbxModelVariable <name>` JSDoc tag.",
|
|
15119
|
-
whenItApplies: "Every field on a `@dbxModel` interface \u2014 the tag carries the human-readable long name the catalog and decoder use when surfacing the field to operators. The long name is the variable name the field would have unabbreviated, written in camelCase (e.g. `uid` \u2192 `userUid`, `n` \u2192 `name`, `crAt` \u2192 `createdAt`).",
|
|
15120
|
-
whenItDoesNotApply: "Fields on embedded sub-object interfaces
|
|
15224
|
+
whenItApplies: "Every field on a `@dbxModel` interface or on a `@dbxModelSubObject`-tagged embedded sub-object interface \u2014 the tag carries the human-readable long name the catalog and decoder use when surfacing the field to operators. The long name is the variable name the field would have unabbreviated, written in camelCase (e.g. `uid` \u2192 `userUid`, `n` \u2192 `name`, `crAt` \u2192 `createdAt`).",
|
|
15225
|
+
whenItDoesNotApply: "Fields on embedded sub-object interfaces that are not tagged with `@dbxModelSubObject` (the tag is opt-in) and fields the project deliberately leaves untagged (rare).",
|
|
15121
15226
|
canonicalFix: "Append `@dbxModelVariable <longName>` to the field's JSDoc block, where `<longName>` is the field's unabbreviated camelCase variable name."
|
|
15122
15227
|
},
|
|
15123
15228
|
{
|
|
@@ -15304,6 +15409,32 @@ var RULE_CATALOG = [
|
|
|
15304
15409
|
whenItDoesNotApply: "When intentionally module-private.",
|
|
15305
15410
|
canonicalFix: "Add `export` to the alias."
|
|
15306
15411
|
},
|
|
15412
|
+
{
|
|
15413
|
+
code: "MODEL_SUBOBJECT_NOT_TAGGED",
|
|
15414
|
+
source: "dbx_model_validate",
|
|
15415
|
+
severity: "warning",
|
|
15416
|
+
title: "An interface is referenced as the first generic type-argument of a sub-object factory call (`firestoreSubObject<T>(...)`, `firestoreObjectArray<T>(...)`, or `firestoreMap<T>(...)`) but its declaration carries neither `@dbxModel` nor `@dbxModelSubObject`. The interface therefore opts out of the workspace's `@dbxModelVariable` long-name conventions even though its fields are persisted to Firestore",
|
|
15417
|
+
whatItFlags: "An interface is referenced as the first generic type-argument of a sub-object factory call (`firestoreSubObject<T>(...)`, `firestoreObjectArray<T>(...)`, or `firestoreMap<T>(...)`) but its declaration carries neither `@dbxModel` nor `@dbxModelSubObject`. The interface therefore opts out of the workspace's `@dbxModelVariable` long-name conventions even though its fields are persisted to Firestore.",
|
|
15418
|
+
whenItApplies: "Any interface declared in the validated source set that is the type-arg of at least one sub-object factory call and lacks both `@dbxModel` and `@dbxModelSubObject`. The warning is emitted once per interface (de-duplicated across all call sites) and anchored at the interface declaration line. Unresolved type-args \u2014 interfaces declared outside the validated source set, generic parameters, inline types \u2014 are silently skipped to avoid false positives.",
|
|
15419
|
+
whenItDoesNotApply: "Interfaces already tagged with `@dbxModel` (top-level models) or `@dbxModelSubObject` (embedded sub-objects), and interfaces referenced only from outside the supplied source set (different package, etc.).",
|
|
15420
|
+
canonicalFix: "Add `@dbxModelSubObject` to the interface's JSDoc block so its fields are subject to `@dbxModelVariable` long-name checks. If the interface is actually a top-level Firestore model, declare a matching `firestoreModelIdentity` and tag it `@dbxModel` instead.",
|
|
15421
|
+
seeAlso: [
|
|
15422
|
+
{
|
|
15423
|
+
kind: "artifact",
|
|
15424
|
+
target: "firestore-model"
|
|
15425
|
+
}
|
|
15426
|
+
]
|
|
15427
|
+
},
|
|
15428
|
+
{
|
|
15429
|
+
code: "MODEL_SUBOBJECT_TAG_CONFLICT",
|
|
15430
|
+
source: "dbx_model_validate",
|
|
15431
|
+
severity: "error",
|
|
15432
|
+
title: "An interface declaration carries both `@dbxModel` and `@dbxModelSubObject` JSDoc tags. The two tags model mutually exclusive concepts \u2014 `@dbxModel` marks a top-level Firestore model registered in the catalog via `firestoreModelIdentity`, while `@dbxModelSubObject` marks an embedded sub-object interface persisted only as part of a parent model's converter \u2014 so an interface must carry at most one",
|
|
15433
|
+
whatItFlags: "An interface declaration carries both `@dbxModel` and `@dbxModelSubObject` JSDoc tags. The two tags model mutually exclusive concepts \u2014 `@dbxModel` marks a top-level Firestore model registered in the catalog via `firestoreModelIdentity`, while `@dbxModelSubObject` marks an embedded sub-object interface persisted only as part of a parent model's converter \u2014 so an interface must carry at most one.",
|
|
15434
|
+
whenItApplies: "Any interface JSDoc block where both `@dbxModel` and `@dbxModelSubObject` are present.",
|
|
15435
|
+
whenItDoesNotApply: "Interfaces carrying only one of the two tags (or neither).",
|
|
15436
|
+
canonicalFix: "Remove whichever tag does not describe the interface. If the interface has a matching `firestoreModelIdentity` call, keep `@dbxModel`; if it is only embedded inside another model via `firestoreSubObject<T>()`, keep `@dbxModelSubObject`."
|
|
15437
|
+
},
|
|
15307
15438
|
{
|
|
15308
15439
|
code: "SUB_MISSING_COLLECTION_FACTORY_FN",
|
|
15309
15440
|
source: "dbx_model_validate",
|
|
@@ -16930,15 +17061,11 @@ function formatSeeAlso(ref) {
|
|
|
16930
17061
|
return `Doc: ${ref.target}${tail}`;
|
|
16931
17062
|
}
|
|
16932
17063
|
|
|
16933
|
-
// packages/dbx-components-mcp/src/tools/model-validate/types.ts
|
|
16934
|
-
var MAX_FIELD_NAME_LENGTH = 5;
|
|
16935
|
-
var ROOT_MODEL_ORDER = ["identity", "interface", "rolesType", "documentClass", "converter", "referenceFn", "collectionType", "collectionFn"];
|
|
16936
|
-
var SUBCOLLECTION_MODEL_ORDER = ["identity", "interface", "rolesType", "documentClass", "converter", "referenceFn", "collectionType", "collectionFactoryType", "collectionFn", "referenceGroupFn", "collectionGroupType", "collectionGroupFn"];
|
|
16937
|
-
|
|
16938
17064
|
// packages/dbx-components-mcp/src/tools/model-validate/rules.ts
|
|
16939
|
-
function runRules(file, options) {
|
|
17065
|
+
function runRules(file, options, context) {
|
|
16940
17066
|
const violations = [];
|
|
16941
17067
|
if (file.models.length === 0) {
|
|
17068
|
+
checkSubObjectFactoryCallSites(file, violations, context);
|
|
16942
17069
|
return violations;
|
|
16943
17070
|
}
|
|
16944
17071
|
checkFileLevel(file, violations);
|
|
@@ -16951,6 +17078,8 @@ function runRules(file, options) {
|
|
|
16951
17078
|
checkDeclarationOrder(file, model, violations);
|
|
16952
17079
|
}
|
|
16953
17080
|
checkFieldNameLengths(file, violations, options);
|
|
17081
|
+
checkSubObjectInterfaceTags(file, violations);
|
|
17082
|
+
checkSubObjectFactoryCallSites(file, violations, context);
|
|
16954
17083
|
return violations;
|
|
16955
17084
|
}
|
|
16956
17085
|
function checkFieldNameLengths(file, violations, options) {
|
|
@@ -16974,9 +17103,10 @@ function checkFieldNameLengths(file, violations, options) {
|
|
|
16974
17103
|
});
|
|
16975
17104
|
}
|
|
16976
17105
|
}
|
|
16977
|
-
checkFieldJsDocs(file, violations);
|
|
17106
|
+
checkFieldJsDocs(file, violations, options);
|
|
16978
17107
|
}
|
|
16979
|
-
function checkFieldJsDocs(file, violations) {
|
|
17108
|
+
function checkFieldJsDocs(file, violations, options) {
|
|
17109
|
+
const ignored = options?.ignoredFieldNames;
|
|
16980
17110
|
for (const iface of file.dataInterfaces) {
|
|
16981
17111
|
for (const field of iface.fields) {
|
|
16982
17112
|
if (!field.jsDocFirstLine) {
|
|
@@ -16989,7 +17119,8 @@ function checkFieldJsDocs(file, violations) {
|
|
|
16989
17119
|
model: iface.name
|
|
16990
17120
|
});
|
|
16991
17121
|
}
|
|
16992
|
-
|
|
17122
|
+
const fieldRulesApply = iface.dbxModelTag || iface.dbxModelSubObjectTag;
|
|
17123
|
+
if (fieldRulesApply && field.dbxModelVariableTag === void 0) {
|
|
16993
17124
|
pushViolation(violations, {
|
|
16994
17125
|
code: "MODEL_FIELD_MISSING_VARIABLE_TAG",
|
|
16995
17126
|
severity: "warning",
|
|
@@ -16999,7 +17130,60 @@ function checkFieldJsDocs(file, violations) {
|
|
|
16999
17130
|
model: iface.name
|
|
17000
17131
|
});
|
|
17001
17132
|
}
|
|
17133
|
+
if (fieldRulesApply && field.dbxModelVariableTag !== void 0 && field.dbxModelVariableTag === field.name && !ignored?.has(field.name)) {
|
|
17134
|
+
pushViolation(violations, {
|
|
17135
|
+
code: "MODEL_FIELD_LONG_NAME_EQUALS_NAME",
|
|
17136
|
+
severity: "warning",
|
|
17137
|
+
message: `Field \`${field.name}\` in interface \`${iface.name}\` has \`@dbxModelVariable ${field.dbxModelVariableTag}\` matching its short name. The long name should be the field's unabbreviated camelCase variable name (e.g. \`h\` \u2192 \`hours\`, \`ub\` \u2192 \`usedBudget\`). If the short name is already the unabbreviated form, add \`${field.name}\` to \`modelValidate.ignoredFieldNames\` in \`dbx-mcp.config.json\`.`,
|
|
17138
|
+
file: file.name,
|
|
17139
|
+
line: field.line,
|
|
17140
|
+
model: iface.name
|
|
17141
|
+
});
|
|
17142
|
+
}
|
|
17143
|
+
}
|
|
17144
|
+
}
|
|
17145
|
+
}
|
|
17146
|
+
function checkSubObjectInterfaceTags(file, violations) {
|
|
17147
|
+
for (const iface of file.dataInterfaces) {
|
|
17148
|
+
if (iface.dbxModelTag && iface.dbxModelSubObjectTag) {
|
|
17149
|
+
pushViolation(violations, {
|
|
17150
|
+
code: "MODEL_SUBOBJECT_TAG_CONFLICT",
|
|
17151
|
+
message: `Interface \`${iface.name}\` carries both \`@dbxModel\` and \`@dbxModelSubObject\`. Use only \`@dbxModel\` for top-level Firestore models; use \`@dbxModelSubObject\` only for embedded sub-objects without a \`firestoreModelIdentity\`.`,
|
|
17152
|
+
file: file.name,
|
|
17153
|
+
line: iface.line,
|
|
17154
|
+
model: iface.name
|
|
17155
|
+
});
|
|
17156
|
+
}
|
|
17157
|
+
}
|
|
17158
|
+
}
|
|
17159
|
+
function checkSubObjectFactoryCallSites(file, violations, context) {
|
|
17160
|
+
if (!context) {
|
|
17161
|
+
return;
|
|
17162
|
+
}
|
|
17163
|
+
if (file.subObjectCalls.length === 0) {
|
|
17164
|
+
return;
|
|
17165
|
+
}
|
|
17166
|
+
for (const call of file.subObjectCalls) {
|
|
17167
|
+
const entry = context.interfacesByName.get(call.typeArgName);
|
|
17168
|
+
if (!entry) {
|
|
17169
|
+
continue;
|
|
17170
|
+
}
|
|
17171
|
+
const { iface, file: declFile } = entry;
|
|
17172
|
+
if (iface.dbxModelTag || iface.dbxModelSubObjectTag) {
|
|
17173
|
+
continue;
|
|
17174
|
+
}
|
|
17175
|
+
if (context.emittedSubObjectInterfaces.has(call.typeArgName)) {
|
|
17176
|
+
continue;
|
|
17002
17177
|
}
|
|
17178
|
+
context.emittedSubObjectInterfaces.add(call.typeArgName);
|
|
17179
|
+
pushViolation(violations, {
|
|
17180
|
+
code: "MODEL_SUBOBJECT_NOT_TAGGED",
|
|
17181
|
+
severity: "warning",
|
|
17182
|
+
message: `Interface \`${iface.name}\` is referenced by \`${call.factoryName}<${iface.name}>(...)\` at ${file.name}:${call.line} but carries neither \`@dbxModel\` nor \`@dbxModelSubObject\`. Tag the interface with \`@dbxModelSubObject\` so its persisted fields are subject to the same \`@dbxModelVariable\` long-name checks as a top-level model.`,
|
|
17183
|
+
file: declFile,
|
|
17184
|
+
line: iface.line,
|
|
17185
|
+
model: iface.name
|
|
17186
|
+
});
|
|
17003
17187
|
}
|
|
17004
17188
|
}
|
|
17005
17189
|
function checkFileLevel(file, violations) {
|
|
@@ -17703,10 +17887,15 @@ function validateFirebaseModelSources(sources, options) {
|
|
|
17703
17887
|
let modelsChecked = 0;
|
|
17704
17888
|
let errorCount = 0;
|
|
17705
17889
|
let warningCount = 0;
|
|
17890
|
+
const extracteds = [];
|
|
17706
17891
|
for (const source of sources) {
|
|
17707
17892
|
const extracted = extractFile(source);
|
|
17893
|
+
extracteds.push(extracted);
|
|
17708
17894
|
modelsChecked += extracted.models.length;
|
|
17709
|
-
|
|
17895
|
+
}
|
|
17896
|
+
const context = buildCrossFileRuleContext(extracteds);
|
|
17897
|
+
for (const extracted of extracteds) {
|
|
17898
|
+
const fileViolations = runRules(extracted, options, context);
|
|
17710
17899
|
for (const v of fileViolations) {
|
|
17711
17900
|
violations.push(v);
|
|
17712
17901
|
if (v.severity === "error") {
|
|
@@ -17725,6 +17914,22 @@ function validateFirebaseModelSources(sources, options) {
|
|
|
17725
17914
|
};
|
|
17726
17915
|
return result;
|
|
17727
17916
|
}
|
|
17917
|
+
function buildCrossFileRuleContext(extracteds) {
|
|
17918
|
+
const interfacesByName = /* @__PURE__ */ new Map();
|
|
17919
|
+
for (const file of extracteds) {
|
|
17920
|
+
for (const iface of file.dataInterfaces) {
|
|
17921
|
+
if (interfacesByName.has(iface.name)) {
|
|
17922
|
+
continue;
|
|
17923
|
+
}
|
|
17924
|
+
interfacesByName.set(iface.name, { file: file.name, iface });
|
|
17925
|
+
}
|
|
17926
|
+
}
|
|
17927
|
+
const context = {
|
|
17928
|
+
interfacesByName,
|
|
17929
|
+
emittedSubObjectInterfaces: /* @__PURE__ */ new Set()
|
|
17930
|
+
};
|
|
17931
|
+
return context;
|
|
17932
|
+
}
|
|
17728
17933
|
|
|
17729
17934
|
// packages/dbx-components-mcp/src/tools/model-validate.tool.ts
|
|
17730
17935
|
var DBX_MODEL_VALIDATE_TOOL = {
|
|
@@ -17779,7 +17984,7 @@ var modelValidateTool = /* @__PURE__ */ createModelValidateTool();
|
|
|
17779
17984
|
var runModelValidate = modelValidateTool.run;
|
|
17780
17985
|
|
|
17781
17986
|
// packages/dbx-components-mcp/src/tools/model-validate-api/extract.ts
|
|
17782
|
-
import { Node as
|
|
17987
|
+
import { Node as Node12, Project as Project5, SyntaxKind as SyntaxKind5 } from "ts-morph";
|
|
17783
17988
|
function extractFile2(source) {
|
|
17784
17989
|
const project = new Project5({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
|
|
17785
17990
|
const sourceFile = project.createSourceFile(source.name, source.text, { overwrite: true });
|
|
@@ -17945,7 +18150,7 @@ function findCrudConfigType(sourceFile) {
|
|
|
17945
18150
|
continue;
|
|
17946
18151
|
}
|
|
17947
18152
|
const typeNode = alias.getTypeNode();
|
|
17948
|
-
const summary = typeNode &&
|
|
18153
|
+
const summary = typeNode && Node12.isTypeLiteral(typeNode) ? summarizeCrudConfigType(typeNode) : { keys: [], nonNullKeys: [], bareLeafParamsNames: [] };
|
|
17949
18154
|
const result = {
|
|
17950
18155
|
name: alias.getName(),
|
|
17951
18156
|
exported: alias.isExported(),
|
|
@@ -17959,14 +18164,14 @@ function findCrudConfigType(sourceFile) {
|
|
|
17959
18164
|
return void 0;
|
|
17960
18165
|
}
|
|
17961
18166
|
function summarizeCrudConfigType(typeLiteral) {
|
|
17962
|
-
if (!
|
|
18167
|
+
if (!Node12.isTypeLiteral(typeLiteral)) {
|
|
17963
18168
|
return { keys: [], nonNullKeys: [], bareLeafParamsNames: [] };
|
|
17964
18169
|
}
|
|
17965
18170
|
const keys = [];
|
|
17966
18171
|
const nonNullKeys = [];
|
|
17967
18172
|
const bareLeafParamsNames = [];
|
|
17968
18173
|
for (const member of typeLiteral.getMembers()) {
|
|
17969
|
-
if (!
|
|
18174
|
+
if (!Node12.isPropertySignature(member)) {
|
|
17970
18175
|
continue;
|
|
17971
18176
|
}
|
|
17972
18177
|
const name = member.getName();
|
|
@@ -17984,18 +18189,18 @@ function summarizeCrudConfigType(typeLiteral) {
|
|
|
17984
18189
|
return { keys, nonNullKeys, bareLeafParamsNames };
|
|
17985
18190
|
}
|
|
17986
18191
|
function isNullLiteralType(node) {
|
|
17987
|
-
if (
|
|
18192
|
+
if (Node12.isLiteralTypeNode(node)) {
|
|
17988
18193
|
const literal = node.getLiteral();
|
|
17989
|
-
if (
|
|
18194
|
+
if (Node12.isNullLiteral(literal)) {
|
|
17990
18195
|
return true;
|
|
17991
18196
|
}
|
|
17992
18197
|
}
|
|
17993
18198
|
return false;
|
|
17994
18199
|
}
|
|
17995
18200
|
function collectBareParamsLeaves(node, out) {
|
|
17996
|
-
if (
|
|
18201
|
+
if (Node12.isTypeLiteral(node)) {
|
|
17997
18202
|
for (const member of node.getMembers()) {
|
|
17998
|
-
if (!
|
|
18203
|
+
if (!Node12.isPropertySignature(member)) {
|
|
17999
18204
|
continue;
|
|
18000
18205
|
}
|
|
18001
18206
|
const valueNode = member.getTypeNode();
|
|
@@ -18005,10 +18210,10 @@ function collectBareParamsLeaves(node, out) {
|
|
|
18005
18210
|
}
|
|
18006
18211
|
return;
|
|
18007
18212
|
}
|
|
18008
|
-
if (
|
|
18213
|
+
if (Node12.isTupleTypeNode(node)) {
|
|
18009
18214
|
return;
|
|
18010
18215
|
}
|
|
18011
|
-
if (
|
|
18216
|
+
if (Node12.isTypeReference(node)) {
|
|
18012
18217
|
const name = node.getTypeName().getText();
|
|
18013
18218
|
if (name.endsWith("Params")) {
|
|
18014
18219
|
out.push(name);
|
|
@@ -18025,12 +18230,12 @@ function findCrudConfigConst(sourceFile) {
|
|
|
18025
18230
|
const typeNode = decl.getTypeNode();
|
|
18026
18231
|
const initializer = decl.getInitializer();
|
|
18027
18232
|
const runtimeKeys = [];
|
|
18028
|
-
if (initializer &&
|
|
18233
|
+
if (initializer && Node12.isAsExpression(initializer)) {
|
|
18029
18234
|
const inner = initializer.getExpression();
|
|
18030
|
-
if (
|
|
18235
|
+
if (Node12.isObjectLiteralExpression(inner)) {
|
|
18031
18236
|
runtimeKeys.push(...collectObjectLiteralKeys(inner));
|
|
18032
18237
|
}
|
|
18033
|
-
} else if (initializer &&
|
|
18238
|
+
} else if (initializer && Node12.isObjectLiteralExpression(initializer)) {
|
|
18034
18239
|
runtimeKeys.push(...collectObjectLiteralKeys(initializer));
|
|
18035
18240
|
}
|
|
18036
18241
|
const result = {
|
|
@@ -18048,7 +18253,7 @@ function findCrudConfigConst(sourceFile) {
|
|
|
18048
18253
|
function collectObjectLiteralKeys(obj) {
|
|
18049
18254
|
const out = [];
|
|
18050
18255
|
for (const prop of obj.getProperties()) {
|
|
18051
|
-
if (
|
|
18256
|
+
if (Node12.isPropertyAssignment(prop) || Node12.isShorthandPropertyAssignment(prop)) {
|
|
18052
18257
|
out.push(prop.getName());
|
|
18053
18258
|
}
|
|
18054
18259
|
}
|
|
@@ -18064,7 +18269,7 @@ function findFunctionMap(sourceFile) {
|
|
|
18064
18269
|
const initializer = decl.getInitializer();
|
|
18065
18270
|
let callsFactory = false;
|
|
18066
18271
|
const factoryArgs = [];
|
|
18067
|
-
if (initializer &&
|
|
18272
|
+
if (initializer && Node12.isCallExpression(initializer)) {
|
|
18068
18273
|
const exprText = initializer.getExpression().getText();
|
|
18069
18274
|
if (exprText === "callModelFirebaseFunctionMapFactory") {
|
|
18070
18275
|
callsFactory = true;
|
|
@@ -18202,18 +18407,18 @@ function extractCastTargetName(node) {
|
|
|
18202
18407
|
return void 0;
|
|
18203
18408
|
}
|
|
18204
18409
|
let current = node;
|
|
18205
|
-
while (current &&
|
|
18410
|
+
while (current && Node12.isAsExpression(current)) {
|
|
18206
18411
|
const typeNode = current.getTypeNode();
|
|
18207
18412
|
if (!typeNode) {
|
|
18208
18413
|
break;
|
|
18209
18414
|
}
|
|
18210
|
-
if (
|
|
18415
|
+
if (Node12.isTypeReference(typeNode)) {
|
|
18211
18416
|
const refName = typeNode.getTypeName().getText();
|
|
18212
18417
|
if (refName === "Type") {
|
|
18213
18418
|
const args = typeNode.getTypeArguments();
|
|
18214
18419
|
if (args.length === 1) {
|
|
18215
18420
|
const arg = args[0];
|
|
18216
|
-
if (
|
|
18421
|
+
if (Node12.isTypeReference(arg)) {
|
|
18217
18422
|
return arg.getTypeName().getText();
|
|
18218
18423
|
}
|
|
18219
18424
|
return arg.getText();
|
|
@@ -18232,7 +18437,7 @@ function extractValidatorProperties(initializer) {
|
|
|
18232
18437
|
}
|
|
18233
18438
|
const out = [];
|
|
18234
18439
|
for (const prop of obj.getProperties()) {
|
|
18235
|
-
if (!
|
|
18440
|
+
if (!Node12.isPropertyAssignment(prop)) {
|
|
18236
18441
|
continue;
|
|
18237
18442
|
}
|
|
18238
18443
|
const propAssignment = prop;
|
|
@@ -18242,7 +18447,7 @@ function extractValidatorProperties(initializer) {
|
|
|
18242
18447
|
const clean = optional ? stripped.slice(0, -1) : stripped;
|
|
18243
18448
|
const valueNode = propAssignment.getInitializer();
|
|
18244
18449
|
let hasClearable = false;
|
|
18245
|
-
if (valueNode &&
|
|
18450
|
+
if (valueNode && Node12.isCallExpression(valueNode)) {
|
|
18246
18451
|
const exprText = valueNode.getExpression().getText();
|
|
18247
18452
|
if (exprText === "clearable") {
|
|
18248
18453
|
hasClearable = true;
|
|
@@ -18254,25 +18459,25 @@ function extractValidatorProperties(initializer) {
|
|
|
18254
18459
|
}
|
|
18255
18460
|
function findArktypeObjectLiteral(initializer) {
|
|
18256
18461
|
let current = initializer;
|
|
18257
|
-
while (current &&
|
|
18462
|
+
while (current && Node12.isAsExpression(current)) {
|
|
18258
18463
|
current = current.getExpression();
|
|
18259
18464
|
}
|
|
18260
|
-
if (!current || !
|
|
18465
|
+
if (!current || !Node12.isCallExpression(current)) {
|
|
18261
18466
|
return void 0;
|
|
18262
18467
|
}
|
|
18263
18468
|
const expr = current.getExpression();
|
|
18264
|
-
if (
|
|
18469
|
+
if (Node12.isIdentifier(expr) && expr.getText() === "type") {
|
|
18265
18470
|
const args = current.getArguments();
|
|
18266
18471
|
const arg = args[0];
|
|
18267
|
-
if (arg &&
|
|
18472
|
+
if (arg && Node12.isObjectLiteralExpression(arg)) {
|
|
18268
18473
|
return arg;
|
|
18269
18474
|
}
|
|
18270
18475
|
return void 0;
|
|
18271
18476
|
}
|
|
18272
|
-
if (
|
|
18477
|
+
if (Node12.isPropertyAccessExpression(expr) && expr.getName() === "merge") {
|
|
18273
18478
|
const args = current.getArguments();
|
|
18274
18479
|
const arg = args[0];
|
|
18275
|
-
if (arg &&
|
|
18480
|
+
if (arg && Node12.isObjectLiteralExpression(arg)) {
|
|
18276
18481
|
return arg;
|
|
18277
18482
|
}
|
|
18278
18483
|
}
|
|
@@ -18957,7 +19162,7 @@ import { readdir as readdir2, readFile as readFile4, stat as stat4 } from "node:
|
|
|
18957
19162
|
import { join as join4, relative as relative4, sep as sep5 } from "node:path";
|
|
18958
19163
|
|
|
18959
19164
|
// packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts
|
|
18960
|
-
import { Node as
|
|
19165
|
+
import { Node as Node13, Project as Project6 } from "ts-morph";
|
|
18961
19166
|
var SUPPORTED_VERBS = /* @__PURE__ */ new Set(["create", "read", "update", "delete", "query"]);
|
|
18962
19167
|
function extractCrudEntries(source) {
|
|
18963
19168
|
const project = new Project6({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
|
|
@@ -18983,9 +19188,9 @@ function extractCrudEntries(source) {
|
|
|
18983
19188
|
};
|
|
18984
19189
|
if (crudConfigType) {
|
|
18985
19190
|
const literal = crudConfigType.getTypeNode();
|
|
18986
|
-
if (literal &&
|
|
19191
|
+
if (literal && Node13.isTypeLiteral(literal)) {
|
|
18987
19192
|
for (const member of literal.getMembers()) {
|
|
18988
|
-
if (!
|
|
19193
|
+
if (!Node13.isPropertySignature(member)) {
|
|
18989
19194
|
continue;
|
|
18990
19195
|
}
|
|
18991
19196
|
const modelName = member.getName();
|
|
@@ -18997,9 +19202,9 @@ function extractCrudEntries(source) {
|
|
|
18997
19202
|
if (isNullLiteralType2(valueNode)) {
|
|
18998
19203
|
continue;
|
|
18999
19204
|
}
|
|
19000
|
-
if (
|
|
19205
|
+
if (Node13.isTypeLiteral(valueNode)) {
|
|
19001
19206
|
for (const verbMember of valueNode.getMembers()) {
|
|
19002
|
-
if (!
|
|
19207
|
+
if (!Node13.isPropertySignature(verbMember)) {
|
|
19003
19208
|
continue;
|
|
19004
19209
|
}
|
|
19005
19210
|
const verbName = verbMember.getName();
|
|
@@ -19020,9 +19225,9 @@ function extractCrudEntries(source) {
|
|
|
19020
19225
|
const functionTypeMap = findTypeAliasByEnding(sourceFile, "FunctionTypeMap");
|
|
19021
19226
|
if (functionTypeMap) {
|
|
19022
19227
|
const literal = functionTypeMap.getTypeNode();
|
|
19023
|
-
if (literal &&
|
|
19228
|
+
if (literal && Node13.isTypeLiteral(literal)) {
|
|
19024
19229
|
for (const member of literal.getMembers()) {
|
|
19025
|
-
if (!
|
|
19230
|
+
if (!Node13.isPropertySignature(member)) {
|
|
19026
19231
|
continue;
|
|
19027
19232
|
}
|
|
19028
19233
|
const key = member.getName();
|
|
@@ -19090,9 +19295,9 @@ function inferGroupName2(sourceFile) {
|
|
|
19090
19295
|
return void 0;
|
|
19091
19296
|
}
|
|
19092
19297
|
function isNullLiteralType2(node) {
|
|
19093
|
-
if (
|
|
19298
|
+
if (Node13.isLiteralTypeNode(node)) {
|
|
19094
19299
|
const literal = node.getLiteral();
|
|
19095
|
-
if (
|
|
19300
|
+
if (Node13.isNullLiteral(literal)) {
|
|
19096
19301
|
return true;
|
|
19097
19302
|
}
|
|
19098
19303
|
}
|
|
@@ -19100,9 +19305,9 @@ function isNullLiteralType2(node) {
|
|
|
19100
19305
|
}
|
|
19101
19306
|
function collectVerbEntries(input) {
|
|
19102
19307
|
const { modelName, verb, valueNode, entries, fallbackDescription, resolveTypeDocs } = input;
|
|
19103
|
-
if (
|
|
19308
|
+
if (Node13.isTypeLiteral(valueNode)) {
|
|
19104
19309
|
for (const specMember of valueNode.getMembers()) {
|
|
19105
|
-
if (!
|
|
19310
|
+
if (!Node13.isPropertySignature(specMember)) {
|
|
19106
19311
|
continue;
|
|
19107
19312
|
}
|
|
19108
19313
|
const specifier = specMember.getName();
|
|
@@ -19144,7 +19349,7 @@ function collectVerbEntries(input) {
|
|
|
19144
19349
|
});
|
|
19145
19350
|
}
|
|
19146
19351
|
function readTupleParamsResult(node) {
|
|
19147
|
-
if (!
|
|
19352
|
+
if (!Node13.isTupleTypeNode(node)) {
|
|
19148
19353
|
return void 0;
|
|
19149
19354
|
}
|
|
19150
19355
|
const elements = node.getElements();
|
|
@@ -19163,7 +19368,7 @@ function readBareParams(node) {
|
|
|
19163
19368
|
return { params, result: void 0 };
|
|
19164
19369
|
}
|
|
19165
19370
|
function typeNodeName(node) {
|
|
19166
|
-
if (
|
|
19371
|
+
if (Node13.isTypeReference(node)) {
|
|
19167
19372
|
return node.getTypeName().getText();
|
|
19168
19373
|
}
|
|
19169
19374
|
const text = node.getText().trim();
|
|
@@ -20002,7 +20207,7 @@ async function collectApiFiles2(rootAbs) {
|
|
|
20002
20207
|
// packages/dbx-components-mcp/src/tools/model-api-validate-app/extract-handlers.ts
|
|
20003
20208
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
20004
20209
|
import { join as join8 } from "node:path";
|
|
20005
|
-
import { Node as
|
|
20210
|
+
import { Node as Node14, Project as Project8 } from "ts-morph";
|
|
20006
20211
|
var HANDLER_MAP_REL = "src/app/function/model/crud.functions.ts";
|
|
20007
20212
|
var VERB_TOKENS = [
|
|
20008
20213
|
{ token: "Create", verb: "create" },
|
|
@@ -20030,7 +20235,7 @@ async function extractHandlerEntries(apiAbs, apiDir) {
|
|
|
20030
20235
|
const verb = matchVerbFromConstName(name);
|
|
20031
20236
|
if (!verb) continue;
|
|
20032
20237
|
const initializer = decl.getInitializer();
|
|
20033
|
-
if (!initializer || !
|
|
20238
|
+
if (!initializer || !Node14.isObjectLiteralExpression(initializer)) continue;
|
|
20034
20239
|
verbsFound.push(verb);
|
|
20035
20240
|
collectVerbMap({ verb, mapLiteral: initializer, sourceFileRel, entries });
|
|
20036
20241
|
}
|
|
@@ -20048,7 +20253,7 @@ function matchVerbFromConstName(name) {
|
|
|
20048
20253
|
function collectVerbMap(input) {
|
|
20049
20254
|
const { verb, mapLiteral, sourceFileRel, entries } = input;
|
|
20050
20255
|
for (const prop of mapLiteral.getProperties()) {
|
|
20051
|
-
if (!
|
|
20256
|
+
if (!Node14.isPropertyAssignment(prop)) continue;
|
|
20052
20257
|
const model = prop.getName();
|
|
20053
20258
|
const value = prop.getInitializer();
|
|
20054
20259
|
if (!value) continue;
|
|
@@ -20067,25 +20272,25 @@ function collectVerbMap(input) {
|
|
|
20067
20272
|
}
|
|
20068
20273
|
}
|
|
20069
20274
|
function readSpecifierHandler(node) {
|
|
20070
|
-
if (!
|
|
20275
|
+
if (!Node14.isCallExpression(node)) return void 0;
|
|
20071
20276
|
const expr = node.getExpression();
|
|
20072
20277
|
if (!expr.getText().endsWith("onCallSpecifierHandler")) return void 0;
|
|
20073
20278
|
const args = node.getArguments();
|
|
20074
20279
|
if (args.length === 0) return void 0;
|
|
20075
20280
|
const firstArg = args[0];
|
|
20076
|
-
if (!
|
|
20281
|
+
if (!Node14.isObjectLiteralExpression(firstArg)) return void 0;
|
|
20077
20282
|
const out = /* @__PURE__ */ new Map();
|
|
20078
20283
|
for (const prop of firstArg.getProperties()) {
|
|
20079
|
-
if (!
|
|
20284
|
+
if (!Node14.isPropertyAssignment(prop) && !Node14.isShorthandPropertyAssignment(prop)) continue;
|
|
20080
20285
|
const specifier = prop.getName();
|
|
20081
|
-
const handlerName = readBareHandlerName(
|
|
20286
|
+
const handlerName = readBareHandlerName(Node14.isPropertyAssignment(prop) ? prop.getInitializerOrThrow() : prop) ?? "(unresolved)";
|
|
20082
20287
|
out.set(specifier, handlerName);
|
|
20083
20288
|
}
|
|
20084
20289
|
return out;
|
|
20085
20290
|
}
|
|
20086
20291
|
function readBareHandlerName(node) {
|
|
20087
|
-
if (
|
|
20088
|
-
if (
|
|
20292
|
+
if (Node14.isIdentifier(node)) return node.getText();
|
|
20293
|
+
if (Node14.isShorthandPropertyAssignment(node)) return node.getName();
|
|
20089
20294
|
const text = node.getText().split(/\s|\(/)[0];
|
|
20090
20295
|
if (/^[A-Za-z_]\w*$/.test(text)) return text;
|
|
20091
20296
|
return void 0;
|
|
@@ -21287,7 +21492,7 @@ function paramsHasFixtureDependencies(params) {
|
|
|
21287
21492
|
}
|
|
21288
21493
|
|
|
21289
21494
|
// packages/dbx-components-mcp/src/tools/model-fixture-shared/extract.ts
|
|
21290
|
-
import { Node as
|
|
21495
|
+
import { Node as Node15, Project as Project9, SyntaxKind as SyntaxKind7 } from "ts-morph";
|
|
21291
21496
|
|
|
21292
21497
|
// packages/dbx-components-mcp/src/tools/model-fixture-shared/framework-fixtures.ts
|
|
21293
21498
|
var KNOWN_NON_MODEL_FIXTURE_FAMILIES = [
|
|
@@ -21399,7 +21604,7 @@ function extendsByName(cls, baseName) {
|
|
|
21399
21604
|
const extendsClause = cls.getExtends();
|
|
21400
21605
|
if (!extendsClause) return false;
|
|
21401
21606
|
const expr = extendsClause.getExpression();
|
|
21402
|
-
if (
|
|
21607
|
+
if (Node15.isIdentifier(expr)) {
|
|
21403
21608
|
return expr.getText() === baseName;
|
|
21404
21609
|
}
|
|
21405
21610
|
return extendsClause.getText().startsWith(baseName);
|
|
@@ -21527,14 +21732,14 @@ function readContextFactory(decl) {
|
|
|
21527
21732
|
const initializer = decl.getInitializer();
|
|
21528
21733
|
if (!initializer) return void 0;
|
|
21529
21734
|
let bodyExpr;
|
|
21530
|
-
if (
|
|
21735
|
+
if (Node15.isArrowFunction(initializer) || Node15.isFunctionExpression(initializer)) {
|
|
21531
21736
|
bodyExpr = readSingleReturnExpression(initializer);
|
|
21532
21737
|
} else {
|
|
21533
21738
|
bodyExpr = initializer;
|
|
21534
21739
|
}
|
|
21535
|
-
if (!bodyExpr || !
|
|
21740
|
+
if (!bodyExpr || !Node15.isCallExpression(bodyExpr)) return void 0;
|
|
21536
21741
|
const callee = bodyExpr.getExpression();
|
|
21537
|
-
if (!
|
|
21742
|
+
if (!Node15.isIdentifier(callee)) return void 0;
|
|
21538
21743
|
const calleeName = callee.getText();
|
|
21539
21744
|
let family;
|
|
21540
21745
|
if (calleeName !== MODEL_FACTORY_NAME) {
|
|
@@ -21549,9 +21754,9 @@ function readContextFactory(decl) {
|
|
|
21549
21754
|
let parentFixtureFieldFromGetCollection;
|
|
21550
21755
|
if (args.length > 0) {
|
|
21551
21756
|
const first = args[0];
|
|
21552
|
-
if (
|
|
21757
|
+
if (Node15.isObjectLiteralExpression(first)) {
|
|
21553
21758
|
const getCollection = first.getProperty("getCollection");
|
|
21554
|
-
if (getCollection &&
|
|
21759
|
+
if (getCollection && Node15.isPropertyAssignment(getCollection)) {
|
|
21555
21760
|
const fnInit = getCollection.getInitializer();
|
|
21556
21761
|
const arity = readArrowParameterCount(fnInit);
|
|
21557
21762
|
if (arity >= 2) {
|
|
@@ -21602,7 +21807,7 @@ function familyFromExtends(cls) {
|
|
|
21602
21807
|
if (!ext) return void 0;
|
|
21603
21808
|
const expr = ext.getExpression();
|
|
21604
21809
|
let baseName;
|
|
21605
|
-
if (
|
|
21810
|
+
if (Node15.isIdentifier(expr)) {
|
|
21606
21811
|
baseName = expr.getText();
|
|
21607
21812
|
} else {
|
|
21608
21813
|
const text = ext.getText();
|
|
@@ -21615,9 +21820,9 @@ function familyFromExtends(cls) {
|
|
|
21615
21820
|
function readSingleReturnExpression(fn) {
|
|
21616
21821
|
const body = fn.getBody();
|
|
21617
21822
|
if (!body) return void 0;
|
|
21618
|
-
if (
|
|
21823
|
+
if (Node15.isBlock(body)) {
|
|
21619
21824
|
for (const stmt of body.getStatements()) {
|
|
21620
|
-
if (
|
|
21825
|
+
if (Node15.isReturnStatement(stmt)) {
|
|
21621
21826
|
return stmt.getExpression();
|
|
21622
21827
|
}
|
|
21623
21828
|
}
|
|
@@ -21627,19 +21832,19 @@ function readSingleReturnExpression(fn) {
|
|
|
21627
21832
|
}
|
|
21628
21833
|
function readArrowParameterCount(fn) {
|
|
21629
21834
|
if (!fn) return 0;
|
|
21630
|
-
if (
|
|
21835
|
+
if (Node15.isArrowFunction(fn) || Node15.isFunctionExpression(fn) || Node15.isFunctionDeclaration(fn) || Node15.isMethodDeclaration(fn)) {
|
|
21631
21836
|
return fn.getParameters().length;
|
|
21632
21837
|
}
|
|
21633
21838
|
return 0;
|
|
21634
21839
|
}
|
|
21635
21840
|
function readParamsAccessFieldName(fn) {
|
|
21636
21841
|
if (!fn) return void 0;
|
|
21637
|
-
if (!
|
|
21842
|
+
if (!Node15.isArrowFunction(fn) && !Node15.isFunctionExpression(fn)) return void 0;
|
|
21638
21843
|
const body = fn.getBody();
|
|
21639
21844
|
if (!body) return void 0;
|
|
21640
21845
|
for (const access2 of body.getDescendantsOfKind(SyntaxKind7.PropertyAccessExpression)) {
|
|
21641
21846
|
const expr = access2.getExpression();
|
|
21642
|
-
if (
|
|
21847
|
+
if (Node15.isIdentifier(expr) && expr.getText() === "params") {
|
|
21643
21848
|
return access2.getName();
|
|
21644
21849
|
}
|
|
21645
21850
|
}
|
|
@@ -21680,9 +21885,9 @@ function collectSingletonsByFactory(sourceFile) {
|
|
|
21680
21885
|
for (const stmt of sourceFile.getVariableStatements()) {
|
|
21681
21886
|
for (const decl of stmt.getDeclarations()) {
|
|
21682
21887
|
const init = decl.getInitializer();
|
|
21683
|
-
if (!init || !
|
|
21888
|
+
if (!init || !Node15.isCallExpression(init)) continue;
|
|
21684
21889
|
const callee = init.getExpression();
|
|
21685
|
-
if (!
|
|
21890
|
+
if (!Node15.isIdentifier(callee)) continue;
|
|
21686
21891
|
out.set(callee.getText(), decl.getName());
|
|
21687
21892
|
}
|
|
21688
21893
|
}
|
|
@@ -22930,7 +23135,7 @@ import { resolve as resolve32 } from "node:path";
|
|
|
22930
23135
|
import { type as type47 } from "arktype";
|
|
22931
23136
|
|
|
22932
23137
|
// packages/dbx-components-mcp/src/tools/model-test-shared/extract.ts
|
|
22933
|
-
import { Node as
|
|
23138
|
+
import { Node as Node16, Project as Project11, SyntaxKind as SyntaxKind8 } from "ts-morph";
|
|
22934
23139
|
var SPEC_FILE_VIRTUAL_PATH = "__spec__/spec.ts";
|
|
22935
23140
|
var FIXTURE_CONTEXT_SUFFIX = "Context";
|
|
22936
23141
|
var FIXTURE_FACTORY_SUFFIX = "ContextFactory";
|
|
@@ -22951,9 +23156,9 @@ function extractSpecTreeFromText(input) {
|
|
|
22951
23156
|
const counts = { describe: 0, it: 0, fixture: 0 };
|
|
22952
23157
|
const rootChildren = [];
|
|
22953
23158
|
for (const stmt of sourceFile.getStatements()) {
|
|
22954
|
-
if (!
|
|
23159
|
+
if (!Node16.isExpressionStatement(stmt)) continue;
|
|
22955
23160
|
const expr = stmt.getExpression();
|
|
22956
|
-
if (!
|
|
23161
|
+
if (!Node16.isCallExpression(expr)) continue;
|
|
22957
23162
|
const node = walkCall(expr, { prefix, knownFixtureNames, helperNames, counts });
|
|
22958
23163
|
if (node !== void 0) {
|
|
22959
23164
|
rootChildren.push(node);
|
|
@@ -23119,7 +23324,7 @@ function fixtureNode(input) {
|
|
|
23119
23324
|
const { call, calleeName, ctx, line, endLine } = input;
|
|
23120
23325
|
const args = call.getArguments();
|
|
23121
23326
|
const argsObject = args[0];
|
|
23122
|
-
const parentVars =
|
|
23327
|
+
const parentVars = Node16.isObjectLiteralExpression(argsObject) ? readParentVars(argsObject) : [];
|
|
23123
23328
|
const callback = findCallback(call);
|
|
23124
23329
|
const varName = callback === void 0 ? void 0 : readCallbackVarName(callback);
|
|
23125
23330
|
const model = stripFixturePrefix(calleeName, ctx.prefix);
|
|
@@ -23157,11 +23362,11 @@ function stripFixturePrefix(name, prefix) {
|
|
|
23157
23362
|
}
|
|
23158
23363
|
function readTitle(arg) {
|
|
23159
23364
|
if (arg === void 0) return { title: void 0, titleIsTemplate: false };
|
|
23160
|
-
if (
|
|
23365
|
+
if (Node16.isStringLiteral(arg) || Node16.isNoSubstitutionTemplateLiteral(arg)) {
|
|
23161
23366
|
const result2 = { title: arg.getLiteralText(), titleIsTemplate: false };
|
|
23162
23367
|
return result2;
|
|
23163
23368
|
}
|
|
23164
|
-
if (
|
|
23369
|
+
if (Node16.isTemplateExpression(arg)) {
|
|
23165
23370
|
const result2 = { title: arg.getText(), titleIsTemplate: true };
|
|
23166
23371
|
return result2;
|
|
23167
23372
|
}
|
|
@@ -23172,7 +23377,7 @@ function findCallback(call) {
|
|
|
23172
23377
|
const args = call.getArguments();
|
|
23173
23378
|
for (let i = args.length - 1; i >= 0; i--) {
|
|
23174
23379
|
const a = args[i];
|
|
23175
|
-
if (
|
|
23380
|
+
if (Node16.isArrowFunction(a) || Node16.isFunctionExpression(a)) {
|
|
23176
23381
|
return a;
|
|
23177
23382
|
}
|
|
23178
23383
|
}
|
|
@@ -23183,7 +23388,7 @@ function readCallbackVarName(callback) {
|
|
|
23183
23388
|
if (params.length === 0) return void 0;
|
|
23184
23389
|
const first = params[0];
|
|
23185
23390
|
const nameNode = first.getNameNode();
|
|
23186
|
-
if (
|
|
23391
|
+
if (Node16.isIdentifier(nameNode)) {
|
|
23187
23392
|
return nameNode.getText();
|
|
23188
23393
|
}
|
|
23189
23394
|
return void 0;
|
|
@@ -23191,13 +23396,13 @@ function readCallbackVarName(callback) {
|
|
|
23191
23396
|
function readParentVars(obj) {
|
|
23192
23397
|
const out = [];
|
|
23193
23398
|
for (const prop of obj.getProperties()) {
|
|
23194
|
-
if (
|
|
23399
|
+
if (Node16.isShorthandPropertyAssignment(prop)) {
|
|
23195
23400
|
out.push(prop.getName());
|
|
23196
23401
|
continue;
|
|
23197
23402
|
}
|
|
23198
|
-
if (
|
|
23403
|
+
if (Node16.isPropertyAssignment(prop)) {
|
|
23199
23404
|
const init = prop.getInitializer();
|
|
23200
|
-
if (init !== void 0 &&
|
|
23405
|
+
if (init !== void 0 && Node16.isIdentifier(init)) {
|
|
23201
23406
|
out.push(init.getText());
|
|
23202
23407
|
}
|
|
23203
23408
|
}
|
|
@@ -23206,10 +23411,10 @@ function readParentVars(obj) {
|
|
|
23206
23411
|
}
|
|
23207
23412
|
function walkCallbackBody(callback, ctx) {
|
|
23208
23413
|
const body = callback.getBody();
|
|
23209
|
-
if (
|
|
23414
|
+
if (Node16.isBlock(body)) {
|
|
23210
23415
|
return walkBlock(body, ctx);
|
|
23211
23416
|
}
|
|
23212
|
-
if (
|
|
23417
|
+
if (Node16.isCallExpression(body)) {
|
|
23213
23418
|
const child = walkCall(body, ctx);
|
|
23214
23419
|
return child === void 0 ? [] : [child];
|
|
23215
23420
|
}
|
|
@@ -23218,9 +23423,9 @@ function walkCallbackBody(callback, ctx) {
|
|
|
23218
23423
|
function walkBlock(block, ctx) {
|
|
23219
23424
|
const children = [];
|
|
23220
23425
|
for (const stmt of block.getStatements()) {
|
|
23221
|
-
if (!
|
|
23426
|
+
if (!Node16.isExpressionStatement(stmt)) continue;
|
|
23222
23427
|
const expr = stmt.getExpression();
|
|
23223
|
-
if (!
|
|
23428
|
+
if (!Node16.isCallExpression(expr)) continue;
|
|
23224
23429
|
const child = walkCall(expr, ctx);
|
|
23225
23430
|
if (child !== void 0) {
|
|
23226
23431
|
children.push(child);
|
|
@@ -23230,7 +23435,7 @@ function walkBlock(block, ctx) {
|
|
|
23230
23435
|
}
|
|
23231
23436
|
function getCalleeName(call) {
|
|
23232
23437
|
const expr = call.getExpression();
|
|
23233
|
-
if (
|
|
23438
|
+
if (Node16.isIdentifier(expr)) return expr.getText();
|
|
23234
23439
|
return void 0;
|
|
23235
23440
|
}
|
|
23236
23441
|
function collectHelpers(sourceFile) {
|
|
@@ -23246,7 +23451,7 @@ function collectHelpers(sourceFile) {
|
|
|
23246
23451
|
for (const decl of v.getDeclarations()) {
|
|
23247
23452
|
const init = decl.getInitializer();
|
|
23248
23453
|
if (init === void 0) continue;
|
|
23249
|
-
if (!
|
|
23454
|
+
if (!Node16.isArrowFunction(init) && !Node16.isFunctionExpression(init)) continue;
|
|
23250
23455
|
const usage = scanForDescribeOrIt(init);
|
|
23251
23456
|
if (!usage.emitsDescribe && !usage.emitsIt) continue;
|
|
23252
23457
|
out.push({ name: decl.getName(), line: decl.getStartLineNumber(), endLine: decl.getEndLineNumber(), emitsDescribe: usage.emitsDescribe, emitsIt: usage.emitsIt });
|
|
@@ -23260,7 +23465,7 @@ function scanForDescribeOrIt(node) {
|
|
|
23260
23465
|
if (descendant.getKind() !== SyntaxKind8.CallExpression) return;
|
|
23261
23466
|
const call = descendant;
|
|
23262
23467
|
const expr = call.getExpression();
|
|
23263
|
-
if (!
|
|
23468
|
+
if (!Node16.isIdentifier(expr)) return;
|
|
23264
23469
|
const name = expr.getText();
|
|
23265
23470
|
if (DESCRIBE_NAMES.has(name)) usage.emitsDescribe = true;
|
|
23266
23471
|
if (isItName(name)) usage.emitsIt = true;
|
|
@@ -24033,10 +24238,10 @@ var modelHierarchyTool = {
|
|
|
24033
24238
|
};
|
|
24034
24239
|
|
|
24035
24240
|
// packages/dbx-components-mcp/src/tools/storagefile-m-validate-app/extract.ts
|
|
24036
|
-
import { Node as
|
|
24241
|
+
import { Node as Node18, SyntaxKind as SyntaxKind10 } from "ts-morph";
|
|
24037
24242
|
|
|
24038
24243
|
// packages/dbx-components-mcp/src/tools/_validate/ast.ts
|
|
24039
|
-
import { Node as
|
|
24244
|
+
import { Node as Node17, Project as Project12, SyntaxKind as SyntaxKind9 } from "ts-morph";
|
|
24040
24245
|
var COMPONENT_VIRTUAL_PREFIX = "__component__/";
|
|
24041
24246
|
var API_VIRTUAL_PREFIX = "__api__/";
|
|
24042
24247
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -24061,28 +24266,28 @@ function componentRelPath(sourceFile) {
|
|
|
24061
24266
|
}
|
|
24062
24267
|
function unwrapAsExpressions(node) {
|
|
24063
24268
|
let current = node;
|
|
24064
|
-
while (current &&
|
|
24269
|
+
while (current && Node17.isAsExpression(current)) {
|
|
24065
24270
|
current = current.getExpression();
|
|
24066
24271
|
}
|
|
24067
24272
|
return current;
|
|
24068
24273
|
}
|
|
24069
24274
|
function asObjectLiteral(node) {
|
|
24070
24275
|
const inner = unwrapAsExpressions(node);
|
|
24071
|
-
if (inner &&
|
|
24276
|
+
if (inner && Node17.isObjectLiteralExpression(inner)) {
|
|
24072
24277
|
return inner;
|
|
24073
24278
|
}
|
|
24074
24279
|
return void 0;
|
|
24075
24280
|
}
|
|
24076
24281
|
function asArrayLiteral(node) {
|
|
24077
24282
|
const inner = unwrapAsExpressions(node);
|
|
24078
|
-
if (inner &&
|
|
24283
|
+
if (inner && Node17.isArrayLiteralExpression(inner)) {
|
|
24079
24284
|
return inner;
|
|
24080
24285
|
}
|
|
24081
24286
|
return void 0;
|
|
24082
24287
|
}
|
|
24083
24288
|
function readStringLiteralInitializer(decl) {
|
|
24084
24289
|
const initializer = unwrapAsExpressions(decl.getInitializer());
|
|
24085
|
-
if (initializer &&
|
|
24290
|
+
if (initializer && Node17.isStringLiteral(initializer)) {
|
|
24086
24291
|
return initializer.getLiteralText();
|
|
24087
24292
|
}
|
|
24088
24293
|
return void 0;
|
|
@@ -24094,37 +24299,37 @@ function typeAnnotationText(node) {
|
|
|
24094
24299
|
function getPropertyInitializer(obj, name) {
|
|
24095
24300
|
const prop = obj.getProperty(name);
|
|
24096
24301
|
if (!prop) return void 0;
|
|
24097
|
-
if (
|
|
24302
|
+
if (Node17.isPropertyAssignment(prop)) {
|
|
24098
24303
|
return prop.getInitializer();
|
|
24099
24304
|
}
|
|
24100
|
-
if (
|
|
24305
|
+
if (Node17.isShorthandPropertyAssignment(prop)) {
|
|
24101
24306
|
return prop.getNameNode();
|
|
24102
24307
|
}
|
|
24103
24308
|
return void 0;
|
|
24104
24309
|
}
|
|
24105
24310
|
function readStringProperty2(obj, name) {
|
|
24106
24311
|
const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
|
|
24107
|
-
if (init &&
|
|
24312
|
+
if (init && Node17.isStringLiteral(init)) {
|
|
24108
24313
|
return init.getLiteralText();
|
|
24109
24314
|
}
|
|
24110
24315
|
return void 0;
|
|
24111
24316
|
}
|
|
24112
24317
|
function readIdentifierProperty(obj, name) {
|
|
24113
24318
|
const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
|
|
24114
|
-
if (init &&
|
|
24319
|
+
if (init && Node17.isIdentifier(init)) {
|
|
24115
24320
|
return init.getText();
|
|
24116
24321
|
}
|
|
24117
24322
|
return void 0;
|
|
24118
24323
|
}
|
|
24119
24324
|
function findReturnExpression(fn) {
|
|
24120
|
-
if (!
|
|
24325
|
+
if (!Node17.isArrowFunction(fn) && !Node17.isFunctionDeclaration(fn) && !Node17.isFunctionExpression(fn)) {
|
|
24121
24326
|
return void 0;
|
|
24122
24327
|
}
|
|
24123
24328
|
const body = fn.getBody();
|
|
24124
24329
|
if (!body) return void 0;
|
|
24125
|
-
if (
|
|
24330
|
+
if (Node17.isBlock(body)) {
|
|
24126
24331
|
for (const stmt of body.getStatements()) {
|
|
24127
|
-
if (
|
|
24332
|
+
if (Node17.isReturnStatement(stmt)) {
|
|
24128
24333
|
return stmt.getExpression();
|
|
24129
24334
|
}
|
|
24130
24335
|
}
|
|
@@ -24144,7 +24349,7 @@ function findLocalVariable(sf, name) {
|
|
|
24144
24349
|
return void 0;
|
|
24145
24350
|
}
|
|
24146
24351
|
function collectTypeofReferences(node, out) {
|
|
24147
|
-
if (
|
|
24352
|
+
if (Node17.isTypeQuery(node)) {
|
|
24148
24353
|
out.push(node.getExprName().getText());
|
|
24149
24354
|
return;
|
|
24150
24355
|
}
|
|
@@ -24346,7 +24551,7 @@ function buildApiFunctionIndex(sources) {
|
|
|
24346
24551
|
for (const decl of stmt.getDeclarations()) {
|
|
24347
24552
|
const initializer = unwrapAsExpressions(decl.getInitializer());
|
|
24348
24553
|
if (!initializer) continue;
|
|
24349
|
-
if (
|
|
24554
|
+
if (Node18.isArrowFunction(initializer) || Node18.isFunctionExpression(initializer)) {
|
|
24350
24555
|
map.set(decl.getName(), { node: initializer, sourceFile: sf });
|
|
24351
24556
|
}
|
|
24352
24557
|
}
|
|
@@ -24359,34 +24564,34 @@ function collectInitializerBindingsFromValue(options) {
|
|
|
24359
24564
|
const { node, sf, index, resolved, unresolved, visited } = options;
|
|
24360
24565
|
const inner = unwrapAsExpressions(node);
|
|
24361
24566
|
if (!inner) return false;
|
|
24362
|
-
if (
|
|
24567
|
+
if (Node18.isArrayLiteralExpression(inner)) {
|
|
24363
24568
|
for (const el of inner.getElements()) {
|
|
24364
|
-
if (
|
|
24569
|
+
if (Node18.isSpreadElement(el)) {
|
|
24365
24570
|
const spreadInner = el.getExpression();
|
|
24366
|
-
if (
|
|
24571
|
+
if (Node18.isIdentifier(spreadInner)) {
|
|
24367
24572
|
collectInitializerBindingsFromIdentifier({ name: spreadInner.getText(), sf, index, resolved, unresolved, visited });
|
|
24368
|
-
} else if (
|
|
24573
|
+
} else if (Node18.isCallExpression(spreadInner)) {
|
|
24369
24574
|
const callee = spreadInner.getExpression();
|
|
24370
|
-
if (
|
|
24575
|
+
if (Node18.isIdentifier(callee)) {
|
|
24371
24576
|
collectInitializerBindingsFromIdentifier({ name: callee.getText(), sf, index, resolved, unresolved, visited });
|
|
24372
24577
|
}
|
|
24373
24578
|
}
|
|
24374
24579
|
continue;
|
|
24375
24580
|
}
|
|
24376
24581
|
const elementInner = unwrapAsExpressions(el);
|
|
24377
|
-
if (elementInner &&
|
|
24582
|
+
if (elementInner && Node18.isIdentifier(elementInner)) {
|
|
24378
24583
|
resolved.push(elementInner.getText());
|
|
24379
24584
|
}
|
|
24380
24585
|
}
|
|
24381
24586
|
return true;
|
|
24382
24587
|
}
|
|
24383
|
-
if (
|
|
24588
|
+
if (Node18.isCallExpression(inner)) {
|
|
24384
24589
|
const callee = inner.getExpression();
|
|
24385
|
-
if (
|
|
24590
|
+
if (Node18.isIdentifier(callee)) {
|
|
24386
24591
|
return collectInitializerBindingsFromIdentifier({ name: callee.getText(), sf, index, resolved, unresolved, visited });
|
|
24387
24592
|
}
|
|
24388
24593
|
}
|
|
24389
|
-
if (
|
|
24594
|
+
if (Node18.isIdentifier(inner)) {
|
|
24390
24595
|
return collectInitializerBindingsFromIdentifier({ name: inner.getText(), sf, index, resolved, unresolved, visited });
|
|
24391
24596
|
}
|
|
24392
24597
|
return false;
|
|
@@ -24425,15 +24630,15 @@ function collectUploadInitializerArray(options) {
|
|
|
24425
24630
|
const { initializerArr, sf, index, direct, spreads, resolved, unresolved } = options;
|
|
24426
24631
|
const visited = /* @__PURE__ */ new Set();
|
|
24427
24632
|
for (const el of initializerArr.getElements()) {
|
|
24428
|
-
if (
|
|
24633
|
+
if (Node18.isSpreadElement(el)) {
|
|
24429
24634
|
const inner2 = el.getExpression();
|
|
24430
|
-
if (
|
|
24635
|
+
if (Node18.isIdentifier(inner2)) {
|
|
24431
24636
|
const name = inner2.getText();
|
|
24432
24637
|
spreads.push(name);
|
|
24433
24638
|
collectInitializerBindingsFromIdentifier({ name, sf, index, resolved, unresolved, visited });
|
|
24434
|
-
} else if (
|
|
24639
|
+
} else if (Node18.isCallExpression(inner2)) {
|
|
24435
24640
|
const callee = inner2.getExpression();
|
|
24436
|
-
if (
|
|
24641
|
+
if (Node18.isIdentifier(callee)) {
|
|
24437
24642
|
const name = callee.getText();
|
|
24438
24643
|
spreads.push(name);
|
|
24439
24644
|
collectInitializerBindingsFromIdentifier({ name, sf, index, resolved, unresolved, visited });
|
|
@@ -24442,7 +24647,7 @@ function collectUploadInitializerArray(options) {
|
|
|
24442
24647
|
continue;
|
|
24443
24648
|
}
|
|
24444
24649
|
const inner = unwrapAsExpressions(el);
|
|
24445
|
-
if (inner &&
|
|
24650
|
+
if (inner && Node18.isIdentifier(inner)) {
|
|
24446
24651
|
const name = inner.getText();
|
|
24447
24652
|
direct.push(name);
|
|
24448
24653
|
resolved.push(name);
|
|
@@ -24455,7 +24660,7 @@ function extractUploadServiceCalls(sources, index) {
|
|
|
24455
24660
|
const rel = apiRelPath(sf);
|
|
24456
24661
|
for (const call of sf.getDescendantsOfKind(SyntaxKind10.CallExpression)) {
|
|
24457
24662
|
const expr = call.getExpression();
|
|
24458
|
-
if (!
|
|
24663
|
+
if (!Node18.isIdentifier(expr) || expr.getText() !== UPLOAD_SERVICE_FACTORY) continue;
|
|
24459
24664
|
const args = call.getArguments();
|
|
24460
24665
|
const first = args[0] ? resolveObjectArg(args[0], sf) : void 0;
|
|
24461
24666
|
if (!first) continue;
|
|
@@ -24483,12 +24688,12 @@ function extractUploadServiceCalls(sources, index) {
|
|
|
24483
24688
|
function resolveObjectArg(node, sf) {
|
|
24484
24689
|
const inner = unwrapAsExpressions(node);
|
|
24485
24690
|
if (!inner) return void 0;
|
|
24486
|
-
if (
|
|
24487
|
-
if (
|
|
24691
|
+
if (Node18.isObjectLiteralExpression(inner)) return inner;
|
|
24692
|
+
if (Node18.isIdentifier(inner)) {
|
|
24488
24693
|
const declNode = findLocalVariable(sf, inner.getText());
|
|
24489
24694
|
if (declNode) {
|
|
24490
24695
|
const declInit = unwrapAsExpressions(declNode.getInitializer());
|
|
24491
|
-
if (declInit &&
|
|
24696
|
+
if (declInit && Node18.isObjectLiteralExpression(declInit)) {
|
|
24492
24697
|
return declInit;
|
|
24493
24698
|
}
|
|
24494
24699
|
}
|
|
@@ -24498,12 +24703,12 @@ function resolveObjectArg(node, sf) {
|
|
|
24498
24703
|
function resolveArrayFromProperty(obj, name, sf) {
|
|
24499
24704
|
const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
|
|
24500
24705
|
if (!init) return void 0;
|
|
24501
|
-
if (
|
|
24502
|
-
if (
|
|
24706
|
+
if (Node18.isArrayLiteralExpression(init)) return init;
|
|
24707
|
+
if (Node18.isIdentifier(init)) {
|
|
24503
24708
|
const declNode = findLocalVariable(sf, init.getText());
|
|
24504
24709
|
if (declNode) {
|
|
24505
24710
|
const declInit = unwrapAsExpressions(declNode.getInitializer());
|
|
24506
|
-
if (declInit &&
|
|
24711
|
+
if (declInit && Node18.isArrayLiteralExpression(declInit)) {
|
|
24507
24712
|
return declInit;
|
|
24508
24713
|
}
|
|
24509
24714
|
}
|
|
@@ -24514,11 +24719,11 @@ function enclosingFactoryName(node) {
|
|
|
24514
24719
|
let current = node.getParent();
|
|
24515
24720
|
let result;
|
|
24516
24721
|
while (current) {
|
|
24517
|
-
if (
|
|
24722
|
+
if (Node18.isFunctionDeclaration(current)) {
|
|
24518
24723
|
result = current.getName() ?? void 0;
|
|
24519
24724
|
break;
|
|
24520
24725
|
}
|
|
24521
|
-
if (
|
|
24726
|
+
if (Node18.isVariableDeclaration(current)) {
|
|
24522
24727
|
result = current.getName();
|
|
24523
24728
|
break;
|
|
24524
24729
|
}
|
|
@@ -24572,10 +24777,10 @@ function extractProcessingConfigFromDecl(decl, rel) {
|
|
|
24572
24777
|
function readFlowSubtasks(obj) {
|
|
24573
24778
|
const flowInit = unwrapAsExpressions(getPropertyInitializer(obj, "flow"));
|
|
24574
24779
|
const subtasks = [];
|
|
24575
|
-
if (flowInit &&
|
|
24780
|
+
if (flowInit && Node18.isArrayLiteralExpression(flowInit)) {
|
|
24576
24781
|
for (const el of flowInit.getElements()) {
|
|
24577
24782
|
const inner = unwrapAsExpressions(el);
|
|
24578
|
-
if (inner &&
|
|
24783
|
+
if (inner && Node18.isObjectLiteralExpression(inner)) {
|
|
24579
24784
|
const subtask = readIdentifierProperty(inner, "subtask");
|
|
24580
24785
|
if (subtask) subtasks.push(subtask);
|
|
24581
24786
|
}
|
|
@@ -24589,7 +24794,7 @@ function extractProcessingHandlerCalls(sources) {
|
|
|
24589
24794
|
const rel = apiRelPath(sf);
|
|
24590
24795
|
for (const call of sf.getDescendantsOfKind(SyntaxKind10.CallExpression)) {
|
|
24591
24796
|
const expr = call.getExpression();
|
|
24592
|
-
if (!
|
|
24797
|
+
if (!Node18.isIdentifier(expr) || expr.getText() !== PROCESSING_HANDLER_FACTORY) continue;
|
|
24593
24798
|
const args = call.getArguments();
|
|
24594
24799
|
const first = args[0] ? resolveObjectArg(args[0], sf) : void 0;
|
|
24595
24800
|
if (!first) continue;
|
|
@@ -24610,7 +24815,7 @@ function extractProcessingHandlerCalls(sources) {
|
|
|
24610
24815
|
}
|
|
24611
24816
|
function collectProcessorArrayElements(processorsArr, direct, spreads) {
|
|
24612
24817
|
for (const el of processorsArr.getElements()) {
|
|
24613
|
-
if (
|
|
24818
|
+
if (Node18.isSpreadElement(el)) {
|
|
24614
24819
|
addProcessorIdentifierName(el.getExpression(), spreads);
|
|
24615
24820
|
continue;
|
|
24616
24821
|
}
|
|
@@ -24622,13 +24827,13 @@ function collectProcessorArrayElements(processorsArr, direct, spreads) {
|
|
|
24622
24827
|
}
|
|
24623
24828
|
function addProcessorIdentifierName(node, bucket) {
|
|
24624
24829
|
if (!node) return;
|
|
24625
|
-
if (
|
|
24830
|
+
if (Node18.isIdentifier(node)) {
|
|
24626
24831
|
bucket.push(node.getText());
|
|
24627
24832
|
return;
|
|
24628
24833
|
}
|
|
24629
|
-
if (
|
|
24834
|
+
if (Node18.isCallExpression(node)) {
|
|
24630
24835
|
const callee = node.getExpression();
|
|
24631
|
-
if (
|
|
24836
|
+
if (Node18.isIdentifier(callee)) {
|
|
24632
24837
|
bucket.push(callee.getText());
|
|
24633
24838
|
}
|
|
24634
24839
|
}
|
|
@@ -25620,7 +25825,7 @@ var storageFileMValidateFolderTool = createTwoSideValidateTool({
|
|
|
25620
25825
|
});
|
|
25621
25826
|
|
|
25622
25827
|
// packages/dbx-components-mcp/src/tools/notification-m-validate-app/extract.ts
|
|
25623
|
-
import { Node as
|
|
25828
|
+
import { Node as Node19, SyntaxKind as SyntaxKind11 } from "ts-morph";
|
|
25624
25829
|
var NOTIF_TEMPLATE_TYPE = "NotificationTemplateType";
|
|
25625
25830
|
var NOTIF_TEMPLATE_TYPE_INFO = "NotificationTemplateTypeInfo";
|
|
25626
25831
|
var NOTIF_TEMPLATE_TYPE_INFO_ARRAY = "NotificationTemplateTypeInfo[]";
|
|
@@ -25741,7 +25946,7 @@ function extractTemplateInfoAggregates(sources) {
|
|
|
25741
25946
|
const ids = [];
|
|
25742
25947
|
for (const el of arr.getElements()) {
|
|
25743
25948
|
const inner = unwrapAsExpressions(el);
|
|
25744
|
-
if (inner &&
|
|
25949
|
+
if (inner && Node19.isIdentifier(inner)) {
|
|
25745
25950
|
ids.push(inner.getText());
|
|
25746
25951
|
}
|
|
25747
25952
|
}
|
|
@@ -25787,7 +25992,7 @@ function extractTaskAllTypesAggregates(sources) {
|
|
|
25787
25992
|
const ids = [];
|
|
25788
25993
|
for (const el of arr.getElements()) {
|
|
25789
25994
|
const inner = unwrapAsExpressions(el);
|
|
25790
|
-
if (inner &&
|
|
25995
|
+
if (inner && Node19.isIdentifier(inner)) {
|
|
25791
25996
|
ids.push(inner.getText());
|
|
25792
25997
|
}
|
|
25793
25998
|
}
|
|
@@ -25815,14 +26020,14 @@ function extractTaskCheckpointAliases(sources) {
|
|
|
25815
26020
|
return out;
|
|
25816
26021
|
}
|
|
25817
26022
|
function collectStringLiterals(node, out) {
|
|
25818
|
-
if (
|
|
26023
|
+
if (Node19.isLiteralTypeNode(node)) {
|
|
25819
26024
|
const lit = node.getLiteral();
|
|
25820
|
-
if (
|
|
26025
|
+
if (Node19.isStringLiteral(lit)) {
|
|
25821
26026
|
out.push(lit.getLiteralText());
|
|
25822
26027
|
}
|
|
25823
26028
|
return;
|
|
25824
26029
|
}
|
|
25825
|
-
if (
|
|
26030
|
+
if (Node19.isUnionTypeNode(node)) {
|
|
25826
26031
|
for (const child of node.getTypeNodes()) {
|
|
25827
26032
|
collectStringLiterals(child, out);
|
|
25828
26033
|
}
|
|
@@ -25876,7 +26081,7 @@ function extractTemplateInfoRecord(sources, index) {
|
|
|
25876
26081
|
}
|
|
25877
26082
|
function tryReadTemplateInfoRecord(decl, rel, index) {
|
|
25878
26083
|
const initializer = unwrapAsExpressions(decl.getInitializer());
|
|
25879
|
-
if (!initializer || !
|
|
26084
|
+
if (!initializer || !Node19.isCallExpression(initializer)) return void 0;
|
|
25880
26085
|
if (initializer.getExpression().getText() !== TEMPLATE_INFO_RECORD_FACTORY) return void 0;
|
|
25881
26086
|
const args = initializer.getArguments();
|
|
25882
26087
|
const arr = args[0] ? asArrayLiteral(args[0]) : void 0;
|
|
@@ -25897,15 +26102,15 @@ function tryReadTemplateInfoRecord(decl, rel, index) {
|
|
|
25897
26102
|
}
|
|
25898
26103
|
function classifyInfoRecordArrayElements(arr, direct, spreads) {
|
|
25899
26104
|
for (const el of arr.getElements()) {
|
|
25900
|
-
if (
|
|
26105
|
+
if (Node19.isSpreadElement(el)) {
|
|
25901
26106
|
const inner2 = el.getExpression();
|
|
25902
|
-
if (
|
|
26107
|
+
if (Node19.isIdentifier(inner2)) {
|
|
25903
26108
|
spreads.push(inner2.getText());
|
|
25904
26109
|
}
|
|
25905
26110
|
continue;
|
|
25906
26111
|
}
|
|
25907
26112
|
const inner = unwrapAsExpressions(el);
|
|
25908
|
-
if (inner &&
|
|
26113
|
+
if (inner && Node19.isIdentifier(inner)) {
|
|
25909
26114
|
direct.push(inner.getText());
|
|
25910
26115
|
}
|
|
25911
26116
|
}
|
|
@@ -25932,7 +26137,7 @@ function extractTemplateInfoRecordWiring(sources) {
|
|
|
25932
26137
|
const first = args[0];
|
|
25933
26138
|
if (!first) continue;
|
|
25934
26139
|
const inner = unwrapAsExpressions(first);
|
|
25935
|
-
if (!inner || !
|
|
26140
|
+
if (!inner || !Node19.isIdentifier(inner)) continue;
|
|
25936
26141
|
const result = {
|
|
25937
26142
|
recordIdentifier: inner.getText(),
|
|
25938
26143
|
sourceFile: rel
|
|
@@ -25970,7 +26175,7 @@ function buildApiFunctionIndex2(sources) {
|
|
|
25970
26175
|
for (const decl of stmt.getDeclarations()) {
|
|
25971
26176
|
const initializer = unwrapAsExpressions(decl.getInitializer());
|
|
25972
26177
|
if (!initializer) continue;
|
|
25973
|
-
if (
|
|
26178
|
+
if (Node19.isArrowFunction(initializer) || Node19.isFunctionExpression(initializer)) {
|
|
25974
26179
|
map.set(decl.getName(), { node: initializer, sourceFile: sf, relPath: rel });
|
|
25975
26180
|
}
|
|
25976
26181
|
}
|
|
@@ -26006,11 +26211,11 @@ function extractTemplateConfigsArrayFactory(sources, index) {
|
|
|
26006
26211
|
const arr = returnExpr ? asArrayLiteral(returnExpr) : void 0;
|
|
26007
26212
|
if (arr) {
|
|
26008
26213
|
for (const el of arr.getElements()) {
|
|
26009
|
-
if (
|
|
26214
|
+
if (Node19.isSpreadElement(el)) {
|
|
26010
26215
|
const inner2 = el.getExpression();
|
|
26011
|
-
if (
|
|
26216
|
+
if (Node19.isCallExpression(inner2)) {
|
|
26012
26217
|
const callee = inner2.getExpression();
|
|
26013
|
-
if (
|
|
26218
|
+
if (Node19.isIdentifier(callee)) {
|
|
26014
26219
|
const callName = callee.getText();
|
|
26015
26220
|
spreadCalls.push(callName);
|
|
26016
26221
|
if (!index.functionsByName.has(callName)) {
|
|
@@ -26021,9 +26226,9 @@ function extractTemplateConfigsArrayFactory(sources, index) {
|
|
|
26021
26226
|
continue;
|
|
26022
26227
|
}
|
|
26023
26228
|
const inner = unwrapAsExpressions(el);
|
|
26024
|
-
if (inner &&
|
|
26229
|
+
if (inner && Node19.isCallExpression(inner)) {
|
|
26025
26230
|
const callee = inner.getExpression();
|
|
26026
|
-
if (
|
|
26231
|
+
if (Node19.isIdentifier(callee)) {
|
|
26027
26232
|
directCalls.push(callee.getText());
|
|
26028
26233
|
}
|
|
26029
26234
|
}
|
|
@@ -26072,11 +26277,11 @@ function collectFromArrayEntryFactory(name, out, index) {
|
|
|
26072
26277
|
const arr = asArrayLiteral(returnExpr);
|
|
26073
26278
|
if (!arr) return;
|
|
26074
26279
|
for (const el of arr.getElements()) {
|
|
26075
|
-
if (
|
|
26280
|
+
if (Node19.isSpreadElement(el)) {
|
|
26076
26281
|
const inner2 = el.getExpression();
|
|
26077
|
-
if (
|
|
26282
|
+
if (Node19.isCallExpression(inner2)) {
|
|
26078
26283
|
const callee = inner2.getExpression();
|
|
26079
|
-
if (
|
|
26284
|
+
if (Node19.isIdentifier(callee)) {
|
|
26080
26285
|
collectFromArrayEntryFactory(callee.getText(), out, index);
|
|
26081
26286
|
}
|
|
26082
26287
|
}
|
|
@@ -26084,9 +26289,9 @@ function collectFromArrayEntryFactory(name, out, index) {
|
|
|
26084
26289
|
}
|
|
26085
26290
|
const inner = unwrapAsExpressions(el);
|
|
26086
26291
|
if (!inner) continue;
|
|
26087
|
-
if (
|
|
26292
|
+
if (Node19.isCallExpression(inner)) {
|
|
26088
26293
|
const callee = inner.getExpression();
|
|
26089
|
-
if (
|
|
26294
|
+
if (Node19.isIdentifier(callee)) {
|
|
26090
26295
|
collectFromSingleEntryFactory(callee.getText(), out, index);
|
|
26091
26296
|
}
|
|
26092
26297
|
continue;
|
|
@@ -26106,7 +26311,7 @@ function extractTaskServiceCalls(sources, index, trustedExternal) {
|
|
|
26106
26311
|
const rel = apiRelPath(sf);
|
|
26107
26312
|
for (const call of sf.getDescendantsOfKind(SyntaxKind11.CallExpression)) {
|
|
26108
26313
|
const expr = call.getExpression();
|
|
26109
|
-
if (!
|
|
26314
|
+
if (!Node19.isIdentifier(expr) || expr.getText() !== TASK_SERVICE_FACTORY) continue;
|
|
26110
26315
|
const args = call.getArguments();
|
|
26111
26316
|
const first = args[0] ? asObjectLiteral(args[0]) : void 0;
|
|
26112
26317
|
if (!first) continue;
|
|
@@ -26132,13 +26337,13 @@ function collectValidateArrayElements(validateArr) {
|
|
|
26132
26337
|
const spreads = [];
|
|
26133
26338
|
if (!validateArr) return { ids, spreads };
|
|
26134
26339
|
for (const el of validateArr.getElements()) {
|
|
26135
|
-
if (
|
|
26340
|
+
if (Node19.isSpreadElement(el)) {
|
|
26136
26341
|
const inner2 = el.getExpression();
|
|
26137
|
-
if (
|
|
26342
|
+
if (Node19.isIdentifier(inner2)) spreads.push(inner2.getText());
|
|
26138
26343
|
continue;
|
|
26139
26344
|
}
|
|
26140
26345
|
const inner = unwrapAsExpressions(el);
|
|
26141
|
-
if (inner &&
|
|
26346
|
+
if (inner && Node19.isIdentifier(inner)) ids.push(inner.getText());
|
|
26142
26347
|
}
|
|
26143
26348
|
return { ids, spreads };
|
|
26144
26349
|
}
|
|
@@ -26151,17 +26356,17 @@ function collectHandlersArrayElements(options) {
|
|
|
26151
26356
|
if (!handlersArr) return { handlerTypes, unresolvedSpreads, resolvedBindings, unresolvedBindings };
|
|
26152
26357
|
const visited = /* @__PURE__ */ new Set();
|
|
26153
26358
|
for (const el of handlersArr.getElements()) {
|
|
26154
|
-
if (
|
|
26359
|
+
if (Node19.isSpreadElement(el)) {
|
|
26155
26360
|
consumeHandlersSpreadElement({ inner: el.getExpression(), sf, index, trustedExternal, unresolvedSpreads, resolvedBindings, unresolvedBindings, visited });
|
|
26156
26361
|
continue;
|
|
26157
26362
|
}
|
|
26158
26363
|
const inner = unwrapAsExpressions(el);
|
|
26159
26364
|
if (!inner) continue;
|
|
26160
|
-
if (
|
|
26365
|
+
if (Node19.isIdentifier(inner)) {
|
|
26161
26366
|
collectHandlerBindingsFromIdentifier({ name: inner.getText(), sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
|
|
26162
|
-
} else if (
|
|
26367
|
+
} else if (Node19.isCallExpression(inner)) {
|
|
26163
26368
|
const callee = inner.getExpression();
|
|
26164
|
-
if (
|
|
26369
|
+
if (Node19.isIdentifier(callee)) {
|
|
26165
26370
|
collectHandlerBindingsFromIdentifier({ name: callee.getText(), sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
|
|
26166
26371
|
}
|
|
26167
26372
|
}
|
|
@@ -26170,16 +26375,16 @@ function collectHandlersArrayElements(options) {
|
|
|
26170
26375
|
}
|
|
26171
26376
|
function consumeHandlersSpreadElement(options) {
|
|
26172
26377
|
const { inner, sf, index, trustedExternal, unresolvedSpreads, resolvedBindings, unresolvedBindings, visited } = options;
|
|
26173
|
-
if (
|
|
26378
|
+
if (Node19.isCallExpression(inner)) {
|
|
26174
26379
|
const callee = inner.getExpression();
|
|
26175
|
-
if (
|
|
26380
|
+
if (Node19.isIdentifier(callee)) {
|
|
26176
26381
|
const name = callee.getText();
|
|
26177
26382
|
unresolvedSpreads.push(name);
|
|
26178
26383
|
collectHandlerBindingsFromIdentifier({ name, sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
|
|
26179
26384
|
}
|
|
26180
26385
|
return;
|
|
26181
26386
|
}
|
|
26182
|
-
if (
|
|
26387
|
+
if (Node19.isIdentifier(inner)) {
|
|
26183
26388
|
const name = inner.getText();
|
|
26184
26389
|
unresolvedSpreads.push(name);
|
|
26185
26390
|
collectHandlerBindingsFromIdentifier({ name, sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
|
|
@@ -26189,15 +26394,31 @@ function collectHandlerBindingsFromValue(options) {
|
|
|
26189
26394
|
const { node, sf, index, trustedExternal, resolved, unresolved, visited } = options;
|
|
26190
26395
|
const inner = unwrapAsExpressions(node);
|
|
26191
26396
|
if (!inner) return false;
|
|
26192
|
-
if (
|
|
26397
|
+
if (Node19.isCallExpression(inner)) {
|
|
26193
26398
|
const callee = inner.getExpression();
|
|
26194
|
-
if (
|
|
26399
|
+
if (Node19.isIdentifier(callee)) {
|
|
26195
26400
|
return collectHandlerBindingsFromIdentifier({ name: callee.getText(), sf, index, trustedExternal, resolved, unresolved, visited });
|
|
26196
26401
|
}
|
|
26402
|
+
return false;
|
|
26197
26403
|
}
|
|
26198
|
-
if (
|
|
26404
|
+
if (Node19.isIdentifier(inner)) {
|
|
26199
26405
|
return collectHandlerBindingsFromIdentifier({ name: inner.getText(), sf, index, trustedExternal, resolved, unresolved, visited });
|
|
26200
26406
|
}
|
|
26407
|
+
if (Node19.isArrayLiteralExpression(inner)) {
|
|
26408
|
+
let any = false;
|
|
26409
|
+
for (const el of inner.getElements()) {
|
|
26410
|
+
if (Node19.isSpreadElement(el)) {
|
|
26411
|
+
if (collectHandlerBindingsFromValue({ node: el.getExpression(), sf, index, trustedExternal, resolved, unresolved, visited })) {
|
|
26412
|
+
any = true;
|
|
26413
|
+
}
|
|
26414
|
+
continue;
|
|
26415
|
+
}
|
|
26416
|
+
if (collectHandlerBindingsFromValue({ node: el, sf, index, trustedExternal, resolved, unresolved, visited })) {
|
|
26417
|
+
any = true;
|
|
26418
|
+
}
|
|
26419
|
+
}
|
|
26420
|
+
return any;
|
|
26421
|
+
}
|
|
26201
26422
|
return false;
|
|
26202
26423
|
}
|
|
26203
26424
|
function collectHandlerBindingsFromIdentifier(options) {
|
|
@@ -26212,7 +26433,7 @@ function collectHandlerBindingsFromIdentifier(options) {
|
|
|
26212
26433
|
const typeText = typeNode ? typeNode.getText() : void 0;
|
|
26213
26434
|
const isHandlerConfigTyped = typeText !== void 0 && (typeText === NOTIF_TASK_SERVICE_HANDLER_CONFIG || typeText.startsWith(`${NOTIF_TASK_SERVICE_HANDLER_CONFIG}<`));
|
|
26214
26435
|
const declInit = unwrapAsExpressions(localDecl.getInitializer());
|
|
26215
|
-
const isObjectLit = declInit !== void 0 &&
|
|
26436
|
+
const isObjectLit = declInit !== void 0 && Node19.isObjectLiteralExpression(declInit);
|
|
26216
26437
|
if (isHandlerConfigTyped && isObjectLit) {
|
|
26217
26438
|
resolved.push(localDecl.getName());
|
|
26218
26439
|
resolvedAny = true;
|
|
@@ -26243,12 +26464,12 @@ function collectHandlerBindingsFromIdentifier(options) {
|
|
|
26243
26464
|
function resolveArrayFromProperty2(obj, name, sf) {
|
|
26244
26465
|
const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
|
|
26245
26466
|
if (!init) return void 0;
|
|
26246
|
-
if (
|
|
26247
|
-
if (
|
|
26467
|
+
if (Node19.isArrayLiteralExpression(init)) return init;
|
|
26468
|
+
if (Node19.isIdentifier(init)) {
|
|
26248
26469
|
const declNode = findLocalVariable(sf, init.getText());
|
|
26249
26470
|
if (declNode) {
|
|
26250
26471
|
const declInit = unwrapAsExpressions(declNode.getInitializer());
|
|
26251
|
-
if (declInit &&
|
|
26472
|
+
if (declInit && Node19.isArrayLiteralExpression(declInit)) {
|
|
26252
26473
|
return declInit;
|
|
26253
26474
|
}
|
|
26254
26475
|
}
|
|
@@ -26269,12 +26490,12 @@ function extractTaskHandlerEntries(sources) {
|
|
|
26269
26490
|
if (!typeIdent) return;
|
|
26270
26491
|
const flowInit = unwrapAsExpressions(getPropertyInitializer(obj, "flow"));
|
|
26271
26492
|
let flowCount;
|
|
26272
|
-
if (flowInit &&
|
|
26493
|
+
if (flowInit && Node19.isArrayLiteralExpression(flowInit)) {
|
|
26273
26494
|
flowCount = flowInit.getElements().length;
|
|
26274
26495
|
}
|
|
26275
26496
|
let dataArg;
|
|
26276
26497
|
let checkpointArg;
|
|
26277
|
-
if (
|
|
26498
|
+
if (Node19.isTypeReference(typeNode)) {
|
|
26278
26499
|
const tArgs = typeNode.getTypeArguments();
|
|
26279
26500
|
if (tArgs.length >= 1) dataArg = tArgs[0].getText();
|
|
26280
26501
|
if (tArgs.length >= 2) checkpointArg = tArgs[1].getText();
|
|
@@ -27167,7 +27388,7 @@ async function inspectFolder2(path) {
|
|
|
27167
27388
|
}
|
|
27168
27389
|
|
|
27169
27390
|
// packages/dbx-components-mcp/src/tools/system-m-validate-folder/extract.ts
|
|
27170
|
-
import { Node as
|
|
27391
|
+
import { Node as Node20, Project as Project13 } from "ts-morph";
|
|
27171
27392
|
var TYPE_CONSTANT_SUFFIX = "_SYSTEM_STATE_TYPE";
|
|
27172
27393
|
var DATA_INTERFACE_SUFFIX = "SystemData";
|
|
27173
27394
|
var CONVERTER_CONFIG_TYPE = "SystemStateStoredDataFieldConverterConfig";
|
|
@@ -27231,7 +27452,7 @@ function findDataInterfaces2(sourceFile) {
|
|
|
27231
27452
|
return out;
|
|
27232
27453
|
}
|
|
27233
27454
|
function extendsSystemStateStoredData(iface) {
|
|
27234
|
-
if (!
|
|
27455
|
+
if (!Node20.isInterfaceDeclaration(iface)) return false;
|
|
27235
27456
|
for (const clause of iface.getExtends()) {
|
|
27236
27457
|
const text = clause.getText();
|
|
27237
27458
|
if (text === SYSTEM_STATE_STORED_DATA || text.startsWith(`${SYSTEM_STATE_STORED_DATA}<`) || text === `${SYSTEM_STATE_STORED_DATA}, ${SYSTEM_STATE_STORED_DATA}`) {
|
|
@@ -27251,14 +27472,14 @@ function findConverters2(sourceFile) {
|
|
|
27251
27472
|
for (const decl of stmt.getDeclarations()) {
|
|
27252
27473
|
const typeNode = decl.getTypeNode();
|
|
27253
27474
|
if (!typeNode) continue;
|
|
27254
|
-
if (!
|
|
27475
|
+
if (!Node20.isTypeReference(typeNode)) continue;
|
|
27255
27476
|
const typeName = typeNode.getTypeName().getText();
|
|
27256
27477
|
if (typeName !== CONVERTER_CONFIG_TYPE) continue;
|
|
27257
27478
|
const typeArgs = typeNode.getTypeArguments();
|
|
27258
27479
|
let dataTypeArgument;
|
|
27259
27480
|
if (typeArgs.length >= 1) {
|
|
27260
27481
|
const arg = typeArgs[0];
|
|
27261
|
-
if (
|
|
27482
|
+
if (Node20.isTypeReference(arg)) {
|
|
27262
27483
|
dataTypeArgument = arg.getTypeName().getText();
|
|
27263
27484
|
} else {
|
|
27264
27485
|
dataTypeArgument = arg.getText();
|
|
@@ -27305,19 +27526,19 @@ function collectConverterMapKeys(decl) {
|
|
|
27305
27526
|
if (!obj) return [];
|
|
27306
27527
|
const out = [];
|
|
27307
27528
|
for (const prop of obj.getProperties()) {
|
|
27308
|
-
if (!
|
|
27529
|
+
if (!Node20.isPropertyAssignment(prop)) continue;
|
|
27309
27530
|
const nameNode = prop.getNameNode();
|
|
27310
27531
|
const line = prop.getStartLineNumber();
|
|
27311
|
-
if (
|
|
27532
|
+
if (Node20.isComputedPropertyName(nameNode)) {
|
|
27312
27533
|
const inner = nameNode.getExpression();
|
|
27313
27534
|
out.push({ raw: inner.getText(), kind: "identifier", line });
|
|
27314
27535
|
continue;
|
|
27315
27536
|
}
|
|
27316
|
-
if (
|
|
27537
|
+
if (Node20.isStringLiteral(nameNode)) {
|
|
27317
27538
|
out.push({ raw: nameNode.getLiteralText(), kind: "string", line });
|
|
27318
27539
|
continue;
|
|
27319
27540
|
}
|
|
27320
|
-
if (
|
|
27541
|
+
if (Node20.isIdentifier(nameNode)) {
|
|
27321
27542
|
out.push({ raw: nameNode.getText(), kind: "string", line });
|
|
27322
27543
|
continue;
|
|
27323
27544
|
}
|
|
@@ -27327,10 +27548,10 @@ function collectConverterMapKeys(decl) {
|
|
|
27327
27548
|
}
|
|
27328
27549
|
function unwrapObjectLiteral(node) {
|
|
27329
27550
|
let current = node;
|
|
27330
|
-
while (current &&
|
|
27551
|
+
while (current && Node20.isAsExpression(current)) {
|
|
27331
27552
|
current = current.getExpression();
|
|
27332
27553
|
}
|
|
27333
|
-
if (current &&
|
|
27554
|
+
if (current && Node20.isObjectLiteralExpression(current)) {
|
|
27334
27555
|
return current;
|
|
27335
27556
|
}
|
|
27336
27557
|
return void 0;
|
|
@@ -27364,10 +27585,10 @@ function findLastTopLevelExportLine(sourceFile) {
|
|
|
27364
27585
|
return last;
|
|
27365
27586
|
}
|
|
27366
27587
|
function isExportedTopLevel(stmt) {
|
|
27367
|
-
if (
|
|
27588
|
+
if (Node20.isVariableStatement(stmt) || Node20.isFunctionDeclaration(stmt) || Node20.isClassDeclaration(stmt) || Node20.isInterfaceDeclaration(stmt) || Node20.isTypeAliasDeclaration(stmt) || Node20.isEnumDeclaration(stmt)) {
|
|
27368
27589
|
return stmt.isExported();
|
|
27369
27590
|
}
|
|
27370
|
-
if (
|
|
27591
|
+
if (Node20.isExportDeclaration(stmt) || Node20.isExportAssignment(stmt)) {
|
|
27371
27592
|
return true;
|
|
27372
27593
|
}
|
|
27373
27594
|
return false;
|
|
@@ -27678,7 +27899,7 @@ var systemMValidateFolderTool = createFolderValidateTool({
|
|
|
27678
27899
|
});
|
|
27679
27900
|
|
|
27680
27901
|
// packages/dbx-components-mcp/src/tools/dbx-asset-validate-app/extract.ts
|
|
27681
|
-
import { Node as
|
|
27902
|
+
import { Node as Node21, Project as Project14 } from "ts-morph";
|
|
27682
27903
|
var ASSETS_RELPATH = "src/lib/assets.ts";
|
|
27683
27904
|
var BARREL_RELPATH = "src/lib/index.ts";
|
|
27684
27905
|
var LOCAL_ASSET_BUILDER = "localAsset";
|
|
@@ -27737,11 +27958,11 @@ function extractFromAssetsSource(ctx, sf) {
|
|
|
27737
27958
|
const initializer = unwrapAsExpressions(decl.getInitializer());
|
|
27738
27959
|
if (!initializer) continue;
|
|
27739
27960
|
const site = { isExported, symbolName: decl.getName(), line: decl.getStartLineNumber(), rel };
|
|
27740
|
-
if (
|
|
27961
|
+
if (Node21.isCallExpression(initializer)) {
|
|
27741
27962
|
handleCallInitializer(ctx, site, initializer);
|
|
27742
27963
|
continue;
|
|
27743
27964
|
}
|
|
27744
|
-
if (isExported &&
|
|
27965
|
+
if (isExported && Node21.isArrayLiteralExpression(initializer) && typeAnnotationText(decl) === ASSET_PATH_REF_ARRAY_TYPE) {
|
|
27745
27966
|
ctx.aggregatorExports.push({ symbolName: site.symbolName, memberNames: collectArrayIdentifiers(initializer.getElements()), sourceFile: rel, line: site.line });
|
|
27746
27967
|
}
|
|
27747
27968
|
}
|
|
@@ -27751,7 +27972,7 @@ function collectArrayIdentifiers(elements) {
|
|
|
27751
27972
|
const out = [];
|
|
27752
27973
|
for (const el of elements) {
|
|
27753
27974
|
const inner = unwrapAsExpressions(el);
|
|
27754
|
-
if (inner &&
|
|
27975
|
+
if (inner && Node21.isIdentifier(inner)) {
|
|
27755
27976
|
out.push(inner.getText());
|
|
27756
27977
|
}
|
|
27757
27978
|
}
|
|
@@ -27759,11 +27980,11 @@ function collectArrayIdentifiers(elements) {
|
|
|
27759
27980
|
}
|
|
27760
27981
|
function handleCallInitializer(ctx, site, callExpr) {
|
|
27761
27982
|
const callee = callExpr.getExpression();
|
|
27762
|
-
if (
|
|
27983
|
+
if (Node21.isIdentifier(callee)) {
|
|
27763
27984
|
handleIdentifierCallee({ ctx, site, callExpr, calleeName: callee.getText() });
|
|
27764
27985
|
return;
|
|
27765
27986
|
}
|
|
27766
|
-
if (
|
|
27987
|
+
if (Node21.isPropertyAccessExpression(callee)) {
|
|
27767
27988
|
handleFluentMemberCall(ctx, site, callExpr);
|
|
27768
27989
|
}
|
|
27769
27990
|
}
|
|
@@ -27821,9 +28042,9 @@ function handleRemoteBaseBuilder(ctx, site, arg) {
|
|
|
27821
28042
|
}
|
|
27822
28043
|
function handleFluentMemberCall(ctx, site, callExpr) {
|
|
27823
28044
|
const callee = callExpr.getExpression();
|
|
27824
|
-
if (!
|
|
28045
|
+
if (!Node21.isPropertyAccessExpression(callee)) return;
|
|
27825
28046
|
const identNode = callee.getExpression();
|
|
27826
|
-
if (!
|
|
28047
|
+
if (!Node21.isIdentifier(identNode)) return;
|
|
27827
28048
|
const memberName = callee.getName();
|
|
27828
28049
|
if (memberName !== "asset" && memberName !== "assets") return;
|
|
27829
28050
|
const builderName = identNode.getText();
|
|
@@ -27848,7 +28069,7 @@ function handleFluentMemberCall(ctx, site, callExpr) {
|
|
|
27848
28069
|
return;
|
|
27849
28070
|
}
|
|
27850
28071
|
const arrayInner = unwrapAsExpressions(args[0]);
|
|
27851
|
-
if (!arrayInner || !
|
|
28072
|
+
if (!arrayInner || !Node21.isArrayLiteralExpression(arrayInner)) return;
|
|
27852
28073
|
const resolvedPaths = collectFluentArrayPaths({ elements: arrayInner.getElements(), sourceType, folder, remoteBase });
|
|
27853
28074
|
if (site.isExported) {
|
|
27854
28075
|
ctx.assetConstants.push({ symbolName: site.symbolName, sourceType, helper, resolved: void 0, resolvedPaths, sourceFile: site.rel, line: site.line });
|
|
@@ -27858,7 +28079,7 @@ function collectFluentArrayPaths(input) {
|
|
|
27858
28079
|
const out = [];
|
|
27859
28080
|
for (const el of input.elements) {
|
|
27860
28081
|
const inner = unwrapAsExpressions(el);
|
|
27861
|
-
if (inner &&
|
|
28082
|
+
if (inner && Node21.isStringLiteral(inner)) {
|
|
27862
28083
|
const joined = joinFluent({ sourceType: input.sourceType, folder: input.folder, remoteBase: input.remoteBase, child: inner.getLiteralText() });
|
|
27863
28084
|
if (joined !== void 0) out.push(joined);
|
|
27864
28085
|
}
|
|
@@ -27891,7 +28112,7 @@ function readStringArg(call) {
|
|
|
27891
28112
|
}
|
|
27892
28113
|
function readStringArgFromNode(node) {
|
|
27893
28114
|
const inner = unwrapAsExpressions(node);
|
|
27894
|
-
if (inner &&
|
|
28115
|
+
if (inner && Node21.isStringLiteral(inner)) {
|
|
27895
28116
|
return inner.getLiteralText();
|
|
27896
28117
|
}
|
|
27897
28118
|
return void 0;
|
|
@@ -29260,6 +29481,83 @@ export class EditProfilePageComponent {
|
|
|
29260
29481
|
notes: "`dbxActionForm` lives in `@dereekb/dbx-form` \u2014 it is the value provider in this composition. The form's `dbxFormSource` seeds the initial value and the form's modification status feeds `isModified` on the action store."
|
|
29261
29482
|
};
|
|
29262
29483
|
|
|
29484
|
+
// packages/dbx-components-mcp/src/tools/data/patterns/actions/action.form-with-secondary.pattern.ts
|
|
29485
|
+
var ACTION_PATTERN_FORM_WITH_SECONDARY = {
|
|
29486
|
+
slug: "form-with-secondary",
|
|
29487
|
+
name: "Form submit with secondary action button",
|
|
29488
|
+
summary: "Outer `dbxAction` + `dbxActionForm` drives a primary (Approve) button; a nested `<ng-container dbxAction>` with `dbxActionValue` provides an independent secondary (Deny / Cancel) button that fires a void handler.",
|
|
29489
|
+
usesActionSlugs: ["action", "handler", "value", "button", "error-handler"],
|
|
29490
|
+
snippets: {
|
|
29491
|
+
minimal: `<div dbxAction [dbxActionHandler]="handleApprove">
|
|
29492
|
+
<my-form dbxActionForm></my-form>
|
|
29493
|
+
<dbx-button text="Approve" dbxActionButton></dbx-button>
|
|
29494
|
+
<ng-container dbxAction dbxActionValue [dbxActionHandler]="handleDeny">
|
|
29495
|
+
<dbx-button text="Deny" dbxActionButton></dbx-button>
|
|
29496
|
+
</ng-container>
|
|
29497
|
+
</div>`,
|
|
29498
|
+
brief: `<div dbxAction dbxActionSnackbarError [dbxActionHandler]="handleApprove">
|
|
29499
|
+
<my-form dbxActionForm [dbxFormSource]="data$"></my-form>
|
|
29500
|
+
<dbx-button [raised]="true" text="Approve" color="primary" dbxActionButton></dbx-button>
|
|
29501
|
+
<dbx-button-spacer></dbx-button-spacer>
|
|
29502
|
+
<ng-container dbxAction dbxActionSnackbarError dbxActionValue [dbxActionHandler]="handleDeny">
|
|
29503
|
+
<dbx-button [flat]="true" text="Deny" color="warn" dbxActionButton></dbx-button>
|
|
29504
|
+
</ng-container>
|
|
29505
|
+
</div>`,
|
|
29506
|
+
full: `import { Component, signal } from '@angular/core';
|
|
29507
|
+
import { type WorkUsingContext } from '@dereekb/rxjs';
|
|
29508
|
+
|
|
29509
|
+
type ConsentDecision = { readonly outcome: 'approved'; readonly value: ConsentFormValue } | { readonly outcome: 'denied' };
|
|
29510
|
+
|
|
29511
|
+
@Component({
|
|
29512
|
+
selector: 'app-consent-page',
|
|
29513
|
+
template: \`
|
|
29514
|
+
<!-- Outer context: form-driven Approve -->
|
|
29515
|
+
<div dbxAction dbxActionSnackbarError [dbxActionHandler]="handleApprove">
|
|
29516
|
+
<my-consent-form dbxActionForm [dbxFormSource]="defaults$"></my-consent-form>
|
|
29517
|
+
|
|
29518
|
+
<div class="dbx-pt3">
|
|
29519
|
+
<dbx-button [raised]="true" text="Approve" color="primary" dbxActionButton></dbx-button>
|
|
29520
|
+
<dbx-button-spacer></dbx-button-spacer>
|
|
29521
|
+
|
|
29522
|
+
<!-- Nested context: void Deny. dbxActionValue with no input -->
|
|
29523
|
+
<!-- supplies the empty payload that lets the button fire. -->
|
|
29524
|
+
<ng-container dbxAction dbxActionSnackbarError dbxActionValue [dbxActionHandler]="handleDeny">
|
|
29525
|
+
<dbx-button [flat]="true" text="Deny" color="warn" dbxActionButton></dbx-button>
|
|
29526
|
+
</ng-container>
|
|
29527
|
+
</div>
|
|
29528
|
+
</div>
|
|
29529
|
+
|
|
29530
|
+
@let decision = lastDecisionSignal();
|
|
29531
|
+
@if (decision) {
|
|
29532
|
+
<div class="dbx-pt3">
|
|
29533
|
+
@if (decision.outcome === 'approved') {
|
|
29534
|
+
<span>Approved with: <strong>{{ decision.value | json }}</strong></span>
|
|
29535
|
+
} @else {
|
|
29536
|
+
<span>Denied.</span>
|
|
29537
|
+
}
|
|
29538
|
+
</div>
|
|
29539
|
+
}
|
|
29540
|
+
\`,
|
|
29541
|
+
standalone: true
|
|
29542
|
+
})
|
|
29543
|
+
export class ConsentPageComponent {
|
|
29544
|
+
readonly defaults$ = this.store.defaults$;
|
|
29545
|
+
readonly lastDecisionSignal = signal<ConsentDecision | undefined>(undefined);
|
|
29546
|
+
|
|
29547
|
+
readonly handleApprove: WorkUsingContext<ConsentFormValue, ConsentResult> = (value, context) => {
|
|
29548
|
+
this.lastDecisionSignal.set({ outcome: 'approved', value });
|
|
29549
|
+
context.startWorkingWithLoadingStateObservable(this.store.approve(value));
|
|
29550
|
+
};
|
|
29551
|
+
|
|
29552
|
+
readonly handleDeny: WorkUsingContext<void, ConsentResult> = (_, context) => {
|
|
29553
|
+
this.lastDecisionSignal.set({ outcome: 'denied' });
|
|
29554
|
+
context.startWorkingWithLoadingStateObservable(this.store.deny());
|
|
29555
|
+
};
|
|
29556
|
+
}`
|
|
29557
|
+
},
|
|
29558
|
+
notes: 'Two non-obvious mechanics: (1) Each `dbxAction` creates its own `ActionContextStore`. `dbxActionButton` and other child directives inject the **nearest ancestor** store via Angular DI, so the inner button picks up the inner context \u2014 not the outer. (2) `dbxActionValue` with no input emits the empty-string sentinel, which `filterMaybe()` lets through, so `readyValue("")` fires immediately when the secondary button triggers; that satisfies `dbxActionButton` without needing a form on the secondary path. Each context can carry its own `dbxActionSnackbarError` so success/error feedback stays scoped per button. This is the canonical OIDC consent shape used in `@dereekb/dbx-firebase` (`oauth.consent.view.component.ts`).'
|
|
29559
|
+
};
|
|
29560
|
+
|
|
29263
29561
|
// packages/dbx-components-mcp/src/tools/data/patterns/actions/action.provide-context-up.pattern.ts
|
|
29264
29562
|
var ACTION_PATTERN_PROVIDE_CONTEXT_UP = {
|
|
29265
29563
|
slug: "provide-context-up",
|
|
@@ -29369,7 +29667,7 @@ export class TagEditorComponent {
|
|
|
29369
29667
|
};
|
|
29370
29668
|
|
|
29371
29669
|
// packages/dbx-components-mcp/src/tools/data/patterns/action-patterns.ts
|
|
29372
|
-
var ACTION_EXAMPLE_PATTERNS = [ACTION_PATTERN_BUTTON_CONFIRM_DELETE, ACTION_PATTERN_FORM_SUBMIT, ACTION_PATTERN_AUTO_TRIGGER_ON_MODIFY, ACTION_PATTERN_DISABLED_BY_KEY, ACTION_PATTERN_VALUE_GETTER_ON_TRIGGER, ACTION_PATTERN_PROVIDE_CONTEXT_UP];
|
|
29670
|
+
var ACTION_EXAMPLE_PATTERNS = [ACTION_PATTERN_BUTTON_CONFIRM_DELETE, ACTION_PATTERN_FORM_SUBMIT, ACTION_PATTERN_FORM_WITH_SECONDARY, ACTION_PATTERN_AUTO_TRIGGER_ON_MODIFY, ACTION_PATTERN_DISABLED_BY_KEY, ACTION_PATTERN_VALUE_GETTER_ON_TRIGGER, ACTION_PATTERN_PROVIDE_CONTEXT_UP];
|
|
29373
29671
|
function getActionExamplePattern(slug) {
|
|
29374
29672
|
const lowered = slug.trim().toLowerCase();
|
|
29375
29673
|
return ACTION_EXAMPLE_PATTERNS.find((p) => p.slug === lowered);
|
|
@@ -29729,7 +30027,7 @@ import { glob as fsGlob5, readFile as readFile18, stat as stat14 } from "node:fs
|
|
|
29729
30027
|
import { dirname as dirname13, isAbsolute as isAbsolute13, resolve as resolve34, sep as sep12 } from "node:path";
|
|
29730
30028
|
|
|
29731
30029
|
// packages/dbx-components-mcp/src/tools/route/extract.ts
|
|
29732
|
-
import { Node as
|
|
30030
|
+
import { Node as Node22, Project as Project15, SyntaxKind as SyntaxKind12 } from "ts-morph";
|
|
29733
30031
|
function extractFile3(source) {
|
|
29734
30032
|
const project = new Project15({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
|
|
29735
30033
|
const sourceFile = project.createSourceFile(source.name, source.text, { overwrite: true });
|
|
@@ -29744,9 +30042,9 @@ function extractFile3(source) {
|
|
|
29744
30042
|
}
|
|
29745
30043
|
for (const arrayLit of findStateArrayLiterals(sourceFile)) {
|
|
29746
30044
|
for (const element of arrayLit.getElements()) {
|
|
29747
|
-
if (
|
|
30045
|
+
if (Node22.isObjectLiteralExpression(element)) {
|
|
29748
30046
|
addNode({ file: source.name, literal: element, fallbackConstName: void 0, into: collected, issues });
|
|
29749
|
-
} else if (
|
|
30047
|
+
} else if (Node22.isIdentifier(element)) {
|
|
29750
30048
|
const ref = objectLiteralsByName.get(element.getText());
|
|
29751
30049
|
if (ref) {
|
|
29752
30050
|
addNode({ file: source.name, literal: ref.literal, fallbackConstName: element.getText(), into: collected, issues });
|
|
@@ -29767,7 +30065,7 @@ function collectStateConsts(sourceFile) {
|
|
|
29767
30065
|
for (const stmt of sourceFile.getVariableStatements()) {
|
|
29768
30066
|
for (const decl of stmt.getDeclarations()) {
|
|
29769
30067
|
const initializer = decl.getInitializer();
|
|
29770
|
-
if (!initializer || !
|
|
30068
|
+
if (!initializer || !Node22.isObjectLiteralExpression(initializer)) {
|
|
29771
30069
|
continue;
|
|
29772
30070
|
}
|
|
29773
30071
|
const typeNode = decl.getTypeNode();
|
|
@@ -29782,7 +30080,7 @@ function findStateArrayLiterals(sourceFile) {
|
|
|
29782
30080
|
for (const stmt of sourceFile.getVariableStatements()) {
|
|
29783
30081
|
for (const decl of stmt.getDeclarations()) {
|
|
29784
30082
|
const initializer = decl.getInitializer();
|
|
29785
|
-
if (initializer &&
|
|
30083
|
+
if (initializer && Node22.isArrayLiteralExpression(initializer) && declarationIsStateArray(stmt, decl.getName(), initializer)) {
|
|
29786
30084
|
arrays.push(initializer);
|
|
29787
30085
|
}
|
|
29788
30086
|
}
|
|
@@ -29796,17 +30094,17 @@ function findStateArrayLiterals(sourceFile) {
|
|
|
29796
30094
|
continue;
|
|
29797
30095
|
}
|
|
29798
30096
|
for (const arg of call.getArguments()) {
|
|
29799
|
-
if (!
|
|
30097
|
+
if (!Node22.isObjectLiteralExpression(arg)) {
|
|
29800
30098
|
continue;
|
|
29801
30099
|
}
|
|
29802
30100
|
const statesProp = arg.getProperty("states");
|
|
29803
|
-
if (!statesProp || !
|
|
30101
|
+
if (!statesProp || !Node22.isPropertyAssignment(statesProp)) {
|
|
29804
30102
|
continue;
|
|
29805
30103
|
}
|
|
29806
30104
|
const initializer = statesProp.getInitializer();
|
|
29807
|
-
if (initializer &&
|
|
30105
|
+
if (initializer && Node22.isArrayLiteralExpression(initializer)) {
|
|
29808
30106
|
arrays.push(initializer);
|
|
29809
|
-
} else if (initializer &&
|
|
30107
|
+
} else if (initializer && Node22.isIdentifier(initializer)) {
|
|
29810
30108
|
const referenced = findArrayLiteralForIdentifier(sourceFile, initializer);
|
|
29811
30109
|
if (referenced) {
|
|
29812
30110
|
arrays.push(referenced);
|
|
@@ -29823,10 +30121,10 @@ function declarationIsStateArray(stmt, name, literal) {
|
|
|
29823
30121
|
return true;
|
|
29824
30122
|
}
|
|
29825
30123
|
for (const element of literal.getElements()) {
|
|
29826
|
-
if (
|
|
30124
|
+
if (Node22.isObjectLiteralExpression(element) && hasStringNameProperty(element)) {
|
|
29827
30125
|
return true;
|
|
29828
30126
|
}
|
|
29829
|
-
if (
|
|
30127
|
+
if (Node22.isIdentifier(element)) {
|
|
29830
30128
|
return true;
|
|
29831
30129
|
}
|
|
29832
30130
|
}
|
|
@@ -29834,11 +30132,11 @@ function declarationIsStateArray(stmt, name, literal) {
|
|
|
29834
30132
|
}
|
|
29835
30133
|
function hasStringNameProperty(literal) {
|
|
29836
30134
|
const nameProp = literal.getProperty("name");
|
|
29837
|
-
if (!nameProp || !
|
|
30135
|
+
if (!nameProp || !Node22.isPropertyAssignment(nameProp)) {
|
|
29838
30136
|
return false;
|
|
29839
30137
|
}
|
|
29840
30138
|
const initializer = nameProp.getInitializer();
|
|
29841
|
-
return initializer !== void 0 && (
|
|
30139
|
+
return initializer !== void 0 && (Node22.isStringLiteral(initializer) || Node22.isNoSubstitutionTemplateLiteral(initializer));
|
|
29842
30140
|
}
|
|
29843
30141
|
function findArrayLiteralForIdentifier(sourceFile, identifier) {
|
|
29844
30142
|
const name = identifier.getText();
|
|
@@ -29848,7 +30146,7 @@ function findArrayLiteralForIdentifier(sourceFile, identifier) {
|
|
|
29848
30146
|
continue;
|
|
29849
30147
|
}
|
|
29850
30148
|
const initializer = decl.getInitializer();
|
|
29851
|
-
if (initializer &&
|
|
30149
|
+
if (initializer && Node22.isArrayLiteralExpression(initializer)) {
|
|
29852
30150
|
return initializer;
|
|
29853
30151
|
}
|
|
29854
30152
|
}
|
|
@@ -29898,21 +30196,21 @@ function addNode(options) {
|
|
|
29898
30196
|
}
|
|
29899
30197
|
function stringPropertyValue(literal, key) {
|
|
29900
30198
|
const prop = literal.getProperty(key);
|
|
29901
|
-
if (!prop || !
|
|
30199
|
+
if (!prop || !Node22.isPropertyAssignment(prop)) {
|
|
29902
30200
|
return void 0;
|
|
29903
30201
|
}
|
|
29904
30202
|
const initializer = prop.getInitializer();
|
|
29905
30203
|
if (!initializer) {
|
|
29906
30204
|
return void 0;
|
|
29907
30205
|
}
|
|
29908
|
-
if (
|
|
30206
|
+
if (Node22.isStringLiteral(initializer) || Node22.isNoSubstitutionTemplateLiteral(initializer)) {
|
|
29909
30207
|
return initializer.getLiteralText();
|
|
29910
30208
|
}
|
|
29911
30209
|
return void 0;
|
|
29912
30210
|
}
|
|
29913
30211
|
function booleanPropertyValue(literal, key) {
|
|
29914
30212
|
const prop = literal.getProperty(key);
|
|
29915
|
-
if (!prop || !
|
|
30213
|
+
if (!prop || !Node22.isPropertyAssignment(prop)) {
|
|
29916
30214
|
return void 0;
|
|
29917
30215
|
}
|
|
29918
30216
|
const initializer = prop.getInitializer();
|
|
@@ -29929,33 +30227,33 @@ function booleanPropertyValue(literal, key) {
|
|
|
29929
30227
|
}
|
|
29930
30228
|
function identifierPropertyValue(literal, key) {
|
|
29931
30229
|
const prop = literal.getProperty(key);
|
|
29932
|
-
if (!prop || !
|
|
30230
|
+
if (!prop || !Node22.isPropertyAssignment(prop)) {
|
|
29933
30231
|
return void 0;
|
|
29934
30232
|
}
|
|
29935
30233
|
const initializer = prop.getInitializer();
|
|
29936
30234
|
if (!initializer) {
|
|
29937
30235
|
return void 0;
|
|
29938
30236
|
}
|
|
29939
|
-
if (
|
|
30237
|
+
if (Node22.isIdentifier(initializer)) {
|
|
29940
30238
|
return initializer.getText();
|
|
29941
30239
|
}
|
|
29942
|
-
if (
|
|
30240
|
+
if (Node22.isPropertyAccessExpression(initializer)) {
|
|
29943
30241
|
return initializer.getText();
|
|
29944
30242
|
}
|
|
29945
30243
|
return void 0;
|
|
29946
30244
|
}
|
|
29947
30245
|
function objectPropertyKeys(literal, key) {
|
|
29948
30246
|
const prop = literal.getProperty(key);
|
|
29949
|
-
if (!prop || !
|
|
30247
|
+
if (!prop || !Node22.isPropertyAssignment(prop)) {
|
|
29950
30248
|
return [];
|
|
29951
30249
|
}
|
|
29952
30250
|
const initializer = prop.getInitializer();
|
|
29953
|
-
if (!initializer || !
|
|
30251
|
+
if (!initializer || !Node22.isObjectLiteralExpression(initializer)) {
|
|
29954
30252
|
return [];
|
|
29955
30253
|
}
|
|
29956
30254
|
const out = [];
|
|
29957
30255
|
for (const member of initializer.getProperties()) {
|
|
29958
|
-
if (
|
|
30256
|
+
if (Node22.isPropertyAssignment(member) || Node22.isShorthandPropertyAssignment(member) || Node22.isMethodDeclaration(member)) {
|
|
29959
30257
|
const nameNode = member.getNameNode();
|
|
29960
30258
|
if (nameNode) {
|
|
29961
30259
|
out.push(nameNode.getText());
|
|
@@ -29966,7 +30264,7 @@ function objectPropertyKeys(literal, key) {
|
|
|
29966
30264
|
}
|
|
29967
30265
|
function collectResolveKeys(literal) {
|
|
29968
30266
|
const prop = literal.getProperty("resolve");
|
|
29969
|
-
if (!prop || !
|
|
30267
|
+
if (!prop || !Node22.isPropertyAssignment(prop)) {
|
|
29970
30268
|
return [];
|
|
29971
30269
|
}
|
|
29972
30270
|
const initializer = prop.getInitializer();
|
|
@@ -29974,22 +30272,22 @@ function collectResolveKeys(literal) {
|
|
|
29974
30272
|
return [];
|
|
29975
30273
|
}
|
|
29976
30274
|
const keys = [];
|
|
29977
|
-
if (
|
|
30275
|
+
if (Node22.isObjectLiteralExpression(initializer)) {
|
|
29978
30276
|
for (const member of initializer.getProperties()) {
|
|
29979
|
-
if (
|
|
30277
|
+
if (Node22.isPropertyAssignment(member) || Node22.isShorthandPropertyAssignment(member) || Node22.isMethodDeclaration(member)) {
|
|
29980
30278
|
const nameNode = member.getNameNode();
|
|
29981
30279
|
if (nameNode) {
|
|
29982
30280
|
keys.push(nameNode.getText());
|
|
29983
30281
|
}
|
|
29984
30282
|
}
|
|
29985
30283
|
}
|
|
29986
|
-
} else if (
|
|
30284
|
+
} else if (Node22.isArrayLiteralExpression(initializer)) {
|
|
29987
30285
|
for (const element of initializer.getElements()) {
|
|
29988
|
-
if (
|
|
30286
|
+
if (Node22.isObjectLiteralExpression(element)) {
|
|
29989
30287
|
const tokenProp = element.getProperty("token");
|
|
29990
|
-
if (tokenProp &&
|
|
30288
|
+
if (tokenProp && Node22.isPropertyAssignment(tokenProp)) {
|
|
29991
30289
|
const tokenInit = tokenProp.getInitializer();
|
|
29992
|
-
if (tokenInit && (
|
|
30290
|
+
if (tokenInit && (Node22.isStringLiteral(tokenInit) || Node22.isIdentifier(tokenInit))) {
|
|
29993
30291
|
keys.push(tokenInit.getText().replaceAll(/^['"]|['"]$/g, ""));
|
|
29994
30292
|
}
|
|
29995
30293
|
}
|
|
@@ -32058,7 +32356,7 @@ function createSearchModelSnapshotFieldTool(config) {
|
|
|
32058
32356
|
import { glob, readFile as readFile19 } from "node:fs/promises";
|
|
32059
32357
|
import { resolve as resolve35 } from "node:path";
|
|
32060
32358
|
import { type as type59 } from "arktype";
|
|
32061
|
-
import { Node as
|
|
32359
|
+
import { Node as Node23, Project as Project16 } from "ts-morph";
|
|
32062
32360
|
var ListAppArgsType2 = type59({
|
|
32063
32361
|
componentDir: "string",
|
|
32064
32362
|
"apiDir?": "string",
|
|
@@ -32188,7 +32486,7 @@ async function buildListAppReport(input) {
|
|
|
32188
32486
|
function findSnapshotConverterCalls(sourceFile) {
|
|
32189
32487
|
const out = [];
|
|
32190
32488
|
sourceFile.forEachDescendant((node) => {
|
|
32191
|
-
if (
|
|
32489
|
+
if (Node23.isCallExpression(node)) {
|
|
32192
32490
|
const expr = node.getExpression();
|
|
32193
32491
|
const exprText = expr.getText();
|
|
32194
32492
|
const head = exprText.replace(/<[^>]*>$/, "");
|
|
@@ -32203,17 +32501,17 @@ function readFieldsObject(call) {
|
|
|
32203
32501
|
const args = call.getArguments();
|
|
32204
32502
|
if (args.length === 0) return void 0;
|
|
32205
32503
|
const first = args[0];
|
|
32206
|
-
if (!
|
|
32504
|
+
if (!Node23.isObjectLiteralExpression(first)) return void 0;
|
|
32207
32505
|
const fieldsProp = first.getProperty("fields");
|
|
32208
|
-
if (fieldsProp === void 0 || !
|
|
32506
|
+
if (fieldsProp === void 0 || !Node23.isPropertyAssignment(fieldsProp)) return void 0;
|
|
32209
32507
|
const initializer = fieldsProp.getInitializer();
|
|
32210
|
-
if (initializer === void 0 || !
|
|
32508
|
+
if (initializer === void 0 || !Node23.isObjectLiteralExpression(initializer)) return void 0;
|
|
32211
32509
|
return initializer;
|
|
32212
32510
|
}
|
|
32213
32511
|
function resolveModelName(call) {
|
|
32214
32512
|
let current = call.getParent();
|
|
32215
32513
|
while (current !== void 0) {
|
|
32216
|
-
if (
|
|
32514
|
+
if (Node23.isVariableDeclaration(current)) {
|
|
32217
32515
|
return current.getName();
|
|
32218
32516
|
}
|
|
32219
32517
|
current = current.getParent();
|
|
@@ -32223,10 +32521,10 @@ function resolveModelName(call) {
|
|
|
32223
32521
|
function extractFieldUsages(fieldsObj, registry) {
|
|
32224
32522
|
const out = [];
|
|
32225
32523
|
for (const property of fieldsObj.getProperties()) {
|
|
32226
|
-
if (!
|
|
32524
|
+
if (!Node23.isPropertyAssignment(property) && !Node23.isShorthandPropertyAssignment(property)) continue;
|
|
32227
32525
|
const fieldName = property.getName();
|
|
32228
32526
|
let converterText;
|
|
32229
|
-
if (
|
|
32527
|
+
if (Node23.isShorthandPropertyAssignment(property)) {
|
|
32230
32528
|
converterText = property.getName();
|
|
32231
32529
|
} else {
|
|
32232
32530
|
const initializer = property.getInitializer();
|
|
@@ -33749,7 +34047,7 @@ import { type as type64 } from "arktype";
|
|
|
33749
34047
|
// packages/dbx-components-mcp/src/tools/model-list-component/extract.ts
|
|
33750
34048
|
import { readdir as readdir12, readFile as readFile20, stat as stat16 } from "node:fs/promises";
|
|
33751
34049
|
import { basename as basename6, join as join19, relative as relative11, sep as sep14 } from "node:path";
|
|
33752
|
-
import { Node as
|
|
34050
|
+
import { Node as Node24, Project as Project17 } from "ts-morph";
|
|
33753
34051
|
var MODEL_SUBPATH3 = "src/lib/model";
|
|
33754
34052
|
var MODEL_SUBPATH_PREFIX = `${MODEL_SUBPATH3}/`;
|
|
33755
34053
|
var RESERVED_NAMES = RESERVED_MODEL_FOLDERS.map((r) => r.name);
|
|
@@ -33890,7 +34188,7 @@ function findIdentityIn(sourceFile) {
|
|
|
33890
34188
|
for (const statement of sourceFile.getVariableStatements()) {
|
|
33891
34189
|
for (const decl of statement.getDeclarations()) {
|
|
33892
34190
|
const initializer = decl.getInitializer();
|
|
33893
|
-
if (!initializer || !
|
|
34191
|
+
if (!initializer || !Node24.isCallExpression(initializer)) continue;
|
|
33894
34192
|
if (initializer.getExpression().getText() !== "firestoreModelIdentity") continue;
|
|
33895
34193
|
const args = initializer.getArguments();
|
|
33896
34194
|
const parsed = parseIdentityArgs2(args);
|
|
@@ -33910,13 +34208,13 @@ function parseIdentityArgs2(args) {
|
|
|
33910
34208
|
return { parentIdentityRef: void 0, collectionName: stringLiteralValue3(args[0]), collectionPrefix: stringLiteralValue3(args[1]) };
|
|
33911
34209
|
}
|
|
33912
34210
|
if (args.length === 3) {
|
|
33913
|
-
const parent =
|
|
34211
|
+
const parent = Node24.isIdentifier(args[0]) ? args[0].getText() : void 0;
|
|
33914
34212
|
return { parentIdentityRef: parent, collectionName: stringLiteralValue3(args[1]), collectionPrefix: stringLiteralValue3(args[2]) };
|
|
33915
34213
|
}
|
|
33916
34214
|
return { parentIdentityRef: void 0, collectionName: void 0, collectionPrefix: void 0 };
|
|
33917
34215
|
}
|
|
33918
34216
|
function stringLiteralValue3(node) {
|
|
33919
|
-
if (
|
|
34217
|
+
if (Node24.isStringLiteral(node) || Node24.isNoSubstitutionTemplateLiteral(node)) {
|
|
33920
34218
|
return node.getLiteralText();
|
|
33921
34219
|
}
|
|
33922
34220
|
return void 0;
|
|
@@ -34078,7 +34376,7 @@ import { type as type65 } from "arktype";
|
|
|
34078
34376
|
// packages/dbx-components-mcp/src/tools/server-actions-list-app/extract.ts
|
|
34079
34377
|
import { readdir as readdir13, readFile as readFile21, stat as stat17 } from "node:fs/promises";
|
|
34080
34378
|
import { dirname as dirname14, join as join20, relative as relative12, sep as sep15 } from "node:path";
|
|
34081
|
-
import { Node as
|
|
34379
|
+
import { Node as Node25, Project as Project18 } from "ts-morph";
|
|
34082
34380
|
var ACTION_SERVER_SUFFIX2 = ".action.server.ts";
|
|
34083
34381
|
var COMMON_MODEL_SUBPATH2 = "src/app/common/model";
|
|
34084
34382
|
var COMMON_BARREL_REL = "src/app/common/index.ts";
|
|
@@ -34215,7 +34513,7 @@ function inspectModuleText(input) {
|
|
|
34215
34513
|
for (const decorator of cls.getDecorators()) {
|
|
34216
34514
|
if (decorator.getName() !== "Module") continue;
|
|
34217
34515
|
const args = decorator.getArguments();
|
|
34218
|
-
if (args.length === 0 || !
|
|
34516
|
+
if (args.length === 0 || !Node25.isObjectLiteralExpression(args[0])) continue;
|
|
34219
34517
|
const obj = args[0];
|
|
34220
34518
|
providedByModule ||= moduleArrayContains(obj, "providers", input.className);
|
|
34221
34519
|
exportedByModule ||= moduleArrayContains(obj, "exports", input.className);
|
|
@@ -34225,16 +34523,16 @@ function inspectModuleText(input) {
|
|
|
34225
34523
|
}
|
|
34226
34524
|
function moduleArrayContains(decoratorArg, propertyName, className) {
|
|
34227
34525
|
const property = decoratorArg.getProperty(propertyName);
|
|
34228
|
-
if (!property || !
|
|
34526
|
+
if (!property || !Node25.isPropertyAssignment(property)) return false;
|
|
34229
34527
|
const initializer = property.getInitializer();
|
|
34230
|
-
if (!initializer || !
|
|
34528
|
+
if (!initializer || !Node25.isArrayLiteralExpression(initializer)) return false;
|
|
34231
34529
|
for (const element of initializer.getElements()) {
|
|
34232
|
-
if (
|
|
34233
|
-
if (
|
|
34530
|
+
if (Node25.isIdentifier(element) && element.getText() === className) return true;
|
|
34531
|
+
if (Node25.isObjectLiteralExpression(element)) {
|
|
34234
34532
|
const provideProp = element.getProperty("provide");
|
|
34235
|
-
if (provideProp &&
|
|
34533
|
+
if (provideProp && Node25.isPropertyAssignment(provideProp)) {
|
|
34236
34534
|
const provideInit = provideProp.getInitializer();
|
|
34237
|
-
if (provideInit &&
|
|
34535
|
+
if (provideInit && Node25.isIdentifier(provideInit) && provideInit.getText() === className) return true;
|
|
34238
34536
|
}
|
|
34239
34537
|
}
|
|
34240
34538
|
}
|
|
@@ -34288,11 +34586,11 @@ function collectInterfaceGetters(sourceFile) {
|
|
|
34288
34586
|
const out = /* @__PURE__ */ new Map();
|
|
34289
34587
|
for (const iface of sourceFile.getInterfaces()) {
|
|
34290
34588
|
for (const member of iface.getMembers()) {
|
|
34291
|
-
if (
|
|
34589
|
+
if (Node25.isGetAccessorDeclaration(member)) {
|
|
34292
34590
|
out.set(member.getName(), iface.getName());
|
|
34293
34591
|
continue;
|
|
34294
34592
|
}
|
|
34295
|
-
if (
|
|
34593
|
+
if (Node25.isPropertySignature(member)) {
|
|
34296
34594
|
out.set(member.getName(), iface.getName());
|
|
34297
34595
|
}
|
|
34298
34596
|
}
|
|
@@ -34304,7 +34602,7 @@ function collectClassGetters(sourceFile) {
|
|
|
34304
34602
|
for (const cls of sourceFile.getClasses()) {
|
|
34305
34603
|
const set = /* @__PURE__ */ new Set();
|
|
34306
34604
|
for (const member of cls.getMembers()) {
|
|
34307
|
-
if (
|
|
34605
|
+
if (Node25.isGetAccessorDeclaration(member)) set.add(member.getName());
|
|
34308
34606
|
}
|
|
34309
34607
|
if (set.size > 0) out.set(cls.getName() ?? "<anon>", set);
|
|
34310
34608
|
}
|
|
@@ -34816,7 +35114,7 @@ import { resolve as resolve43 } from "node:path";
|
|
|
34816
35114
|
import { type as type67 } from "arktype";
|
|
34817
35115
|
|
|
34818
35116
|
// packages/dbx-components-mcp/src/scan/actions-extract.ts
|
|
34819
|
-
import { Node as
|
|
35117
|
+
import { Node as Node26, SyntaxKind as SyntaxKind13 } from "ts-morph";
|
|
34820
35118
|
var ACTION_MARKER = "dbxAction";
|
|
34821
35119
|
var ACTION_SLUG_TAG = "dbxActionSlug";
|
|
34822
35120
|
var ACTION_ROLE_TAG = "dbxActionRole";
|
|
@@ -35024,7 +35322,7 @@ function filterStates(values) {
|
|
|
35024
35322
|
}
|
|
35025
35323
|
function readEnumMemberLiteral(member) {
|
|
35026
35324
|
const initializer = member.getInitializer();
|
|
35027
|
-
if (initializer !== void 0 && (
|
|
35325
|
+
if (initializer !== void 0 && (Node26.isStringLiteral(initializer) || Node26.isNoSubstitutionTemplateLiteral(initializer))) {
|
|
35028
35326
|
return initializer.getLiteralText();
|
|
35029
35327
|
}
|
|
35030
35328
|
return member.getName();
|
|
@@ -35644,7 +35942,7 @@ import { resolve as resolve45 } from "node:path";
|
|
|
35644
35942
|
import { type as type71 } from "arktype";
|
|
35645
35943
|
|
|
35646
35944
|
// packages/dbx-components-mcp/src/scan/pipes-extract.ts
|
|
35647
|
-
import { Node as
|
|
35945
|
+
import { Node as Node27 } from "ts-morph";
|
|
35648
35946
|
var PIPE_MARKER = "dbxPipe";
|
|
35649
35947
|
var PIPE_SLUG_TAG = "dbxPipeSlug";
|
|
35650
35948
|
var PIPE_CATEGORY_TAG = "dbxPipeCategory";
|
|
@@ -35837,7 +36135,7 @@ function readPipeDecoratorConfig(decorator) {
|
|
|
35837
36135
|
return void 0;
|
|
35838
36136
|
}
|
|
35839
36137
|
const firstArg = args[0];
|
|
35840
|
-
if (!
|
|
36138
|
+
if (!Node27.isObjectLiteralExpression(firstArg)) {
|
|
35841
36139
|
return void 0;
|
|
35842
36140
|
}
|
|
35843
36141
|
const name = readStringProperty(firstArg, "name");
|
|
@@ -35850,7 +36148,7 @@ function readPipeDecoratorConfig(decorator) {
|
|
|
35850
36148
|
}
|
|
35851
36149
|
function readBooleanProperty(obj, propName) {
|
|
35852
36150
|
const prop = obj.getProperty(propName);
|
|
35853
|
-
if (prop === void 0 || !
|
|
36151
|
+
if (prop === void 0 || !Node27.isPropertyAssignment(prop)) {
|
|
35854
36152
|
return void 0;
|
|
35855
36153
|
}
|
|
35856
36154
|
const initializer = prop.getInitializer();
|