@voxgig/apidef 1.8.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.
Files changed (74) hide show
  1. package/dist/apidef.d.ts +3 -29
  2. package/dist/apidef.js +84 -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 +125 -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 +178 -0
  21. package/dist/guide/heuristic01.js.map +1 -0
  22. package/dist/guide.d.ts +2 -0
  23. package/dist/guide.js +62 -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 +4 -2
  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 +22 -11
  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 +21 -10
  43. package/dist/transform.js.map +1 -1
  44. package/dist/tsconfig.tsbuildinfo +1 -1
  45. package/dist/types.d.ts +682 -0
  46. package/dist/types.js +38 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/utility.d.ts +4 -0
  49. package/dist/utility.js +59 -0
  50. package/dist/utility.js.map +1 -0
  51. package/model/apidef.jsonic +28 -24
  52. package/package.json +11 -9
  53. package/src/apidef.ts +117 -263
  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 +165 -0
  58. package/src/builder/flow/flowHeuristic01.ts~ +45 -0
  59. package/src/builder/flow.ts +60 -0
  60. package/src/guide/heuristic01.ts +225 -0
  61. package/src/guide.ts +91 -0
  62. package/src/parse.ts +6 -4
  63. package/src/resolver.ts +91 -0
  64. package/src/transform/entity.ts +10 -7
  65. package/src/transform/field.ts +9 -92
  66. package/src/transform/operation.ts +39 -25
  67. package/src/transform/top.ts +11 -9
  68. package/src/transform.ts +23 -11
  69. package/src/types.ts +88 -0
  70. package/src/utility.ts +83 -0
  71. package/dist/transform/manual.d.ts +0 -3
  72. package/dist/transform/manual.js +0 -12
  73. package/dist/transform/manual.js.map +0 -1
  74. package/src/transform/manual.ts +0 -29
@@ -0,0 +1,4 @@
1
+ import type { FsUtil, Log } from './types';
2
+ declare function loadFile(path: string, what: string, fs: FsUtil, log: Log): string;
3
+ declare function formatJsonSrc(jsonsrc: string): string;
4
+ export { loadFile, formatJsonSrc };
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loadFile = loadFile;
7
+ exports.formatJsonSrc = formatJsonSrc;
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ function loadFile(path, what, fs, log) {
10
+ try {
11
+ const source = fs.readFileSync(path, 'utf8');
12
+ return source;
13
+ }
14
+ catch (err) {
15
+ log.error({ load: 'fail', what, path, err });
16
+ throw err;
17
+ }
18
+ }
19
+ function formatJsonSrc(jsonsrc) {
20
+ return jsonsrc
21
+ .replace(/"([a-zA-Z_][a-zA-Z_0-9]*)": /g, '$1: ')
22
+ .replace(/},/g, '}\n');
23
+ }
24
+ function writeChanged(point, path, content, fs, log, flags) {
25
+ let exists = false;
26
+ let changed = false;
27
+ flags = flags || {};
28
+ flags.update = null == flags.update ? true : !!flags.update;
29
+ let action = '';
30
+ try {
31
+ let existingContent = '';
32
+ path = node_path_1.default.normalize(path);
33
+ exists = fs.existsSync(path);
34
+ if (exists) {
35
+ action = 'read';
36
+ existingContent = fs.readFileSync(path, 'utf8');
37
+ }
38
+ changed = existingContent !== content;
39
+ action = flags.update ? 'write' : 'skip';
40
+ log.info({
41
+ point: 'write-' + point,
42
+ note: (changed ? '' : 'not-') + 'changed ' + path,
43
+ write: 'file', skip: !changed, exists, changed,
44
+ contentLength: content.length, file: path
45
+ });
46
+ if (!exists || (changed && flags.update)) {
47
+ fs.writeFileSync(path, content);
48
+ }
49
+ }
50
+ catch (err) {
51
+ log.error({
52
+ fail: action, point, file: path, exists, changed,
53
+ contentLength: content.length, err
54
+ });
55
+ err.__logged__ = true;
56
+ throw err;
57
+ }
58
+ }
59
+ //# sourceMappingURL=utility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utility.js","sourceRoot":"","sources":["../src/utility.ts"],"names":[],"mappings":";;;;;AA+EE,4BAAQ;AACR,sCAAa;AA/Ef,0DAA4B;AAS5B,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAY,EAAE,EAAU,EAAE,GAAQ;IAChE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC5C,OAAO,MAAM,CAAA;IACf,CAAC;IACD,OAAO,GAAQ,EAAE,CAAC;QAChB,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;QAC5C,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC;AAGD,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,OAAO;SACX,OAAO,CAAC,+BAA+B,EAAE,MAAM,CAAC;SAChD,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAGD,SAAS,YAAY,CACnB,KAAa,EAAE,IAAY,EAAE,OAAe,EAC5C,EAAU,EAAE,GAAQ,EACpB,KAA4B;IAE5B,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,OAAO,GAAG,KAAK,CAAA;IAEnB,KAAK,GAAG,KAAK,IAAI,EAAE,CAAA;IACnB,KAAK,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;IAE3D,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,CAAC;QACH,IAAI,eAAe,GAAW,EAAE,CAAA;QAChC,IAAI,GAAG,mBAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAE3B,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAE5B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,GAAG,MAAM,CAAA;YACf,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACjD,CAAC;QAED,OAAO,GAAG,eAAe,KAAK,OAAO,CAAA;QAErC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAA;QAExC,GAAG,CAAC,IAAI,CAAC;YACP,KAAK,EAAE,QAAQ,GAAG,KAAK;YACvB,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,UAAU,GAAG,IAAI;YACjD,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO;YAC9C,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI;SAC1C,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IACD,OAAO,GAAQ,EAAE,CAAC;QAChB,GAAG,CAAC,KAAK,CAAC;YACR,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO;YAChD,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG;SACnC,CAAC,CAAA;QACF,GAAG,CAAC,UAAU,GAAG,IAAI,CAAA;QACrB,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC"}
@@ -1,33 +1,36 @@
1
1
 
2
- main: api: guide: control: transform: &: {
3
- order: string
4
- }
5
-
6
- main: api: guide: control: transform: openapi: {
7
- order: *`
2
+ main: api: guide: control: {
3
+
4
+ transform: openapi: {
5
+ order: *`
6
+ top,
7
+ entity,
8
+ operation,
9
+ field,
10
+ ` | string,
11
+
12
+ element: {
13
+ top: {}
14
+ entity: {}
15
+ operation: {}
16
+ field: {}
17
+ }
18
+ }
8
19
 
9
- top,
10
- entity,
11
- operation,
12
- field,
13
- manual,
14
-
15
- ` | string
16
- }
20
+ builder: standard: {
21
+ order: *`
22
+ entity,
23
+ flow,
24
+ ` | string,
17
25
 
26
+ element: {
27
+ entity: {}
28
+ flow: {}
29
+ }
30
+ }
18
31
 
19
- main: api: guide: transform: &: {
20
- name: .$KEY
21
- load: string
22
32
  }
23
33
 
24
- main: api: guide: transform: {
25
- top: {}
26
- entity: {}
27
- operation: {}
28
- field: {}
29
- manual: {}
30
- }
31
34
 
32
35
 
33
36
  main: api: guide: entity: &: {
@@ -46,3 +49,4 @@ main: api: guide: entity: &: {
46
49
 
47
50
 
48
51
 
52
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voxgig/apidef",
3
- "version": "1.8.0",
3
+ "version": "2.0.0",
4
4
  "main": "dist/apidef.js",
5
5
  "type": "commonjs",
6
6
  "types": "dist/apidef.d.ts",
@@ -19,13 +19,13 @@
19
19
  "voxgig-apidef": "bin/voxgig-apidef"
20
20
  },
21
21
  "scripts": {
22
- "test": "node --enable-source-maps --test dist-test",
23
- "test22": "node --enable-source-maps --test \"dist-test/*.test.js\"",
24
- "test-some": "node --enable-source-maps --test-name-pattern=\"$npm_config_pattern\" --test dist-test",
22
+ "test": "node --enable-source-maps --test \"dist-test/**/*.test.js\"",
23
+ "test-some": "node --enable-source-maps --test-name-pattern=\"$npm_config_pattern\" --test \"dist-test/**/*.test.js\"",
25
24
  "watch": "tsc --build src test -w",
26
25
  "build": "tsc --build src test",
27
26
  "clean": "rm -rf dist dist-test node_modules yarn.lock package-lock.json",
28
27
  "reset": "npm run clean && npm i && npm run build && npm test",
28
+ "postinstall": "patch-package",
29
29
  "repo-tag": "REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;",
30
30
  "repo-publish": "npm run clean && npm i && npm run repo-publish-quick",
31
31
  "repo-publish-quick": "npm run build && npm run test && npm run repo-tag && npm publish --registry https://registry.npmjs.org --access=public"
@@ -41,20 +41,22 @@
41
41
  "devDependencies": {
42
42
  "@hapi/code": "^9.0.3",
43
43
  "@types/js-yaml": "^4.0.9",
44
- "@types/node": "22.15.17",
44
+ "@types/node": "24.0.7",
45
45
  "aontu": "^0.28.0",
46
- "esbuild": "^0.25.4",
46
+ "esbuild": "^0.25.5",
47
47
  "json-schema-to-ts": "^3.1.1",
48
- "memfs": "^4.17.1",
48
+ "memfs": "^4.17.2",
49
+ "patch-package": "^8.0.0",
49
50
  "typescript": "^5.8.3"
50
51
  },
51
52
  "dependencies": {
52
53
  "@redocly/openapi-core": "^1.34.3",
54
+ "@voxgig/struct": "^0.0.3",
53
55
  "@voxgig/util": "^0.0.10",
54
56
  "chokidar": "^4.0.3",
55
57
  "gubu": "^9.0.0",
56
- "jostraca": "^0.18.0",
57
- "pino": "^9.6.0",
58
+ "jostraca": "^0.20.0",
59
+ "pino": "^9.7.0",
58
60
  "pino-pretty": "^13.0.0",
59
61
  "sonic-boom": "^4.2.0"
60
62
  }
package/src/apidef.ts CHANGED
@@ -1,13 +1,35 @@
1
- /* Copyright (c) 2024 Voxgig, MIT License */
1
+ /* Copyright (c) 2024-2025 Voxgig, MIT License */
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
- import { bundleFromString, createConfig } from '@redocly/openapi-core'
8
- import { Gubu, Open, Any } from 'gubu'
9
- import { each } from 'jostraca'
10
- import { prettyPino, Pino } from '@voxgig/util'
7
+ import { Jostraca, Project, names } from 'jostraca'
8
+
9
+ import { prettyPino } from '@voxgig/util'
10
+
11
+
12
+ import type {
13
+ ApiDefOptions,
14
+ Model,
15
+ Build,
16
+ ApiModel,
17
+ } from './types'
18
+
19
+ import {
20
+ OpenModelShape,
21
+ OpenBuildShape,
22
+ } from './types'
23
+
24
+
25
+ import {
26
+ resolveGuide,
27
+ } from './guide'
28
+
29
+
30
+ import {
31
+ parse
32
+ } from './parse'
11
33
 
12
34
 
13
35
  import {
@@ -17,76 +39,55 @@ import {
17
39
  } from './transform'
18
40
 
19
41
 
20
- type ApiDefOptions = {
21
- def?: string
22
- fs?: any
23
- pino?: ReturnType<typeof Pino>
24
- debug?: boolean | string
25
- folder?: string
26
- meta?: Record<string, any>
27
- outprefix?: string
28
- }
29
-
30
42
 
31
- type ApiModel = {
32
- main: {
33
- api: {
34
- entity: Record<string, any>
35
- }
36
- def: Record<string, any>
37
- }
38
- }
43
+ import {
44
+ resolveElements
45
+ } from './resolver'
39
46
 
47
+ import {
48
+ loadFile,
49
+ } from './utility'
40
50
 
41
- const ModelShape = Gubu({
42
- def: String,
43
- main: {
44
- sdk: {},
45
- def: {},
46
- api: {},
47
- }
48
- })
49
- const OpenModelShape = Gubu(Open(ModelShape))
50
-
51
- type Model = ReturnType<typeof ModelShape>
52
-
53
-
54
- const BuildShape = Gubu({
55
- spec: {
56
- base: '',
57
- path: '',
58
- debug: '',
59
- use: {},
60
- res: [],
61
- require: '',
62
- log: {},
63
- fs: Any(),
64
- watch: {
65
- mod: true,
66
- add: true,
67
- rem: true,
68
- }
69
- }
70
- })
71
- const OpenBuildShape = Gubu(Open(BuildShape))
72
51
 
73
- type Build = ReturnType<typeof BuildShape>
52
+ import { topTransform } from './transform/top'
53
+ import { entityTransform } from './transform/entity'
54
+ import { operationTransform } from './transform/operation'
55
+ import { fieldTransform } from './transform/field'
74
56
 
57
+ import { makeEntityBuilder } from './builder/entity'
58
+ import { makeFlowBuilder } from './builder/flow'
75
59
 
76
60
 
77
61
  function ApiDef(opts: ApiDefOptions) {
62
+
63
+ // TODO: gubu opts!
78
64
  const fs = opts.fs || Fs
79
65
  const pino = prettyPino('apidef', opts)
80
-
81
66
  const log = pino.child({ cmp: 'apidef' })
82
67
 
68
+ opts.strategy = opts.strategy || 'heuristic01'
69
+
83
70
 
84
71
  async function generate(spec: any) {
85
72
  const start = Date.now()
86
73
 
74
+ // console.log('APIDEF GENERATE')
75
+ // console.dir(spec, { depth: null })
76
+
87
77
  const model: Model = OpenModelShape(spec.model)
88
78
  const build: Build = OpenBuildShape(spec.build)
89
79
 
80
+ names(model, model.name)
81
+
82
+ const apimodel: ApiModel = {
83
+ main: {
84
+ api: {
85
+ entity: {}
86
+ },
87
+ def: {},
88
+ },
89
+ }
90
+
90
91
  const buildspec = build.spec
91
92
 
92
93
  let defpath = model.def
@@ -101,214 +102,96 @@ function ApiDef(opts: ApiDefOptions) {
101
102
 
102
103
  // TODO: Validate spec
103
104
  const ctx = {
105
+ fs,
104
106
  log,
105
107
  spec,
106
108
  opts,
107
109
  util: { fixName },
108
110
  defpath: Path.dirname(defpath),
109
111
  model,
110
- }
111
-
112
- const transformSpec = await resolveTransforms(ctx)
113
-
114
- log.debug({
115
- point: 'transform', spec: transformSpec,
116
- note: log.levelVal <= 20 ? inspect(transformSpec) : ''
117
- })
118
-
119
-
120
- let source
121
- try {
122
- source = fs.readFileSync(defpath, 'utf8')
123
- }
124
- catch (err: any) {
125
- log.error({ read: 'fail', what: 'def', file: defpath, err })
126
- throw err
127
- }
128
-
129
-
130
- const config = await createConfig({})
131
- let bundle
132
-
133
- try {
134
- bundle = await bundleFromString({
135
- source,
136
- config,
137
- dereference: true,
138
- })
139
- }
140
- catch (err: any) {
141
- log.error({ parse: 'fail', what: 'openapi', file: defpath, err })
142
- throw err
143
- }
144
-
145
-
146
- const apimodel: ApiModel = {
147
- main: {
148
- api: {
149
- entity: {}
150
- },
151
- def: {},
152
- },
153
- }
154
-
155
- const def = bundle.bundle.parsed
156
- const processResult = await processTransforms(ctx, transformSpec, apimodel, def)
157
-
158
- if (!processResult.ok) {
159
- log.error({
160
- fail: 'process', point: 'transform-result',
161
- result: processResult, note: processResult.msg,
162
- err: processResult.results[0]?.err
163
- })
164
-
165
- return { ok: false, name: 'apidef', processResult }
166
- }
167
-
168
-
169
- const modelPath = Path.normalize(spec.config.model)
170
-
171
- buildModel_api(apimodel, modelPath)
172
- buildModel_def(apimodel, modelPath)
173
- buildModel_entity(apimodel, modelPath)
174
-
175
- log.info({ point: 'generate-end', note: 'success', break: true })
176
-
177
- return {
178
- ok: true,
179
- name: 'apidef',
180
112
  apimodel,
113
+ def: undefined
181
114
  }
182
- }
183
-
184
-
185
- function buildModel_api(apimodel: ApiModel, modelPath: string) {
186
- const modelapi = { main: { api: apimodel.main.api } }
187
- let modelSrc = JSON.stringify(modelapi, null, 2)
188
-
189
- modelSrc =
190
- '# GENERATED FILE - DO NOT EDIT\n\n' +
191
- modelSrc.substring(1, modelSrc.length - 1).replace(/\n /g, '\n')
192
-
193
- writeChanged('api-model', modelPath, modelSrc)
194
- return modelPath
195
- }
196
-
197
-
198
- function buildModel_def(apimodel: ApiModel, modelPath: string) {
199
- const modelBasePath = Path.dirname(modelPath)
200
- const defFilePath = Path.join(modelBasePath,
201
- (null == opts.outprefix ? '' : opts.outprefix) + 'def-generated.jsonic')
202
-
203
- const modelDef = { main: { def: apimodel.main.def } }
204
- let modelDefSrc = JSON.stringify(modelDef, null, 2)
205
-
206
- modelDefSrc =
207
- '# GENERATED FILE - DO NOT EDIT\n\n' +
208
- modelDefSrc.substring(1, modelDefSrc.length - 1).replace(/\n /g, '\n')
209
-
210
- writeChanged('def-model', defFilePath, modelDefSrc)
211
- }
212
115
 
116
+ const defsrc = loadFile(defpath, 'def', fs, log)
213
117
 
214
- function buildModel_entity(apimodel: ApiModel, modelPath: string) {
215
- const modelBasePath = Path.dirname(modelPath)
118
+ const def = await parse('OpenAPI', defsrc, { file: defpath })
119
+ ctx.def = def
216
120
 
217
- const entityIncludes: string[] = []
121
+ const guideBuilder = await resolveGuide(ctx)
218
122
 
219
- each(apimodel.main.api.entity, ((entity: any) => {
220
- entityIncludes.push(entity.name)
221
123
 
222
- // HEURISTIC: id may be name_id or nameId
223
- const fieldAliases =
224
- each(entity.op, (op: any) =>
225
- each(op.param))
226
- .flat()
227
- .reduce((a: any, p: any) =>
228
-
229
- (entity.field[p.keys] ? null :
230
- (p.key$.toLowerCase().includes(entity.name) ?
231
- (a[p.key$] = 'id', a.id = p.key$) :
232
- null)
233
-
234
- , a), {})
124
+ // const transformSpec = await resolveTransforms(ctx)
125
+ const transforms = await resolveElements(ctx, 'transform', 'openapi', {
126
+ top: topTransform,
127
+ entity: entityTransform,
128
+ operation: operationTransform,
129
+ field: fieldTransform,
130
+ })
235
131
 
236
- const fieldAliasesSrc =
237
- JSON.stringify(fieldAliases, null, 2)
238
- .replace(/\n/g, '\n ')
132
+ // log.debug({
133
+ // point: 'transform', spec: transformSpec,
134
+ // note: log.levelVal <= 20 ? inspect(transformSpec) : ''
135
+ // })
239
136
 
240
- const entityFileSrc = `
241
- # Entity ${entity.name}
137
+ // const processResult = await processTransforms(ctx, transforms, apimodel, def)
242
138
 
243
- main: sdk: entity: ${entity.name}: {
244
- alias: field: ${fieldAliasesSrc}
245
- }
139
+ // if (!processResult.ok) {
140
+ // log.error({
141
+ // fail: 'process', point: 'transform-result',
142
+ // result: processResult, note: processResult.msg,
143
+ // err: processResult.results[0]?.err
144
+ // })
246
145
 
247
- `
248
- const entityFilePath = Path.join(modelBasePath, 'entity',
249
- (null == opts.outprefix ? '' : opts.outprefix) + entity.name + '.jsonic')
146
+ // return { ok: false, name: 'apidef', processResult }
147
+ // }
250
148
 
251
- fs.mkdirSync(Path.dirname(entityFilePath), { recursive: true })
252
149
 
253
- // TODO: diff merge
254
- writeChanged('entity-model', entityFilePath, entityFileSrc, { update: false })
255
- }))
150
+ const builders = await resolveElements(ctx, 'builder', 'standard', {
151
+ entity: makeEntityBuilder,
152
+ flow: makeFlowBuilder,
153
+ })
256
154
 
257
155
 
258
- modifyModel(
259
- fs,
260
- Path.join(
261
- modelBasePath,
262
- (null == opts.outprefix ? '' : opts.outprefix) + 'sdk.jsonic'),
263
- entityIncludes
264
- )
265
- }
266
156
 
157
+ // const entityBuilder = resolveEntity(apimodel, spec, opts)
267
158
 
268
- function writeChanged(
269
- point: string, path: string, content: string,
270
- flags?: { update?: boolean }
271
- ) {
272
- let exists = false
273
- let changed = false
159
+ // const entityBuilder = await resolveEntity(ctx)
160
+ // const flowBuilder = await resolveFlows(ctx)
274
161
 
275
- flags = flags || {}
276
- flags.update = null == flags.update ? true : !!flags.update
162
+ const jostraca = Jostraca({
163
+ now: spec.now,
164
+ fs: () => fs,
165
+ log,
166
+ })
277
167
 
278
- let action = ''
279
- try {
280
- let existingContent: string = ''
281
- path = Path.normalize(path)
168
+ const jmodel = {}
282
169
 
283
- exists = fs.existsSync(path)
170
+ const root = () => Project({ folder: '.' }, async () => {
171
+ guideBuilder()
172
+ // entityBuilder()
173
+ // flowBuilder()
284
174
 
285
- if (exists) {
286
- action = 'read'
287
- existingContent = fs.readFileSync(path, 'utf8')
175
+ for (let builder of builders) {
176
+ builder()
288
177
  }
178
+ })
289
179
 
290
- changed = existingContent !== content
180
+ const jres = await jostraca.generate({
181
+ // folder: Path.dirname(opts.folder as string),
182
+ folder: opts.folder,
183
+ model: jmodel,
184
+ existing: { txt: { merge: true } }
185
+ }, root)
291
186
 
292
- action = flags.update ? 'write' : 'skip'
187
+ // console.log('JRES', jres)
293
188
 
294
- log.info({
295
- point: 'write-' + point,
296
- note: (changed ? '' : 'not-') + 'changed ' + path,
297
- write: 'file', skip: !changed, exists, changed,
298
- contentLength: content.length, file: path
299
- })
189
+ log.info({ point: 'generate-end', note: 'success', break: true })
300
190
 
301
- if (!exists || (changed && flags.update)) {
302
- fs.writeFileSync(path, content)
303
- }
304
- }
305
- catch (err: any) {
306
- log.error({
307
- fail: action, point, file: path, exists, changed,
308
- contentLength: content.length, err
309
- })
310
- err.__logged__ = true
311
- throw err
191
+ return {
192
+ ok: true,
193
+ name: 'apidef',
194
+ apimodel,
312
195
  }
313
196
  }
314
197
 
@@ -318,17 +201,14 @@ main: sdk: entity: ${entity.name}: {
318
201
  }
319
202
 
320
203
 
321
-
322
204
  ApiDef.makeBuild = async function(opts: ApiDefOptions) {
323
205
  let apidef: any = undefined
324
206
 
325
- const outprefix = null == opts.outprefix ? '' : opts.outprefix
207
+ // const outprefix = null == opts.outprefix ? '' : opts.outprefix
326
208
 
327
209
  const config = {
328
210
  def: opts.def || 'no-def',
329
211
  kind: 'openapi3',
330
- model: opts.folder ?
331
- (opts.folder + '/' + outprefix + 'api-generated.jsonic') : 'no-model',
332
212
  meta: opts.meta || {},
333
213
  }
334
214
 
@@ -351,41 +231,15 @@ ApiDef.makeBuild = async function(opts: ApiDefOptions) {
351
231
 
352
232
 
353
233
 
354
- async function modifyModel(fs: any, path: string, entityIncludes: string[]) {
355
- // TODO: This is a kludge.
356
- // Aontu should provide option for as-is AST so that can be used
357
- // to find injection point more reliably
358
-
359
-
360
- let src = fs.existsSync(path) ? fs.readFileSync(path, 'utf8') :
361
- 'main: sdk: entity: {}\n'
362
-
363
- let newsrc = '' + src
364
-
365
- // Inject target file references into model
366
- entityIncludes.sort().map((entname: string) => {
367
- const lineRE =
368
- new RegExp(`@"entity/${entname}.jsonic"`)
369
-
370
- if (!src.match(lineRE)) {
371
- newsrc = newsrc.replace(/(main:\s+sdk:\s+entity:\s+\{\s*\}\n)/, '$1' +
372
- `@"entity/${entname}.jsonic"\n`)
373
- }
374
- })
375
-
376
- if (newsrc.length !== src.length) {
377
- fs.writeFileSync(path, newsrc)
378
- }
379
- }
380
234
 
381
235
 
382
236
 
383
237
  export type {
384
238
  ApiDefOptions,
385
- // ApiDefSpec,
386
239
  }
387
240
 
388
241
 
389
242
  export {
390
243
  ApiDef,
244
+ parse,
391
245
  }