@suss/packs 0.31.2 → 0.33.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/node.js CHANGED
@@ -1,34 +1,302 @@
1
1
  // ../runtime/node/dist/index.js
2
2
  import { z } from "zod";
3
3
  import {
4
- Node as N,
5
- SyntaxKind
4
+ Node as N2,
5
+ SyntaxKind as SyntaxKind2
6
6
  } from "ts-morph";
7
7
  import {
8
+ declarationsBehind,
8
9
  findEnclosingFunction,
9
10
  functionTargetOf,
10
11
  isDefaultedAt,
11
12
  stringValueOf,
12
- symbolBehind
13
+ symbolBehind,
14
+ toFunctionRoot
13
15
  } from "@suss/adapter-typescript";
14
16
  import { runtimeConfigBinding } from "@suss/behavioral-ir";
17
+ import { Node as N, SyntaxKind } from "ts-morph";
18
+ import {
19
+ objectLiteralOf,
20
+ propertiesOf,
21
+ propertyNameOf,
22
+ propertyOf,
23
+ propertyValueOf,
24
+ writtenNodeOf
25
+ } from "@suss/adapter-typescript";
15
26
  import { Node } from "ts-morph";
16
- import { runtimeConfigBinding as runtimeConfigBinding2 } from "@suss/behavioral-ir";
17
27
  import {
18
28
  Node as Node2
19
29
  } from "ts-morph";
20
- import { runtimeConfigBinding as runtimeConfigBinding3 } from "@suss/behavioral-ir";
21
30
  import {
22
31
  Node as Node3
23
32
  } from "ts-morph";
24
33
  import { functionCallBinding } from "@suss/behavioral-ir";
34
+ var RECOGNITION = "@suss/runtime-node";
35
+ function configBinding(where) {
36
+ return runtimeConfigBinding({ recognition: RECOGNITION, ...where });
37
+ }
38
+ function opaqueRuntimeRead(callee) {
39
+ return {
40
+ type: "interaction",
41
+ binding: configBinding({}),
42
+ callee,
43
+ interaction: { class: "metadata-read", name: callee }
44
+ };
45
+ }
46
+ var SCHEMA_READERS = [
47
+ // cleanEnv(process.env, { PORT: port({ default: 8080 }), DB_NAME: str() })
48
+ {
49
+ modules: ["envalid"],
50
+ calls: ["cleanEnv"],
51
+ environment: { in: "argument", at: 0 },
52
+ schema: { in: "argument", at: 1 }
53
+ },
54
+ // parseEnv(process.env, { PORT: z.number().default(8080) })
55
+ {
56
+ modules: ["znv"],
57
+ calls: ["parseEnv"],
58
+ environment: { in: "argument", at: 0 },
59
+ schema: { in: "argument", at: 1 }
60
+ },
61
+ // createEnv({ server: { DB_NAME: z.string() }, runtimeEnv: process.env })
62
+ {
63
+ modules: ["@t3-oss/env-core", "@t3-oss/env-nextjs"],
64
+ calls: ["createEnv"],
65
+ environment: { in: "property", at: 0, named: "runtimeEnv" },
66
+ schema: { in: "properties", at: 0, named: ["server", "client", "shared"] }
67
+ },
68
+ // v.parse(v.object({ DB_NAME: v.string() }), process.env)
69
+ {
70
+ modules: ["valibot"],
71
+ calls: ["parse", "safeParse", "parseAsync", "safeParseAsync"],
72
+ environment: { in: "argument", at: 1 },
73
+ schema: { in: "builtAt", at: 0, builders: ["object"] }
74
+ },
75
+ // Env.parse(process.env), where Env came from z.object({ ... })
76
+ {
77
+ modules: ["zod"],
78
+ calls: ["parse", "safeParse", "parseAsync", "safeParseAsync"],
79
+ onSchema: true,
80
+ environment: { in: "argument", at: 0 },
81
+ schema: { in: "builtAtReceiver", builders: ["object"] }
82
+ }
83
+ ];
84
+ var PARSE_CALL_NAMES = new Set(
85
+ SCHEMA_READERS.flatMap((reader) => [...reader.calls])
86
+ );
87
+ var MODULES_MENTIONED = /* @__PURE__ */ new WeakMap();
88
+ function writtenCalleeName(callee) {
89
+ if (N.isIdentifier(callee)) {
90
+ return callee.getText();
91
+ }
92
+ return N.isPropertyAccessExpression(callee) ? callee.getName() : null;
93
+ }
94
+ function modulesMentionedIn(sourceFile) {
95
+ const remembered = MODULES_MENTIONED.get(sourceFile);
96
+ if (remembered !== void 0) {
97
+ return remembered;
98
+ }
99
+ const text = sourceFile.getFullText();
100
+ const found = new Set(
101
+ SCHEMA_READERS.flatMap((reader) => [...reader.modules]).filter(
102
+ (module) => text.includes(module)
103
+ )
104
+ );
105
+ MODULES_MENTIONED.set(sourceFile, found);
106
+ return found;
107
+ }
108
+ function readerCouldFire(call, reader, written) {
109
+ if (!reader.calls.includes(written)) {
110
+ return false;
111
+ }
112
+ if (reader.onSchema === true) {
113
+ return true;
114
+ }
115
+ const mentioned = modulesMentionedIn(call.getSourceFile());
116
+ return reader.modules.some((module) => mentioned.has(module));
117
+ }
118
+ function schemaEnvReads(call, resolution) {
119
+ if (resolution === void 0) {
120
+ return [];
121
+ }
122
+ const written = writtenCalleeName(call.getExpression());
123
+ if (written === null || !PARSE_CALL_NAMES.has(written)) {
124
+ return [];
125
+ }
126
+ for (const reader of SCHEMA_READERS) {
127
+ if (!readerCouldFire(call, reader, written) || !callMatches(call, reader, resolution)) {
128
+ continue;
129
+ }
130
+ const environment = environmentArgument(call, reader, resolution);
131
+ if (environment === null || !resolution.isEnvironmentValue(environment)) {
132
+ continue;
133
+ }
134
+ const reads = readsFromSchema(call, reader, resolution);
135
+ if (reads.length > 0) {
136
+ return reads;
137
+ }
138
+ }
139
+ return [];
140
+ }
141
+ function callMatches(call, reader, resolution) {
142
+ const callee = call.getExpression();
143
+ if (reader.onSchema === true) {
144
+ return N.isPropertyAccessExpression(callee) && reader.calls.includes(callee.getName());
145
+ }
146
+ const name = moduleCallName(callee, reader.modules, resolution);
147
+ return name !== null && reader.calls.includes(name);
148
+ }
149
+ function moduleCallName(callee, modules, resolution) {
150
+ if (N.isIdentifier(callee)) {
151
+ return resolution.importedNamesOf(callee, [...modules])[0] ?? null;
152
+ }
153
+ if (!N.isPropertyAccessExpression(callee)) {
154
+ return null;
155
+ }
156
+ const fromPackage = resolution.importedNamesOf(callee.getExpression(), [
157
+ ...modules
158
+ ]);
159
+ return fromPackage.length > 0 ? callee.getName() : null;
160
+ }
161
+ function environmentArgument(call, reader, resolution) {
162
+ const at = call.getArguments()[reader.environment.at];
163
+ if (at === void 0) {
164
+ return null;
165
+ }
166
+ if (reader.environment.in === "argument") {
167
+ return at;
168
+ }
169
+ return namedValue(at, reader.environment.named, resolution);
170
+ }
171
+ function readsFromSchema(call, reader, resolution) {
172
+ return schemaLiterals(call, reader, resolution).flatMap(
173
+ (literal) => keysOf(literal, resolution)
174
+ );
175
+ }
176
+ function schemaLiterals(call, reader, resolution) {
177
+ const { schema } = reader;
178
+ if (schema.in === "builtAtReceiver") {
179
+ const callee = call.getExpression();
180
+ if (!N.isPropertyAccessExpression(callee)) {
181
+ return [];
182
+ }
183
+ return builtSchema(
184
+ callee.getExpression(),
185
+ reader.modules,
186
+ schema.builders,
187
+ resolution
188
+ );
189
+ }
190
+ const at = call.getArguments()[schema.at];
191
+ if (at === void 0) {
192
+ return [];
193
+ }
194
+ if (schema.in === "argument") {
195
+ return [at];
196
+ }
197
+ if (schema.in === "builtAt") {
198
+ return builtSchema(at, reader.modules, schema.builders, resolution);
199
+ }
200
+ return schema.named.map((name) => namedValue(at, name, resolution)).filter((found) => found !== null);
201
+ }
202
+ function namedValue(value, named, resolution) {
203
+ const object = objectLiteralOf(value, resolution);
204
+ return object === null ? null : propertyOf(object, named, resolution);
205
+ }
206
+ function builtSchema(value, modules, builders, resolution) {
207
+ const built = chainRoot(writtenCallOf(value, resolution));
208
+ if (built === null) {
209
+ return [];
210
+ }
211
+ const name = moduleCallName(built.getExpression(), modules, resolution);
212
+ if (name === null || !builders.includes(name)) {
213
+ return [];
214
+ }
215
+ const literal = built.getArguments()[0];
216
+ return literal === void 0 ? [] : [literal];
217
+ }
218
+ function writtenCallOf(value, resolution) {
219
+ const written = writtenNodeOf(value, resolution);
220
+ return written !== null && N.isCallExpression(written) ? written : null;
221
+ }
222
+ function chainRoot(call) {
223
+ let at = call;
224
+ while (at !== null) {
225
+ const callee = at.getExpression();
226
+ if (!N.isPropertyAccessExpression(callee)) {
227
+ return at;
228
+ }
229
+ const receiver = callee.getExpression();
230
+ if (!N.isCallExpression(receiver)) {
231
+ return at;
232
+ }
233
+ at = receiver;
234
+ }
235
+ return null;
236
+ }
237
+ function keysOf(literal, resolution) {
238
+ const object = objectLiteralOf(literal, resolution);
239
+ if (object === null) {
240
+ return [];
241
+ }
242
+ const reads = [];
243
+ for (const property of propertiesOf(object, resolution)) {
244
+ const name = propertyNameOf(property);
245
+ if (name === null || name.length === 0) {
246
+ continue;
247
+ }
248
+ const value = propertyValueOf(property);
249
+ reads.push({ name, defaulted: value !== null && suppliesValue(value) });
250
+ }
251
+ return reads;
252
+ }
253
+ var DEFAULTING_CALLS = /* @__PURE__ */ new Set([
254
+ "default",
255
+ "optional",
256
+ "nullish",
257
+ "catch",
258
+ "or"
259
+ ]);
260
+ var DEFAULTING_OPTIONS = /* @__PURE__ */ new Set(["default", "devDefault"]);
261
+ function suppliesValue(value) {
262
+ let found = defaults(value);
263
+ value.forEachDescendant((node, traversal) => {
264
+ if (!defaults(node)) {
265
+ return;
266
+ }
267
+ found = true;
268
+ traversal.stop();
269
+ });
270
+ return found;
271
+ }
272
+ function defaults(node) {
273
+ if (N.isCallExpression(node)) {
274
+ const written = writtenCalleeName(node.getExpression());
275
+ return written !== null && DEFAULTING_CALLS.has(written);
276
+ }
277
+ if (!N.isPropertyAssignment(node)) {
278
+ return false;
279
+ }
280
+ const option = propertyNameOf(node);
281
+ return option !== null && DEFAULTING_OPTIONS.has(option);
282
+ }
283
+ var SCHEMA_READS_INSIDE = /* @__PURE__ */ new WeakMap();
284
+ function schemaEnvReadsInside(callee, resolution) {
285
+ const remembered = SCHEMA_READS_INSIDE.get(callee);
286
+ if (remembered !== void 0) {
287
+ return remembered;
288
+ }
289
+ const found = callee.getDescendantsOfKind(SyntaxKind.CallExpression).flatMap((inner) => schemaEnvReads(inner, resolution));
290
+ SCHEMA_READS_INSIDE.set(callee, found);
291
+ return found;
292
+ }
25
293
  var readName = (name) => `process.env.${name}`;
26
294
  function isProcessEnv(node) {
27
- if (!N.isPropertyAccessExpression(node) || node.getName() !== "env") {
295
+ if (!N2.isPropertyAccessExpression(node) || node.getName() !== "env") {
28
296
  return false;
29
297
  }
30
298
  const root = node.getExpression();
31
- return N.isIdentifier(root) && root.getText() === "process";
299
+ return N2.isIdentifier(root) && root.getText() === "process";
32
300
  }
33
301
  function dottedRead(node) {
34
302
  if (!isProcessEnv(node.getExpression())) {
@@ -41,14 +309,14 @@ function bracketRead(access, resolution) {
41
309
  if (argument === void 0) {
42
310
  return [];
43
311
  }
44
- if (N.isStringLiteral(argument) || N.isNoSubstitutionTemplateLiteral(argument)) {
312
+ if (N2.isStringLiteral(argument) || N2.isNoSubstitutionTemplateLiteral(argument)) {
45
313
  const name = argument.getLiteralValue();
46
314
  if (name.length === 0) {
47
315
  return [];
48
316
  }
49
317
  return [{ name, defaulted: isDefaultedAt(access), node: access }];
50
318
  }
51
- if (N.isIdentifier(argument)) {
319
+ if (N2.isIdentifier(argument)) {
52
320
  return readsThroughParameter(access, argument, resolution);
53
321
  }
54
322
  return [];
@@ -100,7 +368,7 @@ function callerLiteralReads(access, index, resolution) {
100
368
  return reads;
101
369
  }
102
370
  function forwardedParameter(passed, call) {
103
- if (!N.isIdentifier(passed)) {
371
+ if (!N2.isIdentifier(passed)) {
104
372
  return null;
105
373
  }
106
374
  const caller = findEnclosingFunction(call);
@@ -108,7 +376,7 @@ function forwardedParameter(passed, call) {
108
376
  return null;
109
377
  }
110
378
  const behind = symbolBehind(passed)?.getValueDeclaration();
111
- if (behind === void 0 || !N.isParameterDeclaration(behind)) {
379
+ if (behind === void 0 || !N2.isParameterDeclaration(behind)) {
112
380
  return null;
113
381
  }
114
382
  return behind.getParent() === caller ? behind : null;
@@ -118,10 +386,10 @@ function bindingRead(element) {
118
386
  return [];
119
387
  }
120
388
  const named = element.getPropertyNameNode() ?? element.getNameNode();
121
- if (!(N.isIdentifier(named) || N.isStringLiteral(named))) {
389
+ if (!(N2.isIdentifier(named) || N2.isStringLiteral(named))) {
122
390
  return [];
123
391
  }
124
- const name = N.isIdentifier(named) ? named.getText() : named.getLiteralValue();
392
+ const name = N2.isIdentifier(named) ? named.getText() : named.getLiteralValue();
125
393
  if (name.length === 0) {
126
394
  return [];
127
395
  }
@@ -137,131 +405,134 @@ function bindingRead(element) {
137
405
  }
138
406
  function destructuredReads(declaration) {
139
407
  const pattern = declaration.getNameNode();
140
- if (!N.isObjectBindingPattern(pattern)) {
408
+ if (!N2.isObjectBindingPattern(pattern)) {
141
409
  return [];
142
410
  }
143
411
  return pattern.getElements().flatMap(bindingRead);
144
412
  }
145
413
  function readsThroughEnvObject(envNode, resolution) {
146
414
  const parent = envNode.getParent();
147
- if (N.isElementAccessExpression(parent)) {
415
+ if (N2.isElementAccessExpression(parent)) {
148
416
  return bracketRead(parent, resolution);
149
417
  }
150
- if (N.isVariableDeclaration(parent)) {
418
+ if (N2.isVariableDeclaration(parent)) {
151
419
  return destructuredReads(parent);
152
420
  }
153
421
  return [];
154
422
  }
155
423
  function envReadsAt(node, resolution) {
156
- if (N.isCallExpression(node)) {
157
- return readsThroughHelperCall(node, resolution);
424
+ if (N2.isCallExpression(node)) {
425
+ const parsed = anchoredAt(schemaEnvReads(node, resolution), node);
426
+ return parsed.length > 0 ? parsed : readsThroughHelperCall(node, resolution);
158
427
  }
159
- if (!N.isPropertyAccessExpression(node)) {
428
+ if (!N2.isPropertyAccessExpression(node)) {
160
429
  return [];
161
430
  }
162
431
  return isProcessEnv(node) ? readsThroughEnvObject(node, resolution) : dottedRead(node);
163
432
  }
164
433
  function readsThroughHelperCall(call, resolution) {
165
- const reads = [];
166
- const callee = functionBehindCallee(call.getExpression());
434
+ const callee = functionBehindCallee(call.getExpression(), resolution);
167
435
  if (callee === null) {
168
- return reads;
436
+ return [];
169
437
  }
438
+ const sitesNaming = namesReadAtSites(callee, resolution);
439
+ const parameters = callee.getParameters();
440
+ const defaultedByName = /* @__PURE__ */ new Map();
170
441
  call.getArguments().forEach((passed, at) => {
171
- const read = parameterReachesEnvRead(callee, at, resolution);
172
- if (read === null) {
442
+ const parameter = parameters[at];
443
+ if (parameter === void 0) {
444
+ return;
445
+ }
446
+ const sites = sitesNaming(parameter) ?? directEnvReads(callee, parameter);
447
+ if (sites.length === 0) {
173
448
  return;
174
449
  }
175
450
  const literal = stringValueOf(passed, resolution);
176
- if (literal !== null && literal.length > 0) {
177
- reads.push({ name: literal, defaulted: read.defaulted, node: call });
451
+ if (!namesSomething(literal)) {
452
+ return;
178
453
  }
454
+ const everywhere = sites.every(isDefaultedAt);
455
+ defaultedByName.set(
456
+ literal,
457
+ (defaultedByName.get(literal) ?? true) && everywhere
458
+ );
179
459
  });
180
- return reads;
460
+ const wrapped = isDefaultedAt(call);
461
+ return [
462
+ ...[...defaultedByName].map(([name, atSites]) => ({
463
+ name,
464
+ defaulted: atSites || wrapped,
465
+ node: call
466
+ })),
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.
469
+ ...anchoredAt(schemaEnvReadsInside(callee, resolution), call)
470
+ ];
471
+ }
472
+ function anchoredAt(reads, node) {
473
+ return reads.map((read) => ({ ...read, node }));
181
474
  }
182
- function functionBehindCallee(callee) {
183
- const nameNode = N.isPropertyAccessExpression(callee) ? callee.getNameNode() : callee;
184
- if (!N.isIdentifier(nameNode)) {
475
+ function functionBehindCallee(callee, resolution) {
476
+ const nameNode = N2.isPropertyAccessExpression(callee) ? callee.getNameNode() : callee;
477
+ if (!N2.isIdentifier(nameNode)) {
185
478
  return null;
186
479
  }
187
- return functionTargetOf(nameNode)?.func ?? null;
480
+ const declared = functionTargetOf(nameNode)?.func;
481
+ if (declared !== void 0 || resolution === void 0) {
482
+ return declared ?? null;
483
+ }
484
+ return factoryReturnedCallee(nameNode, callee, resolution);
188
485
  }
189
- var PARAM_ENV_READS = /* @__PURE__ */ new WeakMap();
190
- function parameterReachesEnvRead(fn, at, resolution) {
191
- const byParameter = PARAM_ENV_READS.get(fn.compilerNode) ?? /* @__PURE__ */ new Map();
192
- PARAM_ENV_READS.set(fn.compilerNode, byParameter);
193
- const remembered = byParameter.get(at);
194
- if (remembered !== void 0) {
195
- return remembered;
486
+ function factoryReturnedCallee(nameNode, callee, resolution) {
487
+ if (!isDeclaredAsCall(nameNode)) {
488
+ return null;
196
489
  }
197
- const found = reachesEnvRead(fn, at, resolution);
198
- byParameter.set(at, found);
199
- return found;
490
+ const returned = resolution.resolveReturnedCallable(callee);
491
+ return returned === null ? null : toFunctionRoot(returned);
200
492
  }
201
- function reachesEnvRead(fn, at, resolution) {
202
- const pending = [{ fn, at }];
203
- const taken = /* @__PURE__ */ new Set();
204
- while (pending.length > 0) {
205
- const wanted = pending.pop();
206
- const key = `${wanted.fn.getPos()}:${wanted.at}`;
207
- if (taken.has(key)) {
208
- continue;
209
- }
210
- taken.add(key);
211
- const parameter = wanted.fn.getParameters()[wanted.at];
212
- if (parameter === void 0) {
213
- continue;
214
- }
215
- const direct = directEnvRead(wanted.fn, parameter);
216
- if (direct !== null) {
217
- return direct;
218
- }
219
- if (resolution === void 0) {
220
- continue;
221
- }
222
- for (const passed of resolution.callsPassing(parameter)) {
223
- if (!N.isCallExpression(passed.call)) {
224
- continue;
225
- }
226
- const position = passed.call.getArguments().indexOf(passed.argument);
227
- const next = functionLikeOf(
228
- resolution.resolveCallable(passed.call.getExpression())
229
- );
230
- if (position >= 0 && next !== null && next !== wanted.fn) {
231
- pending.push({ fn: next, at: position });
232
- }
233
- }
493
+ function isDeclaredAsCall(nameNode) {
494
+ const declarations = declarationsBehind(symbolBehind(nameNode));
495
+ return declarations.length > 0 && declarations.every(isVariableSetToCall);
496
+ }
497
+ function isVariableSetToCall(declaration) {
498
+ if (!N2.isVariableDeclaration(declaration)) {
499
+ return false;
234
500
  }
235
- return null;
501
+ const initializer = declaration.getInitializer();
502
+ return initializer !== void 0 && N2.isCallExpression(initializer);
503
+ }
504
+ function namesSomething(value) {
505
+ return value !== null && value.length > 0;
506
+ }
507
+ function namesReadAtSites(fn, resolution) {
508
+ if (resolution === void 0) {
509
+ return () => null;
510
+ }
511
+ const namers = resolution.envNamers(fn.getSourceFile());
512
+ return (parameter) => namers.sitesNaming(parameter);
513
+ }
514
+ function directEnvReads(fn, parameter) {
515
+ const direct = directEnvRead(fn, parameter);
516
+ return direct === null ? [] : [direct];
236
517
  }
237
518
  function directEnvRead(fn, parameter) {
238
519
  for (const access of fn.getDescendantsOfKind(
239
- SyntaxKind.ElementAccessExpression
520
+ SyntaxKind2.ElementAccessExpression
240
521
  )) {
241
522
  if (!isProcessEnv(access.getExpression())) {
242
523
  continue;
243
524
  }
244
525
  const argument = access.getArgumentExpression();
245
- if (argument !== void 0 && N.isIdentifier(argument) && symbolBehind(argument)?.getValueDeclaration() === parameter) {
246
- return { defaulted: isDefaultedAt(access) };
526
+ if (argument !== void 0 && N2.isIdentifier(argument) && symbolBehind(argument)?.getValueDeclaration() === parameter) {
527
+ return access;
247
528
  }
248
529
  }
249
530
  return null;
250
531
  }
251
- function functionLikeOf(node) {
252
- if (node === null) {
253
- return null;
254
- }
255
- return N.isFunctionDeclaration(node) || N.isArrowFunction(node) || N.isFunctionExpression(node) || N.isMethodDeclaration(node) ? node : null;
256
- }
257
- function configReadEffect(read, deploymentTarget, instanceName) {
532
+ function configReadEffect(read, where) {
258
533
  return {
259
534
  type: "interaction",
260
- binding: runtimeConfigBinding({
261
- recognition: "@suss/runtime-node",
262
- deploymentTarget,
263
- instanceName
264
- }),
535
+ binding: configBinding(where),
265
536
  callee: readName(read.name),
266
537
  interaction: {
267
538
  class: "config-read",
@@ -270,42 +541,21 @@ function configReadEffect(read, deploymentTarget, instanceName) {
270
541
  }
271
542
  };
272
543
  }
273
- function recognizeProcessEnvRead(access, deploymentTarget, instanceName, resolution) {
544
+ function recognizeProcessEnvRead(access, where, resolution) {
274
545
  const reads = envReadsAt(access, resolution);
275
546
  if (reads.length === 0) {
276
547
  return null;
277
548
  }
278
- return reads.map(
279
- (read) => configReadEffect(read, deploymentTarget, instanceName)
280
- );
549
+ return reads.map((read) => configReadEffect(read, where));
281
550
  }
282
551
  function envVarRecognizer(opts = {}) {
283
- const deploymentTarget = opts.deploymentTarget ?? "lambda";
284
- const instanceName = opts.instanceName ?? "<unknown>";
285
552
  return (access, ctx) => recognizeProcessEnvRead(
286
553
  access,
287
- deploymentTarget,
288
- instanceName,
554
+ opts,
289
555
  ctx.resolution
290
556
  );
291
557
  }
292
558
  var FILE_LOCATION_GLOBALS = /* @__PURE__ */ new Set(["__dirname", "__filename"]);
293
- function moduleMetaRead(callee) {
294
- return {
295
- type: "interaction",
296
- binding: runtimeConfigBinding2({
297
- recognition: "@suss/runtime-node",
298
- deploymentTarget: "lambda",
299
- instanceName: "<runtime>"
300
- }),
301
- callee,
302
- interaction: {
303
- class: "config-read",
304
- name: callee,
305
- defaulted: false
306
- }
307
- };
308
- }
309
559
  var importMetaRecognizer = (access, _ctx) => {
310
560
  const node = access;
311
561
  if (!Node.isPropertyAccessExpression(node)) {
@@ -319,7 +569,7 @@ var importMetaRecognizer = (access, _ctx) => {
319
569
  if (keyword === void 0 || inner.getNameNode().getText() !== "meta") {
320
570
  return null;
321
571
  }
322
- return [moduleMetaRead(node.getText())];
572
+ return [opaqueRuntimeRead(node.getText())];
323
573
  };
324
574
  var fileLocationRecognizer = (access, _ctx) => {
325
575
  const node = access;
@@ -334,7 +584,7 @@ var fileLocationRecognizer = (access, _ctx) => {
334
584
  if (!FILE_LOCATION_GLOBALS.has(text)) {
335
585
  return null;
336
586
  }
337
- return [moduleMetaRead(text)];
587
+ return [opaqueRuntimeRead(text)];
338
588
  };
339
589
  function isProcessEnvVarRead(node) {
340
590
  const inner = node.getExpression();
@@ -361,35 +611,33 @@ var OPAQUE_PROPERTY_NAMES = /* @__PURE__ */ new Set([
361
611
  "execPath",
362
612
  "execArgv"
363
613
  ]);
364
- function makeProcessSurfaceRecognizer(opts) {
365
- const deploymentTarget = opts.deploymentTarget ?? "lambda";
366
- const instanceName = opts.instanceName ?? "<unknown>";
614
+ function makeProcessSurfaceRecognizer(where) {
367
615
  return (access, _ctx) => {
368
616
  const node = access;
369
617
  if (Node2.isPropertyAccessExpression(node)) {
370
- return recognizeProperty(node, deploymentTarget, instanceName);
618
+ return recognizeProperty(node, where);
371
619
  }
372
620
  if (Node2.isElementAccessExpression(node)) {
373
- return recognizeElementAccess(node, deploymentTarget, instanceName);
621
+ return recognizeElementAccess(node, where);
374
622
  }
375
623
  return null;
376
624
  };
377
625
  }
378
- function recognizeProperty(node, deploymentTarget, instanceName) {
626
+ function recognizeProperty(node, where) {
379
627
  if (isProcessEnvVarRead(node)) {
380
628
  return null;
381
629
  }
382
630
  const subject = node.getExpression();
383
631
  const name = node.getName();
384
632
  if (isProcessIdentifier(subject) && name === "argv") {
385
- return [argvRead(deploymentTarget, instanceName, node.getText(), null)];
633
+ return [argvRead(where, node.getText(), null)];
386
634
  }
387
635
  if (isProcessIdentifier(subject) && OPAQUE_PROPERTY_NAMES.has(name)) {
388
- return [opaqueProcessRead(node.getText(), `process.${name}`)];
636
+ return [opaqueRuntimeRead(node.getText())];
389
637
  }
390
638
  return null;
391
639
  }
392
- function recognizeElementAccess(node, deploymentTarget, instanceName) {
640
+ function recognizeElementAccess(node, where) {
393
641
  const subject = node.getExpression();
394
642
  if (!Node2.isPropertyAccessExpression(subject)) {
395
643
  return null;
@@ -406,17 +654,13 @@ function recognizeElementAccess(node, deploymentTarget, instanceName) {
406
654
  if (arg !== void 0 && Node2.isNumericLiteral(arg)) {
407
655
  indexLabel = String(arg.getLiteralValue());
408
656
  }
409
- return [argvRead(deploymentTarget, instanceName, node.getText(), indexLabel)];
657
+ return [argvRead(where, node.getText(), indexLabel)];
410
658
  }
411
- function argvRead(deploymentTarget, instanceName, callee, indexLabel) {
659
+ function argvRead(where, callee, indexLabel) {
412
660
  const name = indexLabel !== null ? `argv[${indexLabel}]` : "argv";
413
661
  return {
414
662
  type: "interaction",
415
- binding: runtimeConfigBinding3({
416
- recognition: "@suss/runtime-node",
417
- deploymentTarget,
418
- instanceName
419
- }),
663
+ binding: configBinding(where),
420
664
  callee,
421
665
  interaction: {
422
666
  class: "config-read",
@@ -425,22 +669,6 @@ function argvRead(deploymentTarget, instanceName, callee, indexLabel) {
425
669
  }
426
670
  };
427
671
  }
428
- function opaqueProcessRead(callee, _label) {
429
- return {
430
- type: "interaction",
431
- binding: runtimeConfigBinding3({
432
- recognition: "@suss/runtime-node",
433
- deploymentTarget: "lambda",
434
- instanceName: "<runtime>"
435
- }),
436
- callee,
437
- interaction: {
438
- class: "config-read",
439
- name: callee,
440
- defaulted: false
441
- }
442
- };
443
- }
444
672
  function processSurfaceRecognizer(opts = {}) {
445
673
  return makeProcessSurfaceRecognizer(opts);
446
674
  }
@@ -582,16 +810,16 @@ function nodeSchedulingSubUnits(parent, _ctx) {
582
810
  });
583
811
  return out;
584
812
  }
585
- var PACK_VERSION = "0.1.0";
813
+ var PACK_VERSION = "0.2.0";
586
814
  var optionsSchema = z.object({
587
815
  /**
588
816
  * Deployment context for runtime-config reads (process.env.X,
589
- * process.argv). Defaults to `"lambda"`.
817
+ * process.argv). Left off the binding unless a run sets it.
590
818
  */
591
819
  deploymentTarget: z.enum(["lambda", "ecs-task", "container", "k8s-deployment"]).optional(),
592
820
  /**
593
- * Instance name placeholder for runtime-config bindings the pack
594
- * emits. Defaults to `"<unknown>"`.
821
+ * The deployed instance the reads belong to. Left off the binding
822
+ * unless a run sets it.
595
823
  */
596
824
  instanceName: z.string().optional()
597
825
  }).strict();
@@ -611,6 +839,7 @@ function nodeRuntimePack(options = {}) {
611
839
  terminals: [],
612
840
  inputMapping: { type: "positionalParams", params: [] },
613
841
  invocationRecognizers: [schedulingRecognizer],
842
+ environmentObjects: ["process.env"],
614
843
  accessRecognizers: [
615
844
  // `envRecognizer` owns `process.env.X`; `processRecognizer`
616
845
  // owns the rest of the process surface and skips env reads,
@@ -628,7 +857,7 @@ var declares = {
628
857
  package: "@suss/runtime-node",
629
858
  dependencies: [],
630
859
  shippedWith: "typescript",
631
- reads: "Node.js runtime primitives, scheduling, the `process` surface (incl. `process.env.X` config-read interactions), module-loading globals, emitted as interaction effects."
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."
632
861
  };
633
862
  var index_default = nodeRuntimePack;
634
863
  export {