@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.
- package/dist/apidef.d.ts +3 -29
- package/dist/apidef.js +65 -186
- package/dist/apidef.js.map +1 -1
- package/dist/builder/entity/apiEntity.d.ts +3 -0
- package/dist/builder/entity/apiEntity.js +51 -0
- package/dist/builder/entity/apiEntity.js.map +1 -0
- package/dist/builder/entity/def.d.ts +3 -0
- package/dist/builder/entity/def.js +19 -0
- package/dist/builder/entity/def.js.map +1 -0
- package/dist/builder/entity.d.ts +2 -0
- package/dist/builder/entity.js +30 -0
- package/dist/builder/entity.js.map +1 -0
- package/dist/builder/flow/flowHeuristic01.d.ts +2 -0
- package/dist/builder/flow/flowHeuristic01.js +153 -0
- package/dist/builder/flow/flowHeuristic01.js.map +1 -0
- package/dist/builder/flow.d.ts +2 -0
- package/dist/builder/flow.js +41 -0
- package/dist/builder/flow.js.map +1 -0
- package/dist/guide/heuristic01.d.ts +2 -0
- package/dist/guide/heuristic01.js +119 -0
- package/dist/guide/heuristic01.js.map +1 -0
- package/dist/guide.d.ts +2 -0
- package/dist/guide.js +60 -0
- package/dist/guide.js.map +1 -0
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +5 -4
- package/dist/parse.js.map +1 -1
- package/dist/resolver.d.ts +2 -0
- package/dist/resolver.js +62 -0
- package/dist/resolver.js.map +1 -0
- package/dist/transform/entity.js +25 -4
- package/dist/transform/entity.js.map +1 -1
- package/dist/transform/field.js +4 -84
- package/dist/transform/field.js.map +1 -1
- package/dist/transform/operation.d.ts +2 -2
- package/dist/transform/operation.js +60 -30
- package/dist/transform/operation.js.map +1 -1
- package/dist/transform/top.d.ts +2 -2
- package/dist/transform/top.js +5 -4
- package/dist/transform/top.js.map +1 -1
- package/dist/transform.d.ts +1 -1
- package/dist/transform.js +20 -10
- package/dist/transform.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +691 -0
- package/dist/types.js +39 -0
- package/dist/types.js.map +1 -0
- package/dist/utility.d.ts +5 -0
- package/dist/utility.js +84 -0
- package/dist/utility.js.map +1 -0
- package/model/apidef.jsonic +28 -24
- package/package.json +9 -7
- package/src/apidef.ts +94 -271
- package/src/builder/entity/apiEntity.ts +88 -0
- package/src/builder/entity/def.ts +44 -0
- package/src/builder/entity.ts +54 -0
- package/src/builder/flow/flowHeuristic01.ts +200 -0
- package/src/builder/flow.ts +61 -0
- package/src/guide/heuristic01.ts +178 -0
- package/src/guide.ts +87 -0
- package/src/parse.ts +6 -4
- package/src/resolver.ts +91 -0
- package/src/transform/entity.ts +36 -10
- package/src/transform/field.ts +9 -92
- package/src/transform/operation.ts +112 -46
- package/src/transform/top.ts +11 -9
- package/src/transform.ts +22 -11
- package/src/types.ts +89 -0
- package/src/utility.ts +161 -0
- package/dist/transform/manual.d.ts +0 -3
- package/dist/transform/manual.js +0 -12
- package/dist/transform/manual.js.map +0 -1
- 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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
+
}
|
package/dist/transform/manual.js
DELETED
|
@@ -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"}
|
package/src/transform/manual.ts
DELETED
|
@@ -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
|
-
}
|