prostgles-types 4.0.307 → 4.0.309
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/auth.d.ts +19 -58
- package/dist/auth.d.ts.map +1 -1
- package/dist/authContract.d.ts +293 -0
- package/dist/authContract.d.ts.map +1 -0
- package/dist/authContract.js +70 -0
- package/dist/authContract.js.map +1 -0
- package/dist/authResponseSchemas.d.ts +176 -0
- package/dist/authResponseSchemas.d.ts.map +1 -0
- package/dist/authResponseSchemas.js +114 -0
- package/dist/authResponseSchemas.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/index_umd.js +1 -1
- package/dist/replication.d.ts +4 -5
- package/dist/replication.d.ts.map +1 -1
- package/dist/replication.js +10 -2
- package/dist/replication.js.map +1 -1
- package/dist/requestResponse.d.ts +9 -0
- package/dist/requestResponse.d.ts.map +1 -0
- package/dist/requestResponse.js +3 -0
- package/dist/requestResponse.js.map +1 -0
- package/lib/auth.ts +35 -84
- package/lib/authContract.ts +92 -0
- package/lib/authResponseSchemas.ts +113 -0
- package/lib/index.ts +5 -1
- package/lib/replication.ts +64 -32
- package/lib/requestResponse.ts +15 -0
- package/package.json +1 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { authResponseSchemas } from "./authResponseSchemas";
|
|
2
|
+
import type { JSONB } from "./JSONBSchemaValidation/JSONBSchema";
|
|
3
|
+
import type {
|
|
4
|
+
RequestResponseCall,
|
|
5
|
+
RequestResponseHandler,
|
|
6
|
+
RequestResponseSchema,
|
|
7
|
+
} from "./requestResponse";
|
|
8
|
+
|
|
9
|
+
const credentials = {
|
|
10
|
+
username: "string",
|
|
11
|
+
password: { type: "string", optional: true },
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
export const authContract = {
|
|
15
|
+
login: {
|
|
16
|
+
request: {
|
|
17
|
+
type: {
|
|
18
|
+
...credentials,
|
|
19
|
+
remember_me: { type: "boolean", optional: true },
|
|
20
|
+
totp_token: { type: "string", optional: true },
|
|
21
|
+
totp_recovery_code: { type: "string", optional: true },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
response: {
|
|
25
|
+
oneOf: [
|
|
26
|
+
authResponseSchemas.authSuccess,
|
|
27
|
+
authResponseSchemas.passwordLoginFailure,
|
|
28
|
+
authResponseSchemas.magicLinkAuthSuccess,
|
|
29
|
+
authResponseSchemas.magicLinkAuthFailure,
|
|
30
|
+
authResponseSchemas.oauthRegisterFailure,
|
|
31
|
+
authResponseSchemas.codeVerificationFailure,
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
register: {
|
|
36
|
+
request: { type: credentials },
|
|
37
|
+
response: {
|
|
38
|
+
oneOf: [
|
|
39
|
+
authResponseSchemas.passwordRegisterSuccess,
|
|
40
|
+
authResponseSchemas.passwordRegisterFailure,
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
magicLinkOrOTP: {
|
|
45
|
+
request: {
|
|
46
|
+
oneOfType: [
|
|
47
|
+
{ id: "string", returnToken: { type: "boolean", optional: true } },
|
|
48
|
+
{
|
|
49
|
+
email: "string",
|
|
50
|
+
code: "string",
|
|
51
|
+
returnToken: { type: "boolean", optional: true },
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
response: {
|
|
56
|
+
oneOf: [
|
|
57
|
+
authResponseSchemas.authSuccess,
|
|
58
|
+
authResponseSchemas.emailConfirmationSuccess,
|
|
59
|
+
authResponseSchemas.magicLinkAuthFailure,
|
|
60
|
+
authResponseSchemas.codeVerificationFailure,
|
|
61
|
+
authResponseSchemas.invalidEmail,
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
logout: {
|
|
66
|
+
request: { type: {} },
|
|
67
|
+
response: {
|
|
68
|
+
oneOf: [
|
|
69
|
+
authResponseSchemas.authSuccess,
|
|
70
|
+
authResponseSchemas.commonFailure,
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
} as const satisfies Record<string, RequestResponseSchema>;
|
|
75
|
+
|
|
76
|
+
export type AuthOperation = keyof typeof authContract;
|
|
77
|
+
export type AuthInput<Operation extends AuthOperation> = JSONB.GetType<
|
|
78
|
+
(typeof authContract)[Operation]["request"]
|
|
79
|
+
>;
|
|
80
|
+
export type AuthOutput<Operation extends AuthOperation> = JSONB.GetType<
|
|
81
|
+
(typeof authContract)[Operation]["response"]
|
|
82
|
+
>;
|
|
83
|
+
export type AuthCalls = {
|
|
84
|
+
[Operation in AuthOperation]: RequestResponseCall<
|
|
85
|
+
(typeof authContract)[Operation]
|
|
86
|
+
>;
|
|
87
|
+
};
|
|
88
|
+
export type AuthHandlers = {
|
|
89
|
+
[Operation in AuthOperation]: RequestResponseHandler<
|
|
90
|
+
(typeof authContract)[Operation]
|
|
91
|
+
>;
|
|
92
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { JSONB } from "./JSONBSchemaValidation/JSONBSchema";
|
|
2
|
+
|
|
3
|
+
const message = { type: "string", optional: true } as const;
|
|
4
|
+
const success = { success: { enum: [true] }, message } as const;
|
|
5
|
+
const failure = { success: { enum: [false] }, message } as const;
|
|
6
|
+
const commonFailureCodes = [
|
|
7
|
+
"server-error",
|
|
8
|
+
"rate-limit-exceeded",
|
|
9
|
+
"something-went-wrong",
|
|
10
|
+
] as const;
|
|
11
|
+
const authFailureCodes = [
|
|
12
|
+
...commonFailureCodes,
|
|
13
|
+
"no-match",
|
|
14
|
+
"inactive-account",
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
export const authResponseSchemas = {
|
|
18
|
+
authSuccess: {
|
|
19
|
+
type: {
|
|
20
|
+
...success,
|
|
21
|
+
code: { enum: [undefined], optional: true },
|
|
22
|
+
token: { type: "string", optional: true },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
commonFailure: { type: { ...failure, code: { enum: commonFailureCodes } } },
|
|
26
|
+
authFailure: { type: { ...failure, code: { enum: authFailureCodes } } },
|
|
27
|
+
magicLinkAuthSuccess: {
|
|
28
|
+
type: {
|
|
29
|
+
...success,
|
|
30
|
+
code: { enum: ["email-verification-code-sent", "magic-link-sent"] },
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
magicLinkAuthFailure: {
|
|
34
|
+
type: {
|
|
35
|
+
...failure,
|
|
36
|
+
code: {
|
|
37
|
+
enum: [
|
|
38
|
+
...authFailureCodes,
|
|
39
|
+
"expired-magic-link",
|
|
40
|
+
"invalid-magic-link",
|
|
41
|
+
"used-magic-link",
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
oauthRegisterFailure: {
|
|
47
|
+
type: {
|
|
48
|
+
...failure,
|
|
49
|
+
code: { enum: [...commonFailureCodes, "provider-issue"] },
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
passwordLoginFailure: {
|
|
53
|
+
type: {
|
|
54
|
+
...failure,
|
|
55
|
+
code: {
|
|
56
|
+
enum: [
|
|
57
|
+
...authFailureCodes,
|
|
58
|
+
"totp-token-missing",
|
|
59
|
+
"invalid-username",
|
|
60
|
+
"username-missing",
|
|
61
|
+
"invalid-email",
|
|
62
|
+
"password-missing",
|
|
63
|
+
"invalid-password",
|
|
64
|
+
"is-from-OAuth",
|
|
65
|
+
"is-from-magic-link",
|
|
66
|
+
"invalid-totp-recovery-code",
|
|
67
|
+
"invalid-totp-code",
|
|
68
|
+
"email-not-confirmed",
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
passwordRegisterFailure: {
|
|
74
|
+
type: {
|
|
75
|
+
...failure,
|
|
76
|
+
code: {
|
|
77
|
+
enum: [
|
|
78
|
+
...commonFailureCodes,
|
|
79
|
+
"weak-password",
|
|
80
|
+
"user-already-registered",
|
|
81
|
+
"username-missing",
|
|
82
|
+
"password-missing",
|
|
83
|
+
"invalid-email-confirmation-code",
|
|
84
|
+
"expired-email-confirmation-code",
|
|
85
|
+
"inactive-account",
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
passwordRegisterSuccess: {
|
|
91
|
+
type: {
|
|
92
|
+
...success,
|
|
93
|
+
code: {
|
|
94
|
+
enum: [
|
|
95
|
+
"email-verification-code-sent",
|
|
96
|
+
"already-registered-but-did-not-confirm-email",
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
codeVerificationFailure: {
|
|
102
|
+
type: {
|
|
103
|
+
...failure,
|
|
104
|
+
code: {
|
|
105
|
+
enum: [...authFailureCodes, "invalid-otp-code", "expired-otp-code"],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
emailConfirmationSuccess: {
|
|
110
|
+
type: { ...success, code: { enum: ["email-verified"] } },
|
|
111
|
+
},
|
|
112
|
+
invalidEmail: { type: { ...failure, code: { enum: ["invalid-email"] } } },
|
|
113
|
+
} as const satisfies Record<string, JSONB.FieldTypeObj>;
|
package/lib/index.ts
CHANGED
|
@@ -440,7 +440,9 @@ export const getAllowedTableMethods = ({
|
|
|
440
440
|
if (!publishInfo.select) return false;
|
|
441
441
|
const disabledMethod = cmd === "subscribeOne" ? "subscribe" : cmd;
|
|
442
442
|
return (
|
|
443
|
-
!Object.keys(publishInfo.select.disabledMethods ?? {}).includes(
|
|
443
|
+
!Object.keys(publishInfo.select.disabledMethods ?? {}).includes(
|
|
444
|
+
disabledMethod,
|
|
445
|
+
) &&
|
|
444
446
|
(cmd !== "sync" || publishInfo.select.syncConfig !== undefined)
|
|
445
447
|
);
|
|
446
448
|
}),
|
|
@@ -1727,6 +1729,8 @@ export const getPossibleNestedInsert = (
|
|
|
1727
1729
|
};
|
|
1728
1730
|
|
|
1729
1731
|
export * from "./auth";
|
|
1732
|
+
export * from "./authContract";
|
|
1733
|
+
export * from "./requestResponse";
|
|
1730
1734
|
export { CONTENT_TYPE_TO_EXT } from "./files";
|
|
1731
1735
|
export type {
|
|
1732
1736
|
ALLOWED_CONTENT_TYPE,
|
package/lib/replication.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { AnyObject, type EqualityFilter } from "./filters";
|
|
2
|
+
import type {
|
|
3
|
+
RequestResponseCall,
|
|
4
|
+
RequestResponseHandler,
|
|
5
|
+
RequestResponseSchema,
|
|
6
|
+
} from "./requestResponse";
|
|
2
7
|
import {
|
|
3
8
|
CHANNEL_PREFIX,
|
|
4
9
|
createPromiseWithTimeout,
|
|
@@ -106,13 +111,17 @@ export type ClientSyncHandles = {
|
|
|
106
111
|
* Used by client to notify server that data has changed (and send express data if necessary)
|
|
107
112
|
* Also used by server to request client ClientSyncInfo
|
|
108
113
|
*/
|
|
109
|
-
onSyncRequest: (
|
|
114
|
+
onSyncRequest: (
|
|
115
|
+
params: SyncBatchParams,
|
|
116
|
+
) => MaybePromise<ClientSyncInfo | ClientExpressData>;
|
|
110
117
|
|
|
111
118
|
/**
|
|
112
119
|
* Used to respond to server with the requested data
|
|
113
120
|
* @description: server will send { onPullRequest: { from_synced, limit, ...etc } }
|
|
114
121
|
*/
|
|
115
|
-
onPullRequest: (
|
|
122
|
+
onPullRequest: (
|
|
123
|
+
params: SyncBatchParams,
|
|
124
|
+
) => MaybePromise<ClientSyncPullResponse>;
|
|
116
125
|
|
|
117
126
|
/**
|
|
118
127
|
* Used to set the data sent by server.
|
|
@@ -146,11 +155,9 @@ export const getSyncChannelName = ({
|
|
|
146
155
|
|
|
147
156
|
export type SocketCallback = (err?: unknown, res?: unknown) => void;
|
|
148
157
|
|
|
149
|
-
type RequestBase = {
|
|
158
|
+
type RequestBase = RequestResponseSchema & {
|
|
150
159
|
name: string;
|
|
151
160
|
source: "client" | "server";
|
|
152
|
-
request: Omit<JSONB.FieldTypeObj, "optional">;
|
|
153
|
-
response: Omit<JSONB.FieldTypeObj, "optional">;
|
|
154
161
|
};
|
|
155
162
|
export namespace ReplicationProtocol {
|
|
156
163
|
const TIMEOUT = 10_000;
|
|
@@ -181,7 +188,9 @@ export namespace ReplicationProtocol {
|
|
|
181
188
|
} as const satisfies RequestBase;
|
|
182
189
|
|
|
183
190
|
export type CreateSchemaRequest = JSONB.GetType<typeof CreateSchema.request>;
|
|
184
|
-
export type CreateSchemaResponse = JSONB.GetType<
|
|
191
|
+
export type CreateSchemaResponse = JSONB.GetType<
|
|
192
|
+
typeof CreateSchema.response
|
|
193
|
+
>;
|
|
185
194
|
|
|
186
195
|
const ClientSyncInfoSchema = {
|
|
187
196
|
state: { enum: ["syncing"] },
|
|
@@ -235,7 +244,10 @@ export namespace ReplicationProtocol {
|
|
|
235
244
|
oneOfType: [ClientSyncInfoSchema, ClientExpressDataSchema],
|
|
236
245
|
},
|
|
237
246
|
response: {
|
|
238
|
-
oneOfType: [
|
|
247
|
+
oneOfType: [
|
|
248
|
+
{ success: { enum: [true] } },
|
|
249
|
+
{ success: { enum: [false] }, err: "unknown" },
|
|
250
|
+
],
|
|
239
251
|
},
|
|
240
252
|
} as const satisfies RequestBase;
|
|
241
253
|
|
|
@@ -295,20 +307,27 @@ export namespace ReplicationProtocol {
|
|
|
295
307
|
},
|
|
296
308
|
} as const satisfies RequestBase;
|
|
297
309
|
|
|
298
|
-
const Schemas = {
|
|
310
|
+
const Schemas = {
|
|
311
|
+
ClientSyncRequest,
|
|
312
|
+
ServerSyncRequest,
|
|
313
|
+
PullRequest,
|
|
314
|
+
UpdateRequest,
|
|
315
|
+
} as const;
|
|
299
316
|
type SchemasType = typeof Schemas;
|
|
300
317
|
const SchemasList = Object.values(Schemas);
|
|
301
318
|
|
|
302
319
|
export type IncomingHandlers<Side extends RequestBase["source"]> = {
|
|
303
|
-
[
|
|
304
|
-
|
|
305
|
-
|
|
320
|
+
[
|
|
321
|
+
K in keyof SchemasType as SchemasType[K]["source"] extends Side ? never
|
|
322
|
+
: K
|
|
323
|
+
]: RequestResponseHandler<SchemasType[K]>;
|
|
306
324
|
};
|
|
307
325
|
|
|
308
326
|
export type OutgoingHandlers<Side extends RequestBase["source"]> = {
|
|
309
|
-
[
|
|
310
|
-
|
|
311
|
-
|
|
327
|
+
[
|
|
328
|
+
K in keyof SchemasType as SchemasType[K]["source"] extends Side ? K
|
|
329
|
+
: never
|
|
330
|
+
]: RequestResponseCall<SchemasType[K]>;
|
|
312
331
|
};
|
|
313
332
|
|
|
314
333
|
const getHandlers = <Side extends RequestBase["source"]>(
|
|
@@ -336,7 +355,9 @@ export namespace ReplicationProtocol {
|
|
|
336
355
|
return;
|
|
337
356
|
}
|
|
338
357
|
|
|
339
|
-
const schema = SchemasList.find(
|
|
358
|
+
const schema = SchemasList.find(
|
|
359
|
+
(s) => s.name === type && s.source !== side,
|
|
360
|
+
);
|
|
340
361
|
if (!schema) {
|
|
341
362
|
cb("Invalid data.type");
|
|
342
363
|
return;
|
|
@@ -349,9 +370,16 @@ export namespace ReplicationProtocol {
|
|
|
349
370
|
|
|
350
371
|
/** Must validate incoming data */
|
|
351
372
|
if (side === "server") {
|
|
352
|
-
const validationResult = getJSONBSchemaValidationError(
|
|
373
|
+
const validationResult = getJSONBSchemaValidationError(
|
|
374
|
+
schema.request,
|
|
375
|
+
request,
|
|
376
|
+
);
|
|
353
377
|
if (validationResult.error !== undefined) {
|
|
354
|
-
console.error(
|
|
378
|
+
console.error(
|
|
379
|
+
"Invalid request from client",
|
|
380
|
+
validationResult.error,
|
|
381
|
+
request,
|
|
382
|
+
);
|
|
355
383
|
cb(validationResult.error);
|
|
356
384
|
return;
|
|
357
385
|
}
|
|
@@ -378,24 +406,28 @@ export namespace ReplicationProtocol {
|
|
|
378
406
|
key,
|
|
379
407
|
(request: unknown) => {
|
|
380
408
|
return createPromiseWithTimeout((resolve, reject) => {
|
|
381
|
-
socket.emit(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
console.error(
|
|
389
|
-
"Invalid response from client for " + schema.name,
|
|
390
|
-
validationResult.error,
|
|
409
|
+
socket.emit(
|
|
410
|
+
channelName,
|
|
411
|
+
{ type: schema.name, request },
|
|
412
|
+
(response: unknown) => {
|
|
413
|
+
if (side === "server") {
|
|
414
|
+
const validationResult = getJSONBSchemaValidationError(
|
|
415
|
+
schema.response,
|
|
391
416
|
response,
|
|
392
417
|
);
|
|
393
|
-
|
|
394
|
-
|
|
418
|
+
if (validationResult.error !== undefined) {
|
|
419
|
+
console.error(
|
|
420
|
+
"Invalid response from client for " + schema.name,
|
|
421
|
+
validationResult.error,
|
|
422
|
+
response,
|
|
423
|
+
);
|
|
424
|
+
reject(validationResult.error);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
395
427
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
428
|
+
resolve(response);
|
|
429
|
+
},
|
|
430
|
+
);
|
|
399
431
|
}, TIMEOUT);
|
|
400
432
|
},
|
|
401
433
|
] as const;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JSONB } from "./JSONBSchemaValidation/JSONBSchema";
|
|
2
|
+
import type { MaybePromise } from "./index";
|
|
3
|
+
|
|
4
|
+
export type RequestResponseSchema = {
|
|
5
|
+
request: Omit<JSONB.FieldTypeObj, "optional">;
|
|
6
|
+
response: Omit<JSONB.FieldTypeObj, "optional">;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type RequestResponseHandler<Schema extends RequestResponseSchema> = (
|
|
10
|
+
data: JSONB.GetType<Schema["request"]>,
|
|
11
|
+
) => MaybePromise<JSONB.GetType<Schema["response"]>>;
|
|
12
|
+
|
|
13
|
+
export type RequestResponseCall<Schema extends RequestResponseSchema> = (
|
|
14
|
+
data: JSONB.GetType<Schema["request"]>,
|
|
15
|
+
) => Promise<JSONB.GetType<Schema["response"]>>;
|