@voxgig/apidef 1.9.0 → 2.0.0
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 +84 -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 +125 -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 +178 -0
- package/dist/guide/heuristic01.js.map +1 -0
- package/dist/guide.d.ts +2 -0
- package/dist/guide.js +62 -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 +4 -2
- 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 +22 -11
- 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 +21 -10
- package/dist/transform.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +682 -0
- package/dist/types.js +38 -0
- package/dist/types.js.map +1 -0
- package/dist/utility.d.ts +4 -0
- package/dist/utility.js +59 -0
- package/dist/utility.js.map +1 -0
- package/model/apidef.jsonic +28 -24
- package/package.json +8 -6
- package/src/apidef.ts +117 -263
- 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 +165 -0
- package/src/builder/flow/flowHeuristic01.ts~ +45 -0
- package/src/builder/flow.ts +60 -0
- package/src/guide/heuristic01.ts +225 -0
- package/src/guide.ts +91 -0
- package/src/parse.ts +6 -4
- package/src/resolver.ts +91 -0
- package/src/transform/entity.ts +10 -7
- package/src/transform/field.ts +9 -92
- package/src/transform/operation.ts +39 -25
- package/src/transform/top.ts +11 -9
- package/src/transform.ts +23 -11
- package/src/types.ts +88 -0
- package/src/utility.ts +83 -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/guide.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
|
|
2
|
+
import Path from 'node:path'
|
|
3
|
+
|
|
4
|
+
import { File, Content, each } from 'jostraca'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import { heuristic01 } from './guide/heuristic01'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async function resolveGuide(ctx: any) {
|
|
11
|
+
// console.log('GUIDE CTX', ctx)
|
|
12
|
+
|
|
13
|
+
let guide: Record<string, any> = ctx.model.main.api.guide
|
|
14
|
+
|
|
15
|
+
if ('heuristic01' === ctx.opts.strategy) {
|
|
16
|
+
guide = await heuristic01(ctx)
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
throw new Error('Unknown guide strategy: ' + ctx.opts.strategy)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
guide = cleanGuide(guide)
|
|
23
|
+
|
|
24
|
+
ctx.model.main.api.guide = guide
|
|
25
|
+
|
|
26
|
+
const guideFile =
|
|
27
|
+
Path.join(ctx.opts.folder,
|
|
28
|
+
(null == ctx.opts.outprefix ? '' : ctx.opts.outprefix) + 'guide.jsonic')
|
|
29
|
+
|
|
30
|
+
const guideBlocks = [
|
|
31
|
+
'# Guide',
|
|
32
|
+
'',
|
|
33
|
+
'main: api: guide: { ',
|
|
34
|
+
'',
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
guideBlocks.push(...each(guide.entity, (entity, entityname) => {
|
|
39
|
+
guideBlocks.push(`\nentity: ${entityname}: path: {`)
|
|
40
|
+
|
|
41
|
+
each(entity.path, (path, pathname) => {
|
|
42
|
+
guideBlocks.push(` '${pathname}': op: {`)
|
|
43
|
+
|
|
44
|
+
each(path.op, (op, opname) => {
|
|
45
|
+
guideBlocks.push(` '${opname}': method: ${op.method}`)
|
|
46
|
+
if (op.transform?.reqform) {
|
|
47
|
+
guideBlocks.push(
|
|
48
|
+
` '${opname}': transform: reqform: ${JSON.stringify(op.transform.reqform)}`)
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
guideBlocks.push(` }`)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
guideBlocks.push(`}`)
|
|
56
|
+
}))
|
|
57
|
+
|
|
58
|
+
guideBlocks.push('}')
|
|
59
|
+
|
|
60
|
+
const guideSrc = guideBlocks.join('\n')
|
|
61
|
+
|
|
62
|
+
// console.log(guideSrc)
|
|
63
|
+
|
|
64
|
+
return () => {
|
|
65
|
+
File({ name: Path.basename(guideFile) }, () => Content(guideSrc))
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
function cleanGuide(guide: Record<string, any>): Record<string, any> {
|
|
72
|
+
const clean: Record<string, any> = {
|
|
73
|
+
control: guide.control,
|
|
74
|
+
entity: {}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
each(guide.entity, (entity: any, name: string) => {
|
|
78
|
+
let ent: any = clean.entity[name] = clean.entity[name] = { name, path: {} }
|
|
79
|
+
|
|
80
|
+
each(entity.path, (path: any, pathname: string) => {
|
|
81
|
+
ent.path[pathname] = path
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
return clean
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
resolveGuide
|
|
91
|
+
}
|
package/src/parse.ts
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
import { bundleFromString, createConfig } from '@redocly/openapi-core'
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
// Parse an API definition source into a JSON sructure.
|
|
8
|
+
async function parse(kind: string, source: any, meta?: any) {
|
|
7
9
|
if ('OpenAPI' === kind) {
|
|
8
|
-
return parseOpenAPI(source)
|
|
10
|
+
return parseOpenAPI(source, meta)
|
|
9
11
|
}
|
|
10
12
|
else {
|
|
11
13
|
throw new Error('@voxgig/apidef-parse: unknown kind: ' + kind)
|
|
@@ -13,8 +15,8 @@ async function parse(kind: string, source: any) {
|
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
async function parseOpenAPI(source: any) {
|
|
17
|
-
const config = await createConfig({})
|
|
18
|
+
async function parseOpenAPI(source: any, meta?: any) {
|
|
19
|
+
const config = await createConfig(meta?.config || {})
|
|
18
20
|
let bundle
|
|
19
21
|
|
|
20
22
|
bundle = await bundleFromString({
|
package/src/resolver.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Copyright (c) 2024-2025 Voxgig, MIT License */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import Path from 'node:path'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
async function resolveElements(
|
|
8
|
+
ctx: any,
|
|
9
|
+
kind: string,
|
|
10
|
+
subkind: string,
|
|
11
|
+
standard: Record<string, any>
|
|
12
|
+
) {
|
|
13
|
+
|
|
14
|
+
const { log, model } = ctx
|
|
15
|
+
|
|
16
|
+
// TODO: model access should be via a utility that generates
|
|
17
|
+
// useful errors when the target is missing
|
|
18
|
+
const control = model.main.api.guide.control[kind][subkind]
|
|
19
|
+
|
|
20
|
+
const target = kind + '.' + subkind
|
|
21
|
+
|
|
22
|
+
const elementNames = control.order
|
|
23
|
+
.split(/\s*,\s*/)
|
|
24
|
+
.map((t: string) => t.trim())
|
|
25
|
+
.filter((elem: string) => '' != elem)
|
|
26
|
+
|
|
27
|
+
log.info({
|
|
28
|
+
point: 'element', note: target + ': order: ' + elementNames.join(';'),
|
|
29
|
+
order: elementNames
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const elementResults: any = []
|
|
33
|
+
|
|
34
|
+
for (const en of elementNames) {
|
|
35
|
+
log.debug({ point: 'element', note: target + ': ' + en })
|
|
36
|
+
const element = await resolveElement(en, control, target, standard, ctx)
|
|
37
|
+
const result = await element(ctx)
|
|
38
|
+
elementResults.push(result)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return elementResults
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
async function resolveElement(
|
|
46
|
+
en: string,
|
|
47
|
+
control: any,
|
|
48
|
+
target: string,
|
|
49
|
+
standard: Record<string, any>,
|
|
50
|
+
ctx: any
|
|
51
|
+
) {
|
|
52
|
+
const { log } = ctx
|
|
53
|
+
|
|
54
|
+
let element = standard[en]
|
|
55
|
+
if (element) {
|
|
56
|
+
return element
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const elemdef = control.element[en]
|
|
60
|
+
if (null == elemdef) {
|
|
61
|
+
const err = new Error('Unknown element: ' + en)
|
|
62
|
+
log.error({ what: 'element', element: target + ': ' + en, fail: 'unknown', err })
|
|
63
|
+
throw err
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!en.startsWith('custom')) {
|
|
67
|
+
const err =
|
|
68
|
+
new Error('Custom element name must start with "custom": ' + en)
|
|
69
|
+
log.error({ what: 'element', element: target + ': ' + en, fail: 'prefix', err })
|
|
70
|
+
throw err
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const customtpath = Path.join(ctx.defpath, elemdef.load)
|
|
74
|
+
try {
|
|
75
|
+
const elementModule = require(customtpath)
|
|
76
|
+
element = elementModule[en]
|
|
77
|
+
}
|
|
78
|
+
catch (e: any) {
|
|
79
|
+
const err = new Error('Custom element not found: ' +
|
|
80
|
+
customtpath + ': ' + e.message)
|
|
81
|
+
log.error({ what: 'element', element: target + ': ' + en, fail: 'require', err })
|
|
82
|
+
throw err
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return element
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
resolveElements,
|
|
91
|
+
}
|
package/src/transform/entity.ts
CHANGED
|
@@ -2,25 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
import { each } from 'jostraca'
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { TransformResult, Transform } from '../transform'
|
|
6
6
|
|
|
7
7
|
import { fixName } from '../transform'
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
const entityTransform: Transform = async function(
|
|
11
|
-
ctx:
|
|
12
|
-
guide: Guide,
|
|
13
|
-
tspec: TransformSpec,
|
|
14
|
-
model: any,
|
|
15
|
-
def: any
|
|
11
|
+
ctx: any,
|
|
12
|
+
// guide: Guide,
|
|
13
|
+
// // tspec: TransformSpec,
|
|
14
|
+
// model: any,
|
|
15
|
+
// def: any
|
|
16
16
|
): Promise<TransformResult> {
|
|
17
|
+
const { apimodel, model, def } = ctx
|
|
18
|
+
const guide = model.main.api.guide
|
|
19
|
+
|
|
17
20
|
let msg = ''
|
|
18
21
|
|
|
19
22
|
each(guide.entity, (guideEntity: any) => {
|
|
20
23
|
const entityName = guideEntity.key$
|
|
21
24
|
ctx.log.debug({ point: 'guide-entity', note: entityName })
|
|
22
25
|
|
|
23
|
-
const entityModel: any =
|
|
26
|
+
const entityModel: any = apimodel.main.api.entity[entityName] = {
|
|
24
27
|
op: {},
|
|
25
28
|
field: {},
|
|
26
29
|
cmd: {},
|
package/src/transform/field.ts
CHANGED
|
@@ -2,25 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
import { each, getx } from 'jostraca'
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { TransformResult, Transform } from '../transform'
|
|
6
6
|
|
|
7
7
|
import { fixName } from '../transform'
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
const fieldTransform: Transform = async function(
|
|
12
|
-
ctx:
|
|
13
|
-
guide: Guide,
|
|
14
|
-
tspec: TransformSpec,
|
|
15
|
-
model: any,
|
|
16
|
-
def: any
|
|
12
|
+
ctx: any,
|
|
13
|
+
// guide: Guide,
|
|
14
|
+
// // tspec: TransformSpec,
|
|
15
|
+
// model: any,
|
|
16
|
+
// def: any
|
|
17
17
|
): Promise<TransformResult> {
|
|
18
|
+
const { apimodel, model, def } = ctx
|
|
19
|
+
const guide = model.main.api.guide
|
|
18
20
|
|
|
19
21
|
let msg = 'fields: '
|
|
20
22
|
|
|
21
23
|
each(guide.entity, (guideEntity: any) => {
|
|
22
24
|
const entityName = guideEntity.key$
|
|
23
|
-
const entityModel =
|
|
25
|
+
const entityModel = apimodel.main.api.entity[entityName]
|
|
24
26
|
|
|
25
27
|
let fieldCount = 0
|
|
26
28
|
each(guideEntity.path, (guidePath: any) => {
|
|
@@ -96,88 +98,3 @@ export {
|
|
|
96
98
|
fieldTransform
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
/*
|
|
103
|
-
|
|
104
|
-
# API Specification Transform Guide
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@"@voxgig/apidef/model/guide.jsonic"
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
guide: control: transform: openapi: order: `
|
|
111
|
-
|
|
112
|
-
top,
|
|
113
|
-
entity,
|
|
114
|
-
operation,
|
|
115
|
-
field,
|
|
116
|
-
customField,
|
|
117
|
-
|
|
118
|
-
`
|
|
119
|
-
|
|
120
|
-
guide: transform: customField: {
|
|
121
|
-
load: 'customField.js'
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
guide: entity: {
|
|
126
|
-
pet: path: {
|
|
127
|
-
'/pet/{petId}': {
|
|
128
|
-
op:{ load: 'get', create: 'post', update: 'put' }
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
pet: test: {
|
|
132
|
-
quick: {
|
|
133
|
-
active: true,
|
|
134
|
-
create: { id: 1, name:'Rex' },
|
|
135
|
-
load: { id: 1 },
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
# direct custom definition
|
|
140
|
-
pet: def: {}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const { each, getx } = require('jostraca')
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
async function customField(ctx, tspec, model, def) {
|
|
150
|
-
const { spec, util: {fixName} } = ctx
|
|
151
|
-
|
|
152
|
-
const nameField = {
|
|
153
|
-
name: 'name',
|
|
154
|
-
type: 'string',
|
|
155
|
-
short: 'Name of pet'
|
|
156
|
-
}
|
|
157
|
-
fixName(nameField, nameField.name)
|
|
158
|
-
fixName(nameField, nameField.type, 'type')
|
|
159
|
-
|
|
160
|
-
const ageField = {
|
|
161
|
-
name: 'age',
|
|
162
|
-
type: 'number',
|
|
163
|
-
short: 'Age of pet'
|
|
164
|
-
}
|
|
165
|
-
fixName(ageField, ageField.name)
|
|
166
|
-
fixName(ageField, ageField.type, 'type')
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Object.assign(model.main.api.entity.pet.field, {
|
|
170
|
-
name: nameField,
|
|
171
|
-
age: ageField,
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
return { ok: true }
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
module.exports = {
|
|
179
|
-
customField
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
*/
|
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
import { each, getx } from 'jostraca'
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { TransformResult } from '../transform'
|
|
6
6
|
|
|
7
7
|
import { fixName, OPKIND } from '../transform'
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
const operationTransform = async function(
|
|
12
|
-
ctx:
|
|
13
|
-
guide: Guide,
|
|
14
|
-
tspec: TransformSpec,
|
|
15
|
-
model: any,
|
|
16
|
-
def: any
|
|
12
|
+
ctx: any,
|
|
13
|
+
// guide: Guide,
|
|
14
|
+
// // tspec: TransformSpec,
|
|
15
|
+
// model: any,
|
|
16
|
+
// def: any
|
|
17
17
|
): Promise<TransformResult> {
|
|
18
|
+
const { apimodel, model, def } = ctx
|
|
19
|
+
const guide = model.main.api.guide
|
|
18
20
|
|
|
19
21
|
let msg = 'operations: '
|
|
20
22
|
|
|
@@ -48,6 +50,7 @@ const operationTransform = async function(
|
|
|
48
50
|
// Resolve the JSON structure of the request or response.
|
|
49
51
|
// NOTE: uses heuristics.
|
|
50
52
|
const resolveTransform = (
|
|
53
|
+
entityModel: any,
|
|
51
54
|
op: any,
|
|
52
55
|
kind: 'res' | 'req',
|
|
53
56
|
direction: 'resform' | 'reqform',
|
|
@@ -69,28 +72,39 @@ const operationTransform = async function(
|
|
|
69
72
|
getx(mdef, 'responses.201.content')) :
|
|
70
73
|
getx(mdef, 'requestBody.content')
|
|
71
74
|
|
|
75
|
+
// console.log(entityModel)
|
|
76
|
+
// console.log(mdef)
|
|
77
|
+
// console.log(getx(mdef, 'responses.200.content'))
|
|
78
|
+
// console.log(kind, method, pathdef, content)
|
|
72
79
|
|
|
73
|
-
|
|
80
|
+
if (content) {
|
|
74
81
|
|
|
75
|
-
|
|
82
|
+
const schema = content['application/json']?.schema
|
|
76
83
|
|
|
77
|
-
|
|
78
|
-
'resform' === direction ? resolveResponseTransform : resolveRequestTransform
|
|
84
|
+
const propkeys = null == schema?.properties ? [] : Object.keys(schema.properties)
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
const resolveDirectionTransform =
|
|
87
|
+
'resform' === direction ? resolveResponseTransform : resolveRequestTransform
|
|
88
|
+
|
|
89
|
+
const transform = resolveDirectionTransform(
|
|
90
|
+
op,
|
|
91
|
+
kind,
|
|
92
|
+
method,
|
|
93
|
+
mdef,
|
|
94
|
+
content,
|
|
95
|
+
schema,
|
|
96
|
+
propkeys
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
// out = JSON.stringify(transform)
|
|
100
|
+
out = transform
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
out = 'res' === kind ? '`body`' : '`reqdata`'
|
|
104
|
+
}
|
|
92
105
|
}
|
|
93
106
|
|
|
107
|
+
|
|
94
108
|
return out
|
|
95
109
|
}
|
|
96
110
|
|
|
@@ -218,8 +232,8 @@ const operationTransform = async function(
|
|
|
218
232
|
param: {},
|
|
219
233
|
query: {},
|
|
220
234
|
// transform: {
|
|
221
|
-
resform: resolveTransform(op, kind, 'resform', pathdef),
|
|
222
|
-
reqform: resolveTransform(op, kind, 'reqform', pathdef),
|
|
235
|
+
resform: resolveTransform(entityModel, op, kind, 'resform', pathdef),
|
|
236
|
+
reqform: resolveTransform(entityModel, op, kind, 'reqform', pathdef),
|
|
223
237
|
// }
|
|
224
238
|
}
|
|
225
239
|
|
|
@@ -270,7 +284,7 @@ const operationTransform = async function(
|
|
|
270
284
|
|
|
271
285
|
each(guide.entity, (guideEntity: any) => {
|
|
272
286
|
let opcount = 0
|
|
273
|
-
const entityModel =
|
|
287
|
+
const entityModel = apimodel.main.api.entity[guideEntity.key$]
|
|
274
288
|
each(guideEntity.path, (guidePath: any) => {
|
|
275
289
|
const pathdef = def.paths[guidePath.key$]
|
|
276
290
|
|
package/src/transform/top.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
|
|
2
2
|
import { each, getx } from 'jostraca'
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type { TransformResult } from '../transform'
|
|
5
5
|
|
|
6
6
|
import { fixName } from '../transform'
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
const topTransform = async function(
|
|
10
|
-
ctx:
|
|
11
|
-
guide: Guide,
|
|
12
|
-
tspec: TransformSpec,
|
|
13
|
-
model: any,
|
|
14
|
-
def: any
|
|
10
|
+
ctx: any,
|
|
11
|
+
// guide: Guide,
|
|
12
|
+
// // tspec: TransformSpec,
|
|
13
|
+
// model: any,
|
|
14
|
+
// def: any
|
|
15
15
|
): Promise<TransformResult> {
|
|
16
|
-
const {
|
|
16
|
+
const { apimodel, def } = ctx
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// const { spec } = ctx
|
|
19
|
+
|
|
20
|
+
apimodel.main.def.info = def.info
|
|
21
|
+
apimodel.main.def.servers = def.servers
|
|
20
22
|
|
|
21
23
|
return { ok: true, msg: 'top' }
|
|
22
24
|
}
|
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,16 @@ 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
|
+
console.log(err)
|
|
110
|
+
throw err
|
|
105
111
|
}
|
|
106
112
|
|
|
107
113
|
return tspec
|
|
@@ -146,10 +152,10 @@ async function resolveTransform(tn: string, ctx: TransformCtx) {
|
|
|
146
152
|
}
|
|
147
153
|
|
|
148
154
|
|
|
149
|
-
|
|
150
155
|
async function processTransforms(
|
|
151
156
|
ctx: TransformCtx,
|
|
152
|
-
spec: TransformSpec,
|
|
157
|
+
// spec: TransformSpec,
|
|
158
|
+
transforms: any[],
|
|
153
159
|
apimodel: any,
|
|
154
160
|
def: any
|
|
155
161
|
): Promise<ProcessResult> {
|
|
@@ -162,15 +168,21 @@ async function processTransforms(
|
|
|
162
168
|
const guide: Guide = GuideShape(ctx.model.main.api.guide)
|
|
163
169
|
|
|
164
170
|
|
|
165
|
-
for (let tI = 0; tI < spec.transform.length; tI++) {
|
|
166
|
-
|
|
171
|
+
// for (let tI = 0; tI < spec.transform.length; tI++) {
|
|
172
|
+
// const transform = spec.transform[tI]
|
|
173
|
+
|
|
174
|
+
for (let tI = 0; tI < transforms.length; tI++) {
|
|
175
|
+
const transform = transforms[tI]
|
|
167
176
|
|
|
168
177
|
try {
|
|
169
|
-
const tres = await transform(ctx, guide,
|
|
178
|
+
const tres = await transform(ctx, guide, apimodel, def)
|
|
170
179
|
pres.ok = pres.ok && tres.ok
|
|
171
180
|
pres.results.push(tres)
|
|
172
181
|
}
|
|
173
182
|
catch (err: any) {
|
|
183
|
+
// TODO: fix: this error does not get printed
|
|
184
|
+
console.log(err)
|
|
185
|
+
|
|
174
186
|
pres.ok = false
|
|
175
187
|
pres.msg += transform.name + ': ' + err.message + '\n'
|
|
176
188
|
pres.results.push({
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
},
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
const OpenModelShape = Gubu(Open(ModelShape))
|
|
37
|
+
|
|
38
|
+
type Model = ReturnType<typeof ModelShape>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
const BuildShape = Gubu({
|
|
42
|
+
spec: {
|
|
43
|
+
base: '',
|
|
44
|
+
path: '',
|
|
45
|
+
debug: '',
|
|
46
|
+
use: {},
|
|
47
|
+
res: [],
|
|
48
|
+
require: '',
|
|
49
|
+
log: {},
|
|
50
|
+
fs: Any(),
|
|
51
|
+
watch: {
|
|
52
|
+
mod: true,
|
|
53
|
+
add: true,
|
|
54
|
+
rem: true,
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
const OpenBuildShape = Gubu(Open(BuildShape))
|
|
59
|
+
|
|
60
|
+
type Build = ReturnType<typeof BuildShape>
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
type ApiModel = {
|
|
65
|
+
main: {
|
|
66
|
+
api: {
|
|
67
|
+
entity: Record<string, any>
|
|
68
|
+
}
|
|
69
|
+
def: Record<string, any>
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
export {
|
|
75
|
+
OpenModelShape,
|
|
76
|
+
OpenBuildShape,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
export type {
|
|
81
|
+
Log,
|
|
82
|
+
FsUtil,
|
|
83
|
+
ApiDefOptions,
|
|
84
|
+
Model,
|
|
85
|
+
Build,
|
|
86
|
+
ApiModel,
|
|
87
|
+
}
|
|
88
|
+
|