@voxgig/apidef 1.1.1 → 1.3.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/bin/voxgig-apidef +0 -2
- package/dist/apidef.d.ts +26 -13
- package/dist/apidef.js +114 -146
- package/dist/apidef.js.map +1 -1
- package/dist/parse.d.ts +2 -0
- package/dist/parse.js +26 -0
- package/dist/parse.js.map +1 -0
- package/dist/transform/entity.d.ts +2 -5
- package/dist/transform/entity.js +16 -8
- package/dist/transform/entity.js.map +1 -1
- package/dist/transform/field.d.ts +2 -5
- package/dist/transform/field.js +11 -8
- package/dist/transform/field.js.map +1 -1
- package/dist/transform/manual.d.ts +2 -5
- package/dist/transform/manual.js +5 -4
- package/dist/transform/manual.js.map +1 -1
- package/dist/transform/operation.d.ts +2 -5
- package/dist/transform/operation.js +83 -7
- package/dist/transform/operation.js.map +1 -1
- package/dist/transform/top.d.ts +2 -5
- package/dist/transform/top.js +7 -7
- package/dist/transform/top.js.map +1 -1
- package/dist/transform.d.ts +71 -5
- package/dist/transform.js +45 -9
- package/dist/transform.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/apidef.jsonic +44 -0
- package/package.json +11 -11
- package/src/apidef.ts +117 -171
- package/src/parse.ts +36 -0
- package/src/transform/entity.ts +22 -9
- package/src/transform/field.ts +12 -8
- package/src/transform/manual.ts +10 -3
- package/src/transform/operation.ts +105 -9
- package/src/transform/top.ts +11 -5
- package/src/transform.ts +60 -11
- /package/model/{guide.jsonic → guide.jsonic.off} +0 -0
package/src/apidef.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Fs from 'node:fs'
|
|
4
4
|
import Path from 'node:path'
|
|
5
|
-
|
|
5
|
+
import { inspect } from 'node:util'
|
|
6
6
|
|
|
7
7
|
import { bundleFromString, createConfig } from '@redocly/openapi-core'
|
|
8
8
|
import { FSWatcher } from 'chokidar'
|
|
9
9
|
import { Aontu, Context } from 'aontu'
|
|
10
|
-
|
|
10
|
+
import { Gubu, Open, Any } from 'gubu'
|
|
11
11
|
import { prettyPino, Pino } from '@voxgig/util'
|
|
12
12
|
|
|
13
13
|
|
|
@@ -19,88 +19,94 @@ import {
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
type ApiDefOptions = {
|
|
22
|
+
def?: string
|
|
22
23
|
fs?: any
|
|
23
24
|
pino?: ReturnType<typeof Pino>
|
|
24
25
|
debug?: boolean | string
|
|
26
|
+
folder?: string
|
|
27
|
+
meta?: Record<string, any>
|
|
28
|
+
outprefix?: string
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
def:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
32
|
+
const ModelShape = Gubu({
|
|
33
|
+
def: String,
|
|
34
|
+
main: {
|
|
35
|
+
guide: {},
|
|
36
|
+
sdk: {},
|
|
37
|
+
def: {},
|
|
38
|
+
api: {},
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
const OpenModelShape = Gubu(Open(ModelShape))
|
|
42
|
+
|
|
43
|
+
type Model = ReturnType<typeof ModelShape>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
const BuildShape = Gubu({
|
|
47
|
+
spec: {
|
|
48
|
+
base: '',
|
|
49
|
+
path: '',
|
|
50
|
+
debug: '',
|
|
51
|
+
use: {},
|
|
52
|
+
res: [],
|
|
53
|
+
require: '',
|
|
54
|
+
log: {},
|
|
55
|
+
fs: Any()
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
const OpenBuildShape = Gubu(Open(BuildShape))
|
|
35
59
|
|
|
60
|
+
type Build = ReturnType<typeof BuildShape>
|
|
36
61
|
|
|
37
|
-
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
function ApiDef(opts: ApiDefOptions) {
|
|
38
65
|
const fs = opts.fs || Fs
|
|
39
66
|
const pino = prettyPino('apidef', opts)
|
|
40
67
|
|
|
41
68
|
const log = pino.child({ cmp: 'apidef' })
|
|
42
69
|
|
|
43
70
|
|
|
44
|
-
async function
|
|
45
|
-
|
|
46
|
-
log.debug({ point: 'watch-spec', spec })
|
|
47
|
-
|
|
48
|
-
await generate(spec)
|
|
49
|
-
|
|
50
|
-
const fsw = new FSWatcher()
|
|
51
|
-
|
|
52
|
-
fsw.on('change', (...args: any[]) => {
|
|
53
|
-
log.trace({ watch: 'change', file: args[0] })
|
|
54
|
-
generate(spec)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
log.trace({ watch: 'add', what: 'def', file: spec.def })
|
|
58
|
-
fsw.add(spec.def)
|
|
59
|
-
|
|
60
|
-
log.trace({ watch: 'add', what: 'guide', file: spec.guide })
|
|
61
|
-
fsw.add(spec.guide)
|
|
62
|
-
}
|
|
71
|
+
async function generate(spec: any) {
|
|
72
|
+
const start = Date.now()
|
|
63
73
|
|
|
74
|
+
const model: Model = OpenModelShape(spec.model)
|
|
75
|
+
const build: Build = OpenBuildShape(spec.build)
|
|
64
76
|
|
|
65
|
-
|
|
66
|
-
const start = Date.now()
|
|
77
|
+
const buildspec = build.spec
|
|
67
78
|
|
|
68
|
-
|
|
79
|
+
let defpath = model.def
|
|
69
80
|
|
|
70
|
-
|
|
81
|
+
// TOOD: defpath should be independently defined
|
|
82
|
+
defpath = Path.join(buildspec.base, '..', 'def', defpath)
|
|
71
83
|
|
|
72
|
-
log.info({
|
|
73
|
-
|
|
84
|
+
log.info({
|
|
85
|
+
point: 'generate-start',
|
|
86
|
+
note: defpath.replace(process.cwd(), '.'), defpath, start
|
|
87
|
+
})
|
|
74
88
|
|
|
75
89
|
// TODO: Validate spec
|
|
76
90
|
const ctx = {
|
|
77
91
|
log,
|
|
78
92
|
spec,
|
|
79
|
-
guide: {},
|
|
80
93
|
opts,
|
|
81
94
|
util: { fixName },
|
|
82
|
-
defpath: Path.dirname(defpath)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const guide = await resolveGuide(spec, opts)
|
|
88
|
-
|
|
89
|
-
if (null == guide) {
|
|
90
|
-
return
|
|
95
|
+
defpath: Path.dirname(defpath),
|
|
96
|
+
model,
|
|
91
97
|
}
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
log.debug({ point: 'guide', guide })
|
|
95
|
-
|
|
96
|
-
ctx.guide = guide
|
|
97
99
|
const transformSpec = await resolveTransforms(ctx)
|
|
98
|
-
|
|
100
|
+
|
|
101
|
+
log.debug({
|
|
102
|
+
point: 'transform', spec: transformSpec,
|
|
103
|
+
note: log.levelVal <= 20 ? inspect(transformSpec) : ''
|
|
104
|
+
})
|
|
99
105
|
|
|
100
106
|
|
|
101
107
|
let source
|
|
102
108
|
try {
|
|
103
|
-
source = fs.readFileSync(
|
|
109
|
+
source = fs.readFileSync(defpath, 'utf8')
|
|
104
110
|
}
|
|
105
111
|
catch (err: any) {
|
|
106
112
|
log.error({ read: 'fail', what: 'def', file: defpath, err })
|
|
@@ -124,7 +130,7 @@ function ApiDef(opts: ApiDefOptions = {}) {
|
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
|
|
127
|
-
const
|
|
133
|
+
const apimodel = {
|
|
128
134
|
main: {
|
|
129
135
|
api: {
|
|
130
136
|
entity: {}
|
|
@@ -133,36 +139,41 @@ function ApiDef(opts: ApiDefOptions = {}) {
|
|
|
133
139
|
},
|
|
134
140
|
}
|
|
135
141
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const processResult = await processTransforms(ctx, transformSpec, model, def)
|
|
142
|
+
const def = bundle.bundle.parsed
|
|
143
|
+
const processResult = await processTransforms(ctx, transformSpec, apimodel, def)
|
|
139
144
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
catch (err: any) {
|
|
149
|
-
log.error({ process: 'fail', what: 'transform', err })
|
|
150
|
-
throw err
|
|
145
|
+
if (!processResult.ok) {
|
|
146
|
+
log.error({
|
|
147
|
+
fail: 'process', point: 'transform-result',
|
|
148
|
+
result: processResult, note: processResult.msg,
|
|
149
|
+
err: processResult.results[0]?.err
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
return { ok: false, name: 'apidef', processResult }
|
|
151
153
|
}
|
|
152
154
|
|
|
153
|
-
const modelapi = { main: { api:
|
|
155
|
+
const modelapi = { main: { api: apimodel.main.api } }
|
|
154
156
|
let modelSrc = JSON.stringify(modelapi, null, 2)
|
|
155
|
-
modelSrc = modelSrc.substring(1, modelSrc.length - 1)
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
modelSrc =
|
|
159
|
+
'# GENERATED FILE - DO NOT EDIT\n\n' +
|
|
160
|
+
modelSrc.substring(1, modelSrc.length - 1).replace(/\n /g, '\n')
|
|
158
161
|
|
|
162
|
+
const modelPath = Path.normalize(spec.config.model)
|
|
163
|
+
// console.log('modelPath', modelPath)
|
|
164
|
+
writeChanged('api-model', modelPath, modelSrc)
|
|
159
165
|
|
|
160
|
-
const modelBasePath = Path.dirname(
|
|
161
|
-
const defFilePath =
|
|
166
|
+
const modelBasePath = Path.dirname(modelPath)
|
|
167
|
+
const defFilePath =
|
|
168
|
+
Path.join(modelBasePath,
|
|
169
|
+
(null == opts.outprefix ? '' : opts.outprefix) + 'def-generated.jsonic')
|
|
162
170
|
|
|
163
|
-
const modelDef = { main: { def:
|
|
171
|
+
const modelDef = { main: { def: apimodel.main.def } }
|
|
164
172
|
let modelDefSrc = JSON.stringify(modelDef, null, 2)
|
|
165
|
-
|
|
173
|
+
|
|
174
|
+
modelDefSrc =
|
|
175
|
+
'# GENERATED FILE - DO NOT EDIT\n\n' +
|
|
176
|
+
modelDefSrc.substring(1, modelDefSrc.length - 1).replace(/\n /g, '\n')
|
|
166
177
|
|
|
167
178
|
writeChanged('def-model', defFilePath, modelDefSrc)
|
|
168
179
|
|
|
@@ -170,13 +181,13 @@ function ApiDef(opts: ApiDefOptions = {}) {
|
|
|
170
181
|
|
|
171
182
|
return {
|
|
172
183
|
ok: true,
|
|
173
|
-
|
|
184
|
+
name: 'apidef',
|
|
185
|
+
apimodel,
|
|
174
186
|
}
|
|
175
187
|
}
|
|
176
188
|
|
|
177
189
|
|
|
178
|
-
|
|
179
|
-
function writeChanged(what: string, path: string, content: string) {
|
|
190
|
+
function writeChanged(point: string, path: string, content: string) {
|
|
180
191
|
let exists = false
|
|
181
192
|
let changed = false
|
|
182
193
|
let action = ''
|
|
@@ -193,10 +204,12 @@ function ApiDef(opts: ApiDefOptions = {}) {
|
|
|
193
204
|
|
|
194
205
|
changed = existingContent !== content
|
|
195
206
|
|
|
207
|
+
// console.log('WC', changed, path, existingContent, content)
|
|
208
|
+
|
|
196
209
|
log.info({
|
|
197
|
-
point: 'write-' +
|
|
198
|
-
note: 'changed
|
|
199
|
-
write: 'file',
|
|
210
|
+
point: 'write-' + point,
|
|
211
|
+
note: (changed ? '' : 'not-') + 'changed ' + path,
|
|
212
|
+
write: 'file', skip: !changed, exists, changed,
|
|
200
213
|
contentLength: content.length, file: path
|
|
201
214
|
})
|
|
202
215
|
|
|
@@ -207,116 +220,49 @@ function ApiDef(opts: ApiDefOptions = {}) {
|
|
|
207
220
|
}
|
|
208
221
|
catch (err: any) {
|
|
209
222
|
log.error({
|
|
210
|
-
fail: action,
|
|
223
|
+
fail: action, point, file: path, exists, changed,
|
|
211
224
|
contentLength: content.length, err
|
|
212
225
|
})
|
|
226
|
+
err.__logged__ = true
|
|
213
227
|
throw err
|
|
214
228
|
}
|
|
215
229
|
}
|
|
216
230
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (null == spec.guide) {
|
|
221
|
-
spec.guide = spec.def + '-guide.jsonic'
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const path = Path.normalize(spec.guide)
|
|
225
|
-
let src: string
|
|
226
|
-
|
|
227
|
-
let action = ''
|
|
228
|
-
let exists = false
|
|
229
|
-
try {
|
|
230
|
-
|
|
231
|
-
action = 'exists'
|
|
232
|
-
let exists = fs.existsSync(path)
|
|
233
|
-
|
|
234
|
-
log.debug({ read: 'file', what: 'guide', file: path, exists })
|
|
235
|
-
|
|
236
|
-
if (exists) {
|
|
237
|
-
action = 'read'
|
|
238
|
-
src = fs.readFileSync(path, 'utf8')
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
src = `
|
|
242
|
-
# API Specification Transform Guide
|
|
243
|
-
|
|
244
|
-
@"@voxgig/apidef/model/guide.jsonic"
|
|
245
|
-
|
|
246
|
-
guide: entity: {
|
|
247
|
-
|
|
231
|
+
return {
|
|
232
|
+
generate,
|
|
233
|
+
}
|
|
248
234
|
}
|
|
249
235
|
|
|
250
|
-
guide: control: transform: openapi: order: \`
|
|
251
|
-
top,
|
|
252
|
-
entity,
|
|
253
|
-
operation,
|
|
254
|
-
field,
|
|
255
|
-
manual,
|
|
256
|
-
\`
|
|
257
236
|
|
|
258
|
-
`
|
|
259
|
-
action = 'write'
|
|
260
|
-
fs.writeFileSync(path, src)
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
catch (err: any) {
|
|
264
|
-
log.error({ fail: action, what: 'guide', file: path, exists, err })
|
|
265
|
-
throw err
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const aopts = { path }
|
|
269
|
-
const root = Aontu(src, aopts)
|
|
270
|
-
const hasErr = root.err && 0 < root.err.length
|
|
271
|
-
|
|
272
|
-
if (hasErr) {
|
|
273
|
-
for (let serr of root.err) {
|
|
274
|
-
let err: any = new Error('Guide model: ' + serr.msg)
|
|
275
|
-
err.cause$ = [serr]
|
|
276
237
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
238
|
+
ApiDef.makeBuild = async function(opts: ApiDefOptions) {
|
|
239
|
+
let apidef: any = undefined
|
|
280
240
|
|
|
281
|
-
|
|
241
|
+
const outprefix = null == opts.outprefix ? '' : opts.outprefix
|
|
282
242
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
}
|
|
243
|
+
const config = {
|
|
244
|
+
def: opts.def || 'no-def',
|
|
245
|
+
kind: 'openapi3',
|
|
246
|
+
model: opts.folder ?
|
|
247
|
+
(opts.folder + '/' + outprefix + 'api-generated.jsonic') : 'no-model',
|
|
248
|
+
meta: opts.meta || {},
|
|
249
|
+
}
|
|
292
250
|
|
|
293
|
-
|
|
294
|
-
const guide = spec.guideModel = root.gen(genctx)
|
|
251
|
+
const build = async function(model: any, build: any, ctx: any) {
|
|
295
252
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
err.errs = () => genctx.err
|
|
302
|
-
throw err
|
|
253
|
+
if (null == apidef) {
|
|
254
|
+
apidef = ApiDef({
|
|
255
|
+
...opts,
|
|
256
|
+
pino: build.log,
|
|
257
|
+
})
|
|
303
258
|
}
|
|
304
259
|
|
|
305
|
-
|
|
306
|
-
spec.guideModelPath = Path.join(pathParts.dir, pathParts.name + '.json')
|
|
307
|
-
|
|
308
|
-
const updatedSrc = JSON.stringify(guide, null, 2)
|
|
309
|
-
|
|
310
|
-
writeChanged('guide-model', spec.guideModelPath, updatedSrc)
|
|
311
|
-
|
|
312
|
-
return guide
|
|
260
|
+
return await apidef.generate({ model, build, config })
|
|
313
261
|
}
|
|
314
262
|
|
|
263
|
+
build.step = 'pre'
|
|
315
264
|
|
|
316
|
-
return
|
|
317
|
-
watch,
|
|
318
|
-
generate,
|
|
319
|
-
}
|
|
265
|
+
return build
|
|
320
266
|
}
|
|
321
267
|
|
|
322
268
|
|
|
@@ -324,7 +270,7 @@ guide: control: transform: openapi: order: \`
|
|
|
324
270
|
|
|
325
271
|
export type {
|
|
326
272
|
ApiDefOptions,
|
|
327
|
-
ApiDefSpec,
|
|
273
|
+
// ApiDefSpec,
|
|
328
274
|
}
|
|
329
275
|
|
|
330
276
|
|
package/src/parse.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Voxgig, MIT License */
|
|
2
|
+
|
|
3
|
+
import { bundleFromString, createConfig } from '@redocly/openapi-core'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async function parse(kind: string, source: any) {
|
|
7
|
+
if ('OpenAPI' === kind) {
|
|
8
|
+
return parseOpenAPI(source)
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
throw new Error('@voxgig/apidef-parse: unknown kind: ' + kind)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async function parseOpenAPI(source: any) {
|
|
17
|
+
const config = await createConfig({})
|
|
18
|
+
let bundle
|
|
19
|
+
|
|
20
|
+
bundle = await bundleFromString({
|
|
21
|
+
source,
|
|
22
|
+
config,
|
|
23
|
+
dereference: true,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// console.dir(bundle.bundle, { depth: 1 })
|
|
27
|
+
|
|
28
|
+
const def = bundle.bundle.parsed
|
|
29
|
+
|
|
30
|
+
return def
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
export {
|
|
35
|
+
parse
|
|
36
|
+
}
|
package/src/transform/entity.ts
CHANGED
|
@@ -2,19 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
import { each } from 'jostraca'
|
|
4
4
|
|
|
5
|
-
import type { TransformCtx, TransformSpec } from '../transform'
|
|
5
|
+
import type { TransformCtx, TransformSpec, TransformResult, Transform, Guide } from '../transform'
|
|
6
6
|
|
|
7
7
|
import { fixName } from '../transform'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const entityTransform: Transform = async function(
|
|
11
|
+
ctx: TransformCtx,
|
|
12
|
+
guide: Guide,
|
|
13
|
+
tspec: TransformSpec,
|
|
14
|
+
model: any,
|
|
15
|
+
def: any
|
|
16
|
+
): Promise<TransformResult> {
|
|
13
17
|
let msg = ''
|
|
14
18
|
|
|
19
|
+
// console.log('DEF', def)
|
|
20
|
+
// console.log('GUIDE', guide)
|
|
21
|
+
|
|
15
22
|
each(guide.entity, (guideEntity: any) => {
|
|
23
|
+
const entityName = guideEntity.key$
|
|
24
|
+
ctx.log.debug({ point: 'guide-entity', note: entityName })
|
|
16
25
|
|
|
17
|
-
const entityModel: any = model.main.api.entity[
|
|
26
|
+
const entityModel: any = model.main.api.entity[entityName] = {
|
|
18
27
|
op: {},
|
|
19
28
|
field: {},
|
|
20
29
|
cmd: {},
|
|
@@ -27,14 +36,19 @@ async function entityTransform(ctx: TransformCtx, tspec: TransformSpec, model: a
|
|
|
27
36
|
fixName(entityModel, guideEntity.key$)
|
|
28
37
|
|
|
29
38
|
each(guideEntity.path, (guidePath: any) => {
|
|
30
|
-
const
|
|
39
|
+
const path = guidePath.key$
|
|
40
|
+
const pathdef = def.paths[path]
|
|
41
|
+
|
|
42
|
+
// console.log('APIDEF FIND PATH', guidePath.key$, Object.keys(def.paths),
|
|
43
|
+
// Object.keys(def.paths).includes(guidePath.key$))
|
|
31
44
|
|
|
32
45
|
if (null == pathdef) {
|
|
33
|
-
throw new Error('
|
|
46
|
+
throw new Error('path not found in OpenAPI: ' + path +
|
|
34
47
|
' (entity: ' + guideEntity.name + ')')
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
|
|
50
|
+
// TODO: is this needed?
|
|
51
|
+
guidePath.parts$ = path.split('/')
|
|
38
52
|
guidePath.params$ = guidePath.parts$
|
|
39
53
|
.filter((p: string) => p.startsWith('{'))
|
|
40
54
|
.map((p: string) => p.substring(1, p.length - 1))
|
|
@@ -42,7 +56,6 @@ async function entityTransform(ctx: TransformCtx, tspec: TransformSpec, model: a
|
|
|
42
56
|
})
|
|
43
57
|
|
|
44
58
|
msg += guideEntity.name + ' '
|
|
45
|
-
|
|
46
59
|
})
|
|
47
60
|
|
|
48
61
|
return { ok: true, msg }
|
package/src/transform/field.ts
CHANGED
|
@@ -2,31 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
import { each, getx } from 'jostraca'
|
|
4
4
|
|
|
5
|
-
import type { TransformCtx, TransformSpec } from '../transform'
|
|
5
|
+
import type { TransformCtx, TransformSpec, TransformResult, Transform, Guide } from '../transform'
|
|
6
6
|
|
|
7
7
|
import { fixName } from '../transform'
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
async function
|
|
11
|
+
const fieldTransform: Transform = async function(
|
|
12
12
|
ctx: TransformCtx,
|
|
13
|
+
guide: Guide,
|
|
13
14
|
tspec: TransformSpec,
|
|
14
15
|
model: any,
|
|
15
16
|
def: any
|
|
16
|
-
) {
|
|
17
|
-
|
|
17
|
+
): Promise<TransformResult> {
|
|
18
|
+
|
|
18
19
|
let msg = 'fields: '
|
|
19
20
|
|
|
20
21
|
each(guide.entity, (guideEntity: any) => {
|
|
22
|
+
const entityName = guideEntity.key$
|
|
23
|
+
const entityModel = model.main.api.entity[entityName]
|
|
21
24
|
|
|
22
|
-
const entityModel = model.main.api.entity[guideEntity.key$]
|
|
23
25
|
let fieldCount = 0
|
|
24
26
|
each(guideEntity.path, (guidePath: any) => {
|
|
25
|
-
const
|
|
27
|
+
const path = guidePath.key$
|
|
28
|
+
const pathdef = def.paths[path]
|
|
26
29
|
|
|
27
30
|
each(guidePath.op, (op: any) => {
|
|
31
|
+
const opname = op.key$
|
|
28
32
|
|
|
29
|
-
if ('load' ===
|
|
33
|
+
if ('load' === opname) {
|
|
30
34
|
fieldCount = fieldbuild(entityModel, pathdef, op, guidePath, guideEntity, model)
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -127,7 +131,7 @@ guide: transform: customField: {
|
|
|
127
131
|
guide: entity: {
|
|
128
132
|
pet: path: {
|
|
129
133
|
'/pet/{petId}': {
|
|
130
|
-
op:{ load: 'get', create: 'post',
|
|
134
|
+
op:{ load: 'get', create: 'post', update: 'put' }
|
|
131
135
|
}
|
|
132
136
|
}
|
|
133
137
|
pet: test: {
|
package/src/transform/manual.ts
CHANGED
|
@@ -3,13 +3,20 @@ import { Jsonic } from '@jsonic/jsonic-next'
|
|
|
3
3
|
|
|
4
4
|
import { each, getx } from 'jostraca'
|
|
5
5
|
|
|
6
|
-
import type { TransformCtx, TransformSpec } from '../transform'
|
|
6
|
+
import type { TransformCtx, TransformSpec, TransformResult, Transform, Guide } from '../transform'
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
const { deep } = Jsonic.util
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
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 { model: { main: { guide: { manual } } } } = ctx
|
|
13
20
|
|
|
14
21
|
deep(model, manual)
|
|
15
22
|
|