@checkdigit/eslint-plugin 7.18.0-PR.143-b064 → 7.18.0-PR.143-b6d4

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 (40) hide show
  1. package/dist-mjs/athena/athena.mjs +82 -36
  2. package/dist-mjs/athena/visitor.mjs +27 -1
  3. package/dist-mjs/openapi/service-schema-generator.mjs +26 -64
  4. package/dist-types/athena/visitor.d.ts +4 -0
  5. package/package.json +1 -1
  6. package/src/athena/athena.ts +93 -43
  7. package/src/athena/visitor.ts +28 -0
  8. package/src/openapi/service-schema-generator.ts +26 -74
  9. package/src/services/interchange/v1/swagger.schema.deref.json +16 -15
  10. package/src/services/ledger/v1/swagger.schema.deref.json +81 -81
  11. package/src/services/ledger/v2/swagger.schema.deref.json +4119 -0
  12. package/src/services/link/v1/swagger.schema.deref.json +13 -12
  13. package/src/services/link/{v1/swagger.schema.json → v2/swagger.schema.deref.json} +98 -28
  14. package/src/services/message/v1/swagger.schema.deref.json +731 -731
  15. package/src/services/message/v2/swagger.schema.deref.json +1017 -1017
  16. package/src/services/paymentCard/v1/swagger.schema.deref.json +248 -238
  17. package/src/services/paymentCard/v2/swagger.schema.deref.json +257 -274
  18. package/src/services/paymentCard/v3/swagger.schema.deref.json +2843 -0
  19. package/src/services/person/v1/swagger.schema.deref.json +111 -96
  20. package/src/services/person/v2/swagger.schema.deref.json +4931 -0
  21. package/src/services/teampayApproval/v1/swagger.schema.deref.json +2 -165
  22. package/src/services/teampayCardManagement/v1/swagger.schema.deref.json +220 -1768
  23. package/src/services/teampayClientManagement/v1/swagger.schema.deref.json +217 -217
  24. package/src/services/interchange/v1/swagger.schema.json +0 -423
  25. package/src/services/interchange/v1/swagger.yml +0 -414
  26. package/src/services/ledger/v1/swagger.schema.json +0 -1048
  27. package/src/services/ledger/v1/swagger.yml +0 -1094
  28. package/src/services/link/v1/swagger.yml +0 -343
  29. package/src/services/message/v1/swagger.schema.json +0 -2944
  30. package/src/services/message/v1/swagger.yml +0 -2798
  31. package/src/services/message/v2/swagger.schema.json +0 -3040
  32. package/src/services/message/v2/swagger.yml +0 -3009
  33. package/src/services/paymentCard/v1/swagger.schema.json +0 -1687
  34. package/src/services/paymentCard/v1/swagger.yml +0 -1161
  35. package/src/services/paymentCard/v2/swagger.schema.json +0 -1649
  36. package/src/services/paymentCard/v2/swagger.yml +0 -1149
  37. package/src/services/person/v1/swagger.schema.json +0 -979
  38. package/src/services/person/v1/swagger.yml +0 -1157
  39. package/src/services/teampayClientManagement/v1/swagger.schema.json +0 -1598
  40. package/src/services/teampayClientManagement/v1/swagger.yml +0 -1376
@@ -28,6 +28,8 @@ import {
28
28
  } from './context.ts';
29
29
  import { buildServiceTables } from './service-table.ts';
30
30
  import {
31
+ containsCastToArray,
32
+ containsCastToMap,
31
33
  containsLambda,
32
34
  extractBracketAccessorPath,
33
35
  extractColumnRefs,
@@ -228,7 +230,7 @@ function resolveFromClause(select: Select, ctx: VisitContext): void {
228
230
 
229
231
  interface UnnestMapping {
230
232
  fromColumn: string;
231
- toColumn: string;
233
+ toColumns: string[]; // 1 item for array UNNEST, 2 items for map UNNEST (key, value)
232
234
  ast: object;
233
235
  }
234
236
 
@@ -243,15 +245,17 @@ function extractUnnestMappings(select: Select): UnnestMapping[] {
243
245
  const fromColumn = typeof item.expr.column === 'string' ? item.expr.column : undefined;
244
246
  assert.ok(fromColumn !== undefined, 'UNNEST expr must be a column_ref with a string column name');
245
247
 
246
- // The alias is stored as a func_call node: UNNEST(col) AS t(alias)
247
- const toColumn = item.as?.args.value[0];
248
- const toColName =
249
- toColumn !== undefined && typeof (toColumn as { column?: unknown }).column === 'string'
250
- ? (toColumn as { column: string }).column
251
- : undefined;
252
- assert.ok(toColName !== undefined, 'UNNEST alias must be a column_ref with a string column name');
248
+ // The alias is stored as a func_call node: UNNEST(col) AS t(alias1[, alias2])
249
+ const aliasArgs = item.as?.args.value ?? [];
250
+ const toColumns: string[] = [];
251
+ for (const col of aliasArgs) {
252
+ if (typeof (col as { column?: unknown }).column === 'string') {
253
+ toColumns.push((col as { column: string }).column);
254
+ }
255
+ }
256
+ assert.ok(toColumns.length > 0, 'UNNEST alias must have at least one column name');
253
257
 
254
- mappings.push({ fromColumn, toColumn: toColName, ast: item.expr });
258
+ mappings.push({ fromColumn, toColumns, ast: item.expr });
255
259
  }
256
260
 
257
261
  return mappings;
@@ -260,45 +264,93 @@ function extractUnnestMappings(select: Select): UnnestMapping[] {
260
264
  function applyUnnestPre(mappings: UnnestMapping[], ctx: VisitContext): UnnestMapping[] {
261
265
  const deferred: UnnestMapping[] = [];
262
266
 
263
- for (const { fromColumn, toColumn, ast } of mappings) {
267
+ for (const { fromColumn, toColumns, ast } of mappings) {
264
268
  // Find the table that owns the source column
265
269
  const ownerTable = [...ctx.tables.values()].flat().find((table) => table.columns.has(fromColumn));
266
270
 
267
271
  if (ownerTable === undefined) {
268
- deferred.push({ fromColumn, toColumn, ast });
272
+ deferred.push({ fromColumn, toColumns, ast });
269
273
  continue;
270
274
  }
271
275
 
272
276
  const sourceColumns = ownerTable.columns.get(fromColumn) ?? [];
273
277
  const sourceSchema = sourceColumns[0]?.schema;
274
- if (sourceSchema?.type !== 'array') {
275
- throw new AthenaError(ATHENA_ERROR, `UNNEST source column '${fromColumn}' must resolve to an array schema`, ast);
276
- }
277
-
278
278
  const unnestTableName = `${ownerTable.name ?? '<anonymous>'}:<unnested>`;
279
- ctx.tables.set(unnestTableName, [
280
- {
281
- name: unnestTableName,
282
- ...(ownerTable.apiOperation !== undefined ? { apiOperation: ownerTable.apiOperation } : {}),
283
- columns: new Map([[toColumn, [resolvedCol(toColumn, sourceSchema.items, sourceColumns[0]?.ast)]]]),
284
- },
285
- ]);
279
+ const apiOperation = ownerTable.apiOperation !== undefined ? { apiOperation: ownerTable.apiOperation } : {};
280
+
281
+ if (sourceSchema?.type === 'array') {
282
+ const [toColumn] = toColumns;
283
+ assert.ok(toColumn !== undefined);
284
+ ctx.tables.set(unnestTableName, [
285
+ {
286
+ name: unnestTableName,
287
+ ...apiOperation,
288
+ columns: new Map([[toColumn, [resolvedCol(toColumn, sourceSchema.items, sourceColumns[0]?.ast)]]]),
289
+ },
290
+ ]);
291
+ } else if (sourceSchema?.type === 'object') {
292
+ // MAP UNNEST: UNNEST(map_col) AS t(key_col, value_col)
293
+ const [keyColumn, valueColumn] = toColumns;
294
+ assert.ok(
295
+ keyColumn !== undefined && valueColumn !== undefined,
296
+ `UNNEST of map column '${fromColumn}' requires exactly two alias columns (key, value)`,
297
+ );
298
+ const addlProps = (sourceSchema as SchemaObject)['additionalProperties'] as unknown;
299
+ const valueSchema: SchemaObject =
300
+ typeof addlProps === 'object' && addlProps !== null ? addlProps : { type: 'string' };
301
+ ctx.tables.set(unnestTableName, [
302
+ {
303
+ name: unnestTableName,
304
+ ...apiOperation,
305
+ columns: new Map([
306
+ [keyColumn, [resolvedCol(keyColumn, { type: 'string' }, sourceColumns[0]?.ast)]],
307
+ [valueColumn, [resolvedCol(valueColumn, valueSchema, sourceColumns[0]?.ast)]],
308
+ ]),
309
+ },
310
+ ]);
311
+ } else {
312
+ throw new AthenaError(
313
+ ATHENA_ERROR,
314
+ `UNNEST source column '${fromColumn}' must resolve to an array or map schema`,
315
+ ast,
316
+ );
317
+ }
286
318
  }
287
319
 
288
320
  return deferred;
289
321
  }
290
322
 
291
323
  function applyUnnestPost(mappings: UnnestMapping[], columns: Map<string, ResolvedColumn[]>): void {
292
- for (const { fromColumn, toColumn, ast } of mappings) {
324
+ for (const { fromColumn, toColumns, ast } of mappings) {
293
325
  const sourceColumns = columns.get(fromColumn);
294
326
  if (sourceColumns === undefined) {
295
327
  throw new AthenaError(ATHENA_ERROR, `UNNEST source column '${fromColumn}' not found in SELECT`, ast);
296
328
  }
297
329
  const sourceSchema = sourceColumns[0]?.schema;
298
- if (sourceSchema?.type !== 'array') {
299
- throw new AthenaError(ATHENA_ERROR, `UNNEST source column '${fromColumn}' must resolve to an array schema`, ast);
330
+
331
+ if (sourceSchema?.type === 'array') {
332
+ const [toColumn] = toColumns;
333
+ assert.ok(toColumn !== undefined);
334
+ columns.set(toColumn, [resolvedCol(toColumn, sourceSchema.items, sourceColumns[0]?.ast)]);
335
+ } else if (sourceSchema?.type === 'object') {
336
+ // MAP UNNEST: produces key column and value column
337
+ const [keyColumn, valueColumn] = toColumns;
338
+ assert.ok(
339
+ keyColumn !== undefined && valueColumn !== undefined,
340
+ `UNNEST of map column '${fromColumn}' requires exactly two alias columns (key, value)`,
341
+ );
342
+ const addlProps = (sourceSchema as SchemaObject)['additionalProperties'] as unknown;
343
+ const valueSchema: SchemaObject =
344
+ typeof addlProps === 'object' && addlProps !== null ? addlProps : { type: 'string' };
345
+ columns.set(keyColumn, [resolvedCol(keyColumn, { type: 'string' }, sourceColumns[0]?.ast)]);
346
+ columns.set(valueColumn, [resolvedCol(valueColumn, valueSchema, sourceColumns[0]?.ast)]);
347
+ } else {
348
+ throw new AthenaError(
349
+ ATHENA_ERROR,
350
+ `UNNEST source column '${fromColumn}' must resolve to an array or map schema`,
351
+ ast,
352
+ );
300
353
  }
301
- columns.set(toColumn, [resolvedCol(toColumn, sourceSchema.items, sourceColumns[0]?.ast)]);
302
354
  }
303
355
  }
304
356
 
@@ -502,22 +554,6 @@ function resolveSingleColumnRef(
502
554
  );
503
555
  }
504
556
 
505
- /** Return true when the column expression is a CAST / TRY_CAST to ARRAY<…>. */
506
- function isCastToArray(node: unknown): boolean {
507
- if (typeof node !== 'object' || node === null) {
508
- return false;
509
- }
510
- const typed = node as Record<string, unknown>;
511
- if (typed['type'] === 'cast') {
512
- const target = (typed['target'] as { dataType?: string }[] | undefined)?.[0];
513
- return target?.dataType === 'ARRAY';
514
- }
515
- if (typed['type'] === 'expr') {
516
- return isCastToArray(typed['expr']);
517
- }
518
- return false;
519
- }
520
-
521
557
  function resolveSelectColumns(select: Select, ctx: VisitContext): Map<string, ResolvedColumn[]> {
522
558
  const allTables = [...ctx.tables.values()].flat();
523
559
  const columns = new Map<string, ResolvedColumn[]>();
@@ -544,7 +580,7 @@ function resolveSelectColumns(select: Select, ctx: VisitContext): Map<string, Re
544
580
  // the inner expression (e.g. json_parse) has no schema-aware path to navigate.
545
581
  // Skip when the inner expression already resolved to an array (e.g. json_extract on an
546
582
  // array-typed property): overriding would strip the items schema and break UNNEST typing.
547
- if (isCastToArray(columnAST)) {
583
+ if (containsCastToArray(columnAST)) {
548
584
  const colName = columnAlias ?? indexedName;
549
585
  const existing = columns.get(colName);
550
586
  if (existing !== undefined && existing[0]?.schema.type !== 'array') {
@@ -554,6 +590,20 @@ function resolveSelectColumns(select: Select, ctx: VisitContext): Map<string, Re
554
590
  );
555
591
  }
556
592
  }
593
+
594
+ // Same for CAST/TRY_CAST to MAP<…>: honour the declared map type when the inner
595
+ // expression (e.g. split_to_map) has no schema-aware navigation available.
596
+ // Skip when the schema is already an object to preserve additionalProperties.
597
+ if (containsCastToMap(columnAST)) {
598
+ const colName = columnAlias ?? indexedName;
599
+ const existing = columns.get(colName);
600
+ if (existing !== undefined && existing[0]?.schema.type !== 'object') {
601
+ columns.set(
602
+ colName,
603
+ existing.map((col) => resolvedCol(col.name, { type: 'object' }, col.ast)),
604
+ );
605
+ }
606
+ }
557
607
  }
558
608
 
559
609
  return columns;
@@ -382,3 +382,31 @@ export function hasFunctionCalls(expr: unknown): boolean {
382
382
  });
383
383
  return found;
384
384
  }
385
+
386
+ /** Return true when the expression tree contains any CAST / TRY_CAST to ARRAY<…>. */
387
+ export function containsCastToArray(expr: unknown): boolean {
388
+ let found = false;
389
+ walkExpr(expr, {
390
+ visitCast(node) {
391
+ const target = (node as unknown as { target?: { dataType?: string }[] }).target?.[0];
392
+ if (target?.dataType === 'ARRAY') {
393
+ found = true;
394
+ }
395
+ },
396
+ });
397
+ return found;
398
+ }
399
+
400
+ /** Return true when the expression tree contains any CAST / TRY_CAST to MAP<…>. */
401
+ export function containsCastToMap(expr: unknown): boolean {
402
+ let found = false;
403
+ walkExpr(expr, {
404
+ visitCast(node) {
405
+ const target = (node as unknown as { target?: { dataType?: string }[] }).target?.[0];
406
+ if (target?.dataType === 'MAP') {
407
+ found = true;
408
+ }
409
+ },
410
+ });
411
+ return found;
412
+ }
@@ -1,6 +1,5 @@
1
1
  // openapi/service-schema-generator.ts
2
2
 
3
- import { execFileSync } from 'node:child_process';
4
3
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
5
4
 
6
5
  import debug from 'debug';
@@ -53,18 +52,6 @@ function derefApiSchemas(schemas: ApiSchemas): ApiSchemas {
53
52
  return { apis: resolvedApis };
54
53
  }
55
54
 
56
- function fetchUrlSync(url: string): string | null {
57
- try {
58
- return execFileSync(process.execPath, ['--input-type=module'], {
59
- input: `const r=await fetch(${JSON.stringify(url)});if(!r.ok)process.exit(1);process.stdout.write(await r.text());`,
60
- encoding: 'utf-8',
61
- timeout: 15_000,
62
- });
63
- } catch {
64
- return null;
65
- }
66
- }
67
-
68
55
  function readServiceConfig(
69
56
  packageJsonContent: string,
70
57
  org: string,
@@ -105,73 +92,33 @@ function findServiceLocally(serviceFolder: string, org: string, serviceName: str
105
92
  }
106
93
 
107
94
  function findServiceInProject(serviceName: string): ServiceSource | null {
108
- const packageJsonString = readFileSync(`./package.json`, 'utf-8');
109
- const packageJson = JSON.parse(packageJsonString) as unknown as { name: string };
110
- const [org, projectName] = packageJson.name.slice(1).split('/');
111
- if (org === undefined) {
95
+ const packageJson = JSON.parse(readFileSync('./package.json', 'utf-8')) as { name?: string };
96
+ const [org, projectName] = (packageJson.name ?? '').slice(1).split('/');
97
+ if (org === undefined || projectName !== serviceName) {
112
98
  return null;
113
99
  }
114
-
115
- if (projectName === serviceName) {
116
- log('service is the current project, looking for API schemas locally', serviceName);
117
- const serviceSource = findServiceLocally('.', org, serviceName);
118
- if (serviceSource !== null) {
119
- return serviceSource;
120
- }
121
- }
122
-
123
- return null;
100
+ log(`[schema-generator] '${serviceName}' is the current project, reading local swagger files`);
101
+ return findServiceLocally('.', org, serviceName);
124
102
  }
125
103
 
126
104
  function findServiceInNodeModules(serviceName: string): ServiceSource | null {
127
105
  for (const org of GITHUB_ORGANIZATIONS) {
128
106
  const serviceFolder = `node_modules/@${org}/${serviceName}`;
129
107
  if (!existsSync(serviceFolder)) {
108
+ log(`[schema-generator] not found in node_modules: @${org}/${serviceName}`);
130
109
  continue;
131
110
  }
132
-
133
- try {
134
- const serviceSource = findServiceLocally(serviceFolder, org, serviceName);
135
- if (serviceSource !== null) {
136
- return serviceSource;
137
- }
138
- } catch {
139
- // continue to next org
140
- }
141
- }
142
- return null;
143
- }
144
-
145
- function findServiceOnGitHub(serviceName: string): ServiceSource | null {
146
- for (const org of GITHUB_ORGANIZATIONS) {
147
- const pkgUrl = `https://raw.githubusercontent.com/${org}/${serviceName}/main/package.json`;
148
- log(`fetching package.json from ${pkgUrl}`);
149
- const pkgContent = fetchUrlSync(pkgUrl);
150
- if (pkgContent === null) {
151
- continue;
152
- }
153
-
154
111
  try {
155
- const config = readServiceConfig(pkgContent, org, serviceName);
156
- if (config === null) {
157
- continue;
158
- }
159
-
160
- const endpoints: ServiceEndpoint[] = [];
161
- for (const endpoint of config.endpoints) {
162
- const swaggerUrl = `https://raw.githubusercontent.com/${org}/${serviceName}/main/${config.apiRoot}/${endpoint}/swagger.yml`;
163
- log(`fetching swagger.yml from ${swaggerUrl}`);
164
- const yamlContent = fetchUrlSync(swaggerUrl);
165
- if (yamlContent !== null) {
166
- endpoints.push({ path: endpoint, yamlContent });
167
- }
112
+ log(`[schema-generator] found in node_modules: @${org}/${serviceName}, reading swagger files`);
113
+ const source = findServiceLocally(serviceFolder, org, serviceName);
114
+ if (source !== null) {
115
+ return source;
168
116
  }
169
-
170
- if (endpoints.length > 0) {
171
- return { organization: config.organization, serviceName: config.serviceName, endpoints };
172
- }
173
- } catch {
174
- // continue to next org
117
+ log(`[schema-generator] no swagger schema inside node_modules/@${org}/${serviceName}`);
118
+ } catch (error) {
119
+ log(
120
+ `[schema-generator] error reading node_modules/@${org}/${serviceName}: ${error instanceof Error ? error.message : String(error)}`,
121
+ );
175
122
  }
176
123
  }
177
124
  return null;
@@ -181,15 +128,18 @@ export function generateSchemasForService(
181
128
  serviceName: string,
182
129
  outputDir?: string,
183
130
  ): { schema: ApiSchemas; endpoint: string }[] {
184
- log('generating schemas for service', serviceName);
131
+ log(`[schema-generator] locating service '${serviceName}'`);
185
132
 
186
- const source =
187
- findServiceInProject(serviceName) ?? findServiceInNodeModules(serviceName) ?? findServiceOnGitHub(serviceName);
133
+ const source = findServiceInProject(serviceName) ?? findServiceInNodeModules(serviceName);
188
134
  if (source === null) {
189
- log('no swagger source found for service', serviceName);
135
+ log(
136
+ `[schema-generator] '${serviceName}' not found — ensure it is listed as a devDependency or the repo is accessible via git`,
137
+ );
190
138
  return [];
191
139
  }
192
140
 
141
+ log(`[schema-generator] found '${serviceName}' (${source.endpoints.length.toString()} endpoint(s))`);
142
+
193
143
  const results: { schema: ApiSchemas; endpoint: string }[] = [];
194
144
  for (const { path: endpoint, yamlContent } of source.endpoints) {
195
145
  try {
@@ -205,10 +155,12 @@ export function generateSchemasForService(
205
155
  const dir = `${outputDir}/${versionFolder}`;
206
156
  mkdirSync(dir, { recursive: true });
207
157
  writeFileSync(`${dir}/${SWAGGER_SCHEMA_DEREF_FILENAME}`, JSON.stringify(schema, undefined, 2));
208
- log(`cached schema to ${dir}/${SWAGGER_SCHEMA_DEREF_FILENAME}`);
158
+ log(`[schema-generator] cached schema to ${dir}/${SWAGGER_SCHEMA_DEREF_FILENAME}`);
209
159
  }
210
160
  } catch (error) {
211
- log('error generating schema for endpoint', endpoint, error);
161
+ log(
162
+ `[schema-generator] error processing endpoint ${endpoint}: ${error instanceof Error ? error.message : String(error)}`,
163
+ );
212
164
  }
213
165
  }
214
166
 
@@ -5,7 +5,7 @@
5
5
  "put": {
6
6
  "request": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
8
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/api/InterchangePutRequestContext",
8
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/api/InterchangePutRequestContext",
9
9
  "type": "object",
10
10
  "properties": {
11
11
  "params": {
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "body": {
33
33
  "$schema": "https://json-schema.org/draft/2020-12/schema",
34
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Interchange",
34
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Interchange",
35
35
  "type": "object",
36
36
  "additionalProperties": false,
37
37
  "description": "Data that describes an interchange record.",
@@ -281,7 +281,7 @@
281
281
  "allOf": [
282
282
  {
283
283
  "$schema": "https://json-schema.org/draft/2020-12/schema",
284
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Amount",
284
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Amount",
285
285
  "type": "object",
286
286
  "additionalProperties": false,
287
287
  "required": ["amount", "currency"],
@@ -308,7 +308,7 @@
308
308
  "allOf": [
309
309
  {
310
310
  "$schema": "https://json-schema.org/draft/2020-12/schema",
311
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Amount",
311
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Amount",
312
312
  "type": "object",
313
313
  "additionalProperties": false,
314
314
  "required": ["amount", "currency"],
@@ -354,7 +354,7 @@
354
354
  "responses": {
355
355
  "204": {
356
356
  "$schema": "https://json-schema.org/draft/2020-12/schema",
357
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/api/InterchangePutResponseNoContent",
357
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/api/InterchangePutResponseNoContent",
358
358
  "type": "object",
359
359
  "properties": {
360
360
  "headers": {
@@ -368,15 +368,16 @@
368
368
  "type": "string",
369
369
  "format": "date-time"
370
370
  }
371
- }
371
+ },
372
+ "required": ["created-on", "updated-on"]
372
373
  }
373
374
  },
374
- "required": [],
375
+ "required": ["headers"],
375
376
  "additionalProperties": false
376
377
  },
377
378
  "default": {
378
379
  "$schema": "https://json-schema.org/draft/2020-12/schema",
379
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/api/InterchangePutResponseDefault",
380
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/api/InterchangePutResponseDefault",
380
381
  "type": "object",
381
382
  "properties": {
382
383
  "headers": {
@@ -385,7 +386,7 @@
385
386
  },
386
387
  "body": {
387
388
  "$schema": "https://json-schema.org/draft/2020-12/schema",
388
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Error",
389
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Error",
389
390
  "type": "object",
390
391
  "additionalProperties": false,
391
392
  "properties": {
@@ -410,7 +411,7 @@
410
411
  "definitions": {
411
412
  "Ping": {
412
413
  "$schema": "https://json-schema.org/draft/2020-12/schema",
413
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Ping",
414
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Ping",
414
415
  "type": "object",
415
416
  "additionalProperties": false,
416
417
  "required": ["serverTime"],
@@ -424,7 +425,7 @@
424
425
  },
425
426
  "Error": {
426
427
  "$schema": "https://json-schema.org/draft/2020-12/schema",
427
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Error",
428
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Error",
428
429
  "type": "object",
429
430
  "additionalProperties": false,
430
431
  "properties": {
@@ -440,7 +441,7 @@
440
441
  },
441
442
  "Interchange": {
442
443
  "$schema": "https://json-schema.org/draft/2020-12/schema",
443
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Interchange",
444
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Interchange",
444
445
  "type": "object",
445
446
  "additionalProperties": false,
446
447
  "description": "Data that describes an interchange record.",
@@ -690,7 +691,7 @@
690
691
  "allOf": [
691
692
  {
692
693
  "$schema": "https://json-schema.org/draft/2020-12/schema",
693
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Amount",
694
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Amount",
694
695
  "type": "object",
695
696
  "additionalProperties": false,
696
697
  "required": ["amount", "currency"],
@@ -717,7 +718,7 @@
717
718
  "allOf": [
718
719
  {
719
720
  "$schema": "https://json-schema.org/draft/2020-12/schema",
720
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Amount",
721
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Amount",
721
722
  "type": "object",
722
723
  "additionalProperties": false,
723
724
  "required": ["amount", "currency"],
@@ -758,7 +759,7 @@
758
759
  },
759
760
  "Amount": {
760
761
  "$schema": "https://json-schema.org/draft/2020-12/schema",
761
- "$id": "https://eslint-plugin.checkdigit/interchange/v1/schemas/definitions/Amount",
762
+ "$id": "https://interchange.checkdigit/interchange/v1/schemas/definitions/Amount",
762
763
  "type": "object",
763
764
  "additionalProperties": false,
764
765
  "required": ["amount", "currency"],