prostgles-server 4.2.598 → 4.2.600
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/README.md +26 -0
- package/dist/DBSchemaBuilder/getServerFunctionReturnTypes.external.fixture.d.ts +2 -2
- package/dist/DBSchemaBuilder/getServerFunctionReturnTypes.fixture.d.ts +8 -8
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts +8 -5
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +1 -0
- 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 +1 -0
- 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 +2 -0
- package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
- package/dist/Prostgles.d.ts +13 -8
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +57 -4
- package/dist/Prostgles.js.map +1 -1
- package/dist/ProstglesContext.spec.d.ts +2 -0
- package/dist/ProstglesContext.spec.d.ts.map +1 -0
- package/dist/ProstglesContext.spec.js +73 -0
- package/dist/ProstglesContext.spec.js.map +1 -0
- package/dist/ProstglesTypes.d.ts +11 -5
- package/dist/ProstglesTypes.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts +2 -2
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +2 -0
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/defineServerFunction.d.ts +21 -16
- package/dist/PublishParser/defineServerFunction.d.ts.map +1 -1
- package/dist/PublishParser/defineServerFunction.js +7 -1
- package/dist/PublishParser/defineServerFunction.js.map +1 -1
- package/dist/PublishParser/defineServerFunction.spec.js +38 -0
- package/dist/PublishParser/defineServerFunction.spec.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +6 -3
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
- package/dist/StorageClient/getFileTableConfig.d.ts +1 -1
- package/dist/StorageClient/getFileTableConfig.d.ts.map +1 -1
- package/dist/StorageClient/getFileTableConfig.js.map +1 -1
- package/dist/TableConfig/TableConfigTypes.d.ts.map +1 -1
- package/dist/TableConfig/initTableConfig.js +3 -3
- package/dist/TableHooks/TableHooks.d.ts +26 -20
- package/dist/TableHooks/TableHooks.d.ts.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/initProstgles.d.ts +22 -13
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js +11 -2
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.d.ts.map +1 -1
- package/dist/runClientRequest.js.map +1 -1
- package/dist/updateConfiguration.d.ts +1 -1
- package/dist/updateConfiguration.d.ts.map +1 -1
- package/dist/updateConfiguration.js.map +1 -1
- package/lib/DboBuilder/TableHandler/TableHandler.ts +2 -1
- package/lib/DboBuilder/TableHandler/delete.ts +1 -0
- package/lib/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.ts +2 -0
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +2 -2
- package/lib/Prostgles.ts +63 -8
- package/lib/ProstglesContext.spec.ts +76 -0
- package/lib/ProstglesTypes.ts +16 -5
- package/lib/PublishParser/PublishParser.ts +6 -4
- package/lib/PublishParser/defineServerFunction.spec.ts +48 -0
- package/lib/PublishParser/defineServerFunction.ts +61 -21
- package/lib/PublishParser/publishTypesAndUtils.ts +6 -3
- package/lib/StorageClient/getFileTableConfig.ts +2 -2
- package/lib/TableConfig/TableConfigTypes.ts +2 -13
- package/lib/TableConfig/initTableConfig.ts +3 -3
- package/lib/TableHooks/TableHooks.ts +33 -20
- package/lib/index.ts +25 -5
- package/lib/initProstgles.ts +57 -19
- package/lib/runClientRequest.ts +6 -2
- package/lib/updateConfiguration.ts +1 -1
- package/package.json +2 -2
- package/tsconfig.json +2 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, test } from "node:test";
|
|
3
|
+
import type { DboBuilder } from "./DboBuilder/DboBuilder";
|
|
4
|
+
import { Prostgles } from "./Prostgles";
|
|
5
|
+
|
|
6
|
+
void describe("Prostgles context", async () => {
|
|
7
|
+
await test("recreates context and runs cleanups in reverse order", async () => {
|
|
8
|
+
const events: string[] = [];
|
|
9
|
+
let contextId = 0;
|
|
10
|
+
const prostgles = new Prostgles({
|
|
11
|
+
dbConnection: "postgres://unused",
|
|
12
|
+
onReady: () => {},
|
|
13
|
+
createContext: ({ onCleanup }) => {
|
|
14
|
+
const id = ++contextId;
|
|
15
|
+
events.push(`create:${id}`);
|
|
16
|
+
onCleanup(() => {
|
|
17
|
+
events.push(`cleanup:first:${id}`);
|
|
18
|
+
});
|
|
19
|
+
onCleanup(() => {
|
|
20
|
+
events.push(`cleanup:second:${id}`);
|
|
21
|
+
});
|
|
22
|
+
return { id };
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
prostgles.db = {} as typeof prostgles.db;
|
|
26
|
+
prostgles.dboBuilder = {
|
|
27
|
+
build: async () => {},
|
|
28
|
+
dbo: {},
|
|
29
|
+
sql: {},
|
|
30
|
+
tables: [],
|
|
31
|
+
} as unknown as DboBuilder;
|
|
32
|
+
|
|
33
|
+
await prostgles.refreshDBO();
|
|
34
|
+
assert.deepEqual(prostgles.context, { id: 1 });
|
|
35
|
+
await prostgles.refreshDBO();
|
|
36
|
+
assert.deepEqual(prostgles.context, { id: 2 });
|
|
37
|
+
await prostgles.cleanupContext();
|
|
38
|
+
|
|
39
|
+
assert.deepEqual(events, [
|
|
40
|
+
"create:1",
|
|
41
|
+
"cleanup:second:1",
|
|
42
|
+
"cleanup:first:1",
|
|
43
|
+
"create:2",
|
|
44
|
+
"cleanup:second:2",
|
|
45
|
+
"cleanup:first:2",
|
|
46
|
+
]);
|
|
47
|
+
assert.equal(prostgles.context, undefined);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
await test("cleans partially-created context after an error", async () => {
|
|
51
|
+
const events: string[] = [];
|
|
52
|
+
const prostgles = new Prostgles({
|
|
53
|
+
dbConnection: "postgres://unused",
|
|
54
|
+
onReady: () => {},
|
|
55
|
+
createContext: ({ onCleanup }) => {
|
|
56
|
+
onCleanup(() => {
|
|
57
|
+
events.push("cleanup");
|
|
58
|
+
});
|
|
59
|
+
throw new Error("create failed");
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
prostgles.db = {} as typeof prostgles.db;
|
|
63
|
+
prostgles.dbo = {};
|
|
64
|
+
prostgles.dboBuilder = {
|
|
65
|
+
sql: {},
|
|
66
|
+
tables: [],
|
|
67
|
+
} as unknown as DboBuilder;
|
|
68
|
+
|
|
69
|
+
await assert.rejects(
|
|
70
|
+
prostgles.createContext({ type: "init" }),
|
|
71
|
+
/create failed/,
|
|
72
|
+
);
|
|
73
|
+
assert.deepEqual(events, ["cleanup"]);
|
|
74
|
+
assert.equal(prostgles.context, undefined);
|
|
75
|
+
});
|
|
76
|
+
});
|
package/lib/ProstglesTypes.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
SessionUser,
|
|
7
7
|
} from "./Auth/AuthTypes";
|
|
8
8
|
import type { EventTriggerTagFilter } from "./Event_Trigger_Tags";
|
|
9
|
-
import type { DbConnection, OnReadyCallback } from "./initProstgles";
|
|
9
|
+
import type { CreateContext, DbConnection, OnReadyCallback } from "./initProstgles";
|
|
10
10
|
import type { EventInfo } from "./Logging";
|
|
11
11
|
import type { RestApiConfig } from "./RestApi";
|
|
12
12
|
import type { OnSchemaChangeCallback } from "./SchemaWatch/SchemaWatch";
|
|
@@ -102,7 +102,11 @@ type ModifyClientSchema<SUser extends SessionUser = SessionUser> = (
|
|
|
102
102
|
userData: AuthResultWithSID<SUser> | undefined,
|
|
103
103
|
) => MaybePromise<DBSchemaTable>;
|
|
104
104
|
|
|
105
|
-
export type ProstglesInitOptions<
|
|
105
|
+
export type ProstglesInitOptions<
|
|
106
|
+
S = void,
|
|
107
|
+
SUser extends SessionUser = SessionUser,
|
|
108
|
+
Context = undefined,
|
|
109
|
+
> = {
|
|
106
110
|
/**
|
|
107
111
|
* Database connection details and options
|
|
108
112
|
*/
|
|
@@ -112,7 +116,14 @@ export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUs
|
|
|
112
116
|
* Called when the prostgles server is ready to accept connections.
|
|
113
117
|
* It waits for auth, tableConfig and other async configurations to complete before executing
|
|
114
118
|
*/
|
|
115
|
-
onReady: OnReadyCallback<S, SUser>;
|
|
119
|
+
onReady: OnReadyCallback<S, SUser, Context>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Creates instance-scoped dependencies after the database object is ready.
|
|
123
|
+
* The returned context is available to onReady, server functions, and table hooks.
|
|
124
|
+
* Registered cleanups run in reverse order before context replacement and destruction.
|
|
125
|
+
*/
|
|
126
|
+
createContext?: CreateContext<S, Context>;
|
|
116
127
|
|
|
117
128
|
/**
|
|
118
129
|
* Path to the directory where the generated types (`DBGeneratedSchema.d.ts`) will be saved.
|
|
@@ -181,7 +192,7 @@ export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUs
|
|
|
181
192
|
/**
|
|
182
193
|
* Server-side functions that can be invoked by the client
|
|
183
194
|
*/
|
|
184
|
-
functions?: ServerFunctionDefinitions<S, SUser>;
|
|
195
|
+
functions?: ServerFunctionDefinitions<S, SUser, Context>;
|
|
185
196
|
|
|
186
197
|
/**
|
|
187
198
|
* If true then will test all table methods on each socket connect.
|
|
@@ -311,7 +322,7 @@ export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUs
|
|
|
311
322
|
/**
|
|
312
323
|
* Allows defining hooks for table events such as insert, update, delete and select.
|
|
313
324
|
*/
|
|
314
|
-
tableHooks?: TableHooks<S>;
|
|
325
|
+
tableHooks?: TableHooks<S, Context>;
|
|
315
326
|
|
|
316
327
|
/**
|
|
317
328
|
* Useful for logging or debugging
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getObjectEntries, includes, SQL_COMMAND_TABLE_METHODS } from "prostgles-types";
|
|
2
2
|
import { getClientRequestIPsInfo } from "../Auth/AuthHandler";
|
|
3
|
-
import type { AuthClientRequest, AuthResultWithSID } from "../Auth/AuthTypes";
|
|
3
|
+
import type { AuthClientRequest, AuthResultWithSID, SessionUser } from "../Auth/AuthTypes";
|
|
4
4
|
import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
5
5
|
import type { DB, DBHandlerServer, Prostgles } from "../Prostgles";
|
|
6
6
|
import type { ProstglesInitOptions } from "../ProstglesTypes";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "./publishTypesAndUtils";
|
|
28
28
|
|
|
29
29
|
export class PublishParser {
|
|
30
|
-
publish: ProstglesInitOptions["publish"];
|
|
30
|
+
publish: ProstglesInitOptions<void, SessionUser, any>["publish"];
|
|
31
31
|
publishRawSQL?: any;
|
|
32
32
|
dbo: DBHandlerServer;
|
|
33
33
|
db: DB;
|
|
@@ -106,20 +106,22 @@ export class PublishParser {
|
|
|
106
106
|
const runWithContext = async (args: Record<string, unknown> | undefined) => {
|
|
107
107
|
const ctx = await (async () => {
|
|
108
108
|
if (method.unrestrictedDbAccess) {
|
|
109
|
-
const unrestrictedCtx: UnrestrictedFunctionContext = {
|
|
109
|
+
const unrestrictedCtx: UnrestrictedFunctionContext<void, SessionUser, unknown> = {
|
|
110
110
|
...publishParams,
|
|
111
111
|
user,
|
|
112
|
+
context: this.prostgles.context,
|
|
112
113
|
};
|
|
113
114
|
return unrestrictedCtx;
|
|
114
115
|
}
|
|
115
116
|
const { clientDb } = await publishParams.getClientDBHandlers(undefined);
|
|
116
117
|
const { clientInfo, clientReq, tables } = publishParams;
|
|
117
|
-
const restrictedCtx: RestrictedFunctionContext = {
|
|
118
|
+
const restrictedCtx: RestrictedFunctionContext<void, SessionUser, unknown> = {
|
|
118
119
|
dbo: clientDb as unknown as DBOFullyTyped<void>,
|
|
119
120
|
user,
|
|
120
121
|
clientInfo,
|
|
121
122
|
clientReq,
|
|
122
123
|
tables,
|
|
124
|
+
context: this.prostgles.context,
|
|
123
125
|
};
|
|
124
126
|
return restrictedCtx;
|
|
125
127
|
})();
|
|
@@ -2,8 +2,11 @@ import { describe, test } from "node:test";
|
|
|
2
2
|
import {
|
|
3
3
|
defineFunction,
|
|
4
4
|
createFunctionGroupDefiner,
|
|
5
|
+
createFunctionGroupDefinerWithContext,
|
|
5
6
|
createFunctionsDefiner,
|
|
6
7
|
} from "./defineServerFunction";
|
|
8
|
+
import type { TableHooks } from "../TableHooks/TableHooks";
|
|
9
|
+
import { createProstgles } from "../index";
|
|
7
10
|
|
|
8
11
|
type TestSchema = {
|
|
9
12
|
items: {
|
|
@@ -58,5 +61,50 @@ void describe("defineFunction type test", async () => {
|
|
|
58
61
|
|
|
59
62
|
// @ts-expect-error A group must have a user filter.
|
|
60
63
|
defineTestFunctionGroup({ functions });
|
|
64
|
+
|
|
65
|
+
type AppContext = {
|
|
66
|
+
serviceManager: { getService: (name: string) => string };
|
|
67
|
+
};
|
|
68
|
+
const defineContextFunctions =
|
|
69
|
+
createFunctionGroupDefinerWithContext<TestSchema, AppContext>();
|
|
70
|
+
defineContextFunctions({
|
|
71
|
+
userFilter: { type: "public" },
|
|
72
|
+
functions: {
|
|
73
|
+
getContextItem: defineFunction({
|
|
74
|
+
run: (_args, { context, dbo }) => {
|
|
75
|
+
void dbo.items.find();
|
|
76
|
+
return context.serviceManager.getService("documents");
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const contextualHooks: TableHooks<TestSchema, AppContext> = {
|
|
83
|
+
items: {
|
|
84
|
+
afterEach: [
|
|
85
|
+
{
|
|
86
|
+
commands: { insert: 1 },
|
|
87
|
+
validate: ({ context }) => {
|
|
88
|
+
context.serviceManager.getService("documents");
|
|
89
|
+
return Promise.resolve();
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
contextualHooks satisfies TableHooks<TestSchema, AppContext>;
|
|
96
|
+
|
|
97
|
+
const startTestProstgles = createProstgles<TestSchema>();
|
|
98
|
+
const inferredContextTypeTest = () =>
|
|
99
|
+
startTestProstgles({
|
|
100
|
+
dbConnection: "postgres://unused",
|
|
101
|
+
createContext: () => ({
|
|
102
|
+
serviceManager: { getService: (name: string) => name },
|
|
103
|
+
}),
|
|
104
|
+
onReady: ({ context }) => {
|
|
105
|
+
context.serviceManager.getService("documents");
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
void inferredContextTypeTest;
|
|
61
109
|
});
|
|
62
110
|
});
|
|
@@ -12,10 +12,11 @@ import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
|
12
12
|
import type { DB } from "../initProstgles";
|
|
13
13
|
import type { PublishParams } from "./publishTypesAndUtils";
|
|
14
14
|
|
|
15
|
-
type FunctionContextBase<S, SUser extends SessionUser> = Pick<
|
|
15
|
+
type FunctionContextBase<S, SUser extends SessionUser, Context> = Pick<
|
|
16
16
|
PublishParams<S, SUser>,
|
|
17
17
|
"tables" | "clientReq" | "clientInfo"
|
|
18
18
|
> & {
|
|
19
|
+
context: Context;
|
|
19
20
|
dbo: DBOFullyTyped<S>;
|
|
20
21
|
user: S extends DBSchema ?
|
|
21
22
|
S["users"]["columns"] extends AnyObject ?
|
|
@@ -27,18 +28,22 @@ type FunctionContextBase<S, SUser extends SessionUser> = Pick<
|
|
|
27
28
|
export type RestrictedFunctionContext<
|
|
28
29
|
S = void,
|
|
29
30
|
SUser extends SessionUser = SessionUser,
|
|
30
|
-
|
|
31
|
+
Context = undefined,
|
|
32
|
+
> = FunctionContextBase<S, SUser, Context>;
|
|
31
33
|
|
|
32
34
|
export type UnrestrictedFunctionContext<
|
|
33
35
|
S = void,
|
|
34
36
|
SUser extends SessionUser = SessionUser,
|
|
35
|
-
|
|
37
|
+
Context = undefined,
|
|
38
|
+
> = FunctionContextBase<S, SUser, Context> & {
|
|
36
39
|
db: DB;
|
|
37
40
|
sql: SQLHandler;
|
|
38
41
|
getClientDBHandlers: PublishParams<S, SUser>["getClientDBHandlers"];
|
|
39
42
|
};
|
|
40
43
|
|
|
41
|
-
export type ServerFunctionContext =
|
|
44
|
+
export type ServerFunctionContext =
|
|
45
|
+
| RestrictedFunctionContext<void, SessionUser, unknown>
|
|
46
|
+
| UnrestrictedFunctionContext<void, SessionUser, unknown>;
|
|
42
47
|
|
|
43
48
|
export type ServerFunctionDefinition = {
|
|
44
49
|
input?: Record<string, JSONB.FieldType>;
|
|
@@ -48,8 +53,12 @@ export type ServerFunctionDefinition = {
|
|
|
48
53
|
};
|
|
49
54
|
|
|
50
55
|
declare const serverFunctionContext: unique symbol;
|
|
51
|
-
export type ServerFunctionContextMarker<
|
|
52
|
-
|
|
56
|
+
export type ServerFunctionContextMarker<
|
|
57
|
+
S,
|
|
58
|
+
SUser extends SessionUser,
|
|
59
|
+
Context = undefined,
|
|
60
|
+
> = {
|
|
61
|
+
[serverFunctionContext]?: [S, SUser, Context];
|
|
53
62
|
};
|
|
54
63
|
|
|
55
64
|
type DefineFunctionArgs<
|
|
@@ -67,22 +76,24 @@ export function defineFunction<
|
|
|
67
76
|
S = void,
|
|
68
77
|
SUser extends SessionUser = SessionUser,
|
|
69
78
|
Return = unknown,
|
|
79
|
+
Context = undefined,
|
|
70
80
|
>(
|
|
71
|
-
args: DefineFunctionArgs<TInput, UnrestrictedFunctionContext<S, SUser>, Return> & {
|
|
81
|
+
args: DefineFunctionArgs<TInput, UnrestrictedFunctionContext<S, SUser, Context>, Return> & {
|
|
72
82
|
unrestrictedDbAccess: true;
|
|
73
83
|
},
|
|
74
|
-
): typeof args & ServerFunctionContextMarker<S, SUser>;
|
|
84
|
+
): typeof args & ServerFunctionContextMarker<S, SUser, Context>;
|
|
75
85
|
|
|
76
86
|
export function defineFunction<
|
|
77
87
|
TInput extends Record<string, JSONB.FieldType> | undefined = undefined,
|
|
78
88
|
S = void,
|
|
79
89
|
SUser extends SessionUser = SessionUser,
|
|
80
90
|
Return = unknown,
|
|
91
|
+
Context = undefined,
|
|
81
92
|
>(
|
|
82
|
-
args: DefineFunctionArgs<TInput, RestrictedFunctionContext<S, SUser>, Return> & {
|
|
93
|
+
args: DefineFunctionArgs<TInput, RestrictedFunctionContext<S, SUser, Context>, Return> & {
|
|
83
94
|
unrestrictedDbAccess?: undefined;
|
|
84
95
|
},
|
|
85
|
-
): typeof args & ServerFunctionContextMarker<S, SUser>;
|
|
96
|
+
): typeof args & ServerFunctionContextMarker<S, SUser, Context>;
|
|
86
97
|
export function defineFunction(args: unknown) {
|
|
87
98
|
return args;
|
|
88
99
|
}
|
|
@@ -99,30 +110,59 @@ type ValidDbSchema<S> = S extends DBSchema ? S : void;
|
|
|
99
110
|
export type ServerFunctionGroupFunctions<
|
|
100
111
|
S = void,
|
|
101
112
|
SUser extends SessionUser = SessionUser,
|
|
102
|
-
|
|
113
|
+
Context = undefined,
|
|
114
|
+
> = Record<string, ServerFunctionDefinition & ServerFunctionContextMarker<S, SUser, Context>>;
|
|
103
115
|
|
|
104
|
-
export type ServerFunctionGroup<
|
|
116
|
+
export type ServerFunctionGroup<
|
|
117
|
+
S = void,
|
|
118
|
+
SUser extends SessionUser = SessionUser,
|
|
119
|
+
Context = undefined,
|
|
120
|
+
> = {
|
|
105
121
|
userFilter: FullFilter<UsersTableRow<S>, ValidDbSchema<S>>;
|
|
106
|
-
functions: ServerFunctionGroupFunctions<S, SUser>;
|
|
122
|
+
functions: ServerFunctionGroupFunctions<S, SUser, Context>;
|
|
107
123
|
};
|
|
108
124
|
|
|
109
|
-
export type ServerFunctionDefinitions<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
export type ServerFunctionDefinitions<
|
|
126
|
+
S = void,
|
|
127
|
+
SUser extends SessionUser = SessionUser,
|
|
128
|
+
Context = undefined,
|
|
129
|
+
> = Record<string, ServerFunctionGroup<S, SUser, Context>>;
|
|
113
130
|
|
|
114
131
|
/**
|
|
115
132
|
* Creates a schema-aware identity helper for defining a server function group
|
|
116
133
|
* while preserving its inferred function names and return types.
|
|
117
134
|
*/
|
|
118
|
-
export const createFunctionGroupDefiner = <
|
|
119
|
-
|
|
135
|
+
export const createFunctionGroupDefiner = <
|
|
136
|
+
S = void,
|
|
137
|
+
SUser extends SessionUser = SessionUser,
|
|
138
|
+
Context = undefined,
|
|
139
|
+
>() => {
|
|
140
|
+
return <const T extends ServerFunctionGroup<S, SUser, Context>>(group: T): T => group;
|
|
120
141
|
};
|
|
121
142
|
|
|
143
|
+
/** Creates a schema-aware function group definer with application context. */
|
|
144
|
+
export const createFunctionGroupDefinerWithContext = <
|
|
145
|
+
S,
|
|
146
|
+
Context,
|
|
147
|
+
SUser extends SessionUser = SessionUser,
|
|
148
|
+
>() => createFunctionGroupDefiner<S, SUser, Context>();
|
|
149
|
+
|
|
122
150
|
/**
|
|
123
151
|
* Creates a schema-aware identity helper for function maps that are composed
|
|
124
152
|
* into a server function group elsewhere.
|
|
125
153
|
*/
|
|
126
|
-
export const createFunctionsDefiner = <
|
|
127
|
-
|
|
154
|
+
export const createFunctionsDefiner = <
|
|
155
|
+
S = void,
|
|
156
|
+
SUser extends SessionUser = SessionUser,
|
|
157
|
+
Context = undefined,
|
|
158
|
+
>() => {
|
|
159
|
+
return <const T extends ServerFunctionGroupFunctions<S, SUser, Context>>(functions: T): T =>
|
|
160
|
+
functions;
|
|
128
161
|
};
|
|
162
|
+
|
|
163
|
+
/** Creates a schema-aware function-map definer with application context. */
|
|
164
|
+
export const createFunctionsDefinerWithContext = <
|
|
165
|
+
S,
|
|
166
|
+
Context,
|
|
167
|
+
SUser extends SessionUser = SessionUser,
|
|
168
|
+
>() => createFunctionsDefiner<S, SUser, Context>();
|
|
@@ -81,7 +81,7 @@ export type ValidateRowArgsCommon<R = AnyObject, DBX = DBHandlerServer> = {
|
|
|
81
81
|
}
|
|
82
82
|
);
|
|
83
83
|
|
|
84
|
-
export type BeforeEachTsTrigger<R, DBX> = {
|
|
84
|
+
export type BeforeEachTsTrigger<R, DBX, Context = undefined> = {
|
|
85
85
|
commands: Partial<Record<"insert" | "update", 1>>;
|
|
86
86
|
/**
|
|
87
87
|
* Will only run this trigger if the insert/update provides non null values for these fields.
|
|
@@ -91,11 +91,12 @@ export type BeforeEachTsTrigger<R, DBX> = {
|
|
|
91
91
|
params: ValidateBeforeRowArgsCommon<R, DBX> & {
|
|
92
92
|
localParams: undefined | LocalParams;
|
|
93
93
|
hookContext: AnyObject | undefined;
|
|
94
|
+
context: Context;
|
|
94
95
|
},
|
|
95
96
|
) => MaybePromise<void | { row: Partial<R>; hookContext?: AnyObject; onInserted?: () => void }>;
|
|
96
97
|
};
|
|
97
98
|
|
|
98
|
-
export type AfterEachTsTrigger<R, DBX> = {
|
|
99
|
+
export type AfterEachTsTrigger<R, DBX, Context = undefined> = {
|
|
99
100
|
commands: Partial<Record<"insert" | "update" | "delete", 1>>;
|
|
100
101
|
/**
|
|
101
102
|
* Will only run this trigger if the insert/update provides non null values for these fields.
|
|
@@ -104,6 +105,7 @@ export type AfterEachTsTrigger<R, DBX> = {
|
|
|
104
105
|
validate: (
|
|
105
106
|
params: ValidateRowArgsCommon<R, DBX> & {
|
|
106
107
|
localParams: undefined | LocalParams;
|
|
108
|
+
context: Context;
|
|
107
109
|
},
|
|
108
110
|
) => Promise<void>;
|
|
109
111
|
};
|
|
@@ -139,12 +141,13 @@ export type ValidateRowsArgsCommon<R = AnyObject, DBX = DBHandlerServer> = {
|
|
|
139
141
|
}
|
|
140
142
|
);
|
|
141
143
|
|
|
142
|
-
export type AfterAllTsTrigger<R, DBX> = {
|
|
144
|
+
export type AfterAllTsTrigger<R, DBX, Context = undefined> = {
|
|
143
145
|
commands: Partial<Record<"insert" | "update" | "delete", 1>>;
|
|
144
146
|
changedFields?: string[];
|
|
145
147
|
validate: (
|
|
146
148
|
params: ValidateRowsArgsCommon<R, DBX> & {
|
|
147
149
|
localParams: undefined | LocalParams;
|
|
150
|
+
context: Context;
|
|
148
151
|
},
|
|
149
152
|
) => Promise<void>;
|
|
150
153
|
};
|
|
@@ -44,7 +44,7 @@ export type FileTableRow = {
|
|
|
44
44
|
|
|
45
45
|
export const getFileTableConfig = (
|
|
46
46
|
prg: Prostgles,
|
|
47
|
-
): { tableConfig: TableConfig | undefined; tableHooks: TableHooks | undefined } => {
|
|
47
|
+
): { tableConfig: TableConfig | undefined; tableHooks: TableHooks<void, any> | undefined } => {
|
|
48
48
|
const { fileTable, tableConfig, tableHooks } = prg.opts;
|
|
49
49
|
if (!fileTable) {
|
|
50
50
|
return { tableConfig, tableHooks };
|
|
@@ -102,7 +102,7 @@ export const getFileTableConfig = (
|
|
|
102
102
|
};
|
|
103
103
|
|
|
104
104
|
const userFileTableHooks = tableHooks?.[fileTableName];
|
|
105
|
-
const mergedTableHooks: TableHooks = {
|
|
105
|
+
const mergedTableHooks: TableHooks<void, any> = {
|
|
106
106
|
[fileTableName]: {
|
|
107
107
|
...userFileTableHooks,
|
|
108
108
|
beforeEach: [
|
|
@@ -1,24 +1,13 @@
|
|
|
1
|
-
import type pgPromise from "pg-promise";
|
|
2
1
|
import type {
|
|
3
2
|
ALLOWED_CONTENT_TYPE,
|
|
4
3
|
ALLOWED_EXTENSION,
|
|
5
|
-
AnyObject,
|
|
6
|
-
DBSchema,
|
|
7
4
|
JSONB,
|
|
8
5
|
MaybePromise,
|
|
9
6
|
StrictUnion,
|
|
10
7
|
} from "prostgles-types";
|
|
11
|
-
import type { JoinInfo
|
|
12
|
-
import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
8
|
+
import type { JoinInfo } from "../DboBuilder/DboBuilder";
|
|
13
9
|
import type { DB, DBHandlerServer } from "../Prostgles";
|
|
14
|
-
import type {
|
|
15
|
-
AfterAllTsTrigger,
|
|
16
|
-
AfterEachTsTrigger,
|
|
17
|
-
BeforeEachTsTrigger,
|
|
18
|
-
InsertRule,
|
|
19
|
-
SyncConfig,
|
|
20
|
-
ValidateRowArgsCommon,
|
|
21
|
-
} from "../PublishParser/PublishParser";
|
|
10
|
+
import type { SyncConfig } from "../PublishParser/PublishParser";
|
|
22
11
|
|
|
23
12
|
export type ColExtraInfo = {
|
|
24
13
|
min?: string | number;
|
|
@@ -153,7 +153,7 @@ export const initTableConfig = async function (this: TableConfigurator) {
|
|
|
153
153
|
|
|
154
154
|
if (queries.length) {
|
|
155
155
|
await runQueries(queries);
|
|
156
|
-
await this.prostgles.
|
|
156
|
+
await this.prostgles.rebuildDBO();
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
/* Create/Alter columns */
|
|
@@ -348,8 +348,8 @@ export const initTableConfig = async function (this: TableConfigurator) {
|
|
|
348
348
|
console.error("Table config failed queries: ", failedQueries);
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
await this.prostgles.
|
|
351
|
+
await this.prostgles.rebuildDBO();
|
|
352
352
|
await this.setTableOnMounts();
|
|
353
353
|
/** Needed in case some onMounts change schema */
|
|
354
|
-
await this.prostgles.
|
|
354
|
+
await this.prostgles.rebuildDBO();
|
|
355
355
|
};
|
|
@@ -1,38 +1,56 @@
|
|
|
1
1
|
import type pgPromise from "pg-promise";
|
|
2
2
|
import type { AnyObject, DBSchema } from "prostgles-types";
|
|
3
3
|
|
|
4
|
-
import type { DbTxTableHandlers
|
|
4
|
+
import type { DbTxTableHandlers } from "../DboBuilder/DboBuilderTypes";
|
|
5
5
|
import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
6
6
|
import type {
|
|
7
7
|
AfterAllTsTrigger,
|
|
8
8
|
AfterEachTsTrigger,
|
|
9
9
|
BeforeEachTsTrigger,
|
|
10
|
-
InsertRule,
|
|
11
|
-
ValidateRowArgsCommon,
|
|
12
10
|
} from "../PublishParser/PublishParser";
|
|
13
11
|
|
|
14
|
-
export type TableHooks<S = void> =
|
|
12
|
+
export type TableHooks<S = void, Context = undefined> =
|
|
15
13
|
S extends DBSchema ?
|
|
16
14
|
Partial<{
|
|
17
15
|
[tableName in keyof S]: TableHooksDefinition<
|
|
18
16
|
Required<S[tableName]["columns"]>,
|
|
19
|
-
DBOFullyTyped<S
|
|
17
|
+
DBOFullyTyped<S>,
|
|
18
|
+
Context
|
|
20
19
|
>;
|
|
21
20
|
}>
|
|
22
|
-
: Record<string, TableHooksDefinition
|
|
21
|
+
: Record<string, TableHooksDefinition<AnyObject, DbTxTableHandlers, Context>>;
|
|
23
22
|
|
|
24
|
-
export type TableHooksDefinition<
|
|
23
|
+
export type TableHooksDefinition<
|
|
24
|
+
RowDataType = AnyObject,
|
|
25
|
+
DBX = DbTxTableHandlers,
|
|
26
|
+
Context = undefined,
|
|
27
|
+
> = {
|
|
25
28
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
29
|
+
* Runs sequentially before validation and SQL for each insert row, or once per update request.
|
|
30
|
+
* May replace the pending data and pass `hookContext` to the next hook.
|
|
31
|
+
* `onInserted` also runs for updates, is not awaited, and runs before the transaction commits.
|
|
32
|
+
*/
|
|
33
|
+
beforeEach?: BeforeEachTsTrigger<RowDataType, DBX, Context>[];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Runs once per affected row after SQL, inside the same transaction.
|
|
37
|
+
* `row` is the inserted/updated row or the deleted row's pre-delete state. Throwing rolls back.
|
|
38
|
+
*/
|
|
39
|
+
afterEach?: AfterEachTsTrigger<RowDataType, DBX, Context>[];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Runs once after all applicable `afterEach` hooks, inside the same transaction.
|
|
43
|
+
* Receives all affected `rows`; throwing rolls back the operation.
|
|
44
|
+
* Same-table, same-command writes from after-hooks do not retrigger after-hooks.
|
|
45
|
+
*/
|
|
46
|
+
afterAll?: AfterAllTsTrigger<RowDataType, DBX, Context>[];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Replaces the generated DELETE. Must perform the mutation and shape its return value using
|
|
50
|
+
* the prepared filter and returning arguments. Delete `afterEach`/`afterAll` hooks do not run.
|
|
28
51
|
*/
|
|
29
|
-
getPreInsertRow?: (
|
|
30
|
-
args: PreInsertRowArgs,
|
|
31
|
-
) => Promise<{ row: AnyObject; onInserted: Promise<void> }>;
|
|
32
|
-
beforeEach?: BeforeEachTsTrigger<R, DBX>[];
|
|
33
|
-
afterEach?: AfterEachTsTrigger<R, DBX>[];
|
|
34
|
-
afterAll?: AfterAllTsTrigger<R, DBX>[];
|
|
35
52
|
onInsteadOfDelete?: (args: {
|
|
53
|
+
context: Context;
|
|
36
54
|
dbx: DBX;
|
|
37
55
|
tx: pgPromise.ITask<{}>;
|
|
38
56
|
returningQuery: string;
|
|
@@ -44,8 +62,3 @@ export type TableHooksDefinition<R = AnyObject, DBX = DbTxTableHandlers> = {
|
|
|
44
62
|
};
|
|
45
63
|
}) => Promise<AnyObject[] | undefined>;
|
|
46
64
|
};
|
|
47
|
-
|
|
48
|
-
type PreInsertRowArgs = Omit<ValidateRowArgsCommon, "localParams"> & {
|
|
49
|
-
validate: InsertRule["validate"];
|
|
50
|
-
localParams: LocalParams | undefined;
|
|
51
|
-
};
|
package/lib/index.ts
CHANGED
|
@@ -3,14 +3,26 @@ import type { InitResult, OnReadyCallbackBasic } from "./initProstgles";
|
|
|
3
3
|
import { Prostgles } from "./Prostgles";
|
|
4
4
|
import type { ProstglesInitOptions } from "./ProstglesTypes";
|
|
5
5
|
|
|
6
|
-
function prostgles<
|
|
7
|
-
|
|
6
|
+
function prostgles<
|
|
7
|
+
S = void,
|
|
8
|
+
SUser extends SessionUser = SessionUser,
|
|
9
|
+
Context = undefined,
|
|
10
|
+
>(
|
|
11
|
+
params: ProstglesInitOptions<S, SUser, Context>,
|
|
8
12
|
) {
|
|
9
|
-
const prgl = new Prostgles(
|
|
13
|
+
const prgl = new Prostgles(
|
|
14
|
+
params as unknown as ProstglesInitOptions<void, SessionUser, any>,
|
|
15
|
+
);
|
|
10
16
|
return prgl.init(params.onReady as unknown as OnReadyCallbackBasic, {
|
|
11
17
|
type: "init",
|
|
12
|
-
}) as unknown as Promise<InitResult<S, SUser>>;
|
|
18
|
+
}) as unknown as Promise<InitResult<S, SUser, Context>>;
|
|
13
19
|
}
|
|
20
|
+
|
|
21
|
+
/** Creates a schema-bound Prostgles initializer while allowing context inference. */
|
|
22
|
+
export const createProstgles = <S = void, SUser extends SessionUser = SessionUser>() => {
|
|
23
|
+
return <Context = undefined>(params: ProstglesInitOptions<S, SUser, Context>) =>
|
|
24
|
+
prostgles<S, SUser, Context>(params);
|
|
25
|
+
};
|
|
14
26
|
export * from "./PublishParser/defineServerFunction";
|
|
15
27
|
export * from "./Auth/AuthTypes";
|
|
16
28
|
export type { PublishParams } from "./PublishParser/publishTypesAndUtils";
|
|
@@ -18,7 +30,15 @@ export type { DBOFullyTyped } from "./DBSchemaBuilder/DBSchemaBuilder";
|
|
|
18
30
|
export type { DBHandlerServer } from "./Prostgles";
|
|
19
31
|
export type { StorageClient as CloudClient } from "./StorageClient/StorageClientTypes";
|
|
20
32
|
export * from "./StorageClient/getLocalStorageClient";
|
|
21
|
-
export type {
|
|
33
|
+
export type {
|
|
34
|
+
ContextCleanup,
|
|
35
|
+
CreateContext,
|
|
36
|
+
CreateContextParams,
|
|
37
|
+
DB,
|
|
38
|
+
InitResult,
|
|
39
|
+
OnReadyParams,
|
|
40
|
+
} from "./initProstgles";
|
|
41
|
+
export type { ProstglesInitOptions } from "./ProstglesTypes";
|
|
22
42
|
export type * from "./TableConfig/TableConfigTypes";
|
|
23
43
|
export type * from "./TableHooks/TableHooks";
|
|
24
44
|
export * from "./Auth/utils/upsertNamedExpressMiddleware";
|