@voxgig/apidef 1.9.0 → 2.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 (73) hide show
  1. package/dist/apidef.d.ts +3 -29
  2. package/dist/apidef.js +65 -186
  3. package/dist/apidef.js.map +1 -1
  4. package/dist/builder/entity/apiEntity.d.ts +3 -0
  5. package/dist/builder/entity/apiEntity.js +51 -0
  6. package/dist/builder/entity/apiEntity.js.map +1 -0
  7. package/dist/builder/entity/def.d.ts +3 -0
  8. package/dist/builder/entity/def.js +19 -0
  9. package/dist/builder/entity/def.js.map +1 -0
  10. package/dist/builder/entity.d.ts +2 -0
  11. package/dist/builder/entity.js +30 -0
  12. package/dist/builder/entity.js.map +1 -0
  13. package/dist/builder/flow/flowHeuristic01.d.ts +2 -0
  14. package/dist/builder/flow/flowHeuristic01.js +153 -0
  15. package/dist/builder/flow/flowHeuristic01.js.map +1 -0
  16. package/dist/builder/flow.d.ts +2 -0
  17. package/dist/builder/flow.js +41 -0
  18. package/dist/builder/flow.js.map +1 -0
  19. package/dist/guide/heuristic01.d.ts +2 -0
  20. package/dist/guide/heuristic01.js +119 -0
  21. package/dist/guide/heuristic01.js.map +1 -0
  22. package/dist/guide.d.ts +2 -0
  23. package/dist/guide.js +60 -0
  24. package/dist/guide.js.map +1 -0
  25. package/dist/parse.d.ts +1 -1
  26. package/dist/parse.js +5 -4
  27. package/dist/parse.js.map +1 -1
  28. package/dist/resolver.d.ts +2 -0
  29. package/dist/resolver.js +62 -0
  30. package/dist/resolver.js.map +1 -0
  31. package/dist/transform/entity.js +25 -4
  32. package/dist/transform/entity.js.map +1 -1
  33. package/dist/transform/field.js +4 -84
  34. package/dist/transform/field.js.map +1 -1
  35. package/dist/transform/operation.d.ts +2 -2
  36. package/dist/transform/operation.js +60 -30
  37. package/dist/transform/operation.js.map +1 -1
  38. package/dist/transform/top.d.ts +2 -2
  39. package/dist/transform/top.js +5 -4
  40. package/dist/transform/top.js.map +1 -1
  41. package/dist/transform.d.ts +1 -1
  42. package/dist/transform.js +20 -10
  43. package/dist/transform.js.map +1 -1
  44. package/dist/tsconfig.tsbuildinfo +1 -1
  45. package/dist/types.d.ts +691 -0
  46. package/dist/types.js +39 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/utility.d.ts +5 -0
  49. package/dist/utility.js +84 -0
  50. package/dist/utility.js.map +1 -0
  51. package/model/apidef.jsonic +28 -24
  52. package/package.json +9 -7
  53. package/src/apidef.ts +94 -271
  54. package/src/builder/entity/apiEntity.ts +88 -0
  55. package/src/builder/entity/def.ts +44 -0
  56. package/src/builder/entity.ts +54 -0
  57. package/src/builder/flow/flowHeuristic01.ts +200 -0
  58. package/src/builder/flow.ts +61 -0
  59. package/src/guide/heuristic01.ts +178 -0
  60. package/src/guide.ts +87 -0
  61. package/src/parse.ts +6 -4
  62. package/src/resolver.ts +91 -0
  63. package/src/transform/entity.ts +36 -10
  64. package/src/transform/field.ts +9 -92
  65. package/src/transform/operation.ts +112 -46
  66. package/src/transform/top.ts +11 -9
  67. package/src/transform.ts +22 -11
  68. package/src/types.ts +89 -0
  69. package/src/utility.ts +161 -0
  70. package/dist/transform/manual.d.ts +0 -3
  71. package/dist/transform/manual.js +0 -12
  72. package/dist/transform/manual.js.map +0 -1
  73. package/src/transform/manual.ts +0 -29
package/src/transform.ts CHANGED
@@ -11,7 +11,7 @@ import { topTransform } from './transform/top'
11
11
  import { entityTransform } from './transform/entity'
12
12
  import { operationTransform } from './transform/operation'
13
13
  import { fieldTransform } from './transform/field'
14
- import { manualTransform } from './transform/manual'
14
+ // import { manualTransform } from './transform/manual'
15
15
 
16
16
 
17
17
 
@@ -55,7 +55,7 @@ const TRANSFORM: Record<string, Transform> = {
55
55
  entity: entityTransform,
56
56
  operation: operationTransform,
57
57
  field: fieldTransform,
58
- manual: manualTransform,
58
+ // manual: manualTransform,
59
59
  }
60
60
 
61
61
 
@@ -98,10 +98,15 @@ async function resolveTransforms(ctx: TransformCtx): Promise<TransformSpec> {
98
98
  order: transformNames
99
99
  })
100
100
 
101
- for (const tn of transformNames) {
102
- log.debug({ what: 'transform', transform: tn, note: tn })
103
- const transform = await resolveTransform(tn, ctx)
104
- tspec.transform.push(transform)
101
+ try {
102
+ for (const tn of transformNames) {
103
+ log.debug({ what: 'transform', transform: tn, note: tn })
104
+ const transform = await resolveTransform(tn, ctx)
105
+ tspec.transform.push(transform)
106
+ }
107
+ }
108
+ catch (err: any) {
109
+ throw err
105
110
  }
106
111
 
107
112
  return tspec
@@ -146,10 +151,10 @@ async function resolveTransform(tn: string, ctx: TransformCtx) {
146
151
  }
147
152
 
148
153
 
149
-
150
154
  async function processTransforms(
151
155
  ctx: TransformCtx,
152
- spec: TransformSpec,
156
+ // spec: TransformSpec,
157
+ transforms: any[],
153
158
  apimodel: any,
154
159
  def: any
155
160
  ): Promise<ProcessResult> {
@@ -162,15 +167,21 @@ async function processTransforms(
162
167
  const guide: Guide = GuideShape(ctx.model.main.api.guide)
163
168
 
164
169
 
165
- for (let tI = 0; tI < spec.transform.length; tI++) {
166
- const transform = spec.transform[tI]
170
+ // for (let tI = 0; tI < spec.transform.length; tI++) {
171
+ // const transform = spec.transform[tI]
172
+
173
+ for (let tI = 0; tI < transforms.length; tI++) {
174
+ const transform = transforms[tI]
167
175
 
168
176
  try {
169
- const tres = await transform(ctx, guide, spec, apimodel, def)
177
+ const tres = await transform(ctx, guide, apimodel, def)
170
178
  pres.ok = pres.ok && tres.ok
171
179
  pres.results.push(tres)
172
180
  }
173
181
  catch (err: any) {
182
+ // TODO: fix: this error does not get printed
183
+ console.error(err)
184
+
174
185
  pres.ok = false
175
186
  pres.msg += transform.name + ': ' + err.message + '\n'
176
187
  pres.results.push({
package/src/types.ts ADDED
@@ -0,0 +1,89 @@
1
+ /* Copyright (c) 2025 Voxgig, MIT License */
2
+
3
+ import * as Fs from 'node:fs'
4
+
5
+ import { Pino, prettyPino } from '@voxgig/util'
6
+ import { Gubu, Open, Any } from 'gubu'
7
+
8
+
9
+ type FsUtil = typeof Fs
10
+ type Log = ReturnType<typeof prettyPino>
11
+
12
+
13
+ type ApiDefOptions = {
14
+ def?: string
15
+ fs?: any
16
+ pino?: ReturnType<typeof Pino>
17
+ debug?: boolean | string
18
+ folder?: string
19
+ meta?: Record<string, any>
20
+ outprefix?: string
21
+ strategy?: string
22
+ }
23
+
24
+
25
+ const ModelShape = Gubu({
26
+ name: String,
27
+ def: String,
28
+ main: {
29
+ sdk: {},
30
+ def: {},
31
+ api: {
32
+ guide: {},
33
+ entity: {},
34
+ },
35
+ }
36
+ })
37
+ const OpenModelShape = Gubu(Open(ModelShape), { name: 'Model' })
38
+
39
+ type Model = ReturnType<typeof ModelShape>
40
+
41
+
42
+ const BuildShape = Gubu({
43
+ spec: {
44
+ base: '',
45
+ path: '',
46
+ debug: '',
47
+ use: {},
48
+ res: [],
49
+ require: '',
50
+ log: {},
51
+ fs: Any(),
52
+ watch: {
53
+ mod: true,
54
+ add: true,
55
+ rem: true,
56
+ }
57
+ }
58
+ })
59
+ const OpenBuildShape = Gubu(Open(BuildShape))
60
+
61
+ type Build = ReturnType<typeof BuildShape>
62
+
63
+
64
+
65
+ type ApiModel = {
66
+ main: {
67
+ api: {
68
+ entity: Record<string, any>
69
+ }
70
+ def: Record<string, any>
71
+ }
72
+ }
73
+
74
+
75
+ export {
76
+ OpenModelShape,
77
+ OpenBuildShape,
78
+ }
79
+
80
+
81
+ export type {
82
+ Log,
83
+ FsUtil,
84
+ ApiDefOptions,
85
+ Model,
86
+ Build,
87
+ ApiModel,
88
+ }
89
+
package/src/utility.ts ADDED
@@ -0,0 +1,161 @@
1
+
2
+ import Path from 'node:path'
3
+
4
+
5
+ import type {
6
+ FsUtil,
7
+ Log
8
+ } from './types'
9
+
10
+
11
+ function loadFile(path: string, what: string, fs: FsUtil, log: Log) {
12
+ try {
13
+ const source = fs.readFileSync(path, 'utf8')
14
+ return source
15
+ }
16
+ catch (err: any) {
17
+ log.error({ load: 'fail', what, path, err })
18
+ throw err
19
+ }
20
+ }
21
+
22
+
23
+ function formatJsonSrc(jsonsrc: string) {
24
+ return jsonsrc
25
+ .replace(/"([a-zA-Z_][a-zA-Z_0-9]*)": /g, '$1: ')
26
+ .replace(/},/g, '}\n')
27
+ // .replace(/([a-zA-Z_][a-zA-Z_0-9]*)_COMMENT:/g, '# $1')
28
+ .replace(/\n(\s*)([a-zA-Z_][a-zA-Z_0-9]*)_COMMENT:\s*"(.*)",/g, '\n\n$1# $2 $3')
29
+ }
30
+
31
+
32
+ function depluralize(word: string): string {
33
+ if (!word || word.length === 0) {
34
+ return word
35
+ }
36
+
37
+ // Common irregular plurals
38
+ const irregulars: Record<string, string> = {
39
+ 'children': 'child',
40
+ 'men': 'man',
41
+ 'women': 'woman',
42
+ 'teeth': 'tooth',
43
+ 'feet': 'foot',
44
+ 'geese': 'goose',
45
+ 'mice': 'mouse',
46
+ 'people': 'person',
47
+ 'data': 'datum',
48
+ 'criteria': 'criterion',
49
+ 'phenomena': 'phenomenon',
50
+ 'indices': 'index',
51
+ 'matrices': 'matrix',
52
+ 'vertices': 'vertex',
53
+ 'analyses': 'analysis',
54
+ 'axes': 'axis',
55
+ 'crises': 'crisis',
56
+ 'diagnoses': 'diagnosis',
57
+ 'oases': 'oasis',
58
+ 'theses': 'thesis',
59
+ 'appendices': 'appendix'
60
+ }
61
+
62
+ if (irregulars[word]) {
63
+ return irregulars[word]
64
+ }
65
+
66
+ // Rules for regular plurals (applied in order)
67
+
68
+ // -ies -> -y (cities -> city)
69
+ if (word.endsWith('ies') && word.length > 3) {
70
+ return word.slice(0, -3) + 'y'
71
+ }
72
+
73
+ // -ves -> -f or -fe (wolves -> wolf, knives -> knife)
74
+ if (word.endsWith('ves')) {
75
+ const stem = word.slice(0, -3)
76
+ // Check if it should be -fe (like knife, wife, life)
77
+ if (['kni', 'wi', 'li'].includes(stem)) {
78
+ return stem + 'fe'
79
+ }
80
+ return stem + 'f'
81
+ }
82
+
83
+ // -oes -> -o (potatoes -> potato)
84
+ if (word.endsWith('oes')) {
85
+ return word.slice(0, -2)
86
+ }
87
+
88
+ // -ses, -xes, -zes, -shes, -ches -> remove -es (boxes -> box)
89
+ if (word.endsWith('ses') || word.endsWith('xes') || word.endsWith('zes') ||
90
+ word.endsWith('shes') || word.endsWith('ches')) {
91
+ return word.slice(0, -2)
92
+ }
93
+
94
+ // -s -> remove -s (cats -> cat)
95
+ if (word.endsWith('s') && !word.endsWith('ss')) {
96
+ return word.slice(0, -1)
97
+ }
98
+
99
+ // If none of the rules apply, return as is
100
+ return word
101
+ }
102
+
103
+
104
+ /*
105
+ function writeChanged(
106
+ point: string, path: string, content: string,
107
+ fs: FsUtil, log: Log,
108
+ flags?: { update?: boolean }
109
+ ) {
110
+ let exists = false
111
+ let changed = false
112
+
113
+ flags = flags || {}
114
+ flags.update = null == flags.update ? true : !!flags.update
115
+
116
+ let action = ''
117
+ try {
118
+ let existingContent: string = ''
119
+ path = Path.normalize(path)
120
+
121
+ exists = fs.existsSync(path)
122
+
123
+ if (exists) {
124
+ action = 'read'
125
+ existingContent = fs.readFileSync(path, 'utf8')
126
+ }
127
+
128
+ changed = existingContent !== content
129
+
130
+ action = flags.update ? 'write' : 'skip'
131
+
132
+ log.info({
133
+ point: 'write-' + point,
134
+ note: (changed ? '' : 'not-') + 'changed ' + path,
135
+ write: 'file', skip: !changed, exists, changed,
136
+ contentLength: content.length, file: path
137
+ })
138
+
139
+ if (!exists || (changed && flags.update)) {
140
+ fs.writeFileSync(path, content)
141
+ }
142
+ }
143
+ catch (err: any) {
144
+ log.error({
145
+ fail: action, point, file: path, exists, changed,
146
+ contentLength: content.length, err
147
+ })
148
+ err.__logged__ = true
149
+ throw err
150
+ }
151
+ }
152
+ */
153
+
154
+
155
+ export {
156
+ loadFile,
157
+ formatJsonSrc,
158
+ depluralize,
159
+
160
+ // writeChanged,
161
+ }
@@ -1,3 +0,0 @@
1
- import type { TransformCtx, TransformSpec, TransformResult, Guide } from '../transform';
2
- declare const manualTransform: (ctx: TransformCtx, guide: Guide, tspec: TransformSpec, model: any, def: any) => Promise<TransformResult>;
3
- export { manualTransform };
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.manualTransform = void 0;
4
- const jsonic_1 = require("jsonic");
5
- const { deep } = jsonic_1.Jsonic.util;
6
- const manualTransform = async function (ctx, guide, tspec, model, def) {
7
- const { manual } = guide;
8
- deep(model, manual);
9
- return { ok: true, msg: 'manual' };
10
- };
11
- exports.manualTransform = manualTransform;
12
- //# sourceMappingURL=manual.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manual.js","sourceRoot":"","sources":["../../src/transform/manual.ts"],"names":[],"mappings":";;;AACA,mCAA+B;AAO/B,MAAM,EAAE,IAAI,EAAE,GAAG,eAAM,CAAC,IAAI,CAAA;AAE5B,MAAM,eAAe,GAAG,KAAK,WAC3B,GAAiB,EACjB,KAAY,EACZ,KAAoB,EACpB,KAAU,EACV,GAAQ;IAGR,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAExB,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAEnB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAA;AACpC,CAAC,CAAA;AAIC,0CAAe"}
@@ -1,29 +0,0 @@
1
-
2
- import { Jsonic } from 'jsonic'
3
-
4
- import { each, getx } from 'jostraca'
5
-
6
- import type { TransformCtx, TransformSpec, TransformResult, Transform, Guide } from '../transform'
7
-
8
-
9
- const { deep } = Jsonic.util
10
-
11
- const manualTransform = async function(
12
- ctx: TransformCtx,
13
- guide: Guide,
14
- tspec: TransformSpec,
15
- model: any,
16
- def: any
17
- ): Promise<TransformResult> {
18
-
19
- const { manual } = guide
20
-
21
- deep(model, manual)
22
-
23
- return { ok: true, msg: 'manual' }
24
- }
25
-
26
-
27
- export {
28
- manualTransform
29
- }