@feasibleone/blong 1.16.0 → 1.17.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 +29 -0
- package/dist/model.js +10 -0
- package/dist/model.js.map +1 -0
- package/dist/types.d.ts +320 -43
- package/dist/types.js +4 -25
- package/dist/types.js.map +1 -1
- package/package.json +8 -6
- package/types.ts +139 -45
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.17.0](https://github.com/feasibleone/blong/compare/blong-v1.16.1...blong-v1.17.0) (2026-04-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add support for the browser platform ([f483e14](https://github.com/feasibleone/blong/commit/f483e149711acdeebcf9ee5afa3bf7ac7a6b669c))
|
|
9
|
+
* implement wiring pipeline simplifications ([0a3dc01](https://github.com/feasibleone/blong/commit/0a3dc01e97c158d30491e8b76bef7d6bb4987529))
|
|
10
|
+
* model handling ([168e77e](https://github.com/feasibleone/blong/commit/168e77ec3284bbcebf5d7d6bb07cc624d0d1a56e))
|
|
11
|
+
* model init ([7e18e00](https://github.com/feasibleone/blong/commit/7e18e002e3d9d9d2e996762d3ce7dd70d6a7d0be))
|
|
12
|
+
* model mocks ([118a142](https://github.com/feasibleone/blong/commit/118a14254f87b8d1cf0b4d217939a9d49942f93e))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* dependencies ([dd785c4](https://github.com/feasibleone/blong/commit/dd785c49c20045a804df0527638191f5d7d32a49))
|
|
18
|
+
* dependencies ([a21d8eb](https://github.com/feasibleone/blong/commit/a21d8ebe4ce9b476060dec8eeb9017a5eb7f07b5))
|
|
19
|
+
* dependencies ([705b2f7](https://github.com/feasibleone/blong/commit/705b2f7a72ac2dc93aea0f586394dde71192c1b6))
|
|
20
|
+
* eslint ([a3b9f2b](https://github.com/feasibleone/blong/commit/a3b9f2bed4f958abfb378d97d372b3e7a6cd5a21))
|
|
21
|
+
* optimize browser loading ([0aac985](https://github.com/feasibleone/blong/commit/0aac985a24520810dc05eb34d314ed7dec4f1962))
|
|
22
|
+
* remove heft lint ([c4d0eaa](https://github.com/feasibleone/blong/commit/c4d0eaa81714c04e9f9adec01c6ae7fa068f1948))
|
|
23
|
+
* types ([b7f0b57](https://github.com/feasibleone/blong/commit/b7f0b57159019dbeb80b9021b04e04eee57468ba))
|
|
24
|
+
|
|
25
|
+
## [1.16.1](https://github.com/feasibleone/blong/compare/blong-v1.16.0...blong-v1.16.1) (2026-04-10)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* build ([32951e4](https://github.com/feasibleone/blong/commit/32951e46561648651ee4e032545655007c05e274))
|
|
31
|
+
|
|
3
32
|
## [1.16.0](https://github.com/feasibleone/blong/compare/blong-v1.15.0...blong-v1.16.0) (2026-04-10)
|
|
4
33
|
|
|
5
34
|
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model system types.
|
|
3
|
+
*
|
|
4
|
+
* A ModelSpec describes one "subject.object" domain entity and drives:
|
|
5
|
+
* - automatic Browse / New / Open / Report page generation
|
|
6
|
+
* - schema enrichment (server OpenAPI merged with browser overlay)
|
|
7
|
+
* - dropdown dependency tracking and caching
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../model.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
+
import { ChokidarOptions, FSWatcherEventMap } from 'chokidar';
|
|
3
4
|
import { SrvRecord } from 'dns';
|
|
4
5
|
import { EventEmitter } from 'events';
|
|
5
6
|
import { Socket, TcpNetConnectOpts } from 'net';
|
|
6
7
|
import Assert from 'node:assert';
|
|
7
|
-
import { Dirent } from 'node:fs';
|
|
8
|
+
import { Dirent, StatSyncFn } from 'node:fs';
|
|
8
9
|
import { Agent } from 'node:http';
|
|
9
10
|
import { Duplex } from 'node:stream';
|
|
10
11
|
import { Level, LogFn, Logger as PinoLogger } from 'pino';
|
|
@@ -17573,6 +17574,207 @@ declare namespace DeferredKeySelection {
|
|
|
17573
17574
|
}
|
|
17574
17575
|
export type AggregationQueryResult<TResult, TIntersectProps2 extends {}> = ArrayIfAlready<TResult, UnwrapArrayMember<TResult> extends DeferredKeySelection<infer TBase, infer TKeys, infer THasSelect, infer TAliasMapping, infer TSingle, infer TIntersectProps, infer TUnionProps> ? true extends THasSelect ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps & TIntersectProps2, TUnionProps> : DeferredKeySelection<{}, never, true, {}, false, TIntersectProps2> : TIntersectProps2>;
|
|
17575
17576
|
export type ResolveResult<S> = DeferredKeySelection.Resolve<S>;
|
|
17577
|
+
/**
|
|
17578
|
+
* Model system types.
|
|
17579
|
+
*
|
|
17580
|
+
* A ModelSpec describes one "subject.object" domain entity and drives:
|
|
17581
|
+
* - automatic Browse / New / Open / Report page generation
|
|
17582
|
+
* - schema enrichment (server OpenAPI merged with browser overlay)
|
|
17583
|
+
* - dropdown dependency tracking and caching
|
|
17584
|
+
*/
|
|
17585
|
+
/** {value, label} pair used in all dropdown and select widgets */
|
|
17586
|
+
export interface IDropdownOption {
|
|
17587
|
+
value: unknown;
|
|
17588
|
+
label: string;
|
|
17589
|
+
[key: string]: unknown;
|
|
17590
|
+
}
|
|
17591
|
+
/** Widget metadata overlay */
|
|
17592
|
+
export interface IWidgetOverride {
|
|
17593
|
+
type?: string;
|
|
17594
|
+
/** Named dropdown: 'rule.country', 'marine.species', etc. */
|
|
17595
|
+
dropdown?: string;
|
|
17596
|
+
options?: Array<{
|
|
17597
|
+
value: unknown;
|
|
17598
|
+
label: string;
|
|
17599
|
+
}>;
|
|
17600
|
+
keyValue?: boolean;
|
|
17601
|
+
fieldClass?: string;
|
|
17602
|
+
itemClassName?: string;
|
|
17603
|
+
label?: string;
|
|
17604
|
+
master?: Record<string, string>;
|
|
17605
|
+
parent?: string;
|
|
17606
|
+
autoSelect?: boolean;
|
|
17607
|
+
selectionMode?: "single" | "multiple";
|
|
17608
|
+
hidden?: string[];
|
|
17609
|
+
widgets?: string[];
|
|
17610
|
+
params?: Record<string, unknown>;
|
|
17611
|
+
[key: string]: unknown;
|
|
17612
|
+
}
|
|
17613
|
+
/** JSON Schema property overlay — the browser model adds/overrides field metadata */
|
|
17614
|
+
export interface IPropertyOverride {
|
|
17615
|
+
title?: string;
|
|
17616
|
+
type?: string;
|
|
17617
|
+
filter?: boolean;
|
|
17618
|
+
sort?: boolean;
|
|
17619
|
+
required?: boolean;
|
|
17620
|
+
default?: unknown;
|
|
17621
|
+
widget?: IWidgetOverride;
|
|
17622
|
+
validation?: unknown;
|
|
17623
|
+
properties?: Record<string, IPropertyOverride>;
|
|
17624
|
+
items?: {
|
|
17625
|
+
properties?: Record<string, IPropertyOverride>;
|
|
17626
|
+
};
|
|
17627
|
+
[key: string]: unknown;
|
|
17628
|
+
}
|
|
17629
|
+
/** Schema overlay — top-level properties map per subject.object */
|
|
17630
|
+
export interface ISchemaOverlay {
|
|
17631
|
+
properties?: Record<string, IPropertyOverride>;
|
|
17632
|
+
[key: string]: unknown;
|
|
17633
|
+
}
|
|
17634
|
+
/** Named card layout — a group of fields rendered as one collapsible card */
|
|
17635
|
+
export interface ICardOverride {
|
|
17636
|
+
className?: string;
|
|
17637
|
+
label?: string;
|
|
17638
|
+
title?: string;
|
|
17639
|
+
hidden?: boolean;
|
|
17640
|
+
widgets: Array<string | IInlineWidget>;
|
|
17641
|
+
}
|
|
17642
|
+
/** Inline widget descriptor (used inside card.widgets arrays) */
|
|
17643
|
+
export interface IInlineWidget {
|
|
17644
|
+
name: string;
|
|
17645
|
+
type: string;
|
|
17646
|
+
page?: string;
|
|
17647
|
+
params?: Record<string, unknown>;
|
|
17648
|
+
}
|
|
17649
|
+
/** Tab in the editor layout */
|
|
17650
|
+
export interface ILayoutTab {
|
|
17651
|
+
id: string;
|
|
17652
|
+
label?: string;
|
|
17653
|
+
icon?: string;
|
|
17654
|
+
widgets: Array<string | string[]>;
|
|
17655
|
+
}
|
|
17656
|
+
/** Permission names for each CRUD action */
|
|
17657
|
+
export interface IBrowserPermissions {
|
|
17658
|
+
browse: string;
|
|
17659
|
+
add: string;
|
|
17660
|
+
edit: string;
|
|
17661
|
+
delete: string;
|
|
17662
|
+
}
|
|
17663
|
+
/** Browse page configuration */
|
|
17664
|
+
export interface IBrowserConfig {
|
|
17665
|
+
title?: string;
|
|
17666
|
+
icon?: string;
|
|
17667
|
+
permission?: IBrowserPermissions;
|
|
17668
|
+
/** Column transformation applied to server fetch params */
|
|
17669
|
+
fetch?: (params: Record<string, unknown>) => Record<string, unknown>;
|
|
17670
|
+
/** Default filter applied on page open */
|
|
17671
|
+
filter?: Record<string, unknown>;
|
|
17672
|
+
/** Result set key to use from server response */
|
|
17673
|
+
resultSet?: string;
|
|
17674
|
+
/** Whether to show "Create" button */
|
|
17675
|
+
create?: Array<{
|
|
17676
|
+
title?: string;
|
|
17677
|
+
type?: string;
|
|
17678
|
+
permission?: string;
|
|
17679
|
+
}>;
|
|
17680
|
+
/** Extra toolbar buttons */
|
|
17681
|
+
toolbar?: unknown[];
|
|
17682
|
+
}
|
|
17683
|
+
/** Editor page configuration */
|
|
17684
|
+
export interface IEditorConfig {
|
|
17685
|
+
resultSet?: string;
|
|
17686
|
+
}
|
|
17687
|
+
/** Report page configuration */
|
|
17688
|
+
export interface IReportConfig {
|
|
17689
|
+
title?: string;
|
|
17690
|
+
permission?: string;
|
|
17691
|
+
}
|
|
17692
|
+
/** Method name overrides — defaults to semantic triple naming */
|
|
17693
|
+
export interface IMethodsConfig {
|
|
17694
|
+
find?: string;
|
|
17695
|
+
get?: string;
|
|
17696
|
+
add?: string;
|
|
17697
|
+
edit?: string;
|
|
17698
|
+
remove?: string;
|
|
17699
|
+
report?: string;
|
|
17700
|
+
}
|
|
17701
|
+
/**
|
|
17702
|
+
* ModelSpec — the browser-side description of one "subject.object" domain entity.
|
|
17703
|
+
*
|
|
17704
|
+
* Used by modelFactory() to auto-generate Browse/New/Open/Report pages.
|
|
17705
|
+
*/
|
|
17706
|
+
export interface IModelSpec {
|
|
17707
|
+
/** Namespace / subject, e.g. 'marine', 'rule' */
|
|
17708
|
+
subject: string;
|
|
17709
|
+
/** Entity name, e.g. 'coral', 'condition' */
|
|
17710
|
+
object: string;
|
|
17711
|
+
/** Human-readable title, e.g. 'Coral'. Defaults to capitalized object. */
|
|
17712
|
+
objectTitle?: string;
|
|
17713
|
+
/** Primary key field path, e.g. 'coralId'. Defaults to `${object}Id`. */
|
|
17714
|
+
keyField?: string;
|
|
17715
|
+
/** Name field path (dotted), e.g. 'coral.coralName'. Defaults to `${object}.${object}Name`. */
|
|
17716
|
+
nameField?: string;
|
|
17717
|
+
/** JSON Schema overlay merged on top of server OpenAPI schema */
|
|
17718
|
+
schema?: ISchemaOverlay;
|
|
17719
|
+
/** Named card layout definitions */
|
|
17720
|
+
cards?: Record<string, ICardOverride>;
|
|
17721
|
+
/** Browse page configuration */
|
|
17722
|
+
browser?: IBrowserConfig;
|
|
17723
|
+
/** Editor page configuration */
|
|
17724
|
+
editor?: IEditorConfig;
|
|
17725
|
+
/** Report page configuration */
|
|
17726
|
+
report?: IReportConfig;
|
|
17727
|
+
/** Tab layouts for editor */
|
|
17728
|
+
layouts?: {
|
|
17729
|
+
edit?: ILayoutTab[] | string[];
|
|
17730
|
+
[key: string]: unknown;
|
|
17731
|
+
};
|
|
17732
|
+
/** Method name overrides */
|
|
17733
|
+
methods?: IMethodsConfig;
|
|
17734
|
+
}
|
|
17735
|
+
/** Model spec as accepted by modelFactory — objectTitle/keyField/nameField are optional */
|
|
17736
|
+
export type IPartialModelSpec = IModelSpec;
|
|
17737
|
+
/** Fully resolved model spec — all defaults filled in */
|
|
17738
|
+
export interface IResolvedModelSpec extends Required<IModelSpec> {
|
|
17739
|
+
objectTitle: string;
|
|
17740
|
+
keyField: string;
|
|
17741
|
+
nameField: string;
|
|
17742
|
+
browser: Required<IBrowserConfig> & {
|
|
17743
|
+
permission: IBrowserPermissions;
|
|
17744
|
+
};
|
|
17745
|
+
editor: Required<IEditorConfig>;
|
|
17746
|
+
report: Required<IReportConfig>;
|
|
17747
|
+
methods: Required<IMethodsConfig>;
|
|
17748
|
+
}
|
|
17749
|
+
/** Mock OpenAPI document (minimal shape used by schemaFetcher) */
|
|
17750
|
+
export interface IMockOpenApiDoc {
|
|
17751
|
+
paths?: Record<string, Record<string, {
|
|
17752
|
+
operationId?: string;
|
|
17753
|
+
requestBody?: {
|
|
17754
|
+
content?: {
|
|
17755
|
+
"application/json"?: {
|
|
17756
|
+
schema?: Record<string, unknown>;
|
|
17757
|
+
};
|
|
17758
|
+
};
|
|
17759
|
+
};
|
|
17760
|
+
responses?: {
|
|
17761
|
+
"200"?: {
|
|
17762
|
+
content?: {
|
|
17763
|
+
"application/json"?: {
|
|
17764
|
+
schema?: Record<string, unknown>;
|
|
17765
|
+
};
|
|
17766
|
+
};
|
|
17767
|
+
};
|
|
17768
|
+
};
|
|
17769
|
+
}>>;
|
|
17770
|
+
"x-ui-customizations"?: Record<string, Record<string, unknown>>;
|
|
17771
|
+
}
|
|
17772
|
+
export interface IMock {
|
|
17773
|
+
/** Mock OpenAPI documents keyed by subject name */
|
|
17774
|
+
subjects?: Record<string, object[]>;
|
|
17775
|
+
/** Pre-populated dropdown data keyed by dropdown name */
|
|
17776
|
+
dropdowns?: Record<string, IDropdownOption[]>;
|
|
17777
|
+
}
|
|
17576
17778
|
export type ServerContext = {
|
|
17577
17779
|
queryBuilder?: Knex;
|
|
17578
17780
|
kcAdminClient?: KeycloakAdminClient;
|
|
@@ -17591,6 +17793,82 @@ export interface ILog {
|
|
|
17591
17793
|
logger: (level: Level, bindings: object) => ILogger;
|
|
17592
17794
|
child: PinoLogger["child"];
|
|
17593
17795
|
}
|
|
17796
|
+
/** A flat map of dotted-path → [prev, next] pairs that represent changed keys */
|
|
17797
|
+
export type ConfigDiff = Map<string, {
|
|
17798
|
+
prev: unknown;
|
|
17799
|
+
next: unknown;
|
|
17800
|
+
}>;
|
|
17801
|
+
/** Subscriber callback invoked after a successful reload */
|
|
17802
|
+
export type ConfigSubscriber = (diff: ConfigDiff, next: object, prev: object) => void | Promise<void>;
|
|
17803
|
+
/**
|
|
17804
|
+
* Mode used when the config proxy is queried during handler factory initialisation.
|
|
17805
|
+
*
|
|
17806
|
+
* - `'throw'` — throw immediately (default; keeps misuse from going unnoticed)
|
|
17807
|
+
* - `'collect'` — accumulate errors and return them from exitConfigFactoryPhase()
|
|
17808
|
+
* (useful in tests that explicitly verify the anti-pattern is caught)
|
|
17809
|
+
*/
|
|
17810
|
+
export type FactoryPhaseMode = "throw" | "collect";
|
|
17811
|
+
export interface IConfigRuntime {
|
|
17812
|
+
/** Current effective config, exposed as a live proxy */
|
|
17813
|
+
readonly snapshot: object;
|
|
17814
|
+
/** Raw (non-proxy) snapshot of the current effective config */
|
|
17815
|
+
readonly rawSnapshot: object;
|
|
17816
|
+
/** Load (or reload) config from all sources; returns the updated snapshot */
|
|
17817
|
+
load(params?: object): Promise<object>;
|
|
17818
|
+
/**
|
|
17819
|
+
* Reload config in-place. The backing store of the proxy is updated so all
|
|
17820
|
+
* existing proxy references automatically reflect the new values.
|
|
17821
|
+
* Returns the computed diff.
|
|
17822
|
+
*/
|
|
17823
|
+
reload(): Promise<ConfigDiff>;
|
|
17824
|
+
/** Compute the diff between two plain config objects without modifying state */
|
|
17825
|
+
diff(prev: object, next: object): ConfigDiff;
|
|
17826
|
+
/** Register a subscriber to be called after every successful reload */
|
|
17827
|
+
subscribe(fn: ConfigSubscriber): () => void;
|
|
17828
|
+
/** Enter the config factory phase */
|
|
17829
|
+
enterConfig(mode?: FactoryPhaseMode): void;
|
|
17830
|
+
/** Exit the config factory phase */
|
|
17831
|
+
exitConfig(): Error[];
|
|
17832
|
+
}
|
|
17833
|
+
export interface IWatcher extends EventEmitter<FSWatcherEventMap> {
|
|
17834
|
+
close(): Promise<void>;
|
|
17835
|
+
}
|
|
17836
|
+
export type HRTime = [
|
|
17837
|
+
number,
|
|
17838
|
+
number
|
|
17839
|
+
];
|
|
17840
|
+
export interface IPlatformApi {
|
|
17841
|
+
platform: "server" | "browser";
|
|
17842
|
+
loadConfig: (config: string | object) => Promise<{
|
|
17843
|
+
loadedConfig?: object;
|
|
17844
|
+
configRuntime?: IConfigRuntime;
|
|
17845
|
+
}>;
|
|
17846
|
+
readdir: (path: string) => Promise<Dirent[]>;
|
|
17847
|
+
scan: (...path: string[]) => Promise<Dirent[]>;
|
|
17848
|
+
existsSync: (path: string) => boolean;
|
|
17849
|
+
createRequire?: (path: string | URL) => NodeJS.Require;
|
|
17850
|
+
join: (...paths: string[]) => string;
|
|
17851
|
+
dirname: (path: string) => string;
|
|
17852
|
+
basename: (path: string, ext?: string) => string;
|
|
17853
|
+
relative: (from: string, to: string) => string;
|
|
17854
|
+
extname: (path: string) => string;
|
|
17855
|
+
resolve: (...paths: string[]) => string;
|
|
17856
|
+
readFileSync: (path: string, options?: {
|
|
17857
|
+
encoding: BufferEncoding;
|
|
17858
|
+
}) => string | Buffer;
|
|
17859
|
+
writeFileSync: (path: string, data: string | Buffer, options?: {
|
|
17860
|
+
encoding: BufferEncoding;
|
|
17861
|
+
}) => void;
|
|
17862
|
+
statSync: StatSyncFn;
|
|
17863
|
+
watch?: (path: string | string[], options?: ChokidarOptions) => IWatcher;
|
|
17864
|
+
timing: {
|
|
17865
|
+
diff: (time: HRTime, newTime: HRTime) => number;
|
|
17866
|
+
after: (milliseconds: number) => HRTime;
|
|
17867
|
+
now: (previous?: HRTime) => HRTime;
|
|
17868
|
+
isAfter: (time: HRTime, timeout: HRTime) => boolean;
|
|
17869
|
+
spare: (time: HRTime, latency?: number) => number;
|
|
17870
|
+
};
|
|
17871
|
+
}
|
|
17594
17872
|
export interface IErrorFactory {
|
|
17595
17873
|
get(type?: string): unknown;
|
|
17596
17874
|
fetch(type: string): object;
|
|
@@ -17674,6 +17952,9 @@ export interface IApiSchema {
|
|
|
17674
17952
|
}, source: string): Promise<Record<string, GatewaySchema>>;
|
|
17675
17953
|
generateFile(file: string): Promise<boolean>;
|
|
17676
17954
|
generateDir(dir: string, files: Dirent[]): Promise<boolean>;
|
|
17955
|
+
loadApi(locations: string | string[] | object | object[] | {
|
|
17956
|
+
assets: object;
|
|
17957
|
+
}, source: string): unknown;
|
|
17677
17958
|
}
|
|
17678
17959
|
export interface IGateway {
|
|
17679
17960
|
route: (validations: Record<string, GatewaySchema>, pkg: {
|
|
@@ -17691,6 +17972,7 @@ export type Handlers = ((params: {
|
|
|
17691
17972
|
local: object;
|
|
17692
17973
|
literals: object[];
|
|
17693
17974
|
gateway: IGateway;
|
|
17975
|
+
apiSchema: IApiSchema;
|
|
17694
17976
|
}) => void)[];
|
|
17695
17977
|
export interface IRegistry {
|
|
17696
17978
|
start: (configOverride?: object) => Promise<IRegistry>;
|
|
@@ -17724,25 +18006,20 @@ export interface IApi {
|
|
|
17724
18006
|
rpc: IRpcServer;
|
|
17725
18007
|
local: ILocal;
|
|
17726
18008
|
registry: IRegistry;
|
|
17727
|
-
|
|
17728
|
-
|
|
17729
|
-
|
|
17730
|
-
|
|
17731
|
-
|
|
17732
|
-
|
|
17733
|
-
|
|
17734
|
-
|
|
17735
|
-
|
|
17736
|
-
|
|
17737
|
-
|
|
17738
|
-
|
|
17739
|
-
|
|
17740
|
-
|
|
17741
|
-
attachHandlers: (target: object, patterns: unknown, adapter?: boolean) => unknown;
|
|
17742
|
-
};
|
|
17743
|
-
utLog: {
|
|
17744
|
-
createLog: ILog["logger"];
|
|
17745
|
-
};
|
|
18009
|
+
register: (methods: object, namespace: string, id: string, pkg: {
|
|
18010
|
+
version: string;
|
|
18011
|
+
}) => void;
|
|
18012
|
+
unregister: (methods: string[], namespace: string) => void;
|
|
18013
|
+
subscribe: (methods: object, namespace: string, id: string, pkg: {
|
|
18014
|
+
version: string;
|
|
18015
|
+
}) => void;
|
|
18016
|
+
unsubscribe: (methods: string[], namespace: string) => void;
|
|
18017
|
+
dispatch: (...params: unknown[]) => boolean | Promise<unknown>;
|
|
18018
|
+
methodId: (name: string) => string;
|
|
18019
|
+
getPath: (name: string) => string;
|
|
18020
|
+
importMethod: (methodName: string, options?: object) => (...params: unknown[]) => Promise<unknown>;
|
|
18021
|
+
attachHandlers: (target: object, patterns: unknown, adapter?: boolean) => unknown;
|
|
18022
|
+
createLog: ILog["logger"];
|
|
17746
18023
|
attachCheckpoint?: (meta: IMeta) => void;
|
|
17747
18024
|
handlers?: (api: {
|
|
17748
18025
|
utError: IError;
|
|
@@ -17773,6 +18050,7 @@ export interface IAdapter<T, C> {
|
|
|
17773
18050
|
log?: ILogger;
|
|
17774
18051
|
errors?: Errors<IErrorMap>;
|
|
17775
18052
|
imported?: ReturnType<IAdapterFactory<T, C>>;
|
|
18053
|
+
importedMap?: Map<string, IRemoteHandler>;
|
|
17776
18054
|
extends?: object | `adapter.${string}` | `orchestrator.${string}`;
|
|
17777
18055
|
activeConfig?: (this: ReturnType<IAdapterFactory<T, C>>) => Partial<Config<T, C>>;
|
|
17778
18056
|
init?: (this: ReturnType<IAdapterFactory<T, C>>, ...config: Partial<Config<T, C>>[]) => Promise<void>;
|
|
@@ -17794,7 +18072,7 @@ export interface IAdapter<T, C> {
|
|
|
17794
18072
|
}) => Buffer;
|
|
17795
18073
|
encode?: (data: unknown, $meta: IMeta, context: object, log: ILogger) => string | Buffer;
|
|
17796
18074
|
decode?: (buff: string | Buffer, $meta: IMeta, context: object, log: ILogger) => object[];
|
|
17797
|
-
request?: () => Promise<unknown>;
|
|
18075
|
+
request?: (...params: unknown[]) => Promise<unknown>;
|
|
17798
18076
|
publish?: () => Promise<unknown>;
|
|
17799
18077
|
drain?: () => void;
|
|
17800
18078
|
findValidation?: (this: ReturnType<IAdapterFactory<T, C>>, $meta: IMeta) => () => object;
|
|
@@ -17920,10 +18198,6 @@ export interface IMeta {
|
|
|
17920
18198
|
timestamp: number;
|
|
17921
18199
|
}>;
|
|
17922
18200
|
}
|
|
17923
|
-
export type HRTime = [
|
|
17924
|
-
number,
|
|
17925
|
-
number
|
|
17926
|
-
];
|
|
17927
18201
|
export interface IContext {
|
|
17928
18202
|
trace: number;
|
|
17929
18203
|
session?: {
|
|
@@ -17992,6 +18266,7 @@ export interface IModuleConfig<T extends TSchema = TNever> {
|
|
|
17992
18266
|
config?: IActivationConfig<Partial<Static<T>> & Partial<Static<IBaseConfig>>>;
|
|
17993
18267
|
validation?: T;
|
|
17994
18268
|
children?: (string | (() => Promise<object>))[] | ((layer: ModuleApi) => unknown)[];
|
|
18269
|
+
glob?: Record<string, () => Promise<object>>;
|
|
17995
18270
|
}
|
|
17996
18271
|
export interface ILogger {
|
|
17997
18272
|
trace?: LogFn;
|
|
@@ -18054,9 +18329,16 @@ export interface ILib {
|
|
|
18054
18329
|
name: string;
|
|
18055
18330
|
};
|
|
18056
18331
|
assert: typeof Assert | undefined;
|
|
18332
|
+
yaml: {
|
|
18333
|
+
parse: <T>(source: string, options?: unknown) => T;
|
|
18334
|
+
parseAllDocuments: <T>(source: string, options?: unknown) => T;
|
|
18335
|
+
parseDocument: <T>(source: string, options?: unknown) => T;
|
|
18336
|
+
stringify: (value: unknown, options?: unknown) => string;
|
|
18337
|
+
};
|
|
18057
18338
|
ulid: () => string;
|
|
18058
18339
|
uuid4: () => string;
|
|
18059
18340
|
uuid7: () => string;
|
|
18341
|
+
timing: IPlatformApi["timing"];
|
|
18060
18342
|
setProperty: (obj: Record<string, unknown>, path: string, value: unknown) => void;
|
|
18061
18343
|
merge<T, S1>(target: T, source: S1): T & S1;
|
|
18062
18344
|
merge<T, S1, S2>(target: T, source1: S1, source2: S2): T & S1 & S2;
|
|
@@ -18120,6 +18402,7 @@ export interface IHandlerProxy<T> {
|
|
|
18120
18402
|
};
|
|
18121
18403
|
};
|
|
18122
18404
|
};
|
|
18405
|
+
apiSchema: IApiSchema;
|
|
18123
18406
|
}
|
|
18124
18407
|
export type ImportProxyCallback<T, C> = (blong: IHandlerProxy<T>) => PortHandler<T, C> | IAdapterFactory<T, C> | Record<string, PortHandler<T, C>>;
|
|
18125
18408
|
export type Definition<T, C> = object | ImportProxyCallback<T, C> | ImportProxyCallback<T, C>[];
|
|
@@ -18162,21 +18445,13 @@ export declare const handler: <T = Record<string, unknown>, C = AdapterContext>(
|
|
|
18162
18445
|
* The inner function should return a map whose keys are dot-notation method names
|
|
18163
18446
|
* (e.g. `'coral.browse'`) and values are async functions that return component
|
|
18164
18447
|
* metadata `{title, permission, icon, component: async () => ReactComponent}`.
|
|
18165
|
-
*
|
|
18166
|
-
* @example
|
|
18167
|
-
* ```ts
|
|
18168
|
-
* export default componentHandler(blong => function coralBrowse() {
|
|
18169
|
-
* return {
|
|
18170
|
-
* 'coral.browse': async () => ({
|
|
18171
|
-
* title: 'Browse Corals',
|
|
18172
|
-
* permission: 'marine.coral.browse',
|
|
18173
|
-
* component: async () => (await import('./CoralBrowse.js')).default,
|
|
18174
|
-
* }),
|
|
18175
|
-
* };
|
|
18176
|
-
* });
|
|
18177
|
-
* ```
|
|
18178
18448
|
*/
|
|
18179
|
-
export
|
|
18449
|
+
export interface IComponent {
|
|
18450
|
+
title?: string;
|
|
18451
|
+
permission?: string;
|
|
18452
|
+
icon?: string;
|
|
18453
|
+
component: (params?: Record<string, unknown>) => Promise<unknown>;
|
|
18454
|
+
}
|
|
18180
18455
|
/** Action definition for use with `defineActions`. */
|
|
18181
18456
|
export interface IActionDef {
|
|
18182
18457
|
title?: string;
|
|
@@ -18216,6 +18491,8 @@ export declare const defineActions: (actions: Record<string, IActionDef>) => ((_
|
|
|
18216
18491
|
export declare const library: <T = Record<string, unknown>>(definition: Lib<T>) => Lib<T>;
|
|
18217
18492
|
export declare const validation: (validation: ValidationDefinition) => ValidationDefinition;
|
|
18218
18493
|
export declare const api: (api: ApiDefinition) => ApiDefinition;
|
|
18494
|
+
export declare const model: <T extends IModelSpec>(definition: () => () => Promise<T>) => (() => () => Promise<T>);
|
|
18495
|
+
export declare const fixture: <T extends IMock>(definition: () => T) => (() => T);
|
|
18219
18496
|
export declare const validationHandlers: (handlers: Record<string, TFunction<[
|
|
18220
18497
|
ApiSchema
|
|
18221
18498
|
]>>) => ValidationDefinition;
|
|
@@ -18225,11 +18502,10 @@ export declare const browser: <T extends TObject>(definition: SolutionFactory<T>
|
|
|
18225
18502
|
export declare const layer: (activation: Record<string, boolean | object>) => Record<string, boolean | object>;
|
|
18226
18503
|
export declare const adapter: <T, C = AdapterContext>(definition: IAdapterFactory<T, C>) => IAdapterFactory<T, C>;
|
|
18227
18504
|
export declare const orchestrator: <T, C = AdapterContext>(definition: IAdapterFactory<T, C>) => IAdapterFactory<T, C>;
|
|
18228
|
-
export type Kinds = "lib" | "validation" | "api" | "solution" | "server" | "browser" | "adapter" | "orchestrator" | "handler";
|
|
18229
|
-
export declare const kind: (what: {}) => Kinds
|
|
18505
|
+
export type Kinds = "lib" | "validation" | "api" | "solution" | "server" | "browser" | "adapter" | "orchestrator" | "handler" | "model" | "fixture" | "";
|
|
18506
|
+
export declare const kind: (what: {}) => Kinds;
|
|
18230
18507
|
declare const _default: {
|
|
18231
18508
|
handler: <T = Record<string, unknown>, C = AdapterContext>(definition: Definition<T, C>) => Definition<T, C>;
|
|
18232
|
-
componentHandler: <T = Record<string, unknown>, C = AdapterContext>(definition: Definition<T, C>) => Definition<T, C>;
|
|
18233
18509
|
defineActions: (actions: Record<string, IActionDef>) => ((_blong: unknown) => Record<string, () => IActionDef>);
|
|
18234
18510
|
library: <T = Record<string, unknown>>(definition: Lib<T>) => Lib<T>;
|
|
18235
18511
|
validation: (validation: ValidationDefinition) => ValidationDefinition;
|
|
@@ -18239,7 +18515,8 @@ declare const _default: {
|
|
|
18239
18515
|
browser: <T extends TObject>(definition: SolutionFactory<T>) => SolutionFactory<T>;
|
|
18240
18516
|
adapter: <T, C = AdapterContext>(definition: IAdapterFactory<T, C>) => IAdapterFactory<T, C>;
|
|
18241
18517
|
orchestrator: <T, C = AdapterContext>(definition: IAdapterFactory<T, C>) => IAdapterFactory<T, C>;
|
|
18242
|
-
|
|
18518
|
+
fixture: <T extends IMock>(definition: () => T) => (() => T);
|
|
18519
|
+
kind: (what: {}) => Kinds;
|
|
18243
18520
|
};
|
|
18244
18521
|
|
|
18245
18522
|
export {
|
package/dist/types.js
CHANGED
|
@@ -21,29 +21,6 @@ export class Internal {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
export const handler = (definition) => Object.defineProperty(definition, Kind, { value: 'handler' });
|
|
24
|
-
/**
|
|
25
|
-
* Browser-side equivalent of `handler`. Use this to define a component handler
|
|
26
|
-
* in a realm's `component/` layer. Functionally identical to `handler` — the
|
|
27
|
-
* distinction is semantic and makes intent clear in code review.
|
|
28
|
-
*
|
|
29
|
-
* The inner function should return a map whose keys are dot-notation method names
|
|
30
|
-
* (e.g. `'coral.browse'`) and values are async functions that return component
|
|
31
|
-
* metadata `{title, permission, icon, component: async () => ReactComponent}`.
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* export default componentHandler(blong => function coralBrowse() {
|
|
36
|
-
* return {
|
|
37
|
-
* 'coral.browse': async () => ({
|
|
38
|
-
* title: 'Browse Corals',
|
|
39
|
-
* permission: 'marine.coral.browse',
|
|
40
|
-
* component: async () => (await import('./CoralBrowse.js')).default,
|
|
41
|
-
* }),
|
|
42
|
-
* };
|
|
43
|
-
* });
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export const componentHandler = (definition) => Object.defineProperty(definition, Kind, { value: 'handler' });
|
|
47
24
|
/**
|
|
48
25
|
* Register action metadata for a realm's browser layer.
|
|
49
26
|
*
|
|
@@ -67,6 +44,8 @@ export const defineActions = (actions) => Object.defineProperty((_blong) => Obje
|
|
|
67
44
|
export const library = (definition) => Object.defineProperty(definition, Kind, { value: 'lib' });
|
|
68
45
|
export const validation = (validation) => Object.defineProperty(validation, Kind, { value: 'validation' });
|
|
69
46
|
export const api = (api) => Object.defineProperty(api, Kind, { value: 'api' });
|
|
47
|
+
export const model = (definition) => Object.defineProperty(definition, Kind, { value: 'model' });
|
|
48
|
+
export const fixture = (definition) => Object.defineProperty(definition, Kind, { value: 'fixture' });
|
|
70
49
|
export const validationHandlers = handlers => validation(() => Object.fromEntries(Object.entries(handlers).map(([name, handler]) => [
|
|
71
50
|
name,
|
|
72
51
|
Object.defineProperty(() => ({
|
|
@@ -81,10 +60,9 @@ export const browser = (definition) => Object.defineProperty(definition, Kind, {
|
|
|
81
60
|
export const layer = (activation) => Object.defineProperty(activation, Kind, { value: 'layer' });
|
|
82
61
|
export const adapter = (definition) => Object.defineProperty(definition, Kind, { value: 'adapter' });
|
|
83
62
|
export const orchestrator = (definition) => Object.defineProperty(definition, Kind, { value: 'orchestrator' });
|
|
84
|
-
export const kind = (what) => what[Kind];
|
|
63
|
+
export const kind = (what) => what[Kind] || '';
|
|
85
64
|
export default {
|
|
86
65
|
handler,
|
|
87
|
-
componentHandler,
|
|
88
66
|
defineActions,
|
|
89
67
|
library,
|
|
90
68
|
validation,
|
|
@@ -94,6 +72,7 @@ export default {
|
|
|
94
72
|
browser,
|
|
95
73
|
adapter,
|
|
96
74
|
orchestrator,
|
|
75
|
+
fixture,
|
|
97
76
|
kind,
|
|
98
77
|
};
|
|
99
78
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAYA,OAAO,EACH,IAAI,GAWP,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feasibleone/blong",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "API and DRY focused RAD framework https://feasibleone.github.io/blong-docs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"blong",
|
|
@@ -12,8 +12,11 @@
|
|
|
12
12
|
},
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
|
-
".":
|
|
16
|
-
|
|
15
|
+
".": {
|
|
16
|
+
"blong-dev": "./types.ts",
|
|
17
|
+
"types": "./types.ts",
|
|
18
|
+
"default": "./dist/types.js"
|
|
19
|
+
},
|
|
17
20
|
"./types": "./types.ts"
|
|
18
21
|
},
|
|
19
22
|
"dependencies": {
|
|
@@ -23,10 +26,9 @@
|
|
|
23
26
|
"ut-function.merge": "^1.5.6"
|
|
24
27
|
},
|
|
25
28
|
"devDependencies": {
|
|
26
|
-
"@aws-sdk/client-s3": "^3.
|
|
29
|
+
"@aws-sdk/client-s3": "^3.1037.0",
|
|
27
30
|
"@keycloak/keycloak-admin-client": "^26.5.4",
|
|
28
31
|
"@kubernetes/client-node": "^1.4.0",
|
|
29
|
-
"@rushstack/eslint-config": "^4.6.4",
|
|
30
32
|
"@rushstack/heft": "^1.2.6",
|
|
31
33
|
"@rushstack/heft-lint-plugin": "^1.2.6",
|
|
32
34
|
"@rushstack/heft-typescript-plugin": "^1.3.1",
|
|
@@ -35,8 +37,8 @@
|
|
|
35
37
|
"@types/request": "^2.48.13",
|
|
36
38
|
"@types/ut-function.merge": "file:./types/ut-function.merge",
|
|
37
39
|
"bson": "^7.2.0",
|
|
40
|
+
"chokidar": "^5.0.0",
|
|
38
41
|
"dts-bundle-generator": "^9.5.1",
|
|
39
|
-
"eslint": "~9.39.2",
|
|
40
42
|
"knex": "^3.1.0",
|
|
41
43
|
"mongodb": "^7.1.0",
|
|
42
44
|
"node-vault": "^0.10.10",
|
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 {
|
|
@@ -179,6 +270,7 @@ export type Handlers = ((params: {
|
|
|
179
270
|
local: object;
|
|
180
271
|
literals: object[];
|
|
181
272
|
gateway: IGateway;
|
|
273
|
+
apiSchema: IApiSchema;
|
|
182
274
|
}) => void)[];
|
|
183
275
|
|
|
184
276
|
export interface IRegistry {
|
|
@@ -220,24 +312,19 @@ export interface IApi {
|
|
|
220
312
|
rpc: IRpcServer;
|
|
221
313
|
local: ILocal;
|
|
222
314
|
registry: IRegistry;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
attachHandlers: (target: object, patterns: unknown, adapter?: boolean) => unknown;
|
|
237
|
-
};
|
|
238
|
-
utLog: {
|
|
239
|
-
createLog: ILog['logger'];
|
|
240
|
-
};
|
|
315
|
+
register: (methods: object, namespace: string, id: string, pkg: {version: string}) => void;
|
|
316
|
+
unregister: (methods: string[], namespace: string) => void;
|
|
317
|
+
subscribe: (methods: object, namespace: string, id: string, pkg: {version: string}) => void;
|
|
318
|
+
unsubscribe: (methods: string[], namespace: string) => void;
|
|
319
|
+
dispatch: (...params: unknown[]) => boolean | Promise<unknown>;
|
|
320
|
+
methodId: (name: string) => string;
|
|
321
|
+
getPath: (name: string) => string;
|
|
322
|
+
importMethod: (
|
|
323
|
+
methodName: string,
|
|
324
|
+
options?: object,
|
|
325
|
+
) => (...params: unknown[]) => Promise<unknown>;
|
|
326
|
+
attachHandlers: (target: object, patterns: unknown, adapter?: boolean) => unknown;
|
|
327
|
+
createLog: ILog['logger'];
|
|
241
328
|
attachCheckpoint?: (meta: IMeta) => void;
|
|
242
329
|
handlers?: (api: {utError: IError; remote: IRemote; type: typeof Type}) => {
|
|
243
330
|
extends?:
|
|
@@ -270,6 +357,7 @@ export interface IAdapter<T, C> {
|
|
|
270
357
|
log?: ILogger;
|
|
271
358
|
errors?: Errors<IErrorMap>;
|
|
272
359
|
imported?: ReturnType<IAdapterFactory<T, C>>;
|
|
360
|
+
importedMap?: Map<string, IRemoteHandler>;
|
|
273
361
|
extends?: object | `adapter.${string}` | `orchestrator.${string}`;
|
|
274
362
|
activeConfig?: (this: ReturnType<IAdapterFactory<T, C>>) => Partial<Config<T, C>>;
|
|
275
363
|
init?: (
|
|
@@ -296,7 +384,7 @@ export interface IAdapter<T, C> {
|
|
|
296
384
|
) => Buffer;
|
|
297
385
|
encode?: (data: unknown, $meta: IMeta, context: object, log: ILogger) => string | Buffer;
|
|
298
386
|
decode?: (buff: string | Buffer, $meta: IMeta, context: object, log: ILogger) => object[];
|
|
299
|
-
request?: () => Promise<unknown>;
|
|
387
|
+
request?: (...params: unknown[]) => Promise<unknown>;
|
|
300
388
|
publish?: () => Promise<unknown>;
|
|
301
389
|
drain?: () => void;
|
|
302
390
|
findValidation?: (this: ReturnType<IAdapterFactory<T, C>>, $meta: IMeta) => () => object;
|
|
@@ -422,8 +510,6 @@ export interface IMeta {
|
|
|
422
510
|
checkpoints?: Array<{name: string; data?: unknown; timestamp: number}>;
|
|
423
511
|
}
|
|
424
512
|
|
|
425
|
-
export type HRTime = [number, number];
|
|
426
|
-
|
|
427
513
|
export interface IContext {
|
|
428
514
|
trace: number;
|
|
429
515
|
session?: {
|
|
@@ -493,6 +579,7 @@ export interface IModuleConfig<T extends TSchema = TNever> {
|
|
|
493
579
|
config?: IActivationConfig<Partial<Static<T>> & Partial<Static<IBaseConfig>>>;
|
|
494
580
|
validation?: T;
|
|
495
581
|
children?: (string | (() => Promise<object>))[] | ((layer: ModuleApi) => unknown)[];
|
|
582
|
+
glob?: Record<string, () => Promise<object>>;
|
|
496
583
|
}
|
|
497
584
|
|
|
498
585
|
export interface ILogger {
|
|
@@ -567,9 +654,16 @@ export interface ILib {
|
|
|
567
654
|
/** @deprecated The framework now auto-names step arrays from handler names. */
|
|
568
655
|
group: (name: string) => (handlers: ChainStep[]) => ChainStep[] & {name: string};
|
|
569
656
|
assert: typeof Assert | undefined;
|
|
657
|
+
yaml: {
|
|
658
|
+
parse: <T>(source: string, options?: unknown) => T;
|
|
659
|
+
parseAllDocuments: <T>(source: string, options?: unknown) => T;
|
|
660
|
+
parseDocument: <T>(source: string, options?: unknown) => T;
|
|
661
|
+
stringify: (value: unknown, options?: unknown) => string;
|
|
662
|
+
};
|
|
570
663
|
ulid: () => string;
|
|
571
664
|
uuid4: () => string;
|
|
572
665
|
uuid7: () => string;
|
|
666
|
+
timing: IPlatformApi['timing'];
|
|
573
667
|
setProperty: (obj: Record<string, unknown>, path: string, value: unknown) => void;
|
|
574
668
|
merge<T, S1>(target: T, source: S1): T & S1;
|
|
575
669
|
merge<T, S1, S2>(target: T, source1: S1, source2: S2): T & S1 & S2;
|
|
@@ -639,6 +733,7 @@ export interface IHandlerProxy<T> {
|
|
|
639
733
|
gateway: {
|
|
640
734
|
config: () => {public: {sign: object; encrypt: object}};
|
|
641
735
|
};
|
|
736
|
+
apiSchema: IApiSchema;
|
|
642
737
|
}
|
|
643
738
|
|
|
644
739
|
export type ImportProxyCallback<T, C> = (
|
|
@@ -705,23 +800,13 @@ export const handler = <T = Record<string, unknown>, C = AdapterContext>(
|
|
|
705
800
|
* The inner function should return a map whose keys are dot-notation method names
|
|
706
801
|
* (e.g. `'coral.browse'`) and values are async functions that return component
|
|
707
802
|
* 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
803
|
*/
|
|
722
|
-
export
|
|
723
|
-
|
|
724
|
-
|
|
804
|
+
export interface IComponent {
|
|
805
|
+
title?: string;
|
|
806
|
+
permission?: string;
|
|
807
|
+
icon?: string;
|
|
808
|
+
component: (params?: Record<string, unknown>) => Promise<unknown>;
|
|
809
|
+
}
|
|
725
810
|
|
|
726
811
|
/** Action definition for use with `defineActions`. */
|
|
727
812
|
export interface IActionDef {
|
|
@@ -737,7 +822,9 @@ export interface IActionDef {
|
|
|
737
822
|
/** Action names whose query caches should be invalidated on success. */
|
|
738
823
|
invalidates?: string[];
|
|
739
824
|
/** Static params merged into every invocation. */
|
|
740
|
-
params?:
|
|
825
|
+
params?:
|
|
826
|
+
| Record<string, unknown>
|
|
827
|
+
| ((params: Record<string, unknown>) => Record<string, unknown>);
|
|
741
828
|
}
|
|
742
829
|
|
|
743
830
|
/**
|
|
@@ -764,9 +851,7 @@ export const defineActions = (
|
|
|
764
851
|
): ((_blong: unknown) => Record<string, () => IActionDef>) =>
|
|
765
852
|
Object.defineProperty(
|
|
766
853
|
(_blong: unknown) =>
|
|
767
|
-
Object.fromEntries(
|
|
768
|
-
Object.entries(actions).map(([key, value]) => [key, () => value]),
|
|
769
|
-
),
|
|
854
|
+
Object.fromEntries(Object.entries(actions).map(([key, value]) => [key, () => value])),
|
|
770
855
|
Kind,
|
|
771
856
|
{value: 'handler'},
|
|
772
857
|
);
|
|
@@ -777,6 +862,11 @@ export const validation = (validation: ValidationDefinition): ValidationDefiniti
|
|
|
777
862
|
Object.defineProperty(validation, Kind, {value: 'validation'});
|
|
778
863
|
export const api = (api: ApiDefinition): ApiDefinition =>
|
|
779
864
|
Object.defineProperty(api, Kind, {value: 'api'});
|
|
865
|
+
export const model = <T extends IModelSpec>(
|
|
866
|
+
definition: () => () => Promise<T>,
|
|
867
|
+
): (() => () => Promise<T>) => Object.defineProperty(definition, Kind, {value: 'model'});
|
|
868
|
+
export const fixture = <T extends IMock>(definition: () => T): (() => T) =>
|
|
869
|
+
Object.defineProperty(definition, Kind, {value: 'fixture'});
|
|
780
870
|
|
|
781
871
|
export const validationHandlers: (
|
|
782
872
|
handlers: Record<string, TFunction<[ApiSchema]>>,
|
|
@@ -813,6 +903,7 @@ export const adapter = <T, C = AdapterContext>(
|
|
|
813
903
|
export const orchestrator = <T, C = AdapterContext>(
|
|
814
904
|
definition: IAdapterFactory<T, C>,
|
|
815
905
|
): IAdapterFactory<T, C> => Object.defineProperty(definition, Kind, {value: 'orchestrator'});
|
|
906
|
+
|
|
816
907
|
export type Kinds =
|
|
817
908
|
| 'lib'
|
|
818
909
|
| 'validation'
|
|
@@ -822,12 +913,14 @@ export type Kinds =
|
|
|
822
913
|
| 'browser'
|
|
823
914
|
| 'adapter'
|
|
824
915
|
| 'orchestrator'
|
|
825
|
-
| 'handler'
|
|
826
|
-
|
|
916
|
+
| 'handler'
|
|
917
|
+
| 'model'
|
|
918
|
+
| 'fixture'
|
|
919
|
+
| '';
|
|
920
|
+
export const kind = (what: {[Kind]: Kinds | undefined}): Kinds => what[Kind] || '';
|
|
827
921
|
|
|
828
922
|
export default {
|
|
829
923
|
handler,
|
|
830
|
-
componentHandler,
|
|
831
924
|
defineActions,
|
|
832
925
|
library,
|
|
833
926
|
validation,
|
|
@@ -837,5 +930,6 @@ export default {
|
|
|
837
930
|
browser,
|
|
838
931
|
adapter,
|
|
839
932
|
orchestrator,
|
|
933
|
+
fixture,
|
|
840
934
|
kind,
|
|
841
935
|
};
|