@voxgig/apidef 2.4.1 → 3.0.2

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 (96) hide show
  1. package/dist/apidef.d.ts +5 -1
  2. package/dist/apidef.js +197 -112
  3. package/dist/apidef.js.map +1 -1
  4. package/dist/builder/entity/entity.d.ts +3 -0
  5. package/dist/builder/entity/{apiEntity.js → entity.js} +12 -9
  6. package/dist/builder/entity/entity.js.map +1 -0
  7. package/dist/builder/entity/info.d.ts +3 -0
  8. package/dist/builder/entity/info.js +22 -0
  9. package/dist/builder/entity/info.js.map +1 -0
  10. package/dist/builder/entity.js +7 -21
  11. package/dist/builder/entity.js.map +1 -1
  12. package/dist/builder/flow/flowHeuristic01.js +21 -11
  13. package/dist/builder/flow/flowHeuristic01.js.map +1 -1
  14. package/dist/builder/flow.d.ts +2 -1
  15. package/dist/builder/flow.js +29 -4
  16. package/dist/builder/flow.js.map +1 -1
  17. package/dist/def.d.ts +62 -0
  18. package/dist/def.js +4 -0
  19. package/dist/def.js.map +1 -0
  20. package/dist/desc.d.ts +89 -0
  21. package/dist/desc.js +4 -0
  22. package/dist/desc.js.map +1 -0
  23. package/dist/guide/guide.d.ts +2 -1
  24. package/dist/guide/guide.js +161 -30
  25. package/dist/guide/guide.js.map +1 -1
  26. package/dist/guide/heuristic01.d.ts +2 -1
  27. package/dist/guide/heuristic01.js +1120 -234
  28. package/dist/guide/heuristic01.js.map +1 -1
  29. package/dist/model.d.ts +55 -0
  30. package/dist/model.js +4 -0
  31. package/dist/model.js.map +1 -0
  32. package/dist/parse.d.ts +1 -2
  33. package/dist/parse.js +8 -47
  34. package/dist/parse.js.map +1 -1
  35. package/dist/transform/args.d.ts +3 -0
  36. package/dist/transform/args.js +58 -0
  37. package/dist/transform/args.js.map +1 -0
  38. package/dist/transform/clean.js +27 -3
  39. package/dist/transform/clean.js.map +1 -1
  40. package/dist/transform/entity.d.ts +11 -3
  41. package/dist/transform/entity.js +57 -41
  42. package/dist/transform/entity.js.map +1 -1
  43. package/dist/transform/field.d.ts +3 -3
  44. package/dist/transform/field.js +90 -65
  45. package/dist/transform/field.js.map +1 -1
  46. package/dist/transform/operation.d.ts +1 -1
  47. package/dist/transform/operation.js +94 -296
  48. package/dist/transform/operation.js.map +1 -1
  49. package/dist/transform/select.d.ts +3 -0
  50. package/dist/transform/select.js +44 -0
  51. package/dist/transform/select.js.map +1 -0
  52. package/dist/transform/top.d.ts +9 -0
  53. package/dist/transform/top.js +11 -2
  54. package/dist/transform/top.js.map +1 -1
  55. package/dist/transform.js +4 -0
  56. package/dist/transform.js.map +1 -1
  57. package/dist/tsconfig.tsbuildinfo +1 -1
  58. package/dist/types.d.ts +112 -19
  59. package/dist/types.js +4 -2
  60. package/dist/types.js.map +1 -1
  61. package/dist/utility.d.ts +30 -2
  62. package/dist/utility.js +381 -6
  63. package/dist/utility.js.map +1 -1
  64. package/model/apidef.jsonic +75 -1
  65. package/model/guide.jsonic +14 -44
  66. package/package.json +17 -14
  67. package/src/apidef.ts +264 -121
  68. package/src/builder/entity/{apiEntity.ts → entity.ts} +18 -11
  69. package/src/builder/entity/info.ts +53 -0
  70. package/src/builder/entity.ts +9 -35
  71. package/src/builder/flow/flowHeuristic01.ts +46 -12
  72. package/src/builder/flow.ts +39 -5
  73. package/src/def.ts +91 -0
  74. package/src/desc.ts +143 -0
  75. package/src/guide/guide.ts +207 -134
  76. package/src/guide/heuristic01.ts +1651 -272
  77. package/src/model.ts +98 -0
  78. package/src/parse.ts +5 -61
  79. package/src/schematron.ts.off +317 -0
  80. package/src/transform/args.ts +102 -0
  81. package/src/transform/clean.ts +43 -8
  82. package/src/transform/entity.ts +100 -51
  83. package/src/transform/field.ts +150 -71
  84. package/src/transform/operation.ts +118 -414
  85. package/src/transform/select.ts +90 -0
  86. package/src/transform/top.ts +76 -3
  87. package/src/transform.ts +4 -0
  88. package/src/types.ts +185 -5
  89. package/src/utility.ts +481 -9
  90. package/dist/builder/entity/apiEntity.d.ts +0 -3
  91. package/dist/builder/entity/apiEntity.js.map +0 -1
  92. package/dist/builder/entity/def.d.ts +0 -3
  93. package/dist/builder/entity/def.js +0 -19
  94. package/dist/builder/entity/def.js.map +0 -1
  95. package/src/builder/entity/def.ts +0 -44
  96. package/src/guide.ts.off +0 -136
package/src/utility.ts CHANGED
@@ -1,15 +1,51 @@
1
1
 
2
2
  import Path from 'node:path'
3
3
 
4
- import { slice, merge, inject, clone, isnode, walk, transform, select } from '@voxgig/struct'
4
+ import { snakify, camelify, kebabify, each } from 'jostraca'
5
+
6
+ import { decircular } from '@voxgig/util'
7
+
8
+ import {
9
+ slice, merge, inject, clone, isnode, walk, transform, select
10
+ } from '@voxgig/struct'
5
11
 
6
12
 
7
13
  import type {
8
14
  FsUtil,
9
- Log
15
+ Log,
16
+ Warner,
10
17
  } from './types'
11
18
 
12
19
 
20
+
21
+ function makeWarner(spec: { point: string, log: Log }): Warner {
22
+ const { point, log } = spec
23
+ const history: ({ point: string, when: number } & Record<string, any>)[] = []
24
+ const warn = function warn(def: Record<string, any>) {
25
+ const warning = { point, when: Date.now(), ...def }
26
+ log.warn(warning)
27
+ history.push(warning)
28
+ }
29
+ warn.history = history
30
+ warn.point = point
31
+ return warn
32
+ }
33
+
34
+
35
+ function writeFileSyncWarn(warn: Warner, fs: any, path: string, text: string) {
36
+ try {
37
+ fs.writeFileSync(path, text)
38
+ }
39
+ catch (err: any) {
40
+ warn({
41
+ err,
42
+ note: 'Unable to save file: ' + path
43
+ })
44
+ }
45
+ }
46
+
47
+
48
+
13
49
  function getdlog(
14
50
  tagin?: string,
15
51
  filepath?: string)
@@ -61,6 +97,7 @@ function depluralize(word: string): string {
61
97
 
62
98
  // Common irregular plurals
63
99
  const irregulars: Record<string, string> = {
100
+ 'analytics': 'analytics',
64
101
  'analyses': 'analysis',
65
102
  'appendices': 'appendix',
66
103
  'axes': 'axis',
@@ -68,7 +105,7 @@ function depluralize(word: string): string {
68
105
  'courses': 'course',
69
106
  'crises': 'crisis',
70
107
  'criteria': 'criterion',
71
- 'data': 'datum',
108
+ // 'data': 'datum',
72
109
  'diagnoses': 'diagnosis',
73
110
  'feet': 'foot',
74
111
  'furnace': 'furnaces',
@@ -82,6 +119,7 @@ function depluralize(word: string): string {
82
119
  'mice': 'mouse',
83
120
  'notice': 'notices',
84
121
  'oases': 'oasis',
122
+ 'releases': 'release',
85
123
  'people': 'person',
86
124
  'phenomena': 'phenomenon',
87
125
  'practice': 'practices',
@@ -96,6 +134,12 @@ function depluralize(word: string): string {
96
134
  return irregulars[word]
97
135
  }
98
136
 
137
+ for (let ending in irregulars) {
138
+ if (word.endsWith(ending)) {
139
+ return word.replace(ending, irregulars[ending])
140
+ }
141
+ }
142
+
99
143
  // Rules for regular plurals (applied in order)
100
144
 
101
145
  if (word.endsWith('ies') && word.length > 3) {
@@ -136,7 +180,10 @@ function depluralize(word: string): string {
136
180
  }
137
181
 
138
182
  // -s -> remove -s (cats -> cat)
139
- if (word.endsWith('s') && !word.endsWith('ss')) {
183
+ if (word.endsWith('s') &&
184
+ !word.endsWith('ss') &&
185
+ !word.endsWith('us')
186
+ ) {
140
187
  return word.slice(0, -1)
141
188
  }
142
189
 
@@ -167,7 +214,8 @@ function capture(data: any, shape: any): Record<string, any> {
167
214
  $APPEND,
168
215
  $ANY,
169
216
  $SELECT,
170
- $LOWER,
217
+ $LOWER: $RECASE,
218
+ $UPPER: $RECASE,
171
219
  },
172
220
  errs,
173
221
  meta
@@ -274,8 +322,6 @@ function $SELECT(inj: any, _val: any, _ref: any, store: any) {
274
322
  .filter(n => isnode(n[1]))
275
323
  .reduce((a, n) => (a[n[0]] = n[1], a), ({} as any))
276
324
 
277
- // console.log('SELECT-FROM', dparents)
278
-
279
325
  if (selector instanceof RegExp) {
280
326
  selector = {
281
327
  '$KEY': { '`$LIKE`': selector.toString() }
@@ -306,7 +352,7 @@ function $SELECT(inj: any, _val: any, _ref: any, store: any) {
306
352
  }
307
353
 
308
354
 
309
- function $LOWER(inj: any, val: any, ref: any, store: any) {
355
+ function $RECASE(inj: any, val: any, ref: any, store: any) {
310
356
  if ('key:pre' === inj.mode) {
311
357
  const dval = inj.parent[inj.key]
312
358
 
@@ -328,7 +374,7 @@ function $LOWER(inj: any, val: any, ref: any, store: any) {
328
374
  let tval = ptval[gkey][dkey]
329
375
 
330
376
  if ('string' === typeof tval) {
331
- tval = tval.toLowerCase()
377
+ tval = '$UPPER' === ref ? tval.toUpperCase() : tval.toLowerCase()
332
378
  }
333
379
 
334
380
  inj.setval(tval, 2)
@@ -337,12 +383,438 @@ function $LOWER(inj: any, val: any, ref: any, store: any) {
337
383
 
338
384
 
339
385
 
386
+ type PathMatch = (string[] & { index: number, expr: string, path: string })
387
+
388
+ // A special-purpose regex-style matcher for url paths.
389
+ // t - text part
390
+ // p - param part
391
+ // / - part separator
392
+ // / at start - must match from start
393
+ // / at end - must match to end
394
+ // See utility.test.ts for examples
395
+ function pathMatch(path: string | string[], expr: string):
396
+ null | PathMatch {
397
+
398
+ if (null == path) {
399
+ return null
400
+ }
401
+
402
+ const parts = (Array.isArray(path) ? path : path.split('/')).filter(p => '' !== p)
403
+ const res: any = []
404
+ res.index = -1
405
+ res.expr = expr
406
+ res.path = 'string' === typeof path ? path : '/' + path.join('/')
407
+
408
+ const plen = parts.length
409
+ const xlen = expr.length
410
+
411
+ let xI = 0, pI = 0, mI = -1
412
+ for (; pI <= parts.length; pI++) {
413
+ let p = parts[pI]
414
+ let x = expr[xI]
415
+ let isp = isParam(p)
416
+
417
+ if ('/' === x) {
418
+ if (0 === xI) {
419
+ if (0 === pI) {
420
+ mI = 0
421
+ pI--
422
+ xI++
423
+ }
424
+ else {
425
+ break
426
+ }
427
+ }
428
+ else if (xI === xlen - 1) {
429
+ if (pI === plen) {
430
+ xI++
431
+ break
432
+ }
433
+ else {
434
+ if (-1 < mI) {
435
+ // backtrack
436
+ pI = mI
437
+ mI = -1
438
+ }
439
+ xI = 0
440
+ }
441
+ }
442
+ else if (xI < xlen - 1) {
443
+ pI--
444
+ xI++
445
+ }
446
+ else {
447
+ xI = 0
448
+ break
449
+ }
450
+ }
451
+ else if ('t' === x && !isp) {
452
+ xI++
453
+ mI = mI < 0 ? pI : mI
454
+ }
455
+ else if ('p' === x && isp) {
456
+ xI++
457
+ mI = mI < 0 ? pI : mI
458
+ }
459
+ else {
460
+ if (-1 < mI) {
461
+ // backtrack
462
+ pI = mI
463
+ mI = -1
464
+ }
465
+ xI = 0
466
+ }
467
+
468
+ if (xI === xlen) {
469
+ break
470
+ }
471
+ }
472
+
473
+ if (xI === xlen) {
474
+ res.index = mI
475
+ res.push(...parts.slice(mI, pI + 1))
476
+ return res
477
+ }
478
+
479
+ return null
480
+ }
481
+
482
+
483
+ function isParam(partStr: string) {
484
+ return null != partStr && '{' === partStr[0] && '}' === partStr[partStr.length - 1]
485
+ }
486
+
487
+
488
+ function formatJSONIC(
489
+ val?: any,
490
+ opts?: {
491
+ hsepd?: number,
492
+ $?: boolean,
493
+ color?: boolean
494
+ maxlines?: number,
495
+ exclude?: string[],
496
+ }): string {
497
+
498
+ if (undefined === val) return ''
499
+
500
+ val = decircular(val)
501
+
502
+ const hsepd = opts?.hsepd ?? 1
503
+ const showd = !!opts?.$
504
+ const useColor = opts?.color ?? false
505
+ const maxlines = opts?.maxlines ?? Number.MAX_VALUE
506
+ const exclude = opts?.exclude ?? []
507
+
508
+ const space = ' '
509
+ const isBareKey = (k: string) => /^[A-Za-z_][_A-Za-z0-9]*$/.test(k)
510
+ const quoteKey = (k: string) => (isBareKey(k) ? k : JSON.stringify(k))
511
+
512
+ // ANSI color codes
513
+ const colors = {
514
+ reset: '\x1b[0m',
515
+ key: '\x1b[94m', // bright blue
516
+ string: '\x1b[92m', // bright green
517
+ number: '\x1b[93m', // bright yellow
518
+ boolean: '\x1b[96m', // bright cyan
519
+ null: '\x1b[90m', // bright gray
520
+ bracket: '\x1b[37m', // white
521
+ comment: '\x1b[90m', // bright gray
522
+ }
523
+
524
+ const c = (color: keyof typeof colors, text: string) =>
525
+ useColor ? `${colors[color]}${text}${colors.reset}` : text
526
+
527
+ const renderPrimitive = (v: any): string => {
528
+ if (v === null) return c('null', 'null')
529
+ const t = typeof v
530
+ switch (t) {
531
+ case 'string': return c('string', !v.includes('\n') ? JSON.stringify(v) :
532
+ '`' + JSON.stringify(v)
533
+ .substring(1)
534
+ .replace(/\\n/g, '\n')
535
+ .replace(/\\"/g, ':')
536
+ .replace(/`/g, '\\`')
537
+ .replace(/"$/, '`'))
538
+ case 'number': return c('number', Number.isFinite(v) ? String(v) : 'null')
539
+ case 'boolean': return c('boolean', v ? 'true' : 'false')
540
+ case 'bigint': return c('string', JSON.stringify(v.toString()))
541
+ case 'symbol':
542
+ case 'function':
543
+ case 'undefined':
544
+ return c('null', 'null')
545
+ default: return JSON.stringify(v)
546
+ }
547
+ }
548
+
549
+ const renderComment = (c: any): string | null => {
550
+ if (c == null) return null
551
+ if (Array.isArray(c) && c.every(x => typeof x === 'string')) return c.join('; ')
552
+ if (typeof c === 'string') return c
553
+ try { return JSON.stringify(c) } catch { return String(c) }
554
+ }
555
+
556
+ type ValueFrame = {
557
+ kind: 'value'
558
+ value: any
559
+ indentLevel: number
560
+ linePrefix: string
561
+ inlineComment?: string | null
562
+ }
563
+
564
+ type CloseFrame = {
565
+ kind: 'close'
566
+ token: '}' | ']'
567
+ indentLevel: number
568
+ }
569
+
570
+ let stack = new Array<ValueFrame | CloseFrame | undefined>(32)
571
+ let top = -1
572
+
573
+ // Seed root frame, capturing a possible top-level _COMMENT
574
+ let rootInline: string | null = null
575
+ if (val && typeof val === 'object') {
576
+ rootInline = renderComment((val as any)['_COMMENT'])
577
+ }
578
+ stack[++top] = {
579
+ kind: 'value', value: val, indentLevel: 0, linePrefix: '', inlineComment: rootInline
580
+ }
581
+
582
+ const lines: string[] = []
583
+
584
+ while (top >= 0 && (lines.length < maxlines)) {
585
+ const frame = stack[top]!
586
+
587
+ stack[top] = undefined
588
+ top -= 1
589
+
590
+ if (frame.kind === 'close') {
591
+ const indent = space.repeat(frame.indentLevel)
592
+ const hsep = 0 < frame.indentLevel && frame.indentLevel <= hsepd
593
+ lines.push(`${indent}${c('bracket', frame.token)}${hsep ? '\n' : ''}`)
594
+ continue
595
+ }
596
+
597
+ let v = frame.value
598
+ while (v && typeof v === 'object' && typeof (v as any).toJSON === 'function') {
599
+ v = (v as any).toJSON()
600
+ }
601
+
602
+ const { indentLevel, linePrefix } = frame
603
+ const commentSuffix = frame.inlineComment ? ` ${c('comment', `# ${frame.inlineComment}`)}` : ''
604
+
605
+ if (v === null || typeof v !== 'object') {
606
+ lines.push(`${linePrefix}${renderPrimitive(v)}${commentSuffix}`)
607
+ continue
608
+ }
609
+
610
+ if (Array.isArray(v)) {
611
+ const arr = v as any[]
612
+ if (arr.length === 0) {
613
+ lines.push(`${linePrefix}${c('bracket', '[')}${commentSuffix}`)
614
+ stack[++top] = { kind: 'close', token: ']', indentLevel }
615
+ continue
616
+ }
617
+
618
+ // opening line
619
+ lines.push(`${linePrefix}${c('bracket', '[')}${commentSuffix}`)
620
+ stack[++top] = { kind: 'close', token: ']', indentLevel }
621
+
622
+ // children (reverse push)
623
+ const childPrefix = space.repeat(indentLevel + 1)
624
+ for (let i = arr.length - 1; i >= 0; i--) {
625
+ const idxComment = renderComment((v as any)[`${i}_COMMENT`])
626
+ stack[++top] = {
627
+ kind: 'value',
628
+ value: arr[i],
629
+ indentLevel: indentLevel + 1,
630
+ linePrefix: `${childPrefix}`,
631
+ inlineComment: idxComment
632
+ }
633
+ }
634
+ continue
635
+ }
636
+
637
+ // Plain object
638
+ const obj = v as Record<string, any>
639
+ const keys = Object.keys(obj)
640
+ if (v instanceof Error) {
641
+ keys.unshift('name', 'message', 'stack')
642
+ }
643
+
644
+ const printableKeys = keys.filter(k => !k.endsWith('_COMMENT') &&
645
+ (showd || !k.endsWith('$')))
646
+
647
+ if (printableKeys.length === 0) {
648
+ lines.push(`${linePrefix}${c('bracket', '{')}${commentSuffix}`)
649
+ stack[++top] = { kind: 'close', token: '}', indentLevel }
650
+ continue
651
+ }
652
+
653
+ // opening line
654
+ lines.push(`${linePrefix}${c('bracket', '{')}${commentSuffix}`)
655
+ stack[++top] = { kind: 'close', token: '}', indentLevel }
656
+
657
+ const nextIndentStr = space.repeat(indentLevel + 1)
658
+ for (let i = printableKeys.length - 1; i >= 0; i--) {
659
+ const k = printableKeys[i]
660
+ if (exclude.includes(k)) {
661
+ continue
662
+ }
663
+
664
+ const keyText = quoteKey(k)
665
+ const valForKey = obj[k]
666
+ const cmt = renderComment(obj[`${k}_COMMENT`])
667
+
668
+ stack[++top] = {
669
+ kind: 'value',
670
+ value: valForKey,
671
+ indentLevel: indentLevel + 1,
672
+ linePrefix: `${nextIndentStr}${c('key', keyText)}: `,
673
+ inlineComment: cmt
674
+ }
675
+ }
676
+ }
677
+
678
+ return lines.join('\n') + '\n'
679
+ }
680
+
681
+
682
+ const VALID_CANON: Record<string, string> = {
683
+ 'string': '`$STRING`',
684
+ 'number': '`$NUMBER`',
685
+ 'integer': '`$INTEGER`',
686
+ 'boolean': '`$BOOLEAN`',
687
+ 'null': '`$NULL`',
688
+ 'array': '`$ARRAY`',
689
+ 'object': '`$OBJECT`',
690
+ 'any': '`$ANY`',
691
+ }
692
+
693
+
694
+ function validator(torig: undefined | string | string[]): any {
695
+ if ('string' === typeof torig) {
696
+ const tstr = torig.toLowerCase().trim()
697
+ const canon = VALID_CANON[tstr] ?? 'Any'
698
+ return canon
699
+ }
700
+ else if (Array.isArray(torig)) {
701
+ return ['`$ONE`', torig.map((t: string) => validator(t))]
702
+ }
703
+ else {
704
+ return '`$ANY`'
705
+ }
706
+ }
707
+
708
+ function canonize(s: string) {
709
+ return depluralize(snakify(s)).replace(/[^a-zA-Z_0-9]/g, '')
710
+ }
711
+
712
+
713
+ function warnOnError(where: string, warn: Warner, fn: Function, result?: any) {
714
+ try {
715
+ return fn()
716
+ }
717
+ catch (err: any) {
718
+ warn({
719
+ note: 'Error in ' + where + ': ' + err.message,
720
+ err
721
+ })
722
+ return result
723
+ }
724
+ }
725
+
726
+
727
+
728
+ function debugpath(pathStr: string, methodName: string | null | undefined, ...args: any[]): void {
729
+ const apipath = process.env.APIDEF_DEBUG_PATH
730
+ if (!apipath) return
731
+
732
+ const [targetPath, targetMethod] = apipath.split(':')
733
+
734
+ // Check if path matches
735
+ if (pathStr !== targetPath) return
736
+
737
+ // If a method is specified in apipath and we have a method name, check if it matches
738
+ if (targetMethod && methodName) {
739
+ if (methodName.toLowerCase() !== targetMethod.toLowerCase()) return
740
+ }
741
+
742
+ console.log(methodName || '', ...args)
743
+ }
744
+
745
+
746
+ function findPathsWithPrefix(
747
+ ctx: any,
748
+ pathStr: string,
749
+ opts?: { strict?: boolean, param?: boolean }
750
+ ): number {
751
+ const strict = opts?.strict ?? false
752
+ const param = opts?.param ?? false
753
+
754
+ if (!param) {
755
+ pathStr = pathStr.replace(/\{[^}]+\}/g, '{}')
756
+ }
757
+
758
+ const matchingPaths = each(ctx.def.paths)
759
+ .filter((pathDef: any) => {
760
+ let path = pathDef.key$
761
+ if (!param) {
762
+ path = path.replace(/\{[^}]+\}/g, '{}')
763
+ }
764
+ if (strict) {
765
+ // Strict mode: path must start with prefix and have more segments
766
+ return path.startsWith(pathStr) && path.length > pathStr.length
767
+ } else {
768
+ // Non-strict mode: simple prefix match
769
+ return path.startsWith(pathStr)
770
+ }
771
+ })
772
+
773
+ return matchingPaths.length
774
+ }
775
+
776
+
777
+ // TODO: move to jostraca?
778
+ function allcapify(s?: string) {
779
+ return 'string' === typeof s ? snakify(s).toUpperCase() : ''
780
+ }
781
+
782
+
783
+ function nom(v: any, format: string): string {
784
+ let formatstr = 'string' == typeof format ? format : null
785
+ if (null == formatstr) {
786
+ return '__MISSING__'
787
+ }
788
+ const canon = canonize(formatstr)
789
+ let out = v?.[canon] ?? '__MISSING_' + formatstr + '__'
790
+ out =
791
+ /[A-Z][a-z]/.test(formatstr) ? camelify(out) :
792
+ /[A-Z][A-Z]/.test(formatstr) ? allcapify(out) :
793
+ /-/.test(formatstr) ? kebabify(out) : out
794
+
795
+ return out
796
+ }
797
+
798
+ export type {
799
+ PathMatch
800
+ }
340
801
 
341
802
  export {
803
+ nom,
342
804
  getdlog,
343
805
  loadFile,
344
806
  formatJsonSrc,
345
807
  depluralize,
346
808
  find,
347
809
  capture,
810
+ pathMatch,
811
+ makeWarner,
812
+ formatJSONIC,
813
+ validator,
814
+ canonize,
815
+ debugpath,
816
+ findPathsWithPrefix,
817
+ writeFileSyncWarn,
818
+ warnOnError,
819
+
348
820
  }
@@ -1,3 +0,0 @@
1
- import type { ApiDefOptions } from '../../types';
2
- declare function resolveApiEntity(apimodel: any, opts: ApiDefOptions): () => void;
3
- export { resolveApiEntity };
@@ -1 +0,0 @@
1
- {"version":3,"file":"apiEntity.js","sourceRoot":"","sources":["../../../src/builder/entity/apiEntity.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;;;AAsF1C,4CAAgB;AApFlB,0DAA4B;AAE5B,uCAAsD;AAOtD,2CAEsB;AAItB,SAAS,gBAAgB,CACvB,QAAa,EACb,IAAmB;IAEnB,MAAM,MAAM,GAAG;QACb,mBAAmB;KACpB,CAAA;IAED,MAAM,WAAW,GAAoC,EAAE,CAAA;IAEvD,IAAA,eAAI,EAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,MAAW,EAAE,UAAkB,EAAE,EAAE;QAClE,MAAM,UAAU,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,UAAU,GAAG,SAAS,CAAA;QAE1F,MAAM,UAAU,GACd,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAEjC,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;QAE5C,MAAM,SAAS,GACb,aAAa,MAAM,CAAC,IAAI,MAAM;YAC9B,sBAAsB,MAAM,CAAC,IAAI,SAAS;YAC1C,mBAAmB,eAAe,IAAI;YACtC,IAAA,uBAAa,EAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC7D,SAAS,CAAA;QAEX,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAA;QAEtD,MAAM,CAAC,IAAI,CAAC,KAAK,mBAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;IAChD,CAAC,CAAC,CAAC,CAAA;IAEH,MAAM,SAAS,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,yBAAyB,CAAA;IAE5F,OAAO,SAAS,gBAAgB;QAC9B,IAAA,iBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE;YAC3B,IAAA,eAAI,EAAC,WAAW,EAAE,CAAC,UAAU,EAAE,EAAE;gBAC/B,IAAA,eAAI,EAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,IAAA,kBAAO,EAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;YAChE,CAAC,CAAC,CAAA;YAEF,IAAA,eAAI,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,IAAA,kBAAO,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC7D,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;AAEH,CAAC;AAED,SAAS,YAAY,CAAC,MAAW;IAC/B,yCAAyC;IACzC,MAAM,YAAY,GAChB,IAAA,eAAI,EAAC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAO,EAAE,EAAE,CAC1B,IAAA,eAAI,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC;SACd,IAAI,EAAE;SACN,MAAM,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE,CAE3B,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC;UAEL,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEf,MAAM,eAAe,GACnB,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;SAClC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAE3B,OAAO,eAAe,CAAA;AACxB,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { ApiDefOptions, ApiModel } from '../../types';
2
- declare function resolveDef(apimodel: ApiModel, opts: ApiDefOptions): () => void;
3
- export { resolveDef };
@@ -1,19 +0,0 @@
1
- "use strict";
2
- /* Copyright (c) 2025 Voxgig, MIT License */
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.resolveDef = resolveDef;
5
- const jostraca_1 = require("jostraca");
6
- function resolveDef(apimodel, opts) {
7
- const defFile = (null == opts.outprefix ? '' : opts.outprefix) + 'api-def.jsonic';
8
- const modelDef = { main: { def: apimodel.main.def } };
9
- let modelDefSrc = JSON.stringify(modelDef, null, 2);
10
- modelDefSrc =
11
- '# API Definition\n\n' +
12
- modelDefSrc.substring(1, modelDefSrc.length - 1).replace(/\n /g, '\n');
13
- return function defBuilder() {
14
- (0, jostraca_1.Folder)({ name: 'api' }, () => {
15
- (0, jostraca_1.File)({ name: defFile }, () => (0, jostraca_1.Content)(modelDefSrc));
16
- });
17
- };
18
- }
19
- //# sourceMappingURL=def.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"def.js","sourceRoot":"","sources":["../../../src/builder/entity/def.ts"],"names":[],"mappings":";AAAA,4CAA4C;;AA0C1C,gCAAU;AA/BZ,uCAIiB;AAGjB,SAAS,UAAU,CACjB,QAAkB,EAClB,IAAmB;IAEnB,MAAM,OAAO,GACX,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAA;IAEnE,MAAM,QAAQ,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;IACrD,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAEnD,WAAW;QACT,sBAAsB;YACtB,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAEzE,OAAO,SAAS,UAAU;QACxB,IAAA,iBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE;YAC3B,IAAA,eAAI,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,IAAA,kBAAO,EAAC,WAAW,CAAC,CAAC,CAAA;QACrD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;AAEH,CAAC"}
@@ -1,44 +0,0 @@
1
- /* Copyright (c) 2025 Voxgig, MIT License */
2
-
3
- import Path from 'node:path'
4
-
5
-
6
- import type {
7
- ApiDefOptions,
8
- ApiModel,
9
- } from '../../types'
10
-
11
-
12
- import {
13
- File,
14
- Folder,
15
- Content
16
- } from 'jostraca'
17
-
18
-
19
- function resolveDef(
20
- apimodel: ApiModel,
21
- opts: ApiDefOptions,
22
- ) {
23
- const defFile =
24
- (null == opts.outprefix ? '' : opts.outprefix) + 'api-def.jsonic'
25
-
26
- const modelDef = { main: { def: apimodel.main.def } }
27
- let modelDefSrc = JSON.stringify(modelDef, null, 2)
28
-
29
- modelDefSrc =
30
- '# API Definition\n\n' +
31
- modelDefSrc.substring(1, modelDefSrc.length - 1).replace(/\n /g, '\n')
32
-
33
- return function defBuilder() {
34
- Folder({ name: 'api' }, () => {
35
- File({ name: defFile }, () => Content(modelDefSrc))
36
- })
37
- }
38
-
39
- }
40
-
41
-
42
- export {
43
- resolveDef
44
- }