@atolis-hq/corum 0.1.14 → 0.1.15

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.
@@ -229,18 +229,16 @@ function extractParameters(pathItem, operation, packConfig, specPath, diagnostic
229
229
  if (!schema)
230
230
  continue;
231
231
  let type;
232
- let cardinality;
232
+ let collection;
233
233
  if (schema.type === 'array') {
234
- cardinality = 'many';
234
+ collection = 'array';
235
235
  const items = schema.items;
236
236
  type = deriveScalarType(items?.type ?? 'string', items?.format, packConfig.scalarTypes) ?? 'string';
237
237
  }
238
238
  else if (schema.enum) {
239
- cardinality = 'one';
240
239
  type = 'string';
241
240
  }
242
241
  else {
243
- cardinality = 'one';
244
242
  const derived = deriveScalarType(schema.type ?? 'string', schema.format, packConfig.scalarTypes);
245
243
  if (!derived) {
246
244
  diagnostics.push({ severity: 'warning', file: specPath, message: `Unknown type for parameter ${name}: ${schema.type}/${schema.format}, defaulting to string` });
@@ -254,7 +252,7 @@ function extractParameters(pathItem, operation, packConfig, specPath, diagnostic
254
252
  location: param.in,
255
253
  type,
256
254
  required: param.required ?? false,
257
- cardinality,
255
+ ...(collection ? { collection } : {}),
258
256
  };
259
257
  }
260
258
  return Object.keys(parameters).length > 0 ? parameters : undefined;
@@ -308,10 +306,10 @@ function createInlineSchema(schema, name, parentId, section, rootId, packConfig,
308
306
  emitFields(schema, schemaId, 'fields', rootId, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
309
307
  return localRef;
310
308
  }
311
- function resolveFieldRef(schemaName, cardinality, keyed, required, rootId, readsSource, refSchema, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas) {
312
- const extra = { nullable: !required, cardinality };
313
- if (keyed)
314
- extra.keyed = true;
309
+ function resolveFieldRef(schemaName, collection, required, rootId, readsSource, refSchema, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas) {
310
+ const extra = { nullable: !required };
311
+ if (collection !== 'one')
312
+ extra.collection = collection;
315
313
  const globalId = sharedSchemas.get(schemaName);
316
314
  if (globalId) {
317
315
  emitReadsEdge(readsSource, globalId, edges);
@@ -336,26 +334,26 @@ function emitFields(schema, parentId, section, rootId, packConfig, specPath, nod
336
334
  const fieldNode = makeNode(packConfig.constructs.schemaProperty?.template ?? 'Field', component, specPath, fieldId);
337
335
  const required = Array.isArray(schema.required) && schema.required.includes(fieldName);
338
336
  if (isRefSchema(fieldSchema)) {
339
- fieldNode.properties = resolveFieldRef(refName(fieldSchema.$ref), 'one', false, required, rootId, readsSource, fieldSchema, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
337
+ fieldNode.properties = resolveFieldRef(refName(fieldSchema.$ref), 'one', required, rootId, readsSource, fieldSchema, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
340
338
  }
341
339
  else {
342
340
  const fs = fieldSchema;
343
341
  if (fs.enum && fs.type !== 'object') {
344
342
  const enumRef = sharedSchemas.get(fieldName);
345
- fieldNode.properties = { ...(enumRef ? { $ref: enumRef } : { type: 'string' }), nullable: !required, cardinality: 'one' };
343
+ fieldNode.properties = { ...(enumRef ? { $ref: enumRef } : { type: 'string' }), nullable: !required };
346
344
  }
347
345
  else if (fs.type === 'array') {
348
346
  const rawItems = fs.items;
349
347
  const items = rawItems ? resolveAllOfRef(rawItems) : undefined;
350
348
  if (!items) {
351
- fieldNode.properties = { type: 'string', nullable: !required, cardinality: 'many' };
349
+ fieldNode.properties = { type: 'string', nullable: !required, collection: 'array' };
352
350
  }
353
351
  else if (isRefSchema(items)) {
354
- fieldNode.properties = resolveFieldRef(refName(items.$ref), 'many', false, required, rootId, readsSource, items, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
352
+ fieldNode.properties = resolveFieldRef(refName(items.$ref), 'array', required, rootId, readsSource, items, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
355
353
  }
356
354
  else {
357
355
  const itemType = deriveScalarType(items.type ?? 'string', items.format, packConfig.scalarTypes);
358
- fieldNode.properties = { type: itemType ?? 'string', nullable: !required, cardinality: 'many' };
356
+ fieldNode.properties = { type: itemType ?? 'string', nullable: !required, collection: 'array' };
359
357
  }
360
358
  }
361
359
  else if (fs.type === 'object' && fs.properties) {
@@ -363,34 +361,64 @@ function emitFields(schema, parentId, section, rootId, packConfig, specPath, nod
363
361
  if (rootId) {
364
362
  const localRef = emitSchemaNode(fs, fieldName, rootId, 'schemas', rootId, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
365
363
  fieldNode.properties = localRef
366
- ? { $ref: localRef, nullable: !required, cardinality: 'one' }
367
- : { type: 'string', nullable: !required, cardinality: 'one' };
364
+ ? { $ref: localRef, nullable: !required }
365
+ : { type: 'string', nullable: !required };
368
366
  }
369
367
  else {
370
368
  diagnostics.push({ severity: 'warning', file: specPath, message: `Inline object for field ${fieldId} has no endpoint context; treating as string` });
371
- fieldNode.properties = { type: 'string', nullable: !required, cardinality: 'one' };
369
+ fieldNode.properties = { type: 'string', nullable: !required };
372
370
  }
373
371
  }
374
372
  else if (fs.type === 'object' && fs.additionalProperties) {
375
373
  // Map/dictionary: keyed collection
376
374
  const addlRaw = fs.additionalProperties;
377
375
  if (typeof addlRaw === 'boolean') {
378
- fieldNode.properties = { type: 'string', nullable: !required, cardinality: 'many', keyed: true };
376
+ fieldNode.properties = { type: 'string', nullable: !required, collection: 'map' };
379
377
  }
380
378
  else {
381
379
  const addlSchema = resolveAllOfRef(addlRaw);
382
380
  if (isRefSchema(addlSchema)) {
383
- fieldNode.properties = resolveFieldRef(refName(addlSchema.$ref), 'many', true, required, rootId, readsSource, addlSchema, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
381
+ fieldNode.properties = resolveFieldRef(refName(addlSchema.$ref), 'map', required, rootId, readsSource, addlSchema, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
384
382
  }
385
383
  else {
386
384
  const addlObj = addlSchema;
387
385
  if (addlObj.type === 'object') {
388
- diagnostics.push({ severity: 'warning', file: specPath, message: `Double-nested map for field ${fieldId}; value type represented as string` });
389
- fieldNode.properties = { type: 'string', nullable: !required, cardinality: 'many', keyed: true };
386
+ const innerAddl = addlObj.additionalProperties;
387
+ if (!innerAddl || typeof innerAddl === 'boolean') {
388
+ fieldNode.properties = { type: 'string', nullable: !required, collection: 'map-of-map' };
389
+ }
390
+ else {
391
+ const innerSchema = resolveAllOfRef(innerAddl);
392
+ if (isRefSchema(innerSchema)) {
393
+ fieldNode.properties = resolveFieldRef(refName(innerSchema.$ref), 'map-of-map', required, rootId, readsSource, innerSchema, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
394
+ }
395
+ else {
396
+ const inner = innerSchema;
397
+ const scalarType = deriveScalarType(inner.type ?? 'string', inner.format, packConfig.scalarTypes);
398
+ if (scalarType) {
399
+ fieldNode.properties = { type: scalarType, nullable: !required, collection: 'map-of-map' };
400
+ }
401
+ else {
402
+ diagnostics.push({ severity: 'warning', file: specPath, message: `[WARN] Double-nested map for field ${fieldId}; inner value type not representable, using string` });
403
+ fieldNode.properties = { type: 'string', nullable: !required, collection: 'map-of-map' };
404
+ }
405
+ }
406
+ }
407
+ }
408
+ else if (addlObj.type === 'array') {
409
+ const rawItems = addlObj.items;
410
+ const items = rawItems ? resolveAllOfRef(rawItems) : undefined;
411
+ if (items && isRefSchema(items)) {
412
+ fieldNode.properties = resolveFieldRef(refName(items.$ref), 'map-of-array', required, rootId, readsSource, items, packConfig, specPath, nodes, edges, diagnostics, sharedSchemas, sourceSchemas, localSchemas);
413
+ }
414
+ else {
415
+ const scalarType = items ? deriveScalarType(items.type ?? 'string', items.format, packConfig.scalarTypes) : undefined;
416
+ fieldNode.properties = { type: scalarType ?? 'string', nullable: !required, collection: 'map-of-array' };
417
+ }
390
418
  }
391
419
  else {
392
420
  const scalarType = deriveScalarType(addlObj.type ?? 'string', addlObj.format, packConfig.scalarTypes);
393
- fieldNode.properties = { type: scalarType ?? 'string', nullable: !required, cardinality: 'many', keyed: true };
421
+ fieldNode.properties = { type: scalarType ?? 'string', nullable: !required, collection: 'map' };
394
422
  }
395
423
  }
396
424
  }
@@ -398,11 +426,11 @@ function emitFields(schema, parentId, section, rootId, packConfig, specPath, nod
398
426
  else {
399
427
  const scalarType = deriveScalarType(fs.type ?? 'string', fs.format, packConfig.scalarTypes);
400
428
  if (scalarType) {
401
- fieldNode.properties = { type: scalarType, nullable: !required, cardinality: 'one' };
429
+ fieldNode.properties = { type: scalarType, nullable: !required };
402
430
  }
403
431
  else {
404
432
  diagnostics.push({ severity: 'warning', file: specPath, message: `Unknown type for field ${fieldId}: ${fs.type}/${fs.format}` });
405
- fieldNode.properties = { type: 'string', nullable: !required, cardinality: 'one' };
433
+ fieldNode.properties = { type: 'string', nullable: !required };
406
434
  }
407
435
  }
408
436
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atolis-hq/corum",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -212,9 +212,8 @@ function refLocalSchemaName(ref) {
212
212
  }
213
213
 
214
214
  function fieldType(properties) {
215
- const suffix = properties?.cardinality === 'many'
216
- ? (properties?.keyed ? '{}' : '[]')
217
- : '';
215
+ const c = properties?.collection;
216
+ const suffix = c === 'array' ? '[]' : c === 'map' ? '{}' : c === 'map-of-map' ? '{{}}' : c === 'map-of-array' ? '{[]}' : '';
218
217
  if (properties?.type) return `${properties.type}${suffix}`;
219
218
  const ref = properties?.['$ref'];
220
219
  if (ref) return `${refName(ref)}${suffix}`;
@@ -228,7 +227,7 @@ function fieldRequirement(properties) {
228
227
  }
229
228
 
230
229
  function fieldCardinality(properties) {
231
- return properties?.cardinality ?? '-';
230
+ return properties?.collection ?? 'one';
232
231
  }
233
232
 
234
233
  function fieldDetails(properties) {
@@ -336,7 +335,8 @@ function SchemaFieldRows({ schemaName, model, prefix = '', depth = 0, visited =
336
335
  const canExpand = localRef !== null && model.schemasByName.has(localRef) && !visited.has(localRef);
337
336
  const childSchemaNode = canExpand ? model.schemasByName.get(localRef) : null;
338
337
  const childGhostFields = childSchemaNode ? overlayFieldsForSchema(overlayFields, childSchemaNode.id) : [];
339
- const childPrefix = `${prefix}${name}${field.properties?.cardinality === 'many' ? '[].' : '.'}`;
338
+ const c = field.properties?.collection;
339
+ const childPrefix = `${prefix}${name}${c === 'map-of-map' || c === 'map-of-array' ? '[][].' : c === 'array' || c === 'map' ? '[].' : '.'}`;
340
340
  const nextVisited = new Set(visited);
341
341
  nextVisited.add(schemaName);
342
342
  const links = edges.filter(e =>
@@ -552,7 +552,7 @@ function SchemaCard({ title, nodes, allNodes, edges, anchorIdForNode, overlayFie
552
552
  <div />
553
553
  <div className="label-xs">Name</div>
554
554
  <div className="label-xs">Type</div>
555
- <div className="label-xs">Cardinality</div>
555
+ <div className="label-xs">Collection</div>
556
556
  <div className="label-xs">Req</div>
557
557
  <div className="label-xs">State</div>
558
558
  <div className="label-xs">Links</div>