@voxgig/apidef 1.2.0 → 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.
@@ -3,12 +3,19 @@ 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
- async function manualTransform(ctx: TransformCtx, tspec: TransformSpec, model: any, def: any) {
11
+ const manualTransform = async function(
12
+ ctx: TransformCtx,
13
+ guide: Guide,
14
+ tspec: TransformSpec,
15
+ model: any,
16
+ def: any
17
+ ): Promise<TransformResult> {
18
+
12
19
  const { model: { main: { guide: { manual } } } } = ctx
13
20
 
14
21
  deep(model, manual)
@@ -2,19 +2,20 @@
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
- import { fixName } from '../transform'
7
+ import { fixName, OPKIND } from '../transform'
8
8
 
9
9
 
10
10
 
11
- async function operationTransform(
11
+ const operationTransform = async function(
12
12
  ctx: TransformCtx,
13
+ guide: Guide,
13
14
  tspec: TransformSpec,
14
15
  model: any,
15
16
  def: any
16
- ) {
17
- const { model: { main: { guide } } } = ctx
17
+ ): Promise<TransformResult> {
18
+
18
19
  let msg = 'operations: '
19
20
 
20
21
  const paramBuilder = (paramMap: any, paramDef: any,
@@ -43,19 +44,115 @@ async function operationTransform(
43
44
  fixName(queryMap[queryDef.name], type, 'type')
44
45
  }
45
46
 
47
+
48
+ // Resolve the JSON path to the data (the "place").
49
+ const resolvePlace = (op: any, kind: 'res' | 'req', pathdef: any) => {
50
+ const opname = op.key$
51
+ // console.log('RP', kind, op)
52
+
53
+ let place = null == op.place ? '' : op.place
54
+
55
+ if (null != place && '' !== place) {
56
+ return place
57
+ }
58
+
59
+ const method = op.method
60
+ const mdef = pathdef[method]
61
+
62
+ // TODO: fix getx
63
+ const content = 'res' === kind ?
64
+ (getx(mdef, 'responses.200.content') ||
65
+ getx(mdef, 'responses.201.content')) :
66
+ getx(mdef, 'requestBody.content')
67
+
68
+
69
+ // console.log('RP', kind, op, 'content', null == content)
70
+
71
+ if (null == content) {
72
+ return place
73
+ }
74
+
75
+ const schema = content['application/json']?.schema
76
+
77
+ // console.log('RP', kind, op, 'schema', null == schema)
78
+
79
+ if (null == schema) {
80
+ return place
81
+ }
82
+
83
+
84
+ const propkeys = null == schema.properties ? [] : Object.keys(schema.properties)
85
+
86
+ // HEURISTIC: guess place
87
+ if ('list' === opname) {
88
+ if ('array' === schema.type) {
89
+ place = ''
90
+ }
91
+ else {
92
+ if (1 === propkeys.length) {
93
+ place = propkeys[0]
94
+ }
95
+ else {
96
+ // Use sub property that is an array
97
+ for (let pk of propkeys) {
98
+ if ('array' === schema.properties[pk]?.type) {
99
+ place = pk
100
+ break
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ else {
107
+ if ('object' === schema.type) {
108
+ if (schema.properties.id) {
109
+ place = '' // top level
110
+ }
111
+ else {
112
+ if (1 === propkeys.length) {
113
+ place = propkeys[0]
114
+ }
115
+ else {
116
+ // Use sub property with an id
117
+ for (let pk of propkeys) {
118
+ if (schema.properties[pk].properties?.id) {
119
+ place = pk
120
+ break
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ // console.log('PLACE', op, kind, schema.type, 'P=', place)
129
+ return place
130
+ }
131
+
132
+
46
133
  const opBuilder: any = {
47
134
  any: (entityModel: any, pathdef: any, op: any, path: any, entity: any, model: any) => {
48
- const em = entityModel.op[op.key$] = {
135
+ // console.log('OP', op, pathdef, path, entity)
136
+ const opname = op.key$
137
+ const method = op.val$
138
+ const kind = OPKIND[opname]
139
+
140
+ // console.log('EM', entityModel.name)
141
+
142
+ const em = entityModel.op[opname] = {
49
143
  path: path.key$,
50
144
  method: op.val$,
145
+ kind,
51
146
  param: {},
52
147
  query: {},
148
+ place: resolvePlace(op, kind, pathdef)
53
149
  }
150
+
54
151
  fixName(em, op.key$)
55
152
 
56
153
  // Params are in the path
57
154
  if (0 < path.params$.length) {
58
- let params = getx(pathdef[op.val$], 'parameters?in=path') || []
155
+ let params = getx(pathdef[method], 'parameters?in=path') || []
59
156
  if (Array.isArray(params)) {
60
157
  params.reduce((a: any, p: any) =>
61
158
  (paramBuilder(a, p, entityModel, pathdef, op, path, entity, model), a), em.param)
@@ -85,7 +182,7 @@ async function operationTransform(
85
182
  return opBuilder.any(entityModel, pathdef, op, path, entity, model)
86
183
  },
87
184
 
88
- save: (entityModel: any, pathdef: any, op: any, path: any, entity: any, model: any) => {
185
+ update: (entityModel: any, pathdef: any, op: any, path: any, entity: any, model: any) => {
89
186
  return opBuilder.any(entityModel, pathdef, op, path, entity, model)
90
187
  },
91
188
 
@@ -1,18 +1,24 @@
1
1
 
2
2
  import { each, getx } from 'jostraca'
3
3
 
4
- import type { TransformCtx, TransformSpec } from '../transform'
4
+ import type { TransformCtx, TransformSpec, TransformResult, Transform, Guide } from '../transform'
5
5
 
6
6
  import { fixName } from '../transform'
7
7
 
8
8
 
9
- async function topTransform(ctx: TransformCtx, tspec: TransformSpec, model: any, def: any) {
9
+ const topTransform = async function(
10
+ ctx: TransformCtx,
11
+ guide: Guide,
12
+ tspec: TransformSpec,
13
+ model: any,
14
+ def: any
15
+ ): Promise<TransformResult> {
10
16
  const { spec } = ctx
11
17
 
12
- // fixName(model.main.api, spec.meta.name)
13
- model.main.def.desc = def.info.description
18
+ model.main.def.info = def.info
19
+ model.main.def.servers = def.servers
14
20
 
15
- return { ok: true, msg: 'top' } // , msg: spec.meta.name }
21
+ return { ok: true, msg: 'top' }
16
22
  }
17
23
 
18
24
 
package/src/transform.ts CHANGED
@@ -5,6 +5,7 @@ import Path from 'node:path'
5
5
 
6
6
  import { getx, each, camelify } from 'jostraca'
7
7
 
8
+ import { Gubu, Child, Exact } from 'gubu'
8
9
 
9
10
  import { topTransform } from './transform/top'
10
11
  import { entityTransform } from './transform/entity'
@@ -36,6 +37,7 @@ type TransformResult = {
36
37
 
37
38
  type Transform = (
38
39
  ctx: TransformCtx,
40
+ guide: Guide,
39
41
  tspec: TransformSpec,
40
42
  apimodel: any,
41
43
  def: any,
@@ -58,6 +60,35 @@ const TRANSFORM: Record<string, Transform> = {
58
60
 
59
61
 
60
62
 
63
+ const OPKIND: any = {
64
+ list: 'res',
65
+ load: 'res',
66
+ remove: 'res',
67
+ create: 'req',
68
+ update: 'req',
69
+ }
70
+
71
+
72
+ const GuideShape = Gubu({
73
+ /*
74
+ entity: Child({
75
+ key$: '',
76
+ name: String,
77
+ path: Child({
78
+ op: Child({
79
+ method: Exact('get', 'post', 'put', 'patch', 'delete'),
80
+ place: ''
81
+ })
82
+ })
83
+ }),
84
+ */
85
+ entity: {},
86
+ control: {},
87
+ transform: {},
88
+ })
89
+
90
+ type Guide = ReturnType<typeof GuideShape>
91
+
61
92
 
62
93
  async function resolveTransforms(ctx: TransformCtx): Promise<TransformSpec> {
63
94
  const { log, model: { main: { guide } } } = ctx
@@ -143,11 +174,14 @@ async function processTransforms(
143
174
  results: []
144
175
  }
145
176
 
177
+ const guide: Guide = GuideShape(ctx.model.main.guide)
178
+
179
+
146
180
  for (let tI = 0; tI < spec.transform.length; tI++) {
147
181
  const transform = spec.transform[tI]
148
182
 
149
183
  try {
150
- const tres = await transform(ctx, spec, apimodel, def)
184
+ const tres = await transform(ctx, guide, spec, apimodel, def)
151
185
  pres.ok = pres.ok && tres.ok
152
186
  pres.results.push(tres)
153
187
  }
@@ -193,11 +227,16 @@ function fixName(base: any, name: string, prop = 'name') {
193
227
  export type {
194
228
  TransformCtx,
195
229
  TransformSpec,
230
+ Transform,
231
+ TransformResult,
232
+ Guide,
196
233
  }
197
234
 
198
235
 
199
236
  export {
200
237
  fixName,
238
+ OPKIND,
239
+ GuideShape,
201
240
  resolveTransforms,
202
241
  processTransforms,
203
242
  }
File without changes