@suss/adapter-python 0.21.0 → 0.21.1

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.
Files changed (3) hide show
  1. package/dist/index.cjs +105 -45
  2. package/dist/index.js +107 -47
  3. package/package.json +5 -5
package/dist/index.cjs CHANGED
@@ -969,9 +969,9 @@ var RESOLUTION_RULES = [
969
969
  [(0, import_datalog2.lit)("invokes", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("f")), (0, import_datalog2.lit)("returnsValue", (0, import_datalog2.variable)("f"), (0, import_datalog2.variable)("ret"))],
970
970
  "call result"
971
971
  ),
972
- // Where a walk gets to, and whether it ran a call on the way. A value
973
- // step keeps whatever the rest of the walk was, and a result step
974
- // makes the whole walk one that ran a call.
972
+ // Where a walk gets to, and whether it ran a call on the way. The walk
973
+ // so far comes first, so demand stays on the value asked about; the
974
+ // README says what the other order cost.
975
975
  (0, import_datalog2.rule)(
976
976
  "reaches",
977
977
  [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("kind")],
@@ -981,27 +981,27 @@ var RESOLUTION_RULES = [
981
981
  "reaches",
982
982
  [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("kind")],
983
983
  [
984
- (0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), VALUE_STEP),
985
- (0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("kind"))
984
+ (0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), VALUE_STEP),
985
+ (0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("kind"))
986
986
  ]
987
987
  ),
988
- // Two rules rather than one leaving the rest of the walk's kind free.
989
- // A free kind is a second question about the same relation, and a
988
+ // Two rules rather than one leaving the next step's kind free. A free
989
+ // kind is a second question about the same relation, and a
990
990
  // demand-driven run then derives both to answer either.
991
991
  (0, import_datalog2.rule)(
992
992
  "reaches",
993
993
  [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), RESULT_STEP],
994
994
  [
995
- (0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), RESULT_STEP),
996
- (0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), VALUE_STEP)
995
+ (0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), RESULT_STEP),
996
+ (0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), VALUE_STEP)
997
997
  ]
998
998
  ),
999
999
  (0, import_datalog2.rule)(
1000
1000
  "reaches",
1001
1001
  [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), RESULT_STEP],
1002
1002
  [
1003
- (0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), RESULT_STEP),
1004
- (0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), RESULT_STEP)
1003
+ (0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), RESULT_STEP),
1004
+ (0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), RESULT_STEP)
1005
1005
  ]
1006
1006
  ),
1007
1007
  // What a value comes down to: the walk that never ran a call, stopped
@@ -1347,29 +1347,14 @@ var RESOLUTION_QUESTIONS = [
1347
1347
  // here demands reaches or callsInto. The chains are closures with
1348
1348
  // no depth bound: an alias run of any length resolves.
1349
1349
  (0, import_datalog2.rule)("callOriginChain", [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("x")], [(0, import_datalog2.lit)("wantedCallOrigin", (0, import_datalog2.variable)("x"))]),
1350
+ // The chain with at least one hop taken, which is what tells a
1351
+ // destructured binding apart from asking about a node directly. The
1352
+ // whole chain is the seed plus those hops.
1350
1353
  (0, import_datalog2.rule)(
1351
1354
  "callOriginChain",
1352
1355
  [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
1353
- [(0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
1354
- ),
1355
- (0, import_datalog2.rule)(
1356
- "callOriginChain",
1357
- [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
1358
- [
1359
- (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
1360
- (0, import_datalog2.lit)("endsHolding", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
1361
- ]
1362
- ),
1363
- (0, import_datalog2.rule)(
1364
- "callOriginChain",
1365
- [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
1366
- [
1367
- (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
1368
- (0, import_datalog2.lit)("fallbackBranch", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
1369
- ]
1356
+ [(0, import_datalog2.lit)("callOriginChainStepped", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"))]
1370
1357
  ),
1371
- // The chain with at least one hop taken, which is what tells a
1372
- // destructured binding apart from asking about a node directly.
1373
1358
  (0, import_datalog2.rule)(
1374
1359
  "callOriginChainStepped",
1375
1360
  [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
@@ -16996,7 +16981,7 @@ function date4(params) {
16996
16981
  // ../../../node_modules/zod/v4/classic/external.js
16997
16982
  config(en_default());
16998
16983
 
16999
- // ../../ir-core/dist/chunk-QHFMZPEG.js
16984
+ // ../../ir-core/dist/chunk-PPQWK62O.js
17000
16985
  function gqlIdentityKey(typeName, fieldName) {
17001
16986
  return `gql:${typeName}.${fieldName}`;
17002
16987
  }
@@ -17282,6 +17267,42 @@ var metricSemantics = defineBoundarySemantics({
17282
17267
  }
17283
17268
  }
17284
17269
  });
17270
+ var HOLE_SPLIT = /(\{[^}]*\})/;
17271
+ function isHole(piece) {
17272
+ return piece.startsWith("{") && piece.endsWith("}");
17273
+ }
17274
+ function parseBoundaryName(name) {
17275
+ const parts = name.split(HOLE_SPLIT).filter((piece) => piece !== "").map(
17276
+ (piece) => isHole(piece) ? { type: "hole", label: piece.slice(1, -1) } : { type: "text", text: piece }
17277
+ );
17278
+ const only = parts.length === 1 ? parts[0] : void 0;
17279
+ if (only !== void 0 && only.type === "hole") {
17280
+ return { type: "reference", path: only.label.split(".") };
17281
+ }
17282
+ if (parts.some((part) => part.type === "hole")) {
17283
+ return { type: "pattern", parts };
17284
+ }
17285
+ return { type: "literal", value: name };
17286
+ }
17287
+ function patternHole(label) {
17288
+ return `{${label}}`;
17289
+ }
17290
+ function namesNothing(name) {
17291
+ return parseBoundaryName(name).type === "reference";
17292
+ }
17293
+ function referenceOf(name) {
17294
+ if (name.type !== "reference") {
17295
+ return null;
17296
+ }
17297
+ const root = name.path[0];
17298
+ if (root === void 0 || name.path.some((part) => part === "")) {
17299
+ return null;
17300
+ }
17301
+ return { root, fields: name.path.slice(1) };
17302
+ }
17303
+ function referenceFromName(name) {
17304
+ return referenceOf(parseBoundaryName(name));
17305
+ }
17285
17306
  var SCHEME_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
17286
17307
  var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
17287
17308
  function pathAfterOrigin(text) {
@@ -17308,9 +17329,9 @@ var RestSemanticsSchema = external_exports.object({
17308
17329
  declaredResponses: external_exports.array(external_exports.number()).optional()
17309
17330
  });
17310
17331
  var OPENING_HOLE = /^\{([^{}]+)\}(.*)$/;
17311
- function variableOf(label) {
17312
- const parts = label.split(".");
17313
- return parts[parts.length - 1] ?? label;
17332
+ function baseUrlReference(semantics) {
17333
+ const label = OPENING_HOLE.exec(semantics.path ?? "")?.[1];
17334
+ return label === void 0 ? null : referenceFromName(patternHole(label));
17314
17335
  }
17315
17336
  function normalizePath(path4) {
17316
17337
  let normalized = path4.replace(/:([a-zA-Z_]\w*)/g, "{$1}");
@@ -17444,22 +17465,20 @@ var restSemantics = defineBoundarySemantics({
17444
17465
  * route parameter, and `/orders/{id}` means every id rather than a
17445
17466
  * variable somebody set.
17446
17467
  */
17447
- groundName(semantics, deployedAs) {
17448
- if (semantics.path === null) {
17468
+ groundName(semantics, deployment) {
17469
+ const reference = baseUrlReference(semantics);
17470
+ if (reference === null) {
17449
17471
  return null;
17450
17472
  }
17451
- const opening = OPENING_HOLE.exec(semantics.path);
17452
- if (opening === null) {
17453
- return null;
17454
- }
17455
- const [, label, rest] = opening;
17456
- const base = deployedAs(variableOf(label));
17473
+ const base = deployment.setTo(reference);
17457
17474
  if (base === null) {
17458
17475
  return null;
17459
17476
  }
17477
+ const rest = OPENING_HOLE.exec(semantics.path ?? "")?.[2] ?? "";
17460
17478
  const grounded = pathAfterOrigin(`${base}${rest}`);
17461
17479
  return { ...semantics, path: grounded === "" ? "/" : grounded };
17462
17480
  },
17481
+ nameReference: baseUrlReference,
17463
17482
  ruleBoundary: {
17464
17483
  // "METHOD /path": one leading token, then an absolute path.
17465
17484
  claims(raw) {
@@ -17535,6 +17554,9 @@ var StorageSemanticsSchema = external_exports.object({
17535
17554
  */
17536
17555
  accessPath: external_exports.string().nullable()
17537
17556
  });
17557
+ function containerReference(semantics) {
17558
+ return semantics.container === null ? null : referenceFromName(semantics.container);
17559
+ }
17538
17560
  var storageSemantics = defineBoundarySemantics({
17539
17561
  name: "storage",
17540
17562
  schema: StorageSemanticsSchema,
@@ -17551,7 +17573,21 @@ var storageSemantics = defineBoundarySemantics({
17551
17573
  exchangesHttpResponses: false,
17552
17574
  reportsUnpairedItself: false,
17553
17575
  identityKey: () => null,
17554
- displayLabel: storageLabel
17576
+ displayLabel: storageLabel,
17577
+ /**
17578
+ * A container the source states as a variable is whatever the
17579
+ * deployment sets that variable to. `{SUBSCRIBERS_TABLE}` in the
17580
+ * code and `prod-subscribers-v1` in the manifest are one table.
17581
+ */
17582
+ groundName(semantics, deployment) {
17583
+ const reference = containerReference(semantics);
17584
+ if (reference === null) {
17585
+ return null;
17586
+ }
17587
+ const name = deployment.setTo(reference);
17588
+ return name === null ? null : { ...semantics, container: name };
17589
+ },
17590
+ nameReference: containerReference
17555
17591
  }
17556
17592
  });
17557
17593
  function storageLabel(semantics) {
@@ -17566,6 +17602,9 @@ var UnitInvocationSemanticsSchema = DeployableUnitSchema.extend({
17566
17602
  name: external_exports.literal("unit-invocation"),
17567
17603
  instanceName: DeployableUnitSchema.shape.instanceName.nullable()
17568
17604
  });
17605
+ function calleeReference(semantics) {
17606
+ return semantics.instanceName === null ? null : referenceFromName(semantics.instanceName);
17607
+ }
17569
17608
  var unitInvocationSemantics = defineBoundarySemantics({
17570
17609
  name: "unit-invocation",
17571
17610
  schema: UnitInvocationSemanticsSchema,
@@ -17588,8 +17627,13 @@ var unitInvocationSemantics = defineBoundarySemantics({
17588
17627
  * being reported as a problem here.
17589
17628
  */
17590
17629
  reportsUnpairedItself: false,
17630
+ /**
17631
+ * A callee the source states only as a variable is not a name for
17632
+ * anything until the deployment fills it in, so it keys as nothing
17633
+ * rather than as a bucket that would agree with itself alone.
17634
+ */
17591
17635
  identityKey(semantics) {
17592
- if (semantics.instanceName === null) {
17636
+ if (semantics.instanceName === null || namesNothing(semantics.instanceName)) {
17593
17637
  return null;
17594
17638
  }
17595
17639
  return unitIdentityKey(
@@ -17605,7 +17649,23 @@ var unitInvocationSemantics = defineBoundarySemantics({
17605
17649
  semantics.deploymentTarget,
17606
17650
  semantics.instanceName
17607
17651
  );
17608
- }
17652
+ },
17653
+ /**
17654
+ * A call that reads its callee's name out of the environment
17655
+ * reaches whichever resource the template wires that variable to.
17656
+ * The logical id is the answer rather than the deployed name,
17657
+ * because the invoked unit's own summary is keyed by the logical
17658
+ * id and neither side ever writes the other's string.
17659
+ */
17660
+ groundName(semantics, deployment) {
17661
+ const reference = calleeReference(semantics);
17662
+ if (reference === null) {
17663
+ return null;
17664
+ }
17665
+ const logicalId = deployment.pointsAt(reference);
17666
+ return logicalId === null ? null : { ...semantics, instanceName: logicalId };
17667
+ },
17668
+ nameReference: calleeReference
17609
17669
  }
17610
17670
  });
17611
17671
  var SemanticsSchema = external_exports.discriminatedUnion("name", [
package/dist/index.js CHANGED
@@ -754,7 +754,7 @@ function passesParametersThrough(def, inner) {
754
754
  }
755
755
 
756
756
  // src/discovery.ts
757
- import { dispatchByType, restBinding } from "@suss/behavioral-ir";
757
+ import { dispatchByType as dispatchByType2, restBinding } from "@suss/behavioral-ir";
758
758
  import {
759
759
  absentReading,
760
760
  ambiguousReading,
@@ -927,9 +927,9 @@ var RESOLUTION_RULES = [
927
927
  [lit("invokes", v("r"), v("f")), lit("returnsValue", v("f"), v("ret"))],
928
928
  "call result"
929
929
  ),
930
- // Where a walk gets to, and whether it ran a call on the way. A value
931
- // step keeps whatever the rest of the walk was, and a result step
932
- // makes the whole walk one that ran a call.
930
+ // Where a walk gets to, and whether it ran a call on the way. The walk
931
+ // so far comes first, so demand stays on the value asked about; the
932
+ // README says what the other order cost.
933
933
  rule(
934
934
  "reaches",
935
935
  [v("x"), v("z"), v("kind")],
@@ -939,27 +939,27 @@ var RESOLUTION_RULES = [
939
939
  "reaches",
940
940
  [v("x"), v("z"), v("kind")],
941
941
  [
942
- lit("stepsTo", v("x"), v("y"), VALUE_STEP),
943
- lit("reaches", v("y"), v("z"), v("kind"))
942
+ lit("reaches", v("x"), v("y"), VALUE_STEP),
943
+ lit("stepsTo", v("y"), v("z"), v("kind"))
944
944
  ]
945
945
  ),
946
- // Two rules rather than one leaving the rest of the walk's kind free.
947
- // A free kind is a second question about the same relation, and a
946
+ // Two rules rather than one leaving the next step's kind free. A free
947
+ // kind is a second question about the same relation, and a
948
948
  // demand-driven run then derives both to answer either.
949
949
  rule(
950
950
  "reaches",
951
951
  [v("x"), v("z"), RESULT_STEP],
952
952
  [
953
- lit("stepsTo", v("x"), v("y"), RESULT_STEP),
954
- lit("reaches", v("y"), v("z"), VALUE_STEP)
953
+ lit("reaches", v("x"), v("y"), RESULT_STEP),
954
+ lit("stepsTo", v("y"), v("z"), VALUE_STEP)
955
955
  ]
956
956
  ),
957
957
  rule(
958
958
  "reaches",
959
959
  [v("x"), v("z"), RESULT_STEP],
960
960
  [
961
- lit("stepsTo", v("x"), v("y"), RESULT_STEP),
962
- lit("reaches", v("y"), v("z"), RESULT_STEP)
961
+ lit("reaches", v("x"), v("y"), RESULT_STEP),
962
+ lit("stepsTo", v("y"), v("z"), RESULT_STEP)
963
963
  ]
964
964
  ),
965
965
  // What a value comes down to: the walk that never ran a call, stopped
@@ -1305,29 +1305,14 @@ var RESOLUTION_QUESTIONS = [
1305
1305
  // here demands reaches or callsInto. The chains are closures with
1306
1306
  // no depth bound: an alias run of any length resolves.
1307
1307
  rule("callOriginChain", [v("x"), v("x")], [lit("wantedCallOrigin", v("x"))]),
1308
+ // The chain with at least one hop taken, which is what tells a
1309
+ // destructured binding apart from asking about a node directly. The
1310
+ // whole chain is the seed plus those hops.
1308
1311
  rule(
1309
1312
  "callOriginChain",
1310
1313
  [v("x"), v("z")],
1311
- [lit("callOriginChain", v("x"), v("y")), lit("binds", v("y"), v("z"))]
1312
- ),
1313
- rule(
1314
- "callOriginChain",
1315
- [v("x"), v("z")],
1316
- [
1317
- lit("callOriginChain", v("x"), v("y")),
1318
- lit("endsHolding", v("y"), v("z"))
1319
- ]
1320
- ),
1321
- rule(
1322
- "callOriginChain",
1323
- [v("x"), v("z")],
1324
- [
1325
- lit("callOriginChain", v("x"), v("y")),
1326
- lit("fallbackBranch", v("y"), v("z"))
1327
- ]
1314
+ [lit("callOriginChainStepped", v("x"), v("z"))]
1328
1315
  ),
1329
- // The chain with at least one hop taken, which is what tells a
1330
- // destructured binding apart from asking about a node directly.
1331
1316
  rule(
1332
1317
  "callOriginChainStepped",
1333
1318
  [v("x"), v("z")],
@@ -16954,7 +16939,7 @@ function date4(params) {
16954
16939
  // ../../../node_modules/zod/v4/classic/external.js
16955
16940
  config(en_default());
16956
16941
 
16957
- // ../../ir-core/dist/chunk-QHFMZPEG.js
16942
+ // ../../ir-core/dist/chunk-PPQWK62O.js
16958
16943
  function gqlIdentityKey(typeName, fieldName) {
16959
16944
  return `gql:${typeName}.${fieldName}`;
16960
16945
  }
@@ -17240,6 +17225,42 @@ var metricSemantics = defineBoundarySemantics({
17240
17225
  }
17241
17226
  }
17242
17227
  });
17228
+ var HOLE_SPLIT = /(\{[^}]*\})/;
17229
+ function isHole(piece) {
17230
+ return piece.startsWith("{") && piece.endsWith("}");
17231
+ }
17232
+ function parseBoundaryName(name) {
17233
+ const parts = name.split(HOLE_SPLIT).filter((piece) => piece !== "").map(
17234
+ (piece) => isHole(piece) ? { type: "hole", label: piece.slice(1, -1) } : { type: "text", text: piece }
17235
+ );
17236
+ const only = parts.length === 1 ? parts[0] : void 0;
17237
+ if (only !== void 0 && only.type === "hole") {
17238
+ return { type: "reference", path: only.label.split(".") };
17239
+ }
17240
+ if (parts.some((part) => part.type === "hole")) {
17241
+ return { type: "pattern", parts };
17242
+ }
17243
+ return { type: "literal", value: name };
17244
+ }
17245
+ function patternHole(label) {
17246
+ return `{${label}}`;
17247
+ }
17248
+ function namesNothing(name) {
17249
+ return parseBoundaryName(name).type === "reference";
17250
+ }
17251
+ function referenceOf(name) {
17252
+ if (name.type !== "reference") {
17253
+ return null;
17254
+ }
17255
+ const root = name.path[0];
17256
+ if (root === void 0 || name.path.some((part) => part === "")) {
17257
+ return null;
17258
+ }
17259
+ return { root, fields: name.path.slice(1) };
17260
+ }
17261
+ function referenceFromName(name) {
17262
+ return referenceOf(parseBoundaryName(name));
17263
+ }
17243
17264
  var SCHEME_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
17244
17265
  var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
17245
17266
  function pathAfterOrigin(text) {
@@ -17266,9 +17287,9 @@ var RestSemanticsSchema = external_exports.object({
17266
17287
  declaredResponses: external_exports.array(external_exports.number()).optional()
17267
17288
  });
17268
17289
  var OPENING_HOLE = /^\{([^{}]+)\}(.*)$/;
17269
- function variableOf(label) {
17270
- const parts = label.split(".");
17271
- return parts[parts.length - 1] ?? label;
17290
+ function baseUrlReference(semantics) {
17291
+ const label = OPENING_HOLE.exec(semantics.path ?? "")?.[1];
17292
+ return label === void 0 ? null : referenceFromName(patternHole(label));
17272
17293
  }
17273
17294
  function normalizePath(path4) {
17274
17295
  let normalized = path4.replace(/:([a-zA-Z_]\w*)/g, "{$1}");
@@ -17402,22 +17423,20 @@ var restSemantics = defineBoundarySemantics({
17402
17423
  * route parameter, and `/orders/{id}` means every id rather than a
17403
17424
  * variable somebody set.
17404
17425
  */
17405
- groundName(semantics, deployedAs) {
17406
- if (semantics.path === null) {
17426
+ groundName(semantics, deployment) {
17427
+ const reference = baseUrlReference(semantics);
17428
+ if (reference === null) {
17407
17429
  return null;
17408
17430
  }
17409
- const opening = OPENING_HOLE.exec(semantics.path);
17410
- if (opening === null) {
17411
- return null;
17412
- }
17413
- const [, label, rest] = opening;
17414
- const base = deployedAs(variableOf(label));
17431
+ const base = deployment.setTo(reference);
17415
17432
  if (base === null) {
17416
17433
  return null;
17417
17434
  }
17435
+ const rest = OPENING_HOLE.exec(semantics.path ?? "")?.[2] ?? "";
17418
17436
  const grounded = pathAfterOrigin(`${base}${rest}`);
17419
17437
  return { ...semantics, path: grounded === "" ? "/" : grounded };
17420
17438
  },
17439
+ nameReference: baseUrlReference,
17421
17440
  ruleBoundary: {
17422
17441
  // "METHOD /path": one leading token, then an absolute path.
17423
17442
  claims(raw) {
@@ -17493,6 +17512,9 @@ var StorageSemanticsSchema = external_exports.object({
17493
17512
  */
17494
17513
  accessPath: external_exports.string().nullable()
17495
17514
  });
17515
+ function containerReference(semantics) {
17516
+ return semantics.container === null ? null : referenceFromName(semantics.container);
17517
+ }
17496
17518
  var storageSemantics = defineBoundarySemantics({
17497
17519
  name: "storage",
17498
17520
  schema: StorageSemanticsSchema,
@@ -17509,7 +17531,21 @@ var storageSemantics = defineBoundarySemantics({
17509
17531
  exchangesHttpResponses: false,
17510
17532
  reportsUnpairedItself: false,
17511
17533
  identityKey: () => null,
17512
- displayLabel: storageLabel
17534
+ displayLabel: storageLabel,
17535
+ /**
17536
+ * A container the source states as a variable is whatever the
17537
+ * deployment sets that variable to. `{SUBSCRIBERS_TABLE}` in the
17538
+ * code and `prod-subscribers-v1` in the manifest are one table.
17539
+ */
17540
+ groundName(semantics, deployment) {
17541
+ const reference = containerReference(semantics);
17542
+ if (reference === null) {
17543
+ return null;
17544
+ }
17545
+ const name = deployment.setTo(reference);
17546
+ return name === null ? null : { ...semantics, container: name };
17547
+ },
17548
+ nameReference: containerReference
17513
17549
  }
17514
17550
  });
17515
17551
  function storageLabel(semantics) {
@@ -17524,6 +17560,9 @@ var UnitInvocationSemanticsSchema = DeployableUnitSchema.extend({
17524
17560
  name: external_exports.literal("unit-invocation"),
17525
17561
  instanceName: DeployableUnitSchema.shape.instanceName.nullable()
17526
17562
  });
17563
+ function calleeReference(semantics) {
17564
+ return semantics.instanceName === null ? null : referenceFromName(semantics.instanceName);
17565
+ }
17527
17566
  var unitInvocationSemantics = defineBoundarySemantics({
17528
17567
  name: "unit-invocation",
17529
17568
  schema: UnitInvocationSemanticsSchema,
@@ -17546,8 +17585,13 @@ var unitInvocationSemantics = defineBoundarySemantics({
17546
17585
  * being reported as a problem here.
17547
17586
  */
17548
17587
  reportsUnpairedItself: false,
17588
+ /**
17589
+ * A callee the source states only as a variable is not a name for
17590
+ * anything until the deployment fills it in, so it keys as nothing
17591
+ * rather than as a bucket that would agree with itself alone.
17592
+ */
17549
17593
  identityKey(semantics) {
17550
- if (semantics.instanceName === null) {
17594
+ if (semantics.instanceName === null || namesNothing(semantics.instanceName)) {
17551
17595
  return null;
17552
17596
  }
17553
17597
  return unitIdentityKey(
@@ -17563,7 +17607,23 @@ var unitInvocationSemantics = defineBoundarySemantics({
17563
17607
  semantics.deploymentTarget,
17564
17608
  semantics.instanceName
17565
17609
  );
17566
- }
17610
+ },
17611
+ /**
17612
+ * A call that reads its callee's name out of the environment
17613
+ * reaches whichever resource the template wires that variable to.
17614
+ * The logical id is the answer rather than the deployed name,
17615
+ * because the invoked unit's own summary is keyed by the logical
17616
+ * id and neither side ever writes the other's string.
17617
+ */
17618
+ groundName(semantics, deployment) {
17619
+ const reference = calleeReference(semantics);
17620
+ if (reference === null) {
17621
+ return null;
17622
+ }
17623
+ const logicalId = deployment.pointsAt(reference);
17624
+ return logicalId === null ? null : { ...semantics, instanceName: logicalId };
17625
+ },
17626
+ nameReference: calleeReference
17567
17627
  }
17568
17628
  });
17569
17629
  var SemanticsSchema = external_exports.discriminatedUnion("name", [
@@ -18268,7 +18328,7 @@ function unitsFor(pattern, pack, decoratorModule, classification, definition, mo
18268
18328
  );
18269
18329
  }
18270
18330
  };
18271
- return dispatchByType(table, pattern);
18331
+ return dispatchByType2(table, pattern);
18272
18332
  }
18273
18333
  function readPathArgument(classification) {
18274
18334
  const first = classification.args[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/adapter-python",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
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,10 +47,10 @@
47
47
  "typecheck": "tsc --noEmit"
48
48
  },
49
49
  "dependencies": {
50
- "@suss/behavioral-ir": "0.21.0",
51
- "@suss/datalog": "0.21.0",
52
- "@suss/extractor": "0.21.0",
53
- "@suss/sql": "0.21.0",
50
+ "@suss/behavioral-ir": "0.21.1",
51
+ "@suss/datalog": "0.21.1",
52
+ "@suss/extractor": "0.21.1",
53
+ "@suss/sql": "0.21.1",
54
54
  "web-tree-sitter": "^0.26.11"
55
55
  },
56
56
  "devDependencies": {