@objectstack/objectql 2.0.7 → 3.0.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +13 -0
- package/dist/index.d.mts +78 -5
- package/dist/index.d.ts +78 -5
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +119 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/engine.ts +143 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @objectstack/objectql@
|
|
2
|
+
> @objectstack/objectql@3.0.0 build /home/runner/work/spec/spec/packages/objectql
|
|
3
3
|
> tsup --config ../../tsup.config.ts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m75.55 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m152.89 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 120ms
|
|
16
|
+
[32mCJS[39m [1mdist/index.js [22m[32m77.09 KB[39m
|
|
17
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m153.77 KB[39m
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 127ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 13686ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m75.15 KB[39m
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m75.15 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @objectstack/objectql
|
|
2
2
|
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Release v3.0.0 — unified version bump for all ObjectStack packages.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @objectstack/spec@3.0.0
|
|
13
|
+
- @objectstack/core@3.0.0
|
|
14
|
+
- @objectstack/types@3.0.0
|
|
15
|
+
|
|
3
16
|
## 2.0.7
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -353,6 +353,8 @@ declare class SchemaRegistry {
|
|
|
353
353
|
threshold: number;
|
|
354
354
|
} | undefined;
|
|
355
355
|
} | undefined;
|
|
356
|
+
group?: string | undefined;
|
|
357
|
+
conditionalRequired?: string | undefined;
|
|
356
358
|
inlineHelpText?: string | undefined;
|
|
357
359
|
trackFeedHistory?: boolean | undefined;
|
|
358
360
|
caseSensitive?: boolean | undefined;
|
|
@@ -430,6 +432,12 @@ declare class SchemaRegistry {
|
|
|
430
432
|
description?: string | undefined;
|
|
431
433
|
}[]> | undefined;
|
|
432
434
|
}> | undefined;
|
|
435
|
+
displayNameField?: string | undefined;
|
|
436
|
+
recordName?: {
|
|
437
|
+
type: "text" | "autonumber";
|
|
438
|
+
displayFormat?: string | undefined;
|
|
439
|
+
startNumber?: number | undefined;
|
|
440
|
+
} | undefined;
|
|
433
441
|
titleFormat?: string | undefined;
|
|
434
442
|
compactLayout?: string[] | undefined;
|
|
435
443
|
search?: {
|
|
@@ -457,7 +465,7 @@ declare class SchemaRegistry {
|
|
|
457
465
|
label: string | {
|
|
458
466
|
key: string;
|
|
459
467
|
defaultValue?: string | undefined;
|
|
460
|
-
params?: Record<string,
|
|
468
|
+
params?: Record<string, string | number | boolean> | undefined;
|
|
461
469
|
};
|
|
462
470
|
active: boolean;
|
|
463
471
|
isDefault: boolean;
|
|
@@ -465,7 +473,7 @@ declare class SchemaRegistry {
|
|
|
465
473
|
description?: string | {
|
|
466
474
|
key: string;
|
|
467
475
|
defaultValue?: string | undefined;
|
|
468
|
-
params?: Record<string,
|
|
476
|
+
params?: Record<string, string | number | boolean> | undefined;
|
|
469
477
|
} | undefined;
|
|
470
478
|
icon?: string | undefined;
|
|
471
479
|
branding?: {
|
|
@@ -486,7 +494,7 @@ declare class SchemaRegistry {
|
|
|
486
494
|
ariaLabel?: string | {
|
|
487
495
|
key: string;
|
|
488
496
|
defaultValue?: string | undefined;
|
|
489
|
-
params?: Record<string,
|
|
497
|
+
params?: Record<string, string | number | boolean> | undefined;
|
|
490
498
|
} | undefined;
|
|
491
499
|
ariaDescribedBy?: string | undefined;
|
|
492
500
|
role?: string | undefined;
|
|
@@ -797,10 +805,12 @@ declare class SchemaRegistry {
|
|
|
797
805
|
} | undefined;
|
|
798
806
|
} | undefined;
|
|
799
807
|
};
|
|
800
|
-
status: "error" | "disabled" | "installed" | "installing" | "uninstalling";
|
|
808
|
+
status: "error" | "disabled" | "installed" | "installing" | "upgrading" | "uninstalling";
|
|
801
809
|
enabled: boolean;
|
|
802
810
|
installedAt?: string | undefined;
|
|
803
811
|
updatedAt?: string | undefined;
|
|
812
|
+
installedVersion?: string | undefined;
|
|
813
|
+
previousVersion?: string | undefined;
|
|
804
814
|
statusChangedAt?: string | undefined;
|
|
805
815
|
errorMessage?: string | undefined;
|
|
806
816
|
settings?: Record<string, unknown> | undefined;
|
|
@@ -1356,6 +1366,7 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1356
1366
|
private logger;
|
|
1357
1367
|
private hooks;
|
|
1358
1368
|
private middlewares;
|
|
1369
|
+
private actions;
|
|
1359
1370
|
private hostContext;
|
|
1360
1371
|
constructor(hostContext?: Record<string, any>);
|
|
1361
1372
|
/**
|
|
@@ -1387,6 +1398,24 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1387
1398
|
priority?: number;
|
|
1388
1399
|
}): void;
|
|
1389
1400
|
triggerHooks(event: string, context: HookContext): Promise<void>;
|
|
1401
|
+
/**
|
|
1402
|
+
* Register a named action on an object.
|
|
1403
|
+
* Actions are custom business logic callable via `repo.execute(actionName, params)`.
|
|
1404
|
+
*
|
|
1405
|
+
* @param objectName Target object
|
|
1406
|
+
* @param actionName Unique action name within the object
|
|
1407
|
+
* @param handler Handler function
|
|
1408
|
+
* @param packageName Optional package owner (for cleanup)
|
|
1409
|
+
*/
|
|
1410
|
+
registerAction(objectName: string, actionName: string, handler: (ctx: any) => Promise<any> | any, packageName?: string): void;
|
|
1411
|
+
/**
|
|
1412
|
+
* Execute a named action on an object.
|
|
1413
|
+
*/
|
|
1414
|
+
executeAction(objectName: string, actionName: string, ctx: any): Promise<any>;
|
|
1415
|
+
/**
|
|
1416
|
+
* Remove all actions registered by a specific package.
|
|
1417
|
+
*/
|
|
1418
|
+
removeActionsByPackage(packageName: string): void;
|
|
1390
1419
|
/**
|
|
1391
1420
|
* Register a middleware function
|
|
1392
1421
|
* Middlewares execute in onion model around every data operation.
|
|
@@ -1590,6 +1619,8 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1590
1619
|
threshold: number;
|
|
1591
1620
|
} | undefined;
|
|
1592
1621
|
} | undefined;
|
|
1622
|
+
group?: string | undefined;
|
|
1623
|
+
conditionalRequired?: string | undefined;
|
|
1593
1624
|
inlineHelpText?: string | undefined;
|
|
1594
1625
|
trackFeedHistory?: boolean | undefined;
|
|
1595
1626
|
caseSensitive?: boolean | undefined;
|
|
@@ -1667,6 +1698,12 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1667
1698
|
description?: string | undefined;
|
|
1668
1699
|
}[]> | undefined;
|
|
1669
1700
|
}> | undefined;
|
|
1701
|
+
displayNameField?: string | undefined;
|
|
1702
|
+
recordName?: {
|
|
1703
|
+
type: "text" | "autonumber";
|
|
1704
|
+
displayFormat?: string | undefined;
|
|
1705
|
+
startNumber?: number | undefined;
|
|
1706
|
+
} | undefined;
|
|
1670
1707
|
titleFormat?: string | undefined;
|
|
1671
1708
|
compactLayout?: string[] | undefined;
|
|
1672
1709
|
search?: {
|
|
@@ -1731,21 +1768,41 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1731
1768
|
}
|
|
1732
1769
|
/**
|
|
1733
1770
|
* Repository scoped to a single object, bound to an execution context.
|
|
1771
|
+
*
|
|
1772
|
+
* Provides both IDataEngine-style methods (find, insert, update, delete)
|
|
1773
|
+
* and convenience aliases (create, updateById, deleteById) matching
|
|
1774
|
+
* the @objectql/core ObjectRepository API.
|
|
1734
1775
|
*/
|
|
1735
1776
|
declare class ObjectRepository {
|
|
1736
1777
|
private objectName;
|
|
1737
1778
|
private context;
|
|
1738
1779
|
private engine;
|
|
1739
|
-
constructor(objectName: string, context: ExecutionContext, engine: IDataEngine
|
|
1780
|
+
constructor(objectName: string, context: ExecutionContext, engine: IDataEngine & {
|
|
1781
|
+
executeAction?: (o: string, a: string, c: any) => Promise<any>;
|
|
1782
|
+
});
|
|
1740
1783
|
find(query?: any): Promise<any[]>;
|
|
1741
1784
|
findOne(query?: any): Promise<any>;
|
|
1742
1785
|
insert(data: any): Promise<any>;
|
|
1786
|
+
/** Alias for insert() — matches @objectql/core convention */
|
|
1787
|
+
create(data: any): Promise<any>;
|
|
1743
1788
|
update(data: any, options?: any): Promise<any>;
|
|
1789
|
+
/** Update a single record by ID */
|
|
1790
|
+
updateById(id: string | number, data: any): Promise<any>;
|
|
1744
1791
|
delete(options?: any): Promise<any>;
|
|
1792
|
+
/** Delete a single record by ID */
|
|
1793
|
+
deleteById(id: string | number): Promise<any>;
|
|
1745
1794
|
count(query?: any): Promise<number>;
|
|
1795
|
+
/** Aggregate query */
|
|
1796
|
+
aggregate(query?: any): Promise<any[]>;
|
|
1797
|
+
/** Execute a named action registered on this object */
|
|
1798
|
+
execute(actionName: string, params?: any): Promise<any>;
|
|
1746
1799
|
}
|
|
1747
1800
|
/**
|
|
1748
1801
|
* Scoped execution context with object() accessor.
|
|
1802
|
+
*
|
|
1803
|
+
* Provides identity (userId, tenantId/spaceId, roles),
|
|
1804
|
+
* repository access via object(), privilege escalation via sudo(),
|
|
1805
|
+
* and transactional execution via transaction().
|
|
1749
1806
|
*/
|
|
1750
1807
|
declare class ScopedContext {
|
|
1751
1808
|
private executionContext;
|
|
@@ -1755,9 +1812,25 @@ declare class ScopedContext {
|
|
|
1755
1812
|
object(name: string): ObjectRepository;
|
|
1756
1813
|
/** Create an elevated (system) context */
|
|
1757
1814
|
sudo(): ScopedContext;
|
|
1815
|
+
/**
|
|
1816
|
+
* Execute a callback within a database transaction.
|
|
1817
|
+
*
|
|
1818
|
+
* The callback receives a new ScopedContext whose operations
|
|
1819
|
+
* share the same transaction handle. If the callback throws,
|
|
1820
|
+
* the transaction is rolled back; otherwise it is committed.
|
|
1821
|
+
*
|
|
1822
|
+
* Falls back to non-transactional execution if the driver
|
|
1823
|
+
* does not support transactions.
|
|
1824
|
+
*/
|
|
1825
|
+
transaction(callback: (trxCtx: ScopedContext) => Promise<any>): Promise<any>;
|
|
1758
1826
|
get userId(): string | undefined;
|
|
1759
1827
|
get tenantId(): string | undefined;
|
|
1828
|
+
/** Alias for tenantId — matches ObjectQLContext.spaceId convention */
|
|
1829
|
+
get spaceId(): string | undefined;
|
|
1760
1830
|
get roles(): string[];
|
|
1831
|
+
get isSystem(): boolean;
|
|
1832
|
+
/** Internal: expose the transaction handle for driver-level access */
|
|
1833
|
+
get transactionHandle(): unknown;
|
|
1761
1834
|
}
|
|
1762
1835
|
|
|
1763
1836
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -353,6 +353,8 @@ declare class SchemaRegistry {
|
|
|
353
353
|
threshold: number;
|
|
354
354
|
} | undefined;
|
|
355
355
|
} | undefined;
|
|
356
|
+
group?: string | undefined;
|
|
357
|
+
conditionalRequired?: string | undefined;
|
|
356
358
|
inlineHelpText?: string | undefined;
|
|
357
359
|
trackFeedHistory?: boolean | undefined;
|
|
358
360
|
caseSensitive?: boolean | undefined;
|
|
@@ -430,6 +432,12 @@ declare class SchemaRegistry {
|
|
|
430
432
|
description?: string | undefined;
|
|
431
433
|
}[]> | undefined;
|
|
432
434
|
}> | undefined;
|
|
435
|
+
displayNameField?: string | undefined;
|
|
436
|
+
recordName?: {
|
|
437
|
+
type: "text" | "autonumber";
|
|
438
|
+
displayFormat?: string | undefined;
|
|
439
|
+
startNumber?: number | undefined;
|
|
440
|
+
} | undefined;
|
|
433
441
|
titleFormat?: string | undefined;
|
|
434
442
|
compactLayout?: string[] | undefined;
|
|
435
443
|
search?: {
|
|
@@ -457,7 +465,7 @@ declare class SchemaRegistry {
|
|
|
457
465
|
label: string | {
|
|
458
466
|
key: string;
|
|
459
467
|
defaultValue?: string | undefined;
|
|
460
|
-
params?: Record<string,
|
|
468
|
+
params?: Record<string, string | number | boolean> | undefined;
|
|
461
469
|
};
|
|
462
470
|
active: boolean;
|
|
463
471
|
isDefault: boolean;
|
|
@@ -465,7 +473,7 @@ declare class SchemaRegistry {
|
|
|
465
473
|
description?: string | {
|
|
466
474
|
key: string;
|
|
467
475
|
defaultValue?: string | undefined;
|
|
468
|
-
params?: Record<string,
|
|
476
|
+
params?: Record<string, string | number | boolean> | undefined;
|
|
469
477
|
} | undefined;
|
|
470
478
|
icon?: string | undefined;
|
|
471
479
|
branding?: {
|
|
@@ -486,7 +494,7 @@ declare class SchemaRegistry {
|
|
|
486
494
|
ariaLabel?: string | {
|
|
487
495
|
key: string;
|
|
488
496
|
defaultValue?: string | undefined;
|
|
489
|
-
params?: Record<string,
|
|
497
|
+
params?: Record<string, string | number | boolean> | undefined;
|
|
490
498
|
} | undefined;
|
|
491
499
|
ariaDescribedBy?: string | undefined;
|
|
492
500
|
role?: string | undefined;
|
|
@@ -797,10 +805,12 @@ declare class SchemaRegistry {
|
|
|
797
805
|
} | undefined;
|
|
798
806
|
} | undefined;
|
|
799
807
|
};
|
|
800
|
-
status: "error" | "disabled" | "installed" | "installing" | "uninstalling";
|
|
808
|
+
status: "error" | "disabled" | "installed" | "installing" | "upgrading" | "uninstalling";
|
|
801
809
|
enabled: boolean;
|
|
802
810
|
installedAt?: string | undefined;
|
|
803
811
|
updatedAt?: string | undefined;
|
|
812
|
+
installedVersion?: string | undefined;
|
|
813
|
+
previousVersion?: string | undefined;
|
|
804
814
|
statusChangedAt?: string | undefined;
|
|
805
815
|
errorMessage?: string | undefined;
|
|
806
816
|
settings?: Record<string, unknown> | undefined;
|
|
@@ -1356,6 +1366,7 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1356
1366
|
private logger;
|
|
1357
1367
|
private hooks;
|
|
1358
1368
|
private middlewares;
|
|
1369
|
+
private actions;
|
|
1359
1370
|
private hostContext;
|
|
1360
1371
|
constructor(hostContext?: Record<string, any>);
|
|
1361
1372
|
/**
|
|
@@ -1387,6 +1398,24 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1387
1398
|
priority?: number;
|
|
1388
1399
|
}): void;
|
|
1389
1400
|
triggerHooks(event: string, context: HookContext): Promise<void>;
|
|
1401
|
+
/**
|
|
1402
|
+
* Register a named action on an object.
|
|
1403
|
+
* Actions are custom business logic callable via `repo.execute(actionName, params)`.
|
|
1404
|
+
*
|
|
1405
|
+
* @param objectName Target object
|
|
1406
|
+
* @param actionName Unique action name within the object
|
|
1407
|
+
* @param handler Handler function
|
|
1408
|
+
* @param packageName Optional package owner (for cleanup)
|
|
1409
|
+
*/
|
|
1410
|
+
registerAction(objectName: string, actionName: string, handler: (ctx: any) => Promise<any> | any, packageName?: string): void;
|
|
1411
|
+
/**
|
|
1412
|
+
* Execute a named action on an object.
|
|
1413
|
+
*/
|
|
1414
|
+
executeAction(objectName: string, actionName: string, ctx: any): Promise<any>;
|
|
1415
|
+
/**
|
|
1416
|
+
* Remove all actions registered by a specific package.
|
|
1417
|
+
*/
|
|
1418
|
+
removeActionsByPackage(packageName: string): void;
|
|
1390
1419
|
/**
|
|
1391
1420
|
* Register a middleware function
|
|
1392
1421
|
* Middlewares execute in onion model around every data operation.
|
|
@@ -1590,6 +1619,8 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1590
1619
|
threshold: number;
|
|
1591
1620
|
} | undefined;
|
|
1592
1621
|
} | undefined;
|
|
1622
|
+
group?: string | undefined;
|
|
1623
|
+
conditionalRequired?: string | undefined;
|
|
1593
1624
|
inlineHelpText?: string | undefined;
|
|
1594
1625
|
trackFeedHistory?: boolean | undefined;
|
|
1595
1626
|
caseSensitive?: boolean | undefined;
|
|
@@ -1667,6 +1698,12 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1667
1698
|
description?: string | undefined;
|
|
1668
1699
|
}[]> | undefined;
|
|
1669
1700
|
}> | undefined;
|
|
1701
|
+
displayNameField?: string | undefined;
|
|
1702
|
+
recordName?: {
|
|
1703
|
+
type: "text" | "autonumber";
|
|
1704
|
+
displayFormat?: string | undefined;
|
|
1705
|
+
startNumber?: number | undefined;
|
|
1706
|
+
} | undefined;
|
|
1670
1707
|
titleFormat?: string | undefined;
|
|
1671
1708
|
compactLayout?: string[] | undefined;
|
|
1672
1709
|
search?: {
|
|
@@ -1731,21 +1768,41 @@ declare class ObjectQL implements IDataEngine {
|
|
|
1731
1768
|
}
|
|
1732
1769
|
/**
|
|
1733
1770
|
* Repository scoped to a single object, bound to an execution context.
|
|
1771
|
+
*
|
|
1772
|
+
* Provides both IDataEngine-style methods (find, insert, update, delete)
|
|
1773
|
+
* and convenience aliases (create, updateById, deleteById) matching
|
|
1774
|
+
* the @objectql/core ObjectRepository API.
|
|
1734
1775
|
*/
|
|
1735
1776
|
declare class ObjectRepository {
|
|
1736
1777
|
private objectName;
|
|
1737
1778
|
private context;
|
|
1738
1779
|
private engine;
|
|
1739
|
-
constructor(objectName: string, context: ExecutionContext, engine: IDataEngine
|
|
1780
|
+
constructor(objectName: string, context: ExecutionContext, engine: IDataEngine & {
|
|
1781
|
+
executeAction?: (o: string, a: string, c: any) => Promise<any>;
|
|
1782
|
+
});
|
|
1740
1783
|
find(query?: any): Promise<any[]>;
|
|
1741
1784
|
findOne(query?: any): Promise<any>;
|
|
1742
1785
|
insert(data: any): Promise<any>;
|
|
1786
|
+
/** Alias for insert() — matches @objectql/core convention */
|
|
1787
|
+
create(data: any): Promise<any>;
|
|
1743
1788
|
update(data: any, options?: any): Promise<any>;
|
|
1789
|
+
/** Update a single record by ID */
|
|
1790
|
+
updateById(id: string | number, data: any): Promise<any>;
|
|
1744
1791
|
delete(options?: any): Promise<any>;
|
|
1792
|
+
/** Delete a single record by ID */
|
|
1793
|
+
deleteById(id: string | number): Promise<any>;
|
|
1745
1794
|
count(query?: any): Promise<number>;
|
|
1795
|
+
/** Aggregate query */
|
|
1796
|
+
aggregate(query?: any): Promise<any[]>;
|
|
1797
|
+
/** Execute a named action registered on this object */
|
|
1798
|
+
execute(actionName: string, params?: any): Promise<any>;
|
|
1746
1799
|
}
|
|
1747
1800
|
/**
|
|
1748
1801
|
* Scoped execution context with object() accessor.
|
|
1802
|
+
*
|
|
1803
|
+
* Provides identity (userId, tenantId/spaceId, roles),
|
|
1804
|
+
* repository access via object(), privilege escalation via sudo(),
|
|
1805
|
+
* and transactional execution via transaction().
|
|
1749
1806
|
*/
|
|
1750
1807
|
declare class ScopedContext {
|
|
1751
1808
|
private executionContext;
|
|
@@ -1755,9 +1812,25 @@ declare class ScopedContext {
|
|
|
1755
1812
|
object(name: string): ObjectRepository;
|
|
1756
1813
|
/** Create an elevated (system) context */
|
|
1757
1814
|
sudo(): ScopedContext;
|
|
1815
|
+
/**
|
|
1816
|
+
* Execute a callback within a database transaction.
|
|
1817
|
+
*
|
|
1818
|
+
* The callback receives a new ScopedContext whose operations
|
|
1819
|
+
* share the same transaction handle. If the callback throws,
|
|
1820
|
+
* the transaction is rolled back; otherwise it is committed.
|
|
1821
|
+
*
|
|
1822
|
+
* Falls back to non-transactional execution if the driver
|
|
1823
|
+
* does not support transactions.
|
|
1824
|
+
*/
|
|
1825
|
+
transaction(callback: (trxCtx: ScopedContext) => Promise<any>): Promise<any>;
|
|
1758
1826
|
get userId(): string | undefined;
|
|
1759
1827
|
get tenantId(): string | undefined;
|
|
1828
|
+
/** Alias for tenantId — matches ObjectQLContext.spaceId convention */
|
|
1829
|
+
get spaceId(): string | undefined;
|
|
1760
1830
|
get roles(): string[];
|
|
1831
|
+
get isSystem(): boolean;
|
|
1832
|
+
/** Internal: expose the transaction handle for driver-level access */
|
|
1833
|
+
get transactionHandle(): unknown;
|
|
1761
1834
|
}
|
|
1762
1835
|
|
|
1763
1836
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1120,6 +1120,8 @@ var ObjectQL = class {
|
|
|
1120
1120
|
]);
|
|
1121
1121
|
// Middleware chain (onion model)
|
|
1122
1122
|
this.middlewares = [];
|
|
1123
|
+
// Action registry: key = "objectName:actionName"
|
|
1124
|
+
this.actions = /* @__PURE__ */ new Map();
|
|
1123
1125
|
// Host provided context additions (e.g. Server router)
|
|
1124
1126
|
this.hostContext = {};
|
|
1125
1127
|
this.hostContext = hostContext;
|
|
@@ -1209,6 +1211,43 @@ var ObjectQL = class {
|
|
|
1209
1211
|
await entry.handler(context);
|
|
1210
1212
|
}
|
|
1211
1213
|
}
|
|
1214
|
+
// ========================================
|
|
1215
|
+
// Action System
|
|
1216
|
+
// ========================================
|
|
1217
|
+
/**
|
|
1218
|
+
* Register a named action on an object.
|
|
1219
|
+
* Actions are custom business logic callable via `repo.execute(actionName, params)`.
|
|
1220
|
+
*
|
|
1221
|
+
* @param objectName Target object
|
|
1222
|
+
* @param actionName Unique action name within the object
|
|
1223
|
+
* @param handler Handler function
|
|
1224
|
+
* @param packageName Optional package owner (for cleanup)
|
|
1225
|
+
*/
|
|
1226
|
+
registerAction(objectName, actionName, handler, packageName) {
|
|
1227
|
+
const key = `${objectName}:${actionName}`;
|
|
1228
|
+
this.actions.set(key, { handler, package: packageName });
|
|
1229
|
+
this.logger.debug("Registered action", { objectName, actionName, package: packageName });
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* Execute a named action on an object.
|
|
1233
|
+
*/
|
|
1234
|
+
async executeAction(objectName, actionName, ctx) {
|
|
1235
|
+
const entry = this.actions.get(`${objectName}:${actionName}`);
|
|
1236
|
+
if (!entry) {
|
|
1237
|
+
throw new Error(`Action '${actionName}' on object '${objectName}' not found`);
|
|
1238
|
+
}
|
|
1239
|
+
return entry.handler(ctx);
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* Remove all actions registered by a specific package.
|
|
1243
|
+
*/
|
|
1244
|
+
removeActionsByPackage(packageName) {
|
|
1245
|
+
for (const [key, entry] of this.actions.entries()) {
|
|
1246
|
+
if (entry.package === packageName) {
|
|
1247
|
+
this.actions.delete(key);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1212
1251
|
/**
|
|
1213
1252
|
* Register a middleware function
|
|
1214
1253
|
* Middlewares execute in onion model around every data operation.
|
|
@@ -1876,24 +1915,61 @@ var ObjectRepository = class {
|
|
|
1876
1915
|
context: this.context
|
|
1877
1916
|
});
|
|
1878
1917
|
}
|
|
1918
|
+
/** Alias for insert() — matches @objectql/core convention */
|
|
1919
|
+
async create(data) {
|
|
1920
|
+
return this.insert(data);
|
|
1921
|
+
}
|
|
1879
1922
|
async update(data, options = {}) {
|
|
1880
1923
|
return this.engine.update(this.objectName, data, {
|
|
1881
1924
|
...options,
|
|
1882
1925
|
context: this.context
|
|
1883
1926
|
});
|
|
1884
1927
|
}
|
|
1928
|
+
/** Update a single record by ID */
|
|
1929
|
+
async updateById(id, data) {
|
|
1930
|
+
return this.engine.update(this.objectName, { ...data, _id: id }, {
|
|
1931
|
+
filter: { _id: id },
|
|
1932
|
+
context: this.context
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1885
1935
|
async delete(options = {}) {
|
|
1886
1936
|
return this.engine.delete(this.objectName, {
|
|
1887
1937
|
...options,
|
|
1888
1938
|
context: this.context
|
|
1889
1939
|
});
|
|
1890
1940
|
}
|
|
1941
|
+
/** Delete a single record by ID */
|
|
1942
|
+
async deleteById(id) {
|
|
1943
|
+
return this.engine.delete(this.objectName, {
|
|
1944
|
+
filter: { _id: id },
|
|
1945
|
+
context: this.context
|
|
1946
|
+
});
|
|
1947
|
+
}
|
|
1891
1948
|
async count(query = {}) {
|
|
1892
1949
|
return this.engine.count(this.objectName, {
|
|
1893
1950
|
...query,
|
|
1894
1951
|
context: this.context
|
|
1895
1952
|
});
|
|
1896
1953
|
}
|
|
1954
|
+
/** Aggregate query */
|
|
1955
|
+
async aggregate(query = {}) {
|
|
1956
|
+
return this.engine.aggregate(this.objectName, {
|
|
1957
|
+
...query,
|
|
1958
|
+
context: this.context
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
/** Execute a named action registered on this object */
|
|
1962
|
+
async execute(actionName, params) {
|
|
1963
|
+
if (this.engine.executeAction) {
|
|
1964
|
+
return this.engine.executeAction(this.objectName, actionName, {
|
|
1965
|
+
...params,
|
|
1966
|
+
userId: this.context.userId,
|
|
1967
|
+
tenantId: this.context.tenantId,
|
|
1968
|
+
roles: this.context.roles
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
throw new Error(`Actions not supported by engine`);
|
|
1972
|
+
}
|
|
1897
1973
|
};
|
|
1898
1974
|
var ScopedContext = class _ScopedContext {
|
|
1899
1975
|
constructor(executionContext, engine) {
|
|
@@ -1911,15 +1987,58 @@ var ScopedContext = class _ScopedContext {
|
|
|
1911
1987
|
this.engine
|
|
1912
1988
|
);
|
|
1913
1989
|
}
|
|
1990
|
+
/**
|
|
1991
|
+
* Execute a callback within a database transaction.
|
|
1992
|
+
*
|
|
1993
|
+
* The callback receives a new ScopedContext whose operations
|
|
1994
|
+
* share the same transaction handle. If the callback throws,
|
|
1995
|
+
* the transaction is rolled back; otherwise it is committed.
|
|
1996
|
+
*
|
|
1997
|
+
* Falls back to non-transactional execution if the driver
|
|
1998
|
+
* does not support transactions.
|
|
1999
|
+
*/
|
|
2000
|
+
async transaction(callback) {
|
|
2001
|
+
const engine = this.engine;
|
|
2002
|
+
const driver = engine.defaultDriver ? engine.drivers?.get(engine.defaultDriver) : void 0;
|
|
2003
|
+
if (!driver?.beginTransaction) {
|
|
2004
|
+
return callback(this);
|
|
2005
|
+
}
|
|
2006
|
+
const trx = await driver.beginTransaction();
|
|
2007
|
+
const trxCtx = new _ScopedContext(
|
|
2008
|
+
{ ...this.executionContext, transaction: trx },
|
|
2009
|
+
this.engine
|
|
2010
|
+
);
|
|
2011
|
+
try {
|
|
2012
|
+
const result = await callback(trxCtx);
|
|
2013
|
+
if (driver.commit) await driver.commit(trx);
|
|
2014
|
+
else if (driver.commitTransaction) await driver.commitTransaction(trx);
|
|
2015
|
+
return result;
|
|
2016
|
+
} catch (error) {
|
|
2017
|
+
if (driver.rollback) await driver.rollback(trx);
|
|
2018
|
+
else if (driver.rollbackTransaction) await driver.rollbackTransaction(trx);
|
|
2019
|
+
throw error;
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
1914
2022
|
get userId() {
|
|
1915
2023
|
return this.executionContext.userId;
|
|
1916
2024
|
}
|
|
1917
2025
|
get tenantId() {
|
|
1918
2026
|
return this.executionContext.tenantId;
|
|
1919
2027
|
}
|
|
2028
|
+
/** Alias for tenantId — matches ObjectQLContext.spaceId convention */
|
|
2029
|
+
get spaceId() {
|
|
2030
|
+
return this.executionContext.tenantId;
|
|
2031
|
+
}
|
|
1920
2032
|
get roles() {
|
|
1921
2033
|
return this.executionContext.roles;
|
|
1922
2034
|
}
|
|
2035
|
+
get isSystem() {
|
|
2036
|
+
return this.executionContext.isSystem;
|
|
2037
|
+
}
|
|
2038
|
+
/** Internal: expose the transaction handle for driver-level access */
|
|
2039
|
+
get transactionHandle() {
|
|
2040
|
+
return this.executionContext.transaction;
|
|
2041
|
+
}
|
|
1923
2042
|
};
|
|
1924
2043
|
|
|
1925
2044
|
// src/metadata-facade.ts
|