@suss/adapter-ruby 0.5.9 → 0.5.11

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 CHANGED
@@ -15296,7 +15296,16 @@ function date4(params) {
15296
15296
  // ../../../node_modules/zod/v4/classic/external.js
15297
15297
  config(en_default());
15298
15298
 
15299
- // ../../ir-core/dist/chunk-5KE7OWN3.js
15299
+ // ../../ir-core/dist/chunk-WKR5SU4N.js
15300
+ function gqlIdentityKey(typeName, fieldName) {
15301
+ return `gql:${typeName}.${fieldName}`;
15302
+ }
15303
+ function fnIdentityKey(packageName, exportPath) {
15304
+ return `fn:${packageName}::${exportPath.join(".")}`;
15305
+ }
15306
+ function busIdentityKey(messageBus, subject) {
15307
+ return `bus:${messageBus} ${subject}`;
15308
+ }
15300
15309
  function defineBoundarySemantics(definition) {
15301
15310
  return definition;
15302
15311
  }
@@ -15338,6 +15347,12 @@ var functionCallSemantics = defineBoundarySemantics({
15338
15347
  /** A call returns a value, which is not a status and a body. */
15339
15348
  exchangesHttpResponses: false,
15340
15349
  reportsUnpairedItself: false,
15350
+ /**
15351
+ * In-repo units (components, bare handlers) are keyless by design
15352
+ * and pair through call edges rather than the keyed pass, so a
15353
+ * missing key is not a boundary nothing can reach.
15354
+ */
15355
+ canPair: () => true,
15341
15356
  /**
15342
15357
  * `"fn:<package>::<exportPath>"` when both are set. Other in-process
15343
15358
  * function-call units, such as components and bare handlers inside
@@ -15345,7 +15360,7 @@ var functionCallSemantics = defineBoundarySemantics({
15345
15360
  */
15346
15361
  identityKey(semantics) {
15347
15362
  if (semantics.package !== void 0 && semantics.exportPath !== void 0 && semantics.exportPath.length > 0) {
15348
- return `fn:${semantics.package}::${semantics.exportPath.join(".")}`;
15363
+ return fnIdentityKey(semantics.package, semantics.exportPath);
15349
15364
  }
15350
15365
  return null;
15351
15366
  }
@@ -15368,6 +15383,8 @@ var graphqlOperationSemantics = defineBoundarySemantics({
15368
15383
  exchangesHttpResponses: false,
15369
15384
  reportsUnpairedItself: false,
15370
15385
  identityKey: () => null,
15386
+ /** Keyless by design; the dedicated pass pairs it by its document. */
15387
+ canPair: () => true,
15371
15388
  /** "query GetUser". The contract checker pairs it, the key does not. */
15372
15389
  displayLabel(semantics) {
15373
15390
  return `${semantics.operationType} ${semantics.operationName ?? "<anonymous>"}`;
@@ -15401,7 +15418,7 @@ var graphqlResolverSemantics = defineBoundarySemantics({
15401
15418
  if (semantics.typeName === null || semantics.fieldName === "") {
15402
15419
  return null;
15403
15420
  }
15404
- return `gql:${semantics.typeName}.${semantics.fieldName}`;
15421
+ return gqlIdentityKey(semantics.typeName, semantics.fieldName);
15405
15422
  }
15406
15423
  }
15407
15424
  });
@@ -15450,6 +15467,12 @@ var messageBusSemantics = defineBoundarySemantics({
15450
15467
  * ones, so the generic unmatched lists leave them alone.
15451
15468
  */
15452
15469
  reportsUnpairedItself: true,
15470
+ /**
15471
+ * A channel unnamed here can still pair: the dedicated pass
15472
+ * collapses env chains before comparing, so a consumer whose
15473
+ * channel arrives at runtime meets the template that declares it.
15474
+ */
15475
+ canPair: () => true,
15453
15476
  /**
15454
15477
  * `"bus:<messageBus> <subject>"`, or null when the channel is null
15455
15478
  * or its subject is empty.
@@ -15472,7 +15495,7 @@ var messageBusSemantics = defineBoundarySemantics({
15472
15495
  if (subject === "") {
15473
15496
  return null;
15474
15497
  }
15475
- return `bus:${semantics.messageBus} ${subject}`;
15498
+ return busIdentityKey(semantics.messageBus, subject);
15476
15499
  },
15477
15500
  sidesAgree(a, b) {
15478
15501
  if (a.channel === null || b.channel === null) {
@@ -15650,8 +15673,13 @@ var StorageRelationalSemanticsSchema = external_exports.object({
15650
15673
  * and a monorepo with several schemas gives each one its own value.
15651
15674
  */
15652
15675
  scope: external_exports.string(),
15653
- /** The table or model name, as declared in the schema. */
15654
- table: external_exports.string()
15676
+ /**
15677
+ * The table or model name as the schema declares it, or null when
15678
+ * the source states one this reader could not settle. A null table
15679
+ * pairs with nothing, rather than with whatever its source text
15680
+ * happens to spell.
15681
+ */
15682
+ table: external_exports.string().nullable()
15655
15683
  });
15656
15684
  var storageRelationalSemantics = defineBoundarySemantics({
15657
15685
  name: "storage-relational",
@@ -15810,6 +15838,14 @@ var SuppressionFileSchema = external_exports.object({
15810
15838
  version: external_exports.literal(1),
15811
15839
  rules: external_exports.array(SuppressionRuleSchema)
15812
15840
  }).strict();
15841
+ function namedOrNull(value, field2) {
15842
+ if (value === "") {
15843
+ throw new Error(
15844
+ `${field2} is an empty string; write null when the source does not name it`
15845
+ );
15846
+ }
15847
+ return value;
15848
+ }
15813
15849
  function storageRelationalBinding(opts) {
15814
15850
  return {
15815
15851
  transport: opts.storageSystem,
@@ -15817,7 +15853,7 @@ function storageRelationalBinding(opts) {
15817
15853
  name: "storage-relational",
15818
15854
  storageSystem: opts.storageSystem,
15819
15855
  scope: opts.scope,
15820
- table: opts.table
15856
+ table: namedOrNull(opts.table, "storage table")
15821
15857
  },
15822
15858
  recognition: opts.recognition
15823
15859
  };
@@ -16338,7 +16374,40 @@ function readClassContract(ancestry, pattern) {
16338
16374
  handler(readCallArgs(field(statement, "arguments")), scope, pattern, out);
16339
16375
  }
16340
16376
  const returnType = out.typeCallShape ?? (Object.keys(out.fieldProperties).length > 0 ? { type: "record", properties: out.fieldProperties } : null);
16341
- return returnType === null ? null : { returnType, args: [...out.args.values()] };
16377
+ if (returnType === null) {
16378
+ return null;
16379
+ }
16380
+ const args = [...out.args.values()];
16381
+ const wrapping = pattern.argumentWrapping;
16382
+ if (wrapping !== void 0 && ancestryReaches(ancestry, wrapping)) {
16383
+ return {
16384
+ returnType,
16385
+ args: [wrapInputArgument(args, wrapping)],
16386
+ methodArgs: args
16387
+ };
16388
+ }
16389
+ return { returnType, args };
16390
+ }
16391
+ function ancestryReaches(ancestry, wrapping) {
16392
+ return ancestry.some((entry) => entry.name === wrapping.ancestorClassName);
16393
+ }
16394
+ function wrapInputArgument(args, wrapping) {
16395
+ const properties = {};
16396
+ for (const arg of args) {
16397
+ properties[arg.name] = arg.required ? arg.type : optionalShape(arg.type);
16398
+ }
16399
+ for (const [name, extra] of Object.entries(wrapping.extraFields)) {
16400
+ properties[name] = extra.required ? extra.type : optionalShape(extra.type);
16401
+ }
16402
+ return {
16403
+ name: wrapping.argumentName,
16404
+ type: { type: "record", properties },
16405
+ required: true,
16406
+ typeText: null
16407
+ };
16408
+ }
16409
+ function optionalShape(shape) {
16410
+ return { type: "union", variants: [shape, { type: "undefined" }] };
16342
16411
  }
16343
16412
  function resolvedName(symbol2, callArgs, pattern) {
16344
16413
  const override = callArgs.keyword[pattern.camelizeKeyword];
@@ -16353,14 +16422,12 @@ function toCamelCase(name) {
16353
16422
  ].join("");
16354
16423
  }
16355
16424
  function buildFieldUnit(pack, typeName, decl, filePath) {
16356
- const parameters = (decl.contract?.args ?? []).map(
16357
- (arg, position) => ({
16358
- name: arg.name,
16359
- position,
16360
- role: "args",
16361
- typeText: arg.typeText
16362
- })
16363
- );
16425
+ const parameters = (decl.contract?.methodArgs ?? decl.contract?.args ?? []).map((arg, position) => ({
16426
+ name: arg.name,
16427
+ position,
16428
+ role: "args",
16429
+ typeText: arg.typeText
16430
+ }));
16364
16431
  const graphqlDeclaredContract = decl.contract !== null ? {
16365
16432
  returnType: decl.contract.returnType,
16366
16433
  args: decl.contract.args.map((a) => ({
package/dist/index.d.cts CHANGED
@@ -202,6 +202,23 @@ interface GraphqlObjectFields {
202
202
  /** Module prefixes the same scalars can also be written under when someone spells out the full path. */
203
203
  scalarNamePrefixes: string[];
204
204
  typeNameConvention: GraphqlTypeNameConvention;
205
+ /**
206
+ * A base class that changes a mutation's wire contract. When a wired
207
+ * class's ancestry reaches `ancestorClassName`, the library wraps
208
+ * every declared argument into one input-object argument called
209
+ * `argumentName` and adds `extraFields` to it. graphql-ruby's
210
+ * RelayClassicMutation is the class this describes: on the wire the
211
+ * mutation takes a single required `input`, whose fields are the
212
+ * declared arguments plus an optional `clientMutationId`.
213
+ */
214
+ argumentWrapping?: {
215
+ ancestorClassName: string;
216
+ argumentName: string;
217
+ extraFields: Record<string, {
218
+ type: TypeShape;
219
+ required: boolean;
220
+ }>;
221
+ };
205
222
  }
206
223
 
207
224
  interface RbStorageOptions {
package/dist/index.d.ts CHANGED
@@ -202,6 +202,23 @@ interface GraphqlObjectFields {
202
202
  /** Module prefixes the same scalars can also be written under when someone spells out the full path. */
203
203
  scalarNamePrefixes: string[];
204
204
  typeNameConvention: GraphqlTypeNameConvention;
205
+ /**
206
+ * A base class that changes a mutation's wire contract. When a wired
207
+ * class's ancestry reaches `ancestorClassName`, the library wraps
208
+ * every declared argument into one input-object argument called
209
+ * `argumentName` and adds `extraFields` to it. graphql-ruby's
210
+ * RelayClassicMutation is the class this describes: on the wire the
211
+ * mutation takes a single required `input`, whose fields are the
212
+ * declared arguments plus an optional `clientMutationId`.
213
+ */
214
+ argumentWrapping?: {
215
+ ancestorClassName: string;
216
+ argumentName: string;
217
+ extraFields: Record<string, {
218
+ type: TypeShape;
219
+ required: boolean;
220
+ }>;
221
+ };
205
222
  }
206
223
 
207
224
  interface RbStorageOptions {
package/dist/index.js CHANGED
@@ -15245,7 +15245,16 @@ function date4(params) {
15245
15245
  // ../../../node_modules/zod/v4/classic/external.js
15246
15246
  config(en_default());
15247
15247
 
15248
- // ../../ir-core/dist/chunk-5KE7OWN3.js
15248
+ // ../../ir-core/dist/chunk-WKR5SU4N.js
15249
+ function gqlIdentityKey(typeName, fieldName) {
15250
+ return `gql:${typeName}.${fieldName}`;
15251
+ }
15252
+ function fnIdentityKey(packageName, exportPath) {
15253
+ return `fn:${packageName}::${exportPath.join(".")}`;
15254
+ }
15255
+ function busIdentityKey(messageBus, subject) {
15256
+ return `bus:${messageBus} ${subject}`;
15257
+ }
15249
15258
  function defineBoundarySemantics(definition) {
15250
15259
  return definition;
15251
15260
  }
@@ -15287,6 +15296,12 @@ var functionCallSemantics = defineBoundarySemantics({
15287
15296
  /** A call returns a value, which is not a status and a body. */
15288
15297
  exchangesHttpResponses: false,
15289
15298
  reportsUnpairedItself: false,
15299
+ /**
15300
+ * In-repo units (components, bare handlers) are keyless by design
15301
+ * and pair through call edges rather than the keyed pass, so a
15302
+ * missing key is not a boundary nothing can reach.
15303
+ */
15304
+ canPair: () => true,
15290
15305
  /**
15291
15306
  * `"fn:<package>::<exportPath>"` when both are set. Other in-process
15292
15307
  * function-call units, such as components and bare handlers inside
@@ -15294,7 +15309,7 @@ var functionCallSemantics = defineBoundarySemantics({
15294
15309
  */
15295
15310
  identityKey(semantics) {
15296
15311
  if (semantics.package !== void 0 && semantics.exportPath !== void 0 && semantics.exportPath.length > 0) {
15297
- return `fn:${semantics.package}::${semantics.exportPath.join(".")}`;
15312
+ return fnIdentityKey(semantics.package, semantics.exportPath);
15298
15313
  }
15299
15314
  return null;
15300
15315
  }
@@ -15317,6 +15332,8 @@ var graphqlOperationSemantics = defineBoundarySemantics({
15317
15332
  exchangesHttpResponses: false,
15318
15333
  reportsUnpairedItself: false,
15319
15334
  identityKey: () => null,
15335
+ /** Keyless by design; the dedicated pass pairs it by its document. */
15336
+ canPair: () => true,
15320
15337
  /** "query GetUser". The contract checker pairs it, the key does not. */
15321
15338
  displayLabel(semantics) {
15322
15339
  return `${semantics.operationType} ${semantics.operationName ?? "<anonymous>"}`;
@@ -15350,7 +15367,7 @@ var graphqlResolverSemantics = defineBoundarySemantics({
15350
15367
  if (semantics.typeName === null || semantics.fieldName === "") {
15351
15368
  return null;
15352
15369
  }
15353
- return `gql:${semantics.typeName}.${semantics.fieldName}`;
15370
+ return gqlIdentityKey(semantics.typeName, semantics.fieldName);
15354
15371
  }
15355
15372
  }
15356
15373
  });
@@ -15399,6 +15416,12 @@ var messageBusSemantics = defineBoundarySemantics({
15399
15416
  * ones, so the generic unmatched lists leave them alone.
15400
15417
  */
15401
15418
  reportsUnpairedItself: true,
15419
+ /**
15420
+ * A channel unnamed here can still pair: the dedicated pass
15421
+ * collapses env chains before comparing, so a consumer whose
15422
+ * channel arrives at runtime meets the template that declares it.
15423
+ */
15424
+ canPair: () => true,
15402
15425
  /**
15403
15426
  * `"bus:<messageBus> <subject>"`, or null when the channel is null
15404
15427
  * or its subject is empty.
@@ -15421,7 +15444,7 @@ var messageBusSemantics = defineBoundarySemantics({
15421
15444
  if (subject === "") {
15422
15445
  return null;
15423
15446
  }
15424
- return `bus:${semantics.messageBus} ${subject}`;
15447
+ return busIdentityKey(semantics.messageBus, subject);
15425
15448
  },
15426
15449
  sidesAgree(a, b) {
15427
15450
  if (a.channel === null || b.channel === null) {
@@ -15599,8 +15622,13 @@ var StorageRelationalSemanticsSchema = external_exports.object({
15599
15622
  * and a monorepo with several schemas gives each one its own value.
15600
15623
  */
15601
15624
  scope: external_exports.string(),
15602
- /** The table or model name, as declared in the schema. */
15603
- table: external_exports.string()
15625
+ /**
15626
+ * The table or model name as the schema declares it, or null when
15627
+ * the source states one this reader could not settle. A null table
15628
+ * pairs with nothing, rather than with whatever its source text
15629
+ * happens to spell.
15630
+ */
15631
+ table: external_exports.string().nullable()
15604
15632
  });
15605
15633
  var storageRelationalSemantics = defineBoundarySemantics({
15606
15634
  name: "storage-relational",
@@ -15759,6 +15787,14 @@ var SuppressionFileSchema = external_exports.object({
15759
15787
  version: external_exports.literal(1),
15760
15788
  rules: external_exports.array(SuppressionRuleSchema)
15761
15789
  }).strict();
15790
+ function namedOrNull(value, field2) {
15791
+ if (value === "") {
15792
+ throw new Error(
15793
+ `${field2} is an empty string; write null when the source does not name it`
15794
+ );
15795
+ }
15796
+ return value;
15797
+ }
15762
15798
  function storageRelationalBinding(opts) {
15763
15799
  return {
15764
15800
  transport: opts.storageSystem,
@@ -15766,7 +15802,7 @@ function storageRelationalBinding(opts) {
15766
15802
  name: "storage-relational",
15767
15803
  storageSystem: opts.storageSystem,
15768
15804
  scope: opts.scope,
15769
- table: opts.table
15805
+ table: namedOrNull(opts.table, "storage table")
15770
15806
  },
15771
15807
  recognition: opts.recognition
15772
15808
  };
@@ -16287,7 +16323,40 @@ function readClassContract(ancestry, pattern) {
16287
16323
  handler(readCallArgs(field(statement, "arguments")), scope, pattern, out);
16288
16324
  }
16289
16325
  const returnType = out.typeCallShape ?? (Object.keys(out.fieldProperties).length > 0 ? { type: "record", properties: out.fieldProperties } : null);
16290
- return returnType === null ? null : { returnType, args: [...out.args.values()] };
16326
+ if (returnType === null) {
16327
+ return null;
16328
+ }
16329
+ const args = [...out.args.values()];
16330
+ const wrapping = pattern.argumentWrapping;
16331
+ if (wrapping !== void 0 && ancestryReaches(ancestry, wrapping)) {
16332
+ return {
16333
+ returnType,
16334
+ args: [wrapInputArgument(args, wrapping)],
16335
+ methodArgs: args
16336
+ };
16337
+ }
16338
+ return { returnType, args };
16339
+ }
16340
+ function ancestryReaches(ancestry, wrapping) {
16341
+ return ancestry.some((entry) => entry.name === wrapping.ancestorClassName);
16342
+ }
16343
+ function wrapInputArgument(args, wrapping) {
16344
+ const properties = {};
16345
+ for (const arg of args) {
16346
+ properties[arg.name] = arg.required ? arg.type : optionalShape(arg.type);
16347
+ }
16348
+ for (const [name, extra] of Object.entries(wrapping.extraFields)) {
16349
+ properties[name] = extra.required ? extra.type : optionalShape(extra.type);
16350
+ }
16351
+ return {
16352
+ name: wrapping.argumentName,
16353
+ type: { type: "record", properties },
16354
+ required: true,
16355
+ typeText: null
16356
+ };
16357
+ }
16358
+ function optionalShape(shape) {
16359
+ return { type: "union", variants: [shape, { type: "undefined" }] };
16291
16360
  }
16292
16361
  function resolvedName(symbol2, callArgs, pattern) {
16293
16362
  const override = callArgs.keyword[pattern.camelizeKeyword];
@@ -16302,14 +16371,12 @@ function toCamelCase(name) {
16302
16371
  ].join("");
16303
16372
  }
16304
16373
  function buildFieldUnit(pack, typeName, decl, filePath) {
16305
- const parameters = (decl.contract?.args ?? []).map(
16306
- (arg, position) => ({
16307
- name: arg.name,
16308
- position,
16309
- role: "args",
16310
- typeText: arg.typeText
16311
- })
16312
- );
16374
+ const parameters = (decl.contract?.methodArgs ?? decl.contract?.args ?? []).map((arg, position) => ({
16375
+ name: arg.name,
16376
+ position,
16377
+ role: "args",
16378
+ typeText: arg.typeText
16379
+ }));
16313
16380
  const graphqlDeclaredContract = decl.contract !== null ? {
16314
16381
  returnType: decl.contract.returnType,
16315
16382
  args: decl.contract.args.map((a) => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/adapter-ruby",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "type": "module",
5
5
  "description": "Ruby language adapter for suss, parsing source with tree-sitter (WASM), resolving constant nesting with a lexical binder, and emitting raw extractions for the suss pipeline.",
6
6
  "keywords": [
@@ -47,9 +47,9 @@
47
47
  "typecheck": "tsc --noEmit"
48
48
  },
49
49
  "dependencies": {
50
- "@suss/behavioral-ir": "0.5.9",
51
- "@suss/datalog": "0.5.9",
52
- "@suss/extractor": "0.5.9",
50
+ "@suss/behavioral-ir": "0.5.11",
51
+ "@suss/datalog": "0.5.11",
52
+ "@suss/extractor": "0.5.11",
53
53
  "web-tree-sitter": "^0.26.11"
54
54
  },
55
55
  "devDependencies": {