@feasibleone/blong 1.16.1 → 1.18.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.
- package/CHANGELOG.md +35 -0
- package/dist/model.js +10 -0
- package/dist/model.js.map +1 -0
- package/dist/types.d.ts +412 -127
- package/dist/types.js +22 -32
- package/dist/types.js.map +1 -1
- package/package.json +9 -6
- package/types.ts +298 -141
package/types.ts
CHANGED
|
@@ -24,12 +24,15 @@ import {
|
|
|
24
24
|
type TUnknown,
|
|
25
25
|
} from 'typebox';
|
|
26
26
|
// import type {client} from 'node-vault';
|
|
27
|
-
import type {
|
|
27
|
+
import type {ChokidarOptions, FSWatcherEventMap} from 'chokidar';
|
|
28
|
+
import type {EventEmitter} from 'events';
|
|
29
|
+
import type {Dirent, StatSyncFn} from 'node:fs';
|
|
28
30
|
import type {Duplex} from 'node:stream';
|
|
29
31
|
import type {OpenAPI, OpenAPIV2, OpenAPIV3_1} from 'openapi-types';
|
|
30
32
|
import type {Level, LogFn, Logger as PinoLogger} from 'pino';
|
|
31
33
|
import merge from 'ut-function.merge';
|
|
32
34
|
import type {Knex} from './knex.js';
|
|
35
|
+
import type {IMock, IModelSpec} from './model.ts';
|
|
33
36
|
|
|
34
37
|
// export {
|
|
35
38
|
// AppsV1Api,
|
|
@@ -45,6 +48,7 @@ export type * from 'mongodb';
|
|
|
45
48
|
export type {IJsonSchema, OpenAPI, OpenAPIV2, OpenAPIV3, OpenAPIV3_1} from 'openapi-types';
|
|
46
49
|
// export type {Level, LogFn, Logger as PinoLogger} from 'pino';
|
|
47
50
|
export type {Knex} from './knex.js';
|
|
51
|
+
export type * from './model.ts';
|
|
48
52
|
|
|
49
53
|
export type ServerContext = {
|
|
50
54
|
queryBuilder?: Knex;
|
|
@@ -75,6 +79,89 @@ export interface ILog {
|
|
|
75
79
|
child: PinoLogger['child'];
|
|
76
80
|
}
|
|
77
81
|
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Types
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
/** A flat map of dotted-path → [prev, next] pairs that represent changed keys */
|
|
87
|
+
export type ConfigDiff = Map<string, {prev: unknown; next: unknown}>;
|
|
88
|
+
|
|
89
|
+
/** Subscriber callback invoked after a successful reload */
|
|
90
|
+
export type ConfigSubscriber = (
|
|
91
|
+
diff: ConfigDiff,
|
|
92
|
+
next: object,
|
|
93
|
+
prev: object,
|
|
94
|
+
) => void | Promise<void>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Mode used when the config proxy is queried during handler factory initialisation.
|
|
98
|
+
*
|
|
99
|
+
* - `'throw'` — throw immediately (default; keeps misuse from going unnoticed)
|
|
100
|
+
* - `'collect'` — accumulate errors and return them from exitConfigFactoryPhase()
|
|
101
|
+
* (useful in tests that explicitly verify the anti-pattern is caught)
|
|
102
|
+
*/
|
|
103
|
+
export type FactoryPhaseMode = 'throw' | 'collect';
|
|
104
|
+
export interface IConfigRuntime {
|
|
105
|
+
/** Current effective config, exposed as a live proxy */
|
|
106
|
+
readonly snapshot: object;
|
|
107
|
+
/** Raw (non-proxy) snapshot of the current effective config */
|
|
108
|
+
readonly rawSnapshot: object;
|
|
109
|
+
/** Load (or reload) config from all sources; returns the updated snapshot */
|
|
110
|
+
load(params?: object): Promise<object>;
|
|
111
|
+
/**
|
|
112
|
+
* Reload config in-place. The backing store of the proxy is updated so all
|
|
113
|
+
* existing proxy references automatically reflect the new values.
|
|
114
|
+
* Returns the computed diff.
|
|
115
|
+
*/
|
|
116
|
+
reload(): Promise<ConfigDiff>;
|
|
117
|
+
/** Compute the diff between two plain config objects without modifying state */
|
|
118
|
+
diff(prev: object, next: object): ConfigDiff;
|
|
119
|
+
/** Register a subscriber to be called after every successful reload */
|
|
120
|
+
subscribe(fn: ConfigSubscriber): () => void;
|
|
121
|
+
/** Enter the config factory phase */
|
|
122
|
+
enterConfig(mode?: FactoryPhaseMode): void;
|
|
123
|
+
/** Exit the config factory phase */
|
|
124
|
+
exitConfig(): Error[];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface IWatcher extends EventEmitter<FSWatcherEventMap> {
|
|
128
|
+
close(): Promise<void>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export type HRTime = [number, number];
|
|
132
|
+
|
|
133
|
+
export interface IPlatformApi {
|
|
134
|
+
platform: 'server' | 'browser';
|
|
135
|
+
loadConfig: (
|
|
136
|
+
config: string | object,
|
|
137
|
+
) => Promise<{loadedConfig?: object; configRuntime?: IConfigRuntime}>;
|
|
138
|
+
readdir: (path: string) => Promise<Dirent[]>;
|
|
139
|
+
scan: (...path: string[]) => Promise<Dirent[]>;
|
|
140
|
+
existsSync: (path: string) => boolean;
|
|
141
|
+
createRequire?: (path: string | URL) => NodeJS.Require;
|
|
142
|
+
join: (...paths: string[]) => string;
|
|
143
|
+
dirname: (path: string) => string;
|
|
144
|
+
basename: (path: string, ext?: string) => string;
|
|
145
|
+
relative: (from: string, to: string) => string;
|
|
146
|
+
extname: (path: string) => string;
|
|
147
|
+
resolve: (...paths: string[]) => string;
|
|
148
|
+
readFileSync: (path: string, options?: {encoding: BufferEncoding}) => string | Buffer;
|
|
149
|
+
writeFileSync: (
|
|
150
|
+
path: string,
|
|
151
|
+
data: string | Buffer,
|
|
152
|
+
options?: {encoding: BufferEncoding},
|
|
153
|
+
) => void;
|
|
154
|
+
statSync: StatSyncFn;
|
|
155
|
+
watch?: (path: string | string[], options?: ChokidarOptions) => IWatcher;
|
|
156
|
+
timing: {
|
|
157
|
+
diff: (time: HRTime, newTime: HRTime) => number;
|
|
158
|
+
after: (milliseconds: number) => HRTime;
|
|
159
|
+
now: (previous?: HRTime) => HRTime;
|
|
160
|
+
isAfter: (time: HRTime, timeout: HRTime) => boolean;
|
|
161
|
+
spare: (time: HRTime, latency?: number) => number;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
78
165
|
export interface IErrorFactory {
|
|
79
166
|
get(type?: string): unknown;
|
|
80
167
|
fetch(type: string): object;
|
|
@@ -160,6 +247,10 @@ export interface IApiSchema {
|
|
|
160
247
|
): Promise<Record<string, GatewaySchema>>;
|
|
161
248
|
generateFile(file: string): Promise<boolean>;
|
|
162
249
|
generateDir(dir: string, files: Dirent[]): Promise<boolean>;
|
|
250
|
+
loadApi(
|
|
251
|
+
locations: string | string[] | object | object[] | {assets: object},
|
|
252
|
+
source: string,
|
|
253
|
+
): unknown;
|
|
163
254
|
}
|
|
164
255
|
|
|
165
256
|
export interface IGateway {
|
|
@@ -175,28 +266,30 @@ export interface IGateway {
|
|
|
175
266
|
export type Handlers = ((params: {
|
|
176
267
|
remote: unknown;
|
|
177
268
|
lib: object;
|
|
178
|
-
port: object;
|
|
269
|
+
port: object | undefined;
|
|
179
270
|
local: object;
|
|
180
271
|
literals: object[];
|
|
181
272
|
gateway: IGateway;
|
|
273
|
+
apiSchema: IApiSchema;
|
|
274
|
+
attachCheckpoint?: (meta: IMeta) => void;
|
|
182
275
|
}) => void)[];
|
|
183
276
|
|
|
184
277
|
export interface IRegistry {
|
|
185
|
-
start: (configOverride
|
|
278
|
+
start: (configOverride: object) => Promise<IRegistry>;
|
|
186
279
|
test: (tester?: unknown) => Promise<void>;
|
|
187
280
|
stop: () => Promise<IRegistry>;
|
|
188
|
-
ports: Map<string,
|
|
281
|
+
ports: Map<string, IAdapterRegistry>;
|
|
189
282
|
methods: Map<string, Handlers>;
|
|
190
283
|
modules: Map<string | symbol, IRegistry[]>;
|
|
191
|
-
createPort: (id: string) => Promise<
|
|
192
|
-
getPort: (id: string) =>
|
|
193
|
-
replaceHandlers: (id: string, handlers:
|
|
284
|
+
createPort: (id: string) => Promise<Adapter | undefined>;
|
|
285
|
+
getPort: (id: string) => Adapter | undefined;
|
|
286
|
+
replaceHandlers: (id: string, handlers: Handlers) => Promise<void>;
|
|
194
287
|
loadApi: (
|
|
195
288
|
id: string,
|
|
196
289
|
def: {
|
|
197
290
|
namespace: Record<string, string | string[]>;
|
|
198
291
|
},
|
|
199
|
-
source
|
|
292
|
+
source: string,
|
|
200
293
|
) => Promise<void>;
|
|
201
294
|
connected: () => Promise<boolean>;
|
|
202
295
|
}
|
|
@@ -204,15 +297,7 @@ export interface IRegistry {
|
|
|
204
297
|
export interface IApi {
|
|
205
298
|
id?: string;
|
|
206
299
|
type: typeof Type;
|
|
207
|
-
adapter: (
|
|
208
|
-
id: string,
|
|
209
|
-
) => (api: {
|
|
210
|
-
utError: IError;
|
|
211
|
-
remote: IRemote;
|
|
212
|
-
rpc: IRpcServer;
|
|
213
|
-
local: ILocal;
|
|
214
|
-
registry: IRegistry;
|
|
215
|
-
}) => object;
|
|
300
|
+
adapter: (id: string) => IAdapterRegistry | undefined;
|
|
216
301
|
utError: IError;
|
|
217
302
|
errors: IErrorFactory;
|
|
218
303
|
gateway: unknown;
|
|
@@ -220,24 +305,27 @@ export interface IApi {
|
|
|
220
305
|
rpc: IRpcServer;
|
|
221
306
|
local: ILocal;
|
|
222
307
|
registry: IRegistry;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
308
|
+
register: (methods: object, namespace: string, id: string, pkg: {version: string}) => void;
|
|
309
|
+
unregister: (methods: string[], namespace: string) => void;
|
|
310
|
+
subscribe: (methods: object, namespace: string, id: string, pkg: {version: string}) => void;
|
|
311
|
+
unsubscribe: (methods: string[], namespace: string) => void;
|
|
312
|
+
dispatch: (...params: unknown[]) => boolean | Promise<unknown>;
|
|
313
|
+
methodId: (name: string) => string;
|
|
314
|
+
getPath: (name: string) => string;
|
|
315
|
+
importMethod: (
|
|
316
|
+
methodName: string,
|
|
317
|
+
options?: object,
|
|
318
|
+
) => (...params: unknown[]) => Promise<unknown>;
|
|
319
|
+
attachHandlers: (
|
|
320
|
+
target: {
|
|
321
|
+
importedMap?: Map<string, object>;
|
|
322
|
+
imported: object;
|
|
323
|
+
config: {namespace?: string | string[]};
|
|
324
|
+
},
|
|
325
|
+
patterns: (string | RegExp)[] | string | RegExp,
|
|
326
|
+
adapter?: boolean,
|
|
327
|
+
) => unknown;
|
|
328
|
+
createLog: ILog['logger'];
|
|
241
329
|
attachCheckpoint?: (meta: IMeta) => void;
|
|
242
330
|
handlers?: (api: {utError: IError; remote: IRemote; type: typeof Type}) => {
|
|
243
331
|
extends?:
|
|
@@ -262,6 +350,21 @@ export interface IErrorMap {
|
|
|
262
350
|
};
|
|
263
351
|
}
|
|
264
352
|
|
|
353
|
+
export type Adapter<T = Record<string, unknown>, C = Record<string, unknown>> = IAdapter<T, C> &
|
|
354
|
+
Pick<
|
|
355
|
+
Required<IAdapter<T, C>>,
|
|
356
|
+
| 'init'
|
|
357
|
+
| 'start'
|
|
358
|
+
| 'stop'
|
|
359
|
+
| 'ready'
|
|
360
|
+
| 'config'
|
|
361
|
+
| 'imported'
|
|
362
|
+
| 'errors'
|
|
363
|
+
| 'error'
|
|
364
|
+
| 'findValidation'
|
|
365
|
+
| 'getConversion'
|
|
366
|
+
| 'dispatch'
|
|
367
|
+
>;
|
|
265
368
|
export interface IAdapter<T, C> {
|
|
266
369
|
validation?: TSchema;
|
|
267
370
|
config?: Config<T, C>;
|
|
@@ -269,59 +372,63 @@ export interface IAdapter<T, C> {
|
|
|
269
372
|
configBase?: string;
|
|
270
373
|
log?: ILogger;
|
|
271
374
|
errors?: Errors<IErrorMap>;
|
|
272
|
-
imported?:
|
|
375
|
+
imported?: Record<string, PortHandlerBound>;
|
|
376
|
+
importedMap?: Map<string, IRemoteHandler>;
|
|
273
377
|
extends?: object | `adapter.${string}` | `orchestrator.${string}`;
|
|
274
|
-
activeConfig
|
|
275
|
-
init
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
unpack
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
)
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
378
|
+
activeConfig?(this: Adapter<T, C>): Partial<Config<T, C>>;
|
|
379
|
+
init?(this: Adapter<T, C>, ...config: unknown[]): Promise<unknown>;
|
|
380
|
+
start?(this: Adapter<T, C>, ...params: unknown[]): Promise<unknown>;
|
|
381
|
+
ready?(this: Adapter<T, C>): Promise<unknown>;
|
|
382
|
+
stop?(this: Adapter<T, C>, ...params: unknown[]): Promise<unknown>;
|
|
383
|
+
link?(
|
|
384
|
+
this: Adapter<T, C>,
|
|
385
|
+
patterns: (string | RegExp)[] | string | RegExp,
|
|
386
|
+
target: object,
|
|
387
|
+
): Promise<{
|
|
388
|
+
importedMap?: Map<string, object>;
|
|
389
|
+
imported?: object;
|
|
390
|
+
config?: {namespace?: string | string[]};
|
|
391
|
+
}>;
|
|
392
|
+
connected?(this: Adapter<T, C>): Promise<boolean>;
|
|
393
|
+
error?(error: unknown, $meta: unknown): void;
|
|
394
|
+
pack?(this: Adapter<T, C>, ...params: unknown[]): unknown;
|
|
395
|
+
unpackSize?(this: Adapter<T, C>, ...params: unknown[]): unknown;
|
|
396
|
+
unpack?(this: Adapter<T, C>, ...params: unknown[]): unknown;
|
|
397
|
+
encode?(
|
|
398
|
+
data: unknown,
|
|
399
|
+
$meta: unknown,
|
|
400
|
+
context: unknown,
|
|
401
|
+
log: unknown,
|
|
402
|
+
): Promise<string | Buffer>;
|
|
403
|
+
decode?(
|
|
404
|
+
buff: string | Buffer,
|
|
405
|
+
$meta: unknown,
|
|
406
|
+
context: unknown,
|
|
407
|
+
log: unknown,
|
|
408
|
+
): Promise<object[]>;
|
|
409
|
+
request?(...params: unknown[]): Promise<unknown>;
|
|
410
|
+
publish?(): Promise<unknown>;
|
|
411
|
+
drain?(): void;
|
|
412
|
+
findValidation?(this: Adapter<T, C>, $meta: unknown): (...params: unknown[]) => object;
|
|
413
|
+
getConversion?(
|
|
414
|
+
this: Adapter<T, C>,
|
|
415
|
+
$meta: unknown,
|
|
416
|
+
type: string,
|
|
417
|
+
): {name: string; fn: (...params: unknown[]) => Promise<object>};
|
|
418
|
+
findHandler?(this: Adapter<T, C>, name: string): () => unknown;
|
|
419
|
+
handles?(this: Adapter<T, C>, name: string): boolean;
|
|
420
|
+
forNamespaces?<U>(reducer: (prev: U, current: unknown) => U, initial: U): U;
|
|
421
|
+
methodPath?(name: string): string;
|
|
422
|
+
dispatch?(...params: unknown[]): Promise<unknown>;
|
|
423
|
+
exec?(this: Adapter<T, C>, ...params: unknown[]): Promise<unknown>;
|
|
424
|
+
bytesSent?(count: number): void;
|
|
425
|
+
bytesReceived?(count: number): void;
|
|
426
|
+
msgSent?(count: number): void;
|
|
427
|
+
msgReceived?(count: number): void;
|
|
318
428
|
isConnected?: Promise<boolean>;
|
|
319
|
-
event
|
|
320
|
-
handle
|
|
321
|
-
connect
|
|
322
|
-
what: unknown,
|
|
323
|
-
context: {requests: unknown; waiting: unknown; buffer: unknown},
|
|
324
|
-
) => void;
|
|
429
|
+
event?(name: string, params?: unknown): Promise<object>;
|
|
430
|
+
handle?(...params: unknown[]): Promise<unknown>;
|
|
431
|
+
connect?(what: unknown, context: unknown): void;
|
|
325
432
|
/**
|
|
326
433
|
* Optional lifecycle hook called when configuration changes.
|
|
327
434
|
* When present, the framework calls this instead of a full stop+start cycle.
|
|
@@ -333,11 +440,14 @@ export interface IAdapter<T, C> {
|
|
|
333
440
|
* @param next The full new effective config snapshot (via proxy)
|
|
334
441
|
* @param prev The full previous effective config snapshot
|
|
335
442
|
*/
|
|
336
|
-
configChanged
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
443
|
+
configChanged?(
|
|
444
|
+
this: Adapter<T, C>,
|
|
445
|
+
diff: unknown,
|
|
446
|
+
next: unknown,
|
|
447
|
+
prev?: unknown,
|
|
448
|
+
): Promise<void>;
|
|
449
|
+
/** Allow arbitrary extra methods on adapter definitions (e.g. authenticate) */
|
|
450
|
+
[key: string]: unknown;
|
|
341
451
|
}
|
|
342
452
|
|
|
343
453
|
export interface IAdapterFactory<T = Record<string, unknown>, C = Record<string, unknown>> {
|
|
@@ -345,6 +455,17 @@ export interface IAdapterFactory<T = Record<string, unknown>, C = Record<string,
|
|
|
345
455
|
(api: IApi): IAdapter<T, C>;
|
|
346
456
|
}
|
|
347
457
|
|
|
458
|
+
export interface IAdapterRegistry {
|
|
459
|
+
config: unknown;
|
|
460
|
+
(api: {
|
|
461
|
+
utError: IError;
|
|
462
|
+
remote: IRemote;
|
|
463
|
+
rpc: IRpcServer;
|
|
464
|
+
local: ILocal;
|
|
465
|
+
registry: IRegistry;
|
|
466
|
+
}): Promise<Adapter>;
|
|
467
|
+
}
|
|
468
|
+
|
|
348
469
|
export interface IMeta {
|
|
349
470
|
mtid?: 'request' | 'response' | 'error' | 'notification' | 'discard' | 'event';
|
|
350
471
|
request?: IMeta;
|
|
@@ -356,7 +477,7 @@ export interface IMeta {
|
|
|
356
477
|
expect?: string[] | string;
|
|
357
478
|
opcode?: string;
|
|
358
479
|
source?: string;
|
|
359
|
-
forward?:
|
|
480
|
+
forward?: Record<string, string>;
|
|
360
481
|
httpResponse?: {
|
|
361
482
|
type?: string;
|
|
362
483
|
redirect?: string;
|
|
@@ -402,16 +523,16 @@ export interface IMeta {
|
|
|
402
523
|
deviceId?: string | string[];
|
|
403
524
|
latitude?: string | string[];
|
|
404
525
|
longitude?: string | string[];
|
|
405
|
-
conId?: number;
|
|
526
|
+
conId?: string | number;
|
|
406
527
|
dispatch?: (
|
|
407
528
|
msg?: object,
|
|
408
529
|
$meta?: IMeta,
|
|
409
530
|
) => [msg: object, $meta: IMeta] | boolean | void | Promise<boolean>;
|
|
410
531
|
reply?: unknown;
|
|
411
|
-
timeout?:
|
|
532
|
+
timeout?: HRTime;
|
|
412
533
|
timer?: (
|
|
413
534
|
name?: string,
|
|
414
|
-
newTime?: HRTime |
|
|
535
|
+
newTime?: HRTime | undefined,
|
|
415
536
|
) => {
|
|
416
537
|
[name: string]: number;
|
|
417
538
|
};
|
|
@@ -422,19 +543,18 @@ export interface IMeta {
|
|
|
422
543
|
checkpoints?: Array<{name: string; data?: unknown; timestamp: number}>;
|
|
423
544
|
}
|
|
424
545
|
|
|
425
|
-
export type HRTime = [number, number];
|
|
426
|
-
|
|
427
546
|
export interface IContext {
|
|
428
|
-
trace: number;
|
|
547
|
+
// trace: number;
|
|
429
548
|
session?: {
|
|
430
549
|
[name: string]: unknown;
|
|
431
550
|
};
|
|
432
|
-
conId?: string;
|
|
551
|
+
conId?: string | number;
|
|
433
552
|
requests: Map<
|
|
434
553
|
string,
|
|
435
|
-
{$meta: IMeta; end
|
|
554
|
+
{$meta: IMeta; end?: (error: Error) => {local: object; literals: object[]}}
|
|
436
555
|
>;
|
|
437
556
|
waiting: Set<(error: Error) => void>;
|
|
557
|
+
buffer?: Buffer;
|
|
438
558
|
}
|
|
439
559
|
|
|
440
560
|
export interface ITypedError extends Error {
|
|
@@ -492,7 +612,11 @@ export interface IModuleConfig<T extends TSchema = TNever> {
|
|
|
492
612
|
url: string;
|
|
493
613
|
config?: IActivationConfig<Partial<Static<T>> & Partial<Static<IBaseConfig>>>;
|
|
494
614
|
validation?: T;
|
|
495
|
-
children?:
|
|
615
|
+
children?:
|
|
616
|
+
| (string | (() => Promise<object>))[]
|
|
617
|
+
| ((layer: ModuleApi) => unknown)[]
|
|
618
|
+
| Record<string, () => Promise<unknown>>;
|
|
619
|
+
glob?: Record<string, () => Promise<object>>;
|
|
496
620
|
}
|
|
497
621
|
|
|
498
622
|
export interface ILogger {
|
|
@@ -567,9 +691,16 @@ export interface ILib {
|
|
|
567
691
|
/** @deprecated The framework now auto-names step arrays from handler names. */
|
|
568
692
|
group: (name: string) => (handlers: ChainStep[]) => ChainStep[] & {name: string};
|
|
569
693
|
assert: typeof Assert | undefined;
|
|
694
|
+
yaml: {
|
|
695
|
+
parse: <T>(source: string, options?: unknown) => T;
|
|
696
|
+
parseAllDocuments: <T>(source: string, options?: unknown) => T;
|
|
697
|
+
parseDocument: <T>(source: string, options?: unknown) => T;
|
|
698
|
+
stringify: (value: unknown, options?: unknown) => string;
|
|
699
|
+
};
|
|
570
700
|
ulid: () => string;
|
|
571
701
|
uuid4: () => string;
|
|
572
702
|
uuid7: () => string;
|
|
703
|
+
timing: IPlatformApi['timing'];
|
|
573
704
|
setProperty: (obj: Record<string, unknown>, path: string, value: unknown) => void;
|
|
574
705
|
merge<T, S1>(target: T, source: S1): T & S1;
|
|
575
706
|
merge<T, S1, S2>(target: T, source1: S1, source2: S2): T & S1 & S2;
|
|
@@ -608,17 +739,24 @@ export type ApiDefinition = (blong: IValidationProxy) =>
|
|
|
608
739
|
};
|
|
609
740
|
|
|
610
741
|
export type PortHandler<T, C> = <R>(
|
|
611
|
-
this:
|
|
612
|
-
params:
|
|
742
|
+
this: Adapter<T, C>,
|
|
743
|
+
params: object,
|
|
613
744
|
$meta: IMeta,
|
|
614
745
|
context?: IContext,
|
|
615
746
|
) => Promise<R> | R;
|
|
616
|
-
export type PortHandlerBound = <T>(
|
|
747
|
+
export type PortHandlerBound = (<T>(
|
|
748
|
+
params: object,
|
|
749
|
+
$meta: IMeta,
|
|
750
|
+
context?: IContext,
|
|
751
|
+
) => Promise<T> | T) & {
|
|
752
|
+
[name: string]: PortHandlerBound;
|
|
753
|
+
};
|
|
617
754
|
export type LibFn = <T>(...params: unknown[]) => T;
|
|
618
755
|
export interface IRemoteHandler {
|
|
619
756
|
[name: string]: PortHandlerBound;
|
|
620
757
|
}
|
|
621
|
-
|
|
758
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
759
|
+
export interface ISchema {} // this is being extended via ambient declarations in ~.schema.ts
|
|
622
760
|
export interface IHandlerProxy<T> {
|
|
623
761
|
config: T;
|
|
624
762
|
handler: {
|
|
@@ -639,6 +777,7 @@ export interface IHandlerProxy<T> {
|
|
|
639
777
|
gateway: {
|
|
640
778
|
config: () => {public: {sign: object; encrypt: object}};
|
|
641
779
|
};
|
|
780
|
+
apiSchema: IApiSchema;
|
|
642
781
|
}
|
|
643
782
|
|
|
644
783
|
export type ImportProxyCallback<T, C> = (
|
|
@@ -674,9 +813,9 @@ const Kind: symbol = Symbol.for('blong:kind');
|
|
|
674
813
|
export type Kind = typeof Kind;
|
|
675
814
|
|
|
676
815
|
export abstract class Internal {
|
|
677
|
-
#log?: ILog;
|
|
816
|
+
#log?: ILog | undefined;
|
|
678
817
|
protected log?: ReturnType<ILog['logger']>;
|
|
679
|
-
public constructor(api?: {log
|
|
818
|
+
public constructor(api?: {log?: ILog}) {
|
|
680
819
|
this.#log = api?.log;
|
|
681
820
|
}
|
|
682
821
|
protected merge: ILib['merge'] = (...args: Parameters<ILib['merge']>) => {
|
|
@@ -688,7 +827,8 @@ export abstract class Internal {
|
|
|
688
827
|
public async stop(): Promise<unknown> {
|
|
689
828
|
return this;
|
|
690
829
|
}
|
|
691
|
-
|
|
830
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
831
|
+
public async start(..._args: unknown[]): Promise<unknown> {
|
|
692
832
|
return this;
|
|
693
833
|
}
|
|
694
834
|
}
|
|
@@ -705,23 +845,13 @@ export const handler = <T = Record<string, unknown>, C = AdapterContext>(
|
|
|
705
845
|
* The inner function should return a map whose keys are dot-notation method names
|
|
706
846
|
* (e.g. `'coral.browse'`) and values are async functions that return component
|
|
707
847
|
* metadata `{title, permission, icon, component: async () => ReactComponent}`.
|
|
708
|
-
*
|
|
709
|
-
* @example
|
|
710
|
-
* ```ts
|
|
711
|
-
* export default componentHandler(blong => function coralBrowse() {
|
|
712
|
-
* return {
|
|
713
|
-
* 'coral.browse': async () => ({
|
|
714
|
-
* title: 'Browse Corals',
|
|
715
|
-
* permission: 'marine.coral.browse',
|
|
716
|
-
* component: async () => (await import('./CoralBrowse.js')).default,
|
|
717
|
-
* }),
|
|
718
|
-
* };
|
|
719
|
-
* });
|
|
720
|
-
* ```
|
|
721
848
|
*/
|
|
722
|
-
export
|
|
723
|
-
|
|
724
|
-
|
|
849
|
+
export interface IComponent {
|
|
850
|
+
title?: string;
|
|
851
|
+
permission?: string;
|
|
852
|
+
icon?: string;
|
|
853
|
+
component: (params?: Record<string, unknown>) => Promise<unknown>;
|
|
854
|
+
}
|
|
725
855
|
|
|
726
856
|
/** Action definition for use with `defineActions`. */
|
|
727
857
|
export interface IActionDef {
|
|
@@ -737,7 +867,9 @@ export interface IActionDef {
|
|
|
737
867
|
/** Action names whose query caches should be invalidated on success. */
|
|
738
868
|
invalidates?: string[];
|
|
739
869
|
/** Static params merged into every invocation. */
|
|
740
|
-
params?:
|
|
870
|
+
params?:
|
|
871
|
+
| Record<string, unknown>
|
|
872
|
+
| ((params: Record<string, unknown>) => Record<string, unknown>);
|
|
741
873
|
}
|
|
742
874
|
|
|
743
875
|
/**
|
|
@@ -763,10 +895,7 @@ export const defineActions = (
|
|
|
763
895
|
actions: Record<string, IActionDef>,
|
|
764
896
|
): ((_blong: unknown) => Record<string, () => IActionDef>) =>
|
|
765
897
|
Object.defineProperty(
|
|
766
|
-
(
|
|
767
|
-
Object.fromEntries(
|
|
768
|
-
Object.entries(actions).map(([key, value]) => [key, () => value]),
|
|
769
|
-
),
|
|
898
|
+
() => Object.fromEntries(Object.entries(actions).map(([key, value]) => [key, () => value])),
|
|
770
899
|
Kind,
|
|
771
900
|
{value: 'handler'},
|
|
772
901
|
);
|
|
@@ -777,6 +906,11 @@ export const validation = (validation: ValidationDefinition): ValidationDefiniti
|
|
|
777
906
|
Object.defineProperty(validation, Kind, {value: 'validation'});
|
|
778
907
|
export const api = (api: ApiDefinition): ApiDefinition =>
|
|
779
908
|
Object.defineProperty(api, Kind, {value: 'api'});
|
|
909
|
+
export const model = <T extends IModelSpec>(
|
|
910
|
+
definition: () => () => Promise<T>,
|
|
911
|
+
): (() => () => Promise<T>) => Object.defineProperty(definition, Kind, {value: 'model'});
|
|
912
|
+
export const fixture = <T extends IMock>(definition: () => T): (() => T) =>
|
|
913
|
+
Object.defineProperty(definition, Kind, {value: 'fixture'});
|
|
780
914
|
|
|
781
915
|
export const validationHandlers: (
|
|
782
916
|
handlers: Record<string, TFunction<[ApiSchema]>>,
|
|
@@ -798,21 +932,41 @@ export const validationHandlers: (
|
|
|
798
932
|
),
|
|
799
933
|
);
|
|
800
934
|
|
|
801
|
-
export const realm = <T extends TObject>(
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
Object.defineProperty(definition
|
|
805
|
-
|
|
806
|
-
|
|
935
|
+
export const realm = <T extends TObject>(
|
|
936
|
+
definition: SolutionFactory<T>,
|
|
937
|
+
): SolutionFactory<T> & {[Kind]: 'solution'} =>
|
|
938
|
+
Object.defineProperty(definition as SolutionFactory<T> & {[Kind]: 'solution'}, Kind, {
|
|
939
|
+
value: 'solution',
|
|
940
|
+
});
|
|
941
|
+
export const server = <T extends TObject>(
|
|
942
|
+
definition: SolutionFactory<T>,
|
|
943
|
+
): SolutionFactory<T> & {[Kind]: 'server'} =>
|
|
944
|
+
Object.defineProperty(definition as SolutionFactory<T> & {[Kind]: 'server'}, Kind, {
|
|
945
|
+
value: 'server',
|
|
946
|
+
});
|
|
947
|
+
export const browser = <T extends TObject>(
|
|
948
|
+
definition: SolutionFactory<T>,
|
|
949
|
+
): SolutionFactory<T> & {[Kind]: 'browser'} =>
|
|
950
|
+
Object.defineProperty(definition as SolutionFactory<T> & {[Kind]: 'browser'}, Kind, {
|
|
951
|
+
value: 'browser',
|
|
952
|
+
});
|
|
807
953
|
export const layer = (
|
|
808
954
|
activation: Record<string, boolean | object>,
|
|
809
|
-
): Record<string, boolean | object>
|
|
955
|
+
): Record<string, boolean | object> & {[Kind]: 'layer'} =>
|
|
956
|
+
Object.defineProperty(activation, Kind, {value: 'layer'});
|
|
810
957
|
export const adapter = <T, C = AdapterContext>(
|
|
811
958
|
definition: IAdapterFactory<T, C>,
|
|
812
|
-
): IAdapterFactory<T, C>
|
|
959
|
+
): IAdapterFactory<T, C> & {[Kind]: 'adapter'} =>
|
|
960
|
+
Object.defineProperty(definition as IAdapterFactory<T, C> & {[Kind]: 'adapter'}, Kind, {
|
|
961
|
+
value: 'adapter',
|
|
962
|
+
});
|
|
813
963
|
export const orchestrator = <T, C = AdapterContext>(
|
|
814
964
|
definition: IAdapterFactory<T, C>,
|
|
815
|
-
): IAdapterFactory<T, C>
|
|
965
|
+
): IAdapterFactory<T, C> & {[Kind]: 'orchestrator'} =>
|
|
966
|
+
Object.defineProperty(definition as IAdapterFactory<T, C> & {[Kind]: 'orchestrator'}, Kind, {
|
|
967
|
+
value: 'orchestrator',
|
|
968
|
+
});
|
|
969
|
+
|
|
816
970
|
export type Kinds =
|
|
817
971
|
| 'lib'
|
|
818
972
|
| 'validation'
|
|
@@ -822,12 +976,14 @@ export type Kinds =
|
|
|
822
976
|
| 'browser'
|
|
823
977
|
| 'adapter'
|
|
824
978
|
| 'orchestrator'
|
|
825
|
-
| 'handler'
|
|
826
|
-
|
|
979
|
+
| 'handler'
|
|
980
|
+
| 'model'
|
|
981
|
+
| 'fixture'
|
|
982
|
+
| '';
|
|
983
|
+
export const kind = (what: {[Kind]: Kinds | undefined}): Kinds => what[Kind] || '';
|
|
827
984
|
|
|
828
985
|
export default {
|
|
829
986
|
handler,
|
|
830
|
-
componentHandler,
|
|
831
987
|
defineActions,
|
|
832
988
|
library,
|
|
833
989
|
validation,
|
|
@@ -837,5 +993,6 @@ export default {
|
|
|
837
993
|
browser,
|
|
838
994
|
adapter,
|
|
839
995
|
orchestrator,
|
|
996
|
+
fixture,
|
|
840
997
|
kind,
|
|
841
998
|
};
|