@suss/adapter-python 0.5.10 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +197 -58
- package/dist/index.d.cts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +197 -58
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -1739,7 +1739,7 @@ __export(core_exports2, {
|
|
|
1739
1739
|
parse: () => parse,
|
|
1740
1740
|
parseAsync: () => parseAsync,
|
|
1741
1741
|
prettifyError: () => prettifyError,
|
|
1742
|
-
process: () =>
|
|
1742
|
+
process: () => process2,
|
|
1743
1743
|
regexes: () => regexes_exports,
|
|
1744
1744
|
registry: () => registry,
|
|
1745
1745
|
safeDecode: () => safeDecode,
|
|
@@ -12664,7 +12664,7 @@ function initializeContext(params) {
|
|
|
12664
12664
|
external: params?.external ?? void 0
|
|
12665
12665
|
};
|
|
12666
12666
|
}
|
|
12667
|
-
function
|
|
12667
|
+
function process2(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
12668
12668
|
var _a3;
|
|
12669
12669
|
const def = schema._zod.def;
|
|
12670
12670
|
const seen = ctx.seen.get(schema);
|
|
@@ -12701,7 +12701,7 @@ function process(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
|
12701
12701
|
if (parent) {
|
|
12702
12702
|
if (!result.ref)
|
|
12703
12703
|
result.ref = parent;
|
|
12704
|
-
|
|
12704
|
+
process2(parent, ctx, params);
|
|
12705
12705
|
ctx.seen.get(parent).isParent = true;
|
|
12706
12706
|
}
|
|
12707
12707
|
}
|
|
@@ -12989,14 +12989,14 @@ function isTransforming(_schema, _ctx) {
|
|
|
12989
12989
|
}
|
|
12990
12990
|
var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
|
|
12991
12991
|
const ctx = initializeContext({ ...params, processors });
|
|
12992
|
-
|
|
12992
|
+
process2(schema, ctx);
|
|
12993
12993
|
extractDefs(ctx, schema);
|
|
12994
12994
|
return finalize(ctx, schema);
|
|
12995
12995
|
};
|
|
12996
12996
|
var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
|
|
12997
12997
|
const { libraryOptions, target } = params ?? {};
|
|
12998
12998
|
const ctx = initializeContext({ ...libraryOptions ?? {}, target, io, processors });
|
|
12999
|
-
|
|
12999
|
+
process2(schema, ctx);
|
|
13000
13000
|
extractDefs(ctx, schema);
|
|
13001
13001
|
return finalize(ctx, schema);
|
|
13002
13002
|
};
|
|
@@ -13242,7 +13242,7 @@ var arrayProcessor = (schema, ctx, _json, params) => {
|
|
|
13242
13242
|
if (typeof maximum === "number")
|
|
13243
13243
|
json2.maxItems = maximum;
|
|
13244
13244
|
json2.type = "array";
|
|
13245
|
-
json2.items =
|
|
13245
|
+
json2.items = process2(def.element, ctx, {
|
|
13246
13246
|
...params,
|
|
13247
13247
|
path: [...params.path, "items"]
|
|
13248
13248
|
});
|
|
@@ -13254,7 +13254,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
13254
13254
|
json2.properties = {};
|
|
13255
13255
|
const shape = def.shape;
|
|
13256
13256
|
for (const key in shape) {
|
|
13257
|
-
json2.properties[key] =
|
|
13257
|
+
json2.properties[key] = process2(shape[key], ctx, {
|
|
13258
13258
|
...params,
|
|
13259
13259
|
path: [...params.path, "properties", key]
|
|
13260
13260
|
});
|
|
@@ -13277,7 +13277,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
13277
13277
|
if (ctx.io === "output")
|
|
13278
13278
|
json2.additionalProperties = false;
|
|
13279
13279
|
} else if (def.catchall) {
|
|
13280
|
-
json2.additionalProperties =
|
|
13280
|
+
json2.additionalProperties = process2(def.catchall, ctx, {
|
|
13281
13281
|
...params,
|
|
13282
13282
|
path: [...params.path, "additionalProperties"]
|
|
13283
13283
|
});
|
|
@@ -13286,7 +13286,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
13286
13286
|
var unionProcessor = (schema, ctx, json2, params) => {
|
|
13287
13287
|
const def = schema._zod.def;
|
|
13288
13288
|
const isExclusive = def.inclusive === false;
|
|
13289
|
-
const options = def.options.map((x, i) =>
|
|
13289
|
+
const options = def.options.map((x, i) => process2(x, ctx, {
|
|
13290
13290
|
...params,
|
|
13291
13291
|
path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
|
|
13292
13292
|
}));
|
|
@@ -13298,11 +13298,11 @@ var unionProcessor = (schema, ctx, json2, params) => {
|
|
|
13298
13298
|
};
|
|
13299
13299
|
var intersectionProcessor = (schema, ctx, json2, params) => {
|
|
13300
13300
|
const def = schema._zod.def;
|
|
13301
|
-
const a =
|
|
13301
|
+
const a = process2(def.left, ctx, {
|
|
13302
13302
|
...params,
|
|
13303
13303
|
path: [...params.path, "allOf", 0]
|
|
13304
13304
|
});
|
|
13305
|
-
const b =
|
|
13305
|
+
const b = process2(def.right, ctx, {
|
|
13306
13306
|
...params,
|
|
13307
13307
|
path: [...params.path, "allOf", 1]
|
|
13308
13308
|
});
|
|
@@ -13319,11 +13319,11 @@ var tupleProcessor = (schema, ctx, _json, params) => {
|
|
|
13319
13319
|
json2.type = "array";
|
|
13320
13320
|
const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
13321
13321
|
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
13322
|
-
const prefixItems = def.items.map((x, i) =>
|
|
13322
|
+
const prefixItems = def.items.map((x, i) => process2(x, ctx, {
|
|
13323
13323
|
...params,
|
|
13324
13324
|
path: [...params.path, prefixPath, i]
|
|
13325
13325
|
}));
|
|
13326
|
-
const rest = def.rest ?
|
|
13326
|
+
const rest = def.rest ? process2(def.rest, ctx, {
|
|
13327
13327
|
...params,
|
|
13328
13328
|
path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
|
|
13329
13329
|
}) : null;
|
|
@@ -13363,7 +13363,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
13363
13363
|
const keyBag = keyType._zod.bag;
|
|
13364
13364
|
const patterns = keyBag?.patterns;
|
|
13365
13365
|
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
13366
|
-
const valueSchema =
|
|
13366
|
+
const valueSchema = process2(def.valueType, ctx, {
|
|
13367
13367
|
...params,
|
|
13368
13368
|
path: [...params.path, "patternProperties", "*"]
|
|
13369
13369
|
});
|
|
@@ -13373,12 +13373,12 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
13373
13373
|
}
|
|
13374
13374
|
} else {
|
|
13375
13375
|
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
|
|
13376
|
-
json2.propertyNames =
|
|
13376
|
+
json2.propertyNames = process2(def.keyType, ctx, {
|
|
13377
13377
|
...params,
|
|
13378
13378
|
path: [...params.path, "propertyNames"]
|
|
13379
13379
|
});
|
|
13380
13380
|
}
|
|
13381
|
-
json2.additionalProperties =
|
|
13381
|
+
json2.additionalProperties = process2(def.valueType, ctx, {
|
|
13382
13382
|
...params,
|
|
13383
13383
|
path: [...params.path, "additionalProperties"]
|
|
13384
13384
|
});
|
|
@@ -13393,7 +13393,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
13393
13393
|
};
|
|
13394
13394
|
var nullableProcessor = (schema, ctx, json2, params) => {
|
|
13395
13395
|
const def = schema._zod.def;
|
|
13396
|
-
const inner =
|
|
13396
|
+
const inner = process2(def.innerType, ctx, params);
|
|
13397
13397
|
const seen = ctx.seen.get(schema);
|
|
13398
13398
|
if (ctx.target === "openapi-3.0") {
|
|
13399
13399
|
seen.ref = def.innerType;
|
|
@@ -13404,20 +13404,20 @@ var nullableProcessor = (schema, ctx, json2, params) => {
|
|
|
13404
13404
|
};
|
|
13405
13405
|
var nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
13406
13406
|
const def = schema._zod.def;
|
|
13407
|
-
|
|
13407
|
+
process2(def.innerType, ctx, params);
|
|
13408
13408
|
const seen = ctx.seen.get(schema);
|
|
13409
13409
|
seen.ref = def.innerType;
|
|
13410
13410
|
};
|
|
13411
13411
|
var defaultProcessor = (schema, ctx, json2, params) => {
|
|
13412
13412
|
const def = schema._zod.def;
|
|
13413
|
-
|
|
13413
|
+
process2(def.innerType, ctx, params);
|
|
13414
13414
|
const seen = ctx.seen.get(schema);
|
|
13415
13415
|
seen.ref = def.innerType;
|
|
13416
13416
|
json2.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
13417
13417
|
};
|
|
13418
13418
|
var prefaultProcessor = (schema, ctx, json2, params) => {
|
|
13419
13419
|
const def = schema._zod.def;
|
|
13420
|
-
|
|
13420
|
+
process2(def.innerType, ctx, params);
|
|
13421
13421
|
const seen = ctx.seen.get(schema);
|
|
13422
13422
|
seen.ref = def.innerType;
|
|
13423
13423
|
if (ctx.io === "input")
|
|
@@ -13425,7 +13425,7 @@ var prefaultProcessor = (schema, ctx, json2, params) => {
|
|
|
13425
13425
|
};
|
|
13426
13426
|
var catchProcessor = (schema, ctx, json2, params) => {
|
|
13427
13427
|
const def = schema._zod.def;
|
|
13428
|
-
|
|
13428
|
+
process2(def.innerType, ctx, params);
|
|
13429
13429
|
const seen = ctx.seen.get(schema);
|
|
13430
13430
|
seen.ref = def.innerType;
|
|
13431
13431
|
let catchValue;
|
|
@@ -13440,32 +13440,32 @@ var pipeProcessor = (schema, ctx, _json, params) => {
|
|
|
13440
13440
|
const def = schema._zod.def;
|
|
13441
13441
|
const inIsTransform = def.in._zod.traits.has("$ZodTransform");
|
|
13442
13442
|
const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out;
|
|
13443
|
-
|
|
13443
|
+
process2(innerType, ctx, params);
|
|
13444
13444
|
const seen = ctx.seen.get(schema);
|
|
13445
13445
|
seen.ref = innerType;
|
|
13446
13446
|
};
|
|
13447
13447
|
var readonlyProcessor = (schema, ctx, json2, params) => {
|
|
13448
13448
|
const def = schema._zod.def;
|
|
13449
|
-
|
|
13449
|
+
process2(def.innerType, ctx, params);
|
|
13450
13450
|
const seen = ctx.seen.get(schema);
|
|
13451
13451
|
seen.ref = def.innerType;
|
|
13452
13452
|
json2.readOnly = true;
|
|
13453
13453
|
};
|
|
13454
13454
|
var promiseProcessor = (schema, ctx, _json, params) => {
|
|
13455
13455
|
const def = schema._zod.def;
|
|
13456
|
-
|
|
13456
|
+
process2(def.innerType, ctx, params);
|
|
13457
13457
|
const seen = ctx.seen.get(schema);
|
|
13458
13458
|
seen.ref = def.innerType;
|
|
13459
13459
|
};
|
|
13460
13460
|
var optionalProcessor = (schema, ctx, _json, params) => {
|
|
13461
13461
|
const def = schema._zod.def;
|
|
13462
|
-
|
|
13462
|
+
process2(def.innerType, ctx, params);
|
|
13463
13463
|
const seen = ctx.seen.get(schema);
|
|
13464
13464
|
seen.ref = def.innerType;
|
|
13465
13465
|
};
|
|
13466
13466
|
var lazyProcessor = (schema, ctx, _json, params) => {
|
|
13467
13467
|
const innerType = schema._zod.innerType;
|
|
13468
|
-
|
|
13468
|
+
process2(innerType, ctx, params);
|
|
13469
13469
|
const seen = ctx.seen.get(schema);
|
|
13470
13470
|
seen.ref = innerType;
|
|
13471
13471
|
};
|
|
@@ -13517,7 +13517,7 @@ function toJSONSchema(input, params) {
|
|
|
13517
13517
|
const defs = {};
|
|
13518
13518
|
for (const entry of registry2._idmap.entries()) {
|
|
13519
13519
|
const [_, schema] = entry;
|
|
13520
|
-
|
|
13520
|
+
process2(schema, ctx2);
|
|
13521
13521
|
}
|
|
13522
13522
|
const schemas = {};
|
|
13523
13523
|
const external = {
|
|
@@ -13540,7 +13540,7 @@ function toJSONSchema(input, params) {
|
|
|
13540
13540
|
return { schemas };
|
|
13541
13541
|
}
|
|
13542
13542
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
13543
|
-
|
|
13543
|
+
process2(input, ctx);
|
|
13544
13544
|
extractDefs(ctx, input);
|
|
13545
13545
|
return finalize(ctx, input);
|
|
13546
13546
|
}
|
|
@@ -13598,7 +13598,7 @@ var JSONSchemaGenerator = class {
|
|
|
13598
13598
|
* This must be called before emit().
|
|
13599
13599
|
*/
|
|
13600
13600
|
process(schema, _params = { path: [], schemaPath: [] }) {
|
|
13601
|
-
return
|
|
13601
|
+
return process2(schema, this.ctx, _params);
|
|
13602
13602
|
}
|
|
13603
13603
|
/**
|
|
13604
13604
|
* Emit the final JSON Schema after processing.
|
|
@@ -15747,7 +15747,7 @@ function date4(params) {
|
|
|
15747
15747
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
15748
15748
|
config(en_default());
|
|
15749
15749
|
|
|
15750
|
-
// ../../ir-core/dist/chunk-
|
|
15750
|
+
// ../../ir-core/dist/chunk-TEXSN75M.js
|
|
15751
15751
|
function gqlIdentityKey(typeName, fieldName) {
|
|
15752
15752
|
return `gql:${typeName}.${fieldName}`;
|
|
15753
15753
|
}
|
|
@@ -16116,27 +16116,41 @@ var runtimeConfigSemantics = defineBoundarySemantics({
|
|
|
16116
16116
|
identityKey: () => null
|
|
16117
16117
|
}
|
|
16118
16118
|
});
|
|
16119
|
-
var
|
|
16120
|
-
name: external_exports.literal("storage
|
|
16121
|
-
storageSystem: external_exports.enum(["postgres", "mysql", "sqlite"]),
|
|
16119
|
+
var StorageSemanticsSchema = external_exports.object({
|
|
16120
|
+
name: external_exports.literal("storage"),
|
|
16122
16121
|
/**
|
|
16123
|
-
*
|
|
16124
|
-
*
|
|
16122
|
+
* Which store this is: postgres, mysql, sqlite, dynamodb. Two
|
|
16123
|
+
* products' containers can share a name, so this keeps them apart,
|
|
16124
|
+
* and it is what a finding message calls the store.
|
|
16125
|
+
*/
|
|
16126
|
+
storageSystem: external_exports.string(),
|
|
16127
|
+
/**
|
|
16128
|
+
* The ORM, schema, or deployment scope. A single-database setup uses
|
|
16129
|
+
* `"default"`, and a monorepo with several schemas gives each one its
|
|
16130
|
+
* own value.
|
|
16125
16131
|
*/
|
|
16126
16132
|
scope: external_exports.string(),
|
|
16127
16133
|
/**
|
|
16128
|
-
* The table or
|
|
16129
|
-
* the source states one this reader could not
|
|
16130
|
-
* pairs with nothing, rather than with
|
|
16131
|
-
* happens to spell.
|
|
16134
|
+
* The table, bucket, collection, or index, as the source declares
|
|
16135
|
+
* it, or null when the source states one this reader could not
|
|
16136
|
+
* settle. A null container pairs with nothing, rather than with
|
|
16137
|
+
* whatever its source text happens to spell.
|
|
16132
16138
|
*/
|
|
16133
|
-
|
|
16139
|
+
container: external_exports.string().nullable(),
|
|
16140
|
+
/**
|
|
16141
|
+
* A secondary way into the container, a DynamoDB global secondary
|
|
16142
|
+
* index or an Elasticsearch alias, each with its own key fields.
|
|
16143
|
+
* Null means the container's own primary way in. A query through an
|
|
16144
|
+
* index and a query through the table are different accesses, so
|
|
16145
|
+
* they pair separately.
|
|
16146
|
+
*/
|
|
16147
|
+
accessPath: external_exports.string().nullable()
|
|
16134
16148
|
});
|
|
16135
|
-
var
|
|
16136
|
-
name: "storage
|
|
16137
|
-
schema:
|
|
16149
|
+
var storageSemantics = defineBoundarySemantics({
|
|
16150
|
+
name: "storage",
|
|
16151
|
+
schema: StorageSemanticsSchema,
|
|
16138
16152
|
behavior: {
|
|
16139
|
-
/** A query returns rows, not a status and a body. */
|
|
16153
|
+
/** A query returns rows or items, not a status and a body. */
|
|
16140
16154
|
exchangesHttpResponses: false,
|
|
16141
16155
|
reportsUnpairedItself: false,
|
|
16142
16156
|
identityKey: () => null
|
|
@@ -16148,7 +16162,7 @@ var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
|
16148
16162
|
graphqlResolverSemantics.schema,
|
|
16149
16163
|
graphqlOperationSemantics.schema,
|
|
16150
16164
|
runtimeConfigSemantics.schema,
|
|
16151
|
-
|
|
16165
|
+
storageSemantics.schema,
|
|
16152
16166
|
messageBusSemantics.schema
|
|
16153
16167
|
]);
|
|
16154
16168
|
var DEFINITIONS = [
|
|
@@ -16157,7 +16171,7 @@ var DEFINITIONS = [
|
|
|
16157
16171
|
graphqlResolverSemantics,
|
|
16158
16172
|
graphqlOperationSemantics,
|
|
16159
16173
|
runtimeConfigSemantics,
|
|
16160
|
-
|
|
16174
|
+
storageSemantics,
|
|
16161
16175
|
messageBusSemantics
|
|
16162
16176
|
];
|
|
16163
16177
|
var BY_NAME = new Map(
|
|
@@ -16297,19 +16311,97 @@ function namedOrNull(value, field2) {
|
|
|
16297
16311
|
}
|
|
16298
16312
|
return value;
|
|
16299
16313
|
}
|
|
16300
|
-
function
|
|
16314
|
+
function storageBinding(opts) {
|
|
16301
16315
|
return {
|
|
16302
|
-
transport: opts.storageSystem,
|
|
16316
|
+
transport: opts.transport ?? opts.storageSystem,
|
|
16303
16317
|
semantics: {
|
|
16304
|
-
name: "storage
|
|
16318
|
+
name: "storage",
|
|
16305
16319
|
storageSystem: opts.storageSystem,
|
|
16306
16320
|
scope: opts.scope,
|
|
16307
|
-
|
|
16321
|
+
container: namedOrNull(opts.container, "storage container"),
|
|
16322
|
+
accessPath: opts.accessPath ?? null
|
|
16308
16323
|
},
|
|
16309
16324
|
recognition: opts.recognition
|
|
16310
16325
|
};
|
|
16311
16326
|
}
|
|
16312
16327
|
|
|
16328
|
+
// src/rawSql.ts
|
|
16329
|
+
var import_sql = require("@suss/sql");
|
|
16330
|
+
function rawSqlEffects(calls, options) {
|
|
16331
|
+
if (options.patterns.length === 0) {
|
|
16332
|
+
return [];
|
|
16333
|
+
}
|
|
16334
|
+
const effects = [];
|
|
16335
|
+
for (const call of calls) {
|
|
16336
|
+
const pattern = patternFor(call, options);
|
|
16337
|
+
if (pattern === void 0) {
|
|
16338
|
+
continue;
|
|
16339
|
+
}
|
|
16340
|
+
const statement = statementIn(call);
|
|
16341
|
+
if (statement === null) {
|
|
16342
|
+
continue;
|
|
16343
|
+
}
|
|
16344
|
+
for (const access of (0, import_sql.readSqlAccess)(statement, {
|
|
16345
|
+
dialect: pattern.storageSystem
|
|
16346
|
+
})) {
|
|
16347
|
+
effects.push({
|
|
16348
|
+
type: "interaction",
|
|
16349
|
+
binding: storageBinding({
|
|
16350
|
+
recognition: `python-${pattern.module}`,
|
|
16351
|
+
storageSystem: pattern.storageSystem,
|
|
16352
|
+
scope: pattern.module,
|
|
16353
|
+
container: access.table
|
|
16354
|
+
}),
|
|
16355
|
+
callee: field(call, "function")?.text ?? "",
|
|
16356
|
+
interaction: {
|
|
16357
|
+
class: "storage-access",
|
|
16358
|
+
kind: access.kind,
|
|
16359
|
+
fields: access.fields,
|
|
16360
|
+
...access.selector.length > 0 ? { selector: access.selector } : {},
|
|
16361
|
+
operation: field(call, "function")?.text ?? ""
|
|
16362
|
+
}
|
|
16363
|
+
});
|
|
16364
|
+
}
|
|
16365
|
+
}
|
|
16366
|
+
return effects;
|
|
16367
|
+
}
|
|
16368
|
+
function patternFor(call, options) {
|
|
16369
|
+
const callee = field(call, "function");
|
|
16370
|
+
if (callee === null || callee.type !== "identifier") {
|
|
16371
|
+
return void 0;
|
|
16372
|
+
}
|
|
16373
|
+
const from = options.facts.facts("pyImportedName").find((row) => String(row[0]) === `${options.filePath}#${callee.text}`);
|
|
16374
|
+
if (from === void 0) {
|
|
16375
|
+
return void 0;
|
|
16376
|
+
}
|
|
16377
|
+
const module2 = String(from[1]);
|
|
16378
|
+
return options.patterns.find(
|
|
16379
|
+
(pattern) => pattern.module === module2 && pattern.functions.includes(callee.text)
|
|
16380
|
+
);
|
|
16381
|
+
}
|
|
16382
|
+
function statementIn(call) {
|
|
16383
|
+
const args = field(call, "arguments");
|
|
16384
|
+
const first = args?.namedChildren.find((child) => child !== null) ?? null;
|
|
16385
|
+
if (first === null || first.type !== "string") {
|
|
16386
|
+
return null;
|
|
16387
|
+
}
|
|
16388
|
+
const parts = [""];
|
|
16389
|
+
for (const child of first.namedChildren) {
|
|
16390
|
+
if (child === null) {
|
|
16391
|
+
continue;
|
|
16392
|
+
}
|
|
16393
|
+
if (child.type === "string_content") {
|
|
16394
|
+
parts[parts.length - 1] += child.text;
|
|
16395
|
+
continue;
|
|
16396
|
+
}
|
|
16397
|
+
if (child.type === "interpolation") {
|
|
16398
|
+
parts.push("");
|
|
16399
|
+
}
|
|
16400
|
+
}
|
|
16401
|
+
const statement = (0, import_sql.sqlFromParts)(parts);
|
|
16402
|
+
return statement.trim() === "" ? null : statement;
|
|
16403
|
+
}
|
|
16404
|
+
|
|
16313
16405
|
// src/facts/resolve.ts
|
|
16314
16406
|
var import_datalog2 = require("@suss/datalog");
|
|
16315
16407
|
|
|
@@ -17160,11 +17252,11 @@ function effectFor(pattern, chain, options) {
|
|
|
17160
17252
|
];
|
|
17161
17253
|
return {
|
|
17162
17254
|
type: "interaction",
|
|
17163
|
-
binding:
|
|
17255
|
+
binding: storageBinding({
|
|
17164
17256
|
recognition: "python-storage",
|
|
17165
17257
|
storageSystem: pattern.storageSystem,
|
|
17166
17258
|
scope: pattern.module,
|
|
17167
|
-
|
|
17259
|
+
container: chain.subject
|
|
17168
17260
|
}),
|
|
17169
17261
|
callee: chain.last.text,
|
|
17170
17262
|
interaction: {
|
|
@@ -17907,10 +17999,17 @@ function buildRouteUnit(options) {
|
|
|
17907
17999
|
() => readReturnAnnotation(definitionNode, enclosingScope, ctx)
|
|
17908
18000
|
);
|
|
17909
18001
|
const effects = invocationEffects(definitionNode);
|
|
17910
|
-
const storage = storageLookup === void 0 ? [] :
|
|
17911
|
-
...
|
|
17912
|
-
|
|
17913
|
-
|
|
18002
|
+
const storage = storageLookup === void 0 ? [] : [
|
|
18003
|
+
...storageEffects(bodyCalls(definitionNode), {
|
|
18004
|
+
...storageLookup,
|
|
18005
|
+
filePath: storageLookup.factsPath
|
|
18006
|
+
}),
|
|
18007
|
+
...rawSqlEffects(bodyCalls(definitionNode), {
|
|
18008
|
+
facts: storageLookup.facts,
|
|
18009
|
+
filePath: storageLookup.factsPath,
|
|
18010
|
+
patterns: storageLookup.rawSql ?? []
|
|
18011
|
+
})
|
|
18012
|
+
];
|
|
17914
18013
|
const perReturn = branchesFromReturns(
|
|
17915
18014
|
readsReturnedStatus,
|
|
17916
18015
|
definitionNode,
|
|
@@ -19231,11 +19330,26 @@ function carrierPrefix(carrier, constructorArg, objectName, scope, scan) {
|
|
|
19231
19330
|
}
|
|
19232
19331
|
|
|
19233
19332
|
// src/project.ts
|
|
19333
|
+
function reportUnresolvedProjectModules(options) {
|
|
19334
|
+
for (const pack of options.packs) {
|
|
19335
|
+
for (const module2 of pack.projectModules ?? []) {
|
|
19336
|
+
const resolved = resolveAbsoluteModule(module2, { roots: options.roots });
|
|
19337
|
+
if (resolved.status === "resolved") {
|
|
19338
|
+
continue;
|
|
19339
|
+
}
|
|
19340
|
+
process.stderr.write(
|
|
19341
|
+
`[suss] ${pack.name}: the configured module ${module2} does not resolve under ${options.roots.join(", ")}, so nothing it wraps will be discovered.
|
|
19342
|
+
`
|
|
19343
|
+
);
|
|
19344
|
+
}
|
|
19345
|
+
}
|
|
19346
|
+
}
|
|
19234
19347
|
async function extractPythonProject(options) {
|
|
19235
19348
|
const db = new import_datalog3.Database();
|
|
19236
19349
|
const summaries = [];
|
|
19237
19350
|
const gapHandling = options.gapHandling ?? "permissive";
|
|
19238
19351
|
const displayPathOf = (file2) => options.workspaceRoot !== void 0 ? import_node_path3.default.relative(options.workspaceRoot, file2) : file2;
|
|
19352
|
+
reportUnresolvedProjectModules(options);
|
|
19239
19353
|
const bound = [];
|
|
19240
19354
|
for (const file2 of options.files) {
|
|
19241
19355
|
const source = import_node_fs3.default.readFileSync(file2, "utf8");
|
|
@@ -19251,6 +19365,7 @@ async function extractPythonProject(options) {
|
|
|
19251
19365
|
(pack) => pack.discovery.some((pattern) => pattern.routerComposition !== void 0)
|
|
19252
19366
|
);
|
|
19253
19367
|
const storagePatterns = options.packs.flatMap((pack) => pack.storage ?? []);
|
|
19368
|
+
const rawSqlPatterns = options.packs.flatMap((pack) => pack.rawSql ?? []);
|
|
19254
19369
|
const needsValues = mountsRouters || storagePatterns.length > 0;
|
|
19255
19370
|
const definitions = /* @__PURE__ */ new Map();
|
|
19256
19371
|
for (const { file: file2, root, module: moduleBinding } of bound) {
|
|
@@ -19280,14 +19395,15 @@ async function extractPythonProject(options) {
|
|
|
19280
19395
|
absoluteFile: file2,
|
|
19281
19396
|
routerIndex,
|
|
19282
19397
|
gapHandling,
|
|
19283
|
-
...storagePatterns.length > 0 ? {
|
|
19398
|
+
...storagePatterns.length > 0 || rawSqlPatterns.length > 0 ? {
|
|
19284
19399
|
storage: {
|
|
19285
19400
|
facts: db,
|
|
19286
19401
|
factsPath: file2,
|
|
19287
19402
|
patterns: storagePatterns,
|
|
19288
19403
|
definitionAt: (key) => definitions.get(key),
|
|
19289
19404
|
couldMatch,
|
|
19290
|
-
leadsToStorage
|
|
19405
|
+
leadsToStorage,
|
|
19406
|
+
rawSql: rawSqlPatterns
|
|
19291
19407
|
}
|
|
19292
19408
|
} : {}
|
|
19293
19409
|
});
|
|
@@ -19298,8 +19414,31 @@ async function extractPythonProject(options) {
|
|
|
19298
19414
|
emitEntryFact(db, file2, raw.identity.range, raw.identity.name);
|
|
19299
19415
|
}
|
|
19300
19416
|
}
|
|
19417
|
+
stampModuleImports(summaries, db, displayPathOf);
|
|
19301
19418
|
return { summaries, facts: db };
|
|
19302
19419
|
}
|
|
19420
|
+
function stampModuleImports(summaries, db, displayPathOf) {
|
|
19421
|
+
const importsByFile = /* @__PURE__ */ new Map();
|
|
19422
|
+
for (const [from, , to] of db.facts("pyImportResolved")) {
|
|
19423
|
+
if (typeof from !== "string" || typeof to !== "string") {
|
|
19424
|
+
continue;
|
|
19425
|
+
}
|
|
19426
|
+
const key = displayPathOf(from);
|
|
19427
|
+
const seen = importsByFile.get(key) ?? /* @__PURE__ */ new Set();
|
|
19428
|
+
seen.add(displayPathOf(to));
|
|
19429
|
+
importsByFile.set(key, seen);
|
|
19430
|
+
}
|
|
19431
|
+
for (const summary of summaries) {
|
|
19432
|
+
const imports = importsByFile.get(summary.location.file);
|
|
19433
|
+
if (imports === void 0 || imports.size === 0) {
|
|
19434
|
+
continue;
|
|
19435
|
+
}
|
|
19436
|
+
summary.metadata = {
|
|
19437
|
+
...summary.metadata ?? {},
|
|
19438
|
+
moduleImports: [...imports].sort()
|
|
19439
|
+
};
|
|
19440
|
+
}
|
|
19441
|
+
}
|
|
19303
19442
|
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
19304
19443
|
"__pycache__",
|
|
19305
19444
|
".venv",
|
package/dist/index.d.cts
CHANGED
|
@@ -178,8 +178,19 @@ interface PythonPack {
|
|
|
178
178
|
/** Wire protocol for the produced boundary bindings, e.g. "http". */
|
|
179
179
|
protocol: string;
|
|
180
180
|
discovery: PythonDiscoveryPattern[];
|
|
181
|
+
/**
|
|
182
|
+
* Modules the project itself supplies, the wrappers a person names
|
|
183
|
+
* when configuring the pack. The library's own module is not one of
|
|
184
|
+
* these: it lives outside the project and would never resolve. The
|
|
185
|
+
* adapter checks each of these against the project's roots, because
|
|
186
|
+
* a wrapper that resolves to nothing does not match any decorator
|
|
187
|
+
* and never says why (#188).
|
|
188
|
+
*/
|
|
189
|
+
projectModules?: string[];
|
|
181
190
|
/** What the library's own database queries look like. The README says how one is matched. */
|
|
182
191
|
storage?: StoragePattern[];
|
|
192
|
+
/** How the library lets a project hand the database SQL it wrote itself. */
|
|
193
|
+
rawSql?: RawSqlPattern[];
|
|
183
194
|
}
|
|
184
195
|
/**
|
|
185
196
|
* A call talks to the database when the method behind it says it returns one
|
|
@@ -203,6 +214,20 @@ interface StoragePattern {
|
|
|
203
214
|
/** Which database the library is talking to, for the boundary binding. */
|
|
204
215
|
storageSystem: "postgres" | "mysql" | "sqlite";
|
|
205
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* The function a library gives a project for handing the database a
|
|
219
|
+
* statement written as SQL, and where it comes from. SQLAlchemy exports
|
|
220
|
+
* `text` from `sqlalchemy`. A local function of the same name is
|
|
221
|
+
* somebody else's, so the import is what settles a match.
|
|
222
|
+
*/
|
|
223
|
+
interface RawSqlPattern {
|
|
224
|
+
/** The module the function is imported from. */
|
|
225
|
+
module: string;
|
|
226
|
+
/** The functions that take a statement written as SQL. */
|
|
227
|
+
functions: string[];
|
|
228
|
+
/** Which database the library is talking to, for the boundary binding. */
|
|
229
|
+
storageSystem: "postgres" | "mysql" | "sqlite";
|
|
230
|
+
}
|
|
206
231
|
type PythonDiscoveryPattern = DecoratedClassRoute | DecoratedFunctionRoute;
|
|
207
232
|
/** Conventions both kinds of route share. Each one describes what the library does, never a project's choice. */
|
|
208
233
|
interface RouteConventions {
|
|
@@ -361,6 +386,8 @@ interface StorageLookup {
|
|
|
361
386
|
readonly definitionAt: (key: string) => Node | undefined;
|
|
362
387
|
readonly couldMatch: ReadonlySet<string>;
|
|
363
388
|
readonly leadsToStorage: ReadonlySet<string>;
|
|
389
|
+
/** What a pack says about statements a project writes as SQL itself. */
|
|
390
|
+
readonly rawSql?: readonly RawSqlPattern[];
|
|
364
391
|
}
|
|
365
392
|
|
|
366
393
|
/**
|
|
@@ -542,4 +569,4 @@ declare function extractPythonProject(options: ExtractPythonOptions): Promise<Ex
|
|
|
542
569
|
/** Every `.py` file under `root`, depth-first, skipping the usual non-source directories. */
|
|
543
570
|
declare function findPythonFiles(root: string): string[];
|
|
544
571
|
|
|
545
|
-
export { type AnnotationContext, type Binding, type BoundPythonFile, type DecoratedClassRoute, type DecoratedFunctionRoute, type DecoratorArg, type DecoratorClassification, type DiscoveryOptions, type ExtractPythonOptions, type ExtractPythonResult, type ModuleBinding, type ModuleResolution, type ModuleResolverOptions, type MountObjectCarrier, type MountObjectPrefix, type MountPrefixEffect, type NoValuePrefix, type PathRepeatedSlashes, type PrefixTrailingSlash, type PythonDiscoveryPattern, type PythonPack, type RelativeModuleSpec, type RouteConventions, type RoutePrefixResolution, type RouterComposition, type RouterIndex, type Scope, type ScopeKind, type StoragePattern, annotationToShape, bindModule, buildRouterIndex, classifyDecorator, containedValues, discoverUnits, emitEntryFact, emitModuleImportFacts, emitValueFacts, extractPythonProject, findPythonFiles, nodeId, objectReturnedBy, parsePython, resolveAbsoluteModule, resolveCalls, resolveModule, resolveName, resolveRelativeModule, shapeFromName, unitKey };
|
|
572
|
+
export { type AnnotationContext, type Binding, type BoundPythonFile, type DecoratedClassRoute, type DecoratedFunctionRoute, type DecoratorArg, type DecoratorClassification, type DiscoveryOptions, type ExtractPythonOptions, type ExtractPythonResult, type ModuleBinding, type ModuleResolution, type ModuleResolverOptions, type MountObjectCarrier, type MountObjectPrefix, type MountPrefixEffect, type NoValuePrefix, type PathRepeatedSlashes, type PrefixTrailingSlash, type PythonDiscoveryPattern, type PythonPack, type RawSqlPattern, type RelativeModuleSpec, type RouteConventions, type RoutePrefixResolution, type RouterComposition, type RouterIndex, type Scope, type ScopeKind, type StoragePattern, annotationToShape, bindModule, buildRouterIndex, classifyDecorator, containedValues, discoverUnits, emitEntryFact, emitModuleImportFacts, emitValueFacts, extractPythonProject, findPythonFiles, nodeId, objectReturnedBy, parsePython, resolveAbsoluteModule, resolveCalls, resolveModule, resolveName, resolveRelativeModule, shapeFromName, unitKey };
|
package/dist/index.d.ts
CHANGED
|
@@ -178,8 +178,19 @@ interface PythonPack {
|
|
|
178
178
|
/** Wire protocol for the produced boundary bindings, e.g. "http". */
|
|
179
179
|
protocol: string;
|
|
180
180
|
discovery: PythonDiscoveryPattern[];
|
|
181
|
+
/**
|
|
182
|
+
* Modules the project itself supplies, the wrappers a person names
|
|
183
|
+
* when configuring the pack. The library's own module is not one of
|
|
184
|
+
* these: it lives outside the project and would never resolve. The
|
|
185
|
+
* adapter checks each of these against the project's roots, because
|
|
186
|
+
* a wrapper that resolves to nothing does not match any decorator
|
|
187
|
+
* and never says why (#188).
|
|
188
|
+
*/
|
|
189
|
+
projectModules?: string[];
|
|
181
190
|
/** What the library's own database queries look like. The README says how one is matched. */
|
|
182
191
|
storage?: StoragePattern[];
|
|
192
|
+
/** How the library lets a project hand the database SQL it wrote itself. */
|
|
193
|
+
rawSql?: RawSqlPattern[];
|
|
183
194
|
}
|
|
184
195
|
/**
|
|
185
196
|
* A call talks to the database when the method behind it says it returns one
|
|
@@ -203,6 +214,20 @@ interface StoragePattern {
|
|
|
203
214
|
/** Which database the library is talking to, for the boundary binding. */
|
|
204
215
|
storageSystem: "postgres" | "mysql" | "sqlite";
|
|
205
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* The function a library gives a project for handing the database a
|
|
219
|
+
* statement written as SQL, and where it comes from. SQLAlchemy exports
|
|
220
|
+
* `text` from `sqlalchemy`. A local function of the same name is
|
|
221
|
+
* somebody else's, so the import is what settles a match.
|
|
222
|
+
*/
|
|
223
|
+
interface RawSqlPattern {
|
|
224
|
+
/** The module the function is imported from. */
|
|
225
|
+
module: string;
|
|
226
|
+
/** The functions that take a statement written as SQL. */
|
|
227
|
+
functions: string[];
|
|
228
|
+
/** Which database the library is talking to, for the boundary binding. */
|
|
229
|
+
storageSystem: "postgres" | "mysql" | "sqlite";
|
|
230
|
+
}
|
|
206
231
|
type PythonDiscoveryPattern = DecoratedClassRoute | DecoratedFunctionRoute;
|
|
207
232
|
/** Conventions both kinds of route share. Each one describes what the library does, never a project's choice. */
|
|
208
233
|
interface RouteConventions {
|
|
@@ -361,6 +386,8 @@ interface StorageLookup {
|
|
|
361
386
|
readonly definitionAt: (key: string) => Node | undefined;
|
|
362
387
|
readonly couldMatch: ReadonlySet<string>;
|
|
363
388
|
readonly leadsToStorage: ReadonlySet<string>;
|
|
389
|
+
/** What a pack says about statements a project writes as SQL itself. */
|
|
390
|
+
readonly rawSql?: readonly RawSqlPattern[];
|
|
364
391
|
}
|
|
365
392
|
|
|
366
393
|
/**
|
|
@@ -542,4 +569,4 @@ declare function extractPythonProject(options: ExtractPythonOptions): Promise<Ex
|
|
|
542
569
|
/** Every `.py` file under `root`, depth-first, skipping the usual non-source directories. */
|
|
543
570
|
declare function findPythonFiles(root: string): string[];
|
|
544
571
|
|
|
545
|
-
export { type AnnotationContext, type Binding, type BoundPythonFile, type DecoratedClassRoute, type DecoratedFunctionRoute, type DecoratorArg, type DecoratorClassification, type DiscoveryOptions, type ExtractPythonOptions, type ExtractPythonResult, type ModuleBinding, type ModuleResolution, type ModuleResolverOptions, type MountObjectCarrier, type MountObjectPrefix, type MountPrefixEffect, type NoValuePrefix, type PathRepeatedSlashes, type PrefixTrailingSlash, type PythonDiscoveryPattern, type PythonPack, type RelativeModuleSpec, type RouteConventions, type RoutePrefixResolution, type RouterComposition, type RouterIndex, type Scope, type ScopeKind, type StoragePattern, annotationToShape, bindModule, buildRouterIndex, classifyDecorator, containedValues, discoverUnits, emitEntryFact, emitModuleImportFacts, emitValueFacts, extractPythonProject, findPythonFiles, nodeId, objectReturnedBy, parsePython, resolveAbsoluteModule, resolveCalls, resolveModule, resolveName, resolveRelativeModule, shapeFromName, unitKey };
|
|
572
|
+
export { type AnnotationContext, type Binding, type BoundPythonFile, type DecoratedClassRoute, type DecoratedFunctionRoute, type DecoratorArg, type DecoratorClassification, type DiscoveryOptions, type ExtractPythonOptions, type ExtractPythonResult, type ModuleBinding, type ModuleResolution, type ModuleResolverOptions, type MountObjectCarrier, type MountObjectPrefix, type MountPrefixEffect, type NoValuePrefix, type PathRepeatedSlashes, type PrefixTrailingSlash, type PythonDiscoveryPattern, type PythonPack, type RawSqlPattern, type RelativeModuleSpec, type RouteConventions, type RoutePrefixResolution, type RouterComposition, type RouterIndex, type Scope, type ScopeKind, type StoragePattern, annotationToShape, bindModule, buildRouterIndex, classifyDecorator, containedValues, discoverUnits, emitEntryFact, emitModuleImportFacts, emitValueFacts, extractPythonProject, findPythonFiles, nodeId, objectReturnedBy, parsePython, resolveAbsoluteModule, resolveCalls, resolveModule, resolveName, resolveRelativeModule, shapeFromName, unitKey };
|
package/dist/index.js
CHANGED
|
@@ -1695,7 +1695,7 @@ __export(core_exports2, {
|
|
|
1695
1695
|
parse: () => parse,
|
|
1696
1696
|
parseAsync: () => parseAsync,
|
|
1697
1697
|
prettifyError: () => prettifyError,
|
|
1698
|
-
process: () =>
|
|
1698
|
+
process: () => process2,
|
|
1699
1699
|
regexes: () => regexes_exports,
|
|
1700
1700
|
registry: () => registry,
|
|
1701
1701
|
safeDecode: () => safeDecode,
|
|
@@ -12620,7 +12620,7 @@ function initializeContext(params) {
|
|
|
12620
12620
|
external: params?.external ?? void 0
|
|
12621
12621
|
};
|
|
12622
12622
|
}
|
|
12623
|
-
function
|
|
12623
|
+
function process2(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
12624
12624
|
var _a3;
|
|
12625
12625
|
const def = schema._zod.def;
|
|
12626
12626
|
const seen = ctx.seen.get(schema);
|
|
@@ -12657,7 +12657,7 @@ function process(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
|
12657
12657
|
if (parent) {
|
|
12658
12658
|
if (!result.ref)
|
|
12659
12659
|
result.ref = parent;
|
|
12660
|
-
|
|
12660
|
+
process2(parent, ctx, params);
|
|
12661
12661
|
ctx.seen.get(parent).isParent = true;
|
|
12662
12662
|
}
|
|
12663
12663
|
}
|
|
@@ -12945,14 +12945,14 @@ function isTransforming(_schema, _ctx) {
|
|
|
12945
12945
|
}
|
|
12946
12946
|
var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
|
|
12947
12947
|
const ctx = initializeContext({ ...params, processors });
|
|
12948
|
-
|
|
12948
|
+
process2(schema, ctx);
|
|
12949
12949
|
extractDefs(ctx, schema);
|
|
12950
12950
|
return finalize(ctx, schema);
|
|
12951
12951
|
};
|
|
12952
12952
|
var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
|
|
12953
12953
|
const { libraryOptions, target } = params ?? {};
|
|
12954
12954
|
const ctx = initializeContext({ ...libraryOptions ?? {}, target, io, processors });
|
|
12955
|
-
|
|
12955
|
+
process2(schema, ctx);
|
|
12956
12956
|
extractDefs(ctx, schema);
|
|
12957
12957
|
return finalize(ctx, schema);
|
|
12958
12958
|
};
|
|
@@ -13198,7 +13198,7 @@ var arrayProcessor = (schema, ctx, _json, params) => {
|
|
|
13198
13198
|
if (typeof maximum === "number")
|
|
13199
13199
|
json2.maxItems = maximum;
|
|
13200
13200
|
json2.type = "array";
|
|
13201
|
-
json2.items =
|
|
13201
|
+
json2.items = process2(def.element, ctx, {
|
|
13202
13202
|
...params,
|
|
13203
13203
|
path: [...params.path, "items"]
|
|
13204
13204
|
});
|
|
@@ -13210,7 +13210,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
13210
13210
|
json2.properties = {};
|
|
13211
13211
|
const shape = def.shape;
|
|
13212
13212
|
for (const key in shape) {
|
|
13213
|
-
json2.properties[key] =
|
|
13213
|
+
json2.properties[key] = process2(shape[key], ctx, {
|
|
13214
13214
|
...params,
|
|
13215
13215
|
path: [...params.path, "properties", key]
|
|
13216
13216
|
});
|
|
@@ -13233,7 +13233,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
13233
13233
|
if (ctx.io === "output")
|
|
13234
13234
|
json2.additionalProperties = false;
|
|
13235
13235
|
} else if (def.catchall) {
|
|
13236
|
-
json2.additionalProperties =
|
|
13236
|
+
json2.additionalProperties = process2(def.catchall, ctx, {
|
|
13237
13237
|
...params,
|
|
13238
13238
|
path: [...params.path, "additionalProperties"]
|
|
13239
13239
|
});
|
|
@@ -13242,7 +13242,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
13242
13242
|
var unionProcessor = (schema, ctx, json2, params) => {
|
|
13243
13243
|
const def = schema._zod.def;
|
|
13244
13244
|
const isExclusive = def.inclusive === false;
|
|
13245
|
-
const options = def.options.map((x, i) =>
|
|
13245
|
+
const options = def.options.map((x, i) => process2(x, ctx, {
|
|
13246
13246
|
...params,
|
|
13247
13247
|
path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
|
|
13248
13248
|
}));
|
|
@@ -13254,11 +13254,11 @@ var unionProcessor = (schema, ctx, json2, params) => {
|
|
|
13254
13254
|
};
|
|
13255
13255
|
var intersectionProcessor = (schema, ctx, json2, params) => {
|
|
13256
13256
|
const def = schema._zod.def;
|
|
13257
|
-
const a =
|
|
13257
|
+
const a = process2(def.left, ctx, {
|
|
13258
13258
|
...params,
|
|
13259
13259
|
path: [...params.path, "allOf", 0]
|
|
13260
13260
|
});
|
|
13261
|
-
const b =
|
|
13261
|
+
const b = process2(def.right, ctx, {
|
|
13262
13262
|
...params,
|
|
13263
13263
|
path: [...params.path, "allOf", 1]
|
|
13264
13264
|
});
|
|
@@ -13275,11 +13275,11 @@ var tupleProcessor = (schema, ctx, _json, params) => {
|
|
|
13275
13275
|
json2.type = "array";
|
|
13276
13276
|
const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
13277
13277
|
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
13278
|
-
const prefixItems = def.items.map((x, i) =>
|
|
13278
|
+
const prefixItems = def.items.map((x, i) => process2(x, ctx, {
|
|
13279
13279
|
...params,
|
|
13280
13280
|
path: [...params.path, prefixPath, i]
|
|
13281
13281
|
}));
|
|
13282
|
-
const rest = def.rest ?
|
|
13282
|
+
const rest = def.rest ? process2(def.rest, ctx, {
|
|
13283
13283
|
...params,
|
|
13284
13284
|
path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
|
|
13285
13285
|
}) : null;
|
|
@@ -13319,7 +13319,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
13319
13319
|
const keyBag = keyType._zod.bag;
|
|
13320
13320
|
const patterns = keyBag?.patterns;
|
|
13321
13321
|
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
13322
|
-
const valueSchema =
|
|
13322
|
+
const valueSchema = process2(def.valueType, ctx, {
|
|
13323
13323
|
...params,
|
|
13324
13324
|
path: [...params.path, "patternProperties", "*"]
|
|
13325
13325
|
});
|
|
@@ -13329,12 +13329,12 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
13329
13329
|
}
|
|
13330
13330
|
} else {
|
|
13331
13331
|
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
|
|
13332
|
-
json2.propertyNames =
|
|
13332
|
+
json2.propertyNames = process2(def.keyType, ctx, {
|
|
13333
13333
|
...params,
|
|
13334
13334
|
path: [...params.path, "propertyNames"]
|
|
13335
13335
|
});
|
|
13336
13336
|
}
|
|
13337
|
-
json2.additionalProperties =
|
|
13337
|
+
json2.additionalProperties = process2(def.valueType, ctx, {
|
|
13338
13338
|
...params,
|
|
13339
13339
|
path: [...params.path, "additionalProperties"]
|
|
13340
13340
|
});
|
|
@@ -13349,7 +13349,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
13349
13349
|
};
|
|
13350
13350
|
var nullableProcessor = (schema, ctx, json2, params) => {
|
|
13351
13351
|
const def = schema._zod.def;
|
|
13352
|
-
const inner =
|
|
13352
|
+
const inner = process2(def.innerType, ctx, params);
|
|
13353
13353
|
const seen = ctx.seen.get(schema);
|
|
13354
13354
|
if (ctx.target === "openapi-3.0") {
|
|
13355
13355
|
seen.ref = def.innerType;
|
|
@@ -13360,20 +13360,20 @@ var nullableProcessor = (schema, ctx, json2, params) => {
|
|
|
13360
13360
|
};
|
|
13361
13361
|
var nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
13362
13362
|
const def = schema._zod.def;
|
|
13363
|
-
|
|
13363
|
+
process2(def.innerType, ctx, params);
|
|
13364
13364
|
const seen = ctx.seen.get(schema);
|
|
13365
13365
|
seen.ref = def.innerType;
|
|
13366
13366
|
};
|
|
13367
13367
|
var defaultProcessor = (schema, ctx, json2, params) => {
|
|
13368
13368
|
const def = schema._zod.def;
|
|
13369
|
-
|
|
13369
|
+
process2(def.innerType, ctx, params);
|
|
13370
13370
|
const seen = ctx.seen.get(schema);
|
|
13371
13371
|
seen.ref = def.innerType;
|
|
13372
13372
|
json2.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
13373
13373
|
};
|
|
13374
13374
|
var prefaultProcessor = (schema, ctx, json2, params) => {
|
|
13375
13375
|
const def = schema._zod.def;
|
|
13376
|
-
|
|
13376
|
+
process2(def.innerType, ctx, params);
|
|
13377
13377
|
const seen = ctx.seen.get(schema);
|
|
13378
13378
|
seen.ref = def.innerType;
|
|
13379
13379
|
if (ctx.io === "input")
|
|
@@ -13381,7 +13381,7 @@ var prefaultProcessor = (schema, ctx, json2, params) => {
|
|
|
13381
13381
|
};
|
|
13382
13382
|
var catchProcessor = (schema, ctx, json2, params) => {
|
|
13383
13383
|
const def = schema._zod.def;
|
|
13384
|
-
|
|
13384
|
+
process2(def.innerType, ctx, params);
|
|
13385
13385
|
const seen = ctx.seen.get(schema);
|
|
13386
13386
|
seen.ref = def.innerType;
|
|
13387
13387
|
let catchValue;
|
|
@@ -13396,32 +13396,32 @@ var pipeProcessor = (schema, ctx, _json, params) => {
|
|
|
13396
13396
|
const def = schema._zod.def;
|
|
13397
13397
|
const inIsTransform = def.in._zod.traits.has("$ZodTransform");
|
|
13398
13398
|
const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out;
|
|
13399
|
-
|
|
13399
|
+
process2(innerType, ctx, params);
|
|
13400
13400
|
const seen = ctx.seen.get(schema);
|
|
13401
13401
|
seen.ref = innerType;
|
|
13402
13402
|
};
|
|
13403
13403
|
var readonlyProcessor = (schema, ctx, json2, params) => {
|
|
13404
13404
|
const def = schema._zod.def;
|
|
13405
|
-
|
|
13405
|
+
process2(def.innerType, ctx, params);
|
|
13406
13406
|
const seen = ctx.seen.get(schema);
|
|
13407
13407
|
seen.ref = def.innerType;
|
|
13408
13408
|
json2.readOnly = true;
|
|
13409
13409
|
};
|
|
13410
13410
|
var promiseProcessor = (schema, ctx, _json, params) => {
|
|
13411
13411
|
const def = schema._zod.def;
|
|
13412
|
-
|
|
13412
|
+
process2(def.innerType, ctx, params);
|
|
13413
13413
|
const seen = ctx.seen.get(schema);
|
|
13414
13414
|
seen.ref = def.innerType;
|
|
13415
13415
|
};
|
|
13416
13416
|
var optionalProcessor = (schema, ctx, _json, params) => {
|
|
13417
13417
|
const def = schema._zod.def;
|
|
13418
|
-
|
|
13418
|
+
process2(def.innerType, ctx, params);
|
|
13419
13419
|
const seen = ctx.seen.get(schema);
|
|
13420
13420
|
seen.ref = def.innerType;
|
|
13421
13421
|
};
|
|
13422
13422
|
var lazyProcessor = (schema, ctx, _json, params) => {
|
|
13423
13423
|
const innerType = schema._zod.innerType;
|
|
13424
|
-
|
|
13424
|
+
process2(innerType, ctx, params);
|
|
13425
13425
|
const seen = ctx.seen.get(schema);
|
|
13426
13426
|
seen.ref = innerType;
|
|
13427
13427
|
};
|
|
@@ -13473,7 +13473,7 @@ function toJSONSchema(input, params) {
|
|
|
13473
13473
|
const defs = {};
|
|
13474
13474
|
for (const entry of registry2._idmap.entries()) {
|
|
13475
13475
|
const [_, schema] = entry;
|
|
13476
|
-
|
|
13476
|
+
process2(schema, ctx2);
|
|
13477
13477
|
}
|
|
13478
13478
|
const schemas = {};
|
|
13479
13479
|
const external = {
|
|
@@ -13496,7 +13496,7 @@ function toJSONSchema(input, params) {
|
|
|
13496
13496
|
return { schemas };
|
|
13497
13497
|
}
|
|
13498
13498
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
13499
|
-
|
|
13499
|
+
process2(input, ctx);
|
|
13500
13500
|
extractDefs(ctx, input);
|
|
13501
13501
|
return finalize(ctx, input);
|
|
13502
13502
|
}
|
|
@@ -13554,7 +13554,7 @@ var JSONSchemaGenerator = class {
|
|
|
13554
13554
|
* This must be called before emit().
|
|
13555
13555
|
*/
|
|
13556
13556
|
process(schema, _params = { path: [], schemaPath: [] }) {
|
|
13557
|
-
return
|
|
13557
|
+
return process2(schema, this.ctx, _params);
|
|
13558
13558
|
}
|
|
13559
13559
|
/**
|
|
13560
13560
|
* Emit the final JSON Schema after processing.
|
|
@@ -15703,7 +15703,7 @@ function date4(params) {
|
|
|
15703
15703
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
15704
15704
|
config(en_default());
|
|
15705
15705
|
|
|
15706
|
-
// ../../ir-core/dist/chunk-
|
|
15706
|
+
// ../../ir-core/dist/chunk-TEXSN75M.js
|
|
15707
15707
|
function gqlIdentityKey(typeName, fieldName) {
|
|
15708
15708
|
return `gql:${typeName}.${fieldName}`;
|
|
15709
15709
|
}
|
|
@@ -16072,27 +16072,41 @@ var runtimeConfigSemantics = defineBoundarySemantics({
|
|
|
16072
16072
|
identityKey: () => null
|
|
16073
16073
|
}
|
|
16074
16074
|
});
|
|
16075
|
-
var
|
|
16076
|
-
name: external_exports.literal("storage
|
|
16077
|
-
storageSystem: external_exports.enum(["postgres", "mysql", "sqlite"]),
|
|
16075
|
+
var StorageSemanticsSchema = external_exports.object({
|
|
16076
|
+
name: external_exports.literal("storage"),
|
|
16078
16077
|
/**
|
|
16079
|
-
*
|
|
16080
|
-
*
|
|
16078
|
+
* Which store this is: postgres, mysql, sqlite, dynamodb. Two
|
|
16079
|
+
* products' containers can share a name, so this keeps them apart,
|
|
16080
|
+
* and it is what a finding message calls the store.
|
|
16081
|
+
*/
|
|
16082
|
+
storageSystem: external_exports.string(),
|
|
16083
|
+
/**
|
|
16084
|
+
* The ORM, schema, or deployment scope. A single-database setup uses
|
|
16085
|
+
* `"default"`, and a monorepo with several schemas gives each one its
|
|
16086
|
+
* own value.
|
|
16081
16087
|
*/
|
|
16082
16088
|
scope: external_exports.string(),
|
|
16083
16089
|
/**
|
|
16084
|
-
* The table or
|
|
16085
|
-
* the source states one this reader could not
|
|
16086
|
-
* pairs with nothing, rather than with
|
|
16087
|
-
* happens to spell.
|
|
16090
|
+
* The table, bucket, collection, or index, as the source declares
|
|
16091
|
+
* it, or null when the source states one this reader could not
|
|
16092
|
+
* settle. A null container pairs with nothing, rather than with
|
|
16093
|
+
* whatever its source text happens to spell.
|
|
16088
16094
|
*/
|
|
16089
|
-
|
|
16095
|
+
container: external_exports.string().nullable(),
|
|
16096
|
+
/**
|
|
16097
|
+
* A secondary way into the container, a DynamoDB global secondary
|
|
16098
|
+
* index or an Elasticsearch alias, each with its own key fields.
|
|
16099
|
+
* Null means the container's own primary way in. A query through an
|
|
16100
|
+
* index and a query through the table are different accesses, so
|
|
16101
|
+
* they pair separately.
|
|
16102
|
+
*/
|
|
16103
|
+
accessPath: external_exports.string().nullable()
|
|
16090
16104
|
});
|
|
16091
|
-
var
|
|
16092
|
-
name: "storage
|
|
16093
|
-
schema:
|
|
16105
|
+
var storageSemantics = defineBoundarySemantics({
|
|
16106
|
+
name: "storage",
|
|
16107
|
+
schema: StorageSemanticsSchema,
|
|
16094
16108
|
behavior: {
|
|
16095
|
-
/** A query returns rows, not a status and a body. */
|
|
16109
|
+
/** A query returns rows or items, not a status and a body. */
|
|
16096
16110
|
exchangesHttpResponses: false,
|
|
16097
16111
|
reportsUnpairedItself: false,
|
|
16098
16112
|
identityKey: () => null
|
|
@@ -16104,7 +16118,7 @@ var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
|
16104
16118
|
graphqlResolverSemantics.schema,
|
|
16105
16119
|
graphqlOperationSemantics.schema,
|
|
16106
16120
|
runtimeConfigSemantics.schema,
|
|
16107
|
-
|
|
16121
|
+
storageSemantics.schema,
|
|
16108
16122
|
messageBusSemantics.schema
|
|
16109
16123
|
]);
|
|
16110
16124
|
var DEFINITIONS = [
|
|
@@ -16113,7 +16127,7 @@ var DEFINITIONS = [
|
|
|
16113
16127
|
graphqlResolverSemantics,
|
|
16114
16128
|
graphqlOperationSemantics,
|
|
16115
16129
|
runtimeConfigSemantics,
|
|
16116
|
-
|
|
16130
|
+
storageSemantics,
|
|
16117
16131
|
messageBusSemantics
|
|
16118
16132
|
];
|
|
16119
16133
|
var BY_NAME = new Map(
|
|
@@ -16253,19 +16267,97 @@ function namedOrNull(value, field2) {
|
|
|
16253
16267
|
}
|
|
16254
16268
|
return value;
|
|
16255
16269
|
}
|
|
16256
|
-
function
|
|
16270
|
+
function storageBinding(opts) {
|
|
16257
16271
|
return {
|
|
16258
|
-
transport: opts.storageSystem,
|
|
16272
|
+
transport: opts.transport ?? opts.storageSystem,
|
|
16259
16273
|
semantics: {
|
|
16260
|
-
name: "storage
|
|
16274
|
+
name: "storage",
|
|
16261
16275
|
storageSystem: opts.storageSystem,
|
|
16262
16276
|
scope: opts.scope,
|
|
16263
|
-
|
|
16277
|
+
container: namedOrNull(opts.container, "storage container"),
|
|
16278
|
+
accessPath: opts.accessPath ?? null
|
|
16264
16279
|
},
|
|
16265
16280
|
recognition: opts.recognition
|
|
16266
16281
|
};
|
|
16267
16282
|
}
|
|
16268
16283
|
|
|
16284
|
+
// src/rawSql.ts
|
|
16285
|
+
import { readSqlAccess, sqlFromParts } from "@suss/sql";
|
|
16286
|
+
function rawSqlEffects(calls, options) {
|
|
16287
|
+
if (options.patterns.length === 0) {
|
|
16288
|
+
return [];
|
|
16289
|
+
}
|
|
16290
|
+
const effects = [];
|
|
16291
|
+
for (const call of calls) {
|
|
16292
|
+
const pattern = patternFor(call, options);
|
|
16293
|
+
if (pattern === void 0) {
|
|
16294
|
+
continue;
|
|
16295
|
+
}
|
|
16296
|
+
const statement = statementIn(call);
|
|
16297
|
+
if (statement === null) {
|
|
16298
|
+
continue;
|
|
16299
|
+
}
|
|
16300
|
+
for (const access of readSqlAccess(statement, {
|
|
16301
|
+
dialect: pattern.storageSystem
|
|
16302
|
+
})) {
|
|
16303
|
+
effects.push({
|
|
16304
|
+
type: "interaction",
|
|
16305
|
+
binding: storageBinding({
|
|
16306
|
+
recognition: `python-${pattern.module}`,
|
|
16307
|
+
storageSystem: pattern.storageSystem,
|
|
16308
|
+
scope: pattern.module,
|
|
16309
|
+
container: access.table
|
|
16310
|
+
}),
|
|
16311
|
+
callee: field(call, "function")?.text ?? "",
|
|
16312
|
+
interaction: {
|
|
16313
|
+
class: "storage-access",
|
|
16314
|
+
kind: access.kind,
|
|
16315
|
+
fields: access.fields,
|
|
16316
|
+
...access.selector.length > 0 ? { selector: access.selector } : {},
|
|
16317
|
+
operation: field(call, "function")?.text ?? ""
|
|
16318
|
+
}
|
|
16319
|
+
});
|
|
16320
|
+
}
|
|
16321
|
+
}
|
|
16322
|
+
return effects;
|
|
16323
|
+
}
|
|
16324
|
+
function patternFor(call, options) {
|
|
16325
|
+
const callee = field(call, "function");
|
|
16326
|
+
if (callee === null || callee.type !== "identifier") {
|
|
16327
|
+
return void 0;
|
|
16328
|
+
}
|
|
16329
|
+
const from = options.facts.facts("pyImportedName").find((row) => String(row[0]) === `${options.filePath}#${callee.text}`);
|
|
16330
|
+
if (from === void 0) {
|
|
16331
|
+
return void 0;
|
|
16332
|
+
}
|
|
16333
|
+
const module = String(from[1]);
|
|
16334
|
+
return options.patterns.find(
|
|
16335
|
+
(pattern) => pattern.module === module && pattern.functions.includes(callee.text)
|
|
16336
|
+
);
|
|
16337
|
+
}
|
|
16338
|
+
function statementIn(call) {
|
|
16339
|
+
const args = field(call, "arguments");
|
|
16340
|
+
const first = args?.namedChildren.find((child) => child !== null) ?? null;
|
|
16341
|
+
if (first === null || first.type !== "string") {
|
|
16342
|
+
return null;
|
|
16343
|
+
}
|
|
16344
|
+
const parts = [""];
|
|
16345
|
+
for (const child of first.namedChildren) {
|
|
16346
|
+
if (child === null) {
|
|
16347
|
+
continue;
|
|
16348
|
+
}
|
|
16349
|
+
if (child.type === "string_content") {
|
|
16350
|
+
parts[parts.length - 1] += child.text;
|
|
16351
|
+
continue;
|
|
16352
|
+
}
|
|
16353
|
+
if (child.type === "interpolation") {
|
|
16354
|
+
parts.push("");
|
|
16355
|
+
}
|
|
16356
|
+
}
|
|
16357
|
+
const statement = sqlFromParts(parts);
|
|
16358
|
+
return statement.trim() === "" ? null : statement;
|
|
16359
|
+
}
|
|
16360
|
+
|
|
16269
16361
|
// src/facts/resolve.ts
|
|
16270
16362
|
import { deriveOnDemand, evaluate } from "@suss/datalog";
|
|
16271
16363
|
|
|
@@ -17116,11 +17208,11 @@ function effectFor(pattern, chain, options) {
|
|
|
17116
17208
|
];
|
|
17117
17209
|
return {
|
|
17118
17210
|
type: "interaction",
|
|
17119
|
-
binding:
|
|
17211
|
+
binding: storageBinding({
|
|
17120
17212
|
recognition: "python-storage",
|
|
17121
17213
|
storageSystem: pattern.storageSystem,
|
|
17122
17214
|
scope: pattern.module,
|
|
17123
|
-
|
|
17215
|
+
container: chain.subject
|
|
17124
17216
|
}),
|
|
17125
17217
|
callee: chain.last.text,
|
|
17126
17218
|
interaction: {
|
|
@@ -17863,10 +17955,17 @@ function buildRouteUnit(options) {
|
|
|
17863
17955
|
() => readReturnAnnotation(definitionNode, enclosingScope, ctx)
|
|
17864
17956
|
);
|
|
17865
17957
|
const effects = invocationEffects(definitionNode);
|
|
17866
|
-
const storage = storageLookup === void 0 ? [] :
|
|
17867
|
-
...
|
|
17868
|
-
|
|
17869
|
-
|
|
17958
|
+
const storage = storageLookup === void 0 ? [] : [
|
|
17959
|
+
...storageEffects(bodyCalls(definitionNode), {
|
|
17960
|
+
...storageLookup,
|
|
17961
|
+
filePath: storageLookup.factsPath
|
|
17962
|
+
}),
|
|
17963
|
+
...rawSqlEffects(bodyCalls(definitionNode), {
|
|
17964
|
+
facts: storageLookup.facts,
|
|
17965
|
+
filePath: storageLookup.factsPath,
|
|
17966
|
+
patterns: storageLookup.rawSql ?? []
|
|
17967
|
+
})
|
|
17968
|
+
];
|
|
17870
17969
|
const perReturn = branchesFromReturns(
|
|
17871
17970
|
readsReturnedStatus,
|
|
17872
17971
|
definitionNode,
|
|
@@ -19187,11 +19286,26 @@ function carrierPrefix(carrier, constructorArg, objectName, scope, scan) {
|
|
|
19187
19286
|
}
|
|
19188
19287
|
|
|
19189
19288
|
// src/project.ts
|
|
19289
|
+
function reportUnresolvedProjectModules(options) {
|
|
19290
|
+
for (const pack of options.packs) {
|
|
19291
|
+
for (const module of pack.projectModules ?? []) {
|
|
19292
|
+
const resolved = resolveAbsoluteModule(module, { roots: options.roots });
|
|
19293
|
+
if (resolved.status === "resolved") {
|
|
19294
|
+
continue;
|
|
19295
|
+
}
|
|
19296
|
+
process.stderr.write(
|
|
19297
|
+
`[suss] ${pack.name}: the configured module ${module} does not resolve under ${options.roots.join(", ")}, so nothing it wraps will be discovered.
|
|
19298
|
+
`
|
|
19299
|
+
);
|
|
19300
|
+
}
|
|
19301
|
+
}
|
|
19302
|
+
}
|
|
19190
19303
|
async function extractPythonProject(options) {
|
|
19191
19304
|
const db = new Database();
|
|
19192
19305
|
const summaries = [];
|
|
19193
19306
|
const gapHandling = options.gapHandling ?? "permissive";
|
|
19194
19307
|
const displayPathOf = (file2) => options.workspaceRoot !== void 0 ? path3.relative(options.workspaceRoot, file2) : file2;
|
|
19308
|
+
reportUnresolvedProjectModules(options);
|
|
19195
19309
|
const bound = [];
|
|
19196
19310
|
for (const file2 of options.files) {
|
|
19197
19311
|
const source = fs3.readFileSync(file2, "utf8");
|
|
@@ -19207,6 +19321,7 @@ async function extractPythonProject(options) {
|
|
|
19207
19321
|
(pack) => pack.discovery.some((pattern) => pattern.routerComposition !== void 0)
|
|
19208
19322
|
);
|
|
19209
19323
|
const storagePatterns = options.packs.flatMap((pack) => pack.storage ?? []);
|
|
19324
|
+
const rawSqlPatterns = options.packs.flatMap((pack) => pack.rawSql ?? []);
|
|
19210
19325
|
const needsValues = mountsRouters || storagePatterns.length > 0;
|
|
19211
19326
|
const definitions = /* @__PURE__ */ new Map();
|
|
19212
19327
|
for (const { file: file2, root, module: moduleBinding } of bound) {
|
|
@@ -19236,14 +19351,15 @@ async function extractPythonProject(options) {
|
|
|
19236
19351
|
absoluteFile: file2,
|
|
19237
19352
|
routerIndex,
|
|
19238
19353
|
gapHandling,
|
|
19239
|
-
...storagePatterns.length > 0 ? {
|
|
19354
|
+
...storagePatterns.length > 0 || rawSqlPatterns.length > 0 ? {
|
|
19240
19355
|
storage: {
|
|
19241
19356
|
facts: db,
|
|
19242
19357
|
factsPath: file2,
|
|
19243
19358
|
patterns: storagePatterns,
|
|
19244
19359
|
definitionAt: (key) => definitions.get(key),
|
|
19245
19360
|
couldMatch,
|
|
19246
|
-
leadsToStorage
|
|
19361
|
+
leadsToStorage,
|
|
19362
|
+
rawSql: rawSqlPatterns
|
|
19247
19363
|
}
|
|
19248
19364
|
} : {}
|
|
19249
19365
|
});
|
|
@@ -19254,8 +19370,31 @@ async function extractPythonProject(options) {
|
|
|
19254
19370
|
emitEntryFact(db, file2, raw.identity.range, raw.identity.name);
|
|
19255
19371
|
}
|
|
19256
19372
|
}
|
|
19373
|
+
stampModuleImports(summaries, db, displayPathOf);
|
|
19257
19374
|
return { summaries, facts: db };
|
|
19258
19375
|
}
|
|
19376
|
+
function stampModuleImports(summaries, db, displayPathOf) {
|
|
19377
|
+
const importsByFile = /* @__PURE__ */ new Map();
|
|
19378
|
+
for (const [from, , to] of db.facts("pyImportResolved")) {
|
|
19379
|
+
if (typeof from !== "string" || typeof to !== "string") {
|
|
19380
|
+
continue;
|
|
19381
|
+
}
|
|
19382
|
+
const key = displayPathOf(from);
|
|
19383
|
+
const seen = importsByFile.get(key) ?? /* @__PURE__ */ new Set();
|
|
19384
|
+
seen.add(displayPathOf(to));
|
|
19385
|
+
importsByFile.set(key, seen);
|
|
19386
|
+
}
|
|
19387
|
+
for (const summary of summaries) {
|
|
19388
|
+
const imports = importsByFile.get(summary.location.file);
|
|
19389
|
+
if (imports === void 0 || imports.size === 0) {
|
|
19390
|
+
continue;
|
|
19391
|
+
}
|
|
19392
|
+
summary.metadata = {
|
|
19393
|
+
...summary.metadata ?? {},
|
|
19394
|
+
moduleImports: [...imports].sort()
|
|
19395
|
+
};
|
|
19396
|
+
}
|
|
19397
|
+
}
|
|
19259
19398
|
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
19260
19399
|
"__pycache__",
|
|
19261
19400
|
".venv",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/adapter-python",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Python language adapter for suss — parses source with tree-sitter (WASM), resolves names with a lexical binder, and emits raw extractions for the suss pipeline.",
|
|
6
6
|
"keywords": [
|
|
@@ -47,9 +47,10 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@suss/behavioral-ir": "0.
|
|
51
|
-
"@suss/datalog": "0.
|
|
52
|
-
"@suss/extractor": "0.
|
|
50
|
+
"@suss/behavioral-ir": "0.6.0",
|
|
51
|
+
"@suss/datalog": "0.6.0",
|
|
52
|
+
"@suss/extractor": "0.6.0",
|
|
53
|
+
"@suss/sql": "0.6.0",
|
|
53
54
|
"web-tree-sitter": "^0.26.11"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|