@emeryld/rrroutes-contract 2.2.3 → 2.2.4

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
@@ -562,6 +562,21 @@ body {
562
562
  box-shadow: 0 10px 30px -10px rgba(0,0,0,0.5);
563
563
  }
564
564
 
565
+ .schema-indent {
566
+ display: inline-block;
567
+ }
568
+
569
+ .schema-branch {
570
+ opacity: 0.6;
571
+ font-family: var(--font-mono);
572
+ margin-right: 2px;
573
+ }
574
+
575
+ .schema-meta code {
576
+ font-family: var(--font-mono);
577
+ font-size: 11px;
578
+ }
579
+
565
580
  /* Top Row: Filters */
566
581
  .filters-row {
567
582
  display: flex;
@@ -1187,30 +1202,211 @@ var DOCS_JS = `
1187
1202
  );
1188
1203
  }
1189
1204
 
1190
- function renderSchemaTable(node, title) {
1191
- let rows = '';
1192
- if (node.kind === 'object' && node.properties) {
1193
- Object.keys(node.properties).forEach(function(key) {
1194
- const prop = node.properties[key];
1195
- const reqClass = prop.optional ? 'req-false' : 'req-true';
1196
- const reqText = prop.optional ? 'OPT' : 'REQ';
1197
- rows +=
1198
- '<tr>' +
1199
- '<td class="col-name">' + escapeHtml(key) + '</td>' +
1200
- '<td class="col-type">' + escapeHtml(getTypeLabel(prop)) + '</td>' +
1201
- '<td><span class="req-badge ' + reqClass + '">' + reqText + '</span></td>' +
1202
- '<td>' + escapeHtml(prop.description || '') + '</td>' +
1203
- '</tr>';
1204
- });
1205
- } else {
1206
- rows = '<tr><td colspan="4">Type: ' + escapeHtml(getTypeLabel(node)) + '</td></tr>';
1205
+
1206
+ function renderSchemaTable(node, title) {
1207
+ let rows = '';
1208
+
1209
+ if (node.kind === 'object' && node.properties) {
1210
+ rows = renderObjectChildren(node, 0);
1211
+ } else {
1212
+ rows = renderNodeRow('(root)', node, 0);
1213
+ }
1214
+
1215
+ return (
1216
+ (title
1217
+ ? '<div class="schema-subtitle">' + escapeHtml(title) + '</div>'
1218
+ : '') +
1219
+ '<table class="schema-table">' +
1220
+ rows +
1221
+ '</table>'
1222
+ );
1223
+ }
1224
+
1225
+ /**
1226
+ * Render all children of an object node (at a given depth).
1227
+ */
1228
+ function renderObjectChildren(node, depth) {
1229
+ if (!node.properties) return '';
1230
+
1231
+ let rows = '';
1232
+ Object.keys(node.properties).forEach(function (key) {
1233
+ rows += renderNodeRow(key, node.properties[key], depth);
1234
+ });
1235
+ return rows;
1236
+ }
1237
+
1238
+ /**
1239
+ * Render a single row for a property / node, then recursively render nested structure.
1240
+ */
1241
+ function renderNodeRow(name, node, depth) {
1242
+ const reqClass = node.optional ? 'req-false' : 'req-true';
1243
+ const reqText = node.optional ? 'OPT' : 'REQ';
1244
+
1245
+ const indentPx = depth * 16;
1246
+ const nameCell =
1247
+ '<span class="schema-indent" style="padding-left:' +
1248
+ indentPx +
1249
+ 'px;"></span>' +
1250
+ (depth > 0 ? '<span class="schema-branch">\u2514\u2500 </span>' : '') +
1251
+ escapeHtml(name);
1252
+
1253
+ const typeLabel = getTypeLabel(node);
1254
+ const descriptionHtml = renderNodeDescription(node);
1255
+
1256
+ let rows =
1257
+ '<tr>' +
1258
+ '<td class="col-name">' + nameCell + '</td>' +
1259
+ '<td class="col-type">' + escapeHtml(typeLabel) + '</td>' +
1260
+ '<td><span class="req-badge ' + reqClass + '">' + reqText + '</span></td>' +
1261
+ '<td>' + descriptionHtml + '</td>' +
1262
+ '</tr>';
1263
+
1264
+ // 1) Object properties
1265
+ if (node.kind === 'object' && node.properties) {
1266
+ rows += renderObjectChildren(node, depth + 1);
1267
+ }
1268
+
1269
+ // 2) Array element type
1270
+ if (node.kind === 'array' && node.element) {
1271
+ const element = node.element;
1272
+ if (isComplexNode(element)) {
1273
+ rows += renderNodeRow('[items]', element, depth + 1);
1207
1274
  }
1208
- return (
1209
- (title ? '<div class="schema-subtitle">' + escapeHtml(title) + '</div>' : '') +
1210
- '<table class="schema-table">' + rows + '</table>'
1275
+ }
1276
+
1277
+ // 3) Union variants
1278
+ if (node.kind === 'union' && Array.isArray(node.union)) {
1279
+ node.union.forEach(function (variant, index) {
1280
+ rows += renderNodeRow('option ' + (index + 1), variant, depth + 1);
1281
+ });
1282
+ }
1283
+
1284
+ return rows;
1285
+ }
1286
+
1287
+ /**
1288
+ * Decide if a node is \u201Ccomplex\u201D enough to warrant a nested expansion row.
1289
+ */
1290
+ function isComplexNode(node) {
1291
+ return (
1292
+ node.kind === 'object' ||
1293
+ node.kind === 'array' ||
1294
+ node.kind === 'union' ||
1295
+ node.kind === 'record' ||
1296
+ node.kind === 'tuple'
1297
+ );
1298
+ }
1299
+
1300
+ /**
1301
+ * Helper: simple vs complex node, for compact type labels.
1302
+ */
1303
+ function isSimpleNode(node) {
1304
+ return !isComplexNode(node);
1305
+ }
1306
+
1307
+ /**
1308
+ * Type label shown in the "Type" column.
1309
+ */
1310
+ function getTypeLabel(node) {
1311
+ let base;
1312
+
1313
+ switch (node.kind) {
1314
+ case 'object':
1315
+ base = 'object';
1316
+ break;
1317
+
1318
+ case 'array':
1319
+ if (!node.element) {
1320
+ base = 'array';
1321
+ } else if (isSimpleNode(node.element)) {
1322
+ base = 'array<' + getTypeLabel(node.element) + '>';
1323
+ } else {
1324
+ base = 'array<object>';
1325
+ }
1326
+ break;
1327
+
1328
+ case 'union':
1329
+ if (node.union && node.union.length) {
1330
+ const parts = node.union.map(function (u) {
1331
+ return isSimpleNode(u) ? getTypeLabel(u) : 'object';
1332
+ });
1333
+ base = parts.join(' | ');
1334
+ } else {
1335
+ base = 'union';
1336
+ }
1337
+ break;
1338
+
1339
+ case 'literal':
1340
+ base = 'literal';
1341
+ break;
1342
+
1343
+ case 'enum':
1344
+ base = 'enum';
1345
+ break;
1346
+
1347
+ case 'record':
1348
+ base = 'record';
1349
+ break;
1350
+
1351
+ case 'tuple':
1352
+ base = 'tuple';
1353
+ break;
1354
+
1355
+ default:
1356
+ base = node.kind || 'unknown';
1357
+ break;
1358
+ }
1359
+
1360
+ if (node.nullable) {
1361
+ base = base + ' | null';
1362
+ }
1363
+ return base;
1364
+ }
1365
+
1366
+ /**
1367
+ * Description cell content:
1368
+ * - main description text
1369
+ * - for enum: allowed values
1370
+ * - for literal: literal value
1371
+ */
1372
+ function renderNodeDescription(node) {
1373
+ const parts = [];
1374
+
1375
+ if (node.description) {
1376
+ parts.push(escapeHtml(node.description));
1377
+ }
1378
+
1379
+ if (node.kind === 'enum' && node.enumValues && node.enumValues.length) {
1380
+ const values = node.enumValues
1381
+ .map(function (v) {
1382
+ return '<code>' + escapeHtml(String(v)) + '</code>';
1383
+ })
1384
+ .join(' | ');
1385
+ parts.push('<div class="schema-meta">Allowed: ' + values + '</div>');
1386
+ }
1387
+
1388
+ if (node.kind === 'literal' && typeof node.literal !== 'undefined') {
1389
+ const valueStr = escapeHtml(JSON.stringify(node.literal));
1390
+ parts.push(
1391
+ '<div class="schema-meta">Literal: <code>' + valueStr + '</code></div>'
1211
1392
  );
1212
1393
  }
1213
1394
 
1395
+ return parts.join('<br>');
1396
+ }
1397
+
1398
+ /**
1399
+ * Escape HTML helper.
1400
+ */
1401
+ function escapeHtml(str) {
1402
+ return String(str)
1403
+ .replace(/&/g, '&amp;')
1404
+ .replace(/</g, '&lt;')
1405
+ .replace(/>/g, '&gt;')
1406
+ .replace(/"/g, '&quot;')
1407
+ .replace(/'/g, '&#39;');
1408
+ }
1409
+
1214
1410
  function getTypeLabel(node) {
1215
1411
  if (!node) return 'any';
1216
1412
  if (node.kind === 'array') return getTypeLabel(node.element) + '[]';