on-zero 0.6.12 → 0.6.13
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/cjs/createZeroSQLiteServer.cjs +319 -0
- package/dist/cjs/createZeroSQLiteServer.native.js +440 -0
- package/dist/cjs/createZeroSQLiteServer.native.js.map +1 -0
- package/dist/cjs/createZeroSQLiteServer.test.cjs +429 -0
- package/dist/cjs/createZeroSQLiteServer.test.native.js +466 -0
- package/dist/cjs/createZeroSQLiteServer.test.native.js.map +1 -0
- package/dist/cjs/createZeroServer.cjs +20 -234
- package/dist/cjs/createZeroServer.native.js +24 -250
- package/dist/cjs/createZeroServer.native.js.map +1 -1
- package/dist/cjs/createZeroServer.test.cjs +35 -1
- package/dist/cjs/createZeroServer.test.native.js +38 -1
- package/dist/cjs/createZeroServer.test.native.js.map +1 -1
- package/dist/cjs/createZeroServerCore.cjs +362 -0
- package/dist/cjs/createZeroServerCore.native.js +389 -0
- package/dist/cjs/createZeroServerCore.native.js.map +1 -0
- package/dist/cjs/generate-lite.cjs +1 -0
- package/dist/cjs/generate-lite.native.js +1 -0
- package/dist/cjs/generate-lite.native.js.map +1 -1
- package/dist/cjs/generate-lite.test.cjs +5 -1
- package/dist/cjs/generate-lite.test.native.js +5 -1
- package/dist/cjs/generate-lite.test.native.js.map +1 -1
- package/dist/cjs/generate.cjs +20 -11
- package/dist/cjs/generate.native.js +29 -21
- package/dist/cjs/generate.native.js.map +1 -1
- package/dist/cjs/generate.test.cjs +110 -0
- package/dist/cjs/generate.test.native.js +110 -0
- package/dist/cjs/generate.test.native.js.map +1 -1
- package/dist/cjs/httpPull/transport.test.cjs +5 -4
- package/dist/cjs/httpPull/transport.test.native.js +6 -5
- package/dist/cjs/httpPull/transport.test.native.js.map +1 -1
- package/dist/cjs/httpPullTransport.cjs +2 -1
- package/dist/cjs/httpPullTransport.native.js +3 -2
- package/dist/cjs/httpPullTransport.native.js.map +1 -1
- package/dist/cjs/server.cjs +2 -1
- package/dist/cjs/syncHost.cjs +164 -0
- package/dist/cjs/syncHost.native.js +371 -0
- package/dist/cjs/syncHost.native.js.map +1 -0
- package/dist/cjs/syncHost.test.cjs +229 -0
- package/dist/cjs/syncHost.test.native.js +278 -0
- package/dist/cjs/syncHost.test.native.js.map +1 -0
- package/dist/esm/createZeroSQLiteServer.mjs +293 -0
- package/dist/esm/createZeroSQLiteServer.mjs.map +1 -0
- package/dist/esm/createZeroSQLiteServer.native.js +411 -0
- package/dist/esm/createZeroSQLiteServer.native.js.map +1 -0
- package/dist/esm/createZeroSQLiteServer.test.mjs +430 -0
- package/dist/esm/createZeroSQLiteServer.test.mjs.map +1 -0
- package/dist/esm/createZeroSQLiteServer.test.native.js +464 -0
- package/dist/esm/createZeroSQLiteServer.test.native.js.map +1 -0
- package/dist/esm/createZeroServer.mjs +17 -231
- package/dist/esm/createZeroServer.mjs.map +1 -1
- package/dist/esm/createZeroServer.native.js +21 -247
- package/dist/esm/createZeroServer.native.js.map +1 -1
- package/dist/esm/createZeroServer.test.mjs +35 -1
- package/dist/esm/createZeroServer.test.mjs.map +1 -1
- package/dist/esm/createZeroServer.test.native.js +38 -1
- package/dist/esm/createZeroServer.test.native.js.map +1 -1
- package/dist/esm/createZeroServerCore.mjs +336 -0
- package/dist/esm/createZeroServerCore.mjs.map +1 -0
- package/dist/esm/createZeroServerCore.native.js +360 -0
- package/dist/esm/createZeroServerCore.native.js.map +1 -0
- package/dist/esm/generate-lite.mjs +1 -0
- package/dist/esm/generate-lite.mjs.map +1 -1
- package/dist/esm/generate-lite.native.js +1 -0
- package/dist/esm/generate-lite.native.js.map +1 -1
- package/dist/esm/generate-lite.test.mjs +5 -1
- package/dist/esm/generate-lite.test.mjs.map +1 -1
- package/dist/esm/generate-lite.test.native.js +5 -1
- package/dist/esm/generate-lite.test.native.js.map +1 -1
- package/dist/esm/generate.mjs +20 -11
- package/dist/esm/generate.mjs.map +1 -1
- package/dist/esm/generate.native.js +29 -21
- package/dist/esm/generate.native.js.map +1 -1
- package/dist/esm/generate.test.mjs +87 -1
- package/dist/esm/generate.test.mjs.map +1 -1
- package/dist/esm/generate.test.native.js +87 -1
- package/dist/esm/generate.test.native.js.map +1 -1
- package/dist/esm/httpPull/transport.test.mjs +5 -4
- package/dist/esm/httpPull/transport.test.mjs.map +1 -1
- package/dist/esm/httpPull/transport.test.native.js +6 -5
- package/dist/esm/httpPull/transport.test.native.js.map +1 -1
- package/dist/esm/httpPullTransport.mjs +2 -1
- package/dist/esm/httpPullTransport.mjs.map +1 -1
- package/dist/esm/httpPullTransport.native.js +3 -2
- package/dist/esm/httpPullTransport.native.js.map +1 -1
- package/dist/esm/server.mjs +1 -0
- package/dist/esm/server.mjs.map +1 -1
- package/dist/esm/syncHost.mjs +138 -0
- package/dist/esm/syncHost.mjs.map +1 -0
- package/dist/esm/syncHost.native.js +342 -0
- package/dist/esm/syncHost.native.js.map +1 -0
- package/dist/esm/syncHost.test.mjs +206 -0
- package/dist/esm/syncHost.test.mjs.map +1 -0
- package/dist/esm/syncHost.test.native.js +252 -0
- package/dist/esm/syncHost.test.native.js.map +1 -0
- package/package.json +19 -3
- package/readme.md +26 -0
- package/src/createZeroSQLiteServer.test.ts +461 -0
- package/src/createZeroSQLiteServer.ts +523 -0
- package/src/createZeroServer.test.ts +39 -1
- package/src/createZeroServer.ts +35 -428
- package/src/createZeroServerCore.ts +557 -0
- package/src/generate-lite.test.ts +4 -0
- package/src/generate-lite.ts +1 -0
- package/src/generate.test.ts +87 -1
- package/src/generate.ts +29 -20
- package/src/httpPull/transport.test.ts +6 -5
- package/src/httpPullTransport.ts +9 -4
- package/src/server.ts +1 -0
- package/src/syncHost.test.ts +216 -0
- package/src/syncHost.ts +255 -0
- package/test-fixtures/server-return-types.ts +50 -0
- package/test-fixtures/tsconfig.json +13 -0
- package/types/createZeroSQLiteServer.d.ts +37 -0
- package/types/createZeroSQLiteServer.d.ts.map +1 -0
- package/types/createZeroSQLiteServer.test.d.ts +2 -0
- package/types/createZeroSQLiteServer.test.d.ts.map +1 -0
- package/types/createZeroServer.d.ts +11 -293
- package/types/createZeroServer.d.ts.map +1 -1
- package/types/createZeroServerCore.d.ts +310 -0
- package/types/createZeroServerCore.d.ts.map +1 -0
- package/types/generate-lite.d.ts.map +1 -1
- package/types/generate.d.ts +2 -1
- package/types/generate.d.ts.map +1 -1
- package/types/httpPullTransport.d.ts +1 -0
- package/types/httpPullTransport.d.ts.map +1 -1
- package/types/server.d.ts +1 -0
- package/types/server.d.ts.map +1 -1
- package/types/syncHost.d.ts +51 -0
- package/types/syncHost.d.ts.map +1 -0
- package/types/syncHost.test.d.ts +2 -0
- package/types/syncHost.test.d.ts.map +1 -0
|
@@ -1,265 +1,51 @@
|
|
|
1
|
-
import { mustGetQuery } from "@rocicorp/zero";
|
|
2
|
-
import { PushProcessor } from "@rocicorp/zero/pg";
|
|
3
|
-
import { handleQueryRequest as zeroHandleQueryRequest } from "@rocicorp/zero/server";
|
|
4
1
|
import { zeroNodePg } from "@rocicorp/zero/server/adapters/pg";
|
|
5
2
|
import { assertString } from "@take-out/helpers";
|
|
6
3
|
import { Pool } from "pg";
|
|
7
|
-
import {
|
|
8
|
-
import { createMutators } from "./helpers/createMutators.mjs";
|
|
9
|
-
import { getScopedAuthData, isInZeroMutation, mutatorContext, runWithAuthScope } from "./helpers/mutatorContext.mjs";
|
|
10
|
-
import { runWithQueryContext } from "./helpers/queryContext.mjs";
|
|
11
|
-
import { getMutationsPermissions } from "./modelRegistry.mjs";
|
|
12
|
-
import { setCustomQueries } from "./run.mjs";
|
|
13
|
-
import { getZQL, setEnvironment, setSchema } from "./state.mjs";
|
|
14
|
-
import { setEvaluatingPermission } from "./where.mjs";
|
|
15
|
-
import { setRunner } from "./zeroRunner.mjs";
|
|
4
|
+
import { createZeroServerCore } from "./createZeroServerCore.mjs";
|
|
16
5
|
function createZeroServer({
|
|
17
|
-
createServerActions,
|
|
18
6
|
database,
|
|
19
7
|
pool: externalPool,
|
|
20
|
-
|
|
21
|
-
models,
|
|
22
|
-
queries,
|
|
23
|
-
mutations: mutationValidators,
|
|
24
|
-
validateQuery,
|
|
25
|
-
validateMutation,
|
|
26
|
-
defaultAllowAdminRole = "all",
|
|
27
|
-
defaultMutateAuthData = {}
|
|
8
|
+
...options
|
|
28
9
|
}) {
|
|
29
|
-
setSchema(schema);
|
|
30
|
-
setEnvironment("server");
|
|
31
10
|
let pool;
|
|
32
11
|
if (externalPool) {
|
|
33
12
|
pool = externalPool;
|
|
34
13
|
} else {
|
|
35
|
-
const dbString = assertString(database,
|
|
14
|
+
const dbString = assertString(database, 'createZeroServer "database"');
|
|
36
15
|
const pgPool = new Pool({
|
|
37
16
|
connectionString: dbString,
|
|
38
|
-
// handle self-signed certificates in production
|
|
39
17
|
ssl: dbString.includes("sslmode=require") ? {
|
|
40
18
|
rejectUnauthorized: false
|
|
41
19
|
} : void 0
|
|
42
20
|
});
|
|
43
21
|
pgPool.on("error", error => {
|
|
44
|
-
console.error(
|
|
22
|
+
console.error("[on-zero] pool error", error.message);
|
|
45
23
|
});
|
|
46
24
|
pgPool.on("connect", client => {
|
|
47
25
|
client.on("error", error => {
|
|
48
|
-
console.error(
|
|
26
|
+
console.error("[on-zero] client error", error.message);
|
|
49
27
|
});
|
|
50
28
|
});
|
|
51
29
|
pool = pgPool;
|
|
52
30
|
}
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
});
|
|
59
|
-
const processor = new PushProcessor(zeroDb);
|
|
60
|
-
const handleMutationRequest = async ({
|
|
61
|
-
authData,
|
|
62
|
-
request,
|
|
63
|
-
skipAsyncTasks
|
|
64
|
-
}) => {
|
|
65
|
-
const asyncTasks = [];
|
|
66
|
-
const recoveryRequest = request.clone();
|
|
67
|
-
const mutators = createMutators({
|
|
68
|
-
asyncTasks,
|
|
69
|
-
can: permissions.can,
|
|
70
|
-
createServerActions,
|
|
71
|
-
environment: "server",
|
|
72
|
-
models,
|
|
73
|
-
authData,
|
|
74
|
-
validateMutation,
|
|
75
|
-
mutationValidators
|
|
76
|
-
});
|
|
77
|
-
const response = await processor.process(mutators, request);
|
|
78
|
-
await persistAlreadyProcessedMutationResults(pool, recoveryRequest, response);
|
|
79
|
-
if (!skipAsyncTasks && asyncTasks.length) {
|
|
80
|
-
Promise.all(asyncTasks.map(task => runWithAuthScope(authData, task))).catch(err => {
|
|
81
|
-
console.error(`[push] async tasks failed`, err);
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
response,
|
|
86
|
-
asyncTasks
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
const handleQueryRequest = async ({
|
|
90
|
-
authData,
|
|
91
|
-
request
|
|
92
|
-
}) => {
|
|
93
|
-
if (!queries) {
|
|
94
|
-
throw new Error("No queries registered with createZeroServer. Pass the syncedQueries registry to createZeroServer via the queries option.");
|
|
95
|
-
}
|
|
96
|
-
const handler = (name, args) => {
|
|
97
|
-
if (name.startsWith("permission.")) {
|
|
98
|
-
const table = name.slice("permission.".length);
|
|
99
|
-
const {
|
|
100
|
-
objOrId
|
|
101
|
-
} = args;
|
|
102
|
-
const perm = getMutationsPermissions(table);
|
|
103
|
-
if (!perm) {
|
|
104
|
-
throw new Error(`[permission] no permission defined for table: ${table}`);
|
|
105
|
-
}
|
|
106
|
-
setEvaluatingPermission(true);
|
|
107
|
-
try {
|
|
108
|
-
return getZQL()[table].where(eb => {
|
|
109
|
-
return permissions.buildPermissionQuery(authData, eb, perm, objOrId, table);
|
|
110
|
-
}).one();
|
|
111
|
-
} finally {
|
|
112
|
-
setEvaluatingPermission(false);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (validateQuery) {
|
|
116
|
-
validateQuery({
|
|
117
|
-
authData,
|
|
118
|
-
queryName: name,
|
|
119
|
-
params: args
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
const query2 = mustGetQuery(queries, name);
|
|
123
|
-
return query2.fn({
|
|
124
|
-
args,
|
|
125
|
-
ctx: authData
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
const userID = typeof authData?.id === "string" ? authData.id : void 0;
|
|
129
|
-
const response = await runWithQueryContext({
|
|
130
|
-
authData: authData || {}
|
|
131
|
-
}, () => userID === void 0 ? zeroHandleQueryRequest(handler, schema, request) : zeroHandleQueryRequest({
|
|
132
|
-
handler,
|
|
133
|
-
schema,
|
|
134
|
-
request,
|
|
135
|
-
userID
|
|
136
|
-
}));
|
|
137
|
-
return {
|
|
138
|
-
response
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
async function runMutate(modelName, mutatorName, mutatorArg, options) {
|
|
142
|
-
let authData = options?.authData;
|
|
143
|
-
if (!authData) {
|
|
144
|
-
const scoped = getScopedAuthData();
|
|
145
|
-
if (scoped) {
|
|
146
|
-
authData = scoped;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const asyncTasks = [];
|
|
150
|
-
const mutators = createMutators({
|
|
151
|
-
models,
|
|
152
|
-
environment: "server",
|
|
153
|
-
asyncTasks,
|
|
154
|
-
authData: {
|
|
155
|
-
...defaultMutateAuthData,
|
|
156
|
-
...authData
|
|
157
|
-
},
|
|
158
|
-
createServerActions,
|
|
159
|
-
can: permissions.can,
|
|
160
|
-
validateMutation,
|
|
161
|
-
mutationValidators
|
|
162
|
-
});
|
|
163
|
-
const modelMutators = mutators[modelName];
|
|
164
|
-
const mutator = modelMutators[mutatorName];
|
|
165
|
-
await transaction(async tx => {
|
|
166
|
-
await mutator(tx, mutatorArg);
|
|
167
|
-
});
|
|
168
|
-
if (asyncTasks.length) {
|
|
169
|
-
const resolvedAuth = authData ?? null;
|
|
170
|
-
const promise = Promise.all(asyncTasks.map(t => runWithAuthScope(resolvedAuth, t)));
|
|
171
|
-
if (options?.awaitEffects) {
|
|
172
|
-
await promise;
|
|
173
|
-
} else {
|
|
174
|
-
promise.catch(err => {
|
|
175
|
-
console.error(`[mutate] async tasks failed`, err);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
const mutate = new Proxy({}, {
|
|
181
|
-
get(_, modelName) {
|
|
182
|
-
return new Proxy({}, {
|
|
183
|
-
get(_2, mutatorName) {
|
|
184
|
-
return (arg, options) => runMutate(modelName, mutatorName, arg, options);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
async function transaction(query2) {
|
|
190
|
-
try {
|
|
191
|
-
if (isInZeroMutation()) {
|
|
192
|
-
const {
|
|
193
|
-
tx
|
|
194
|
-
} = mutatorContext();
|
|
195
|
-
return await query2(tx);
|
|
196
|
-
}
|
|
197
|
-
const output = await zeroDb.transaction(query2, dummyTransactionInput);
|
|
198
|
-
return output;
|
|
199
|
-
} catch (err) {
|
|
200
|
-
if (err?.name !== "PermissionError") {
|
|
201
|
-
console.error(`Error running transaction(): ${err}`);
|
|
202
|
-
}
|
|
203
|
-
throw err;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
function query(cb, authData) {
|
|
207
|
-
const run = () => transaction(async tx => {
|
|
208
|
-
return tx.run(cb(getZQL()));
|
|
209
|
-
});
|
|
210
|
-
if (authData !== void 0) {
|
|
211
|
-
return runWithQueryContext({
|
|
212
|
-
authData
|
|
213
|
-
}, run);
|
|
214
|
-
}
|
|
215
|
-
return run();
|
|
216
|
-
}
|
|
217
|
-
if (queries) {
|
|
218
|
-
setCustomQueries(queries);
|
|
219
|
-
}
|
|
220
|
-
setRunner(queryObj => {
|
|
221
|
-
return transaction(async tx => {
|
|
222
|
-
return tx.run(queryObj);
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
const dummyTransactionInput = {
|
|
226
|
-
clientGroupID: "unused",
|
|
227
|
-
clientID: "unused",
|
|
228
|
-
mutationID: 42,
|
|
229
|
-
upstreamSchema: "unused"
|
|
230
|
-
};
|
|
231
|
-
return {
|
|
232
|
-
handleMutationRequest,
|
|
233
|
-
handleQueryRequest,
|
|
234
|
-
transaction,
|
|
235
|
-
mutate,
|
|
236
|
-
query
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
function alreadyProcessedMutations(response) {
|
|
240
|
-
if (!response || typeof response !== "object") return [];
|
|
241
|
-
const mutations = response.mutations;
|
|
242
|
-
if (!Array.isArray(mutations)) return [];
|
|
243
|
-
return mutations.filter(mutation => {
|
|
244
|
-
if (!mutation || typeof mutation !== "object") return false;
|
|
245
|
-
const id = mutation.id;
|
|
246
|
-
const result = mutation.result;
|
|
247
|
-
return !!id && typeof id === "object" && typeof id.clientID === "string" && typeof id.id === "number" && !!result && typeof result === "object" && result.error === "alreadyProcessed";
|
|
31
|
+
const databaseProvider = zeroNodePg(options.schema, pool);
|
|
32
|
+
return createZeroServerCore({
|
|
33
|
+
...options,
|
|
34
|
+
createDatabase: () => databaseProvider,
|
|
35
|
+
persistAlreadyProcessed: args => persistAlreadyProcessedMutationResults(pool, args)
|
|
248
36
|
});
|
|
249
37
|
}
|
|
250
|
-
async function persistAlreadyProcessedMutationResults(pool,
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
if (typeof body.clientGroupID !== "string") return;
|
|
257
|
-
const table = `${quotePgIdentifier(schema)}."mutations"`;
|
|
38
|
+
async function persistAlreadyProcessedMutationResults(pool, {
|
|
39
|
+
clientGroupID,
|
|
40
|
+
mutations,
|
|
41
|
+
upstreamSchema
|
|
42
|
+
}) {
|
|
43
|
+
const table = `${quotePgIdentifier(upstreamSchema)}."mutations"`;
|
|
258
44
|
const values = mutations.map((_, index) => {
|
|
259
45
|
const offset = index * 4;
|
|
260
46
|
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}::json)`;
|
|
261
47
|
}).join(", ");
|
|
262
|
-
const params = mutations.flatMap(mutation => [
|
|
48
|
+
const params = mutations.flatMap(mutation => [clientGroupID, mutation.id.clientID, mutation.id.id, JSON.stringify(mutation.result)]);
|
|
263
49
|
await pool.query(`INSERT INTO ${table} ("clientGroupID", "clientID", "mutationID", "result")
|
|
264
50
|
VALUES ${values}
|
|
265
51
|
ON CONFLICT ("clientGroupID", "clientID", "mutationID") DO NOTHING`, params);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["zeroNodePg","assertString","Pool","createZeroServerCore","createZeroServer","database","pool","externalPool","options","dbString","pgPool","connectionString","ssl","includes","rejectUnauthorized","on","error","console","message","client","databaseProvider","schema","createDatabase","persistAlreadyProcessed","args","persistAlreadyProcessedMutationResults","clientGroupID","mutations","upstreamSchema","table","quotePgIdentifier","values","map","_","index","offset","join","params","flatMap","mutation","id","clientID","JSON","stringify","result","query","value","replaceAll"],"sources":["../../src/createZeroServer.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,UAAA,QAAkB;AAC3B,SAASC,YAAA,QAAoB;AAC7B,SAASC,IAAA,QAAY;AAErB,SAASC,oBAAA,QAA4B;AAmB9B,SAASC,iBAId;EACAC,QAAA;EACAC,IAAA,EAAMC,YAAA;EACN,GAAGC;AACL,GAW8C;EAC5C,IAAIF,IAAA;EACJ,IAAIC,YAAA,EAAc;IAChBD,IAAA,GAAOC,YAAA;EACT,OAAO;IACL,MAAME,QAAA,GAAWR,YAAA,CAAaI,QAAA,EAAU,6BAA6B;IACrE,MAAMK,MAAA,GAAS,IAAIR,IAAA,CAAK;MACtBS,gBAAA,EAAkBF,QAAA;MAClBG,GAAA,EAAKH,QAAA,CAASI,QAAA,CAAS,iBAAiB,IACpC;QAAEC,kBAAA,EAAoB;MAAM,IAC5B;IACN,CAAC;IACDJ,MAAA,CAAOK,EAAA,CAAG,SAAUC,KAAA,IAAU;MAC5BC,OAAA,CAAQD,KAAA,CAAM,wBAAwBA,KAAA,CAAME,OAAO;IACrD,CAAC;IACDR,MAAA,CAAOK,EAAA,CAAG,WAAYI,MAAA,IAAW;MAC/BA,MAAA,CAAOJ,EAAA,CAAG,SAAUC,KAAA,IAAU;QAC5BC,OAAA,CAAQD,KAAA,CAAM,0BAA0BA,KAAA,CAAME,OAAO;MACvD,CAAC;IACH,CAAC;IACDZ,IAAA,GAAOI,MAAA;EACT;EAEA,MAAMU,gBAAA,GAAmBpB,UAAA,CAAWQ,OAAA,CAAQa,MAAA,EAAQf,IAAI;EAExD,OAAOH,oBAAA,CAAqB;IAC1B,GAAGK,OAAA;IACHc,cAAA,EAAgBA,CAAA,KAAMF,gBAAA;IACtBG,uBAAA,EAA0BC,IAAA,IAASC,sCAAA,CAAuCnB,IAAA,EAAMkB,IAAI;EACtF,CAAC;AACH;AAEA,eAAeC,uCACbnB,IAAA,EACA;EAAEoB,aAAA;EAAeC,SAAA;EAAWC;AAAe,GAC3C;EACA,MAAMC,KAAA,GAAQ,GAAGC,iBAAA,CAAkBF,cAAc,CAAC;EAClD,MAAMG,MAAA,GAASJ,SAAA,CACZK,GAAA,CAAI,CAACC,CAAA,EAAGC,KAAA,KAAU;IACjB,MAAMC,MAAA,GAASD,KAAA,GAAQ;IACvB,OAAO,KAAKC,MAAA,GAAS,CAAC,MAAMA,MAAA,GAAS,CAAC,MAAMA,MAAA,GAAS,CAAC,MAAMA,MAAA,GAAS,CAAC;EACxE,CAAC,EACAC,IAAA,CAAK,IAAI;EACZ,MAAMC,MAAA,GAASV,SAAA,CAAUW,OAAA,CAASC,QAAA,IAAa,CAC7Cb,aAAA,EACAa,QAAA,CAASC,EAAA,CAAGC,QAAA,EACZF,QAAA,CAASC,EAAA,CAAGA,EAAA,EACZE,IAAA,CAAKC,SAAA,CAAUJ,QAAA,CAASK,MAAM,EAC/B;EAED,MAAMtC,IAAA,CAAKuC,KAAA,CACT,eAAehB,KAAK;AAAA,cACVE,MAAM;AAAA,0EAEhBM,MACF;AACF;AAEA,SAASP,kBAAkBgB,KAAA,EAAe;EACxC,OAAO,IAAIA,KAAA,CAAMC,UAAA,CAAW,KAAK,IAAI,CAAC;AACxC","ignoreList":[]}
|
|
@@ -1,284 +1,58 @@
|
|
|
1
|
-
import { mustGetQuery } from "@rocicorp/zero";
|
|
2
|
-
import { PushProcessor } from "@rocicorp/zero/pg";
|
|
3
|
-
import { handleQueryRequest as zeroHandleQueryRequest } from "@rocicorp/zero/server";
|
|
4
1
|
import { zeroNodePg } from "@rocicorp/zero/server/adapters/pg";
|
|
5
2
|
import { assertString } from "@take-out/helpers";
|
|
6
3
|
import { Pool } from "pg";
|
|
7
|
-
import {
|
|
8
|
-
import { createMutators } from "./helpers/createMutators.native.js";
|
|
9
|
-
import { getScopedAuthData, isInZeroMutation, mutatorContext, runWithAuthScope } from "./helpers/mutatorContext.native.js";
|
|
10
|
-
import { runWithQueryContext } from "./helpers/queryContext.native.js";
|
|
11
|
-
import { getMutationsPermissions } from "./modelRegistry.native.js";
|
|
12
|
-
import { setCustomQueries } from "./run.native.js";
|
|
13
|
-
import { getZQL, setEnvironment, setSchema } from "./state.native.js";
|
|
14
|
-
import { setEvaluatingPermission } from "./where.native.js";
|
|
15
|
-
import { setRunner } from "./zeroRunner.native.js";
|
|
16
|
-
function _type_of(obj) {
|
|
17
|
-
"@swc/helpers - typeof";
|
|
18
|
-
|
|
19
|
-
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
20
|
-
}
|
|
4
|
+
import { createZeroServerCore } from "./createZeroServerCore.native.js";
|
|
21
5
|
function createZeroServer(param) {
|
|
22
6
|
var {
|
|
23
|
-
createServerActions,
|
|
24
7
|
database,
|
|
25
8
|
pool: externalPool,
|
|
26
|
-
|
|
27
|
-
models,
|
|
28
|
-
queries,
|
|
29
|
-
mutations: mutationValidators,
|
|
30
|
-
validateQuery,
|
|
31
|
-
validateMutation,
|
|
32
|
-
defaultAllowAdminRole = "all",
|
|
33
|
-
defaultMutateAuthData = {}
|
|
9
|
+
...options
|
|
34
10
|
} = param;
|
|
35
|
-
setSchema(schema);
|
|
36
|
-
setEnvironment("server");
|
|
37
11
|
var pool;
|
|
38
12
|
if (externalPool) {
|
|
39
13
|
pool = externalPool;
|
|
40
14
|
} else {
|
|
41
|
-
var dbString = assertString(database,
|
|
15
|
+
var dbString = assertString(database, 'createZeroServer "database"');
|
|
42
16
|
var pgPool = new Pool({
|
|
43
17
|
connectionString: dbString,
|
|
44
|
-
// handle self-signed certificates in production
|
|
45
18
|
ssl: dbString.includes("sslmode=require") ? {
|
|
46
19
|
rejectUnauthorized: false
|
|
47
20
|
} : void 0
|
|
48
21
|
});
|
|
49
22
|
pgPool.on("error", function (error) {
|
|
50
|
-
console.error(
|
|
23
|
+
console.error("[on-zero] pool error", error.message);
|
|
51
24
|
});
|
|
52
25
|
pgPool.on("connect", function (client) {
|
|
53
26
|
client.on("error", function (error) {
|
|
54
|
-
console.error(
|
|
27
|
+
console.error("[on-zero] client error", error.message);
|
|
55
28
|
});
|
|
56
29
|
});
|
|
57
30
|
pool = pgPool;
|
|
58
31
|
}
|
|
59
|
-
var
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
var {
|
|
68
|
-
authData,
|
|
69
|
-
request,
|
|
70
|
-
skipAsyncTasks
|
|
71
|
-
} = param2;
|
|
72
|
-
var asyncTasks = [];
|
|
73
|
-
var recoveryRequest = request.clone();
|
|
74
|
-
var mutators = createMutators({
|
|
75
|
-
asyncTasks,
|
|
76
|
-
can: permissions.can,
|
|
77
|
-
createServerActions,
|
|
78
|
-
environment: "server",
|
|
79
|
-
models,
|
|
80
|
-
authData,
|
|
81
|
-
validateMutation,
|
|
82
|
-
mutationValidators
|
|
83
|
-
});
|
|
84
|
-
var response = await processor.process(mutators, request);
|
|
85
|
-
await persistAlreadyProcessedMutationResults(pool, recoveryRequest, response);
|
|
86
|
-
if (!skipAsyncTasks && asyncTasks.length) {
|
|
87
|
-
Promise.all(asyncTasks.map(function (task) {
|
|
88
|
-
return runWithAuthScope(authData, task);
|
|
89
|
-
})).catch(function (err) {
|
|
90
|
-
console.error(`[push] async tasks failed`, err);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
return {
|
|
94
|
-
response,
|
|
95
|
-
asyncTasks
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
var handleQueryRequest = async function (param2) {
|
|
99
|
-
var {
|
|
100
|
-
authData,
|
|
101
|
-
request
|
|
102
|
-
} = param2;
|
|
103
|
-
if (!queries) {
|
|
104
|
-
throw new Error("No queries registered with createZeroServer. Pass the syncedQueries registry to createZeroServer via the queries option.");
|
|
105
|
-
}
|
|
106
|
-
var handler = function (name, args) {
|
|
107
|
-
if (name.startsWith("permission.")) {
|
|
108
|
-
var table = name.slice("permission.".length);
|
|
109
|
-
var {
|
|
110
|
-
objOrId
|
|
111
|
-
} = args;
|
|
112
|
-
var perm = getMutationsPermissions(table);
|
|
113
|
-
if (!perm) {
|
|
114
|
-
throw new Error(`[permission] no permission defined for table: ${table}`);
|
|
115
|
-
}
|
|
116
|
-
setEvaluatingPermission(true);
|
|
117
|
-
try {
|
|
118
|
-
return getZQL()[table].where(function (eb) {
|
|
119
|
-
return permissions.buildPermissionQuery(authData, eb, perm, objOrId, table);
|
|
120
|
-
}).one();
|
|
121
|
-
} finally {
|
|
122
|
-
setEvaluatingPermission(false);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (validateQuery) {
|
|
126
|
-
validateQuery({
|
|
127
|
-
authData,
|
|
128
|
-
queryName: name,
|
|
129
|
-
params: args
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
var _$query = mustGetQuery(queries, name);
|
|
133
|
-
return _$query.fn({
|
|
134
|
-
args,
|
|
135
|
-
ctx: authData
|
|
136
|
-
});
|
|
137
|
-
};
|
|
138
|
-
var userID = typeof (authData === null || authData === void 0 ? void 0 : authData.id) === "string" ? authData.id : void 0;
|
|
139
|
-
var response = await runWithQueryContext({
|
|
140
|
-
authData: authData || {}
|
|
141
|
-
}, function () {
|
|
142
|
-
return userID === void 0 ? zeroHandleQueryRequest(handler, schema, request) : zeroHandleQueryRequest({
|
|
143
|
-
handler,
|
|
144
|
-
schema,
|
|
145
|
-
request,
|
|
146
|
-
userID
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
return {
|
|
150
|
-
response
|
|
151
|
-
};
|
|
152
|
-
};
|
|
153
|
-
async function runMutate(modelName, mutatorName, mutatorArg, options) {
|
|
154
|
-
var authData = options === null || options === void 0 ? void 0 : options.authData;
|
|
155
|
-
if (!authData) {
|
|
156
|
-
var scoped = getScopedAuthData();
|
|
157
|
-
if (scoped) {
|
|
158
|
-
authData = scoped;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
var asyncTasks = [];
|
|
162
|
-
var mutators = createMutators({
|
|
163
|
-
models,
|
|
164
|
-
environment: "server",
|
|
165
|
-
asyncTasks,
|
|
166
|
-
authData: {
|
|
167
|
-
...defaultMutateAuthData,
|
|
168
|
-
...authData
|
|
169
|
-
},
|
|
170
|
-
createServerActions,
|
|
171
|
-
can: permissions.can,
|
|
172
|
-
validateMutation,
|
|
173
|
-
mutationValidators
|
|
174
|
-
});
|
|
175
|
-
var modelMutators = mutators[modelName];
|
|
176
|
-
var mutator = modelMutators[mutatorName];
|
|
177
|
-
await transaction(async function (tx) {
|
|
178
|
-
await mutator(tx, mutatorArg);
|
|
179
|
-
});
|
|
180
|
-
if (asyncTasks.length) {
|
|
181
|
-
var resolvedAuth = authData !== null && authData !== void 0 ? authData : null;
|
|
182
|
-
var promise = Promise.all(asyncTasks.map(function (t) {
|
|
183
|
-
return runWithAuthScope(resolvedAuth, t);
|
|
184
|
-
}));
|
|
185
|
-
if (options === null || options === void 0 ? void 0 : options.awaitEffects) {
|
|
186
|
-
await promise;
|
|
187
|
-
} else {
|
|
188
|
-
promise.catch(function (err) {
|
|
189
|
-
console.error(`[mutate] async tasks failed`, err);
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
var mutate = new Proxy({}, {
|
|
195
|
-
get(_, modelName) {
|
|
196
|
-
return new Proxy({}, {
|
|
197
|
-
get(_2, mutatorName) {
|
|
198
|
-
return function (arg, options) {
|
|
199
|
-
return runMutate(modelName, mutatorName, arg, options);
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
});
|
|
32
|
+
var databaseProvider = zeroNodePg(options.schema, pool);
|
|
33
|
+
return createZeroServerCore({
|
|
34
|
+
...options,
|
|
35
|
+
createDatabase: function () {
|
|
36
|
+
return databaseProvider;
|
|
37
|
+
},
|
|
38
|
+
persistAlreadyProcessed: function (args) {
|
|
39
|
+
return persistAlreadyProcessedMutationResults(pool, args);
|
|
203
40
|
}
|
|
204
41
|
});
|
|
205
|
-
async function transaction(query2) {
|
|
206
|
-
try {
|
|
207
|
-
if (isInZeroMutation()) {
|
|
208
|
-
var {
|
|
209
|
-
tx
|
|
210
|
-
} = mutatorContext();
|
|
211
|
-
return await query2(tx);
|
|
212
|
-
}
|
|
213
|
-
var output = await zeroDb.transaction(query2, dummyTransactionInput);
|
|
214
|
-
return output;
|
|
215
|
-
} catch (err) {
|
|
216
|
-
if ((err === null || err === void 0 ? void 0 : err.name) !== "PermissionError") {
|
|
217
|
-
console.error(`Error running transaction(): ${err}`);
|
|
218
|
-
}
|
|
219
|
-
throw err;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
function query(cb, authData) {
|
|
223
|
-
var run = function () {
|
|
224
|
-
return transaction(async function (tx) {
|
|
225
|
-
return tx.run(cb(getZQL()));
|
|
226
|
-
});
|
|
227
|
-
};
|
|
228
|
-
if (authData !== void 0) {
|
|
229
|
-
return runWithQueryContext({
|
|
230
|
-
authData
|
|
231
|
-
}, run);
|
|
232
|
-
}
|
|
233
|
-
return run();
|
|
234
|
-
}
|
|
235
|
-
if (queries) {
|
|
236
|
-
setCustomQueries(queries);
|
|
237
|
-
}
|
|
238
|
-
setRunner(function (queryObj) {
|
|
239
|
-
return transaction(async function (tx) {
|
|
240
|
-
return tx.run(queryObj);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
var dummyTransactionInput = {
|
|
244
|
-
clientGroupID: "unused",
|
|
245
|
-
clientID: "unused",
|
|
246
|
-
mutationID: 42,
|
|
247
|
-
upstreamSchema: "unused"
|
|
248
|
-
};
|
|
249
|
-
return {
|
|
250
|
-
handleMutationRequest,
|
|
251
|
-
handleQueryRequest,
|
|
252
|
-
transaction,
|
|
253
|
-
mutate,
|
|
254
|
-
query
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
function alreadyProcessedMutations(response) {
|
|
258
|
-
if (!response || (typeof response === "undefined" ? "undefined" : _type_of(response)) !== "object") return [];
|
|
259
|
-
var mutations = response.mutations;
|
|
260
|
-
if (!Array.isArray(mutations)) return [];
|
|
261
|
-
return mutations.filter(function (mutation) {
|
|
262
|
-
if (!mutation || (typeof mutation === "undefined" ? "undefined" : _type_of(mutation)) !== "object") return false;
|
|
263
|
-
var id = mutation.id;
|
|
264
|
-
var result = mutation.result;
|
|
265
|
-
return !!id && (typeof id === "undefined" ? "undefined" : _type_of(id)) === "object" && typeof id.clientID === "string" && typeof id.id === "number" && !!result && (typeof result === "undefined" ? "undefined" : _type_of(result)) === "object" && result.error === "alreadyProcessed";
|
|
266
|
-
});
|
|
267
42
|
}
|
|
268
|
-
async function persistAlreadyProcessedMutationResults(pool,
|
|
269
|
-
var
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
var table = `${quotePgIdentifier(schema)}."mutations"`;
|
|
43
|
+
async function persistAlreadyProcessedMutationResults(pool, param) {
|
|
44
|
+
var {
|
|
45
|
+
clientGroupID,
|
|
46
|
+
mutations,
|
|
47
|
+
upstreamSchema
|
|
48
|
+
} = param;
|
|
49
|
+
var table = `${quotePgIdentifier(upstreamSchema)}."mutations"`;
|
|
276
50
|
var values = mutations.map(function (_, index) {
|
|
277
51
|
var offset = index * 4;
|
|
278
52
|
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}::json)`;
|
|
279
53
|
}).join(", ");
|
|
280
54
|
var params = mutations.flatMap(function (mutation) {
|
|
281
|
-
return [
|
|
55
|
+
return [clientGroupID, mutation.id.clientID, mutation.id.id, JSON.stringify(mutation.result)];
|
|
282
56
|
});
|
|
283
57
|
await pool.query(`INSERT INTO ${table} ("clientGroupID", "clientID", "mutationID", "result")
|
|
284
58
|
VALUES ${values}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["zeroNodePg","assertString","Pool","createZeroServerCore","createZeroServer","param","database","pool","externalPool","options","dbString","pgPool","connectionString","ssl","includes","rejectUnauthorized","on","error","console","message","client","databaseProvider","schema","createDatabase","persistAlreadyProcessed","args","persistAlreadyProcessedMutationResults","clientGroupID","mutations","upstreamSchema","table","quotePgIdentifier","values","map","_","index","offset","join","params","flatMap","mutation","id","clientID","JSON","stringify","result","query"],"sources":["../../src/createZeroServer.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,UAAA,QAAkB;AAC3B,SAASC,YAAA,QAAoB;AAC7B,SAASC,IAAA,QAAY;AAErB,SAASC,oBAAA,QAA4B;AAmB9B,SAASC,iBAIdC,KAAA;EACA;IAAAC,QAAA;IAAAC,IAAA,EAAAC,YAAA;IAAA,GAAAC;EAAA,IAAAJ,KAAA;EACA,IAAAE,IAAM;EACN,IAAGC,YAAA;IAYyCD,IAAA,GAAAC,YAAA;EAC5C,OAAI;IACJ,IAAIE,QAAA,GAAAT,YAAc,CAAAK,QAAA;IAChB,IAAAK,MAAO,OAAAT,IAAA;MACTU,gBAAO,EAAAF,QAAA;MACLG,GAAA,EAAMH,QAAA,CAAAI,QAAW,kBAAuB;QACxCC,kBAAmB,EAAK;MACtB;IAAkB,EAClB;IAGFJ,MAAC,CAAAK,EAAA,oBAAAC,KAAA;MACDC,OAAO,CAAGD,KAAA,uBAAoB,EAAAA,KAAA,CAAAE,OAAA;IAC5B;IACFR,MAAC,CAAAK,EAAA,sBAAAI,MAAA;MACDA,MAAO,CAAAJ,EAAG,UAAW,UAACC,KAAW;QAC/BC,OAAO,CAAGD,KAAA,yBAAoB,EAAAA,KAAA,CAAAE,OAAA;MAC5B;IAAqD,EACvD;IACFZ,IAAC,GAAAI,MAAA;EACD;EACF,IAAAU,gBAAA,GAAArB,UAAA,CAAAS,OAAA,CAAAa,MAAA,EAAAf,IAAA;EAEA,OAAMJ,oBAAmB;IAEzB,GAAAM,OAAO;IACLc,cAAG,WAAAA,CAAA;MACH,OAAAF,gBAAsB;IACtB;IACDG,uBAAA,WAAAA,CAAAC,IAAA;MACH,OAAAC,sCAAA,CAAAnB,IAAA,EAAAkB,IAAA;IAEA;EAIE;AACA;AAEI,eAAMC,sCAAiBA,CAAAnB,IAAA,EAAAF,KAAA;EACvB;IAAAsB,aAAY;IAAAC,SAAgB;IAAAC;EAAgB,IAAAxB,KAAU;EACxD,IACCyB,KAAK,GAAI,GAAAC,iBAAA,CAAAF,cAAA;EACZ,IAAAG,MAAM,GAAAJ,SAAS,CAAAK,GAAU,WAASC,CAAA,EAAAC,KAAA;IAChC,IAAAC,MAAA,GAAAD,KAAA;IACA,YAAYC,MAAA,UAAAA,MAAA,UAAAA,MAAA,UAAAA,MAAA;EAAA,EACZ,CAAAC,IAAA,KAAS;EAAG,IACZC,MAAK,GAAAV,SAAU,CAAAW,OAAS,WAAMC,QAAA;IAC/B,QAEDb,aAAW,EACTa,QAAA,CAAAC,EAAA,CAAAC,QAAoB,EAAAF,QACV,CAAAC,EAAA,CAAAA,EAAM,EAAAE,IAAA,CAAAC,SAAA,CAAAJ,QAAA,CAAAK,MAAA,EAEhB;EACF;EACF,MAAAtC,IAAA,CAAAuC,KAAA,gBAAAhB,KAAA;AAEA,cAASE,MAAA;AACP,wEAAsC,EAAAM,MAAA;AACxC","ignoreList":[]}
|