prostgles-server 4.2.648 → 4.2.649
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/debug/als-build.log +4 -0
- package/debug/als-e2e.log +1747 -0
- package/debug/als-lint.log +4 -0
- package/debug/als-npm-test.log +712 -0
- package/debug/als-row-parts-e2e.log +1759 -0
- package/debug/als-row-parts-npm-test.log +716 -0
- package/debug/als-typecheck.log +8 -0
- package/debug/als-unified-build.log +4 -0
- package/debug/als-unified-lint.log +4 -0
- package/debug/als-unified-test-build.log +11 -0
- package/debug/als-unified-test-server.log +3444 -0
- package/dist/Audit/AuditTable.d.ts +1 -1
- package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilder.js +4 -2
- package/dist/DboBuilder/DboBuilder.js.map +1 -1
- package/dist/DboBuilder/DboBuilder.spec.js +3 -1
- package/dist/DboBuilder/DboBuilder.spec.js.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +3 -2
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.js +4 -3
- package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
- package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.js +7 -6
- package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.d.ts +2 -2
- package/dist/ExecutionContext.d.ts +32 -0
- package/dist/ExecutionContext.d.ts.map +1 -0
- package/dist/ExecutionContext.js +25 -0
- package/dist/ExecutionContext.js.map +1 -0
- package/dist/JSONBSchemaValidation/validateJSONBSchemaSQL.d.ts +1 -1
- package/dist/Prostgles.d.ts +5 -0
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +5 -0
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.d.ts +1 -1
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +14 -1
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/getFunctionRelatedRecords.d.ts +5 -0
- package/dist/PublishParser/getFunctionRelatedRecords.d.ts.map +1 -0
- package/dist/PublishParser/getFunctionRelatedRecords.js +26 -0
- package/dist/PublishParser/getFunctionRelatedRecords.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/initProstgles.d.ts +3 -0
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js +1 -0
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.d.ts.map +1 -1
- package/dist/runClientRequest.js +6 -1
- package/dist/runClientRequest.js.map +1 -1
- package/lib/DboBuilder/DboBuilder.spec.ts +3 -7
- package/lib/DboBuilder/DboBuilder.ts +4 -2
- package/lib/DboBuilder/TableHandler/TableHandler.ts +14 -11
- package/lib/DboBuilder/TableHandler/delete.ts +14 -11
- package/lib/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.ts +28 -21
- package/lib/ExecutionContext.ts +60 -0
- package/lib/Prostgles.ts +8 -4
- package/lib/PublishParser/PublishParser.ts +17 -1
- package/lib/PublishParser/getFunctionRelatedRecords.ts +25 -0
- package/lib/index.ts +2 -4
- package/lib/initProstgles.ts +5 -4
- package/lib/runClientRequest.ts +16 -8
- package/package.json +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { AuthClientRequest, SessionUser } from "./Auth/AuthTypes";
|
|
3
|
+
import type { ViewHandler } from "./DboBuilder/ViewHandler/ViewHandler";
|
|
4
|
+
|
|
5
|
+
export type FunctionInvocation = {
|
|
6
|
+
type: "function";
|
|
7
|
+
id: string;
|
|
8
|
+
functionName: string;
|
|
9
|
+
relatedRecords: {
|
|
10
|
+
argName: string;
|
|
11
|
+
tableName: string;
|
|
12
|
+
rowPart: Record<string, unknown>;
|
|
13
|
+
}[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type TriggerInvocation = {
|
|
17
|
+
type: "trigger";
|
|
18
|
+
id: string;
|
|
19
|
+
tableName: string;
|
|
20
|
+
rowParts: Record<string, unknown>[];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type Invocation = FunctionInvocation | TriggerInvocation;
|
|
24
|
+
|
|
25
|
+
/** Correlation metadata only; database authorization still uses the explicit caller. */
|
|
26
|
+
export type ExecutionContext = {
|
|
27
|
+
runId: string;
|
|
28
|
+
user: undefined | SessionUser["user"];
|
|
29
|
+
clientReq: undefined | AuthClientRequest;
|
|
30
|
+
/** Invocation ancestry, oldest first. Parallel branches have separate lists. */
|
|
31
|
+
invocations: Invocation[];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** Record the row parts available to the hook, including rows without primary keys. */
|
|
35
|
+
export const runTableHook = <T>(
|
|
36
|
+
table: ViewHandler,
|
|
37
|
+
rows: Record<string, unknown>[],
|
|
38
|
+
callback: () => T,
|
|
39
|
+
): T => {
|
|
40
|
+
const prostgles = table.dboBuilder.prostgles;
|
|
41
|
+
const parent = createExecutionContext(prostgles.getExecution());
|
|
42
|
+
const invocation: TriggerInvocation = {
|
|
43
|
+
type: "trigger",
|
|
44
|
+
id: randomUUID(),
|
|
45
|
+
tableName: table.name,
|
|
46
|
+
rowParts: rows,
|
|
47
|
+
};
|
|
48
|
+
return prostgles.runWithExecution(
|
|
49
|
+
{ ...parent, invocations: [...parent.invocations, invocation] },
|
|
50
|
+
callback,
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const createExecutionContext = (parent: ExecutionContext | undefined): ExecutionContext =>
|
|
55
|
+
parent ?? {
|
|
56
|
+
runId: randomUUID(),
|
|
57
|
+
invocations: [],
|
|
58
|
+
clientReq: undefined,
|
|
59
|
+
user: undefined,
|
|
60
|
+
};
|
package/lib/Prostgles.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { DB_GENERATED_NAMES } from "./DBSchemaBuilder/constants";
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
import type { ExecutionContext } from "./ExecutionContext";
|
|
2
4
|
import type pgPromise from "pg-promise";
|
|
3
5
|
import { AuthHandler } from "./Auth/AuthHandler";
|
|
4
6
|
import type { SessionUser } from "./Auth/AuthTypes";
|
|
@@ -6,10 +8,7 @@ import type { ContextCleanup, OnInitReason } from "./initProstgles";
|
|
|
6
8
|
import { initProstgles } from "./initProstgles";
|
|
7
9
|
import type { SchemaWatch } from "./SchemaWatch/SchemaWatch";
|
|
8
10
|
import { getClientSchema } from "./WebsocketAPI/getClientSchema";
|
|
9
|
-
import {
|
|
10
|
-
getClientDBHandlers,
|
|
11
|
-
type GetClientDBHandlers,
|
|
12
|
-
} from "./WebsocketAPI/getClientHandlers";
|
|
11
|
+
import { getClientDBHandlers, type GetClientDBHandlers } from "./WebsocketAPI/getClientHandlers";
|
|
13
12
|
import { onSocketConnected } from "./WebsocketAPI/onSocketConnected";
|
|
14
13
|
import pg = require("pg-promise/typescript/pg-subset");
|
|
15
14
|
|
|
@@ -266,6 +265,10 @@ export class Prostgles {
|
|
|
266
265
|
}
|
|
267
266
|
|
|
268
267
|
context: unknown;
|
|
268
|
+
readonly executionStorage = new AsyncLocalStorage<ExecutionContext | undefined>();
|
|
269
|
+
getExecution = () => this.executionStorage.getStore();
|
|
270
|
+
runWithExecution = <T>(execution: ExecutionContext | undefined, callback: () => T): T =>
|
|
271
|
+
this.executionStorage.run(execution, callback);
|
|
269
272
|
private contextCleanups: ContextCleanup[] = [];
|
|
270
273
|
|
|
271
274
|
cleanupContext = async () => {
|
|
@@ -296,6 +299,7 @@ export class Prostgles {
|
|
|
296
299
|
sql: this.dboBuilder.sql,
|
|
297
300
|
tables: this.dboBuilder.tables,
|
|
298
301
|
reason,
|
|
302
|
+
getExecution: this.getExecution,
|
|
299
303
|
onCleanup: (cleanup) => cleanups.push(cleanup),
|
|
300
304
|
});
|
|
301
305
|
this.context = context;
|
|
@@ -36,6 +36,9 @@ import {
|
|
|
36
36
|
type PublishObject,
|
|
37
37
|
} from "./publishTypesAndUtils";
|
|
38
38
|
import { validatePublishProfiles } from "./validatePublishProfiles";
|
|
39
|
+
import { randomUUID } from "node:crypto";
|
|
40
|
+
import { createExecutionContext } from "../ExecutionContext";
|
|
41
|
+
import { getFunctionRelatedRecords } from "./getFunctionRelatedRecords";
|
|
39
42
|
|
|
40
43
|
export class PublishParser {
|
|
41
44
|
parsedPublish: ReturnType<typeof getParsedPublish>;
|
|
@@ -144,7 +147,20 @@ export class PublishParser {
|
|
|
144
147
|
})();
|
|
145
148
|
|
|
146
149
|
this.prostgles.checkNotDestroyed();
|
|
147
|
-
|
|
150
|
+
const parent = createExecutionContext(this.prostgles.getExecution());
|
|
151
|
+
const relatedRecords = getFunctionRelatedRecords(method.input, args);
|
|
152
|
+
return this.prostgles.runWithExecution(
|
|
153
|
+
{
|
|
154
|
+
...parent,
|
|
155
|
+
user,
|
|
156
|
+
clientReq,
|
|
157
|
+
invocations: [
|
|
158
|
+
...parent.invocations,
|
|
159
|
+
{ type: "function", id: randomUUID(), functionName: name, relatedRecords },
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
() => method.run(args, ctx),
|
|
163
|
+
);
|
|
148
164
|
};
|
|
149
165
|
allowedFunctionsMap.set(name, { ...method, run: runWithContext });
|
|
150
166
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FunctionInvocation } from "../ExecutionContext";
|
|
2
|
+
import type { ServerFunctionDefinition } from "./defineServerFunction";
|
|
3
|
+
|
|
4
|
+
/** Capture top-level RowLookup/ValueLookup inputs without querying the database. */
|
|
5
|
+
export const getFunctionRelatedRecords = (
|
|
6
|
+
input: ServerFunctionDefinition["input"],
|
|
7
|
+
args: Record<string, unknown> | undefined,
|
|
8
|
+
): FunctionInvocation["relatedRecords"] => {
|
|
9
|
+
const records: FunctionInvocation["relatedRecords"] = [];
|
|
10
|
+
for (const [argName, schema] of Object.entries(input ?? {})) {
|
|
11
|
+
if (typeof schema !== "object" || !("table" in schema)) continue;
|
|
12
|
+
const isRow = schema.type === "RowLookup" || schema.type === "RowLookup[]";
|
|
13
|
+
const isValue = schema.type === "ValueLookup" || schema.type === "ValueLookup[]";
|
|
14
|
+
if (!isRow && !isValue) continue;
|
|
15
|
+
const value = args?.[argName];
|
|
16
|
+
if (value === undefined || value === null) continue;
|
|
17
|
+
const values: unknown[] = schema.type.endsWith("[]") ? (value as unknown[]) : [value];
|
|
18
|
+
for (const item of values) {
|
|
19
|
+
const rowPart =
|
|
20
|
+
"column" in schema ? { [schema.column]: item } : (item as Record<string, unknown>);
|
|
21
|
+
records.push({ argName, tableName: schema.table, rowPart });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return records;
|
|
25
|
+
};
|
package/lib/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ export const createProstgles = <
|
|
|
28
28
|
};
|
|
29
29
|
export * from "./PublishParser/defineServerFunction";
|
|
30
30
|
export * from "./Auth/AuthTypes";
|
|
31
|
+
export type { ExecutionContext, FunctionInvocation, TriggerInvocation } from "./ExecutionContext";
|
|
31
32
|
|
|
32
33
|
export type {
|
|
33
34
|
PublishContextValue,
|
|
@@ -42,10 +43,7 @@ export type {
|
|
|
42
43
|
PublishProfile,
|
|
43
44
|
PublishParams,
|
|
44
45
|
} from "./PublishParser/publishTypesAndUtils";
|
|
45
|
-
export type {
|
|
46
|
-
ClientDBHandlerRequest,
|
|
47
|
-
GetClientDBHandlers,
|
|
48
|
-
} from "./WebsocketAPI/getClientHandlers";
|
|
46
|
+
export type { ClientDBHandlerRequest, GetClientDBHandlers } from "./WebsocketAPI/getClientHandlers";
|
|
49
47
|
export type { DBOFullyTyped, DBOFullyTypedClient } from "./DBSchemaBuilder/DBSchemaBuilder";
|
|
50
48
|
export type { DBHandlerServer } from "./Prostgles";
|
|
51
49
|
export type { StorageClient as CloudClient } from "./StorageClient/StorageClientTypes";
|
package/lib/initProstgles.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { syncTableTriggers } from "./TableConfig/syncTableTriggers";
|
|
2
|
+
import type { ExecutionContext } from "./ExecutionContext";
|
|
2
3
|
import { deferDbQueries } from "./deferDbQueries";
|
|
3
4
|
import type pgPromise from "pg-promise";
|
|
4
5
|
import type pg from "pg-promise/typescript/pg-subset";
|
|
@@ -18,10 +19,7 @@ import { runSQLFile } from "./TableConfig/runSQLFile";
|
|
|
18
19
|
import { updateConfiguration, type clientOnlyUpdateKeys } from "./updateConfiguration";
|
|
19
20
|
import { sleep } from "./utils/utils";
|
|
20
21
|
import { getAdminClient } from "./DboBuilder/runSql/getAdminClient";
|
|
21
|
-
import type {
|
|
22
|
-
ClientDBHandlerRequest,
|
|
23
|
-
GetClientDBHandlers,
|
|
24
|
-
} from "./WebsocketAPI/getClientHandlers";
|
|
22
|
+
import type { ClientDBHandlerRequest, GetClientDBHandlers } from "./WebsocketAPI/getClientHandlers";
|
|
25
23
|
|
|
26
24
|
/**
|
|
27
25
|
* Database connection details
|
|
@@ -93,6 +91,8 @@ export type OnReadyParams<S, Context = undefined> = OnReadyParamsCommon & {
|
|
|
93
91
|
export type ContextCleanup = () => MaybePromise<void>;
|
|
94
92
|
export type CreateContextParams<S> = OnReadyParamsCommon & {
|
|
95
93
|
dbo: DBOFullyTyped<S>;
|
|
94
|
+
/** Read at call time; undefined outside a function, client operation, or table hook. */
|
|
95
|
+
getExecution: () => ExecutionContext | undefined;
|
|
96
96
|
onCleanup: (cleanup: ContextCleanup) => void;
|
|
97
97
|
};
|
|
98
98
|
export type CreateContext<S, Context> = (params: CreateContextParams<S>) => MaybePromise<Context>;
|
|
@@ -324,6 +324,7 @@ export const initProstgles = async function (
|
|
|
324
324
|
}
|
|
325
325
|
this.restApi?.destroy();
|
|
326
326
|
await this.cleanupContext();
|
|
327
|
+
this.executionStorage.disable();
|
|
327
328
|
await this.dboBuilder.destroy();
|
|
328
329
|
this.authHandler.destroy();
|
|
329
330
|
await this.tableConfigurator?.destroy();
|
package/lib/runClientRequest.ts
CHANGED
|
@@ -12,10 +12,10 @@ import type { LocalParams } from "./DboBuilder/DboBuilder";
|
|
|
12
12
|
import type { DbTxTableHandlers } from "./DboBuilder/DboBuilderTypes";
|
|
13
13
|
import type { TableHandler as TableHandlerServer } from "./DboBuilder/TableHandler/TableHandler";
|
|
14
14
|
import { canRunSQL } from "./DboBuilder/runSql/runSQL";
|
|
15
|
+
import { createExecutionContext } from "./ExecutionContext";
|
|
15
16
|
import type { Prostgles } from "./Prostgles";
|
|
16
17
|
import type { ParsedTableRule } from "./PublishParser/publishTypesAndUtils";
|
|
17
18
|
import { type PermissionScope } from "./PublishParser/publishTypesAndUtils";
|
|
18
|
-
import { getAbortSignalKeys } from "./DboBuilder/ViewHandler/getDbHandlerWithAbort";
|
|
19
19
|
|
|
20
20
|
const TABLE_METHODS = {
|
|
21
21
|
find: 1,
|
|
@@ -184,13 +184,21 @@ export const runClientRequest = async function (
|
|
|
184
184
|
undefined | TableMethodFunctionWithRulesAndLocalParams;
|
|
185
185
|
|
|
186
186
|
this.checkNotDestroyed();
|
|
187
|
-
return (
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
return this.runWithExecution(
|
|
188
|
+
{
|
|
189
|
+
...createExecutionContext(this.getExecution()),
|
|
190
|
+
user: clientInfo.user,
|
|
191
|
+
clientReq,
|
|
192
|
+
},
|
|
193
|
+
() =>
|
|
194
|
+
(tableHandler[command] as TableMethodFunctionWithRulesAndLocalParams)(
|
|
195
|
+
param1,
|
|
196
|
+
param2,
|
|
197
|
+
param3,
|
|
198
|
+
parsedTableRule,
|
|
199
|
+
localParams,
|
|
200
|
+
) as AnyObject | undefined,
|
|
201
|
+
);
|
|
194
202
|
};
|
|
195
203
|
|
|
196
204
|
export const clientCanRunSqlRequest = async function (
|