@suss/packs 0.33.1 → 0.34.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 (64) hide show
  1. package/README.md +10 -11
  2. package/dist/activerecord.d.ts +7 -0
  3. package/dist/activerecord.js +53 -5
  4. package/dist/aiohttp.js +20 -9
  5. package/dist/apollo-client.js +26 -39
  6. package/dist/apollo.js +12 -20
  7. package/dist/aws-dynamodb.js +4 -4
  8. package/dist/aws-eventbridge.js +3 -3
  9. package/dist/aws-lambda.js +31 -54
  10. package/dist/aws-s3.js +1 -1
  11. package/dist/aws-secrets-manager.js +1 -1
  12. package/dist/aws-sns.js +2 -2
  13. package/dist/aws-sqs.js +20 -11
  14. package/dist/aws-ssm.js +1 -1
  15. package/dist/axios.js +36 -37
  16. package/dist/bigquery-python.js +3 -3
  17. package/dist/bigquery.js +1 -1
  18. package/dist/{chunk-NYWZHQBJ.js → chunk-GK4BILHB.js} +8 -9
  19. package/dist/cloudflare-workers.js +26 -35
  20. package/dist/drizzle.js +15 -20
  21. package/dist/express.js +3 -6
  22. package/dist/fabrication.d.ts +1 -0
  23. package/dist/fabrication.js +36 -0
  24. package/dist/factory-bot.d.ts +1 -0
  25. package/dist/factory-bot.js +36 -0
  26. package/dist/faraday.js +8 -6
  27. package/dist/fastapi.js +123 -5
  28. package/dist/fastify.js +10 -14
  29. package/dist/fetch.js +12 -6
  30. package/dist/flask-restx.js +19 -12
  31. package/dist/gcs.js +1 -1
  32. package/dist/graphql-ruby.js +20 -16
  33. package/dist/hono.js +17 -27
  34. package/dist/httpx.js +8 -6
  35. package/dist/minitest.d.ts +1 -0
  36. package/dist/minitest.js +59 -0
  37. package/dist/mongoose.js +7 -7
  38. package/dist/nestjs-graphql.js +14 -25
  39. package/dist/nestjs-microservices.js +9 -10
  40. package/dist/nestjs-rest.js +193 -23
  41. package/dist/net-http.js +9 -7
  42. package/dist/nextjs.js +16 -17
  43. package/dist/node.js +139 -23
  44. package/dist/package-exports.js +1 -1
  45. package/dist/pg.js +3 -2
  46. package/dist/prisma.js +375 -56
  47. package/dist/pytest.d.ts +1 -0
  48. package/dist/pytest.js +81 -0
  49. package/dist/rails.js +1792 -132
  50. package/dist/react-query.js +1 -1
  51. package/dist/react-router.js +21 -48
  52. package/dist/react.js +14 -5
  53. package/dist/redis.js +1 -1
  54. package/dist/requests.js +27 -19
  55. package/dist/rspec.d.ts +1 -0
  56. package/dist/rspec.js +135 -0
  57. package/dist/sqlalchemy.js +1 -1
  58. package/dist/sqlmodel.js +7 -8
  59. package/dist/ts-rest.js +6 -8
  60. package/dist/typeorm.d.ts +1 -0
  61. package/dist/typeorm.js +291 -0
  62. package/dist/vitest.d.ts +1 -0
  63. package/dist/vitest.js +64 -0
  64. package/package.json +47 -11
package/dist/node.js CHANGED
@@ -25,12 +25,17 @@ import {
25
25
  } from "@suss/adapter-typescript";
26
26
  import { Node } from "ts-morph";
27
27
  import {
28
- Node as Node2
28
+ Node as Node2,
29
+ SyntaxKind as SyntaxKind3
29
30
  } from "ts-morph";
31
+ import { numberValueOf } from "@suss/adapter-typescript";
30
32
  import {
31
33
  Node as Node3
32
34
  } from "ts-morph";
33
35
  import { functionCallBinding } from "@suss/behavioral-ir";
36
+ import { Node as Node4 } from "ts-morph";
37
+ import { writtenPayloadOf } from "@suss/adapter-typescript";
38
+ import { ioBinding } from "@suss/behavioral-ir";
34
39
  var RECOGNITION = "@suss/runtime-node";
35
40
  function configBinding(where) {
36
41
  return runtimeConfigBinding({ recognition: RECOGNITION, ...where });
@@ -396,9 +401,9 @@ function bindingRead(element) {
396
401
  return [
397
402
  {
398
403
  name,
399
- // A binding default supplies the value the variable is missing,
400
- // which is what `??` does for the other two spellings.
401
- defaulted: element.getInitializer() !== void 0,
404
+ // A binding default covers a missing variable the same way `??`
405
+ // does after a dotted read.
406
+ defaulted: element.getInitializer() !== void 0 || isDefaultedAt(element),
402
407
  node: element
403
408
  }
404
409
  ];
@@ -464,8 +469,8 @@ function readsThroughHelperCall(call, resolution) {
464
469
  defaulted: atSites || wrapped,
465
470
  node: call
466
471
  })),
467
- // A config module parses its schema once and every handler calls
468
- // the function around it, so the call reports what the parse reads.
472
+ // A config module often parses its schema inside a function that
473
+ // every handler calls, so each call reports the keys that parse reads.
469
474
  ...anchoredAt(schemaEnvReadsInside(callee, resolution), call)
470
475
  ];
471
476
  }
@@ -612,10 +617,14 @@ var OPAQUE_PROPERTY_NAMES = /* @__PURE__ */ new Set([
612
617
  "execArgv"
613
618
  ]);
614
619
  function makeProcessSurfaceRecognizer(where) {
615
- return (access, _ctx) => {
620
+ return (access, ctx) => {
616
621
  const node = access;
617
622
  if (Node2.isPropertyAccessExpression(node)) {
618
- return recognizeProperty(node, where);
623
+ return recognizeProperty(
624
+ node,
625
+ where,
626
+ ctx?.resolution
627
+ );
619
628
  }
620
629
  if (Node2.isElementAccessExpression(node)) {
621
630
  return recognizeElementAccess(node, where);
@@ -623,7 +632,7 @@ function makeProcessSurfaceRecognizer(where) {
623
632
  return null;
624
633
  };
625
634
  }
626
- function recognizeProperty(node, where) {
635
+ function recognizeProperty(node, where, resolution) {
627
636
  if (isProcessEnvVarRead(node)) {
628
637
  return null;
629
638
  }
@@ -635,8 +644,25 @@ function recognizeProperty(node, where) {
635
644
  if (isProcessIdentifier(subject) && OPAQUE_PROPERTY_NAMES.has(name)) {
636
645
  return [opaqueRuntimeRead(node.getText())];
637
646
  }
647
+ if (isProcessIdentifier(subject) && name === "exitCode") {
648
+ return exitCodeSet(node, resolution);
649
+ }
638
650
  return null;
639
651
  }
652
+ function exitCodeSet(node, resolution) {
653
+ const assignment = node.getParent();
654
+ if (!Node2.isBinaryExpression(assignment) || assignment.getLeft() !== node || assignment.getOperatorToken().getKind() !== SyntaxKind3.EqualsToken) {
655
+ return null;
656
+ }
657
+ const written = assignment.getRight();
658
+ return [
659
+ {
660
+ type: "stateChange",
661
+ variable: node.getText(),
662
+ newValue: numberValueOf(written, resolution) ?? written.getText()
663
+ }
664
+ ];
665
+ }
640
666
  function recognizeElementAccess(node, where) {
641
667
  const subject = node.getExpression();
642
668
  if (!Node2.isPropertyAccessExpression(subject)) {
@@ -767,9 +793,8 @@ var schedulingRecognizer = (call, _ctx) => {
767
793
  };
768
794
  var SCHEDULED_CALLBACK_INPUT = {
769
795
  type: "positionalParams",
770
- // Timer callbacks receive whatever `...args` were passed at the
771
- // schedule site. v0 doesn't track these positions individually,
772
- // packs that need argument-shape modeling can layer it on top.
796
+ // A timer callback receives the extra arguments passed to the
797
+ // scheduling call. Those are not mapped to its parameters yet.
773
798
  params: []
774
799
  };
775
800
  function nodeSchedulingSubUnits(parent, _ctx) {
@@ -797,8 +822,8 @@ function nodeSchedulingSubUnits(parent, _ctx) {
797
822
  out.push({
798
823
  func: arg,
799
824
  kind: "scheduled-callback",
800
- // Naming convention: `<parent>.<via>#<index>`. Multiple
801
- // setImmediate calls in the same parent get distinct indices.
825
+ // The index keeps two calls to the same primitive in one parent
826
+ // apart.
802
827
  name: `${parent.name}.${primitive.via}#${idx}`,
803
828
  inputMapping: SCHEDULED_CALLBACK_INPUT,
804
829
  metadata: {
@@ -810,11 +835,84 @@ function nodeSchedulingSubUnits(parent, _ctx) {
810
835
  });
811
836
  return out;
812
837
  }
813
- var PACK_VERSION = "0.2.0";
838
+ var RECOGNITION2 = "@suss/runtime-node";
839
+ var PROCESS_STREAMS = ["process.stdout", "process.stderr"];
840
+ var CONSOLE_STREAMS = {
841
+ log: "stdout",
842
+ info: "stdout",
843
+ debug: "stdout",
844
+ table: "stdout",
845
+ dir: "stdout",
846
+ warn: "stderr",
847
+ error: "stderr",
848
+ trace: "stderr"
849
+ };
850
+ var CONSOLE_TYPES = ["Console"];
851
+ var STREAM_TYPES = ["NodeJS.WriteStream", "NodeJS.WritableStream"];
852
+ var streamWriteRecognizer = (call, ctx) => {
853
+ const written = call;
854
+ if (!Node4.isCallExpression(written)) {
855
+ return null;
856
+ }
857
+ const callee = written.getExpression();
858
+ if (!Node4.isPropertyAccessExpression(callee)) {
859
+ return null;
860
+ }
861
+ const resolution = ctx?.resolution;
862
+ const target = targetOf(callee.getExpression(), callee.getName(), resolution);
863
+ if (target === void 0) {
864
+ return null;
865
+ }
866
+ const payload = writtenPayloadOf(written.getArguments());
867
+ const effect = {
868
+ type: "interaction",
869
+ binding: ioBinding({ recognition: RECOGNITION2, target }),
870
+ callee: callee.getText(),
871
+ groupId: callSiteId(written),
872
+ interaction: {
873
+ class: "stream-write",
874
+ payload: payload.shape,
875
+ serialized: payload.serialized
876
+ }
877
+ };
878
+ return [effect];
879
+ };
880
+ function targetOf(receiver, method, resolution) {
881
+ const consoleStream = Object.hasOwn(CONSOLE_STREAMS, method) ? CONSOLE_STREAMS[method] : void 0;
882
+ if (consoleStream !== void 0) {
883
+ if (Node4.isIdentifier(receiver) && receiver.getText() === "console") {
884
+ return consoleStream;
885
+ }
886
+ return viaParameter(receiver, CONSOLE_TYPES, resolution);
887
+ }
888
+ if (method !== "write") {
889
+ return void 0;
890
+ }
891
+ if (Node4.isPropertyAccessExpression(receiver)) {
892
+ const spelled = receiver.getText();
893
+ return PROCESS_STREAMS.includes(spelled) ? streamName(spelled) : void 0;
894
+ }
895
+ const path = viaParameter(receiver, STREAM_TYPES, resolution);
896
+ return path === null || path === void 0 ? path : streamName(path);
897
+ }
898
+ function viaParameter(receiver, annotations, resolution) {
899
+ if (resolution === void 0 || !Node4.isIdentifier(receiver)) {
900
+ return void 0;
901
+ }
902
+ return resolution.streamPathOf(receiver, annotations);
903
+ }
904
+ function streamName(path) {
905
+ return path.slice(path.lastIndexOf(".") + 1);
906
+ }
907
+ function callSiteId(call) {
908
+ const { line, column } = call.getSourceFile().getLineAndColumnAtPos(call.getStart());
909
+ return `${line}:${column}`;
910
+ }
911
+ var PACK_VERSION = "0.3.0";
814
912
  var optionsSchema = z.object({
815
913
  /**
816
- * Deployment context for runtime-config reads (process.env.X,
817
- * process.argv). Left off the binding unless a run sets it.
914
+ * The kind of deployment that runtime-config reads such as
915
+ * `process.env.X` belong to. Left off the binding unless a run sets it.
818
916
  */
819
917
  deploymentTarget: z.enum(["lambda", "ecs-task", "container", "k8s-deployment"]).optional(),
820
918
  /**
@@ -823,6 +921,22 @@ var optionsSchema = z.object({
823
921
  */
824
922
  instanceName: z.string().optional()
825
923
  }).strict();
924
+ var PROCESS_EXIT = {
925
+ kind: "exit",
926
+ inEveryUnit: true,
927
+ match: { type: "functionCall", functionName: "process.exit" },
928
+ extraction: {
929
+ statusCode: { from: "argument", position: 0 },
930
+ defaultStatusCode: 0
931
+ }
932
+ };
933
+ var PARSE_ARGS = ["node:util", "util"].map((module) => ({
934
+ module,
935
+ name: "parseArgs",
936
+ argument: 0,
937
+ argsKey: "args",
938
+ optionsKey: "options"
939
+ }));
826
940
  function nodeRuntimePack(options = {}) {
827
941
  const configOptions = {
828
942
  ...options.deploymentTarget !== void 0 ? { deploymentTarget: options.deploymentTarget } : {},
@@ -836,14 +950,16 @@ function nodeRuntimePack(options = {}) {
836
950
  protocol: "in-process",
837
951
  languages: ["typescript", "javascript"],
838
952
  discovery: [],
839
- terminals: [],
953
+ terminals: [PROCESS_EXIT],
954
+ exitCodeWrites: ["process.exitCode"],
955
+ argumentParsers: PARSE_ARGS,
840
956
  inputMapping: { type: "positionalParams", params: [] },
841
- invocationRecognizers: [schedulingRecognizer],
957
+ invocationRecognizers: [schedulingRecognizer, streamWriteRecognizer],
842
958
  environmentObjects: ["process.env"],
959
+ streamObjects: PROCESS_STREAMS,
843
960
  accessRecognizers: [
844
- // `envRecognizer` owns `process.env.X`; `processRecognizer`
845
- // owns the rest of the process surface and skips env reads,
846
- // together they partition `process.*` without duplication.
961
+ // envRecognizer handles `process.env.X` and processRecognizer skips
962
+ // it, so each `process.*` read produces one effect.
847
963
  envRecognizer,
848
964
  processRecognizer,
849
965
  importMetaRecognizer,
@@ -857,7 +973,7 @@ var declares = {
857
973
  package: "@suss/runtime-node",
858
974
  dependencies: [],
859
975
  shippedWith: "typescript",
860
- reads: "Node.js runtime primitives, scheduling, the `process` surface (incl. `process.env.X` config-read interactions and the keys of a schema parsed against `process.env`), module-loading globals as metadata-read interactions, emitted as interaction effects."
976
+ reads: "Node.js runtime primitives, scheduling and the `process` surface, each recorded as an interaction effect. A `process.env.X` read, or a key of a schema parsed against `process.env`, becomes a config-read interaction. A module-loading global becomes a metadata-read interaction. A `console` call or a write to `process.stdout` or `process.stderr` becomes a stream-write interaction on the stream it goes to."
861
977
  };
862
978
  var index_default = nodeRuntimePack;
863
979
  export {
@@ -33,7 +33,7 @@ var declares = {
33
33
  kind: "framework",
34
34
  package: "@suss/framework-package-exports",
35
35
  dependencies: [],
36
- reads: "The boundary between packages in one workspace: public exports on the provider side, imports of them on the consumer side. Reads the workspace manifest, so it needs no per-project package list."
36
+ reads: "The boundary between packages in one workspace: public exports on the provider side, and imports of them on the consumer side. The pack reads the workspace manifest, so nobody has to list the packages for each project."
37
37
  };
38
38
  var index_default = packageExportsFramework;
39
39
  export {
package/dist/pg.js CHANGED
@@ -2,7 +2,8 @@
2
2
  import { declaredBy, pack, sqlStatements } from "@suss/recognize";
3
3
  var CLIENT_MODULES = ["pg", "@types/pg"];
4
4
  var STATEMENT = {
5
- statement: [{ at: 0 }, { at: 0, property: ["text"] }]
5
+ statement: [{ at: 0 }, { at: 0, property: ["text"] }],
6
+ parameters: [{ at: 1 }, { at: 0, property: ["values"] }]
6
7
  };
7
8
  var QUERIES = sqlStatements({
8
9
  system: "postgresql",
@@ -19,7 +20,7 @@ var declares = {
19
20
  kind: "effects",
20
21
  package: "@suss/framework-pg",
21
22
  dependencies: [{ ecosystem: "npm", name: "pg" }],
22
- reads: "node-postgres queries, emits storage-access interactions with the tables each statement touches."
23
+ reads: "node-postgres queries. Each one becomes a storage-access interaction on the tables its statement touches."
23
24
  };
24
25
  var index_default = pgFramework;
25
26
  export {