@feasibleone/blong 1.23.0 → 1.25.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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.25.0](https://github.com/feasibleone/blong/compare/blong-v1.24.0...blong-v1.25.0) (2026-08-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * access sessions and audit ([694349f](https://github.com/feasibleone/blong/commit/694349f7e70973b984a30f696d2b6e892b55ec02))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * blong-access-mock, silent error, expected error ([dc00429](https://github.com/feasibleone/blong/commit/dc00429a63a973996d6e94359830cc52d149b995))
14
+
15
+ ## [1.24.0](https://github.com/feasibleone/blong/compare/blong-v1.23.0...blong-v1.24.0) (2026-08-19)
16
+
17
+
18
+ ### Features
19
+
20
+ * master-detail handling ([03c5bbd](https://github.com/feasibleone/blong/commit/03c5bbd9401a82a9427577e7611f2622aadee4e5))
21
+ * redis adapter and blong-gateway ([c28a68f](https://github.com/feasibleone/blong/commit/c28a68f5f9cfc2398771cca05c4366efc147eb6e))
22
+ * resolve some AI agent frictions ([13ca27f](https://github.com/feasibleone/blong/commit/13ca27f09f0271a25ea7ad45a2ce3f73bf6710e0))
23
+ * resolve some AI agent frictions and improve the framework features ([23b6986](https://github.com/feasibleone/blong/commit/23b69863b458e97f1dad249fcdeec5e182a69b74))
24
+
3
25
  ## [1.23.0](https://github.com/feasibleone/blong/compare/blong-v1.22.0...blong-v1.23.0) (2026-07-14)
4
26
 
5
27
 
package/dist/types.d.ts CHANGED
@@ -18756,7 +18756,7 @@ export type IAction = string | {
18756
18756
  invalidates?: string[];
18757
18757
  };
18758
18758
  /** All supported widget types */
18759
- export type WidgetType = "input" | "mask" | "text" | "textArea" | "password" | "number" | "integer" | "currency" | "percent" | "boolean" | "checkbox" | "switch" | "date" | "time" | "dateTime" | "dateRange" | "dropdown" | "dropdownTree" | "select" | "selectTable" | "multiSelect" | "multiSelectTree" | "multiSelectPanel" | "multiSelectTreeTable" | "chips" | "file" | "image" | "imageUpload" | "autocomplete" | "table" | "navigator" | "json" | "code" | "divider" | "label" | "link" | "component" | "custom";
18759
+ export type WidgetType = "input" | "mask" | "text" | "textArea" | "password" | "number" | "integer" | "bigint" | "currency" | "percent" | "boolean" | "checkbox" | "switch" | "date" | "time" | "dateTime" | "dateRange" | "dropdown" | "dropdownTree" | "select" | "selectTable" | "multiSelect" | "multiSelectTree" | "multiSelectPanel" | "multiSelectTreeTable" | "chips" | "file" | "image" | "imageUpload" | "autocomplete" | "table" | "navigator" | "json" | "code" | "divider" | "label" | "link" | "component" | "custom";
18760
18760
  /** Base widget configuration (stored in schema x-widget) */
18761
18761
  export interface IWidgetConfig {
18762
18762
  type: WidgetType;
@@ -19251,6 +19251,30 @@ export interface IMethodsConfig {
19251
19251
  remove?: string;
19252
19252
  report?: string;
19253
19253
  }
19254
+ /**
19255
+ * Master-detail detail entity. A master model (e.g. `invoice`) declares its
19256
+ * detail entities (e.g. `line`, `payment`) here. Each detail is an **array
19257
+ * property at the SAME level as the master record** — the model schema has a
19258
+ * dedicated key for the master object (`schema.properties[object]`) and one
19259
+ * sibling array key per detail (`schema.properties[detail.object]`), whose
19260
+ * `items` hold the detail-row schema (declared right there by the realm).
19261
+ * Each detail produces:
19262
+ * - a sibling array in the auto `add`/`edit` validation schemas, so a public
19263
+ * invoice `add` accepts `{invoice: {...}, line: [...], payment: [...]}`,
19264
+ * - an editable table + a tab in the browser New/Open forms (one per detail).
19265
+ */
19266
+ export interface IModelDetail {
19267
+ /**
19268
+ * Detail entity name, e.g. 'line'. The framework looks it up as a sibling
19269
+ * array property of the master object schema
19270
+ * (`schema.properties[detail.object]`) whose `items` hold the detail-row
19271
+ * schema; it fills in `type: 'array'`, the editable table widget, a
19272
+ * `details-<object>` card and an edit-layout tab.
19273
+ */
19274
+ object: string;
19275
+ /** Primary key field of the detail rows, e.g. 'lineId'. Defaults to `${object}Id`. */
19276
+ keyField?: string;
19277
+ }
19254
19278
  /**
19255
19279
  * ModelSpec — the browser-side description of one "subject.object" domain entity.
19256
19280
  *
@@ -19269,6 +19293,12 @@ export interface IModelSpec {
19269
19293
  nameField?: string;
19270
19294
  /** JSON Schema overlay merged on top of server OpenAPI schema */
19271
19295
  schema?: ISchemaOverlay;
19296
+ /**
19297
+ * Optional master-detail entities. When present, the auto `add`/`edit`
19298
+ * validations include a nested array per detail and the New/Open forms
19299
+ * render one editable table + tab per detail.
19300
+ */
19301
+ details?: IModelDetail[];
19272
19302
  /** Named card layout definitions */
19273
19303
  cards?: Record<string, ICardConfig>;
19274
19304
  /** Browse page configuration */
@@ -19287,6 +19317,13 @@ export interface IModelSpec {
19287
19317
  layouts?: Record<string, LayoutConfig>;
19288
19318
  /** Method name overrides */
19289
19319
  methods?: IMethodsConfig;
19320
+ /**
19321
+ * Mark this model as part of the "public API" — its standard CRUD operations
19322
+ * get gateway validations by default (via the `subject.validation`
19323
+ * orchestrator). Declarative marker: no suite config is needed; a suite can
19324
+ * opt out only in rare cases (`validations: false`, or per model).
19325
+ */
19326
+ public?: boolean;
19290
19327
  }
19291
19328
  /** Model spec as accepted by modelFactory — objectTitle/keyField/nameField are optional */
19292
19329
  export type IPartialModelSpec = IModelSpec;
@@ -19337,6 +19374,12 @@ export type ServerContext = {
19337
19374
  kafkaStream?: Duplex;
19338
19375
  mongodb?: MongoClient;
19339
19376
  slack?: IncomingWebhook;
19377
+ /** Live redis client shared with derived adapters. */
19378
+ redis?: {
19379
+ status: string;
19380
+ connect(): Promise<unknown>;
19381
+ quit(): Promise<unknown>;
19382
+ };
19340
19383
  };
19341
19384
  export type BrowserContext = {
19342
19385
  /** TanStack Query client instance (injected by the browser platform). */
@@ -19771,6 +19814,7 @@ export interface IMeta {
19771
19814
  redirect?: string;
19772
19815
  code?: number;
19773
19816
  state?: unknown[];
19817
+ unstate?: unknown[];
19774
19818
  header?: string[] | [
19775
19819
  string,
19776
19820
  unknown
@@ -19787,6 +19831,10 @@ export interface IMeta {
19787
19831
  permissionMap?: Buffer;
19788
19832
  actorId?: string | number;
19789
19833
  sessionId?: string;
19834
+ /** Audit record id of the access-check audit recorded for this request. */
19835
+ auditId?: string;
19836
+ /** Allowed action methodIds — populated by the gateway authorize handler. */
19837
+ actions?: string[];
19790
19838
  };
19791
19839
  language?: {
19792
19840
  languageId?: string | number;
@@ -19856,6 +19904,7 @@ export interface ITypedError extends Error {
19856
19904
  method?: string | string[];
19857
19905
  params?: object;
19858
19906
  code?: string;
19907
+ silent?: boolean;
19859
19908
  req?: {
19860
19909
  httpVersion: string;
19861
19910
  url: URL;
@@ -19892,6 +19941,7 @@ export interface IBaseConfig extends TObject<{
19892
19941
  rpcServer: TBoolean | TObject;
19893
19942
  restFs: TBoolean | TObject;
19894
19943
  systemDebug: TBoolean | TObject;
19944
+ apiGateway: TBoolean | TObject;
19895
19945
  }> {
19896
19946
  additionalProperties: false;
19897
19947
  }
@@ -19920,6 +19970,23 @@ export interface ILogger {
19920
19970
  warn?: LogFn;
19921
19971
  error?: LogFn;
19922
19972
  fatal?: LogFn;
19973
+ /**
19974
+ * Wrap a long-running promise and report progress on this logger.
19975
+ *
19976
+ * Once the operation runs past `thresholdMs`, a snapshot (from `getProgress`)
19977
+ * is logged every `intervalMs` at the given `level` (default 'warn'), followed
19978
+ * by a completion line. Delegates to the shared `withProgress` helper from
19979
+ * `@feasibleone/blong-lib`.
19980
+ *
19981
+ * @example
19982
+ * await runtime.log.progress('schema sync', syncPromise, {getProgress: () => ({done: 1, total: 2})});
19983
+ */
19984
+ progress?: <T>(label: string, promise: Promise<T>, options?: {
19985
+ getProgress?: () => string | object;
19986
+ thresholdMs?: number;
19987
+ intervalMs?: number;
19988
+ level?: "info" | "warn";
19989
+ }) => Promise<T>;
19923
19990
  }
19924
19991
  export interface IStep {
19925
19992
  name: string;
@@ -19953,6 +20020,23 @@ export type GatewaySchema = ({
19953
20020
  subject?: string;
19954
20021
  destination?: string;
19955
20022
  operation?: OpenAPIV3_1.OperationObject | OpenAPIV2.OperationObject;
20023
+ /** Metering metadata threaded into the Fastify route config by Gateway.ts. */
20024
+ bundle?: string;
20025
+ creditCost?: number;
20026
+ meter?: boolean;
20027
+ /**
20028
+ * Opt this route OUT of the gateway access-check audit (`gateway.audit`).
20029
+ * Use for operations that record their own audit trail (e.g. payments)
20030
+ * or that must not generate audit noise (e.g. integration-test probes).
20031
+ */
20032
+ audit?: boolean;
20033
+ /**
20034
+ * Authenticate the route (bearer) but skip the RBAC action-list check.
20035
+ * Use ONLY for self-service methods that operate on the caller's own
20036
+ * session (e.g. `login.token.revoke`) — the action is scoped by the
20037
+ * token's own `ses` claim, so no cross-user action is possible.
20038
+ */
20039
+ skipAuthorize?: boolean;
19956
20040
  };
19957
20041
  export type SchemaObject = OpenAPIV3_1.SchemaObject | OpenAPIV2.SchemaObject;
19958
20042
  export type PathItemObject = OpenAPIV3_1.PathItemObject | OpenAPIV2.PathItemObject;
@@ -20054,6 +20138,25 @@ export interface ILib {
20054
20138
  render: (what: object[] | object) => object;
20055
20139
  crockfordEncode: (data: Uint8Array) => string;
20056
20140
  crockfordDecode: (data: string) => Uint8Array;
20141
+ withProgress: <T>(log: {
20142
+ info?: LogFn;
20143
+ warn?: LogFn;
20144
+ } | undefined, label: string, promise: Promise<T>, options?: {
20145
+ getProgress?: () => string | object;
20146
+ thresholdMs?: number;
20147
+ intervalMs?: number;
20148
+ level?: "info" | "warn";
20149
+ }) => Promise<T>;
20150
+ /**
20151
+ * Optional map of configurable method/handler bindings that a library may
20152
+ * expose under the conventional `methods` member — the idiomatic way to
20153
+ * bundle soft dependencies (e.g. the access-realm methods that blong-login's
20154
+ * `sessionLib` resolves from config). Handlers read the resolved handlers
20155
+ * through `lib.methods.<name>`; each value is a bound handler or `undefined`
20156
+ * when the binding is disabled. See the blong-handler skill →
20157
+ * "Library as a configurable-bindings bundle (soft dependencies)".
20158
+ */
20159
+ methods?: LibMethods;
20057
20160
  }
20058
20161
  export type ValidationFn = () => GatewaySchema;
20059
20162
  export interface IValidationProxy<T> {
@@ -20084,6 +20187,15 @@ export type PortHandlerBound = (<T>(params: object, $meta: IMeta, context?: ICon
20084
20187
  [name: string]: PortHandlerBound;
20085
20188
  };
20086
20189
  export type LibFn = <T>(...params: unknown[]) => T;
20190
+ /**
20191
+ * A map of configurable handler/method bindings exposed by a library under the
20192
+ * conventional `methods` member (see the blong-handler skill). Values are
20193
+ * bound handlers (usually resolved from config against the `handler` proxy);
20194
+ * `undefined` when the binding is disabled.
20195
+ */
20196
+ export type LibMethods = {
20197
+ [method: string]: LibFn | undefined;
20198
+ };
20087
20199
  export interface IRemoteHandler {
20088
20200
  [name: string]: PortHandlerBound;
20089
20201
  }
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"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"}
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.23.0",
3
+ "version": "1.25.0",
4
4
  "description": "API and DRY focused RAD framework https://feasibleone.github.io/blong-docs",
5
5
  "keywords": [
6
6
  "blong",
@@ -47,7 +47,7 @@
47
47
  "react": "^19.1.0",
48
48
  "tarn": "^3.0.2",
49
49
  "typescript": "^6.0.3",
50
- "@feasibleone/blong-dev": "1.1.0"
50
+ "@feasibleone/blong-dev": "1.2.0"
51
51
  },
52
52
  "scripts": {
53
53
  "build": "heft build --clean;dts-bundle-generator --config dts-gen.config.json",
package/types.ts CHANGED
@@ -68,6 +68,12 @@ export type ServerContext = {
68
68
  // s3?: S3Client;
69
69
  slack?: IncomingWebhook;
70
70
  // vault?: client;
71
+ /** Live redis client shared with derived adapters. */
72
+ redis?: {
73
+ status: string;
74
+ connect(): Promise<unknown>;
75
+ quit(): Promise<unknown>;
76
+ };
71
77
  };
72
78
 
73
79
  export type BrowserContext = {
@@ -580,6 +586,7 @@ export interface IMeta {
580
586
  redirect?: string;
581
587
  code?: number;
582
588
  state?: unknown[];
589
+ unstate?: unknown[];
583
590
  header?: string[] | [string, unknown][];
584
591
  };
585
592
  httpRequest?: {
@@ -593,6 +600,10 @@ export interface IMeta {
593
600
  permissionMap?: Buffer;
594
601
  actorId?: string | number;
595
602
  sessionId?: string;
603
+ /** Audit record id of the access-check audit recorded for this request. */
604
+ auditId?: string;
605
+ /** Allowed action methodIds — populated by the gateway authorize handler. */
606
+ actions?: string[];
596
607
  };
597
608
  language?: {
598
609
  languageId?: string | number;
@@ -661,6 +672,7 @@ export interface ITypedError extends Error {
661
672
  method?: string | string[];
662
673
  params?: object;
663
674
  code?: string;
675
+ silent?: boolean;
664
676
  req?: {
665
677
  httpVersion: string;
666
678
  url: URL;
@@ -699,6 +711,7 @@ export interface IBaseConfig extends TObject<{
699
711
  rpcServer: TBoolean | TObject;
700
712
  restFs: TBoolean | TObject;
701
713
  systemDebug: TBoolean | TObject;
714
+ apiGateway: TBoolean | TObject;
702
715
  }> {
703
716
  additionalProperties: false;
704
717
  }
@@ -732,6 +745,27 @@ export interface ILogger {
732
745
  warn?: LogFn;
733
746
  error?: LogFn;
734
747
  fatal?: LogFn;
748
+ /**
749
+ * Wrap a long-running promise and report progress on this logger.
750
+ *
751
+ * Once the operation runs past `thresholdMs`, a snapshot (from `getProgress`)
752
+ * is logged every `intervalMs` at the given `level` (default 'warn'), followed
753
+ * by a completion line. Delegates to the shared `withProgress` helper from
754
+ * `@feasibleone/blong-lib`.
755
+ *
756
+ * @example
757
+ * await runtime.log.progress('schema sync', syncPromise, {getProgress: () => ({done: 1, total: 2})});
758
+ */
759
+ progress?: <T>(
760
+ label: string,
761
+ promise: Promise<T>,
762
+ options?: {
763
+ getProgress?: () => string | object;
764
+ thresholdMs?: number;
765
+ intervalMs?: number;
766
+ level?: 'info' | 'warn';
767
+ },
768
+ ) => Promise<T>;
735
769
  }
736
770
 
737
771
  export interface IStep {
@@ -774,6 +808,23 @@ export type GatewaySchema = (
774
808
  subject?: string;
775
809
  destination?: string;
776
810
  operation?: OpenAPIV3_1.OperationObject | OpenAPIV2.OperationObject;
811
+ /** Metering metadata threaded into the Fastify route config by Gateway.ts. */
812
+ bundle?: string;
813
+ creditCost?: number;
814
+ meter?: boolean;
815
+ /**
816
+ * Opt this route OUT of the gateway access-check audit (`gateway.audit`).
817
+ * Use for operations that record their own audit trail (e.g. payments)
818
+ * or that must not generate audit noise (e.g. integration-test probes).
819
+ */
820
+ audit?: boolean;
821
+ /**
822
+ * Authenticate the route (bearer) but skip the RBAC action-list check.
823
+ * Use ONLY for self-service methods that operate on the caller's own
824
+ * session (e.g. `login.token.revoke`) — the action is scoped by the
825
+ * token's own `ses` claim, so no cross-user action is possible.
826
+ */
827
+ skipAuthorize?: boolean;
777
828
  };
778
829
 
779
830
  export type SchemaObject = OpenAPIV3_1.SchemaObject | OpenAPIV2.SchemaObject;
@@ -876,6 +927,27 @@ export interface ILib {
876
927
  render: (what: object[] | object) => object;
877
928
  crockfordEncode: (data: Uint8Array) => string;
878
929
  crockfordDecode: (data: string) => Uint8Array;
930
+ withProgress: <T>(
931
+ log: {info?: LogFn; warn?: LogFn} | undefined,
932
+ label: string,
933
+ promise: Promise<T>,
934
+ options?: {
935
+ getProgress?: () => string | object;
936
+ thresholdMs?: number;
937
+ intervalMs?: number;
938
+ level?: 'info' | 'warn';
939
+ },
940
+ ) => Promise<T>;
941
+ /**
942
+ * Optional map of configurable method/handler bindings that a library may
943
+ * expose under the conventional `methods` member — the idiomatic way to
944
+ * bundle soft dependencies (e.g. the access-realm methods that blong-login's
945
+ * `sessionLib` resolves from config). Handlers read the resolved handlers
946
+ * through `lib.methods.<name>`; each value is a bound handler or `undefined`
947
+ * when the binding is disabled. See the blong-handler skill →
948
+ * "Library as a configurable-bindings bundle (soft dependencies)".
949
+ */
950
+ methods?: LibMethods;
879
951
  }
880
952
 
881
953
  export type ValidationFn = () => GatewaySchema;
@@ -925,6 +997,15 @@ export type PortHandlerBound = (<T>(
925
997
  [name: string]: PortHandlerBound;
926
998
  };
927
999
  export type LibFn = <T>(...params: unknown[]) => T;
1000
+ /**
1001
+ * A map of configurable handler/method bindings exposed by a library under the
1002
+ * conventional `methods` member (see the blong-handler skill). Values are
1003
+ * bound handlers (usually resolved from config against the `handler` proxy);
1004
+ * `undefined` when the binding is disabled.
1005
+ */
1006
+ export type LibMethods = {
1007
+ [method: string]: LibFn | undefined;
1008
+ };
928
1009
  export interface IRemoteHandler {
929
1010
  [name: string]: PortHandlerBound;
930
1011
  }