@neat.is/core 0.10.1-dev.20260927 → 0.10.1-dev.20260928
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-J3VVEB45.js → chunk-CNOJ4T6I.js} +135 -7
- package/dist/chunk-CNOJ4T6I.js.map +1 -0
- package/dist/{chunk-EJPNEEJA.js → chunk-HVBD4ULO.js} +94 -48
- package/dist/chunk-HVBD4ULO.js.map +1 -0
- package/dist/cli.cjs +465 -202
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +265 -129
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +226 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +226 -52
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +134 -6
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-EJPNEEJA.js.map +0 -1
- package/dist/chunk-J3VVEB45.js.map +0 -1
|
@@ -11115,13 +11115,16 @@ function objectKeys(obj) {
|
|
|
11115
11115
|
var MODULAR_WRITES = /* @__PURE__ */ new Set(["addDoc", "setDoc", "updateDoc"]);
|
|
11116
11116
|
var NAMESPACED_WRITES = /* @__PURE__ */ new Set(["add", "set", "update"]);
|
|
11117
11117
|
var READ_CLAUSES = /* @__PURE__ */ new Set(["where", "orderBy"]);
|
|
11118
|
-
function firestoreEndpointsFromFile(file, serviceDir) {
|
|
11118
|
+
function firestoreEndpointsFromFile(file, serviceDir, imported) {
|
|
11119
11119
|
const hasClient = FIRESTORE_CLIENT_IMPORT_RE.test(file.content);
|
|
11120
11120
|
const hasAdmin = FIRESTORE_ADMIN_IMPORT_RE.test(file.content);
|
|
11121
|
-
|
|
11122
|
-
|
|
11121
|
+
const importedNames = imported?.names ?? /* @__PURE__ */ new Set();
|
|
11122
|
+
if (!hasClient && !hasAdmin && importedNames.size === 0) return [];
|
|
11123
|
+
const ownSdk = hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
|
|
11124
|
+
const fileSdk = !hasClient && !hasAdmin ? imported?.sdk ?? null : ownSdk;
|
|
11123
11125
|
const tree = parseSource3(parserForExt2(path44.extname(file.path)), file.content);
|
|
11124
11126
|
const clientVars = firestoreClientVars(tree.rootNode);
|
|
11127
|
+
for (const n of importedNames) clientVars.add(n);
|
|
11125
11128
|
const collLine = /* @__PURE__ */ new Map();
|
|
11126
11129
|
const writes = /* @__PURE__ */ new Map();
|
|
11127
11130
|
const reads = /* @__PURE__ */ new Map();
|
|
@@ -11232,6 +11235,99 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
11232
11235
|
}
|
|
11233
11236
|
return out;
|
|
11234
11237
|
}
|
|
11238
|
+
function exportedFirestoreClients(root) {
|
|
11239
|
+
const out = /* @__PURE__ */ new Set();
|
|
11240
|
+
const collect = (node) => {
|
|
11241
|
+
if (node.type === "variable_declarator") {
|
|
11242
|
+
const name = node.childForFieldName("name");
|
|
11243
|
+
let value = node.childForFieldName("value");
|
|
11244
|
+
if (value?.type === "await_expression") value = namedChildren(value)[0] ?? null;
|
|
11245
|
+
if (name?.type === "identifier" && isFirestoreClientFactory(value)) out.add(name.text);
|
|
11246
|
+
}
|
|
11247
|
+
for (const c of namedChildren(node)) collect(c);
|
|
11248
|
+
};
|
|
11249
|
+
const walk11 = (node) => {
|
|
11250
|
+
if (node.type === "export_statement") collect(node);
|
|
11251
|
+
else for (const c of namedChildren(node)) walk11(c);
|
|
11252
|
+
};
|
|
11253
|
+
walk11(root);
|
|
11254
|
+
return out;
|
|
11255
|
+
}
|
|
11256
|
+
function namedImportBindings(root) {
|
|
11257
|
+
const out = [];
|
|
11258
|
+
const walk11 = (node) => {
|
|
11259
|
+
if (node.type === "import_statement") {
|
|
11260
|
+
const src = node.childForFieldName("source");
|
|
11261
|
+
const specifier = src ? src.text.slice(1, -1) : "";
|
|
11262
|
+
if (specifier.length > 0) {
|
|
11263
|
+
const stack = [node];
|
|
11264
|
+
while (stack.length > 0) {
|
|
11265
|
+
const n = stack.pop();
|
|
11266
|
+
if (n.type === "import_specifier") {
|
|
11267
|
+
const nameNode = n.childForFieldName("name");
|
|
11268
|
+
const aliasNode = n.childForFieldName("alias");
|
|
11269
|
+
const importedName = nameNode?.text;
|
|
11270
|
+
if (importedName) {
|
|
11271
|
+
out.push({ local: aliasNode?.text ?? importedName, imported: importedName, specifier });
|
|
11272
|
+
}
|
|
11273
|
+
continue;
|
|
11274
|
+
}
|
|
11275
|
+
for (const c of namedChildren(n)) stack.push(c);
|
|
11276
|
+
}
|
|
11277
|
+
}
|
|
11278
|
+
}
|
|
11279
|
+
for (const c of namedChildren(node)) walk11(c);
|
|
11280
|
+
};
|
|
11281
|
+
walk11(root);
|
|
11282
|
+
return out;
|
|
11283
|
+
}
|
|
11284
|
+
function sdkOf(content) {
|
|
11285
|
+
const hasClient = FIRESTORE_CLIENT_IMPORT_RE.test(content);
|
|
11286
|
+
const hasAdmin = FIRESTORE_ADMIN_IMPORT_RE.test(content);
|
|
11287
|
+
return hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
|
|
11288
|
+
}
|
|
11289
|
+
function parseOrNull(file) {
|
|
11290
|
+
const ext = path44.extname(file.path);
|
|
11291
|
+
if (!(ext in GRAMMAR_BY_EXT)) return null;
|
|
11292
|
+
try {
|
|
11293
|
+
return parseSource3(parserForExt2(ext), file.content).rootNode;
|
|
11294
|
+
} catch {
|
|
11295
|
+
return null;
|
|
11296
|
+
}
|
|
11297
|
+
}
|
|
11298
|
+
async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
11299
|
+
const registry = /* @__PURE__ */ new Map();
|
|
11300
|
+
for (const f of files) {
|
|
11301
|
+
if (sdkOf(f.content) === null && !FIRESTORE_CLIENT_IMPORT_RE.test(f.content)) continue;
|
|
11302
|
+
const root = parseOrNull(f);
|
|
11303
|
+
if (!root) continue;
|
|
11304
|
+
const names = exportedFirestoreClients(root);
|
|
11305
|
+
if (names.size === 0) continue;
|
|
11306
|
+
registry.set(toPosix(path44.relative(serviceDir, f.path)), { names, sdk: sdkOf(f.content) });
|
|
11307
|
+
}
|
|
11308
|
+
if (registry.size === 0) return [];
|
|
11309
|
+
const out = [];
|
|
11310
|
+
for (const f of files) {
|
|
11311
|
+
const root = parseOrNull(f);
|
|
11312
|
+
if (!root) continue;
|
|
11313
|
+
if (firestoreClientVars(root).size > 0) continue;
|
|
11314
|
+
const bindings = namedImportBindings(root);
|
|
11315
|
+
if (bindings.length === 0) continue;
|
|
11316
|
+
const names = /* @__PURE__ */ new Set();
|
|
11317
|
+
let sdk = null;
|
|
11318
|
+
for (const b of bindings) {
|
|
11319
|
+
const rel = await resolveJsImport(b.specifier, path44.dirname(f.path), serviceDir, null);
|
|
11320
|
+
if (!rel) continue;
|
|
11321
|
+
const entry = registry.get(rel);
|
|
11322
|
+
if (!entry || !entry.names.has(b.imported)) continue;
|
|
11323
|
+
names.add(b.local);
|
|
11324
|
+
sdk ??= entry.sdk;
|
|
11325
|
+
}
|
|
11326
|
+
if (names.size === 0) continue;
|
|
11327
|
+
out.push(...firestoreEndpointsFromFile(f, serviceDir, { names, sdk }));
|
|
11328
|
+
}
|
|
11329
|
+
return out;
|
|
11330
|
+
}
|
|
11235
11331
|
|
|
11236
11332
|
// src/extract/calls/mongoose.ts
|
|
11237
11333
|
import path45 from "path";
|
|
@@ -14029,6 +14125,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
14029
14125
|
recordExtractionError("python socket call extraction", file.path, err);
|
|
14030
14126
|
}
|
|
14031
14127
|
}
|
|
14128
|
+
endpoints.push(...await firestoreCrossFileEndpoints(maskedFiles, service.dir));
|
|
14032
14129
|
endpoints.push(...await mongooseCrossFileEndpoints(maskedFiles, service.dir));
|
|
14033
14130
|
endpoints.push(...pythonOrmCrossFileEndpoints(maskedFiles, service.dir));
|
|
14034
14131
|
endpoints.push(...await prismaColumnEndpoints(service.dir));
|
|
@@ -15323,6 +15420,9 @@ function stripComments(src) {
|
|
|
15323
15420
|
function segmentsFromMatchPath(pathToken) {
|
|
15324
15421
|
return pathToken.split("/").filter((s) => s.length > 0);
|
|
15325
15422
|
}
|
|
15423
|
+
function isRecursiveWildcard(seg) {
|
|
15424
|
+
return /^\{[^}]*=\s*\*\*\}$/.test(seg);
|
|
15425
|
+
}
|
|
15326
15426
|
function collectionKeyFromSegments(segments) {
|
|
15327
15427
|
let segs = segments;
|
|
15328
15428
|
if (segs.length >= 3 && segs[0] === "databases" && /^\{.*\}$/.test(segs[1]) && segs[2] === "documents") {
|
|
@@ -15335,10 +15435,11 @@ function collectionKeyFromName(name) {
|
|
|
15335
15435
|
}
|
|
15336
15436
|
function fieldsFromCondition(cond) {
|
|
15337
15437
|
const out = [];
|
|
15338
|
-
const callRe =
|
|
15438
|
+
const callRe = /(!\s*)?\b(?:hasAll|hasOnly|hasAny)\s*\(\s*\[([^\]]*)\]\s*\)/g;
|
|
15339
15439
|
let m;
|
|
15340
15440
|
while ((m = callRe.exec(cond)) !== null) {
|
|
15341
|
-
|
|
15441
|
+
if (m[1] !== void 0 || isNegatedAt(cond, m.index)) continue;
|
|
15442
|
+
const inner = m[2];
|
|
15342
15443
|
const litRe = /'([^']*)'|"([^"]*)"/g;
|
|
15343
15444
|
let lm;
|
|
15344
15445
|
while ((lm = litRe.exec(inner)) !== null) {
|
|
@@ -15348,6 +15449,28 @@ function fieldsFromCondition(cond) {
|
|
|
15348
15449
|
}
|
|
15349
15450
|
return out;
|
|
15350
15451
|
}
|
|
15452
|
+
function isNegatedAt(cond, idx) {
|
|
15453
|
+
let i = idx - 1;
|
|
15454
|
+
while (i >= 0) {
|
|
15455
|
+
const ch = cond[i];
|
|
15456
|
+
if (ch === ")") {
|
|
15457
|
+
let depth = 1;
|
|
15458
|
+
i--;
|
|
15459
|
+
while (i >= 0 && depth > 0) {
|
|
15460
|
+
if (cond[i] === ")") depth++;
|
|
15461
|
+
else if (cond[i] === "(") depth--;
|
|
15462
|
+
i--;
|
|
15463
|
+
}
|
|
15464
|
+
continue;
|
|
15465
|
+
}
|
|
15466
|
+
if (/[A-Za-z0-9_$.\]['"]/.test(ch) || ch === " ") {
|
|
15467
|
+
i--;
|
|
15468
|
+
continue;
|
|
15469
|
+
}
|
|
15470
|
+
return ch === "!";
|
|
15471
|
+
}
|
|
15472
|
+
return false;
|
|
15473
|
+
}
|
|
15351
15474
|
function parseFirestoreRules(content) {
|
|
15352
15475
|
const src = stripComments(content);
|
|
15353
15476
|
const tokenRe = /match\s+((?:\/(?:\{[^}]*\}|[^\s/{}]+))+)\s*\{|allow\b([^;{}]*);|(\{)|(\})/g;
|
|
@@ -15360,7 +15483,8 @@ function parseFirestoreRules(content) {
|
|
|
15360
15483
|
while ((m = tokenRe.exec(src)) !== null) {
|
|
15361
15484
|
if (m[1] !== void 0) {
|
|
15362
15485
|
depth++;
|
|
15363
|
-
|
|
15486
|
+
const segs = segmentsFromMatchPath(m[1]);
|
|
15487
|
+
matchStack.push({ depth, segs, recursive: segs.some(isRecursiveWildcard) });
|
|
15364
15488
|
continue;
|
|
15365
15489
|
}
|
|
15366
15490
|
if (m[2] !== void 0) {
|
|
@@ -15371,6 +15495,10 @@ function parseFirestoreRules(content) {
|
|
|
15371
15495
|
if (!methods.some((mm) => WRITE_METHODS.has(mm))) continue;
|
|
15372
15496
|
const key = currentKey();
|
|
15373
15497
|
if (key.length === 0) continue;
|
|
15498
|
+
if (matchStack.some((f) => f.recursive)) {
|
|
15499
|
+
indeterminate.add(key);
|
|
15500
|
+
continue;
|
|
15501
|
+
}
|
|
15374
15502
|
const cond = colon === -1 ? "" : body.slice(colon + 1);
|
|
15375
15503
|
const fields = fieldsFromCondition(cond);
|
|
15376
15504
|
if (fields.length > 0) {
|
|
@@ -23170,4 +23298,4 @@ export {
|
|
|
23170
23298
|
deprovisionConnector,
|
|
23171
23299
|
buildApi
|
|
23172
23300
|
};
|
|
23173
|
-
//# sourceMappingURL=chunk-
|
|
23301
|
+
//# sourceMappingURL=chunk-CNOJ4T6I.js.map
|