@voxgig/create-sdkgen 0.0.1 → 0.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/README.md CHANGED
@@ -1,2 +1,4 @@
1
1
  # create-sdkgen
2
2
  Create a Voxgig SDK Generator project
3
+
4
+
@@ -1,5 +1,269 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ const Path = require('node:path')
4
+ const { statSync } = require('node:fs')
5
+ const { parseArgs } = require('node:util')
6
+
7
+ const { Gubu, Fault } = require('gubu')
8
+
9
+ const Pkg = require('../package.json')
10
+
3
11
  const { CreateSdkGen } = require('../dist/create-sdkgen.js')
4
12
 
5
- console.log('CreateSdkGen', CreateSdkGen)
13
+ // const { Root } = require('../dist/standard/Root')
14
+ const rootpath = require.resolve('../dist/standard/Root')
15
+
16
+ let DEBUG = false
17
+ let CONSOLE = console
18
+
19
+
20
+ try {
21
+ let options = resolveOptions()
22
+
23
+ if(options.debug) {
24
+ DEBUG = true
25
+ }
26
+
27
+ if(options.version) {
28
+ version()
29
+ }
30
+
31
+ if(options.help) {
32
+ help()
33
+ }
34
+
35
+ if(options.version || options.help) {
36
+ exit()
37
+ }
38
+
39
+ options = validateOptions(options)
40
+
41
+ generate(options)
42
+
43
+ }
44
+ catch(err) {
45
+ handleError(err)
46
+ }
47
+
48
+
49
+
50
+ function exit(err) {
51
+ let code = 0
52
+ if(err) {
53
+ code = 1
54
+ }
55
+ process.exit(code)
56
+ }
57
+
58
+
59
+ function generate(options) {
60
+ const createSdkGen = CreateSdkGen({
61
+ folder: options.folder,
62
+ rootpath
63
+ })
64
+
65
+
66
+ // TODO: load model
67
+
68
+ const model = {
69
+ name: options.name,
70
+ year: new Date().getFullYear(),
71
+ def: {
72
+ filepath: options.def || 'def.yml'
73
+ }
74
+ }
75
+
76
+ model.def.filename = Path.basename(model.def.filepath)
77
+
78
+ const spec = {
79
+ // TODO: move to CreateSdkGen options
80
+ spec: options.spec,
81
+ model,
82
+ // root: Root,
83
+ }
84
+
85
+ if(options.watch) {
86
+ spec.watch = [
87
+ '../tm',
88
+ '../dist',
89
+ ]
90
+ createSdkGen.watch(spec)
91
+ }
92
+ else {
93
+ createSdkGen.generate(spec)
94
+ }
95
+
96
+ }
97
+
98
+
99
+ function resolveOptions() {
100
+
101
+ const args = parseArgs({
102
+ allowPositionals: true,
103
+ options: {
104
+ folder: {
105
+ type: 'string',
106
+ short: 'f',
107
+ default: '',
108
+ },
109
+
110
+ def: {
111
+ type: 'string',
112
+ short: 'd',
113
+ default: '',
114
+ },
115
+
116
+ model: {
117
+ type: 'string',
118
+ short: 'm',
119
+ default: '',
120
+ },
121
+
122
+ watch: {
123
+ type: 'boolean',
124
+ short: 'w',
125
+ },
126
+
127
+ debug: {
128
+ type: 'boolean',
129
+ short: 'g',
130
+ },
131
+
132
+ help: {
133
+ type: 'boolean',
134
+ short: 'h',
135
+ },
136
+
137
+ version: {
138
+ type: 'boolean',
139
+ short: 'v',
140
+ },
141
+
142
+ }
143
+ })
144
+
145
+ const options = {
146
+ name: args.positionals[0],
147
+ folder: '' === args.values.folder ? args.positionals[0] : args.values.folder,
148
+ def: args.values.def,
149
+ model: args.values.model,
150
+ watch: !!args.values.watch,
151
+ debug: !!args.values.debug,
152
+ help: !!args.values.help,
153
+ version: !!args.values.version,
154
+ }
155
+
156
+ return options
157
+ }
158
+
159
+
160
+ function validateOptions(rawOptions) {
161
+ const optShape = Gubu({
162
+ name: Fault('The first argument should be the project name.', String),
163
+ folder: String,
164
+ def: '',
165
+ model: '',
166
+ watch: Boolean,
167
+ debug: Boolean,
168
+ help: Boolean,
169
+ version: Boolean,
170
+ })
171
+
172
+ const err = []
173
+ const options = optShape(rawOptions,{err})
174
+
175
+ if(err[0]) {
176
+ throw new Error(err[0].text)
177
+ }
178
+
179
+ if('' !== options.def) {
180
+ options.def = Path.resolve(options.def)
181
+ const stat = statSync(options.def, {throwIfNoEntry:false})
182
+ if(null == stat) {
183
+ throw new Error('Definition file not found: '+options.def)
184
+ }
185
+ }
186
+
187
+ if('' !== options.model) {
188
+ options.model = Path.resolve(options.model)
189
+ const stat = statSync(options.model, {throwIfNoEntry:false})
190
+ if(null == stat) {
191
+ throw new Error('Model file not found: '+options.model)
192
+ }
193
+ }
194
+
195
+ return options
196
+ }
197
+
198
+
199
+ function handleError(err) {
200
+ CONSOLE.log('Voxgig SDK Generator Error:')
201
+
202
+ if(DEBUG) {
203
+ CONSOLE.log(err)
204
+ }
205
+ else {
206
+ CONSOLE.log(err.message)
207
+ }
208
+
209
+ exit(err)
210
+ }
211
+
212
+
213
+ function version() {
214
+ CONSOLE.log(Pkg.version)
215
+ }
216
+
217
+
218
+ function help() {
219
+ let s = `
220
+ Create a Voxgig SDK Generator project.
221
+
222
+ Usage: npm create @voxgig/sdkgen@latest <name> <args>
223
+
224
+ where <name> is the name of the SDK project. This is also used to
225
+ create a project folder if one is not explictly defined using the -f
226
+ argument. If run against an existing folder generated files will be
227
+ overwritten.
228
+
229
+ <args> are the command arguments:
230
+
231
+ --folder <folder> Specific the folder for the SDK project. Optional.
232
+ -f <folder> Default: <name> in current folder.
233
+
234
+ --def <file> Specify the API definition file (OpenAPI, Swagger, etc)
235
+ -d that defines the SDK. Optional.
236
+
237
+ --model <file> Specify the SDK model file to customize the SDK. Optional.
238
+ -m
239
+
240
+ --watch Run in watch mode. The SDK project will be updated if any of the
241
+ -w project inputs (such as the spec file) change.
242
+
243
+ --debug Print verbose logging.
244
+ -d
245
+
246
+ --help Print this help message.
247
+ -h
248
+
249
+ --version Print version number.
250
+ -v
251
+
252
+
253
+ Examples:
254
+
255
+ # Basic usage
256
+ > npm create @voxgig/sdkgen@latest foo
257
+ # Creates the SDK Project in the folder ./foo
258
+
259
+
260
+ # Custom project folder
261
+ > npm create @voxgig/sdkgen@latest foo -f ~/Projects/Foo
262
+ # Creates the SDK Project in the folder ~/Projects/Foo
263
+
264
+
265
+ See also: https://voxgig.com/sdkgen
266
+ `
267
+
268
+ CONSOLE.log(s)
269
+ }
@@ -3,10 +3,12 @@ type FullCreateSdkGenOptions = {
3
3
  fs: any;
4
4
  model: any;
5
5
  meta: any;
6
+ rootpath: string;
6
7
  };
7
8
  type CreateSdkGenOptions = Partial<FullCreateSdkGenOptions>;
8
9
  declare function CreateSdkGen(opts: CreateSdkGenOptions): {
9
10
  generate: (spec: any) => Promise<void>;
11
+ watch: (spec: any) => Promise<void>;
10
12
  };
11
13
  export type { CreateSdkGenOptions, };
12
14
  export { CreateSdkGen, };
@@ -26,25 +26,74 @@ var __importStar = (this && this.__importStar) || function (mod) {
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
27
  exports.CreateSdkGen = CreateSdkGen;
28
28
  const Fs = __importStar(require("node:fs"));
29
+ const chokidar_1 = require("chokidar");
29
30
  const JostracaModule = __importStar(require("jostraca"));
30
31
  const { Jostraca } = JostracaModule;
31
32
  function CreateSdkGen(opts) {
32
33
  const fs = opts.fs || Fs;
33
34
  const folder = opts.folder || '.';
34
35
  const jostraca = Jostraca();
36
+ const rootpath = opts.rootpath;
35
37
  async function generate(spec) {
36
- const { model, root } = spec;
38
+ // console.log('CreateSdkGen.generate', spec)
39
+ const { model } = spec;
37
40
  const ctx$ = { fs, folder, meta: { spec } };
41
+ clear();
42
+ const { Root } = require(rootpath);
38
43
  try {
39
- jostraca.generate(ctx$, () => root({ model }));
44
+ await jostraca.generate(ctx$, () => Root({ model }));
40
45
  }
41
46
  catch (err) {
42
47
  console.log('CREATE SDKGEN ERROR: ', err);
43
48
  throw err;
44
49
  }
45
50
  }
51
+ async function watch(spec) {
52
+ const fsw = new chokidar_1.FSWatcher();
53
+ let last_change_time = 0;
54
+ await generate(spec);
55
+ fsw.on('change', (args) => {
56
+ // console.log('CHANGE', args)
57
+ const dorun = 1111 < Date.now() - last_change_time;
58
+ if (dorun) {
59
+ last_change_time = Date.now();
60
+ generate(spec);
61
+ }
62
+ });
63
+ spec.watch
64
+ .map((wf) => (__dirname + '/' + wf))
65
+ // .map((wf: string) => (console.log(wf), wf))
66
+ .map((wf) => fsw.add(wf));
67
+ // generate()
68
+ }
69
+ function clear() {
70
+ if (rootpath) {
71
+ clearRequire(rootpath);
72
+ }
73
+ }
46
74
  return {
47
75
  generate,
76
+ watch,
48
77
  };
49
78
  }
79
+ // Adapted from https://github.com/sindresorhus/import-fresh - Thanks!
80
+ function clearRequire(path) {
81
+ let filePath = require.resolve(path);
82
+ if (require.cache[filePath]) {
83
+ const children = require.cache[filePath].children.map(child => child.id);
84
+ // Delete module from cache
85
+ delete require.cache[filePath];
86
+ for (const id of children) {
87
+ clearRequire(id);
88
+ }
89
+ }
90
+ if (require.cache[filePath] && require.cache[filePath].parent) {
91
+ let i = require.cache[filePath].parent.children.length;
92
+ while (i--) {
93
+ if (require.cache[filePath].parent.children[i].id === filePath) {
94
+ require.cache[filePath].parent.children.splice(i, 1);
95
+ }
96
+ }
97
+ }
98
+ }
50
99
  //# sourceMappingURL=create-sdkgen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-sdkgen.js","sourceRoot":"","sources":["../src/create-sdkgen.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;AA2DlD,oCAAY;AAzDd,4CAA6B;AAG7B,yDAA0C;AAc1C,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAA;AAGnC,SAAS,YAAY,CAAC,IAAyB;IAC7C,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAA;IACjC,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAA;IAG3B,KAAK,UAAU,QAAQ,CAAC,IAAS;QAC/B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;QAE5B,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAA;QAE3C,IAAI,CAAC;YACH,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QAChD,CAAC;QACD,OAAO,GAAQ,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAA;YACzC,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAGD,OAAO;QACL,QAAQ;KACT,CAAA;AAEH,CAAC"}
1
+ {"version":3,"file":"create-sdkgen.js","sourceRoot":"","sources":["../src/create-sdkgen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ declare const ModelSdk: import("jostraca").Component;
2
+ export { ModelSdk };
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModelSdk = void 0;
4
+ const jostraca_1 = require("jostraca");
5
+ const ModelSdk = (0, jostraca_1.cmp)(function ModelSdk(props) {
6
+ const { ctx$, ctx$: { model } } = props;
7
+ // console.log('ModelSdk 2', model)
8
+ // TODO: use apidef
9
+ // const def = ctx$.fs.readFileSync(model.def.filepath)
10
+ (0, jostraca_1.File)({ name: 'sdk.jsonic' }, () => {
11
+ (0, jostraca_1.Content)(`
12
+ name: '${model.name}'
13
+
14
+ @"api.jsonic"
15
+ @"def.jsonic"
16
+
17
+ main: sdk: build: &: { name: .$KEY }
18
+
19
+ main: sdk: build: js: @"js.jsonic"
20
+
21
+ main: sdk: build: rb: @"rb.jsonic"
22
+
23
+ main: sdk: build: py: @"py.jsonic"
24
+
25
+ main: sdk: build: php: @"php.jsonic"
26
+
27
+ main: sdk: build: go: @"go.jsonic"
28
+
29
+
30
+
31
+ main: sdk: test: quick: entity: name: q
32
+
33
+
34
+ main: sdk: entity: $.main.api.entity
35
+
36
+
37
+ main: sdk: entity: &: {
38
+ name: .$KEY
39
+ publish: *true | boolean
40
+ }
41
+
42
+
43
+
44
+ main: sdk: options: &: {
45
+ name: .$KEY
46
+ publish: *true | boolean
47
+ }
48
+
49
+
50
+ main: sdk: options: {
51
+
52
+ endpoint: {
53
+ kind: *String | string
54
+ short: "${model.Name} API URL"
55
+ }
56
+
57
+ apikey: {
58
+ kind: *String | string
59
+ short: "${model.Name} API Key"
60
+ }
61
+
62
+ fetch: {
63
+ kind: *Any | string
64
+ publish: false
65
+ }
66
+ }
67
+ `);
68
+ });
69
+ });
70
+ exports.ModelSdk = ModelSdk;
71
+ //# sourceMappingURL=ModelSdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelSdk.js","sourceRoot":"","sources":["../../src/standard/ModelSdk.ts"],"names":[],"mappings":";;;AACA,uCAWiB;AAIjB,MAAM,QAAQ,GAAG,IAAA,cAAG,EAAC,SAAS,QAAQ,CAAC,KAAU;IAC/C,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,CAAA;IAGvC,mCAAmC;IAEnC,mBAAmB;IACnB,uDAAuD;IAGvD,IAAA,eAAI,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE;QAChC,IAAA,kBAAO,EAAC;SACH,KAAK,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0CL,KAAK,CAAC,IAAI;;;;;cAKV,KAAK,CAAC,IAAI;;;;;;;;CAQvB,CAAC,CAAA;IACA,CAAC,CAAC,CAAA;AAEJ,CAAC,CAAC,CAAA;AAIA,4BAAQ"}
@@ -0,0 +1,2 @@
1
+ declare const Root: import("jostraca").Component;
2
+ export { Root };
@@ -0,0 +1,76 @@
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.Root = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const jostraca_1 = require("jostraca");
9
+ const ModelSdk_1 = require("./ModelSdk");
10
+ const Root = (0, jostraca_1.cmp)(function Root(props) {
11
+ const { model, ctx$ } = props;
12
+ const { folder, meta } = ctx$;
13
+ const { spec } = meta;
14
+ console.log('Root 5');
15
+ // console.log('SPEC', spec)
16
+ (0, jostraca_1.names)(model, model.name);
17
+ // console.log('MODEL')
18
+ // console.dir(model, { depth: null })
19
+ ctx$.model = model;
20
+ /*
21
+ let createInfo = { exclude: [], last: Number.MAX_SAFE_INTEGER }
22
+
23
+
24
+ try {
25
+ createInfo = JSON.parse(ctx$.fs.readFileSync(
26
+ Path.join(folder, '.voxgig', 'create-sdkgen.json'), 'utf8'))
27
+ }
28
+ catch (err: any) {
29
+ console.log(err)
30
+ // TODO: file not foound ignored, handle others!
31
+ }
32
+
33
+ ctx$.info = createInfo
34
+
35
+ console.log('INFO', ctx$.info)
36
+ */
37
+ (0, jostraca_1.Project)({ folder }, () => {
38
+ // TODO: perhaps remove the need for this, create top level folder in Project
39
+ // would keep paths indo of project folder name
40
+ // Folder({ name: Path.basename(folder) }, () => {
41
+ // File({ name: 'foo.txt' }, () => {
42
+ // Content('FOO')
43
+ // })
44
+ // console.log('FOLDER', folder)
45
+ (0, jostraca_1.Copy)({ from: __dirname + '/../../tm/standard' });
46
+ const def = model.def.filepath;
47
+ if (null != def && '' !== def) {
48
+ (0, jostraca_1.Folder)({ name: 'def' }, () => {
49
+ (0, jostraca_1.Copy)({ from: def, name: node_path_1.default.basename(def) });
50
+ });
51
+ }
52
+ (0, jostraca_1.Folder)({ name: '.voxgig' }, () => { });
53
+ (0, jostraca_1.Folder)({ name: 'model' }, () => {
54
+ (0, ModelSdk_1.ModelSdk)({});
55
+ });
56
+ });
57
+ /*
58
+ // TODO: need mechanism to ensure this is last
59
+ setTimeout(() => {
60
+ try {
61
+ const info = {
62
+ last: Date.now(),
63
+ exclude: ctx$.info.exclude,
64
+ }
65
+ ctx$.fs.writeFileSync(Path.join(folder, '.voxgig', 'create-sdkgen.json'),
66
+ JSON.stringify(info, null, 2))
67
+ }
68
+ catch (err: any) {
69
+ console.log(err)
70
+ // TODO: file not foound ignored, handle others!
71
+ }
72
+ }, 777)
73
+ */
74
+ });
75
+ exports.Root = Root;
76
+ //# sourceMappingURL=Root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Root.js","sourceRoot":"","sources":["../../src/standard/Root.ts"],"names":[],"mappings":";;;;;;AAEA,0DAA4B;AAG5B,uCAWiB;AAGjB,yCAAqC;AAGrC,MAAM,IAAI,GAAG,IAAA,cAAG,EAAC,SAAS,IAAI,CAAC,KAAU;IACvC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IAE7B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;IAC7B,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;IAErB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAErB,4BAA4B;IAE5B,IAAA,gBAAK,EAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;IAExB,uBAAuB;IACvB,sCAAsC;IAEtC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IAElB;;;;;;;;;;;;;;;;MAgBE;IAEF,IAAA,kBAAO,EAAC,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE;QAEvB,6EAA6E;QAC7E,+CAA+C;QAC/C,kDAAkD;QAElD,oCAAoC;QACpC,mBAAmB;QACnB,KAAK;QAEL,gCAAgC;QAChC,IAAA,eAAI,EAAC,EAAE,IAAI,EAAE,SAAS,GAAG,oBAAoB,EAAE,CAAC,CAAA;QAEhD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAA;QAC9B,IAAI,IAAI,IAAI,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAC9B,IAAA,iBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE;gBAC3B,IAAA,eAAI,EAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC/C,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,IAAA,iBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;QAEtC,IAAA,iBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE;YAC7B,IAAA,mBAAQ,EAAC,EAAE,CAAC,CAAA;QACd,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF;;;;;;;;;;;;;;;;QAgBI;AACN,CAAC,CAAC,CAAA;AAIA,oBAAI"}
@@ -1 +1 @@
1
- {"root":["../src/create-sdkgen.ts","../src/utility.ts"],"version":"5.6.2"}
1
+ {"root":["../src/create-sdkgen.ts","../src/utility.ts","../src/standard/modelsdk.ts","../src/standard/root.ts"],"version":"5.6.2"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voxgig/create-sdkgen",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "main": "dist/create-sdkgen.js",
5
5
  "type": "commonjs",
6
6
  "types": "dist/create-sdkgen.d.ts",
@@ -38,14 +38,15 @@
38
38
  ],
39
39
  "devDependencies": {
40
40
  "@hapi/code": "^9.0.3",
41
- "@types/node": "22.5.4",
41
+ "@types/node": "22.5.5",
42
42
  "esbuild": "^0.23.1",
43
- "memfs": "^4.11.1",
44
- "typescript": "^5.5.4"
43
+ "memfs": "^4.12.0",
44
+ "typescript": "^5.6.2"
45
45
  },
46
46
  "dependencies": {
47
47
  "aontu": "^0.22.0",
48
- "jostraca": "^0.4.0"
48
+ "chokidar": "^4.0.0",
49
+ "gubu": "^8.3.0",
50
+ "jostraca": "^0.6.0"
49
51
  }
50
52
  }
51
-
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as Fs from 'node:fs'
4
4
 
5
+ import { FSWatcher } from 'chokidar'
5
6
 
6
7
  import * as JostracaModule from 'jostraca'
7
8
 
@@ -12,6 +13,7 @@ type FullCreateSdkGenOptions = {
12
13
  fs: any
13
14
  model: any
14
15
  meta: any
16
+ rootpath: string
15
17
  }
16
18
 
17
19
  type CreateSdkGenOptions = Partial<FullCreateSdkGenOptions>
@@ -24,15 +26,20 @@ function CreateSdkGen(opts: CreateSdkGenOptions) {
24
26
  const fs = opts.fs || Fs
25
27
  const folder = opts.folder || '.'
26
28
  const jostraca = Jostraca()
27
-
29
+ const rootpath = opts.rootpath as string
28
30
 
29
31
  async function generate(spec: any) {
30
- const { model, root } = spec
32
+ // console.log('CreateSdkGen.generate', spec)
33
+
34
+ const { model } = spec
31
35
 
32
36
  const ctx$ = { fs, folder, meta: { spec } }
33
37
 
38
+ clear()
39
+ const { Root } = require(rootpath)
40
+
34
41
  try {
35
- jostraca.generate(ctx$, () => root({ model }))
42
+ await jostraca.generate(ctx$, () => Root({ model }))
36
43
  }
37
44
  catch (err: any) {
38
45
  console.log('CREATE SDKGEN ERROR: ', err)
@@ -41,13 +48,74 @@ function CreateSdkGen(opts: CreateSdkGenOptions) {
41
48
  }
42
49
 
43
50
 
51
+ async function watch(spec: any) {
52
+ const fsw = new FSWatcher()
53
+ let last_change_time = 0
54
+
55
+ await generate(spec)
56
+
57
+ fsw.on('change', (args: any[]) => {
58
+ // console.log('CHANGE', args)
59
+
60
+ const dorun = 1111 < Date.now() - last_change_time
61
+
62
+ if (dorun) {
63
+ last_change_time = Date.now()
64
+ generate(spec)
65
+ }
66
+ })
67
+
68
+ spec.watch
69
+ .map((wf: string) => (__dirname + '/' + wf))
70
+ // .map((wf: string) => (console.log(wf), wf))
71
+ .map((wf: string) => fsw.add(wf))
72
+
73
+ // generate()
74
+ }
75
+
76
+
77
+ function clear() {
78
+ if (rootpath) {
79
+ clearRequire(rootpath)
80
+ }
81
+ }
82
+
83
+
44
84
  return {
45
85
  generate,
86
+ watch,
46
87
  }
47
88
 
48
89
  }
49
90
 
50
91
 
92
+ // Adapted from https://github.com/sindresorhus/import-fresh - Thanks!
93
+ function clearRequire(path: string) {
94
+ let filePath = require.resolve(path)
95
+
96
+ if (require.cache[filePath]) {
97
+ const children = require.cache[filePath].children.map(child => child.id)
98
+
99
+ // Delete module from cache
100
+ delete require.cache[filePath]
101
+
102
+ for (const id of children) {
103
+ clearRequire(id)
104
+ }
105
+ }
106
+
107
+
108
+ if (require.cache[filePath] && require.cache[filePath].parent) {
109
+ let i = require.cache[filePath].parent.children.length
110
+
111
+ while (i--) {
112
+ if (require.cache[filePath].parent.children[i].id === filePath) {
113
+ require.cache[filePath].parent.children.splice(i, 1)
114
+ }
115
+ }
116
+ }
117
+
118
+ }
51
119
 
52
120
 
53
121
  export type {
@@ -0,0 +1,92 @@
1
+
2
+ import {
3
+ names,
4
+ cmp,
5
+ each,
6
+
7
+ Project,
8
+ Folder,
9
+ Copy,
10
+ File,
11
+ Content,
12
+
13
+ } from 'jostraca'
14
+
15
+
16
+
17
+ const ModelSdk = cmp(function ModelSdk(props: any) {
18
+ const { ctx$, ctx$: { model } } = props
19
+
20
+
21
+ // console.log('ModelSdk 2', model)
22
+
23
+ // TODO: use apidef
24
+ // const def = ctx$.fs.readFileSync(model.def.filepath)
25
+
26
+
27
+ File({ name: 'sdk.jsonic' }, () => {
28
+ Content(`
29
+ name: '${model.name}'
30
+
31
+ @"api.jsonic"
32
+ @"def.jsonic"
33
+
34
+ main: sdk: build: &: { name: .$KEY }
35
+
36
+ main: sdk: build: js: @"js.jsonic"
37
+
38
+ main: sdk: build: rb: @"rb.jsonic"
39
+
40
+ main: sdk: build: py: @"py.jsonic"
41
+
42
+ main: sdk: build: php: @"php.jsonic"
43
+
44
+ main: sdk: build: go: @"go.jsonic"
45
+
46
+
47
+
48
+ main: sdk: test: quick: entity: name: q
49
+
50
+
51
+ main: sdk: entity: $.main.api.entity
52
+
53
+
54
+ main: sdk: entity: &: {
55
+ name: .$KEY
56
+ publish: *true | boolean
57
+ }
58
+
59
+
60
+
61
+ main: sdk: options: &: {
62
+ name: .$KEY
63
+ publish: *true | boolean
64
+ }
65
+
66
+
67
+ main: sdk: options: {
68
+
69
+ endpoint: {
70
+ kind: *String | string
71
+ short: "${model.Name} API URL"
72
+ }
73
+
74
+ apikey: {
75
+ kind: *String | string
76
+ short: "${model.Name} API Key"
77
+ }
78
+
79
+ fetch: {
80
+ kind: *Any | string
81
+ publish: false
82
+ }
83
+ }
84
+ `)
85
+ })
86
+
87
+ })
88
+
89
+
90
+ export {
91
+ ModelSdk
92
+ }
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,107 @@
1
+
2
+
3
+ import Path from 'node:path'
4
+
5
+
6
+ import {
7
+ names,
8
+ cmp,
9
+ each,
10
+
11
+ Project,
12
+ Folder,
13
+ Copy,
14
+ File,
15
+ Content,
16
+
17
+ } from 'jostraca'
18
+
19
+
20
+ import { ModelSdk } from './ModelSdk'
21
+
22
+
23
+ const Root = cmp(function Root(props: any) {
24
+ const { model, ctx$ } = props
25
+
26
+ const { folder, meta } = ctx$
27
+ const { spec } = meta
28
+
29
+ console.log('Root 5')
30
+
31
+ // console.log('SPEC', spec)
32
+
33
+ names(model, model.name)
34
+
35
+ // console.log('MODEL')
36
+ // console.dir(model, { depth: null })
37
+
38
+ ctx$.model = model
39
+
40
+ /*
41
+ let createInfo = { exclude: [], last: Number.MAX_SAFE_INTEGER }
42
+
43
+
44
+ try {
45
+ createInfo = JSON.parse(ctx$.fs.readFileSync(
46
+ Path.join(folder, '.voxgig', 'create-sdkgen.json'), 'utf8'))
47
+ }
48
+ catch (err: any) {
49
+ console.log(err)
50
+ // TODO: file not foound ignored, handle others!
51
+ }
52
+
53
+ ctx$.info = createInfo
54
+
55
+ console.log('INFO', ctx$.info)
56
+ */
57
+
58
+ Project({ folder }, () => {
59
+
60
+ // TODO: perhaps remove the need for this, create top level folder in Project
61
+ // would keep paths indo of project folder name
62
+ // Folder({ name: Path.basename(folder) }, () => {
63
+
64
+ // File({ name: 'foo.txt' }, () => {
65
+ // Content('FOO')
66
+ // })
67
+
68
+ // console.log('FOLDER', folder)
69
+ Copy({ from: __dirname + '/../../tm/standard' })
70
+
71
+ const def = model.def.filepath
72
+ if (null != def && '' !== def) {
73
+ Folder({ name: 'def' }, () => {
74
+ Copy({ from: def, name: Path.basename(def) })
75
+ })
76
+ }
77
+
78
+ Folder({ name: '.voxgig' }, () => { })
79
+
80
+ Folder({ name: 'model' }, () => {
81
+ ModelSdk({})
82
+ })
83
+ })
84
+
85
+ /*
86
+ // TODO: need mechanism to ensure this is last
87
+ setTimeout(() => {
88
+ try {
89
+ const info = {
90
+ last: Date.now(),
91
+ exclude: ctx$.info.exclude,
92
+ }
93
+ ctx$.fs.writeFileSync(Path.join(folder, '.voxgig', 'create-sdkgen.json'),
94
+ JSON.stringify(info, null, 2))
95
+ }
96
+ catch (err: any) {
97
+ console.log(err)
98
+ // TODO: file not foound ignored, handle others!
99
+ }
100
+ }, 777)
101
+ */
102
+ })
103
+
104
+
105
+ export {
106
+ Root
107
+ }
@@ -0,0 +1,3 @@
1
+
2
+
3
+