@cadenza.io/service 2.3.17 → 2.4.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 +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +512 -56
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +512 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -330,10 +330,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
330
330
|
} = serviceInstance;
|
|
331
331
|
if (uuid4 === this.serviceInstanceId) return;
|
|
332
332
|
if (deleted) {
|
|
333
|
-
this.instances.get(serviceName)?.
|
|
334
|
-
|
|
335
|
-
1
|
|
336
|
-
|
|
333
|
+
const indexToDelete = this.instances.get(serviceName)?.findIndex((i) => i.uuid === uuid4) ?? -1;
|
|
334
|
+
if (indexToDelete >= 0) {
|
|
335
|
+
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
336
|
+
}
|
|
337
337
|
if (this.instances.get(serviceName)?.length === 0) {
|
|
338
338
|
this.instances.delete(serviceName);
|
|
339
339
|
} else if (this.instances.get(serviceName)?.filter((i) => i.address === address && i.port === port).length === 0) {
|
|
@@ -376,7 +376,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
376
376
|
communicationTypes
|
|
377
377
|
});
|
|
378
378
|
instances?.filter(
|
|
379
|
-
(i) => i.address === address && i.port === port && i.
|
|
379
|
+
(i) => i.address === address && i.port === port && i.isActive
|
|
380
380
|
).forEach((i) => {
|
|
381
381
|
i.clientCreated = true;
|
|
382
382
|
});
|
|
@@ -480,7 +480,12 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
480
480
|
return true;
|
|
481
481
|
},
|
|
482
482
|
"Handles service not responding"
|
|
483
|
-
).doOn(
|
|
483
|
+
).doOn(
|
|
484
|
+
"meta.fetch.handshake_failed",
|
|
485
|
+
"meta.fetch.handshake_failed.*",
|
|
486
|
+
"meta.socket_client.disconnected",
|
|
487
|
+
"meta.socket_client.disconnected.*"
|
|
488
|
+
).attachSignal("global.meta.service_registry.service_not_responding");
|
|
484
489
|
this.handleServiceHandshakeTask = CadenzaService.createMetaTask(
|
|
485
490
|
"Handle service handshake",
|
|
486
491
|
(ctx, emit) => {
|
|
@@ -507,7 +512,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
507
512
|
(i) => i.uuid !== serviceInstanceId && i.address === serviceAddress && i.port === servicePort
|
|
508
513
|
);
|
|
509
514
|
for (const i of instancesToDelete ?? []) {
|
|
510
|
-
this.instances.get(serviceName)?.
|
|
515
|
+
const indexToDelete = this.instances.get(serviceName)?.indexOf(i) ?? -1;
|
|
516
|
+
if (indexToDelete >= 0) {
|
|
517
|
+
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
518
|
+
}
|
|
511
519
|
emit("global.meta.service_registry.deleted", {
|
|
512
520
|
data: {
|
|
513
521
|
isActive: false,
|
|
@@ -667,8 +675,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
667
675
|
}
|
|
668
676
|
if (__broadcast || instances[0].isFrontend) {
|
|
669
677
|
for (const instance of instances) {
|
|
678
|
+
const socketKey = instance.isFrontend ? instance.address : `${instance.address}_${instance.port}`;
|
|
670
679
|
emit(
|
|
671
|
-
`meta.service_registry.selected_instance_for_socket:${
|
|
680
|
+
`meta.service_registry.selected_instance_for_socket:${socketKey}`,
|
|
672
681
|
context
|
|
673
682
|
);
|
|
674
683
|
}
|
|
@@ -1659,6 +1668,46 @@ var RestController = class _RestController {
|
|
|
1659
1668
|
var import_socket = require("socket.io");
|
|
1660
1669
|
var import_rate_limiter_flexible2 = require("rate-limiter-flexible");
|
|
1661
1670
|
var import_socket2 = require("socket.io-client");
|
|
1671
|
+
|
|
1672
|
+
// src/network/socketClientUtils.ts
|
|
1673
|
+
var waitForSocketConnection = async (socket, timeoutMs, createError) => {
|
|
1674
|
+
if (!socket) {
|
|
1675
|
+
return { ok: false, error: createError("disconnected") };
|
|
1676
|
+
}
|
|
1677
|
+
if (socket.connected) {
|
|
1678
|
+
return { ok: true };
|
|
1679
|
+
}
|
|
1680
|
+
return new Promise((resolve) => {
|
|
1681
|
+
let timer = null;
|
|
1682
|
+
let settled = false;
|
|
1683
|
+
const cleanup = () => {
|
|
1684
|
+
if (timer) {
|
|
1685
|
+
clearTimeout(timer);
|
|
1686
|
+
timer = null;
|
|
1687
|
+
}
|
|
1688
|
+
socket.off("connect", onConnect);
|
|
1689
|
+
socket.off("connect_error", onConnectError);
|
|
1690
|
+
socket.off("disconnect", onDisconnect);
|
|
1691
|
+
};
|
|
1692
|
+
const settle = (outcome) => {
|
|
1693
|
+
if (settled) return;
|
|
1694
|
+
settled = true;
|
|
1695
|
+
cleanup();
|
|
1696
|
+
resolve(outcome);
|
|
1697
|
+
};
|
|
1698
|
+
const onConnect = () => settle({ ok: true });
|
|
1699
|
+
const onConnectError = (error) => settle({ ok: false, error: createError("connect_error", error) });
|
|
1700
|
+
const onDisconnect = () => settle({ ok: false, error: createError("disconnected") });
|
|
1701
|
+
socket.once("connect", onConnect);
|
|
1702
|
+
socket.once("connect_error", onConnectError);
|
|
1703
|
+
socket.once("disconnect", onDisconnect);
|
|
1704
|
+
timer = setTimeout(() => {
|
|
1705
|
+
settle({ ok: false, error: createError("connect_timeout") });
|
|
1706
|
+
}, timeoutMs);
|
|
1707
|
+
});
|
|
1708
|
+
};
|
|
1709
|
+
|
|
1710
|
+
// src/network/SocketController.ts
|
|
1662
1711
|
var SocketController = class _SocketController {
|
|
1663
1712
|
static get instance() {
|
|
1664
1713
|
if (!this._instance) this._instance = new _SocketController();
|
|
@@ -1934,35 +1983,71 @@ var SocketController = class _SocketController {
|
|
|
1934
1983
|
});
|
|
1935
1984
|
emitWhenReady = (event, data, timeoutMs = 6e4, ack) => {
|
|
1936
1985
|
return new Promise((resolve) => {
|
|
1937
|
-
const
|
|
1938
|
-
|
|
1939
|
-
|
|
1986
|
+
const resolveWithError = (errorMessage, fallbackError) => {
|
|
1987
|
+
resolve({
|
|
1988
|
+
...data,
|
|
1989
|
+
errored: true,
|
|
1990
|
+
__error: errorMessage,
|
|
1991
|
+
error: fallbackError instanceof Error ? fallbackError.message : errorMessage,
|
|
1992
|
+
socketId: socket?.id,
|
|
1993
|
+
serviceName,
|
|
1994
|
+
URL
|
|
1995
|
+
});
|
|
1996
|
+
};
|
|
1997
|
+
const tryEmit = async () => {
|
|
1998
|
+
const waitTimeoutMs = timeoutMs > 0 ? timeoutMs + 10 : 1e4;
|
|
1999
|
+
const waitResult = await waitForSocketConnection(
|
|
2000
|
+
socket,
|
|
2001
|
+
waitTimeoutMs,
|
|
2002
|
+
(reason, error) => {
|
|
2003
|
+
if (reason === "connect_timeout") {
|
|
2004
|
+
return `Socket connect timed out before '${event}'`;
|
|
2005
|
+
}
|
|
2006
|
+
if (reason === "connect_error") {
|
|
2007
|
+
const errMessage = error instanceof Error ? error.message : String(error);
|
|
2008
|
+
return `Socket connect error before '${event}': ${errMessage}`;
|
|
2009
|
+
}
|
|
2010
|
+
return `Socket disconnected before '${event}'`;
|
|
2011
|
+
}
|
|
2012
|
+
);
|
|
2013
|
+
if (!waitResult.ok) {
|
|
2014
|
+
CadenzaService.log(
|
|
2015
|
+
waitResult.error,
|
|
2016
|
+
{ socketId: socket?.id, serviceName, URL, event },
|
|
2017
|
+
"error"
|
|
2018
|
+
);
|
|
2019
|
+
resolveWithError(waitResult.error);
|
|
1940
2020
|
return;
|
|
1941
2021
|
}
|
|
1942
|
-
let timer;
|
|
2022
|
+
let timer = null;
|
|
1943
2023
|
if (timeoutMs !== 0) {
|
|
1944
2024
|
timer = setTimeout(() => {
|
|
2025
|
+
if (timer) {
|
|
2026
|
+
pendingTimers.delete(timer);
|
|
2027
|
+
timer = null;
|
|
2028
|
+
}
|
|
1945
2029
|
CadenzaService.log(
|
|
1946
2030
|
`Socket event '${event}' timed out`,
|
|
1947
2031
|
{ socketId: socket?.id, serviceName, URL },
|
|
1948
2032
|
"error"
|
|
1949
2033
|
);
|
|
1950
|
-
|
|
1951
|
-
...data,
|
|
1952
|
-
errored: true,
|
|
1953
|
-
__error: `Socket event '${event}' timed out`,
|
|
1954
|
-
error: `Socket event '${event}' timed out`,
|
|
1955
|
-
socketId: socket?.id,
|
|
1956
|
-
serviceName,
|
|
1957
|
-
URL
|
|
1958
|
-
});
|
|
2034
|
+
resolveWithError(`Socket event '${event}' timed out`);
|
|
1959
2035
|
}, timeoutMs + 10);
|
|
1960
2036
|
pendingTimers.add(timer);
|
|
1961
2037
|
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
2038
|
+
const connectedSocket = socket;
|
|
2039
|
+
if (!connectedSocket) {
|
|
2040
|
+
resolveWithError(
|
|
2041
|
+
`Socket unavailable before emitting '${event}'`
|
|
2042
|
+
);
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
connectedSocket.timeout(timeoutMs).emit(event, data, (err, response) => {
|
|
2046
|
+
if (timer) {
|
|
2047
|
+
clearTimeout(timer);
|
|
2048
|
+
pendingTimers.delete(timer);
|
|
2049
|
+
timer = null;
|
|
2050
|
+
}
|
|
1966
2051
|
if (err) {
|
|
1967
2052
|
CadenzaService.log(
|
|
1968
2053
|
"Socket timeout.",
|
|
@@ -1985,11 +2070,7 @@ var SocketController = class _SocketController {
|
|
|
1985
2070
|
resolve(response);
|
|
1986
2071
|
});
|
|
1987
2072
|
};
|
|
1988
|
-
|
|
1989
|
-
tryEmit();
|
|
1990
|
-
} else {
|
|
1991
|
-
socket?.once("connect", tryEmit);
|
|
1992
|
-
}
|
|
2073
|
+
void tryEmit();
|
|
1993
2074
|
});
|
|
1994
2075
|
};
|
|
1995
2076
|
socket.on("connect", () => {
|
|
@@ -2306,14 +2387,25 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2306
2387
|
return {
|
|
2307
2388
|
data: {
|
|
2308
2389
|
...ctx.data,
|
|
2309
|
-
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2390
|
+
serviceName: CadenzaService.serviceRegistry.serviceName,
|
|
2391
|
+
inputContextSchemaId: ctx.data.inputContextSchemaId ? {
|
|
2392
|
+
subOperation: "insert",
|
|
2393
|
+
table: "context_schema",
|
|
2394
|
+
data: {
|
|
2395
|
+
...ctx.data.inputContextSchemaId
|
|
2396
|
+
},
|
|
2397
|
+
return: "uuid"
|
|
2398
|
+
} : null,
|
|
2399
|
+
outputContextSchemaId: ctx.data.outputContextSchemaId ? {
|
|
2400
|
+
subOperation: "insert",
|
|
2401
|
+
table: "context_schema",
|
|
2402
|
+
data: {
|
|
2403
|
+
...ctx.data.outputContextSchemaId
|
|
2404
|
+
},
|
|
2405
|
+
return: "uuid"
|
|
2406
|
+
} : null
|
|
2407
|
+
},
|
|
2408
|
+
transaction: true
|
|
2317
2409
|
};
|
|
2318
2410
|
}).doOn("meta.task.created").emits("global.meta.graph_metadata.task_created");
|
|
2319
2411
|
CadenzaService.createMetaTask("Handle task update", (ctx) => {
|
|
@@ -3621,9 +3713,9 @@ var DatabaseController = class _DatabaseController {
|
|
|
3621
3713
|
createDatabaseTask(op, tableName, table, queryFunction, options) {
|
|
3622
3714
|
const opAction = op === "query" ? "queried" : op === "insert" ? "inserted" : op === "update" ? "updated" : op === "delete" ? "deleted" : "";
|
|
3623
3715
|
const defaultSignal = `global.${options.isMeta ? "meta." : ""}${tableName}.${opAction}`;
|
|
3624
|
-
const
|
|
3625
|
-
const
|
|
3626
|
-
CadenzaService.createThrottledTask(
|
|
3716
|
+
const taskName = `${op.charAt(0).toUpperCase() + op.slice(1)} ${tableName}`;
|
|
3717
|
+
const schema = this.getInputSchema(op, tableName, table);
|
|
3718
|
+
const task = CadenzaService.createThrottledTask(
|
|
3627
3719
|
taskName,
|
|
3628
3720
|
async (context, emit) => {
|
|
3629
3721
|
for (const action of Object.keys(table.customSignals?.triggers ?? {})) {
|
|
@@ -3718,17 +3810,8 @@ var DatabaseController = class _DatabaseController {
|
|
|
3718
3810
|
{
|
|
3719
3811
|
isMeta: options.isMeta,
|
|
3720
3812
|
isSubMeta: options.isMeta,
|
|
3721
|
-
validateInputContext:
|
|
3722
|
-
|
|
3723
|
-
inputSchema: {
|
|
3724
|
-
// TODO
|
|
3725
|
-
type: "object",
|
|
3726
|
-
properties: {
|
|
3727
|
-
filter: {
|
|
3728
|
-
type: "object"
|
|
3729
|
-
}
|
|
3730
|
-
}
|
|
3731
|
-
}
|
|
3813
|
+
validateInputContext: options.securityProfile !== "low",
|
|
3814
|
+
inputSchema: schema
|
|
3732
3815
|
}
|
|
3733
3816
|
).doOn(
|
|
3734
3817
|
...table.customSignals?.triggers?.[op]?.map((signal) => {
|
|
@@ -3739,8 +3822,382 @@ var DatabaseController = class _DatabaseController {
|
|
|
3739
3822
|
return typeof signal === "string" ? signal : signal.signal;
|
|
3740
3823
|
}) ?? []
|
|
3741
3824
|
);
|
|
3825
|
+
if (op === "query") {
|
|
3826
|
+
const intentName = `query-${CadenzaService.serviceRegistry.serviceName}-${tableName}`;
|
|
3827
|
+
CadenzaService.defineIntent({
|
|
3828
|
+
name: intentName,
|
|
3829
|
+
description: `Perform a query operation on the ${tableName} table`,
|
|
3830
|
+
input: schema
|
|
3831
|
+
});
|
|
3832
|
+
task.respondsTo(intentName);
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
getInputSchema(op, tableName, table) {
|
|
3836
|
+
const inputSchema = {
|
|
3837
|
+
type: "object",
|
|
3838
|
+
properties: {
|
|
3839
|
+
queryData: {
|
|
3840
|
+
type: "object",
|
|
3841
|
+
properties: {},
|
|
3842
|
+
strict: true
|
|
3843
|
+
}
|
|
3844
|
+
},
|
|
3845
|
+
strict: true
|
|
3846
|
+
};
|
|
3847
|
+
if (!inputSchema.properties) {
|
|
3848
|
+
return inputSchema;
|
|
3849
|
+
}
|
|
3850
|
+
inputSchema.properties.transaction = getTransactionSchema();
|
|
3851
|
+
inputSchema.properties.queryData.properties.transaction = inputSchema.properties.transaction;
|
|
3852
|
+
switch (op) {
|
|
3853
|
+
case "insert":
|
|
3854
|
+
inputSchema.properties.data = getInsertDataSchemaFromTable(
|
|
3855
|
+
table,
|
|
3856
|
+
tableName
|
|
3857
|
+
);
|
|
3858
|
+
inputSchema.properties.queryData.properties.data = inputSchema.properties.data;
|
|
3859
|
+
inputSchema.properties.batch = getQueryBatchSchemaFromTable();
|
|
3860
|
+
inputSchema.properties.queryData.properties.batch = inputSchema.properties.batch;
|
|
3861
|
+
inputSchema.properties.onConflict = getQueryOnConflictSchemaFromTable(
|
|
3862
|
+
table,
|
|
3863
|
+
tableName
|
|
3864
|
+
);
|
|
3865
|
+
inputSchema.properties.queryData.properties.onConflict = inputSchema.properties.onConflict;
|
|
3866
|
+
break;
|
|
3867
|
+
case "query":
|
|
3868
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3869
|
+
table,
|
|
3870
|
+
tableName
|
|
3871
|
+
);
|
|
3872
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3873
|
+
inputSchema.properties.fields = getQueryFieldsSchemaFromTable(
|
|
3874
|
+
table,
|
|
3875
|
+
tableName
|
|
3876
|
+
);
|
|
3877
|
+
inputSchema.properties.queryData.properties.fields = inputSchema.properties.fields;
|
|
3878
|
+
inputSchema.properties.joins = getQueryJoinsSchemaFromTable(
|
|
3879
|
+
table,
|
|
3880
|
+
tableName
|
|
3881
|
+
);
|
|
3882
|
+
inputSchema.properties.queryData.properties.joins = inputSchema.properties.joins;
|
|
3883
|
+
inputSchema.properties.sort = getQuerySortSchemaFromTable(
|
|
3884
|
+
table,
|
|
3885
|
+
tableName
|
|
3886
|
+
);
|
|
3887
|
+
inputSchema.properties.queryData.properties.sort = inputSchema.properties.sort;
|
|
3888
|
+
inputSchema.properties.limit = getQueryLimitSchemaFromTable();
|
|
3889
|
+
inputSchema.properties.queryData.properties.limit = inputSchema.properties.limit;
|
|
3890
|
+
inputSchema.properties.offset = getQueryOffsetSchemaFromTable();
|
|
3891
|
+
inputSchema.properties.queryData.properties.offset = inputSchema.properties.offset;
|
|
3892
|
+
break;
|
|
3893
|
+
case "update":
|
|
3894
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3895
|
+
table,
|
|
3896
|
+
tableName
|
|
3897
|
+
);
|
|
3898
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3899
|
+
inputSchema.properties.fields = getQueryFieldsSchemaFromTable(
|
|
3900
|
+
table,
|
|
3901
|
+
tableName
|
|
3902
|
+
);
|
|
3903
|
+
inputSchema.properties.queryData.properties.fields = inputSchema.properties.fields;
|
|
3904
|
+
break;
|
|
3905
|
+
case "delete":
|
|
3906
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3907
|
+
table,
|
|
3908
|
+
tableName
|
|
3909
|
+
);
|
|
3910
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3911
|
+
break;
|
|
3912
|
+
}
|
|
3913
|
+
return inputSchema;
|
|
3742
3914
|
}
|
|
3743
3915
|
};
|
|
3916
|
+
function getInsertDataSchemaFromTable(table, tableName) {
|
|
3917
|
+
const dataSchema = {
|
|
3918
|
+
type: "object",
|
|
3919
|
+
properties: {
|
|
3920
|
+
...Object.fromEntries(
|
|
3921
|
+
Object.entries(table.fields).map((field) => {
|
|
3922
|
+
return [
|
|
3923
|
+
field[0],
|
|
3924
|
+
[
|
|
3925
|
+
{
|
|
3926
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3927
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3928
|
+
},
|
|
3929
|
+
{
|
|
3930
|
+
type: "string",
|
|
3931
|
+
constraints: {
|
|
3932
|
+
oneOf: ["increment", "decrement", "set"]
|
|
3933
|
+
}
|
|
3934
|
+
},
|
|
3935
|
+
{
|
|
3936
|
+
type: "object",
|
|
3937
|
+
properties: {
|
|
3938
|
+
subOperation: {
|
|
3939
|
+
type: "string",
|
|
3940
|
+
enum: ["insert", "query"]
|
|
3941
|
+
},
|
|
3942
|
+
table: {
|
|
3943
|
+
type: "string"
|
|
3944
|
+
},
|
|
3945
|
+
data: [
|
|
3946
|
+
{
|
|
3947
|
+
type: "object"
|
|
3948
|
+
},
|
|
3949
|
+
{
|
|
3950
|
+
type: "array",
|
|
3951
|
+
items: {
|
|
3952
|
+
type: "object"
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
],
|
|
3956
|
+
filter: {
|
|
3957
|
+
type: "object"
|
|
3958
|
+
},
|
|
3959
|
+
fields: {
|
|
3960
|
+
type: "array",
|
|
3961
|
+
items: {
|
|
3962
|
+
type: "string"
|
|
3963
|
+
}
|
|
3964
|
+
},
|
|
3965
|
+
return: {
|
|
3966
|
+
type: "string"
|
|
3967
|
+
}
|
|
3968
|
+
},
|
|
3969
|
+
required: ["subOperation", "table"]
|
|
3970
|
+
}
|
|
3971
|
+
]
|
|
3972
|
+
];
|
|
3973
|
+
})
|
|
3974
|
+
)
|
|
3975
|
+
},
|
|
3976
|
+
required: Object.entries(table.fields).filter((field) => field[1].required || field[1].primary).map((field) => field[0]),
|
|
3977
|
+
strict: true
|
|
3978
|
+
};
|
|
3979
|
+
return [
|
|
3980
|
+
dataSchema,
|
|
3981
|
+
{
|
|
3982
|
+
type: "array",
|
|
3983
|
+
items: dataSchema
|
|
3984
|
+
}
|
|
3985
|
+
];
|
|
3986
|
+
}
|
|
3987
|
+
function getQueryFilterSchemaFromTable(table, tableName) {
|
|
3988
|
+
return {
|
|
3989
|
+
type: "object",
|
|
3990
|
+
properties: {
|
|
3991
|
+
...Object.fromEntries(
|
|
3992
|
+
Object.entries(table.fields).map((field) => {
|
|
3993
|
+
return [
|
|
3994
|
+
field[0],
|
|
3995
|
+
[
|
|
3996
|
+
{
|
|
3997
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3998
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3999
|
+
},
|
|
4000
|
+
{
|
|
4001
|
+
type: "array",
|
|
4002
|
+
items: {
|
|
4003
|
+
type: tableFieldTypeToSchemaType(field[1].type)
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
]
|
|
4007
|
+
];
|
|
4008
|
+
})
|
|
4009
|
+
)
|
|
4010
|
+
},
|
|
4011
|
+
strict: true,
|
|
4012
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4013
|
+
};
|
|
4014
|
+
}
|
|
4015
|
+
function getQueryFieldsSchemaFromTable(table, tableName) {
|
|
4016
|
+
return {
|
|
4017
|
+
type: "array",
|
|
4018
|
+
items: {
|
|
4019
|
+
type: "string",
|
|
4020
|
+
constraints: {
|
|
4021
|
+
oneOf: Object.keys(table.fields)
|
|
4022
|
+
}
|
|
4023
|
+
},
|
|
4024
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4025
|
+
};
|
|
4026
|
+
}
|
|
4027
|
+
function getQueryJoinsSchemaFromTable(table, tableName) {
|
|
4028
|
+
return {
|
|
4029
|
+
type: "object",
|
|
4030
|
+
properties: {
|
|
4031
|
+
...Object.fromEntries(
|
|
4032
|
+
Object.entries(table.fields).map((field) => {
|
|
4033
|
+
return [
|
|
4034
|
+
field[0],
|
|
4035
|
+
{
|
|
4036
|
+
type: "object",
|
|
4037
|
+
properties: {
|
|
4038
|
+
on: {
|
|
4039
|
+
type: "string"
|
|
4040
|
+
},
|
|
4041
|
+
fields: {
|
|
4042
|
+
type: "array",
|
|
4043
|
+
items: {
|
|
4044
|
+
type: "string"
|
|
4045
|
+
}
|
|
4046
|
+
},
|
|
4047
|
+
filter: {
|
|
4048
|
+
type: "object"
|
|
4049
|
+
},
|
|
4050
|
+
returnAs: {
|
|
4051
|
+
type: "string",
|
|
4052
|
+
constraints: {
|
|
4053
|
+
oneOf: ["array", "object"]
|
|
4054
|
+
}
|
|
4055
|
+
},
|
|
4056
|
+
alias: {
|
|
4057
|
+
type: "string"
|
|
4058
|
+
},
|
|
4059
|
+
joins: {
|
|
4060
|
+
type: "object"
|
|
4061
|
+
}
|
|
4062
|
+
},
|
|
4063
|
+
required: ["on", "fields"],
|
|
4064
|
+
strict: true
|
|
4065
|
+
}
|
|
4066
|
+
];
|
|
4067
|
+
})
|
|
4068
|
+
)
|
|
4069
|
+
},
|
|
4070
|
+
strict: true,
|
|
4071
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4072
|
+
};
|
|
4073
|
+
}
|
|
4074
|
+
function getQuerySortSchemaFromTable(table, tableName) {
|
|
4075
|
+
return {
|
|
4076
|
+
type: "object",
|
|
4077
|
+
properties: {
|
|
4078
|
+
...Object.fromEntries(
|
|
4079
|
+
Object.entries(table.fields).map((field) => {
|
|
4080
|
+
return [
|
|
4081
|
+
field[0],
|
|
4082
|
+
{
|
|
4083
|
+
type: "string",
|
|
4084
|
+
constraints: {
|
|
4085
|
+
oneOf: ["asc", "desc"]
|
|
4086
|
+
}
|
|
4087
|
+
}
|
|
4088
|
+
];
|
|
4089
|
+
})
|
|
4090
|
+
)
|
|
4091
|
+
},
|
|
4092
|
+
strict: true,
|
|
4093
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4094
|
+
};
|
|
4095
|
+
}
|
|
4096
|
+
function getQueryLimitSchemaFromTable() {
|
|
4097
|
+
return {
|
|
4098
|
+
type: "number",
|
|
4099
|
+
constraints: {
|
|
4100
|
+
min: 1
|
|
4101
|
+
},
|
|
4102
|
+
description: "Limit for query results"
|
|
4103
|
+
};
|
|
4104
|
+
}
|
|
4105
|
+
function getQueryOffsetSchemaFromTable() {
|
|
4106
|
+
return {
|
|
4107
|
+
type: "number",
|
|
4108
|
+
constraints: {
|
|
4109
|
+
min: 0
|
|
4110
|
+
},
|
|
4111
|
+
description: "Offset for query results"
|
|
4112
|
+
};
|
|
4113
|
+
}
|
|
4114
|
+
function getTransactionSchema() {
|
|
4115
|
+
return {
|
|
4116
|
+
type: "boolean",
|
|
4117
|
+
description: "Whether to run the query in a transaction"
|
|
4118
|
+
};
|
|
4119
|
+
}
|
|
4120
|
+
function getQueryBatchSchemaFromTable() {
|
|
4121
|
+
return {
|
|
4122
|
+
type: "boolean",
|
|
4123
|
+
description: "Whether to run the query in batch mode"
|
|
4124
|
+
};
|
|
4125
|
+
}
|
|
4126
|
+
function getQueryOnConflictSchemaFromTable(table, tableName) {
|
|
4127
|
+
return {
|
|
4128
|
+
type: "object",
|
|
4129
|
+
properties: {
|
|
4130
|
+
target: {
|
|
4131
|
+
type: "array",
|
|
4132
|
+
items: {
|
|
4133
|
+
type: "string",
|
|
4134
|
+
constraints: {
|
|
4135
|
+
oneOf: Object.keys(table.fields)
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
},
|
|
4139
|
+
action: {
|
|
4140
|
+
type: "object",
|
|
4141
|
+
properties: {
|
|
4142
|
+
do: {
|
|
4143
|
+
type: "string",
|
|
4144
|
+
constraints: {
|
|
4145
|
+
oneOf: ["nothing", "update"]
|
|
4146
|
+
}
|
|
4147
|
+
},
|
|
4148
|
+
set: {
|
|
4149
|
+
type: "object",
|
|
4150
|
+
properties: {
|
|
4151
|
+
...Object.fromEntries(
|
|
4152
|
+
Object.entries(table.fields).map((field) => {
|
|
4153
|
+
return [
|
|
4154
|
+
field[0],
|
|
4155
|
+
[
|
|
4156
|
+
{
|
|
4157
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
4158
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
4159
|
+
}
|
|
4160
|
+
]
|
|
4161
|
+
];
|
|
4162
|
+
})
|
|
4163
|
+
)
|
|
4164
|
+
}
|
|
4165
|
+
},
|
|
4166
|
+
where: {
|
|
4167
|
+
type: "string"
|
|
4168
|
+
}
|
|
4169
|
+
},
|
|
4170
|
+
required: ["do"]
|
|
4171
|
+
}
|
|
4172
|
+
},
|
|
4173
|
+
required: ["target", "action"],
|
|
4174
|
+
strict: true
|
|
4175
|
+
};
|
|
4176
|
+
}
|
|
4177
|
+
function tableFieldTypeToSchemaType(type) {
|
|
4178
|
+
switch (type) {
|
|
4179
|
+
case "varchar":
|
|
4180
|
+
case "text":
|
|
4181
|
+
case "jsonb":
|
|
4182
|
+
case "uuid":
|
|
4183
|
+
case "date":
|
|
4184
|
+
case "geo_point":
|
|
4185
|
+
case "bytea":
|
|
4186
|
+
return "string";
|
|
4187
|
+
case "int":
|
|
4188
|
+
case "bigint":
|
|
4189
|
+
case "decimal":
|
|
4190
|
+
case "timestamp":
|
|
4191
|
+
return "number";
|
|
4192
|
+
case "boolean":
|
|
4193
|
+
return "boolean";
|
|
4194
|
+
case "array":
|
|
4195
|
+
return "array";
|
|
4196
|
+
case "object":
|
|
4197
|
+
return "object";
|
|
4198
|
+
}
|
|
4199
|
+
return "any";
|
|
4200
|
+
}
|
|
3744
4201
|
|
|
3745
4202
|
// src/Cadenza.ts
|
|
3746
4203
|
var import_uuid3 = require("uuid");
|
|
@@ -4614,10 +5071,9 @@ var CadenzaService = class {
|
|
|
4614
5071
|
this.bootstrap();
|
|
4615
5072
|
this.validateName(tableName);
|
|
4616
5073
|
this.validateName(operation);
|
|
4617
|
-
const tableNameFormatted = tableName.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
4618
5074
|
const name = `${operation.charAt(0).toUpperCase() + operation.slice(1)} ${tableName} in ${databaseServiceName ?? "default database service"}`;
|
|
4619
5075
|
const description = `Executes a ${operation} on table ${tableName} in ${databaseServiceName ?? "default database service"}`;
|
|
4620
|
-
const taskName =
|
|
5076
|
+
const taskName = `${operation.charAt(0).toUpperCase() + operation.slice(1)} ${tableName}`;
|
|
4621
5077
|
options = {
|
|
4622
5078
|
concurrency: 100,
|
|
4623
5079
|
timeout: 0,
|
|
@@ -4879,7 +5335,7 @@ var CadenzaService = class {
|
|
|
4879
5335
|
* This method is not supported in a browser environment and will log a warning if called in such an environment.
|
|
4880
5336
|
*
|
|
4881
5337
|
* @param {string} name - The name of the database service to be created.
|
|
4882
|
-
* @param {
|
|
5338
|
+
* @param {DatabaseSchemaDefinition} schema - The schema definition for the database service.
|
|
4883
5339
|
* @param {string} [description=""] - An optional description of the database service.
|
|
4884
5340
|
* @param {ServerOptions & DatabaseOptions} [options={}] - Optional configuration settings for the database and server.
|
|
4885
5341
|
* @return {void} This method does not return a value.
|
|
@@ -4943,7 +5399,7 @@ var CadenzaService = class {
|
|
|
4943
5399
|
* Creates a meta database service with the specified configuration.
|
|
4944
5400
|
*
|
|
4945
5401
|
* @param {string} name - The name of the database service to be created.
|
|
4946
|
-
* @param {
|
|
5402
|
+
* @param {DatabaseSchemaDefinition} schema - The schema definition for the database.
|
|
4947
5403
|
* @param {string} [description=""] - An optional description of the database service.
|
|
4948
5404
|
* @param {ServerOptions & DatabaseOptions} [options={}] - Optional server and database configuration options. The `isMeta` flag will be automatically set to true.
|
|
4949
5405
|
* @return {void} - This method does not return a value.
|