@objectstack/objectql 4.0.4 → 4.1.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/dist/index.d.mts +726 -1117
- package/dist/index.d.ts +726 -1117
- package/dist/index.js +2316 -374
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2305 -372
- package/dist/index.mjs.map +1 -1
- package/package.json +33 -6
- package/.turbo/turbo-build.log +0 -22
- package/CHANGELOG.md +0 -720
- package/src/datasource-mapping.test.ts +0 -181
- package/src/engine.test.ts +0 -613
- package/src/engine.ts +0 -1668
- package/src/index.ts +0 -41
- package/src/kernel-factory.ts +0 -48
- package/src/metadata-facade.ts +0 -96
- package/src/plugin.integration.test.ts +0 -995
- package/src/plugin.ts +0 -534
- package/src/protocol-data.test.ts +0 -245
- package/src/protocol-discovery.test.ts +0 -213
- package/src/protocol-feed.test.ts +0 -303
- package/src/protocol-meta.test.ts +0 -440
- package/src/protocol.ts +0 -1242
- package/src/registry.test.ts +0 -494
- package/src/registry.ts +0 -716
- package/src/util.test.ts +0 -226
- package/src/util.ts +0 -219
- package/tsconfig.json +0 -10
package/dist/index.d.ts
CHANGED
|
@@ -1,61 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as _objectstack_spec_data from '@objectstack/spec/data';
|
|
3
|
-
import { ObjectOwnership, ServiceObject, QueryAST, HookContext, EngineQueryOptions, DataEngineInsertOptions, EngineUpdateOptions, EngineDeleteOptions, EngineCountOptions, EngineAggregateOptions } from '@objectstack/spec/data';
|
|
1
|
+
import { ServiceObject, ObjectOwnership, HookContext, QueryAST, EngineQueryOptions, DataEngineInsertOptions, EngineUpdateOptions, EngineDeleteOptions, EngineCountOptions, EngineAggregateOptions, DateGranularityValue, Hook } from '@objectstack/spec/data';
|
|
4
2
|
import { ObjectStackManifest, InstalledPackage, ExecutionContext } from '@objectstack/spec/kernel';
|
|
5
3
|
import { ObjectStackProtocol, MetadataCacheRequest, MetadataCacheResponse, BatchUpdateRequest, BatchUpdateResponse, UpdateManyDataRequest, DeleteManyDataRequest } from '@objectstack/spec/api';
|
|
6
4
|
import { IDataEngine, DriverInterface, Logger, Plugin, PluginContext, ObjectKernel } from '@objectstack/core';
|
|
7
5
|
import { IFeedService, IRealtimeService } from '@objectstack/spec/contracts';
|
|
8
6
|
|
|
9
|
-
/**
|
|
10
|
-
* XState-inspired State Machine Protocol
|
|
11
|
-
* Used to define strict business logic constraints and lifecycle management.
|
|
12
|
-
* Prevent AI "hallucinations" by enforcing valid valid transitions.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* References a named action (side effect)
|
|
16
|
-
* Can be a script, a webhook, or a field update.
|
|
17
|
-
*/
|
|
18
|
-
declare const ActionRefSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
19
|
-
type: z.ZodString;
|
|
20
|
-
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
-
}, z.core.$strip>]>;
|
|
22
|
-
/**
|
|
23
|
-
* State Transition Definition
|
|
24
|
-
* "When EVENT happens, if GUARD is true, go to TARGET and run ACTIONS"
|
|
25
|
-
*/
|
|
26
|
-
declare const TransitionSchema: z.ZodObject<{
|
|
27
|
-
target: z.ZodOptional<z.ZodString>;
|
|
28
|
-
cond: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
29
|
-
type: z.ZodString;
|
|
30
|
-
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
31
|
-
}, z.core.$strip>]>>;
|
|
32
|
-
actions: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
33
|
-
type: z.ZodString;
|
|
34
|
-
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
35
|
-
}, z.core.$strip>]>>>;
|
|
36
|
-
description: z.ZodOptional<z.ZodString>;
|
|
37
|
-
}, z.core.$strip>;
|
|
38
|
-
type ActionRef = z.infer<typeof ActionRefSchema>;
|
|
39
|
-
type Transition = z.infer<typeof TransitionSchema>;
|
|
40
|
-
type StateNodeConfig = {
|
|
41
|
-
type?: 'atomic' | 'compound' | 'parallel' | 'final' | 'history';
|
|
42
|
-
entry?: ActionRef[];
|
|
43
|
-
exit?: ActionRef[];
|
|
44
|
-
on?: Record<string, string | Transition | Transition[]>;
|
|
45
|
-
always?: Transition[];
|
|
46
|
-
initial?: string;
|
|
47
|
-
states?: Record<string, StateNodeConfig>;
|
|
48
|
-
meta?: {
|
|
49
|
-
label?: string;
|
|
50
|
-
description?: string;
|
|
51
|
-
color?: string;
|
|
52
|
-
aiInstructions?: string;
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
|
|
56
7
|
/**
|
|
57
8
|
* Reserved namespaces that do not get FQN prefix applied.
|
|
58
|
-
* Objects in these namespaces keep their short names (e.g., "user"
|
|
9
|
+
* Objects in these namespaces keep their short names (e.g., "user" — short name IS the canonical key).
|
|
59
10
|
*/
|
|
60
11
|
declare const RESERVED_NAMESPACES: Set<string>;
|
|
61
12
|
/**
|
|
@@ -75,22 +26,25 @@ interface ObjectContributor {
|
|
|
75
26
|
definition: ServiceObject;
|
|
76
27
|
}
|
|
77
28
|
/**
|
|
78
|
-
* Compute
|
|
29
|
+
* Compute canonical registry key for an object.
|
|
30
|
+
*
|
|
31
|
+
* Under the current naming convention, object names are canonical identifiers
|
|
32
|
+
* and are used as-is (no namespace__ prefix). The namespace parameter is
|
|
33
|
+
* retained for backward compatibility but no longer affects the returned key.
|
|
79
34
|
*
|
|
80
|
-
* @param namespace - The package namespace (
|
|
81
|
-
* @param shortName - The object's
|
|
82
|
-
* @returns
|
|
35
|
+
* @param namespace - The package namespace (unused, kept for API compatibility)
|
|
36
|
+
* @param shortName - The object's name (already the canonical identifier)
|
|
37
|
+
* @returns The object name unchanged
|
|
83
38
|
*
|
|
84
39
|
* @example
|
|
85
|
-
* computeFQN('crm', 'account') // => '
|
|
86
|
-
* computeFQN(
|
|
87
|
-
* computeFQN(undefined, 'task') // => 'task' (legacy, no namespace)
|
|
40
|
+
* computeFQN('crm', 'account') // => 'account'
|
|
41
|
+
* computeFQN(undefined, 'task') // => 'task'
|
|
88
42
|
*/
|
|
89
|
-
declare function computeFQN(
|
|
43
|
+
declare function computeFQN(_namespace: string | undefined, shortName: string): string;
|
|
90
44
|
/**
|
|
91
45
|
* Parse FQN back to namespace and short name.
|
|
92
46
|
*
|
|
93
|
-
* @param fqn -
|
|
47
|
+
* @param fqn - Object name (e.g., "account" or legacy "crm__account" for backward compat)
|
|
94
48
|
* @returns { namespace, shortName } - namespace is undefined for unprefixed names
|
|
95
49
|
*/
|
|
96
50
|
declare function parseFQN(fqn: string): {
|
|
@@ -105,7 +59,7 @@ declare function parseFQN(fqn: string): {
|
|
|
105
59
|
*
|
|
106
60
|
* Objects use a namespace-based FQN system:
|
|
107
61
|
* - `namespace`: Short identifier from package manifest (e.g., "crm", "todo")
|
|
108
|
-
* - `
|
|
62
|
+
* - `name`: canonical object name (e.g., "account", "sys_user")
|
|
109
63
|
* - Reserved namespaces (`base`, `system`) don't get prefixed
|
|
110
64
|
*
|
|
111
65
|
* Ownership modes:
|
|
@@ -120,37 +74,82 @@ declare function parseFQN(fqn: string): {
|
|
|
120
74
|
* - A package may contain 0, 1, or many apps.
|
|
121
75
|
*/
|
|
122
76
|
type RegistryLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
77
|
+
/**
|
|
78
|
+
* Construction options for {@link SchemaRegistry}.
|
|
79
|
+
*/
|
|
80
|
+
interface SchemaRegistryOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Whether the host kernel runs in multi-tenant mode. When `true` (default),
|
|
83
|
+
* the registry auto-injects `organization_id` (lookup → sys_organization)
|
|
84
|
+
* into every registered user object that doesn't already declare it and
|
|
85
|
+
* isn't `managedBy` an external subsystem or explicitly opted-out via
|
|
86
|
+
* `systemFields: false`.
|
|
87
|
+
*
|
|
88
|
+
* Sourced from the `OS_MULTI_TENANT` env var when not explicitly set —
|
|
89
|
+
* matches how the SecurityPlugin and CLI startup banner pick the mode.
|
|
90
|
+
* Pass an explicit boolean to override (useful in tests).
|
|
91
|
+
*/
|
|
92
|
+
multiTenant?: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Augment a registered object with implicit system fields.
|
|
96
|
+
*
|
|
97
|
+
* Returns a *new* schema object when fields are added; returns the input
|
|
98
|
+
* unchanged when nothing applies (the cheap path for system tables).
|
|
99
|
+
*
|
|
100
|
+
* Author-declared fields always win — we splice the system fields at the
|
|
101
|
+
* front of the field map, so any same-named author field overwrites them
|
|
102
|
+
* via the natural `{ ...sys, ...authored }` merge.
|
|
103
|
+
*
|
|
104
|
+
* Currently injects:
|
|
105
|
+
* - `organization_id` — multi-tenant deployments. Required-false (the
|
|
106
|
+
* SecurityPlugin populates it on insert; nullable rows are still
|
|
107
|
+
* filtered out by the `tenant_isolation` RLS USING clause).
|
|
108
|
+
* - `created_at` / `created_by` / `updated_at` / `updated_by` — audit
|
|
109
|
+
* fields. Marked `system: true, readonly: true` so detail views can
|
|
110
|
+
* surface them in a dedicated "System Information" section while
|
|
111
|
+
* edit forms / drawers filter them out. The driver populates the
|
|
112
|
+
* timestamps; the `*_by` lookups are filled by the runtime when an
|
|
113
|
+
* authenticated session is present (NULL otherwise — e.g. seeded
|
|
114
|
+
* rows).
|
|
115
|
+
*/
|
|
116
|
+
declare function applySystemFields(schema: ServiceObject, opts: {
|
|
117
|
+
multiTenant: boolean;
|
|
118
|
+
}): ServiceObject;
|
|
123
119
|
declare class SchemaRegistry {
|
|
124
120
|
/** Controls verbosity of registry console messages. Default: 'info'. */
|
|
125
|
-
private
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
private _logLevel;
|
|
122
|
+
/** Whether to auto-inject multi-tenant system fields. */
|
|
123
|
+
private readonly multiTenant;
|
|
124
|
+
constructor(options?: SchemaRegistryOptions);
|
|
125
|
+
get logLevel(): RegistryLogLevel;
|
|
126
|
+
set logLevel(level: RegistryLogLevel);
|
|
127
|
+
private log;
|
|
129
128
|
/** FQN → Contributor[] (all packages that own/extend this object) */
|
|
130
|
-
private
|
|
129
|
+
private objectContributors;
|
|
131
130
|
/** FQN → Merged ServiceObject (cached, invalidated on changes) */
|
|
132
|
-
private
|
|
131
|
+
private mergedObjectCache;
|
|
133
132
|
/** Namespace → Set<PackageId> (multiple packages can share a namespace) */
|
|
134
|
-
private
|
|
133
|
+
private namespaceRegistry;
|
|
135
134
|
/** Type → Name/ID → MetadataItem */
|
|
136
|
-
private
|
|
135
|
+
private metadata;
|
|
137
136
|
/**
|
|
138
137
|
* Register a namespace for a package.
|
|
139
138
|
* Multiple packages can share the same namespace (e.g. 'sys').
|
|
140
139
|
*/
|
|
141
|
-
|
|
140
|
+
registerNamespace(namespace: string, packageId: string): void;
|
|
142
141
|
/**
|
|
143
142
|
* Unregister a namespace when a package is uninstalled.
|
|
144
143
|
*/
|
|
145
|
-
|
|
144
|
+
unregisterNamespace(namespace: string, packageId: string): void;
|
|
146
145
|
/**
|
|
147
146
|
* Get the packages that use a namespace.
|
|
148
147
|
*/
|
|
149
|
-
|
|
148
|
+
getNamespaceOwner(namespace: string): string | undefined;
|
|
150
149
|
/**
|
|
151
150
|
* Get all packages that share a namespace.
|
|
152
151
|
*/
|
|
153
|
-
|
|
152
|
+
getNamespaceOwners(namespace: string): string[];
|
|
154
153
|
/**
|
|
155
154
|
* Register an object with ownership semantics.
|
|
156
155
|
*
|
|
@@ -162,1086 +161,127 @@ declare class SchemaRegistry {
|
|
|
162
161
|
*
|
|
163
162
|
* @throws Error if trying to 'own' an object that already has an owner
|
|
164
163
|
*/
|
|
165
|
-
|
|
164
|
+
registerObject(schema: ServiceObject, packageId: string, namespace?: string, ownership?: ObjectOwnership, priority?: number): string;
|
|
166
165
|
/**
|
|
167
166
|
* Resolve an object by FQN, merging all contributions.
|
|
168
167
|
* Returns the merged object or undefined if not found.
|
|
169
168
|
*/
|
|
170
|
-
|
|
169
|
+
resolveObject(fqn: string): ServiceObject | undefined;
|
|
171
170
|
/**
|
|
172
|
-
* Get object by name (
|
|
171
|
+
* Get object by name (short name canonical, FQN supported for disambiguation).
|
|
172
|
+
*
|
|
173
|
+
* Short names are canonical for user code, AI generation, and most lookups.
|
|
174
|
+
* FQN is accepted as an explicit fallback for cross-package disambiguation
|
|
175
|
+
* when two packages contribute objects with the same short name.
|
|
173
176
|
*
|
|
174
177
|
* Resolution order:
|
|
175
|
-
* 1. Exact
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
* which uses a single underscore — different from the FQN double underscore.
|
|
178
|
+
* 1. Exact name match — the name IS the canonical key.
|
|
179
|
+
* If multiple packages contribute the same short name, a warning is logged
|
|
180
|
+
* and the first match wins — disambiguate by passing the FQN explicitly.
|
|
181
|
+
* 2. Legacy FQN match (e.g., 'crm__account') — backward compat.
|
|
180
182
|
*/
|
|
181
|
-
|
|
183
|
+
getObject(name: string): ServiceObject | undefined;
|
|
182
184
|
/**
|
|
183
185
|
* Get all registered objects (merged).
|
|
184
186
|
*
|
|
185
187
|
* @param packageId - Optional filter: only objects contributed by this package
|
|
186
188
|
*/
|
|
187
|
-
|
|
189
|
+
getAllObjects(packageId?: string): ServiceObject[];
|
|
188
190
|
/**
|
|
189
191
|
* Get all contributors for an object.
|
|
190
192
|
*/
|
|
191
|
-
|
|
193
|
+
getObjectContributors(fqn: string): ObjectContributor[];
|
|
192
194
|
/**
|
|
193
195
|
* Get the owner contributor for an object.
|
|
194
196
|
*/
|
|
195
|
-
|
|
197
|
+
getObjectOwner(fqn: string): ObjectContributor | undefined;
|
|
196
198
|
/**
|
|
197
199
|
* Unregister all objects contributed by a package.
|
|
198
200
|
*
|
|
199
201
|
* @throws Error if trying to uninstall an owner that has extenders
|
|
200
202
|
*/
|
|
201
|
-
|
|
203
|
+
unregisterObjectsByPackage(packageId: string, force?: boolean): void;
|
|
202
204
|
/**
|
|
203
205
|
* Universal Register Method for non-object metadata.
|
|
204
206
|
*/
|
|
205
|
-
|
|
207
|
+
registerItem<T>(type: string, item: T, keyField?: keyof T, packageId?: string): void;
|
|
206
208
|
/**
|
|
207
209
|
* Validate Metadata against Spec Zod Schemas
|
|
208
210
|
*/
|
|
209
|
-
|
|
210
|
-
name: string;
|
|
211
|
-
active: boolean;
|
|
212
|
-
isSystem: boolean;
|
|
213
|
-
abstract: boolean;
|
|
214
|
-
datasource: string;
|
|
215
|
-
fields: Record<string, {
|
|
216
|
-
type: "number" | "boolean" | "tags" | "date" | "lookup" | "file" | "url" | "json" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "datetime" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "location" | "address" | "code" | "color" | "rating" | "slider" | "signature" | "qrcode" | "progress" | "vector";
|
|
217
|
-
required: boolean;
|
|
218
|
-
searchable: boolean;
|
|
219
|
-
multiple: boolean;
|
|
220
|
-
unique: boolean;
|
|
221
|
-
deleteBehavior: "set_null" | "cascade" | "restrict";
|
|
222
|
-
auditTrail: boolean;
|
|
223
|
-
hidden: boolean;
|
|
224
|
-
readonly: boolean;
|
|
225
|
-
sortable: boolean;
|
|
226
|
-
index: boolean;
|
|
227
|
-
externalId: boolean;
|
|
228
|
-
name?: string | undefined;
|
|
229
|
-
label?: string | undefined;
|
|
230
|
-
description?: string | undefined;
|
|
231
|
-
format?: string | undefined;
|
|
232
|
-
columnName?: string | undefined;
|
|
233
|
-
defaultValue?: unknown;
|
|
234
|
-
maxLength?: number | undefined;
|
|
235
|
-
minLength?: number | undefined;
|
|
236
|
-
precision?: number | undefined;
|
|
237
|
-
scale?: number | undefined;
|
|
238
|
-
min?: number | undefined;
|
|
239
|
-
max?: number | undefined;
|
|
240
|
-
options?: {
|
|
241
|
-
label: string;
|
|
242
|
-
value: string;
|
|
243
|
-
color?: string | undefined;
|
|
244
|
-
default?: boolean | undefined;
|
|
245
|
-
}[] | undefined;
|
|
246
|
-
reference?: string | undefined;
|
|
247
|
-
referenceFilters?: string[] | undefined;
|
|
248
|
-
writeRequiresMasterRead?: boolean | undefined;
|
|
249
|
-
expression?: string | undefined;
|
|
250
|
-
summaryOperations?: {
|
|
251
|
-
object: string;
|
|
252
|
-
field: string;
|
|
253
|
-
function: "min" | "max" | "count" | "sum" | "avg";
|
|
254
|
-
} | undefined;
|
|
255
|
-
language?: string | undefined;
|
|
256
|
-
theme?: string | undefined;
|
|
257
|
-
lineNumbers?: boolean | undefined;
|
|
258
|
-
maxRating?: number | undefined;
|
|
259
|
-
allowHalf?: boolean | undefined;
|
|
260
|
-
displayMap?: boolean | undefined;
|
|
261
|
-
allowGeocoding?: boolean | undefined;
|
|
262
|
-
addressFormat?: "us" | "uk" | "international" | undefined;
|
|
263
|
-
colorFormat?: "hex" | "rgb" | "rgba" | "hsl" | undefined;
|
|
264
|
-
allowAlpha?: boolean | undefined;
|
|
265
|
-
presetColors?: string[] | undefined;
|
|
266
|
-
step?: number | undefined;
|
|
267
|
-
showValue?: boolean | undefined;
|
|
268
|
-
marks?: Record<string, string> | undefined;
|
|
269
|
-
barcodeFormat?: "qr" | "ean13" | "ean8" | "code128" | "code39" | "upca" | "upce" | undefined;
|
|
270
|
-
qrErrorCorrection?: "L" | "M" | "Q" | "H" | undefined;
|
|
271
|
-
displayValue?: boolean | undefined;
|
|
272
|
-
allowScanning?: boolean | undefined;
|
|
273
|
-
currencyConfig?: {
|
|
274
|
-
precision: number;
|
|
275
|
-
currencyMode: "dynamic" | "fixed";
|
|
276
|
-
defaultCurrency: string;
|
|
277
|
-
} | undefined;
|
|
278
|
-
vectorConfig?: {
|
|
279
|
-
dimensions: number;
|
|
280
|
-
distanceMetric: "cosine" | "euclidean" | "dotProduct" | "manhattan";
|
|
281
|
-
normalized: boolean;
|
|
282
|
-
indexed: boolean;
|
|
283
|
-
indexType?: "hnsw" | "ivfflat" | "flat" | undefined;
|
|
284
|
-
} | undefined;
|
|
285
|
-
fileAttachmentConfig?: {
|
|
286
|
-
virusScan: boolean;
|
|
287
|
-
virusScanOnUpload: boolean;
|
|
288
|
-
quarantineOnThreat: boolean;
|
|
289
|
-
allowMultiple: boolean;
|
|
290
|
-
allowReplace: boolean;
|
|
291
|
-
allowDelete: boolean;
|
|
292
|
-
requireUpload: boolean;
|
|
293
|
-
extractMetadata: boolean;
|
|
294
|
-
extractText: boolean;
|
|
295
|
-
versioningEnabled: boolean;
|
|
296
|
-
publicRead: boolean;
|
|
297
|
-
presignedUrlExpiry: number;
|
|
298
|
-
minSize?: number | undefined;
|
|
299
|
-
maxSize?: number | undefined;
|
|
300
|
-
allowedTypes?: string[] | undefined;
|
|
301
|
-
blockedTypes?: string[] | undefined;
|
|
302
|
-
allowedMimeTypes?: string[] | undefined;
|
|
303
|
-
blockedMimeTypes?: string[] | undefined;
|
|
304
|
-
virusScanProvider?: "custom" | "clamav" | "virustotal" | "metadefender" | undefined;
|
|
305
|
-
storageProvider?: string | undefined;
|
|
306
|
-
storageBucket?: string | undefined;
|
|
307
|
-
storagePrefix?: string | undefined;
|
|
308
|
-
imageValidation?: {
|
|
309
|
-
generateThumbnails: boolean;
|
|
310
|
-
preserveMetadata: boolean;
|
|
311
|
-
autoRotate: boolean;
|
|
312
|
-
minWidth?: number | undefined;
|
|
313
|
-
maxWidth?: number | undefined;
|
|
314
|
-
minHeight?: number | undefined;
|
|
315
|
-
maxHeight?: number | undefined;
|
|
316
|
-
aspectRatio?: string | undefined;
|
|
317
|
-
thumbnailSizes?: {
|
|
318
|
-
name: string;
|
|
319
|
-
width: number;
|
|
320
|
-
height: number;
|
|
321
|
-
crop: boolean;
|
|
322
|
-
}[] | undefined;
|
|
323
|
-
} | undefined;
|
|
324
|
-
maxVersions?: number | undefined;
|
|
325
|
-
} | undefined;
|
|
326
|
-
encryptionConfig?: {
|
|
327
|
-
enabled: boolean;
|
|
328
|
-
algorithm: "aes-256-gcm" | "aes-256-cbc" | "chacha20-poly1305";
|
|
329
|
-
keyManagement: {
|
|
330
|
-
provider: "local" | "aws-kms" | "azure-key-vault" | "gcp-kms" | "hashicorp-vault";
|
|
331
|
-
keyId?: string | undefined;
|
|
332
|
-
rotationPolicy?: {
|
|
333
|
-
enabled: boolean;
|
|
334
|
-
frequencyDays: number;
|
|
335
|
-
retainOldVersions: number;
|
|
336
|
-
autoRotate: boolean;
|
|
337
|
-
} | undefined;
|
|
338
|
-
};
|
|
339
|
-
scope: "field" | "table" | "record" | "database";
|
|
340
|
-
deterministicEncryption: boolean;
|
|
341
|
-
searchableEncryption: boolean;
|
|
342
|
-
} | undefined;
|
|
343
|
-
maskingRule?: {
|
|
344
|
-
field: string;
|
|
345
|
-
strategy: "redact" | "partial" | "hash" | "tokenize" | "randomize" | "nullify" | "substitute";
|
|
346
|
-
preserveFormat: boolean;
|
|
347
|
-
preserveLength: boolean;
|
|
348
|
-
pattern?: string | undefined;
|
|
349
|
-
roles?: string[] | undefined;
|
|
350
|
-
exemptRoles?: string[] | undefined;
|
|
351
|
-
} | undefined;
|
|
352
|
-
dependencies?: string[] | undefined;
|
|
353
|
-
cached?: {
|
|
354
|
-
enabled: boolean;
|
|
355
|
-
ttl: number;
|
|
356
|
-
invalidateOn: string[];
|
|
357
|
-
} | undefined;
|
|
358
|
-
dataQuality?: {
|
|
359
|
-
uniqueness: boolean;
|
|
360
|
-
completeness: number;
|
|
361
|
-
accuracy?: {
|
|
362
|
-
source: string;
|
|
363
|
-
threshold: number;
|
|
364
|
-
} | undefined;
|
|
365
|
-
} | undefined;
|
|
366
|
-
group?: string | undefined;
|
|
367
|
-
conditionalRequired?: string | undefined;
|
|
368
|
-
inlineHelpText?: string | undefined;
|
|
369
|
-
trackFeedHistory?: boolean | undefined;
|
|
370
|
-
caseSensitive?: boolean | undefined;
|
|
371
|
-
autonumberFormat?: string | undefined;
|
|
372
|
-
}>;
|
|
373
|
-
label?: string | undefined;
|
|
374
|
-
pluralLabel?: string | undefined;
|
|
375
|
-
description?: string | undefined;
|
|
376
|
-
icon?: string | undefined;
|
|
377
|
-
namespace?: string | undefined;
|
|
378
|
-
tags?: string[] | undefined;
|
|
379
|
-
tableName?: string | undefined;
|
|
380
|
-
indexes?: {
|
|
381
|
-
fields: string[];
|
|
382
|
-
type: "hash" | "btree" | "gin" | "gist" | "fulltext";
|
|
383
|
-
unique: boolean;
|
|
384
|
-
name?: string | undefined;
|
|
385
|
-
partial?: string | undefined;
|
|
386
|
-
}[] | undefined;
|
|
387
|
-
tenancy?: {
|
|
388
|
-
enabled: boolean;
|
|
389
|
-
strategy: "shared" | "isolated" | "hybrid";
|
|
390
|
-
tenantField: string;
|
|
391
|
-
crossTenantAccess: boolean;
|
|
392
|
-
} | undefined;
|
|
393
|
-
softDelete?: {
|
|
394
|
-
enabled: boolean;
|
|
395
|
-
field: string;
|
|
396
|
-
cascadeDelete: boolean;
|
|
397
|
-
} | undefined;
|
|
398
|
-
versioning?: {
|
|
399
|
-
enabled: boolean;
|
|
400
|
-
strategy: "snapshot" | "delta" | "event-sourcing";
|
|
401
|
-
versionField: string;
|
|
402
|
-
retentionDays?: number | undefined;
|
|
403
|
-
} | undefined;
|
|
404
|
-
partitioning?: {
|
|
405
|
-
enabled: boolean;
|
|
406
|
-
strategy: "hash" | "range" | "list";
|
|
407
|
-
key: string;
|
|
408
|
-
interval?: string | undefined;
|
|
409
|
-
} | undefined;
|
|
410
|
-
cdc?: {
|
|
411
|
-
enabled: boolean;
|
|
412
|
-
events: ("update" | "delete" | "insert")[];
|
|
413
|
-
destination: string;
|
|
414
|
-
} | undefined;
|
|
415
|
-
validations?: _objectstack_spec_data.BaseValidationRuleShape[] | undefined;
|
|
416
|
-
stateMachines?: Record<string, {
|
|
417
|
-
id: string;
|
|
418
|
-
initial: string;
|
|
419
|
-
states: Record<string, StateNodeConfig>;
|
|
420
|
-
description?: string | undefined;
|
|
421
|
-
contextSchema?: Record<string, unknown> | undefined;
|
|
422
|
-
on?: Record<string, string | {
|
|
423
|
-
target?: string | undefined;
|
|
424
|
-
cond?: string | {
|
|
425
|
-
type: string;
|
|
426
|
-
params?: Record<string, unknown> | undefined;
|
|
427
|
-
} | undefined;
|
|
428
|
-
actions?: (string | {
|
|
429
|
-
type: string;
|
|
430
|
-
params?: Record<string, unknown> | undefined;
|
|
431
|
-
})[] | undefined;
|
|
432
|
-
description?: string | undefined;
|
|
433
|
-
} | {
|
|
434
|
-
target?: string | undefined;
|
|
435
|
-
cond?: string | {
|
|
436
|
-
type: string;
|
|
437
|
-
params?: Record<string, unknown> | undefined;
|
|
438
|
-
} | undefined;
|
|
439
|
-
actions?: (string | {
|
|
440
|
-
type: string;
|
|
441
|
-
params?: Record<string, unknown> | undefined;
|
|
442
|
-
})[] | undefined;
|
|
443
|
-
description?: string | undefined;
|
|
444
|
-
}[]> | undefined;
|
|
445
|
-
}> | undefined;
|
|
446
|
-
displayNameField?: string | undefined;
|
|
447
|
-
recordName?: {
|
|
448
|
-
type: "text" | "autonumber";
|
|
449
|
-
displayFormat?: string | undefined;
|
|
450
|
-
startNumber?: number | undefined;
|
|
451
|
-
} | undefined;
|
|
452
|
-
titleFormat?: string | undefined;
|
|
453
|
-
compactLayout?: string[] | undefined;
|
|
454
|
-
search?: {
|
|
455
|
-
fields: string[];
|
|
456
|
-
displayFields?: string[] | undefined;
|
|
457
|
-
filters?: string[] | undefined;
|
|
458
|
-
} | undefined;
|
|
459
|
-
enable?: {
|
|
460
|
-
trackHistory: boolean;
|
|
461
|
-
searchable: boolean;
|
|
462
|
-
apiEnabled: boolean;
|
|
463
|
-
files: boolean;
|
|
464
|
-
feeds: boolean;
|
|
465
|
-
activities: boolean;
|
|
466
|
-
trash: boolean;
|
|
467
|
-
mru: boolean;
|
|
468
|
-
clone: boolean;
|
|
469
|
-
apiMethods?: ("search" | "list" | "update" | "delete" | "upsert" | "history" | "get" | "create" | "bulk" | "aggregate" | "restore" | "purge" | "import" | "export")[] | undefined;
|
|
470
|
-
} | undefined;
|
|
471
|
-
recordTypes?: string[] | undefined;
|
|
472
|
-
sharingModel?: "full" | "private" | "read" | "read_write" | undefined;
|
|
473
|
-
keyPrefix?: string | undefined;
|
|
474
|
-
actions?: {
|
|
475
|
-
name: string;
|
|
476
|
-
label: string;
|
|
477
|
-
type: "url" | "flow" | "api" | "script" | "modal";
|
|
478
|
-
refreshAfter: boolean;
|
|
479
|
-
objectName?: string | undefined;
|
|
480
|
-
icon?: string | undefined;
|
|
481
|
-
locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "global_nav")[] | undefined;
|
|
482
|
-
component?: "action:button" | "action:icon" | "action:menu" | "action:group" | undefined;
|
|
483
|
-
target?: string | undefined;
|
|
484
|
-
execute?: string | undefined;
|
|
485
|
-
params?: {
|
|
486
|
-
name: string;
|
|
487
|
-
label: string;
|
|
488
|
-
type: "number" | "boolean" | "date" | "lookup" | "file" | "url" | "json" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "datetime" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "location" | "address" | "code" | "color" | "rating" | "slider" | "signature" | "qrcode" | "progress" | "tags" | "vector";
|
|
489
|
-
required: boolean;
|
|
490
|
-
options?: {
|
|
491
|
-
label: string;
|
|
492
|
-
value: string;
|
|
493
|
-
}[] | undefined;
|
|
494
|
-
}[] | undefined;
|
|
495
|
-
variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | undefined;
|
|
496
|
-
confirmText?: string | undefined;
|
|
497
|
-
successMessage?: string | undefined;
|
|
498
|
-
visible?: string | undefined;
|
|
499
|
-
disabled?: string | boolean | undefined;
|
|
500
|
-
shortcut?: string | undefined;
|
|
501
|
-
bulkEnabled?: boolean | undefined;
|
|
502
|
-
timeout?: number | undefined;
|
|
503
|
-
aria?: {
|
|
504
|
-
ariaLabel?: string | undefined;
|
|
505
|
-
ariaDescribedBy?: string | undefined;
|
|
506
|
-
role?: string | undefined;
|
|
507
|
-
} | undefined;
|
|
508
|
-
}[] | undefined;
|
|
509
|
-
} | {
|
|
510
|
-
name: string;
|
|
511
|
-
label: string;
|
|
512
|
-
active: boolean;
|
|
513
|
-
isDefault: boolean;
|
|
514
|
-
version?: string | undefined;
|
|
515
|
-
description?: string | undefined;
|
|
516
|
-
icon?: string | undefined;
|
|
517
|
-
branding?: {
|
|
518
|
-
primaryColor?: string | undefined;
|
|
519
|
-
logo?: string | undefined;
|
|
520
|
-
favicon?: string | undefined;
|
|
521
|
-
} | undefined;
|
|
522
|
-
navigation?: any[] | undefined;
|
|
523
|
-
areas?: {
|
|
524
|
-
id: string;
|
|
525
|
-
label: string;
|
|
526
|
-
navigation: any[];
|
|
527
|
-
icon?: string | undefined;
|
|
528
|
-
order?: number | undefined;
|
|
529
|
-
description?: string | undefined;
|
|
530
|
-
visible?: string | undefined;
|
|
531
|
-
requiredPermissions?: string[] | undefined;
|
|
532
|
-
}[] | undefined;
|
|
533
|
-
homePageId?: string | undefined;
|
|
534
|
-
requiredPermissions?: string[] | undefined;
|
|
535
|
-
objects?: unknown[] | undefined;
|
|
536
|
-
apis?: unknown[] | undefined;
|
|
537
|
-
sharing?: {
|
|
538
|
-
enabled: boolean;
|
|
539
|
-
allowAnonymous: boolean;
|
|
540
|
-
publicLink?: string | undefined;
|
|
541
|
-
password?: string | undefined;
|
|
542
|
-
allowedDomains?: string[] | undefined;
|
|
543
|
-
expiresAt?: string | undefined;
|
|
544
|
-
} | undefined;
|
|
545
|
-
embed?: {
|
|
546
|
-
enabled: boolean;
|
|
547
|
-
width: string;
|
|
548
|
-
height: string;
|
|
549
|
-
showHeader: boolean;
|
|
550
|
-
showNavigation: boolean;
|
|
551
|
-
responsive: boolean;
|
|
552
|
-
allowedOrigins?: string[] | undefined;
|
|
553
|
-
} | undefined;
|
|
554
|
-
mobileNavigation?: {
|
|
555
|
-
mode: "drawer" | "bottom_nav" | "hamburger";
|
|
556
|
-
bottomNavItems?: string[] | undefined;
|
|
557
|
-
} | undefined;
|
|
558
|
-
aria?: {
|
|
559
|
-
ariaLabel?: string | undefined;
|
|
560
|
-
ariaDescribedBy?: string | undefined;
|
|
561
|
-
role?: string | undefined;
|
|
562
|
-
} | undefined;
|
|
563
|
-
} | {
|
|
564
|
-
manifest: {
|
|
565
|
-
id: string;
|
|
566
|
-
defaultDatasource: string;
|
|
567
|
-
version: string;
|
|
568
|
-
type: "theme" | "app" | "agent" | "driver" | "server" | "ui" | "module" | "objectql" | "plugin" | "gateway" | "adapter";
|
|
569
|
-
name: string;
|
|
570
|
-
namespace?: string | undefined;
|
|
571
|
-
description?: string | undefined;
|
|
572
|
-
permissions?: string[] | undefined;
|
|
573
|
-
objects?: string[] | undefined;
|
|
574
|
-
datasources?: string[] | undefined;
|
|
575
|
-
dependencies?: Record<string, string> | undefined;
|
|
576
|
-
configuration?: {
|
|
577
|
-
properties: Record<string, {
|
|
578
|
-
type: "string" | "number" | "boolean" | "object" | "array";
|
|
579
|
-
default?: unknown;
|
|
580
|
-
description?: string | undefined;
|
|
581
|
-
required?: boolean | undefined;
|
|
582
|
-
secret?: boolean | undefined;
|
|
583
|
-
enum?: string[] | undefined;
|
|
584
|
-
}>;
|
|
585
|
-
title?: string | undefined;
|
|
586
|
-
} | undefined;
|
|
587
|
-
contributes?: {
|
|
588
|
-
kinds?: {
|
|
589
|
-
id: string;
|
|
590
|
-
globs: string[];
|
|
591
|
-
description?: string | undefined;
|
|
592
|
-
}[] | undefined;
|
|
593
|
-
events?: string[] | undefined;
|
|
594
|
-
menus?: Record<string, {
|
|
595
|
-
id: string;
|
|
596
|
-
label: string;
|
|
597
|
-
command?: string | undefined;
|
|
598
|
-
}[]> | undefined;
|
|
599
|
-
themes?: {
|
|
600
|
-
id: string;
|
|
601
|
-
label: string;
|
|
602
|
-
path: string;
|
|
603
|
-
}[] | undefined;
|
|
604
|
-
translations?: {
|
|
605
|
-
locale: string;
|
|
606
|
-
path: string;
|
|
607
|
-
}[] | undefined;
|
|
608
|
-
actions?: {
|
|
609
|
-
name: string;
|
|
610
|
-
label?: string | undefined;
|
|
611
|
-
description?: string | undefined;
|
|
612
|
-
input?: unknown;
|
|
613
|
-
output?: unknown;
|
|
614
|
-
}[] | undefined;
|
|
615
|
-
drivers?: {
|
|
616
|
-
id: string;
|
|
617
|
-
label: string;
|
|
618
|
-
description?: string | undefined;
|
|
619
|
-
}[] | undefined;
|
|
620
|
-
fieldTypes?: {
|
|
621
|
-
name: string;
|
|
622
|
-
label: string;
|
|
623
|
-
description?: string | undefined;
|
|
624
|
-
}[] | undefined;
|
|
625
|
-
functions?: {
|
|
626
|
-
name: string;
|
|
627
|
-
description?: string | undefined;
|
|
628
|
-
args?: string[] | undefined;
|
|
629
|
-
returnType?: string | undefined;
|
|
630
|
-
}[] | undefined;
|
|
631
|
-
routes?: {
|
|
632
|
-
prefix: string;
|
|
633
|
-
service: string;
|
|
634
|
-
methods?: string[] | undefined;
|
|
635
|
-
}[] | undefined;
|
|
636
|
-
commands?: {
|
|
637
|
-
name: string;
|
|
638
|
-
description?: string | undefined;
|
|
639
|
-
module?: string | undefined;
|
|
640
|
-
}[] | undefined;
|
|
641
|
-
} | undefined;
|
|
642
|
-
data?: {
|
|
643
|
-
object: string;
|
|
644
|
-
externalId: string;
|
|
645
|
-
mode: "update" | "upsert" | "insert" | "replace" | "ignore";
|
|
646
|
-
env: ("prod" | "dev" | "test")[];
|
|
647
|
-
records: Record<string, unknown>[];
|
|
648
|
-
}[] | undefined;
|
|
649
|
-
capabilities?: {
|
|
650
|
-
implements?: {
|
|
651
|
-
protocol: {
|
|
652
|
-
id: string;
|
|
653
|
-
label: string;
|
|
654
|
-
version: {
|
|
655
|
-
major: number;
|
|
656
|
-
minor: number;
|
|
657
|
-
patch: number;
|
|
658
|
-
};
|
|
659
|
-
specification?: string | undefined;
|
|
660
|
-
description?: string | undefined;
|
|
661
|
-
};
|
|
662
|
-
conformance: "partial" | "full" | "deprecated" | "experimental";
|
|
663
|
-
certified: boolean;
|
|
664
|
-
implementedFeatures?: string[] | undefined;
|
|
665
|
-
features?: {
|
|
666
|
-
name: string;
|
|
667
|
-
enabled: boolean;
|
|
668
|
-
description?: string | undefined;
|
|
669
|
-
sinceVersion?: string | undefined;
|
|
670
|
-
deprecatedSince?: string | undefined;
|
|
671
|
-
}[] | undefined;
|
|
672
|
-
metadata?: Record<string, unknown> | undefined;
|
|
673
|
-
certificationDate?: string | undefined;
|
|
674
|
-
}[] | undefined;
|
|
675
|
-
provides?: {
|
|
676
|
-
id: string;
|
|
677
|
-
name: string;
|
|
678
|
-
version: {
|
|
679
|
-
major: number;
|
|
680
|
-
minor: number;
|
|
681
|
-
patch: number;
|
|
682
|
-
};
|
|
683
|
-
methods: {
|
|
684
|
-
name: string;
|
|
685
|
-
async: boolean;
|
|
686
|
-
description?: string | undefined;
|
|
687
|
-
parameters?: {
|
|
688
|
-
name: string;
|
|
689
|
-
type: string;
|
|
690
|
-
required: boolean;
|
|
691
|
-
description?: string | undefined;
|
|
692
|
-
}[] | undefined;
|
|
693
|
-
returnType?: string | undefined;
|
|
694
|
-
}[];
|
|
695
|
-
stability: "experimental" | "alpha" | "stable" | "beta";
|
|
696
|
-
description?: string | undefined;
|
|
697
|
-
events?: {
|
|
698
|
-
name: string;
|
|
699
|
-
description?: string | undefined;
|
|
700
|
-
payload?: string | undefined;
|
|
701
|
-
}[] | undefined;
|
|
702
|
-
}[] | undefined;
|
|
703
|
-
requires?: {
|
|
704
|
-
pluginId: string;
|
|
705
|
-
version: string;
|
|
706
|
-
optional: boolean;
|
|
707
|
-
reason?: string | undefined;
|
|
708
|
-
requiredCapabilities?: string[] | undefined;
|
|
709
|
-
}[] | undefined;
|
|
710
|
-
extensionPoints?: {
|
|
711
|
-
id: string;
|
|
712
|
-
name: string;
|
|
713
|
-
type: "provider" | "action" | "hook" | "widget" | "transformer" | "validator" | "decorator";
|
|
714
|
-
cardinality: "multiple" | "single";
|
|
715
|
-
description?: string | undefined;
|
|
716
|
-
contract?: {
|
|
717
|
-
input?: string | undefined;
|
|
718
|
-
output?: string | undefined;
|
|
719
|
-
signature?: string | undefined;
|
|
720
|
-
} | undefined;
|
|
721
|
-
}[] | undefined;
|
|
722
|
-
extensions?: {
|
|
723
|
-
targetPluginId: string;
|
|
724
|
-
extensionPointId: string;
|
|
725
|
-
implementation: string;
|
|
726
|
-
priority: number;
|
|
727
|
-
}[] | undefined;
|
|
728
|
-
} | undefined;
|
|
729
|
-
extensions?: Record<string, unknown> | undefined;
|
|
730
|
-
loading?: {
|
|
731
|
-
strategy: "lazy" | "parallel" | "eager" | "deferred" | "on-demand";
|
|
732
|
-
preload?: {
|
|
733
|
-
enabled: boolean;
|
|
734
|
-
priority: number;
|
|
735
|
-
resources?: ("dependencies" | "code" | "metadata" | "assets" | "services")[] | undefined;
|
|
736
|
-
conditions?: {
|
|
737
|
-
routes?: string[] | undefined;
|
|
738
|
-
roles?: string[] | undefined;
|
|
739
|
-
deviceType?: ("desktop" | "mobile" | "tablet")[] | undefined;
|
|
740
|
-
minNetworkSpeed?: "slow-2g" | "2g" | "3g" | "4g" | undefined;
|
|
741
|
-
} | undefined;
|
|
742
|
-
} | undefined;
|
|
743
|
-
codeSplitting?: {
|
|
744
|
-
enabled: boolean;
|
|
745
|
-
strategy: "custom" | "size" | "route" | "feature";
|
|
746
|
-
chunkNaming: "hashed" | "sequential" | "named";
|
|
747
|
-
maxChunkSize?: number | undefined;
|
|
748
|
-
sharedDependencies?: {
|
|
749
|
-
enabled: boolean;
|
|
750
|
-
minChunks: number;
|
|
751
|
-
} | undefined;
|
|
752
|
-
} | undefined;
|
|
753
|
-
dynamicImport?: {
|
|
754
|
-
enabled: boolean;
|
|
755
|
-
mode: "lazy" | "eager" | "async" | "sync";
|
|
756
|
-
prefetch: boolean;
|
|
757
|
-
preload: boolean;
|
|
758
|
-
timeout: number;
|
|
759
|
-
webpackChunkName?: string | undefined;
|
|
760
|
-
retry?: {
|
|
761
|
-
enabled: boolean;
|
|
762
|
-
maxAttempts: number;
|
|
763
|
-
backoffMs: number;
|
|
764
|
-
} | undefined;
|
|
765
|
-
} | undefined;
|
|
766
|
-
initialization?: {
|
|
767
|
-
mode: "parallel" | "sequential" | "async" | "sync";
|
|
768
|
-
timeout: number;
|
|
769
|
-
priority: number;
|
|
770
|
-
critical: boolean;
|
|
771
|
-
retry?: {
|
|
772
|
-
enabled: boolean;
|
|
773
|
-
maxAttempts: number;
|
|
774
|
-
backoffMs: number;
|
|
775
|
-
} | undefined;
|
|
776
|
-
healthCheckInterval?: number | undefined;
|
|
777
|
-
} | undefined;
|
|
778
|
-
dependencyResolution?: {
|
|
779
|
-
strategy: "strict" | "pinned" | "latest" | "compatible";
|
|
780
|
-
conflictResolution: "latest" | "manual" | "fail" | "oldest";
|
|
781
|
-
circularDependencies: "warn" | "error" | "allow";
|
|
782
|
-
peerDependencies?: {
|
|
783
|
-
resolve: boolean;
|
|
784
|
-
onMissing: "warn" | "error" | "ignore";
|
|
785
|
-
onMismatch: "warn" | "error" | "ignore";
|
|
786
|
-
} | undefined;
|
|
787
|
-
optionalDependencies?: {
|
|
788
|
-
load: boolean;
|
|
789
|
-
onFailure: "warn" | "ignore";
|
|
790
|
-
} | undefined;
|
|
791
|
-
} | undefined;
|
|
792
|
-
hotReload?: {
|
|
793
|
-
enabled: boolean;
|
|
794
|
-
environment: "development" | "production" | "staging";
|
|
795
|
-
strategy: "partial" | "full" | "state-preserve";
|
|
796
|
-
debounceMs: number;
|
|
797
|
-
preserveState: boolean;
|
|
798
|
-
watchPatterns?: string[] | undefined;
|
|
799
|
-
ignorePatterns?: string[] | undefined;
|
|
800
|
-
stateSerialization?: {
|
|
801
|
-
enabled: boolean;
|
|
802
|
-
handler?: string | undefined;
|
|
803
|
-
} | undefined;
|
|
804
|
-
hooks?: {
|
|
805
|
-
beforeReload?: string | undefined;
|
|
806
|
-
afterReload?: string | undefined;
|
|
807
|
-
onError?: string | undefined;
|
|
808
|
-
} | undefined;
|
|
809
|
-
productionSafety?: {
|
|
810
|
-
healthValidation: boolean;
|
|
811
|
-
rollbackOnFailure: boolean;
|
|
812
|
-
healthTimeout: number;
|
|
813
|
-
drainConnections: boolean;
|
|
814
|
-
drainTimeout: number;
|
|
815
|
-
maxConcurrentReloads: number;
|
|
816
|
-
minReloadInterval: number;
|
|
817
|
-
} | undefined;
|
|
818
|
-
} | undefined;
|
|
819
|
-
caching?: {
|
|
820
|
-
enabled: boolean;
|
|
821
|
-
storage: "hybrid" | "indexeddb" | "memory" | "disk";
|
|
822
|
-
keyStrategy: "hash" | "version" | "timestamp";
|
|
823
|
-
ttl?: number | undefined;
|
|
824
|
-
maxSize?: number | undefined;
|
|
825
|
-
invalidateOn?: ("error" | "manual" | "version-change" | "dependency-change")[] | undefined;
|
|
826
|
-
compression?: {
|
|
827
|
-
enabled: boolean;
|
|
828
|
-
algorithm: "gzip" | "brotli" | "deflate";
|
|
829
|
-
} | undefined;
|
|
830
|
-
} | undefined;
|
|
831
|
-
sandboxing?: {
|
|
832
|
-
enabled: boolean;
|
|
833
|
-
scope: "automation-only" | "untrusted-only" | "all-plugins";
|
|
834
|
-
isolationLevel: "none" | "process" | "vm" | "iframe" | "web-worker";
|
|
835
|
-
allowedCapabilities?: string[] | undefined;
|
|
836
|
-
resourceQuotas?: {
|
|
837
|
-
maxMemoryMB?: number | undefined;
|
|
838
|
-
maxCpuTimeMs?: number | undefined;
|
|
839
|
-
maxFileDescriptors?: number | undefined;
|
|
840
|
-
maxNetworkKBps?: number | undefined;
|
|
841
|
-
} | undefined;
|
|
842
|
-
permissions?: {
|
|
843
|
-
allowedAPIs?: string[] | undefined;
|
|
844
|
-
allowedPaths?: string[] | undefined;
|
|
845
|
-
allowedEndpoints?: string[] | undefined;
|
|
846
|
-
allowedEnvVars?: string[] | undefined;
|
|
847
|
-
} | undefined;
|
|
848
|
-
ipc?: {
|
|
849
|
-
enabled: boolean;
|
|
850
|
-
transport: "memory" | "message-port" | "unix-socket" | "tcp";
|
|
851
|
-
maxMessageSize: number;
|
|
852
|
-
timeout: number;
|
|
853
|
-
allowedServices?: string[] | undefined;
|
|
854
|
-
} | undefined;
|
|
855
|
-
} | undefined;
|
|
856
|
-
monitoring?: {
|
|
857
|
-
enabled: boolean;
|
|
858
|
-
samplingRate: number;
|
|
859
|
-
reportingInterval: number;
|
|
860
|
-
onBudgetViolation: "warn" | "error" | "ignore";
|
|
861
|
-
metrics?: ("load-time" | "init-time" | "memory-usage" | "cpu-usage" | "api-calls" | "error-rate" | "cache-hit-rate")[] | undefined;
|
|
862
|
-
budgets?: {
|
|
863
|
-
maxLoadTimeMs?: number | undefined;
|
|
864
|
-
maxInitTimeMs?: number | undefined;
|
|
865
|
-
maxMemoryMB?: number | undefined;
|
|
866
|
-
} | undefined;
|
|
867
|
-
} | undefined;
|
|
868
|
-
} | undefined;
|
|
869
|
-
engine?: {
|
|
870
|
-
objectstack: string;
|
|
871
|
-
} | undefined;
|
|
872
|
-
};
|
|
873
|
-
status: "disabled" | "error" | "installed" | "installing" | "upgrading" | "uninstalling";
|
|
874
|
-
enabled: boolean;
|
|
875
|
-
installedAt?: string | undefined;
|
|
876
|
-
updatedAt?: string | undefined;
|
|
877
|
-
installedVersion?: string | undefined;
|
|
878
|
-
previousVersion?: string | undefined;
|
|
879
|
-
statusChangedAt?: string | undefined;
|
|
880
|
-
errorMessage?: string | undefined;
|
|
881
|
-
settings?: Record<string, unknown> | undefined;
|
|
882
|
-
upgradeHistory?: {
|
|
883
|
-
fromVersion: string;
|
|
884
|
-
toVersion: string;
|
|
885
|
-
upgradedAt: string;
|
|
886
|
-
status: "success" | "failed" | "rolled_back";
|
|
887
|
-
migrationLog?: string[] | undefined;
|
|
888
|
-
}[] | undefined;
|
|
889
|
-
registeredNamespaces?: string[] | undefined;
|
|
890
|
-
} | {
|
|
891
|
-
id: string;
|
|
892
|
-
defaultDatasource: string;
|
|
893
|
-
version: string;
|
|
894
|
-
type: "theme" | "app" | "agent" | "driver" | "server" | "ui" | "module" | "objectql" | "plugin" | "gateway" | "adapter";
|
|
895
|
-
name: string;
|
|
896
|
-
namespace?: string | undefined;
|
|
897
|
-
description?: string | undefined;
|
|
898
|
-
permissions?: string[] | undefined;
|
|
899
|
-
objects?: string[] | undefined;
|
|
900
|
-
datasources?: string[] | undefined;
|
|
901
|
-
dependencies?: Record<string, string> | undefined;
|
|
902
|
-
configuration?: {
|
|
903
|
-
properties: Record<string, {
|
|
904
|
-
type: "string" | "number" | "boolean" | "object" | "array";
|
|
905
|
-
default?: unknown;
|
|
906
|
-
description?: string | undefined;
|
|
907
|
-
required?: boolean | undefined;
|
|
908
|
-
secret?: boolean | undefined;
|
|
909
|
-
enum?: string[] | undefined;
|
|
910
|
-
}>;
|
|
911
|
-
title?: string | undefined;
|
|
912
|
-
} | undefined;
|
|
913
|
-
contributes?: {
|
|
914
|
-
kinds?: {
|
|
915
|
-
id: string;
|
|
916
|
-
globs: string[];
|
|
917
|
-
description?: string | undefined;
|
|
918
|
-
}[] | undefined;
|
|
919
|
-
events?: string[] | undefined;
|
|
920
|
-
menus?: Record<string, {
|
|
921
|
-
id: string;
|
|
922
|
-
label: string;
|
|
923
|
-
command?: string | undefined;
|
|
924
|
-
}[]> | undefined;
|
|
925
|
-
themes?: {
|
|
926
|
-
id: string;
|
|
927
|
-
label: string;
|
|
928
|
-
path: string;
|
|
929
|
-
}[] | undefined;
|
|
930
|
-
translations?: {
|
|
931
|
-
locale: string;
|
|
932
|
-
path: string;
|
|
933
|
-
}[] | undefined;
|
|
934
|
-
actions?: {
|
|
935
|
-
name: string;
|
|
936
|
-
label?: string | undefined;
|
|
937
|
-
description?: string | undefined;
|
|
938
|
-
input?: unknown;
|
|
939
|
-
output?: unknown;
|
|
940
|
-
}[] | undefined;
|
|
941
|
-
drivers?: {
|
|
942
|
-
id: string;
|
|
943
|
-
label: string;
|
|
944
|
-
description?: string | undefined;
|
|
945
|
-
}[] | undefined;
|
|
946
|
-
fieldTypes?: {
|
|
947
|
-
name: string;
|
|
948
|
-
label: string;
|
|
949
|
-
description?: string | undefined;
|
|
950
|
-
}[] | undefined;
|
|
951
|
-
functions?: {
|
|
952
|
-
name: string;
|
|
953
|
-
description?: string | undefined;
|
|
954
|
-
args?: string[] | undefined;
|
|
955
|
-
returnType?: string | undefined;
|
|
956
|
-
}[] | undefined;
|
|
957
|
-
routes?: {
|
|
958
|
-
prefix: string;
|
|
959
|
-
service: string;
|
|
960
|
-
methods?: string[] | undefined;
|
|
961
|
-
}[] | undefined;
|
|
962
|
-
commands?: {
|
|
963
|
-
name: string;
|
|
964
|
-
description?: string | undefined;
|
|
965
|
-
module?: string | undefined;
|
|
966
|
-
}[] | undefined;
|
|
967
|
-
} | undefined;
|
|
968
|
-
data?: {
|
|
969
|
-
object: string;
|
|
970
|
-
externalId: string;
|
|
971
|
-
mode: "update" | "upsert" | "insert" | "replace" | "ignore";
|
|
972
|
-
env: ("prod" | "dev" | "test")[];
|
|
973
|
-
records: Record<string, unknown>[];
|
|
974
|
-
}[] | undefined;
|
|
975
|
-
capabilities?: {
|
|
976
|
-
implements?: {
|
|
977
|
-
protocol: {
|
|
978
|
-
id: string;
|
|
979
|
-
label: string;
|
|
980
|
-
version: {
|
|
981
|
-
major: number;
|
|
982
|
-
minor: number;
|
|
983
|
-
patch: number;
|
|
984
|
-
};
|
|
985
|
-
specification?: string | undefined;
|
|
986
|
-
description?: string | undefined;
|
|
987
|
-
};
|
|
988
|
-
conformance: "partial" | "full" | "deprecated" | "experimental";
|
|
989
|
-
certified: boolean;
|
|
990
|
-
implementedFeatures?: string[] | undefined;
|
|
991
|
-
features?: {
|
|
992
|
-
name: string;
|
|
993
|
-
enabled: boolean;
|
|
994
|
-
description?: string | undefined;
|
|
995
|
-
sinceVersion?: string | undefined;
|
|
996
|
-
deprecatedSince?: string | undefined;
|
|
997
|
-
}[] | undefined;
|
|
998
|
-
metadata?: Record<string, unknown> | undefined;
|
|
999
|
-
certificationDate?: string | undefined;
|
|
1000
|
-
}[] | undefined;
|
|
1001
|
-
provides?: {
|
|
1002
|
-
id: string;
|
|
1003
|
-
name: string;
|
|
1004
|
-
version: {
|
|
1005
|
-
major: number;
|
|
1006
|
-
minor: number;
|
|
1007
|
-
patch: number;
|
|
1008
|
-
};
|
|
1009
|
-
methods: {
|
|
1010
|
-
name: string;
|
|
1011
|
-
async: boolean;
|
|
1012
|
-
description?: string | undefined;
|
|
1013
|
-
parameters?: {
|
|
1014
|
-
name: string;
|
|
1015
|
-
type: string;
|
|
1016
|
-
required: boolean;
|
|
1017
|
-
description?: string | undefined;
|
|
1018
|
-
}[] | undefined;
|
|
1019
|
-
returnType?: string | undefined;
|
|
1020
|
-
}[];
|
|
1021
|
-
stability: "experimental" | "alpha" | "stable" | "beta";
|
|
1022
|
-
description?: string | undefined;
|
|
1023
|
-
events?: {
|
|
1024
|
-
name: string;
|
|
1025
|
-
description?: string | undefined;
|
|
1026
|
-
payload?: string | undefined;
|
|
1027
|
-
}[] | undefined;
|
|
1028
|
-
}[] | undefined;
|
|
1029
|
-
requires?: {
|
|
1030
|
-
pluginId: string;
|
|
1031
|
-
version: string;
|
|
1032
|
-
optional: boolean;
|
|
1033
|
-
reason?: string | undefined;
|
|
1034
|
-
requiredCapabilities?: string[] | undefined;
|
|
1035
|
-
}[] | undefined;
|
|
1036
|
-
extensionPoints?: {
|
|
1037
|
-
id: string;
|
|
1038
|
-
name: string;
|
|
1039
|
-
type: "provider" | "action" | "hook" | "widget" | "transformer" | "validator" | "decorator";
|
|
1040
|
-
cardinality: "multiple" | "single";
|
|
1041
|
-
description?: string | undefined;
|
|
1042
|
-
contract?: {
|
|
1043
|
-
input?: string | undefined;
|
|
1044
|
-
output?: string | undefined;
|
|
1045
|
-
signature?: string | undefined;
|
|
1046
|
-
} | undefined;
|
|
1047
|
-
}[] | undefined;
|
|
1048
|
-
extensions?: {
|
|
1049
|
-
targetPluginId: string;
|
|
1050
|
-
extensionPointId: string;
|
|
1051
|
-
implementation: string;
|
|
1052
|
-
priority: number;
|
|
1053
|
-
}[] | undefined;
|
|
1054
|
-
} | undefined;
|
|
1055
|
-
extensions?: Record<string, unknown> | undefined;
|
|
1056
|
-
loading?: {
|
|
1057
|
-
strategy: "lazy" | "parallel" | "eager" | "deferred" | "on-demand";
|
|
1058
|
-
preload?: {
|
|
1059
|
-
enabled: boolean;
|
|
1060
|
-
priority: number;
|
|
1061
|
-
resources?: ("dependencies" | "code" | "metadata" | "assets" | "services")[] | undefined;
|
|
1062
|
-
conditions?: {
|
|
1063
|
-
routes?: string[] | undefined;
|
|
1064
|
-
roles?: string[] | undefined;
|
|
1065
|
-
deviceType?: ("desktop" | "mobile" | "tablet")[] | undefined;
|
|
1066
|
-
minNetworkSpeed?: "slow-2g" | "2g" | "3g" | "4g" | undefined;
|
|
1067
|
-
} | undefined;
|
|
1068
|
-
} | undefined;
|
|
1069
|
-
codeSplitting?: {
|
|
1070
|
-
enabled: boolean;
|
|
1071
|
-
strategy: "custom" | "size" | "route" | "feature";
|
|
1072
|
-
chunkNaming: "hashed" | "sequential" | "named";
|
|
1073
|
-
maxChunkSize?: number | undefined;
|
|
1074
|
-
sharedDependencies?: {
|
|
1075
|
-
enabled: boolean;
|
|
1076
|
-
minChunks: number;
|
|
1077
|
-
} | undefined;
|
|
1078
|
-
} | undefined;
|
|
1079
|
-
dynamicImport?: {
|
|
1080
|
-
enabled: boolean;
|
|
1081
|
-
mode: "lazy" | "eager" | "async" | "sync";
|
|
1082
|
-
prefetch: boolean;
|
|
1083
|
-
preload: boolean;
|
|
1084
|
-
timeout: number;
|
|
1085
|
-
webpackChunkName?: string | undefined;
|
|
1086
|
-
retry?: {
|
|
1087
|
-
enabled: boolean;
|
|
1088
|
-
maxAttempts: number;
|
|
1089
|
-
backoffMs: number;
|
|
1090
|
-
} | undefined;
|
|
1091
|
-
} | undefined;
|
|
1092
|
-
initialization?: {
|
|
1093
|
-
mode: "parallel" | "sequential" | "async" | "sync";
|
|
1094
|
-
timeout: number;
|
|
1095
|
-
priority: number;
|
|
1096
|
-
critical: boolean;
|
|
1097
|
-
retry?: {
|
|
1098
|
-
enabled: boolean;
|
|
1099
|
-
maxAttempts: number;
|
|
1100
|
-
backoffMs: number;
|
|
1101
|
-
} | undefined;
|
|
1102
|
-
healthCheckInterval?: number | undefined;
|
|
1103
|
-
} | undefined;
|
|
1104
|
-
dependencyResolution?: {
|
|
1105
|
-
strategy: "strict" | "pinned" | "latest" | "compatible";
|
|
1106
|
-
conflictResolution: "latest" | "manual" | "fail" | "oldest";
|
|
1107
|
-
circularDependencies: "warn" | "error" | "allow";
|
|
1108
|
-
peerDependencies?: {
|
|
1109
|
-
resolve: boolean;
|
|
1110
|
-
onMissing: "warn" | "error" | "ignore";
|
|
1111
|
-
onMismatch: "warn" | "error" | "ignore";
|
|
1112
|
-
} | undefined;
|
|
1113
|
-
optionalDependencies?: {
|
|
1114
|
-
load: boolean;
|
|
1115
|
-
onFailure: "warn" | "ignore";
|
|
1116
|
-
} | undefined;
|
|
1117
|
-
} | undefined;
|
|
1118
|
-
hotReload?: {
|
|
1119
|
-
enabled: boolean;
|
|
1120
|
-
environment: "development" | "production" | "staging";
|
|
1121
|
-
strategy: "partial" | "full" | "state-preserve";
|
|
1122
|
-
debounceMs: number;
|
|
1123
|
-
preserveState: boolean;
|
|
1124
|
-
watchPatterns?: string[] | undefined;
|
|
1125
|
-
ignorePatterns?: string[] | undefined;
|
|
1126
|
-
stateSerialization?: {
|
|
1127
|
-
enabled: boolean;
|
|
1128
|
-
handler?: string | undefined;
|
|
1129
|
-
} | undefined;
|
|
1130
|
-
hooks?: {
|
|
1131
|
-
beforeReload?: string | undefined;
|
|
1132
|
-
afterReload?: string | undefined;
|
|
1133
|
-
onError?: string | undefined;
|
|
1134
|
-
} | undefined;
|
|
1135
|
-
productionSafety?: {
|
|
1136
|
-
healthValidation: boolean;
|
|
1137
|
-
rollbackOnFailure: boolean;
|
|
1138
|
-
healthTimeout: number;
|
|
1139
|
-
drainConnections: boolean;
|
|
1140
|
-
drainTimeout: number;
|
|
1141
|
-
maxConcurrentReloads: number;
|
|
1142
|
-
minReloadInterval: number;
|
|
1143
|
-
} | undefined;
|
|
1144
|
-
} | undefined;
|
|
1145
|
-
caching?: {
|
|
1146
|
-
enabled: boolean;
|
|
1147
|
-
storage: "hybrid" | "indexeddb" | "memory" | "disk";
|
|
1148
|
-
keyStrategy: "hash" | "version" | "timestamp";
|
|
1149
|
-
ttl?: number | undefined;
|
|
1150
|
-
maxSize?: number | undefined;
|
|
1151
|
-
invalidateOn?: ("error" | "manual" | "version-change" | "dependency-change")[] | undefined;
|
|
1152
|
-
compression?: {
|
|
1153
|
-
enabled: boolean;
|
|
1154
|
-
algorithm: "gzip" | "brotli" | "deflate";
|
|
1155
|
-
} | undefined;
|
|
1156
|
-
} | undefined;
|
|
1157
|
-
sandboxing?: {
|
|
1158
|
-
enabled: boolean;
|
|
1159
|
-
scope: "automation-only" | "untrusted-only" | "all-plugins";
|
|
1160
|
-
isolationLevel: "none" | "process" | "vm" | "iframe" | "web-worker";
|
|
1161
|
-
allowedCapabilities?: string[] | undefined;
|
|
1162
|
-
resourceQuotas?: {
|
|
1163
|
-
maxMemoryMB?: number | undefined;
|
|
1164
|
-
maxCpuTimeMs?: number | undefined;
|
|
1165
|
-
maxFileDescriptors?: number | undefined;
|
|
1166
|
-
maxNetworkKBps?: number | undefined;
|
|
1167
|
-
} | undefined;
|
|
1168
|
-
permissions?: {
|
|
1169
|
-
allowedAPIs?: string[] | undefined;
|
|
1170
|
-
allowedPaths?: string[] | undefined;
|
|
1171
|
-
allowedEndpoints?: string[] | undefined;
|
|
1172
|
-
allowedEnvVars?: string[] | undefined;
|
|
1173
|
-
} | undefined;
|
|
1174
|
-
ipc?: {
|
|
1175
|
-
enabled: boolean;
|
|
1176
|
-
transport: "memory" | "message-port" | "unix-socket" | "tcp";
|
|
1177
|
-
maxMessageSize: number;
|
|
1178
|
-
timeout: number;
|
|
1179
|
-
allowedServices?: string[] | undefined;
|
|
1180
|
-
} | undefined;
|
|
1181
|
-
} | undefined;
|
|
1182
|
-
monitoring?: {
|
|
1183
|
-
enabled: boolean;
|
|
1184
|
-
samplingRate: number;
|
|
1185
|
-
reportingInterval: number;
|
|
1186
|
-
onBudgetViolation: "warn" | "error" | "ignore";
|
|
1187
|
-
metrics?: ("load-time" | "init-time" | "memory-usage" | "cpu-usage" | "api-calls" | "error-rate" | "cache-hit-rate")[] | undefined;
|
|
1188
|
-
budgets?: {
|
|
1189
|
-
maxLoadTimeMs?: number | undefined;
|
|
1190
|
-
maxInitTimeMs?: number | undefined;
|
|
1191
|
-
maxMemoryMB?: number | undefined;
|
|
1192
|
-
} | undefined;
|
|
1193
|
-
} | undefined;
|
|
1194
|
-
} | undefined;
|
|
1195
|
-
engine?: {
|
|
1196
|
-
objectstack: string;
|
|
1197
|
-
} | undefined;
|
|
1198
|
-
};
|
|
211
|
+
validate(type: string, item: any): unknown;
|
|
1199
212
|
/**
|
|
1200
213
|
* Universal Unregister Method
|
|
1201
214
|
*/
|
|
1202
|
-
|
|
215
|
+
unregisterItem(type: string, name: string): void;
|
|
1203
216
|
/**
|
|
1204
217
|
* Universal Get Method
|
|
1205
218
|
*/
|
|
1206
|
-
|
|
219
|
+
getItem<T>(type: string, name: string): T | undefined;
|
|
1207
220
|
/**
|
|
1208
221
|
* Universal List Method
|
|
1209
222
|
*/
|
|
1210
|
-
|
|
223
|
+
listItems<T>(type: string, packageId?: string): T[];
|
|
1211
224
|
/**
|
|
1212
225
|
* Get all registered metadata types (Kinds)
|
|
1213
226
|
*/
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
227
|
+
getRegisteredTypes(): string[];
|
|
228
|
+
installPackage(manifest: ObjectStackManifest, settings?: Record<string, any>): InstalledPackage;
|
|
229
|
+
uninstallPackage(id: string): boolean;
|
|
230
|
+
getPackage(id: string): InstalledPackage | undefined;
|
|
231
|
+
getAllPackages(): InstalledPackage[];
|
|
232
|
+
enablePackage(id: string): InstalledPackage | undefined;
|
|
233
|
+
disablePackage(id: string): InstalledPackage | undefined;
|
|
234
|
+
registerApp(app: any, packageId?: string): void;
|
|
235
|
+
getApp(name: string): any;
|
|
236
|
+
getAllApps(): any[];
|
|
237
|
+
registerPlugin(manifest: ObjectStackManifest): void;
|
|
238
|
+
getAllPlugins(): ObjectStackManifest[];
|
|
239
|
+
registerKind(kind: {
|
|
1227
240
|
id: string;
|
|
1228
241
|
globs: string[];
|
|
1229
242
|
}): void;
|
|
1230
|
-
|
|
243
|
+
getAllKinds(): {
|
|
1231
244
|
id: string;
|
|
1232
245
|
globs: string[];
|
|
1233
246
|
}[];
|
|
1234
247
|
/**
|
|
1235
248
|
* Clear all registry state. Use only for testing.
|
|
1236
249
|
*/
|
|
1237
|
-
|
|
250
|
+
reset(): void;
|
|
1238
251
|
}
|
|
1239
252
|
|
|
1240
253
|
declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
1241
254
|
private engine;
|
|
1242
255
|
private getServicesRegistry?;
|
|
1243
256
|
private getFeedService?;
|
|
1244
|
-
|
|
257
|
+
/**
|
|
258
|
+
* Project scope applied to sys_metadata reads/writes. When undefined
|
|
259
|
+
* (single-kernel deployments), rows land in / come from the
|
|
260
|
+
* platform-global bucket (`project_id IS NULL`). When set, every
|
|
261
|
+
* saveMetaItem insert/update and loadMetaFromDb query is filtered by
|
|
262
|
+
* `project_id = projectId`, so per-project kernels see only their own
|
|
263
|
+
* metadata even if several projects share the same physical database.
|
|
264
|
+
*/
|
|
265
|
+
private projectId?;
|
|
266
|
+
constructor(engine: IDataEngine, getServicesRegistry?: () => Map<string, any>, getFeedService?: () => IFeedService | undefined, projectId?: string);
|
|
267
|
+
/**
|
|
268
|
+
* One-time guard for ensuring the overlay-uniqueness UNIQUE INDEX exists
|
|
269
|
+
* on `sys_metadata`. ADR-0005: scopes overlays by
|
|
270
|
+
* `(type, name, organization_id, project_id, scope)` for active rows only.
|
|
271
|
+
* Idempotent SQL — safe to attempt on every protocol instance.
|
|
272
|
+
*
|
|
273
|
+
* Inlined here (rather than importing from @objectstack/metadata/migrations)
|
|
274
|
+
* to avoid a circular dependency: metadata already depends on objectql.
|
|
275
|
+
*/
|
|
276
|
+
private overlayIndexEnsured;
|
|
277
|
+
private ensureOverlayIndex;
|
|
278
|
+
/**
|
|
279
|
+
* Exposes the project scope the protocol is bound to. Consumers like
|
|
280
|
+
* the HTTP dispatcher use this to decide whether to trust the process-
|
|
281
|
+
* wide SchemaRegistry or whether they must route a read through the
|
|
282
|
+
* protocol's project_id-filtered lookup.
|
|
283
|
+
*/
|
|
284
|
+
getProjectId(): string | undefined;
|
|
1245
285
|
private requireFeedService;
|
|
1246
286
|
getDiscovery(): Promise<{
|
|
1247
287
|
version: string;
|
|
@@ -1266,7 +306,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1266
306
|
};
|
|
1267
307
|
services: Record<string, {
|
|
1268
308
|
enabled: boolean;
|
|
1269
|
-
status: "
|
|
309
|
+
status: "available" | "registered" | "unavailable" | "degraded" | "stub";
|
|
1270
310
|
handlerReady?: boolean | undefined;
|
|
1271
311
|
route?: string | undefined;
|
|
1272
312
|
provider?: string | undefined;
|
|
@@ -1290,6 +330,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1290
330
|
getMetaItems(request: {
|
|
1291
331
|
type: string;
|
|
1292
332
|
packageId?: string;
|
|
333
|
+
organizationId?: string;
|
|
1293
334
|
}): Promise<{
|
|
1294
335
|
type: string;
|
|
1295
336
|
items: unknown[];
|
|
@@ -1298,6 +339,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1298
339
|
type: string;
|
|
1299
340
|
name: string;
|
|
1300
341
|
packageId?: string;
|
|
342
|
+
organizationId?: string;
|
|
1301
343
|
}): Promise<{
|
|
1302
344
|
type: string;
|
|
1303
345
|
name: string;
|
|
@@ -1335,7 +377,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1335
377
|
label: string | undefined;
|
|
1336
378
|
required: boolean;
|
|
1337
379
|
readonly: boolean;
|
|
1338
|
-
type: "number" | "boolean" | "tags" | "date" | "
|
|
380
|
+
type: "number" | "boolean" | "tags" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
|
|
1339
381
|
colSpan: number;
|
|
1340
382
|
}[];
|
|
1341
383
|
}[];
|
|
@@ -1345,6 +387,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1345
387
|
findData(request: {
|
|
1346
388
|
object: string;
|
|
1347
389
|
query?: any;
|
|
390
|
+
context?: any;
|
|
1348
391
|
}): Promise<{
|
|
1349
392
|
object: string;
|
|
1350
393
|
records: any[];
|
|
@@ -1356,6 +399,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1356
399
|
id: string;
|
|
1357
400
|
expand?: string | string[];
|
|
1358
401
|
select?: string | string[];
|
|
402
|
+
context?: any;
|
|
1359
403
|
}): Promise<{
|
|
1360
404
|
object: string;
|
|
1361
405
|
id: string;
|
|
@@ -1364,6 +408,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1364
408
|
createData(request: {
|
|
1365
409
|
object: string;
|
|
1366
410
|
data: any;
|
|
411
|
+
context?: any;
|
|
1367
412
|
}): Promise<{
|
|
1368
413
|
object: string;
|
|
1369
414
|
id: any;
|
|
@@ -1373,6 +418,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1373
418
|
object: string;
|
|
1374
419
|
id: string;
|
|
1375
420
|
data: any;
|
|
421
|
+
context?: any;
|
|
1376
422
|
}): Promise<{
|
|
1377
423
|
object: string;
|
|
1378
424
|
id: string;
|
|
@@ -1381,11 +427,86 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1381
427
|
deleteData(request: {
|
|
1382
428
|
object: string;
|
|
1383
429
|
id: string;
|
|
430
|
+
context?: any;
|
|
1384
431
|
}): Promise<{
|
|
1385
432
|
object: string;
|
|
1386
433
|
id: string;
|
|
1387
434
|
success: boolean;
|
|
1388
435
|
}>;
|
|
436
|
+
/**
|
|
437
|
+
* Cross-object substring search across all registered objects that opt in
|
|
438
|
+
* via `enable.searchable !== false` and `enable.apiEnabled !== false`.
|
|
439
|
+
* Searches text-like fields (text/textarea/email/url/phone/markdown/html/string)
|
|
440
|
+
* whose `searchable: true` flag is set, falling back to the object's
|
|
441
|
+
* `displayNameField` (or `name`) when no fields are explicitly searchable.
|
|
442
|
+
*
|
|
443
|
+
* The query is split into whitespace-separated terms; each term must match
|
|
444
|
+
* (case-insensitive LIKE) at least one searchable field. RBAC/RLS is
|
|
445
|
+
* enforced by forwarding the caller's `context` to `engine.find` so users
|
|
446
|
+
* only see records they are entitled to read.
|
|
447
|
+
*/
|
|
448
|
+
searchAll(request: {
|
|
449
|
+
q: string;
|
|
450
|
+
objects?: string[];
|
|
451
|
+
limit?: number;
|
|
452
|
+
perObject?: number;
|
|
453
|
+
context?: any;
|
|
454
|
+
}): Promise<{
|
|
455
|
+
query: string;
|
|
456
|
+
hits: Array<{
|
|
457
|
+
object: string;
|
|
458
|
+
id: string;
|
|
459
|
+
title: string;
|
|
460
|
+
snippet?: string;
|
|
461
|
+
record: any;
|
|
462
|
+
}>;
|
|
463
|
+
totalObjects: number;
|
|
464
|
+
totalHits: number;
|
|
465
|
+
truncated: boolean;
|
|
466
|
+
}>;
|
|
467
|
+
/**
|
|
468
|
+
* Convert a qualified Lead into an Account + Contact (+ optional
|
|
469
|
+
* Opportunity) and mark the Lead as converted. Mirrors the Salesforce
|
|
470
|
+
* lead-conversion model:
|
|
471
|
+
*
|
|
472
|
+
* - If `accountId` is provided, the lead's company info is NOT used
|
|
473
|
+
* to create a new account; the new contact and opportunity link to
|
|
474
|
+
* the existing account instead.
|
|
475
|
+
* - If `contactId` is provided, no new contact is created either —
|
|
476
|
+
* useful when the lead is a new contact at an existing account.
|
|
477
|
+
* - `createOpportunity` defaults to true; pass `false` to convert
|
|
478
|
+
* without producing an opportunity (some teams convert "logos
|
|
479
|
+
* only" first).
|
|
480
|
+
* - Lead is updated atomically: `is_converted=true`,
|
|
481
|
+
* `converted_account`/`converted_contact`/`converted_opportunity`
|
|
482
|
+
* pointers, `converted_date`, and `status='converted'`.
|
|
483
|
+
*
|
|
484
|
+
* Atomicity is enforced via the default driver's transaction support
|
|
485
|
+
* when available; otherwise a best-effort compensation (delete
|
|
486
|
+
* already-created child records on failure) is attempted. Permission
|
|
487
|
+
* checks on each child object are inherited from the caller's
|
|
488
|
+
* execution context so SecurityPlugin still gates account/contact/
|
|
489
|
+
* opportunity creates.
|
|
490
|
+
*/
|
|
491
|
+
convertLead(request: {
|
|
492
|
+
leadId: string;
|
|
493
|
+
accountId?: string;
|
|
494
|
+
contactId?: string;
|
|
495
|
+
createOpportunity?: boolean;
|
|
496
|
+
opportunity?: {
|
|
497
|
+
name?: string;
|
|
498
|
+
amount?: number;
|
|
499
|
+
close_date?: string;
|
|
500
|
+
stage?: string;
|
|
501
|
+
};
|
|
502
|
+
convertedStatus?: string;
|
|
503
|
+
context?: any;
|
|
504
|
+
}): Promise<{
|
|
505
|
+
lead: any;
|
|
506
|
+
account: any;
|
|
507
|
+
contact: any;
|
|
508
|
+
opportunity: any | null;
|
|
509
|
+
}>;
|
|
1389
510
|
getMetaItemCached(request: {
|
|
1390
511
|
type: string;
|
|
1391
512
|
name: string;
|
|
@@ -1405,23 +526,51 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1405
526
|
private mapAnalyticsOperator;
|
|
1406
527
|
triggerAutomation(_request: any): Promise<any>;
|
|
1407
528
|
deleteManyData(request: DeleteManyDataRequest): Promise<any>;
|
|
529
|
+
/**
|
|
530
|
+
* Metadata types that are customer-overridable via {@link saveMetaItem}/
|
|
531
|
+
* {@link deleteMetaItem} in project-kernel mode. Derived from the canonical
|
|
532
|
+
* registry in {@link DEFAULT_METADATA_TYPE_REGISTRY}: a type opts in by
|
|
533
|
+
* setting `allowOrgOverride: true` on its registry entry. The set is
|
|
534
|
+
* augmented with the plural form of every singular so callers using REST
|
|
535
|
+
* conventions (`/api/v1/meta/views/...`) get the same gate. See ADR-0005
|
|
536
|
+
* §"Whitelist enforcement" for the rationale and the per-type rollout
|
|
537
|
+
* checklist.
|
|
538
|
+
*/
|
|
539
|
+
private static readonly OVERLAY_ALLOWED_TYPES;
|
|
540
|
+
/** Normalize plural→singular before consulting the allow-list. */
|
|
541
|
+
private static isOverlayAllowed;
|
|
1408
542
|
saveMetaItem(request: {
|
|
1409
543
|
type: string;
|
|
1410
544
|
name: string;
|
|
1411
545
|
item?: any;
|
|
546
|
+
organizationId?: string;
|
|
1412
547
|
}): Promise<{
|
|
1413
548
|
success: boolean;
|
|
1414
549
|
message: string;
|
|
1415
|
-
|
|
1416
|
-
|
|
550
|
+
}>;
|
|
551
|
+
/**
|
|
552
|
+
* Remove a customization overlay row for the given metadata item, so the
|
|
553
|
+
* next read falls through to the artifact-loaded default. Implements the
|
|
554
|
+
* "Reset to factory default" semantic from ADR-0005. Whitelist is shared
|
|
555
|
+
* with {@link saveMetaItem}.
|
|
556
|
+
*/
|
|
557
|
+
deleteMetaItem(request: {
|
|
558
|
+
type: string;
|
|
559
|
+
name: string;
|
|
560
|
+
organizationId?: string;
|
|
561
|
+
}): Promise<{
|
|
1417
562
|
success: boolean;
|
|
1418
|
-
message
|
|
1419
|
-
|
|
563
|
+
message?: string;
|
|
564
|
+
reset?: boolean;
|
|
1420
565
|
}>;
|
|
1421
566
|
/**
|
|
1422
567
|
* Hydrate SchemaRegistry from the database on startup.
|
|
1423
568
|
* Loads all active metadata records and registers them in the in-memory registry.
|
|
1424
569
|
* Safe to call repeatedly — idempotent (latest DB record wins).
|
|
570
|
+
*
|
|
571
|
+
* Per ADR-0005, project-kernel mode ALSO hydrates from sys_metadata —
|
|
572
|
+
* customization overlay rows must survive restart. Scope filter
|
|
573
|
+
* (`project_id = this.projectId ?? null`) keeps tenants isolated.
|
|
1425
574
|
*/
|
|
1426
575
|
loadMetaFromDb(): Promise<{
|
|
1427
576
|
loaded: number;
|
|
@@ -1452,6 +601,14 @@ interface HookEntry {
|
|
|
1452
601
|
object?: string | string[];
|
|
1453
602
|
priority: number;
|
|
1454
603
|
packageId?: string;
|
|
604
|
+
/**
|
|
605
|
+
* Original metadata-form `Hook` definition this entry was bound from
|
|
606
|
+
* (when registered via `bindHooksToEngine`). Pure code-paths that call
|
|
607
|
+
* `engine.registerHook` directly leave this undefined.
|
|
608
|
+
*/
|
|
609
|
+
meta?: any;
|
|
610
|
+
/** Hook `name` from metadata; used for diagnostics & deduplication. */
|
|
611
|
+
hookName?: string;
|
|
1455
612
|
}
|
|
1456
613
|
/**
|
|
1457
614
|
* Operation Context for Middleware Chain
|
|
@@ -1494,8 +651,10 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1494
651
|
private hooks;
|
|
1495
652
|
private middlewares;
|
|
1496
653
|
private actions;
|
|
654
|
+
private functions;
|
|
1497
655
|
private hostContext;
|
|
1498
656
|
private realtimeService?;
|
|
657
|
+
private _registry;
|
|
1499
658
|
constructor(hostContext?: Record<string, any>);
|
|
1500
659
|
/**
|
|
1501
660
|
* Service Status Report
|
|
@@ -1508,9 +667,12 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1508
667
|
features: string[];
|
|
1509
668
|
};
|
|
1510
669
|
/**
|
|
1511
|
-
* Expose the SchemaRegistry for plugins to register metadata
|
|
670
|
+
* Expose the SchemaRegistry for plugins to register metadata.
|
|
671
|
+
*
|
|
672
|
+
* Returns the per-engine instance, NOT the class. Each ObjectQL engine
|
|
673
|
+
* owns its registry so multi-project kernels remain isolated.
|
|
1512
674
|
*/
|
|
1513
|
-
get registry():
|
|
675
|
+
get registry(): SchemaRegistry;
|
|
1514
676
|
/**
|
|
1515
677
|
* Load and Register a Plugin
|
|
1516
678
|
*/
|
|
@@ -1525,7 +687,67 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1525
687
|
object?: string | string[];
|
|
1526
688
|
priority?: number;
|
|
1527
689
|
packageId?: string;
|
|
690
|
+
/** Original metadata Hook definition (set by `bindHooksToEngine`). */
|
|
691
|
+
meta?: any;
|
|
692
|
+
/** Stable name from metadata (set by `bindHooksToEngine`). */
|
|
693
|
+
hookName?: string;
|
|
694
|
+
}): void;
|
|
695
|
+
/**
|
|
696
|
+
* Remove all hooks registered under a given `packageId`. Used by
|
|
697
|
+
* `bindHooksToEngine` to make re-binding (hot reload, app reinstall)
|
|
698
|
+
* idempotent, and by app uninstall flows.
|
|
699
|
+
*/
|
|
700
|
+
unregisterHooksByPackage(packageId: string): number;
|
|
701
|
+
/**
|
|
702
|
+
* Register a named function handler that can later be referenced by
|
|
703
|
+
* string from a `Hook.handler` field. This is the JSON-safe form of
|
|
704
|
+
* handler binding — declarative metadata persisted to disk or shipped
|
|
705
|
+
* over the wire only carries the name.
|
|
706
|
+
*/
|
|
707
|
+
registerFunction(name: string, handler: HookHandler, packageId?: string): void;
|
|
708
|
+
/** Look up a registered function by name. */
|
|
709
|
+
resolveFunction(name: string): HookHandler | undefined;
|
|
710
|
+
/** Remove all functions registered under a given `packageId`. */
|
|
711
|
+
unregisterFunctionsByPackage(packageId: string): number;
|
|
712
|
+
/**
|
|
713
|
+
* Bind a list of declarative `Hook` metadata definitions to this engine.
|
|
714
|
+
*
|
|
715
|
+
* Convenience proxy to the canonical `bindHooksToEngine` so callers do
|
|
716
|
+
* not need a separate import. Use `import { bindHooksToEngine } from
|
|
717
|
+
* '@objectstack/objectql'` directly when you want the result object.
|
|
718
|
+
*/
|
|
719
|
+
bindHooks(hooks: any[] | undefined, opts?: {
|
|
720
|
+
packageId?: string;
|
|
721
|
+
functions?: Record<string, HookHandler>;
|
|
722
|
+
bodyRunner?: any;
|
|
723
|
+
strict?: boolean;
|
|
724
|
+
warnLegacyHandler?: boolean;
|
|
725
|
+
metrics?: any;
|
|
1528
726
|
}): void;
|
|
727
|
+
/**
|
|
728
|
+
* Install a default body-runner used when `bindHooks` is called without
|
|
729
|
+
* an explicit one. The runtime layer sets this once on each per-project
|
|
730
|
+
* engine so every binding path (template seed, metadata sync, AppPlugin)
|
|
731
|
+
* can execute hook `body.source` consistently.
|
|
732
|
+
*/
|
|
733
|
+
setDefaultBodyRunner(runner: any): void;
|
|
734
|
+
/**
|
|
735
|
+
* Toggle strict hook-binding mode for this engine. When enabled, every
|
|
736
|
+
* subsequent `bindHooks` call rejects on the first unresolved hook
|
|
737
|
+
* instead of silently warning. Production runtimes should enable this.
|
|
738
|
+
*/
|
|
739
|
+
setStrictHookBinding(strict: boolean): void;
|
|
740
|
+
/** Toggle deprecation warnings for hooks still using legacy `handler` ref. */
|
|
741
|
+
setWarnLegacyHandler(warn: boolean): void;
|
|
742
|
+
/**
|
|
743
|
+
* Install a metrics recorder used by every subsequent `bindHooks` call.
|
|
744
|
+
* The recorder's methods are invoked per-execution to count outcomes
|
|
745
|
+
* (success / error / timeout / capability_rejected), skips, and retries.
|
|
746
|
+
* Defaults to no-op so the engine pays zero cost when nobody is observing.
|
|
747
|
+
*/
|
|
748
|
+
setHookMetricsRecorder(recorder: any): void;
|
|
749
|
+
/** Read the engine's installed metrics recorder, if any. */
|
|
750
|
+
getHookMetricsRecorder(): any;
|
|
1529
751
|
triggerHooks(event: string, context: HookContext): Promise<void>;
|
|
1530
752
|
/**
|
|
1531
753
|
* Register a named action on an object.
|
|
@@ -1562,6 +784,40 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1562
784
|
* Build a HookContext.session from ExecutionContext
|
|
1563
785
|
*/
|
|
1564
786
|
private buildSession;
|
|
787
|
+
/**
|
|
788
|
+
* Build the DriverOptions blob passed to every IDataDriver call.
|
|
789
|
+
*
|
|
790
|
+
* Always carries `tenantId` from the active ExecutionContext so the
|
|
791
|
+
* driver can enforce per-tenant isolation (SQL driver auto-scopes reads
|
|
792
|
+
* and auto-injects the tenant column on writes). Existing user-supplied
|
|
793
|
+
* shapes (transactions, AST extras) are preserved by spreading them
|
|
794
|
+
* first.
|
|
795
|
+
*
|
|
796
|
+
* System / isSystem callers may still cross tenants by clearing
|
|
797
|
+
* `tenantId` themselves on the resulting object; this helper does not
|
|
798
|
+
* mask the system path.
|
|
799
|
+
*/
|
|
800
|
+
private buildDriverOptions;
|
|
801
|
+
/**
|
|
802
|
+
* Build a HookContext.api: a ScopedContext that hooks can use to
|
|
803
|
+
* read/write other objects within the same execution context.
|
|
804
|
+
* Falls back to a system-elevated empty context when no execCtx
|
|
805
|
+
* is supplied (e.g. system-triggered hooks).
|
|
806
|
+
*/
|
|
807
|
+
private buildHookApi;
|
|
808
|
+
/**
|
|
809
|
+
* Apply field defaults to an incoming insert payload. Defaults that are
|
|
810
|
+
* Expression envelopes (e.g. `{ dialect: 'cel', source: 'today()' }`,
|
|
811
|
+
* `{ dialect: 'cel', source: 'os.user.id' }`) are evaluated via
|
|
812
|
+
* `ExpressionEngine` against the calling user/org/now snapshot. Static
|
|
813
|
+
* defaults are applied verbatim. Records that already supplied a value for a
|
|
814
|
+
* field are left untouched.
|
|
815
|
+
*
|
|
816
|
+
* Implements ROADMAP §M9.9b — `defaultValue` accepts Expression so authors
|
|
817
|
+
* can replace "write a hook to default to today/current-user" with a
|
|
818
|
+
* declarative `defaultValue: cel\`today()\``.
|
|
819
|
+
*/
|
|
820
|
+
private applyFieldDefaults;
|
|
1565
821
|
/**
|
|
1566
822
|
* Register contribution (Manifest)
|
|
1567
823
|
*
|
|
@@ -1573,6 +829,12 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1573
829
|
* the manifest contains UI navigation definitions (AppSchema).
|
|
1574
830
|
*/
|
|
1575
831
|
registerApp(manifest: any): void;
|
|
832
|
+
/**
|
|
833
|
+
* Deep-clone an app definition, resolving objectName references in navigation
|
|
834
|
+
* items via the registry. Object names are canonical identifiers — no FQN
|
|
835
|
+
* expansion is applied.
|
|
836
|
+
*/
|
|
837
|
+
private resolveNavObjectNames;
|
|
1576
838
|
/**
|
|
1577
839
|
* Register a nested plugin's metadata (objects, actions, views, etc.)
|
|
1578
840
|
*
|
|
@@ -1601,14 +863,11 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1601
863
|
*/
|
|
1602
864
|
getSchema(objectName: string): ServiceObject | undefined;
|
|
1603
865
|
/**
|
|
1604
|
-
* Resolve
|
|
866
|
+
* Resolve any object identifier to the physical storage name used by drivers.
|
|
1605
867
|
*
|
|
1606
|
-
*
|
|
1607
|
-
*
|
|
1608
|
-
*
|
|
1609
|
-
*
|
|
1610
|
-
* This ensures that all driver operations use a consistent key
|
|
1611
|
-
* regardless of whether the caller uses the short name or FQN.
|
|
868
|
+
* Accepts the canonical short name (e.g., 'account') or, for explicit
|
|
869
|
+
* cross-package disambiguation, the canonical object name (e.g., 'account'). The result is
|
|
870
|
+
* the physical table name derived via `StorageNameMapping.resolveTableName`.
|
|
1612
871
|
*/
|
|
1613
872
|
private resolveObjectName;
|
|
1614
873
|
/**
|
|
@@ -1672,7 +931,40 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1672
931
|
delete(object: string, options?: EngineDeleteOptions): Promise<any>;
|
|
1673
932
|
count(object: string, query?: EngineCountOptions): Promise<number>;
|
|
1674
933
|
aggregate(object: string, query: EngineAggregateOptions): Promise<any[]>;
|
|
934
|
+
/**
|
|
935
|
+
* Run raw driver-specific commands (SQL for SqlDriver, REST for RestDriver, …).
|
|
936
|
+
*
|
|
937
|
+
* ⚠️ **Tenant isolation bypass.** Raw `execute()` does NOT thread the
|
|
938
|
+
* caller's `ExecutionContext.tenantId` into a `WHERE organization_id`
|
|
939
|
+
* predicate — drivers see the command verbatim. Callers MUST inline the
|
|
940
|
+
* tenant filter themselves, or restrict raw execution to genuinely global
|
|
941
|
+
* statements (schema migrations, sys_* / control-plane tables).
|
|
942
|
+
*
|
|
943
|
+
* Prefer the typed entry points (`find`, `update`, `delete`, `count`, …)
|
|
944
|
+
* whenever feasible — they auto-apply tenancy + soft-delete + audit warnings.
|
|
945
|
+
*/
|
|
1675
946
|
execute(command: any, options?: Record<string, any>): Promise<any>;
|
|
947
|
+
/**
|
|
948
|
+
* Execute a callback inside a database transaction.
|
|
949
|
+
*
|
|
950
|
+
* The callback receives a context object that should be passed to all
|
|
951
|
+
* downstream `engine.insert/update/delete/find/findOne` calls (as
|
|
952
|
+
* `{ context: trxCtx }`). The transaction handle threads through
|
|
953
|
+
* `OperationContext.context.transaction` and the SQL driver's per-builder
|
|
954
|
+
* `.transacting(trx)` call.
|
|
955
|
+
*
|
|
956
|
+
* - If the default driver does not support `beginTransaction`, the callback
|
|
957
|
+
* runs directly with the supplied base context (no rollback). This keeps
|
|
958
|
+
* the API safe to call on drivers without ACID support (e.g. the
|
|
959
|
+
* in-memory driver in tests).
|
|
960
|
+
* - On callback success the transaction is committed; on any thrown error
|
|
961
|
+
* it is rolled back and the original error is re-thrown.
|
|
962
|
+
*
|
|
963
|
+
* Use case: multi-step operations that must be atomic (e.g. CRM
|
|
964
|
+
* `convertLead`, which creates an account + contact + opportunity + flips
|
|
965
|
+
* the lead in a single unit of work).
|
|
966
|
+
*/
|
|
967
|
+
transaction<T>(callback: (trxCtx: any) => Promise<T>, baseContext?: any): Promise<T>;
|
|
1676
968
|
/**
|
|
1677
969
|
* Register a single object definition.
|
|
1678
970
|
*
|
|
@@ -1712,6 +1004,13 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1712
1004
|
* @returns The resolved DriverInterface, or undefined if no driver is available.
|
|
1713
1005
|
*/
|
|
1714
1006
|
getDriverForObject(objectName: string): DriverInterface | undefined;
|
|
1007
|
+
/**
|
|
1008
|
+
* Sync all registered object schemas to their respective drivers.
|
|
1009
|
+
* Call this after dynamically registering new objects at runtime
|
|
1010
|
+
* (e.g. after template seeding) to ensure tables/collections exist
|
|
1011
|
+
* before inserting seed data.
|
|
1012
|
+
*/
|
|
1013
|
+
syncSchemas(): Promise<void>;
|
|
1715
1014
|
/**
|
|
1716
1015
|
* Get a registered driver by datasource name.
|
|
1717
1016
|
* Alias matching @objectql/core datasource() API.
|
|
@@ -1834,6 +1133,249 @@ declare class ScopedContext {
|
|
|
1834
1133
|
get transactionHandle(): unknown;
|
|
1835
1134
|
}
|
|
1836
1135
|
|
|
1136
|
+
/**
|
|
1137
|
+
* Group + aggregate raw rows according to the AST's `groupBy` /
|
|
1138
|
+
* `aggregations`. When neither is present, returns the rows unchanged.
|
|
1139
|
+
*/
|
|
1140
|
+
declare function applyInMemoryAggregation(rows: any[], ast: Pick<QueryAST, 'groupBy' | 'aggregations'>): any[];
|
|
1141
|
+
/**
|
|
1142
|
+
* Bucket a date-like value into an ISO-formatted period label. Weeks start
|
|
1143
|
+
* Monday and use ISO week numbering.
|
|
1144
|
+
*/
|
|
1145
|
+
declare function bucketDateValue(value: unknown, granularity: DateGranularityValue): string;
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* Hook Execution Metrics
|
|
1149
|
+
*
|
|
1150
|
+
* Lightweight, transport-agnostic recorder interface for per-hook execution
|
|
1151
|
+
* counters and latencies. The default implementation is a no-op so the
|
|
1152
|
+
* engine pays zero cost when nobody is observing.
|
|
1153
|
+
*
|
|
1154
|
+
* Wire a real recorder by calling `engine.setHookMetricsRecorder(recorder)`.
|
|
1155
|
+
* The runtime / kernel can adapt this to Otel, Prometheus, StatsD, or
|
|
1156
|
+
* whatever telemetry pipeline ships with the deployment.
|
|
1157
|
+
*
|
|
1158
|
+
* Recorded events:
|
|
1159
|
+
* - `recordExecution(label, outcome, durationMs)`
|
|
1160
|
+
* outcome ∈ 'success' | 'error' | 'timeout' | 'capability_rejected'
|
|
1161
|
+
* - `recordSkip(label, reason)`
|
|
1162
|
+
* reason ∈ 'condition' | 'fire_and_forget'
|
|
1163
|
+
* - `recordRetry(label, attempt)`
|
|
1164
|
+
*/
|
|
1165
|
+
type HookMetricOutcome = 'success' | 'error' | 'timeout' | 'capability_rejected';
|
|
1166
|
+
type HookSkipReason = 'condition' | 'fire_and_forget';
|
|
1167
|
+
interface HookMetricLabel {
|
|
1168
|
+
/** Hook name (stable id from metadata). */
|
|
1169
|
+
hook: string;
|
|
1170
|
+
/** Object name the hook is bound to. May be undefined for global hooks. */
|
|
1171
|
+
object?: string;
|
|
1172
|
+
/** Lifecycle event (`beforeInsert`, `afterUpdate`, etc.). */
|
|
1173
|
+
event?: string;
|
|
1174
|
+
/** True when the handler comes from a metadata `body` (sandboxed JS). */
|
|
1175
|
+
body?: boolean;
|
|
1176
|
+
}
|
|
1177
|
+
interface HookMetricsRecorder {
|
|
1178
|
+
recordExecution(label: HookMetricLabel, outcome: HookMetricOutcome, durationMs: number): void;
|
|
1179
|
+
recordSkip(label: HookMetricLabel, reason: HookSkipReason): void;
|
|
1180
|
+
recordRetry(label: HookMetricLabel, attempt: number): void;
|
|
1181
|
+
}
|
|
1182
|
+
declare const noopHookMetricsRecorder: HookMetricsRecorder;
|
|
1183
|
+
/**
|
|
1184
|
+
* In-memory recorder useful for tests, dev-mode dashboards, and as a
|
|
1185
|
+
* starting point for adapter implementations. Aggregates counts + a
|
|
1186
|
+
* rolling sum of latency per (hook, outcome).
|
|
1187
|
+
*/
|
|
1188
|
+
declare class InMemoryHookMetricsRecorder implements HookMetricsRecorder {
|
|
1189
|
+
private executions;
|
|
1190
|
+
private skips;
|
|
1191
|
+
private retries;
|
|
1192
|
+
recordExecution(label: HookMetricLabel, outcome: HookMetricOutcome, durationMs: number): void;
|
|
1193
|
+
recordSkip(label: HookMetricLabel, reason: HookSkipReason): void;
|
|
1194
|
+
recordRetry(label: HookMetricLabel, _attempt: number): void;
|
|
1195
|
+
snapshot(): {
|
|
1196
|
+
executions: Array<{
|
|
1197
|
+
hook: string;
|
|
1198
|
+
outcome: HookMetricOutcome;
|
|
1199
|
+
count: number;
|
|
1200
|
+
totalMs: number;
|
|
1201
|
+
}>;
|
|
1202
|
+
skips: Array<{
|
|
1203
|
+
hook: string;
|
|
1204
|
+
reason: HookSkipReason;
|
|
1205
|
+
count: number;
|
|
1206
|
+
}>;
|
|
1207
|
+
retries: Array<{
|
|
1208
|
+
hook: string;
|
|
1209
|
+
count: number;
|
|
1210
|
+
}>;
|
|
1211
|
+
};
|
|
1212
|
+
reset(): void;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* Hook Binder
|
|
1217
|
+
*
|
|
1218
|
+
* Single, canonical entry point that turns declarative `Hook` metadata into
|
|
1219
|
+
* runtime registrations on the `ObjectQL` engine. Every metadata source —
|
|
1220
|
+
* `defineStack({ hooks })` (consumed by `AppPlugin`), the per-project
|
|
1221
|
+
* template seeder (`MultiProjectPlugin`), and the metadata service
|
|
1222
|
+
* (`ObjectQLPlugin.loadMetadataFromService`) — funnels through here so
|
|
1223
|
+
* that:
|
|
1224
|
+
*
|
|
1225
|
+
* - Inline function handlers and string-named handlers share one resolver.
|
|
1226
|
+
* - Declarative fields (`condition`, `async`, `retryPolicy`, `timeout`,
|
|
1227
|
+
* `onError`) are honoured uniformly via `wrapDeclarativeHook`.
|
|
1228
|
+
* - Hooks can be unregistered as a unit via `packageId`, enabling clean
|
|
1229
|
+
* hot-reload and app uninstall.
|
|
1230
|
+
*
|
|
1231
|
+
* The ObjectQL engine itself stays simple — it knows how to store and
|
|
1232
|
+
* trigger handlers, but knows nothing about declarative semantics. All
|
|
1233
|
+
* metadata-aware behaviour lives in this binder + the wrapper module.
|
|
1234
|
+
*/
|
|
1235
|
+
|
|
1236
|
+
interface BindHooksOptions {
|
|
1237
|
+
/** Owning package / app id — used for `unregisterHooksByPackage`. */
|
|
1238
|
+
packageId?: string;
|
|
1239
|
+
/**
|
|
1240
|
+
* Optional name → function map for resolving string `handler` references.
|
|
1241
|
+
* Typically supplied by `defineStack({ functions })` and merged with any
|
|
1242
|
+
* functions previously registered on the engine.
|
|
1243
|
+
*/
|
|
1244
|
+
functions?: Record<string, HookHandler>;
|
|
1245
|
+
/**
|
|
1246
|
+
* Optional factory that converts a metadata-only `Hook.body` (L1 expression
|
|
1247
|
+
* or L2 sandboxed JS source) into an executable `HookHandler`. The runtime
|
|
1248
|
+
* package wires this up using `QuickJSScriptRunner`; objectql itself stays
|
|
1249
|
+
* sandbox-free so it can run in lightweight environments.
|
|
1250
|
+
*
|
|
1251
|
+
* If `hook.body` is set and this factory is missing, the hook is skipped
|
|
1252
|
+
* with a clear error.
|
|
1253
|
+
*/
|
|
1254
|
+
bodyRunner?: (hook: Hook) => HookHandler | undefined;
|
|
1255
|
+
/**
|
|
1256
|
+
* When true, treat unresolved hooks (body present but no runner, or handler
|
|
1257
|
+
* string with no implementation) as fatal errors instead of warnings. Used
|
|
1258
|
+
* by production runtimes to fail fast on misconfiguration. Defaults false.
|
|
1259
|
+
*/
|
|
1260
|
+
strict?: boolean;
|
|
1261
|
+
/**
|
|
1262
|
+
* When true, emit a deprecation warning for every hook that still relies
|
|
1263
|
+
* on a `handler` ref string instead of the metadata-only `body`. Used by
|
|
1264
|
+
* the CLI (compile time) and runtime (boot time) to nudge users away from
|
|
1265
|
+
* the legacy `.mjs` runtime bundle path. Defaults false.
|
|
1266
|
+
*/
|
|
1267
|
+
warnLegacyHandler?: boolean;
|
|
1268
|
+
/** Per-hook execution metrics sink. Defaults to no-op. */
|
|
1269
|
+
metrics?: HookMetricsRecorder;
|
|
1270
|
+
/** Logger; defaults to a silent no-op. */
|
|
1271
|
+
logger?: {
|
|
1272
|
+
debug: (msg: string, meta?: any) => void;
|
|
1273
|
+
info: (msg: string, meta?: any) => void;
|
|
1274
|
+
warn: (msg: string, meta?: any) => void;
|
|
1275
|
+
error: (msg: string, meta?: any) => void;
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
/** Counter for stats. */
|
|
1279
|
+
interface BindHooksResult {
|
|
1280
|
+
registered: number;
|
|
1281
|
+
skipped: number;
|
|
1282
|
+
errors: Array<{
|
|
1283
|
+
hook: string;
|
|
1284
|
+
reason: string;
|
|
1285
|
+
}>;
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Bind a list of declarative `Hook` definitions to a running ObjectQL engine.
|
|
1289
|
+
*
|
|
1290
|
+
* Idempotent on `(packageId, hook.name, event, object)`: re-binding the
|
|
1291
|
+
* same set after a hot reload first calls `unregisterHooksByPackage`
|
|
1292
|
+
* (when `packageId` is provided).
|
|
1293
|
+
*/
|
|
1294
|
+
declare function bindHooksToEngine(engine: ObjectQL, hooks: Hook[] | undefined, opts?: BindHooksOptions): BindHooksResult;
|
|
1295
|
+
|
|
1296
|
+
/**
|
|
1297
|
+
* Declarative Hook Wrappers
|
|
1298
|
+
*
|
|
1299
|
+
* Turns a raw `HookHandler` into one that honours the declarative metadata
|
|
1300
|
+
* fields defined on `HookSchema` (`condition`, `async`, `retryPolicy`,
|
|
1301
|
+
* `timeout`, `onError`). This lives outside the engine's `triggerHooks`
|
|
1302
|
+
* loop so the engine stays minimal and the semantics are unit-testable in
|
|
1303
|
+
* isolation.
|
|
1304
|
+
*
|
|
1305
|
+
* The resulting wrapped handler keeps the original `(ctx) => Promise<void>`
|
|
1306
|
+
* signature, so `engine.registerHook` does not need to know anything about
|
|
1307
|
+
* the metadata-driven behaviours.
|
|
1308
|
+
*/
|
|
1309
|
+
|
|
1310
|
+
interface WrapDeclarativeOptions {
|
|
1311
|
+
/** Logger for declarative-layer diagnostics (timeouts, retries, swallowed errors). */
|
|
1312
|
+
logger?: {
|
|
1313
|
+
debug: (msg: string, meta?: any) => void;
|
|
1314
|
+
info: (msg: string, meta?: any) => void;
|
|
1315
|
+
warn: (msg: string, meta?: any) => void;
|
|
1316
|
+
error: (msg: string, meta?: any) => void;
|
|
1317
|
+
};
|
|
1318
|
+
/** Optional per-execution metrics sink. Defaults to no-op. */
|
|
1319
|
+
metrics?: HookMetricsRecorder;
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Wrap a hook handler so it honours the declarative fields defined on
|
|
1323
|
+
* `HookSchema`. The wrapping order, from outermost to innermost, is:
|
|
1324
|
+
*
|
|
1325
|
+
* 1. condition → skip when formula evaluates falsy
|
|
1326
|
+
* 2. async → fire-and-forget (after* events only)
|
|
1327
|
+
* 3. retry → repeat on throw with backoff
|
|
1328
|
+
* 4. timeout → abort if handler runs too long
|
|
1329
|
+
* 5. onError → swallow when set to 'log'
|
|
1330
|
+
*
|
|
1331
|
+
* The condition formula is evaluated against the most useful record-shaped
|
|
1332
|
+
* payload available on the context (write payloads first, then `previous`,
|
|
1333
|
+
* then a flat merge of input). Read events typically have no record yet,
|
|
1334
|
+
* so a condition on a `beforeFind` will simply skip when no data is
|
|
1335
|
+
* present.
|
|
1336
|
+
*/
|
|
1337
|
+
declare function wrapDeclarativeHook(meta: Hook, handler: HookHandler, opts?: WrapDeclarativeOptions): HookHandler;
|
|
1338
|
+
|
|
1339
|
+
interface FieldValidationError {
|
|
1340
|
+
field: string;
|
|
1341
|
+
code: 'required' | 'min_length' | 'max_length' | 'min_value' | 'max_value' | 'invalid_email' | 'invalid_url' | 'invalid_phone' | 'invalid_number' | 'invalid_boolean' | 'invalid_date' | 'invalid_option';
|
|
1342
|
+
message: string;
|
|
1343
|
+
/** Allowed values for select/multiselect, when applicable. */
|
|
1344
|
+
options?: string[];
|
|
1345
|
+
}
|
|
1346
|
+
declare class ValidationError extends Error {
|
|
1347
|
+
readonly code = "VALIDATION_FAILED";
|
|
1348
|
+
readonly fields: FieldValidationError[];
|
|
1349
|
+
constructor(fields: FieldValidationError[]);
|
|
1350
|
+
}
|
|
1351
|
+
type Mode = 'insert' | 'update';
|
|
1352
|
+
interface FieldDef {
|
|
1353
|
+
name?: string;
|
|
1354
|
+
type: string;
|
|
1355
|
+
required?: boolean;
|
|
1356
|
+
readonly?: boolean;
|
|
1357
|
+
system?: boolean;
|
|
1358
|
+
multiple?: boolean;
|
|
1359
|
+
maxLength?: number;
|
|
1360
|
+
minLength?: number;
|
|
1361
|
+
min?: number;
|
|
1362
|
+
max?: number;
|
|
1363
|
+
options?: Array<{
|
|
1364
|
+
value: string | number;
|
|
1365
|
+
label?: string;
|
|
1366
|
+
} | string | number>;
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Validate a payload against a list of declared fields. `objectSchema`
|
|
1370
|
+
* comes from `ObjectQL.getRegistry().getObject(name)` and exposes a
|
|
1371
|
+
* `fields` map of `{ [fieldName]: FieldDef }`.
|
|
1372
|
+
*
|
|
1373
|
+
* Returns void on success; throws `ValidationError` on failure.
|
|
1374
|
+
*/
|
|
1375
|
+
declare function validateRecord(objectSchema: {
|
|
1376
|
+
fields?: Record<string, FieldDef>;
|
|
1377
|
+
} | undefined | null, data: Record<string, unknown> | undefined | null, mode: Mode): void;
|
|
1378
|
+
|
|
1837
1379
|
/**
|
|
1838
1380
|
* MetadataFacade
|
|
1839
1381
|
*
|
|
@@ -1843,8 +1385,14 @@ declare class ScopedContext {
|
|
|
1843
1385
|
*
|
|
1844
1386
|
* Implements the async IMetadataService interface.
|
|
1845
1387
|
* Internally delegates to SchemaRegistry (in-memory) with Promise wrappers.
|
|
1388
|
+
*
|
|
1389
|
+
* Each facade is bound to a specific SchemaRegistry instance — passed in the
|
|
1390
|
+
* constructor — so that multi-kernel servers can give every kernel its own
|
|
1391
|
+
* metadata surface without leaking state across tenants.
|
|
1846
1392
|
*/
|
|
1847
1393
|
declare class MetadataFacade {
|
|
1394
|
+
private registry;
|
|
1395
|
+
constructor(registry: SchemaRegistry);
|
|
1848
1396
|
/**
|
|
1849
1397
|
* Register a metadata item
|
|
1850
1398
|
*/
|
|
@@ -1887,25 +1435,86 @@ declare class MetadataFacade {
|
|
|
1887
1435
|
listObjects(): Promise<any[]>;
|
|
1888
1436
|
}
|
|
1889
1437
|
|
|
1438
|
+
/**
|
|
1439
|
+
* Options for ObjectQLPlugin.
|
|
1440
|
+
*
|
|
1441
|
+
* `projectId` scopes all metadata writes + reads to a specific project.
|
|
1442
|
+
* When set, `protocol.saveMetaItem` stamps `project_id = <projectId>` on
|
|
1443
|
+
* new sys_metadata rows, and `protocol.loadMetaFromDb` filters by the same
|
|
1444
|
+
* column. Leave undefined in single-kernel / self-hosted mode — rows land
|
|
1445
|
+
* in the platform-global scope (project_id IS NULL).
|
|
1446
|
+
*/
|
|
1447
|
+
interface ObjectQLPluginOptions {
|
|
1448
|
+
/** Optional pre-built engine. When absent, one is lazily created in init. */
|
|
1449
|
+
ql?: ObjectQL;
|
|
1450
|
+
/** Passed to `new ObjectQL(...)` when `ql` is not supplied. */
|
|
1451
|
+
hostContext?: Record<string, any>;
|
|
1452
|
+
/** Scope sys_metadata reads/writes to this project. */
|
|
1453
|
+
projectId?: string;
|
|
1454
|
+
/**
|
|
1455
|
+
* Override the kernel's default plugin-start timeout for this plugin.
|
|
1456
|
+
* Defaults to 120000 (120s). Schema sync to a remote SQL backend
|
|
1457
|
+
* (Neon/Postgres/Turso) is latency-bound — the SQL driver currently
|
|
1458
|
+
* does NOT support `batchSchemaSync`, so it issues one round-trip per
|
|
1459
|
+
* registered object × twice (Phase 1 + Phase 3 in `start()`). On a
|
|
1460
|
+
* cold remote DB with N tables this can blow past the kernel's
|
|
1461
|
+
* default 30s easily, even though everything is healthy.
|
|
1462
|
+
*/
|
|
1463
|
+
startupTimeout?: number;
|
|
1464
|
+
/**
|
|
1465
|
+
* Skip both `syncRegisteredSchemas()` calls inside `start()` and
|
|
1466
|
+
* assume DDL is managed out-of-band (e.g. an `apps/cloud/scripts/migrate.ts`
|
|
1467
|
+
* run before deploy that connects directly to the database and creates
|
|
1468
|
+
* all `sys_*` + custom tables once).
|
|
1469
|
+
*
|
|
1470
|
+
* Use this on cold-start-sensitive runtimes (Cloudflare Containers,
|
|
1471
|
+
* Lambda) where the platform's inbound-request budget is shorter than
|
|
1472
|
+
* a fresh remote-DB schema sync. The plugin still hydrates the
|
|
1473
|
+
* SchemaRegistry from `sys_metadata` (Phase 2), so custom user
|
|
1474
|
+
* objects come up — they just aren't re-DDL'd on every cold boot.
|
|
1475
|
+
*
|
|
1476
|
+
* Falls back to `process.env.OS_SKIP_SCHEMA_SYNC === '1'` when the
|
|
1477
|
+
* option is unset, so containers can flip it via their env without a
|
|
1478
|
+
* code change.
|
|
1479
|
+
*/
|
|
1480
|
+
skipSchemaSync?: boolean;
|
|
1481
|
+
}
|
|
1890
1482
|
declare class ObjectQLPlugin implements Plugin {
|
|
1891
1483
|
name: string;
|
|
1892
1484
|
type: string;
|
|
1893
1485
|
version: string;
|
|
1486
|
+
/**
|
|
1487
|
+
* Schema sync to remote SQL DBs is latency-bound (one round-trip per
|
|
1488
|
+
* table × 2 phases). Default to 120s instead of the kernel's 30s so
|
|
1489
|
+
* cold Neon/Turso starts don't get killed mid-sync.
|
|
1490
|
+
*/
|
|
1491
|
+
startupTimeout: number;
|
|
1894
1492
|
private ql;
|
|
1895
1493
|
private hostContext?;
|
|
1896
|
-
|
|
1494
|
+
private projectId?;
|
|
1495
|
+
private skipSchemaSync;
|
|
1496
|
+
constructor(qlOrOptions?: ObjectQL | ObjectQLPluginOptions, hostContext?: Record<string, any>);
|
|
1897
1497
|
init: (ctx: PluginContext) => Promise<void>;
|
|
1898
1498
|
start: (ctx: PluginContext) => Promise<void>;
|
|
1899
1499
|
/**
|
|
1900
1500
|
* Register built-in audit hooks for auto-stamping created_by/updated_by
|
|
1901
|
-
* and fetching previousData for update/delete operations.
|
|
1501
|
+
* and fetching previousData for update/delete operations. These are
|
|
1502
|
+
* declared as canonical `Hook` metadata and bound through the same
|
|
1503
|
+
* `bindHooksToEngine` path used by `defineStack({ hooks })`, so the
|
|
1504
|
+
* engine's built-ins flow through the same rails as user code
|
|
1505
|
+
* (dogfooding the protocol).
|
|
1902
1506
|
*/
|
|
1903
1507
|
private registerAuditHooks;
|
|
1904
1508
|
/**
|
|
1905
|
-
*
|
|
1906
|
-
*
|
|
1509
|
+
* Tenant isolation moved to `@objectstack/plugin-security`'s
|
|
1510
|
+
* `member_default` permission set RLS
|
|
1511
|
+
* (`organization_id = current_user.organization_id`, with
|
|
1512
|
+
* field-existence guards). The legacy `registerTenantMiddleware`
|
|
1513
|
+
* method was removed because it (a) collided with SecurityPlugin's
|
|
1514
|
+
* RLS pipeline and (b) blindly filtered tables that don't have a
|
|
1515
|
+
* `tenant_id` column (e.g. `sys_organization`), returning 0 rows
|
|
1516
|
+
* instead of all rows.
|
|
1907
1517
|
*/
|
|
1908
|
-
private registerTenantMiddleware;
|
|
1909
1518
|
/**
|
|
1910
1519
|
* Synchronize all registered object schemas to the database.
|
|
1911
1520
|
*
|
|
@@ -2067,4 +1676,4 @@ declare function convertIntrospectedSchemaToObjects(introspectedSchema: Introspe
|
|
|
2067
1676
|
skipSystemColumns?: boolean;
|
|
2068
1677
|
}): ServiceObject[];
|
|
2069
1678
|
|
|
2070
|
-
export { DEFAULT_EXTENDER_PRIORITY, DEFAULT_OWNER_PRIORITY, type EngineMiddleware, type HookEntry, type HookHandler, type IntrospectedColumn, type IntrospectedForeignKey, type IntrospectedSchema, type IntrospectedTable, MetadataFacade, type ObjectContributor, ObjectQL, type ObjectQLHostContext, type ObjectQLKernelOptions, ObjectQLPlugin, ObjectRepository, ObjectStackProtocolImplementation, type OperationContext, RESERVED_NAMESPACES, SchemaRegistry, ScopedContext, computeFQN, convertIntrospectedSchemaToObjects, createObjectQLKernel, parseFQN, toTitleCase };
|
|
1679
|
+
export { type BindHooksOptions, type BindHooksResult, DEFAULT_EXTENDER_PRIORITY, DEFAULT_OWNER_PRIORITY, type EngineMiddleware, type FieldValidationError, type HookEntry, type HookHandler, type HookMetricLabel, type HookMetricOutcome, type HookMetricsRecorder, type HookSkipReason, InMemoryHookMetricsRecorder, type IntrospectedColumn, type IntrospectedForeignKey, type IntrospectedSchema, type IntrospectedTable, MetadataFacade, type ObjectContributor, ObjectQL, type ObjectQLHostContext, type ObjectQLKernelOptions, ObjectQLPlugin, ObjectRepository, ObjectStackProtocolImplementation, type OperationContext, RESERVED_NAMESPACES, SchemaRegistry, type SchemaRegistryOptions, ScopedContext, ValidationError, type WrapDeclarativeOptions, applyInMemoryAggregation, applySystemFields, bindHooksToEngine, bucketDateValue, computeFQN, convertIntrospectedSchemaToObjects, createObjectQLKernel, noopHookMetricsRecorder, parseFQN, toTitleCase, validateRecord, wrapDeclarativeHook };
|