@voxgig/station 0.0.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -0
  3. package/dist/src/Station.d.ts +238 -0
  4. package/dist/src/Station.js +1213 -0
  5. package/dist/src/Station.js.map +1 -0
  6. package/dist/src/adapter.d.ts +9 -0
  7. package/dist/src/adapter.js +171 -0
  8. package/dist/src/adapter.js.map +1 -0
  9. package/dist/src/config-shape.d.ts +1 -0
  10. package/dist/src/config-shape.js +329 -0
  11. package/dist/src/config-shape.js.map +1 -0
  12. package/dist/src/descriptor.d.ts +8 -0
  13. package/dist/src/descriptor.js +170 -0
  14. package/dist/src/descriptor.js.map +1 -0
  15. package/dist/src/error.d.ts +8 -0
  16. package/dist/src/error.js +60 -0
  17. package/dist/src/error.js.map +1 -0
  18. package/dist/src/events.d.ts +15 -0
  19. package/dist/src/events.js +46 -0
  20. package/dist/src/events.js.map +1 -0
  21. package/dist/src/factory.d.ts +24 -0
  22. package/dist/src/factory.js +79 -0
  23. package/dist/src/factory.js.map +1 -0
  24. package/dist/src/feature.d.ts +106 -0
  25. package/dist/src/feature.js +324 -0
  26. package/dist/src/feature.js.map +1 -0
  27. package/dist/src/index.browser.d.ts +14 -0
  28. package/dist/src/index.browser.js +64 -0
  29. package/dist/src/index.browser.js.map +1 -0
  30. package/dist/src/index.d.ts +14 -0
  31. package/dist/src/index.js +56 -0
  32. package/dist/src/index.js.map +1 -0
  33. package/dist/src/loader.d.ts +45 -0
  34. package/dist/src/loader.js +181 -0
  35. package/dist/src/loader.js.map +1 -0
  36. package/dist/src/profile.d.ts +6 -0
  37. package/dist/src/profile.js +77 -0
  38. package/dist/src/profile.js.map +1 -0
  39. package/dist/src/profilecore.d.ts +10 -0
  40. package/dist/src/profilecore.js +180 -0
  41. package/dist/src/profilecore.js.map +1 -0
  42. package/dist/src/secrets.d.ts +12 -0
  43. package/dist/src/secrets.js +93 -0
  44. package/dist/src/secrets.js.map +1 -0
  45. package/dist/src/shape.d.ts +42 -0
  46. package/dist/src/shape.js +444 -0
  47. package/dist/src/shape.js.map +1 -0
  48. package/dist/src/types.d.ts +138 -0
  49. package/dist/src/types.js +5 -0
  50. package/dist/src/types.js.map +1 -0
  51. package/package.json +60 -0
  52. package/src/Station.ts +1310 -0
  53. package/src/adapter.ts +183 -0
  54. package/src/config-shape.ts +326 -0
  55. package/src/descriptor.ts +179 -0
  56. package/src/error.ts +64 -0
  57. package/src/events.ts +45 -0
  58. package/src/factory.ts +93 -0
  59. package/src/feature.ts +321 -0
  60. package/src/index.browser.ts +56 -0
  61. package/src/index.ts +50 -0
  62. package/src/loader.ts +188 -0
  63. package/src/profile.ts +67 -0
  64. package/src/profilecore.ts +201 -0
  65. package/src/secrets.ts +96 -0
  66. package/src/shape.ts +435 -0
  67. package/src/types.ts +185 -0
@@ -0,0 +1,444 @@
1
+ "use strict";
2
+ /* The config grammar, as data (design §4).
3
+ *
4
+ * TWO STEPS, AND THE FIRST IS WHAT MAKES THE SECOND HONEST.
5
+ *
6
+ * struct drops the unexpected-key check for a map whose spec node ends
7
+ * up empty - "an empty spec object means the object can be open". An
8
+ * optional key is `['$ONE','$NIL', spec]`, and when the data does not
9
+ * carry that key the validator REMOVES it from the spec node. So a
10
+ * block whose keys are all optional degenerates into an open map
11
+ * exactly when the data has none of them, and `{"solar": {"bass": 1}}`
12
+ * validates clean - the one property the whole exercise is for,
13
+ * silently absent in the one case that matters.
14
+ *
15
+ * So: normalizeConfig materializes every documented default, and
16
+ * validateConfig then runs a shape WITH NO OPTIONAL CONTAINERS AT ALL.
17
+ * After normalization every container is present, so the shape can
18
+ * require them, so unexpected-key detection is live at every level and
19
+ * every error names its path. */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.MERGE_SENSITIVE = exports.BLOCK_DEFAULTS = exports.PROFILE_DEFAULTS = void 0;
22
+ exports.normalizeConfig = normalizeConfig;
23
+ exports.configShape = configShape;
24
+ exports.validateConfig = validateConfig;
25
+ const struct_1 = require("@voxgig/struct");
26
+ const sekreto_1 = require("@voxgig/sekreto");
27
+ const config_shape_1 = require("./config-shape");
28
+ const error_1 = require("./error");
29
+ const descriptor_1 = require("./descriptor");
30
+ // ---------------------------------------------------------------------
31
+ // The defaults table - ONE table, two callers
32
+ // ---------------------------------------------------------------------
33
+ /** Profile-level containers. Safe to materialize early either way:
34
+ * they are containers, and a missing one merges as empty regardless. */
35
+ exports.PROFILE_DEFAULTS = {
36
+ secrets: () => ({ providers: [{ kind: 'env' }] }),
37
+ api: () => ({}),
38
+ sdk: () => ({}),
39
+ feature: () => ({}),
40
+ };
41
+ /** Block-level. `feature` is a container and safe early.
42
+ *
43
+ * `active` IS NOT, and that is the whole timing rule: a default
44
+ * synthesized into an OVERLAY block overwrites the base's real value
45
+ * and silently reactivates an integration the base deliberately barred
46
+ * (§3.3). So the two consumers read this same table at different
47
+ * moments - validateConfig before, to every block, because a block with
48
+ * no present keys is an open map; the resolver AFTER, to the merged
49
+ * instance, because an absent key must stay absent through the merge. */
50
+ exports.BLOCK_DEFAULTS = {
51
+ active: () => true,
52
+ feature: () => ({}),
53
+ };
54
+ /** The one block key carrying the timing rule. Named rather than
55
+ * inferred, so a reader does not have to work out which of the two it
56
+ * is, and so a port can assert it. */
57
+ exports.MERGE_SENSITIVE = ['active'];
58
+ // ---------------------------------------------------------------------
59
+ // normalizeConfig
60
+ // ---------------------------------------------------------------------
61
+ /** Materialize every documented default, DEFENSIVELY: a node that is
62
+ * not the kind it expects is left alone for validate to reject with a
63
+ * proper message. Pure data-in/data-out, which is what makes it
64
+ * portable to 22 languages and expressible in the corpus.
65
+ *
66
+ * THE NORMALIZED FORM IS AN INPUT TO VALIDATION AND TO NOTHING ELSE. */
67
+ function normalizeConfig(raw) {
68
+ if (!ismap(raw)) {
69
+ return raw;
70
+ }
71
+ const out = { ...raw };
72
+ if (undefined === out.station) {
73
+ out.station = 1;
74
+ }
75
+ if (undefined === out.profiles) {
76
+ out.profiles = {};
77
+ }
78
+ if (!ismap(out.profiles)) {
79
+ return out;
80
+ }
81
+ const profiles = {};
82
+ for (const pname of Object.keys(out.profiles)) {
83
+ const p = out.profiles[pname];
84
+ if (!ismap(p)) {
85
+ profiles[pname] = p;
86
+ continue;
87
+ }
88
+ const prof = { ...p };
89
+ for (const k of Object.keys(exports.PROFILE_DEFAULTS)) {
90
+ if (undefined === prof[k]) {
91
+ prof[k] = exports.PROFILE_DEFAULTS[k]();
92
+ }
93
+ }
94
+ // A `secrets` written without `providers` still gets the chain.
95
+ if (ismap(prof.secrets) && undefined === prof.secrets.providers) {
96
+ prof.secrets = { ...prof.secrets, providers: [{ kind: 'env' }] };
97
+ }
98
+ prof.feature = normfeatures(prof.feature);
99
+ for (const bkey of ['api', 'sdk']) {
100
+ if (!ismap(prof[bkey])) {
101
+ continue;
102
+ }
103
+ const blocks = {};
104
+ for (const ref of Object.keys(prof[bkey])) {
105
+ const b = prof[bkey][ref];
106
+ if (!ismap(b)) {
107
+ blocks[ref] = b;
108
+ continue;
109
+ }
110
+ const block = { ...b };
111
+ for (const k of Object.keys(exports.BLOCK_DEFAULTS)) {
112
+ if (undefined === block[k]) {
113
+ block[k] = exports.BLOCK_DEFAULTS[k]();
114
+ }
115
+ }
116
+ block.feature = normfeatures(block.feature);
117
+ blocks[ref] = block;
118
+ }
119
+ prof[bkey] = blocks;
120
+ }
121
+ profiles[pname] = prof;
122
+ }
123
+ out.profiles = profiles;
124
+ return out;
125
+ }
126
+ /** Per feature entry, at every level: `active` -> true.
127
+ *
128
+ * A FEATURE NAMED IN THE CONFIG IS ONE YOU ARE ASKING FOR. The SDK's
129
+ * own default is `active: false` for all but `log`, and
130
+ * `{"retry": {"retries": 3}}` plainly means "retry, with three
131
+ * attempts". It also keeps the feature map closed, for the same reason
132
+ * every other block needs one present key.
133
+ *
134
+ * Defensive like the rest: a non-map is returned untouched for validate
135
+ * to reject by path. */
136
+ function normfeatures(f) {
137
+ if (!ismap(f)) {
138
+ return f;
139
+ }
140
+ const out = {};
141
+ for (const name of Object.keys(f)) {
142
+ const e = f[name];
143
+ out[name] = ismap(e) && undefined === e.active ? { ...e, active: true } : e;
144
+ }
145
+ return out;
146
+ }
147
+ // ---------------------------------------------------------------------
148
+ // validateConfig
149
+ // ---------------------------------------------------------------------
150
+ /** `spec/config-shape.json`, §4.3 verbatim, through the shipped mirror.
151
+ * Every validate gets a CLONE: struct's validate consumes the spec it
152
+ * walks (it deletes satisfied `$ONE` branches as it goes), so handing it
153
+ * the module constant twice would validate the second config against a
154
+ * spec the first had already eaten. */
155
+ function configShape() {
156
+ return (0, struct_1.clone)(config_shape_1.CONFIG_SHAPE);
157
+ }
158
+ /** Credential-shaped keys (§5.2). `secret` is here AND is the one
159
+ * exempt key - see secretvalue below; a blanket deny would reject the
160
+ * very mechanism that keeps values out of the file. */
161
+ const CREDENTIAL_KEYS = [
162
+ 'apikey', 'auth', 'authorization', 'token',
163
+ 'secret', 'password', 'credential', 'bearer',
164
+ ];
165
+ /** The suffix rule catches `access_key`, `X-Api-Token` and friends in
166
+ * one rule rather than a growing list of spellings. */
167
+ const CREDENTIAL_SUFFIX = ['_KEY', '_TOKEN', '_SECRET', '_PASSWORD'];
168
+ /** §5.2's backstop, and it is stated as one rather than as a grammar.
169
+ * `validname()` is a NAME grammar, not a credential filter: it rejects
170
+ * uppercase, hyphens, `+`, `/` and `=`, so it excludes most real
171
+ * credential formats - but a lowercase hex token passes it cleanly. A
172
+ * character class cannot tell a name from a secret.
173
+ *
174
+ * Derived names break on every separator (`voxgig_solardemo.apikey`
175
+ * runs 6/9/6) and a hand-written name for a human to read does too; a
176
+ * 24-character unbroken run is not a name anybody writes. Note this is
177
+ * a RUN bound, not a length bound: `acme_internal_billing_service.apikey`
178
+ * is 36 characters and passes, which is the false positive a naive
179
+ * length bound would produce. */
180
+ const RUN_BOUND = 24;
181
+ const UNBROKEN_RUN = new RegExp('[A-Za-z0-9]{' + RUN_BOUND + ',}');
182
+ /** Normalize, then validate (§4.2). Raises `station_config_invalid`
183
+ * with EVERY struct error at once - an eighteen-instance config that
184
+ * touches three of them must not die because the eighteenth has a
185
+ * typo'd package name - then the §5.2 scans.
186
+ *
187
+ * Takes the NORMALIZED form. Handing it a raw config is the mistake
188
+ * §4.2 exists to prevent, so callers go through open()/loadConfig. */
189
+ function validateConfig(normalized) {
190
+ const errs = [];
191
+ (0, struct_1.validate)(normalized, configShape(), { errs });
192
+ if (0 < errs.length) {
193
+ throw new error_1.StationError('station_config_invalid', errs.join('; ') + renamehint(normalized));
194
+ }
195
+ scanConfig(normalized);
196
+ return normalized;
197
+ }
198
+ /** `plugin` is REMOVED, not aliased (§3.4) - a deprecated alias would
199
+ * be a second grammar for one concept in 17 ports. The shape already
200
+ * rejects it as an unexpected key; this says what to rename, because
201
+ * "unexpected key: plugin" alone does not, and the migration for a
202
+ * single-instance project is exactly this one rename. */
203
+ function renamehint(cfg) {
204
+ const profiles = ismap(cfg) && ismap(cfg.profiles) ? cfg.profiles : {};
205
+ const hit = Object.keys(profiles)
206
+ .filter((p) => ismap(profiles[p]) && undefined !== profiles[p].plugin);
207
+ if (0 === hit.length) {
208
+ return '';
209
+ }
210
+ return '; rename `plugin` to `sdk` in ' +
211
+ hit.map((p) => 'profiles.' + p).join(', ') +
212
+ ' - the keys are unchanged, an untagged ref IS an api slug (§3.4)';
213
+ }
214
+ /** The §5.2 scans, over the parts of the grammar that hold arbitrary
215
+ * data. Everything else is closed by construction and needs no scan. */
216
+ function scanConfig(cfg) {
217
+ const secrets = [];
218
+ const reserved = [];
219
+ const invalid = [];
220
+ const profiles = ismap(cfg) && ismap(cfg.profiles) ? cfg.profiles : {};
221
+ for (const pname of Object.keys(profiles)) {
222
+ const prof = profiles[pname];
223
+ if (!ismap(prof)) {
224
+ continue;
225
+ }
226
+ const ppath = 'profiles.' + pname;
227
+ checkfeatures(prof.feature, ppath + '.feature', secrets, reserved, invalid);
228
+ for (const bkey of ['api', 'sdk']) {
229
+ if (!ismap(prof[bkey])) {
230
+ continue;
231
+ }
232
+ for (const ref of Object.keys(prof[bkey])) {
233
+ const block = prof[bkey][ref];
234
+ if (!ismap(block)) {
235
+ continue;
236
+ }
237
+ const bpath = ppath + '.' + bkey + '.' + ref;
238
+ // The block's own `secret` holds a NAME. resolveProfile checks
239
+ // it again per instance (station_secret_name); this catches it
240
+ // at open(), for the whole file at once.
241
+ if (undefined !== block.secret) {
242
+ secretvalue(block.secret, bpath + '.secret', secrets);
243
+ }
244
+ // `options` is passthrough to a generated constructor, so it is
245
+ // the one place a value can hide.
246
+ scan(block.options, bpath + '.options', secrets, reserved);
247
+ checkfeatures(block.feature, bpath + '.feature', secrets, reserved, invalid);
248
+ // §4.4's explicit checks, applied where the shape cannot reach,
249
+ // raising the same code the shape would - and pinned in the
250
+ // corpus so each workaround is removed deliberately when struct
251
+ // is fixed rather than forgotten.
252
+ checkpolicy(block.policy, bpath + '.policy', invalid);
253
+ }
254
+ }
255
+ }
256
+ if (0 < invalid.length) {
257
+ throw new error_1.StationError('station_config_invalid', invalid.join('; '));
258
+ }
259
+ if (0 < reserved.length) {
260
+ throw new error_1.StationError('station_feature_reserved', reserved.join('; '));
261
+ }
262
+ if (0 < secrets.length) {
263
+ throw new error_1.StationError('station_config_secret', secrets.join('; '));
264
+ }
265
+ }
266
+ /** A feature map at any level. `station` is reserved: station composes
267
+ * its own wrap and a config that reconfigures it is asking for a state
268
+ * the ordering rules cannot express (§8.4). */
269
+ function checkfeatures(f, path, secrets, reserved, invalid) {
270
+ if (!ismap(f)) {
271
+ return;
272
+ }
273
+ for (const name of Object.keys(f)) {
274
+ const fpath = path + '.' + name;
275
+ if ('station' === name) {
276
+ reserved.push(path + '.station is reserved: station composes its own ' +
277
+ 'wrap and it cannot be configured from station.json');
278
+ }
279
+ const order = ismap(f[name]) ? f[name].order : undefined;
280
+ if (ismap(order)) {
281
+ firstelement(order.before, fpath + '.order.before', invalid);
282
+ firstelement(order.after, fpath + '.order.after', invalid);
283
+ }
284
+ scan(f[name], fpath, secrets, reserved);
285
+ }
286
+ }
287
+ /** The policy block's §4.4 workarounds, in one place because they are
288
+ * one class of gap: struct cannot check what its own defects hide.
289
+ *
290
+ * - `hosts`, `allow.op` and `allow.method` are `$CHILD` string lists,
291
+ * so element 0 escapes the shape (see firstelement below).
292
+ * - `budget` is a map whose keys are ALL optional scalars, and struct
293
+ * removes an unsatisfied optional key from the spec node - so
294
+ * `budget: {rp: 1}` degenerates the spec into an open map and the
295
+ * typo passes. `allow` does not have this problem (its `$CHILD` keys
296
+ * stay in the spec whether or not the data carries them, keeping the
297
+ * map closed), and neither does `policy` itself (`hosts` anchors it);
298
+ * `budget` alone needs the explicit unexpected-key check, phrased as
299
+ * struct would phrase it. */
300
+ const BUDGET_KEYS = ['concurrency', 'rps'];
301
+ function checkpolicy(policy, path, invalid) {
302
+ if (!ismap(policy)) {
303
+ return;
304
+ }
305
+ firstelement(policy.hosts, path + '.hosts', invalid);
306
+ const allow = policy.allow;
307
+ if (ismap(allow)) {
308
+ firstelement(allow.op, path + '.allow.op', invalid);
309
+ firstelement(allow.method, path + '.allow.method', invalid);
310
+ }
311
+ const budget = policy.budget;
312
+ if (ismap(budget)) {
313
+ const unknown = Object.keys(budget)
314
+ .filter((k) => !BUDGET_KEYS.includes(k)).sort();
315
+ if (0 < unknown.length) {
316
+ invalid.push('Unexpected keys at field ' + path + '.budget: ' +
317
+ unknown.join(', '));
318
+ }
319
+ }
320
+ }
321
+ /** §4.4: `$CHILD` in list mode DOES NOT VALIDATE ELEMENT 0. Verified:
322
+ * `["a", 1]` fails at index 1, `[1]` passes. validate_CHILD installs the
323
+ * template across the data's indices, sets keyI = 0 and returns element
324
+ * 0 as the slot value, and the injection loop resumes past it. An
325
+ * upstream struct defect; filing it is a deliverable of this plan.
326
+ *
327
+ * It reaches EVERY string list in the shape. §4.4 says the only one left
328
+ * is `policy.hosts` because the profile-level `order` list is gone - but
329
+ * §8.4's per-feature `order` carries `before`/`after` string lists, so
330
+ * the reach is three lists, not one, and §4.5 pins `order: [7]`
331
+ * accordingly. Applied where the shape cannot reach, raising the same
332
+ * code the shape would, and pinned in the corpus so the workaround is
333
+ * removed deliberately when struct is fixed rather than forgotten. */
334
+ function firstelement(list, path, invalid) {
335
+ if (!Array.isArray(list) || 0 === list.length) {
336
+ return;
337
+ }
338
+ if ('string' === typeof list[0]) {
339
+ return;
340
+ }
341
+ invalid.push('Expected field ' + path + '.0 to be string, but found ' +
342
+ kindof(list[0]) + ': ' + JSON.stringify(list[0]));
343
+ }
344
+ /** Recursive over EVERY nested map and list, not just the top level -
345
+ * a credential one level down is the case a top-level scan misses. */
346
+ function scan(node, path, secrets, reserved) {
347
+ if (Array.isArray(node)) {
348
+ for (let i = 0; i < node.length; i++) {
349
+ scan(node[i], path + '.' + i, secrets, reserved);
350
+ }
351
+ return;
352
+ }
353
+ if ('string' === typeof node) {
354
+ userinfo(node, path, secrets);
355
+ return;
356
+ }
357
+ if (!ismap(node)) {
358
+ return;
359
+ }
360
+ for (const key of Object.keys(node)) {
361
+ const kpath = path + '.' + key;
362
+ const val = node[key];
363
+ // §8.6: station owns feature composition, so an `options.feature`
364
+ // in a declarative config is a second, unreconciled ordering input.
365
+ if ('feature' === key) {
366
+ reserved.push(kpath + ' is reserved: configure features under the ' +
367
+ 'block\'s own `feature` key, not through `options`');
368
+ continue;
369
+ }
370
+ if ('secret' === key.toLowerCase()) {
371
+ secretvalue(val, kpath, secrets);
372
+ continue;
373
+ }
374
+ if (credentialkey(key)) {
375
+ secrets.push(kpath + ' is a credential-shaped key: station.json ' +
376
+ 'holds secret NAMES, never values (§5.2)');
377
+ continue;
378
+ }
379
+ scan(val, kpath, secrets, reserved);
380
+ }
381
+ }
382
+ function credentialkey(key) {
383
+ const low = String(key).toLowerCase().replace(/[^a-z0-9]+/g, '');
384
+ if (CREDENTIAL_KEYS.includes(low)) {
385
+ return true;
386
+ }
387
+ const tok = (0, descriptor_1.envtoken)(key);
388
+ return CREDENTIAL_SUFFIX.some((s) => tok.endsWith(s));
389
+ }
390
+ /** A `secret`-named key holds a NAME, and that exemption is not a
391
+ * loophole - it is the whole design. Two checks, not one, and they live
392
+ * in the same three lines precisely so a port cannot implement only the
393
+ * first and inherit the gap the second exists to close. */
394
+ function secretvalue(val, path, secrets) {
395
+ if ('string' !== typeof val) {
396
+ secrets.push(path + ' must be a secret name (a string), but found ' +
397
+ kindof(val));
398
+ return;
399
+ }
400
+ if (!(0, sekreto_1.validname)(val)) {
401
+ secrets.push(path + ' is not a valid sekreto name, so it cannot be a ' +
402
+ 'name and must not be a value: ' + JSON.stringify(val));
403
+ return;
404
+ }
405
+ if (UNBROKEN_RUN.test(val)) {
406
+ secrets.push(path + ' contains an unbroken alphanumeric run of ' +
407
+ RUN_BOUND + ' or more characters, which is not a name anybody writes');
408
+ }
409
+ }
410
+ /** One rule about values rather than keys, because the `proxy` feature
411
+ * makes it concrete: `http://user:pass@proxy.internal:8080`. */
412
+ function userinfo(val, path, secrets) {
413
+ if (!/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(val)) {
414
+ return;
415
+ }
416
+ let u;
417
+ try {
418
+ u = new URL(val);
419
+ }
420
+ catch (e) {
421
+ return;
422
+ }
423
+ if ('' !== u.username || '' !== u.password) {
424
+ secrets.push(path + ' is a URL carrying userinfo, which puts a ' +
425
+ 'credential in the config file; use the proxy feature\'s ' +
426
+ '`fromEnv` option instead (§8.6)');
427
+ }
428
+ }
429
+ function kindof(v) {
430
+ if (null === v) {
431
+ return 'null';
432
+ }
433
+ if (Array.isArray(v)) {
434
+ return 'list';
435
+ }
436
+ if ('number' === typeof v) {
437
+ return Number.isInteger(v) ? 'integer' : 'decimal';
438
+ }
439
+ return typeof v;
440
+ }
441
+ function ismap(v) {
442
+ return null != v && 'object' === typeof v && !Array.isArray(v);
443
+ }
444
+ //# sourceMappingURL=shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape.js","sourceRoot":"","sources":["../../src/shape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ export type StationOptions = {
2
+ profile?: string;
3
+ proxy?: 'auto' | 'off' | 'require' | string;
4
+ folder?: string;
5
+ config?: StationConfig | null;
6
+ load?: boolean;
7
+ repoScoped?: boolean;
8
+ };
9
+ export type StationConfig = {
10
+ station: number;
11
+ profiles?: Record<string, Profile>;
12
+ };
13
+ export type Profile = {
14
+ secrets?: {
15
+ providers?: any[];
16
+ };
17
+ feature?: Record<string, any>;
18
+ api?: Record<string, SdkBlock>;
19
+ sdk?: Record<string, SdkBlock>;
20
+ };
21
+ export type PolicyBlock = {
22
+ hosts?: string[];
23
+ allow?: {
24
+ op?: string[];
25
+ method?: string[];
26
+ };
27
+ budget?: {
28
+ rps?: number;
29
+ concurrency?: number;
30
+ };
31
+ mode?: 'live' | 'record' | 'replay' | 'mock' | 'block';
32
+ };
33
+ export type SdkBlock = {
34
+ package?: string;
35
+ export?: string;
36
+ base?: string;
37
+ secret?: string;
38
+ resolve?: 'library' | 'proxy';
39
+ policy?: PolicyBlock;
40
+ capture?: 'meta' | 'headers' | 'full';
41
+ agent?: {
42
+ write: boolean;
43
+ };
44
+ feature?: Record<string, any>;
45
+ options?: Record<string, any>;
46
+ active?: boolean;
47
+ };
48
+ export type Descriptor = {
49
+ station: 1;
50
+ name: string;
51
+ slug: string;
52
+ envtoken: string;
53
+ version: string;
54
+ target: string;
55
+ base: string;
56
+ server: {
57
+ name: string;
58
+ value: string;
59
+ }[];
60
+ auth: {
61
+ active: boolean;
62
+ prefix: string;
63
+ secretname: string;
64
+ };
65
+ entities: Record<string, DescriptorEntity>;
66
+ features: {
67
+ name: string;
68
+ active: boolean;
69
+ options?: Record<string, any>;
70
+ transport?: string;
71
+ }[];
72
+ };
73
+ export type DescriptorEntity = {
74
+ fields: Record<string, {
75
+ kind: string;
76
+ }>;
77
+ ops: Record<string, {
78
+ points: DescriptorPoint[];
79
+ }>;
80
+ };
81
+ export type DescriptorPoint = {
82
+ method: string;
83
+ path: string;
84
+ params: string[];
85
+ select?: Record<string, any>;
86
+ };
87
+ export type StationEvent = {
88
+ t: number;
89
+ plugin?: string;
90
+ api?: string;
91
+ corr?: string;
92
+ kind: 'construct' | 'op' | 'http' | 'error' | 'feature' | 'station';
93
+ op?: {
94
+ entity: string;
95
+ op: string;
96
+ outcome: string;
97
+ durationMs: number;
98
+ };
99
+ http?: {
100
+ method: string;
101
+ host: string;
102
+ path: string;
103
+ status: number;
104
+ durationMs: number;
105
+ bytes: number;
106
+ };
107
+ err?: {
108
+ code?: string;
109
+ status?: number;
110
+ message: string;
111
+ };
112
+ meta?: Record<string, any>;
113
+ };
114
+ export type Binding = {
115
+ plugin: string;
116
+ instance?: string;
117
+ base?: string;
118
+ placeholder?: string;
119
+ secretname?: string;
120
+ rung: 'none' | 'R1';
121
+ };
122
+ export type PluginEntry = {
123
+ name: string;
124
+ api: string;
125
+ descriptor: Descriptor;
126
+ rung: 'none' | 'R1';
127
+ client: any;
128
+ warnings: string[];
129
+ secretname?: string;
130
+ };
131
+ export type ResolvedInstance = {
132
+ name: string;
133
+ api: string;
134
+ active: boolean;
135
+ live: boolean;
136
+ rung: 'none' | 'R1';
137
+ block: SdkBlock;
138
+ };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ // Shared station types. Descriptor and StationEvent shapes are pinned by
3
+ // the conformance corpus (spec/station.json) - evolve them additively.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,yEAAyE;AACzE,uEAAuE"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@voxgig/station",
3
+ "version": "0.0.1",
4
+ "description": "station: one control surface for outbound integrations (TypeScript, canonical)",
5
+ "main": "dist/src/index.js",
6
+ "type": "commonjs",
7
+ "types": "dist/src/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/src/index.d.ts",
11
+ "browser": "./dist/src/index.browser.js",
12
+ "default": "./dist/src/index.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "homepage": "https://github.com/voxgig/station",
17
+ "keywords": [
18
+ "voxgig",
19
+ "station",
20
+ "sdk",
21
+ "integration",
22
+ "api-client",
23
+ "plugins"
24
+ ],
25
+ "author": "",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git://github.com/voxgig/station.git"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "clean": "rm -rf dist coverage node_modules package-lock.json",
33
+ "test": "npm run build && node --test \"dist/test/*.test.js\"",
34
+ "test-some": "npm run build && node --test --test-name-pattern=$npm_config_pattern \"dist/test/*.test.js\"",
35
+ "watch": "tsc -w",
36
+ "typecheck": "tsc --noEmit",
37
+ "reset": "npm run clean && npm i && npm run build && npm test",
38
+ "repo-tag": "REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: typescript/v$REPO_VERSION && git commit -a -m typescript/v$REPO_VERSION && git push && git tag typescript/v$REPO_VERSION && git push --tags;",
39
+ "repo-publish": "npm run clean && npm i && npm run repo-publish-quick",
40
+ "repo-publish-quick": "npm run build && npm run test && npm run repo-tag && npm stage publish --access public --registry https://registry.npmjs.org",
41
+ "repo-publish-dry": "npm run clean && npm i && npm run repo-publish-dry-quick",
42
+ "repo-publish-dry-quick": "npm run build && npm run test && npm stage publish --dry-run --access public --registry https://registry.npmjs.org"
43
+ },
44
+ "license": "MIT",
45
+ "files": [
46
+ "LICENSE",
47
+ "src",
48
+ "!src/omnihome.*",
49
+ "dist/src",
50
+ "!dist/src/omnihome.*"
51
+ ],
52
+ "dependencies": {
53
+ "@voxgig/sekreto": "^0.1.0",
54
+ "@voxgig/struct": "^0.2.2"
55
+ },
56
+ "devDependencies": {
57
+ "@types/node": "^22.0.0",
58
+ "typescript": "^5.5.0"
59
+ }
60
+ }