@voxgig/system 1.2.0 → 1.3.1

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.
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.Utility = void 0;
8
- const jsonic_next_1 = require("@jsonic/jsonic-next");
8
+ const jsonic_1 = require("@tabnas/jsonic");
9
9
  const patrun_1 = __importDefault(require("patrun"));
10
10
  // TODO: perform this during model build?
11
11
  function srvmsgs(srv, model) {
@@ -53,7 +53,7 @@ function walkmsgs(point, path, handle) {
53
53
  const Utility = {
54
54
  srvmsgs,
55
55
  listmsgs,
56
- deep: jsonic_next_1.util.deep,
56
+ deep: jsonic_1.util.deep,
57
57
  };
58
58
  exports.Utility = Utility;
59
59
  //# sourceMappingURL=utility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utility.js","sourceRoot":"","sources":["../../lib/utility.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utility.js","sourceRoot":"","sources":["../../lib/utility.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"make.js","sourceRoot":"","sources":["../../srv/make.ts"],"names":[],"mappings":";;AAgBE,0BAAO;AAfT,sCAAkC;AAElC,SAAS,OAAO,CAAC,IAAY,EAAE,OAAY;IACzC,MAAM,GAAG,GAAG,UAAoB,OAAY;QAC1C,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAA;QAChD,eAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QACtC,eAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC/B,CAAC,CAAA;IAED,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,CAAA;IAE5D,OAAO,GAAG,CAAA;AACZ,CAAC"}
1
+ {"version":3,"file":"make.js","sourceRoot":"","sources":["../../srv/make.ts"],"names":[],"mappings":";;QAgBE,OAAO;AAfT,sCAAkC;AAElC,SAAS,OAAO,CAAC,IAAY,EAAE,OAAY;IACzC,MAAM,GAAG,GAAG,UAAoB,OAAY;QAC1C,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAA;QAChD,eAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QACtC,eAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC/B,CAAC,CAAA;IAED,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,CAAA;IAE5D,OAAO,GAAG,CAAA;AACZ,CAAC"}
package/dist/system.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Msg } from './lib/types';
2
2
  import { Utility } from './lib/utility';
3
3
  import { MakeSrv } from './srv/make';
4
+ import { addEntity, addSrv, addMsg, addFields, resolveModelFiles } from './lib/add';
4
5
  declare function messages(seneca: any, options: any, reload: any): void;
5
6
  declare function gubuify(params: any, Gubu: any): any;
6
7
  declare function prepare(seneca: any, require: any): void;
@@ -18,4 +19,11 @@ declare const System: {
18
19
  prepare: typeof prepare;
19
20
  };
20
21
  export type { Msg };
21
- export { gubuify, System, MakeSrv, Utility, Local, Live, };
22
+ declare const Add: {
23
+ entity: typeof addEntity;
24
+ srv: typeof addSrv;
25
+ msg: typeof addMsg;
26
+ fields: typeof addFields;
27
+ resolveModelFiles: typeof resolveModelFiles;
28
+ };
29
+ export { Add, gubuify, System, MakeSrv, Utility, Local, Live, };
package/dist/system.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.Utility = exports.MakeSrv = exports.System = void 0;
7
+ exports.Utility = exports.MakeSrv = exports.System = exports.Add = void 0;
8
8
  exports.gubuify = gubuify;
9
9
  exports.Local = Local;
10
10
  exports.Live = Live;
@@ -14,6 +14,7 @@ const utility_1 = require("./lib/utility");
14
14
  Object.defineProperty(exports, "Utility", { enumerable: true, get: function () { return utility_1.Utility; } });
15
15
  const make_1 = require("./srv/make");
16
16
  Object.defineProperty(exports, "MakeSrv", { enumerable: true, get: function () { return make_1.MakeSrv; } });
17
+ const add_1 = require("./lib/add");
17
18
  const { srvmsgs, deep } = utility_1.Utility;
18
19
  function messages(seneca, options, reload) {
19
20
  let srvname = seneca.fixedargs.plugin$.name.replace(/^srv_/, '');
@@ -35,11 +36,28 @@ function gubuify(params, Gubu) {
35
36
  if (null == params) {
36
37
  return params;
37
38
  }
39
+ return Gubu(gubuify_spec(params, Gubu));
40
+ }
41
+ // Convert model param values into a gubu spec. The '$$': 'Open' marker
42
+ // (same convention as entity valid) makes an object open: additional
43
+ // properties are allowed. Without it gubu objects are closed, which made
44
+ // open message params inexpressible in the model. Nested specs stay raw
45
+ // (builder results, not Gubu instances) so attributes like openness
46
+ // compose into the parent shape.
47
+ function gubuify_spec(params, Gubu) {
48
+ if (null == params) {
49
+ return params;
50
+ }
51
+ let open = false;
52
+ if ('Open' === params['$$']) {
53
+ open = true;
54
+ delete params['$$'];
55
+ }
38
56
  for (let pn in params) {
39
57
  let m = null;
40
58
  let pv = params[pn];
41
59
  if ('object' === typeof pv) {
42
- params[pn] = gubuify(pv, Gubu);
60
+ params[pn] = gubuify_spec(pv, Gubu);
43
61
  }
44
62
  else if ('string' === typeof pv &&
45
63
  -1 === pn.indexOf(':') && ('function' === typeof Gubu[(m = ((pv.match(/\s*([A-Z]\w+)([(.\s]|$)/) || []))[1])] ||
@@ -48,11 +66,8 @@ function gubuify(params, Gubu) {
48
66
  params[png] = pv;
49
67
  delete params[pn];
50
68
  }
51
- else {
52
- params[pn] = Gubu(pv);
53
- }
54
69
  }
55
- return Gubu(params);
70
+ return open ? Gubu.Open(params) : params;
56
71
  }
57
72
  function actpath(msg) {
58
73
  if (msg.meta.file) {
@@ -132,4 +147,12 @@ const System = {
132
147
  prepare,
133
148
  };
134
149
  exports.System = System;
150
+ const Add = {
151
+ entity: add_1.addEntity,
152
+ srv: add_1.addSrv,
153
+ msg: add_1.addMsg,
154
+ fields: add_1.addFields,
155
+ resolveModelFiles: add_1.resolveModelFiles,
156
+ };
157
+ exports.Add = Add;
135
158
  //# sourceMappingURL=system.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../system.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../system.ts"],"names":[],"mappings":"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"}
package/lib/add.ts ADDED
@@ -0,0 +1,405 @@
1
+ /* Copyright © 2026 Voxgig Ltd, MIT License. */
2
+
3
+ // Add elements (entity, srv, msg, field) to a Voxgig system project by
4
+ // appending jsonic blocks to the project's model source files. Appending
5
+ // works because aontu unifies repeated paths, and it preserves the user's
6
+ // existing formatting and comments.
7
+ //
8
+ // Each add* function takes either a String(name) - an empty element of
9
+ // that name is added - or a Jsonic(spec) - a jsonic definition of the
10
+ // element with config options.
11
+
12
+ import Fs from 'node:fs'
13
+ import Path from 'node:path'
14
+
15
+ import { Jsonic } from '@tabnas/jsonic'
16
+
17
+
18
+ // Values emitted bare (aontu type/token names); everything else is quoted.
19
+ const BARE_TOKENS = ['String', 'Number', 'Boolean', 'Skip']
20
+
21
+
22
+ export type ModelFiles = {
23
+ folder: string // the model folder
24
+ model: string // root model file path (model.aontu)
25
+ ent: string // entity file path
26
+ msg: string // message file path
27
+ srv: string // service file path
28
+ }
29
+
30
+ export type AddResult = {
31
+ file: string // file appended to
32
+ text: string // the appended block
33
+ }
34
+
35
+
36
+ // Model sources use the .aontu extension; .jsonic is legacy.
37
+ const MODEL_EXTS = ['aontu', 'jsonic']
38
+
39
+ // Locate the model folder from a starting folder: <start>/model,
40
+ // <start>/backend/model, or <start> itself if it holds model.aontu
41
+ // (or legacy model.jsonic).
42
+ function resolveModelFolder(start: string): string {
43
+ const candidates = [
44
+ start,
45
+ Path.join(start, 'model'),
46
+ Path.join(start, 'backend', 'model'),
47
+ ]
48
+ for (const c of candidates) {
49
+ for (const ext of MODEL_EXTS) {
50
+ if (Fs.existsSync(Path.join(c, 'model.' + ext))) {
51
+ return c
52
+ }
53
+ }
54
+ }
55
+ throw new Error('model folder not found (looked for model.aontu in ' +
56
+ candidates.join(', ') + ')')
57
+ }
58
+
59
+
60
+ // Resolve the entity/message/service source files from the @"file" refs
61
+ // in the root model file (main: ent: @"..."), falling back to
62
+ // conventional names.
63
+ function resolveModelFiles(start: string): ModelFiles {
64
+ const folder = resolveModelFolder(start)
65
+
66
+ let model = Path.join(folder, 'model.' + MODEL_EXTS[0])
67
+ for (const ext of MODEL_EXTS) {
68
+ const p = Path.join(folder, 'model.' + ext)
69
+ if (Fs.existsSync(p)) {
70
+ model = p
71
+ break
72
+ }
73
+ }
74
+ const src = Fs.readFileSync(model, 'utf8')
75
+
76
+ const ref = (key: string, base: string) => {
77
+ const m = src.match(
78
+ new RegExp('main:\\s*' + key + ':\\s*@"([^"]+)"'))
79
+ if (m) {
80
+ return Path.join(folder, m[1])
81
+ }
82
+ for (const ext of MODEL_EXTS) {
83
+ const p = Path.join(folder, base + '.' + ext)
84
+ if (Fs.existsSync(p)) {
85
+ return p
86
+ }
87
+ }
88
+ return Path.join(folder, base + '.' + MODEL_EXTS[0])
89
+ }
90
+
91
+ return {
92
+ folder,
93
+ model,
94
+ ent: ref('ent', 'ent'),
95
+ msg: ref('msg', 'msg'),
96
+ srv: ref('srv', 'srv'),
97
+ }
98
+ }
99
+
100
+
101
+ // Format a value as jsonic source. Objects use multiline path-free style;
102
+ // known aontu tokens (String, Skip, ...) are emitted bare.
103
+ function fmt(val: any, depth: number): string {
104
+ const pad = ' '.repeat(depth)
105
+ const padIn = ' '.repeat(depth + 1)
106
+
107
+ if (null == val) {
108
+ return 'null'
109
+ }
110
+ else if ('string' === typeof val) {
111
+ return BARE_TOKENS.includes(val) ? val :
112
+ "'" + val.replace(/'/g, "\\'") + "'"
113
+ }
114
+ else if ('object' !== typeof val) {
115
+ return String(val)
116
+ }
117
+ else if (Array.isArray(val)) {
118
+ return '[' + val.map((v) => fmt(v, depth + 1)).join(', ') + ']'
119
+ }
120
+
121
+ const entries = Object.entries(val)
122
+ if (0 === entries.length) {
123
+ return '{}'
124
+ }
125
+
126
+ return '{\n' +
127
+ entries.map(([k, v]) => padIn + fmtKey(k) + ': ' + fmt(v, depth + 1))
128
+ .join('\n') +
129
+ '\n' + pad + '}'
130
+ }
131
+
132
+ function fmtKey(k: string): string {
133
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(k) ? k :
134
+ "'" + k.replace(/'/g, "\\'") + "'"
135
+ }
136
+
137
+
138
+ function append(file: string, text: string): AddResult {
139
+ const existing = Fs.readFileSync(file, 'utf8')
140
+ const sep = existing.endsWith('\n') ? '\n' : '\n\n'
141
+ Fs.appendFileSync(file, sep + text + '\n')
142
+ return { file, text }
143
+ }
144
+
145
+
146
+ // Parse a name-or-spec argument. Returns { name, def } where def is the
147
+ // element definition object ({} for the plain-name form).
148
+ function parseArg(arg: string, kind: string): { name: string, def: any } {
149
+ let parsed: any
150
+ try {
151
+ parsed = Jsonic(arg)
152
+ }
153
+ catch (e: any) {
154
+ throw new Error('invalid ' + kind + ' argument (jsonic parse failed): ' +
155
+ arg + ' - ' + e.message)
156
+ }
157
+
158
+ if ('string' === typeof parsed) {
159
+ return { name: parsed, def: {} }
160
+ }
161
+
162
+ if (null != parsed && 'object' === typeof parsed && !Array.isArray(parsed)) {
163
+ // { name: 'foo', ...def }
164
+ if ('string' === typeof parsed.name) {
165
+ const def = { ...parsed }
166
+ delete def.name
167
+ return { name: parsed.name, def }
168
+ }
169
+
170
+ // { foo: {...def} } - single-key form
171
+ const keys = Object.keys(parsed)
172
+ if (1 === keys.length && 'object' === typeof parsed[keys[0]]) {
173
+ return { name: keys[0], def: parsed[keys[0]] }
174
+ }
175
+ }
176
+
177
+ throw new Error('invalid ' + kind + ' argument: ' + arg +
178
+ ' - provide a name, {name:...,...spec}, or {thename:{...spec}}')
179
+ }
180
+
181
+
182
+ // Default zone for entities: the single non-sys zone shape spread already
183
+ // in the entity file (`<zone>: &: ...`), else 'app'.
184
+ function defaultZone(entFile: string): string {
185
+ const src = Fs.readFileSync(entFile, 'utf8')
186
+ const zones = [...src.matchAll(/^([a-z][a-z0-9_]*):\s*&:/mg)]
187
+ .map((m) => m[1])
188
+ .filter((z) => 'sys' !== z)
189
+ const uniq = [...new Set(zones)]
190
+ return 1 === uniq.length ? uniq[0] : 'app'
191
+ }
192
+
193
+
194
+ // add entity [String(name)|Jsonic(spec)]
195
+ // Names may be zone-qualified: app/thing. Spec: { name, zone?, ...def }.
196
+ function addEntity(start: string, arg: string): AddResult {
197
+ const files = resolveModelFiles(start)
198
+ const { name: rawname, def } = parseArg(arg, 'entity')
199
+
200
+ let zone = def.zone
201
+ delete def.zone
202
+ let name = rawname
203
+ if (rawname.includes('/')) {
204
+ const parts = rawname.split('/')
205
+ zone = parts[0]
206
+ name = parts[1]
207
+ }
208
+ zone = zone || defaultZone(files.ent)
209
+
210
+ if (null == def.field) {
211
+ def.field = {}
212
+ }
213
+ if (null == def.valid) {
214
+ def.valid = { '$$': 'Open' }
215
+ }
216
+
217
+ const src = Fs.readFileSync(files.ent, 'utf8')
218
+ const shapeLine = new RegExp('^' + zone + ':\\s*&:', 'm').test(src) ? '' :
219
+ zone + ': &: $.main.shape.ent\n\n'
220
+
221
+ const text = '\n' + shapeLine +
222
+ zone + ': ' + name + ': ' + fmt(def, 0)
223
+
224
+ return append(files.ent, text)
225
+ }
226
+
227
+
228
+ // add srv [String(name)|Jsonic(spec)]
229
+ // The plain-name form wires the service to its aim messages and a private
230
+ // web area (matching the standard project scaffold).
231
+ function addSrv(start: string, arg: string): AddResult {
232
+ const files = resolveModelFiles(start)
233
+ const { name, def } = parseArg(arg, 'srv')
234
+
235
+ if (null == def.in) {
236
+ def.in = {
237
+ aim: { [name]: {} },
238
+ }
239
+ }
240
+ if (null == def.user) {
241
+ def.user = { required: true }
242
+ }
243
+ if (null == def.api) {
244
+ def.api = { web: { path: { area: 'private/', suffix: '' } } }
245
+ }
246
+ if (null == def.env) {
247
+ def.env = { lambda: { active: true } }
248
+ }
249
+
250
+ const text = '\n' + name + ': ' + fmt(def, 0)
251
+
252
+ return append(files.srv, text)
253
+ }
254
+
255
+
256
+ // add msg [String(name)|Jsonic(spec)]
257
+ // Name form: a message path like thing.save.item (or thing:save:item);
258
+ // 'aim' is prepended if missing. Spec: { name: 'thing.save.item', ...meta }
259
+ // where meta (params, transport, file, ...) lands under the '$' key.
260
+ function addMsg(start: string, arg: string): AddResult {
261
+ const files = resolveModelFiles(start)
262
+
263
+ // A pure message path (thing.save.item, aim:thing:save:item) is taken
264
+ // as-is - jsonic would otherwise parse the colon form as a nested map.
265
+ const pathform = /^[a-z0-9_-]+([.:/][a-z0-9_-]+)+$/i.test(arg.trim())
266
+
267
+ let parsed: any
268
+ try {
269
+ parsed = pathform ? arg.trim() : Jsonic(arg)
270
+ }
271
+ catch (e: any) {
272
+ throw new Error('invalid msg argument (jsonic parse failed): ' +
273
+ arg + ' - ' + e.message)
274
+ }
275
+
276
+ let path: string[]
277
+ let meta: any = {}
278
+
279
+ if ('string' === typeof parsed) {
280
+ path = parsed.split(/[.:/]/).filter((p) => '' !== p)
281
+ }
282
+ else if (null != parsed && 'string' === typeof parsed.name) {
283
+ path = parsed.name.split(/[.:/]/).filter((p: string) => '' !== p)
284
+ meta = { ...parsed }
285
+ delete meta.name
286
+ }
287
+ else {
288
+ throw new Error('invalid msg argument: ' + arg +
289
+ " - provide a message path like thing.save.item, or {name:'path',...meta}")
290
+ }
291
+
292
+ if ('aim' !== path[0]) {
293
+ path.unshift('aim')
294
+ }
295
+ if (path.length < 2) {
296
+ throw new Error('invalid msg path: ' + path.join('.'))
297
+ }
298
+
299
+ const prefix = path.join(': ')
300
+ const text = 0 === Object.keys(meta).length ?
301
+ '\n' + prefix + ': {}' :
302
+ '\n' + prefix + ": '$': " + fmt(meta, 0)
303
+
304
+ return append(files.msg, text)
305
+ }
306
+
307
+
308
+ // add field <entity> [String(name)|Jsonic(spec)] ...
309
+ // Field forms: title | title:String | title:{kind:String,valid:'Min(1)'}
310
+ // | {name:title,kind:String}
311
+ // A label is derived from the name when not given.
312
+ function addFields(start: string, entref: string, fieldargs: string[])
313
+ : AddResult[] {
314
+ const files = resolveModelFiles(start)
315
+
316
+ let zone: string
317
+ let name: string
318
+ if (entref.includes('/')) {
319
+ [zone, name] = entref.split('/')
320
+ }
321
+ else {
322
+ zone = defaultZone(files.ent)
323
+ name = entref
324
+ }
325
+
326
+ if (0 === fieldargs.length) {
327
+ throw new Error('no fields given')
328
+ }
329
+
330
+ const out: AddResult[] = []
331
+
332
+ for (const arg of fieldargs) {
333
+ let parsed: any
334
+ try {
335
+ parsed = Jsonic(arg)
336
+ }
337
+ catch (e: any) {
338
+ throw new Error('invalid field argument (jsonic parse failed): ' +
339
+ arg + ' - ' + e.message)
340
+ }
341
+
342
+ let fname: string
343
+ let def: any
344
+
345
+ if ('string' === typeof parsed) {
346
+ fname = parsed
347
+ def = {}
348
+ }
349
+ else if (null != parsed && 'object' === typeof parsed) {
350
+ if ('string' === typeof parsed.name) {
351
+ fname = parsed.name
352
+ def = { ...parsed }
353
+ delete def.name
354
+ }
355
+ else {
356
+ const keys = Object.keys(parsed)
357
+ if (1 !== keys.length) {
358
+ throw new Error('invalid field argument: ' + arg)
359
+ }
360
+ fname = keys[0]
361
+ const val = parsed[fname]
362
+ def = 'string' === typeof val ? { kind: val } : { ...val }
363
+ }
364
+ }
365
+ else {
366
+ throw new Error('invalid field argument: ' + arg)
367
+ }
368
+
369
+ if (null == def.kind) {
370
+ def.kind = 'String'
371
+ }
372
+ if (null == def.label) {
373
+ def.label = fname
374
+ .split('_')
375
+ .map((p: string) => '' === p ? p : p[0].toUpperCase() + p.substring(1))
376
+ .join(' ')
377
+ }
378
+
379
+ // Emit label before kind, matching scaffold convention.
380
+ const ordered: any = { label: def.label, kind: def.kind }
381
+ for (const k of Object.keys(def)) {
382
+ if ('label' !== k && 'kind' !== k) {
383
+ ordered[k] = def[k]
384
+ }
385
+ }
386
+
387
+ const text = '\n' + zone + ': ' + name + ': field: ' + fname + ': ' +
388
+ fmt(ordered, 0)
389
+
390
+ out.push(append(files.ent, text))
391
+ }
392
+
393
+ return out
394
+ }
395
+
396
+
397
+ export {
398
+ resolveModelFolder,
399
+ resolveModelFiles,
400
+ addEntity,
401
+ addSrv,
402
+ addMsg,
403
+ addFields,
404
+ fmt,
405
+ }
package/lib/utility.ts CHANGED
@@ -5,7 +5,7 @@ import type {
5
5
  Msg
6
6
  } from './types'
7
7
 
8
- import { util } from '@jsonic/jsonic-next'
8
+ import { util } from '@tabnas/jsonic'
9
9
 
10
10
 
11
11
 
@@ -76,7 +76,7 @@ function walkmsgs(
76
76
  const Utility = {
77
77
  srvmsgs,
78
78
  listmsgs,
79
- deep: util.deep,
79
+ deep: util.deep as (base?: any, ...rest: any[]) => any,
80
80
  }
81
81
 
82
82
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voxgig/system",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "main": "dist/system.js",
5
5
  "type": "commonjs",
6
6
  "types": "dist/system.d.ts",
@@ -25,29 +25,40 @@
25
25
  "reset": "npm run clean && npm i && npm run build && npm test",
26
26
  "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;",
27
27
  "repo-publish": "npm run clean && npm i && npm run repo-publish-quick",
28
- "repo-publish-quick": "npm run build && npm run test && npm run repo-tag && npm publish --registry https://registry.npmjs.org --access=public"
28
+ "repo-publish-quick": "npm run build && npm run test && npm run repo-tag && npm run repo-stage-publish",
29
+ "repo-stage-publish": "aql vault exec --for=npm vxg:pub01 -- npm stage publish --registry https://registry.npmjs.org --access=public",
30
+ "repo-stage-publish-dry": "aql vault exec --dry-run --for=npm vxg:pub01 -- npm stage publish --registry https://registry.npmjs.org --access=public --dry-run",
31
+ "repo-stage-list": "aql vault exec --for=npm vxg:pub01 -- npm stage list",
32
+ "repo-stage-view": "aql vault exec --for=npm vxg:pub01 -- npm stage view",
33
+ "repo-stage-approve": "aql vault exec --for=npm vxg:pub01 -- npm stage approve",
34
+ "repo-stage-reject": "aql vault exec --for=npm vxg:pub01 -- npm stage reject"
29
35
  },
30
36
  "license": "MIT",
31
37
  "files": [
32
38
  "system.ts",
39
+ "cmd.ts",
33
40
  "lib",
34
41
  "srv",
35
42
  "dist",
36
43
  "LICENSE"
37
44
  ],
38
45
  "devDependencies": {
39
- "@types/jest": "^29.5.12",
46
+ "@types/jest": "^30.0.0",
47
+ "@types/node": "^22.20.1",
40
48
  "es-jest": "^2.1.0",
41
- "esbuild": "^0.23.0",
42
- "gubu": "^8.0.2",
43
- "jest": "^29.7.0",
44
- "typescript": "^5.5.3"
49
+ "esbuild": "^0.28.1",
50
+ "gubu": "^9.0.0",
51
+ "jest": "^30.4.2",
52
+ "typescript": "^7.0.2"
45
53
  },
46
54
  "peerDependencies": {
47
55
  "@voxgig/model": ">=2"
48
56
  },
49
57
  "dependencies": {
50
- "@jsonic/jsonic-next": "^2.12.1",
51
- "patrun": "^7.2.5"
58
+ "@tabnas/jsonic": "0.4.1",
59
+ "patrun": "^7.3.0"
60
+ },
61
+ "bin": {
62
+ "voxgig-system": "dist/cmd.js"
52
63
  }
53
64
  }