@objectql/core 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -6
- package/dist/action.d.ts +7 -0
- package/dist/action.js +23 -0
- package/dist/action.js.map +1 -0
- package/dist/app.d.ts +28 -0
- package/dist/app.js +211 -0
- package/dist/app.js.map +1 -0
- package/dist/driver.d.ts +2 -17
- package/dist/driver.js +52 -0
- package/dist/driver.js.map +1 -1
- package/dist/hook.d.ts +8 -0
- package/dist/hook.js +25 -0
- package/dist/hook.js.map +1 -0
- package/dist/index.d.ts +8 -25
- package/dist/index.js +8 -141
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +9 -4
- package/dist/loader.js +206 -9
- package/dist/loader.js.map +1 -1
- package/dist/object.d.ts +3 -0
- package/dist/object.js +28 -0
- package/dist/object.js.map +1 -0
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +56 -0
- package/dist/plugin.js.map +1 -0
- package/dist/remote.d.ts +8 -0
- package/dist/remote.js +43 -0
- package/dist/remote.js.map +1 -0
- package/dist/repository.d.ts +3 -5
- package/dist/repository.js +107 -112
- package/dist/repository.js.map +1 -1
- package/jest.config.js +3 -0
- package/package.json +11 -7
- package/src/action.ts +40 -0
- package/src/app.ts +257 -0
- package/src/driver.ts +51 -21
- package/src/hook.ts +42 -0
- package/src/index.ts +8 -158
- package/src/loader.ts +184 -9
- package/src/object.ts +26 -0
- package/src/plugin.ts +53 -0
- package/src/remote.ts +50 -0
- package/src/repository.ts +123 -127
- package/test/action.test.ts +58 -0
- package/test/fixtures/project.action.js +8 -0
- package/test/hook.test.ts +60 -0
- package/test/loader.test.ts +1 -8
- package/test/metadata.test.ts +1 -1
- package/test/mock-driver.ts +1 -1
- package/test/remote.test.ts +119 -0
- package/test/repository.test.ts +42 -49
- package/test/utils.ts +54 -0
- package/tsconfig.json +7 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/README.md +0 -53
- package/dist/metadata.d.ts +0 -104
- package/dist/metadata.js +0 -3
- package/dist/metadata.js.map +0 -1
- package/dist/query.d.ts +0 -10
- package/dist/query.js +0 -3
- package/dist/query.js.map +0 -1
- package/dist/registry.d.ts +0 -4
- package/dist/registry.js +0 -8
- package/dist/registry.js.map +0 -1
- package/dist/types.d.ts +0 -83
- package/dist/types.js +0 -6
- package/dist/types.js.map +0 -1
- package/src/metadata.ts +0 -143
- package/src/query.ts +0 -11
- package/src/registry.ts +0 -6
- package/src/types.ts +0 -115
- package/test/fixtures/project.action.ts +0 -6
package/README.md
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# @objectql/core
|
|
2
|
-
|
|
3
|
-
The core ORM and runtime engine for ObjectQL. This package handles object querying, CRUD operations, database driver coordination, and transaction management.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Unified Query Language**: A generic way to query data across different databases (SQL, Mongo, etc.).
|
|
8
|
-
- **Repository Pattern**: `ObjectRepository` for managing object records.
|
|
9
|
-
- **Driver Agnostic**: Abstraction layer for database drivers.
|
|
10
|
-
- **Dynamic Schema**: Loads object definitions from `@objectql/metadata`.
|
|
11
|
-
- **Hooks & Actions**: Runtime logic injection.
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install @objectql/core
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Usage
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
import { ObjectQL } from '@objectql/core';
|
|
23
|
-
import { MetadataRegistry } from '@objectql/metadata';
|
|
24
|
-
// Import a driver, e.g., @objectql/driver-knex
|
|
25
|
-
|
|
26
|
-
const objectql = new ObjectQL({
|
|
27
|
-
datasources: {
|
|
28
|
-
default: new MyDriver({ ... })
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
await objectql.init();
|
|
33
|
-
|
|
34
|
-
// Use context for operations
|
|
35
|
-
const ctx = objectql.createContext({ userId: 'u-1' });
|
|
36
|
-
const projects = await ctx.object('project').find({
|
|
37
|
-
filters: [['status', '=', 'active']]
|
|
38
|
-
});
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Shared Metadata
|
|
42
|
-
|
|
43
|
-
You can pass an existing `MetadataRegistry` (e.g., from a low-code platform loader) to ObjectQL:
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
const registry = new MetadataRegistry();
|
|
47
|
-
// ... pre-load metadata ...
|
|
48
|
-
|
|
49
|
-
const objectql = new ObjectQL({
|
|
50
|
-
registry: registry,
|
|
51
|
-
datasources: { ... }
|
|
52
|
-
});
|
|
53
|
-
```
|
package/dist/metadata.d.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents the supported field data types in the ObjectQL schema.
|
|
3
|
-
* These types determine how data is stored, validated, and rendered.
|
|
4
|
-
*
|
|
5
|
-
* - `text`: Simple string.
|
|
6
|
-
* - `textarea`: Long string.
|
|
7
|
-
* - `select`: Choice from a list.
|
|
8
|
-
* - `lookup`: Relationship to another object.
|
|
9
|
-
*/
|
|
10
|
-
export type FieldType = 'text' | 'textarea' | 'html' | 'select' | 'multiselect' | 'date' | 'datetime' | 'number' | 'currency' | 'boolean' | 'lookup' | 'master_detail' | 'password' | 'object' | 'grid';
|
|
11
|
-
/**
|
|
12
|
-
* Defines a single option for select/multiselect fields.
|
|
13
|
-
*/
|
|
14
|
-
export interface FieldOption {
|
|
15
|
-
/** The display label for the option. */
|
|
16
|
-
label: string;
|
|
17
|
-
/** The actual value stored in the database. */
|
|
18
|
-
value: string | number;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Configuration for a single field on an object.
|
|
22
|
-
* This defines the schema, validation rules, and UI hints for the attribute.
|
|
23
|
-
*/
|
|
24
|
-
export interface FieldConfig {
|
|
25
|
-
/**
|
|
26
|
-
* The unique API name of the field.
|
|
27
|
-
* If defined within an object map, this is often automatically populated from the key.
|
|
28
|
-
*/
|
|
29
|
-
name?: string;
|
|
30
|
-
/** The human-readable label used in UIs. */
|
|
31
|
-
label?: string;
|
|
32
|
-
/** The data type of the field. */
|
|
33
|
-
type: FieldType;
|
|
34
|
-
/** Whether the field is mandatory. Defaults to false. */
|
|
35
|
-
required?: boolean;
|
|
36
|
-
/** The default value if not provided during creation. */
|
|
37
|
-
defaultValue?: any;
|
|
38
|
-
/**
|
|
39
|
-
* Options available for `select` or `multiselect` types.
|
|
40
|
-
* Can be an array of strings or {@link FieldOption} objects.
|
|
41
|
-
*/
|
|
42
|
-
options?: FieldOption[] | string[];
|
|
43
|
-
/** Number of decimal places for `currency` types (e.g., 2). */
|
|
44
|
-
scale?: number;
|
|
45
|
-
/** Total number of digits for `number` types. */
|
|
46
|
-
precision?: number;
|
|
47
|
-
/**
|
|
48
|
-
* The API name of the target object.
|
|
49
|
-
* Required when type is `lookup` or `master_detail`.
|
|
50
|
-
*/
|
|
51
|
-
reference_to?: string;
|
|
52
|
-
/** Implementation hint: Whether this field should be indexed for search. */
|
|
53
|
-
searchable?: boolean;
|
|
54
|
-
/** Implementation hint: Whether this field is sortable in lists. */
|
|
55
|
-
sortable?: boolean;
|
|
56
|
-
/** Implementation hint: Whether to create a database index for this column. */
|
|
57
|
-
index?: boolean;
|
|
58
|
-
/** Description for documentation purposes. */
|
|
59
|
-
description?: string;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Configuration for a custom action (RPC).
|
|
63
|
-
*/
|
|
64
|
-
export interface ActionConfig {
|
|
65
|
-
label?: string;
|
|
66
|
-
description?: string;
|
|
67
|
-
/** Output/Result type definition. */
|
|
68
|
-
result?: {
|
|
69
|
-
type: FieldType;
|
|
70
|
-
};
|
|
71
|
-
/** Input parameters schema. */
|
|
72
|
-
params?: Record<string, FieldConfig>;
|
|
73
|
-
/** Implementation of the action. */
|
|
74
|
-
handler?: (ctx: any, params: any) => Promise<any>;
|
|
75
|
-
}
|
|
76
|
-
import { HookFunction } from './types';
|
|
77
|
-
export interface ObjectListeners {
|
|
78
|
-
beforeCreate?: HookFunction;
|
|
79
|
-
afterCreate?: HookFunction;
|
|
80
|
-
beforeUpdate?: HookFunction;
|
|
81
|
-
afterUpdate?: HookFunction;
|
|
82
|
-
beforeDelete?: HookFunction;
|
|
83
|
-
afterDelete?: HookFunction;
|
|
84
|
-
beforeFind?: HookFunction;
|
|
85
|
-
afterFind?: HookFunction;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Configuration for a business object (Entity).
|
|
89
|
-
* Analogous to a Database Table or MongoDB Collection.
|
|
90
|
-
*/
|
|
91
|
-
export interface ObjectConfig {
|
|
92
|
-
name: string;
|
|
93
|
-
datasource?: string;
|
|
94
|
-
label?: string;
|
|
95
|
-
icon?: string;
|
|
96
|
-
description?: string;
|
|
97
|
-
fields: Record<string, FieldConfig>;
|
|
98
|
-
/** Custom Actions (RPC) defined on this object. */
|
|
99
|
-
actions?: Record<string, ActionConfig>;
|
|
100
|
-
/** Lifecycle hooks. */
|
|
101
|
-
listeners?: ObjectListeners;
|
|
102
|
-
/** Initial data to populate when system starts. */
|
|
103
|
-
data?: any[];
|
|
104
|
-
}
|
package/dist/metadata.js
DELETED
package/dist/metadata.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":""}
|
package/dist/query.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export type FilterCriterion = [string, string, any];
|
|
2
|
-
export type FilterExpression = FilterCriterion | 'and' | 'or' | FilterExpression[];
|
|
3
|
-
export interface UnifiedQuery {
|
|
4
|
-
fields?: string[];
|
|
5
|
-
filters?: FilterExpression[];
|
|
6
|
-
sort?: [string, 'asc' | 'desc'][];
|
|
7
|
-
skip?: number;
|
|
8
|
-
limit?: number;
|
|
9
|
-
expand?: Record<string, UnifiedQuery>;
|
|
10
|
-
}
|
package/dist/query.js
DELETED
package/dist/query.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":""}
|
package/dist/registry.d.ts
DELETED
package/dist/registry.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MetadataRegistry = void 0;
|
|
4
|
-
const metadata_1 = require("@objectql/metadata");
|
|
5
|
-
class MetadataRegistry extends metadata_1.MetadataRegistry {
|
|
6
|
-
}
|
|
7
|
-
exports.MetadataRegistry = MetadataRegistry;
|
|
8
|
-
//# sourceMappingURL=registry.js.map
|
package/dist/registry.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":";;;AAAA,iDAAgF;AAGhF,MAAa,gBAAiB,SAAQ,2BAAY;CAEjD;AAFD,4CAEC"}
|
package/dist/types.d.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { ObjectRepository } from "./repository";
|
|
2
|
-
import { ObjectConfig } from "./metadata";
|
|
3
|
-
import { Driver } from "./driver";
|
|
4
|
-
import { UnifiedQuery, FilterCriterion } from "./query";
|
|
5
|
-
import { MetadataRegistry } from "./registry";
|
|
6
|
-
export { ObjectConfig } from "./metadata";
|
|
7
|
-
export { MetadataRegistry } from "./registry";
|
|
8
|
-
export interface ObjectQLConfig {
|
|
9
|
-
registry?: MetadataRegistry;
|
|
10
|
-
datasources: Record<string, Driver>;
|
|
11
|
-
objects?: Record<string, ObjectConfig>;
|
|
12
|
-
packages?: string[];
|
|
13
|
-
}
|
|
14
|
-
export interface IObjectQL {
|
|
15
|
-
getObject(name: string): ObjectConfig | undefined;
|
|
16
|
-
getConfigs(): Record<string, ObjectConfig>;
|
|
17
|
-
datasource(name: string): Driver;
|
|
18
|
-
init(): Promise<void>;
|
|
19
|
-
addPackage(name: string): void;
|
|
20
|
-
removePackage(name: string): void;
|
|
21
|
-
metadata: MetadataRegistry;
|
|
22
|
-
}
|
|
23
|
-
export interface HookContext<T = any> {
|
|
24
|
-
ctx: ObjectQLContext;
|
|
25
|
-
entity: string;
|
|
26
|
-
op: 'find' | 'create' | 'update' | 'delete' | 'count' | 'aggregate';
|
|
27
|
-
doc?: T;
|
|
28
|
-
query?: UnifiedQuery;
|
|
29
|
-
getPreviousDoc: () => Promise<T | undefined>;
|
|
30
|
-
utils: {
|
|
31
|
-
/**
|
|
32
|
-
* Safely injects a new filter criterion into the existing AST.
|
|
33
|
-
* It wraps existing filters in a new group to preserve operator precedence.
|
|
34
|
-
* * Logic: (Existing_Filters) AND (New_Filter)
|
|
35
|
-
*/
|
|
36
|
-
restrict: (criterion: FilterCriterion) => void;
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
export type HookFunction = (context: HookContext) => Promise<void>;
|
|
40
|
-
export interface ObjectQLContext {
|
|
41
|
-
userId?: string;
|
|
42
|
-
spaceId?: string;
|
|
43
|
-
roles: string[];
|
|
44
|
-
/**
|
|
45
|
-
* Sudo Mode / System Bypass.
|
|
46
|
-
* - true: Bypasses all permission checks (CRUD, Field Level Security, Record Level Security).
|
|
47
|
-
* - false/undefined: Enforces all permission checks based on 'roles'.
|
|
48
|
-
*/
|
|
49
|
-
isSystem?: boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Trigger Control.
|
|
52
|
-
* - true: Skips all lifecycle hooks (beforeCreate, afterUpdate, etc.).
|
|
53
|
-
* - Useful for bulk data imports or raw data correction to prevent side effects.
|
|
54
|
-
* - Requires 'isSystem: true' (Security Safeguard).
|
|
55
|
-
*/
|
|
56
|
-
ignoreTriggers?: boolean;
|
|
57
|
-
/**
|
|
58
|
-
* Returns a repository proxy bound to this context.
|
|
59
|
-
* All operations performed via this proxy inherit userId, spaceId, and transaction.
|
|
60
|
-
*/
|
|
61
|
-
object(entityName: string): ObjectRepository;
|
|
62
|
-
/**
|
|
63
|
-
* Execute a function within a transaction.
|
|
64
|
-
* The callback receives a new context 'trxCtx' which inherits userId and spaceId from this context.
|
|
65
|
-
*/
|
|
66
|
-
transaction(callback: (trxCtx: ObjectQLContext) => Promise<any>): Promise<any>;
|
|
67
|
-
/**
|
|
68
|
-
* Returns a new context with system privileges (isSystem: true).
|
|
69
|
-
* It shares the same transaction scope as the current context.
|
|
70
|
-
*/
|
|
71
|
-
sudo(): ObjectQLContext;
|
|
72
|
-
/**
|
|
73
|
-
* Internal: Driver-specific transaction handle.
|
|
74
|
-
*/
|
|
75
|
-
transactionHandle?: any;
|
|
76
|
-
}
|
|
77
|
-
export interface ObjectQLContextOptions {
|
|
78
|
-
userId?: string;
|
|
79
|
-
spaceId?: string;
|
|
80
|
-
roles?: string[];
|
|
81
|
-
isSystem?: boolean;
|
|
82
|
-
ignoreTriggers?: boolean;
|
|
83
|
-
}
|
package/dist/types.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MetadataRegistry = void 0;
|
|
4
|
-
var registry_1 = require("./registry");
|
|
5
|
-
Object.defineProperty(exports, "MetadataRegistry", { enumerable: true, get: function () { return registry_1.MetadataRegistry; } });
|
|
6
|
-
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAOA,uCAA8C;AAArC,4GAAA,gBAAgB,OAAA"}
|
package/src/metadata.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents the supported field data types in the ObjectQL schema.
|
|
3
|
-
* These types determine how data is stored, validated, and rendered.
|
|
4
|
-
*
|
|
5
|
-
* - `text`: Simple string.
|
|
6
|
-
* - `textarea`: Long string.
|
|
7
|
-
* - `select`: Choice from a list.
|
|
8
|
-
* - `lookup`: Relationship to another object.
|
|
9
|
-
*/
|
|
10
|
-
export type FieldType =
|
|
11
|
-
| 'text'
|
|
12
|
-
| 'textarea'
|
|
13
|
-
| 'html'
|
|
14
|
-
| 'select'
|
|
15
|
-
| 'multiselect'
|
|
16
|
-
| 'date'
|
|
17
|
-
| 'datetime'
|
|
18
|
-
| 'number'
|
|
19
|
-
| 'currency'
|
|
20
|
-
| 'boolean'
|
|
21
|
-
| 'lookup'
|
|
22
|
-
| 'master_detail'
|
|
23
|
-
| 'password'
|
|
24
|
-
| 'object'
|
|
25
|
-
| 'grid';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Defines a single option for select/multiselect fields.
|
|
29
|
-
*/
|
|
30
|
-
export interface FieldOption {
|
|
31
|
-
/** The display label for the option. */
|
|
32
|
-
label: string;
|
|
33
|
-
/** The actual value stored in the database. */
|
|
34
|
-
value: string | number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Configuration for a single field on an object.
|
|
39
|
-
* This defines the schema, validation rules, and UI hints for the attribute.
|
|
40
|
-
*/
|
|
41
|
-
export interface FieldConfig {
|
|
42
|
-
/**
|
|
43
|
-
* The unique API name of the field.
|
|
44
|
-
* If defined within an object map, this is often automatically populated from the key.
|
|
45
|
-
*/
|
|
46
|
-
name?: string;
|
|
47
|
-
|
|
48
|
-
/** The human-readable label used in UIs. */
|
|
49
|
-
label?: string;
|
|
50
|
-
|
|
51
|
-
/** The data type of the field. */
|
|
52
|
-
type: FieldType;
|
|
53
|
-
|
|
54
|
-
/** Whether the field is mandatory. Defaults to false. */
|
|
55
|
-
required?: boolean;
|
|
56
|
-
|
|
57
|
-
/** The default value if not provided during creation. */
|
|
58
|
-
defaultValue?: any;
|
|
59
|
-
|
|
60
|
-
// String options
|
|
61
|
-
/**
|
|
62
|
-
* Options available for `select` or `multiselect` types.
|
|
63
|
-
* Can be an array of strings or {@link FieldOption} objects.
|
|
64
|
-
*/
|
|
65
|
-
options?: FieldOption[] | string[];
|
|
66
|
-
|
|
67
|
-
// Number options
|
|
68
|
-
/** Number of decimal places for `currency` types (e.g., 2). */
|
|
69
|
-
scale?: number;
|
|
70
|
-
/** Total number of digits for `number` types. */
|
|
71
|
-
precision?: number;
|
|
72
|
-
|
|
73
|
-
// Relationship properties
|
|
74
|
-
/**
|
|
75
|
-
* The API name of the target object.
|
|
76
|
-
* Required when type is `lookup` or `master_detail`.
|
|
77
|
-
*/
|
|
78
|
-
reference_to?: string;
|
|
79
|
-
|
|
80
|
-
// UI properties (kept for compatibility, though ObjectQL is a query engine)
|
|
81
|
-
/** Implementation hint: Whether this field should be indexed for search. */
|
|
82
|
-
searchable?: boolean;
|
|
83
|
-
/** Implementation hint: Whether this field is sortable in lists. */
|
|
84
|
-
sortable?: boolean;
|
|
85
|
-
/** Implementation hint: Whether to create a database index for this column. */
|
|
86
|
-
index?: boolean;
|
|
87
|
-
|
|
88
|
-
// Other properties
|
|
89
|
-
/** Description for documentation purposes. */
|
|
90
|
-
description?: string;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Configuration for a custom action (RPC).
|
|
95
|
-
*/
|
|
96
|
-
export interface ActionConfig {
|
|
97
|
-
label?: string;
|
|
98
|
-
description?: string;
|
|
99
|
-
/** Output/Result type definition. */
|
|
100
|
-
result?: {
|
|
101
|
-
type: FieldType;
|
|
102
|
-
};
|
|
103
|
-
/** Input parameters schema. */
|
|
104
|
-
params?: Record<string, FieldConfig>;
|
|
105
|
-
/** Implementation of the action. */
|
|
106
|
-
handler?: (ctx: any, params: any) => Promise<any>;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
import { HookFunction } from './types';
|
|
110
|
-
|
|
111
|
-
export interface ObjectListeners {
|
|
112
|
-
beforeCreate?: HookFunction;
|
|
113
|
-
afterCreate?: HookFunction;
|
|
114
|
-
beforeUpdate?: HookFunction;
|
|
115
|
-
afterUpdate?: HookFunction;
|
|
116
|
-
beforeDelete?: HookFunction;
|
|
117
|
-
afterDelete?: HookFunction;
|
|
118
|
-
beforeFind?: HookFunction;
|
|
119
|
-
afterFind?: HookFunction;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Configuration for a business object (Entity).
|
|
124
|
-
* Analogous to a Database Table or MongoDB Collection.
|
|
125
|
-
*/
|
|
126
|
-
export interface ObjectConfig {
|
|
127
|
-
name: string;
|
|
128
|
-
datasource?: string; // The name of the datasource to use
|
|
129
|
-
label?: string;
|
|
130
|
-
icon?: string;
|
|
131
|
-
description?: string;
|
|
132
|
-
|
|
133
|
-
fields: Record<string, FieldConfig>;
|
|
134
|
-
|
|
135
|
-
/** Custom Actions (RPC) defined on this object. */
|
|
136
|
-
actions?: Record<string, ActionConfig>;
|
|
137
|
-
|
|
138
|
-
/** Lifecycle hooks. */
|
|
139
|
-
listeners?: ObjectListeners;
|
|
140
|
-
|
|
141
|
-
/** Initial data to populate when system starts. */
|
|
142
|
-
data?: any[];
|
|
143
|
-
}
|
package/src/query.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export type FilterCriterion = [string, string, any];
|
|
2
|
-
export type FilterExpression = FilterCriterion | 'and' | 'or' | FilterExpression[];
|
|
3
|
-
|
|
4
|
-
export interface UnifiedQuery {
|
|
5
|
-
fields?: string[];
|
|
6
|
-
filters?: FilterExpression[];
|
|
7
|
-
sort?: [string, 'asc' | 'desc'][];
|
|
8
|
-
skip?: number;
|
|
9
|
-
limit?: number;
|
|
10
|
-
expand?: Record<string, UnifiedQuery>;
|
|
11
|
-
}
|
package/src/registry.ts
DELETED
package/src/types.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { ObjectRepository } from "./repository";
|
|
2
|
-
import { ObjectConfig } from "./metadata";
|
|
3
|
-
import { Driver } from "./driver";
|
|
4
|
-
import { UnifiedQuery, FilterCriterion } from "./query";
|
|
5
|
-
import { MetadataRegistry } from "./registry";
|
|
6
|
-
|
|
7
|
-
export { ObjectConfig } from "./metadata";
|
|
8
|
-
export { MetadataRegistry } from "./registry";
|
|
9
|
-
|
|
10
|
-
export interface ObjectQLConfig {
|
|
11
|
-
registry?: MetadataRegistry;
|
|
12
|
-
datasources: Record<string, Driver>;
|
|
13
|
-
objects?: Record<string, ObjectConfig>;
|
|
14
|
-
packages?: string[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface IObjectQL {
|
|
18
|
-
getObject(name: string): ObjectConfig | undefined;
|
|
19
|
-
getConfigs(): Record<string, ObjectConfig>;
|
|
20
|
-
datasource(name: string): Driver;
|
|
21
|
-
init(): Promise<void>;
|
|
22
|
-
addPackage(name: string): void;
|
|
23
|
-
removePackage(name: string): void;
|
|
24
|
-
metadata: MetadataRegistry;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface HookContext<T = any> {
|
|
28
|
-
// === 1. The Session Context ===
|
|
29
|
-
// Automatically propagates userId, spaceId, and Transaction.
|
|
30
|
-
ctx: ObjectQLContext;
|
|
31
|
-
|
|
32
|
-
// === 2. Operational Info ===
|
|
33
|
-
entity: string;
|
|
34
|
-
op: 'find' | 'create' | 'update' | 'delete' | 'count' | 'aggregate';
|
|
35
|
-
|
|
36
|
-
// === 3. Data Payload (Mutable) ===
|
|
37
|
-
// - In beforeCreate/Update: The data to be written.
|
|
38
|
-
// - In afterCreate/Update: The result record returned from DB.
|
|
39
|
-
doc?: T;
|
|
40
|
-
|
|
41
|
-
// === 4. Query Context (Mutable, for 'find' only) ===
|
|
42
|
-
// Complies strictly with the UnifiedQuery JSON-DSL (AST).
|
|
43
|
-
// Developers can modify 'fields', 'sort', or wrap 'filters'.
|
|
44
|
-
query?: UnifiedQuery;
|
|
45
|
-
|
|
46
|
-
// === 5. Helpers ===
|
|
47
|
-
getPreviousDoc: () => Promise<T | undefined>;
|
|
48
|
-
|
|
49
|
-
// AST Manipulation Utilities
|
|
50
|
-
utils: {
|
|
51
|
-
/**
|
|
52
|
-
* Safely injects a new filter criterion into the existing AST.
|
|
53
|
-
* It wraps existing filters in a new group to preserve operator precedence.
|
|
54
|
-
* * Logic: (Existing_Filters) AND (New_Filter)
|
|
55
|
-
*/
|
|
56
|
-
restrict: (criterion: FilterCriterion) => void;
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export type HookFunction = (context: HookContext) => Promise<void>;
|
|
61
|
-
|
|
62
|
-
export interface ObjectQLContext {
|
|
63
|
-
// === Identity & Isolation ===
|
|
64
|
-
userId?: string; // Current User ID
|
|
65
|
-
spaceId?: string; // Multi-tenancy Isolation (Organization ID)
|
|
66
|
-
roles: string[]; // RBAC Roles
|
|
67
|
-
|
|
68
|
-
// === Execution Flags ===
|
|
69
|
-
/**
|
|
70
|
-
* Sudo Mode / System Bypass.
|
|
71
|
-
* - true: Bypasses all permission checks (CRUD, Field Level Security, Record Level Security).
|
|
72
|
-
* - false/undefined: Enforces all permission checks based on 'roles'.
|
|
73
|
-
*/
|
|
74
|
-
isSystem?: boolean;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Trigger Control.
|
|
78
|
-
* - true: Skips all lifecycle hooks (beforeCreate, afterUpdate, etc.).
|
|
79
|
-
* - Useful for bulk data imports or raw data correction to prevent side effects.
|
|
80
|
-
* - Requires 'isSystem: true' (Security Safeguard).
|
|
81
|
-
*/
|
|
82
|
-
ignoreTriggers?: boolean;
|
|
83
|
-
|
|
84
|
-
// === Data Entry Point ===
|
|
85
|
-
/**
|
|
86
|
-
* Returns a repository proxy bound to this context.
|
|
87
|
-
* All operations performed via this proxy inherit userId, spaceId, and transaction.
|
|
88
|
-
*/
|
|
89
|
-
object(entityName: string): ObjectRepository;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Execute a function within a transaction.
|
|
93
|
-
* The callback receives a new context 'trxCtx' which inherits userId and spaceId from this context.
|
|
94
|
-
*/
|
|
95
|
-
transaction(callback: (trxCtx: ObjectQLContext) => Promise<any>): Promise<any>;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Returns a new context with system privileges (isSystem: true).
|
|
99
|
-
* It shares the same transaction scope as the current context.
|
|
100
|
-
*/
|
|
101
|
-
sudo(): ObjectQLContext;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Internal: Driver-specific transaction handle.
|
|
105
|
-
*/
|
|
106
|
-
transactionHandle?: any;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface ObjectQLContextOptions {
|
|
110
|
-
userId?: string;
|
|
111
|
-
spaceId?: string;
|
|
112
|
-
roles?: string[];
|
|
113
|
-
isSystem?: boolean;
|
|
114
|
-
ignoreTriggers?: boolean;
|
|
115
|
-
}
|