@atproto/bsync 0.0.25 → 0.0.26
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/CHANGELOG.md +16 -0
- package/bin/migration-create.ts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -12
- package/dist/client.js.map +1 -1
- package/dist/config.js +16 -24
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +7 -7
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +8 -36
- package/dist/context.js.map +1 -1
- package/dist/db/index.d.ts +7 -5
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +26 -101
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations/20240108T220751294Z-init.js +4 -8
- package/dist/db/migrations/20240108T220751294Z-init.js.map +1 -1
- package/dist/db/migrations/20240717T224303472Z-notif-ops.js +4 -8
- package/dist/db/migrations/20240717T224303472Z-notif-ops.js.map +1 -1
- package/dist/db/migrations/20250527T022203400Z-add-operation.js +5 -9
- package/dist/db/migrations/20250527T022203400Z-add-operation.js.map +1 -1
- package/dist/db/migrations/20250603T163446567Z-alter-operation.js +2 -6
- package/dist/db/migrations/20250603T163446567Z-alter-operation.js.map +1 -1
- package/dist/db/migrations/index.d.ts +4 -4
- package/dist/db/migrations/index.d.ts.map +1 -1
- package/dist/db/migrations/index.js +4 -40
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/migrations/provider.js +2 -11
- package/dist/db/migrations/provider.js.map +1 -1
- package/dist/db/schema/index.d.ts +5 -5
- package/dist/db/schema/index.d.ts.map +1 -1
- package/dist/db/schema/index.js +1 -2
- package/dist/db/schema/index.js.map +1 -1
- package/dist/db/schema/mute_item.js +1 -4
- package/dist/db/schema/mute_item.js.map +1 -1
- package/dist/db/schema/mute_op.d.ts +1 -1
- package/dist/db/schema/mute_op.d.ts.map +1 -1
- package/dist/db/schema/mute_op.js +2 -5
- package/dist/db/schema/mute_op.js.map +1 -1
- package/dist/db/schema/notif_item.js +1 -4
- package/dist/db/schema/notif_item.js.map +1 -1
- package/dist/db/schema/notif_op.js +2 -5
- package/dist/db/schema/notif_op.js.map +1 -1
- package/dist/db/schema/operation.d.ts +2 -2
- package/dist/db/schema/operation.d.ts.map +1 -1
- package/dist/db/schema/operation.js +2 -5
- package/dist/db/schema/operation.js.map +1 -1
- package/dist/db/types.d.ts +3 -1
- package/dist/db/types.d.ts.map +1 -1
- package/dist/db/types.js +1 -2
- package/dist/db/types.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -88
- package/dist/index.js.map +1 -1
- package/dist/logger.js +8 -11
- package/dist/logger.js.map +1 -1
- package/dist/proto/bsync_connect.d.ts +1 -1
- package/dist/proto/bsync_connect.d.ts.map +1 -1
- package/dist/proto/bsync_connect.js +27 -30
- package/dist/proto/bsync_connect.js.map +1 -1
- package/dist/proto/bsync_pb.js +215 -747
- package/dist/proto/bsync_pb.js.map +1 -1
- package/dist/routes/add-mute-operation.d.ts +2 -2
- package/dist/routes/add-mute-operation.d.ts.map +1 -1
- package/dist/routes/add-mute-operation.js +28 -30
- package/dist/routes/add-mute-operation.js.map +1 -1
- package/dist/routes/add-notif-operation.d.ts +2 -2
- package/dist/routes/add-notif-operation.d.ts.map +1 -1
- package/dist/routes/add-notif-operation.js +14 -16
- package/dist/routes/add-notif-operation.js.map +1 -1
- package/dist/routes/auth.d.ts +1 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +4 -8
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/delete-operations.d.ts +2 -2
- package/dist/routes/delete-operations.d.ts.map +1 -1
- package/dist/routes/delete-operations.js +11 -13
- package/dist/routes/delete-operations.js.map +1 -1
- package/dist/routes/index.d.ts +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +19 -24
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/put-operation.d.ts +2 -2
- package/dist/routes/put-operation.d.ts.map +1 -1
- package/dist/routes/put-operation.js +25 -27
- package/dist/routes/put-operation.js.map +1 -1
- package/dist/routes/scan-mute-operations.d.ts +2 -2
- package/dist/routes/scan-mute-operations.d.ts.map +1 -1
- package/dist/routes/scan-mute-operations.js +13 -15
- package/dist/routes/scan-mute-operations.js.map +1 -1
- package/dist/routes/scan-notif-operations.d.ts +2 -2
- package/dist/routes/scan-notif-operations.d.ts.map +1 -1
- package/dist/routes/scan-notif-operations.js +13 -15
- package/dist/routes/scan-notif-operations.js.map +1 -1
- package/dist/routes/scan-operations.d.ts +2 -2
- package/dist/routes/scan-operations.d.ts.map +1 -1
- package/dist/routes/scan-operations.js +13 -15
- package/dist/routes/scan-operations.js.map +1 -1
- package/dist/routes/util.js +12 -20
- package/dist/routes/util.js.map +1 -1
- package/jest.config.cjs +21 -0
- package/package.json +14 -9
- package/src/client.ts +1 -1
- package/src/context.ts +9 -9
- package/src/db/index.ts +13 -9
- package/src/db/migrations/index.ts +4 -4
- package/src/db/schema/index.ts +5 -5
- package/src/db/schema/mute_op.ts +1 -1
- package/src/db/schema/operation.ts +2 -2
- package/src/db/types.ts +3 -1
- package/src/index.ts +17 -13
- package/src/proto/bsync_connect.ts +1 -1
- package/src/routes/add-mute-operation.ts +10 -7
- package/src/routes/add-notif-operation.ts +7 -7
- package/src/routes/auth.ts +1 -1
- package/src/routes/delete-operations.ts +5 -5
- package/src/routes/index.ts +9 -9
- package/src/routes/put-operation.ts +11 -8
- package/src/routes/scan-mute-operations.ts +6 -6
- package/src/routes/scan-notif-operations.ts +6 -6
- package/src/routes/scan-operations.ts +6 -6
- package/tests/delete-operations.test.ts +2 -2
- package/tests/mutes.test.ts +2 -2
- package/tests/notifications.test.ts +2 -2
- package/tests/operations.test.ts +2 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/jest.config.js +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atproto/bsync
|
|
2
2
|
|
|
3
|
+
## 0.0.26
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`f01c59f`](https://github.com/bluesky-social/atproto/commit/f01c59f5bd3f75fb8b47a9eecd4858b84033fb7c) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
|
|
8
|
+
|
|
9
|
+
- [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`c459153`](https://github.com/bluesky-social/atproto/commit/c459153395a30ce89e050892c8fab7dc98e019b9) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
|
|
10
|
+
|
|
11
|
+
Node.js 22's `require()` compatibility layer can still load these packages in CommonJS code.
|
|
12
|
+
|
|
13
|
+
- [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`908bece`](https://github.com/bluesky-social/atproto/commit/908bece169258bff5ad121e5eec157d6ded6f705) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0.
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`affb50c`](https://github.com/bluesky-social/atproto/commit/affb50c040b497a12631df99a6310f8e78cab557), [`f01c59f`](https://github.com/bluesky-social/atproto/commit/f01c59f5bd3f75fb8b47a9eecd4858b84033fb7c), [`c459153`](https://github.com/bluesky-social/atproto/commit/c459153395a30ce89e050892c8fab7dc98e019b9), [`908bece`](https://github.com/bluesky-social/atproto/commit/908bece169258bff5ad121e5eec157d6ded6f705)]:
|
|
16
|
+
- @atproto/common@0.6.0
|
|
17
|
+
- @atproto/syntax@0.6.0
|
|
18
|
+
|
|
3
19
|
## 0.0.25
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/bin/migration-create.ts
CHANGED
|
@@ -19,7 +19,7 @@ export async function main() {
|
|
|
19
19
|
await fs.writeFile(path.join(dir, `${filename}.ts`), template, { flag: 'wx' })
|
|
20
20
|
await fs.writeFile(
|
|
21
21
|
path.join(dir, 'index.ts'),
|
|
22
|
-
`export * as _${prefix} from './${filename}'\n`,
|
|
22
|
+
`export * as _${prefix} from './${filename}.js'\n`,
|
|
23
23
|
{ flag: 'a' },
|
|
24
24
|
)
|
|
25
25
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Interceptor, PromiseClient } from '@connectrpc/connect';
|
|
2
2
|
import { ConnectTransportOptions } from '@connectrpc/connect-node';
|
|
3
|
-
import { Service } from './proto/bsync_connect';
|
|
3
|
+
import { Service } from './proto/bsync_connect.js';
|
|
4
4
|
export type BsyncClient = PromiseClient<typeof Service>;
|
|
5
5
|
export declare const createClient: (opts: ConnectTransportOptions) => BsyncClient;
|
|
6
6
|
export declare const authWithApiKey: (apiKey: string) => Interceptor;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EAEd,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,uBAAuB,EAExB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EAEd,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,uBAAuB,EAExB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAElD,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,OAAO,CAAC,CAAA;AAEvD,eAAO,MAAM,YAAY,GAAI,MAAM,uBAAuB,KAAG,WAG5D,CAAA;AAED,eAAO,MAAM,cAAc,GACxB,QAAQ,MAAM,KAAG,WAKjB,CAAA"}
|
package/dist/client.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const createClient = (opts) => {
|
|
8
|
-
const transport = (0, connect_node_1.createConnectTransport)(opts);
|
|
9
|
-
return (0, connect_1.createPromiseClient)(bsync_connect_1.Service, transport);
|
|
1
|
+
import { createPromiseClient, } from '@connectrpc/connect';
|
|
2
|
+
import { createConnectTransport, } from '@connectrpc/connect-node';
|
|
3
|
+
import { Service } from './proto/bsync_connect.js';
|
|
4
|
+
export const createClient = (opts) => {
|
|
5
|
+
const transport = createConnectTransport(opts);
|
|
6
|
+
return createPromiseClient(Service, transport);
|
|
10
7
|
};
|
|
11
|
-
|
|
12
|
-
const authWithApiKey = (apiKey) => (next) => (req) => {
|
|
8
|
+
export const authWithApiKey = (apiKey) => (next) => (req) => {
|
|
13
9
|
req.header.set('authorization', `Bearer ${apiKey}`);
|
|
14
10
|
return next(req);
|
|
15
11
|
};
|
|
16
|
-
exports.authWithApiKey = authWithApiKey;
|
|
17
12
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,mBAAmB,GACpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAIlD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAA6B,EAAe,EAAE;IACzE,MAAM,SAAS,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;IAC9C,OAAO,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GACzB,CAAC,MAAc,EAAe,EAAE,CAChC,CAAC,IAAI,EAAE,EAAE,CACT,CAAC,GAAG,EAAE,EAAE;IACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,MAAM,EAAE,CAAC,CAAA;IACnD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;AAClB,CAAC,CAAA","sourcesContent":["import {\n Interceptor,\n PromiseClient,\n createPromiseClient,\n} from '@connectrpc/connect'\nimport {\n ConnectTransportOptions,\n createConnectTransport,\n} from '@connectrpc/connect-node'\nimport { Service } from './proto/bsync_connect.js'\n\nexport type BsyncClient = PromiseClient<typeof Service>\n\nexport const createClient = (opts: ConnectTransportOptions): BsyncClient => {\n const transport = createConnectTransport(opts)\n return createPromiseClient(Service, transport)\n}\n\nexport const authWithApiKey =\n (apiKey: string): Interceptor =>\n (next) =>\n (req) => {\n req.header.set('authorization', `Bearer ${apiKey}`)\n return next(req)\n }\n"]}
|
package/dist/config.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.readEnv = exports.envToCfg = void 0;
|
|
7
|
-
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
-
const common_1 = require("@atproto/common");
|
|
9
|
-
const envToCfg = (env) => {
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { envBool, envInt, envList, envStr } from '@atproto/common';
|
|
3
|
+
export const envToCfg = (env) => {
|
|
10
4
|
const serviceCfg = {
|
|
11
5
|
port: env.port ?? 2585,
|
|
12
6
|
version: env.version ?? 'unknown',
|
|
13
7
|
longPollTimeoutMs: env.longPollTimeoutMs ?? 10000,
|
|
14
8
|
};
|
|
15
|
-
(
|
|
9
|
+
assert(env.dbUrl, 'missing postgres url');
|
|
16
10
|
const dbCfg = {
|
|
17
11
|
url: env.dbUrl,
|
|
18
12
|
schema: env.dbSchema,
|
|
@@ -21,7 +15,7 @@ const envToCfg = (env) => {
|
|
|
21
15
|
poolIdleTimeoutMs: env.dbPoolIdleTimeoutMs,
|
|
22
16
|
migrate: env.dbMigrate,
|
|
23
17
|
};
|
|
24
|
-
(
|
|
18
|
+
assert(env.apiKeys.length > 0, 'missing api keys');
|
|
25
19
|
const authCfg = {
|
|
26
20
|
apiKeys: new Set(env.apiKeys),
|
|
27
21
|
};
|
|
@@ -31,23 +25,21 @@ const envToCfg = (env) => {
|
|
|
31
25
|
auth: authCfg,
|
|
32
26
|
};
|
|
33
27
|
};
|
|
34
|
-
|
|
35
|
-
const readEnv = () => {
|
|
28
|
+
export const readEnv = () => {
|
|
36
29
|
return {
|
|
37
30
|
// service
|
|
38
|
-
port:
|
|
39
|
-
version:
|
|
40
|
-
longPollTimeoutMs:
|
|
31
|
+
port: envInt('BSYNC_PORT'),
|
|
32
|
+
version: envStr('BSYNC_VERSION'),
|
|
33
|
+
longPollTimeoutMs: envInt('BSYNC_LONG_POLL_TIMEOUT_MS'),
|
|
41
34
|
// database
|
|
42
|
-
dbUrl:
|
|
43
|
-
dbSchema:
|
|
44
|
-
dbPoolSize:
|
|
45
|
-
dbPoolMaxUses:
|
|
46
|
-
dbPoolIdleTimeoutMs:
|
|
47
|
-
dbMigrate:
|
|
35
|
+
dbUrl: envStr('BSYNC_DB_POSTGRES_URL'),
|
|
36
|
+
dbSchema: envStr('BSYNC_DB_POSTGRES_SCHEMA'),
|
|
37
|
+
dbPoolSize: envInt('BSYNC_DB_POOL_SIZE'),
|
|
38
|
+
dbPoolMaxUses: envInt('BSYNC_DB_POOL_MAX_USES'),
|
|
39
|
+
dbPoolIdleTimeoutMs: envInt('BSYNC_DB_POOL_IDLE_TIMEOUT_MS'),
|
|
40
|
+
dbMigrate: envBool('BSYNC_DB_MIGRATE'),
|
|
48
41
|
// secrets
|
|
49
|
-
apiKeys:
|
|
42
|
+
apiKeys: envList('BSYNC_API_KEYS'),
|
|
50
43
|
};
|
|
51
44
|
};
|
|
52
|
-
exports.readEnv = readEnv;
|
|
53
45
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAElE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAsB,EAAgB,EAAE;IAC/D,MAAM,UAAU,GAA4B;QAC1C,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QACtB,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,SAAS;QACjC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,KAAK;KAClD,CAAA;IAED,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAA;IACzC,MAAM,KAAK,GAAuB;QAChC,GAAG,EAAE,GAAG,CAAC,KAAK;QACd,MAAM,EAAE,GAAG,CAAC,QAAQ;QACpB,QAAQ,EAAE,GAAG,CAAC,UAAU;QACxB,WAAW,EAAE,GAAG,CAAC,aAAa;QAC9B,iBAAiB,EAAE,GAAG,CAAC,mBAAmB;QAC1C,OAAO,EAAE,GAAG,CAAC,SAAS;KACvB,CAAA;IAED,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,kBAAkB,CAAC,CAAA;IAClD,MAAM,OAAO,GAAyB;QACpC,OAAO,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;KAC9B,CAAA;IAED,OAAO;QACL,OAAO,EAAE,UAAU;QACnB,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,OAAO;KACd,CAAA;AACH,CAAC,CAAA;AA2BD,MAAM,CAAC,MAAM,OAAO,GAAG,GAAsB,EAAE;IAC7C,OAAO;QACL,UAAU;QACV,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC,eAAe,CAAC;QAChC,iBAAiB,EAAE,MAAM,CAAC,4BAA4B,CAAC;QACvD,WAAW;QACX,KAAK,EAAE,MAAM,CAAC,uBAAuB,CAAC;QACtC,QAAQ,EAAE,MAAM,CAAC,0BAA0B,CAAC;QAC5C,UAAU,EAAE,MAAM,CAAC,oBAAoB,CAAC;QACxC,aAAa,EAAE,MAAM,CAAC,wBAAwB,CAAC;QAC/C,mBAAmB,EAAE,MAAM,CAAC,+BAA+B,CAAC;QAC5D,SAAS,EAAE,OAAO,CAAC,kBAAkB,CAAC;QACtC,UAAU;QACV,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC;KACnC,CAAA;AACH,CAAC,CAAA","sourcesContent":["import assert from 'node:assert'\nimport { envBool, envInt, envList, envStr } from '@atproto/common'\n\nexport const envToCfg = (env: ServerEnvironment): ServerConfig => {\n const serviceCfg: ServerConfig['service'] = {\n port: env.port ?? 2585,\n version: env.version ?? 'unknown',\n longPollTimeoutMs: env.longPollTimeoutMs ?? 10000,\n }\n\n assert(env.dbUrl, 'missing postgres url')\n const dbCfg: ServerConfig['db'] = {\n url: env.dbUrl,\n schema: env.dbSchema,\n poolSize: env.dbPoolSize,\n poolMaxUses: env.dbPoolMaxUses,\n poolIdleTimeoutMs: env.dbPoolIdleTimeoutMs,\n migrate: env.dbMigrate,\n }\n\n assert(env.apiKeys.length > 0, 'missing api keys')\n const authCfg: ServerConfig['auth'] = {\n apiKeys: new Set(env.apiKeys),\n }\n\n return {\n service: serviceCfg,\n db: dbCfg,\n auth: authCfg,\n }\n}\n\nexport type ServerConfig = {\n service: ServiceConfig\n db: DatabaseConfig\n auth: AuthConfig\n}\n\ntype ServiceConfig = {\n port: number\n version?: string\n longPollTimeoutMs: number\n}\n\ntype DatabaseConfig = {\n url: string\n schema?: string\n poolSize?: number\n poolMaxUses?: number\n poolIdleTimeoutMs?: number\n migrate?: boolean\n}\n\ntype AuthConfig = {\n apiKeys: Set<string>\n}\n\nexport const readEnv = (): ServerEnvironment => {\n return {\n // service\n port: envInt('BSYNC_PORT'),\n version: envStr('BSYNC_VERSION'),\n longPollTimeoutMs: envInt('BSYNC_LONG_POLL_TIMEOUT_MS'),\n // database\n dbUrl: envStr('BSYNC_DB_POSTGRES_URL'),\n dbSchema: envStr('BSYNC_DB_POSTGRES_SCHEMA'),\n dbPoolSize: envInt('BSYNC_DB_POOL_SIZE'),\n dbPoolMaxUses: envInt('BSYNC_DB_POOL_MAX_USES'),\n dbPoolIdleTimeoutMs: envInt('BSYNC_DB_POOL_IDLE_TIMEOUT_MS'),\n dbMigrate: envBool('BSYNC_DB_MIGRATE'),\n // secrets\n apiKeys: envList('BSYNC_API_KEYS'),\n }\n}\n\nexport type ServerEnvironment = {\n // service\n port?: number\n version?: string\n longPollTimeoutMs?: number\n // database\n dbUrl?: string\n dbSchema?: string\n dbPoolSize?: number\n dbPoolMaxUses?: number\n dbPoolIdleTimeoutMs?: number\n dbMigrate?: boolean\n // secrets\n apiKeys: string[]\n}\n"]}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ServerConfig } from './config';
|
|
3
|
-
import { Database } from './db';
|
|
4
|
-
import { createMuteOpChannel } from './db/schema/mute_op';
|
|
5
|
-
import { createNotifOpChannel } from './db/schema/notif_op';
|
|
6
|
-
import { createOperationChannel } from './db/schema/operation';
|
|
1
|
+
import type TypedEmitter from 'typed-emitter';
|
|
2
|
+
import { ServerConfig } from './config.js';
|
|
3
|
+
import { Database } from './db/index.js';
|
|
4
|
+
import { createMuteOpChannel } from './db/schema/mute_op.js';
|
|
5
|
+
import { createNotifOpChannel } from './db/schema/notif_op.js';
|
|
6
|
+
import { createOperationChannel } from './db/schema/operation.js';
|
|
7
7
|
export type AppContextOptions = {
|
|
8
8
|
db: Database;
|
|
9
9
|
cfg: ServerConfig;
|
|
@@ -13,7 +13,7 @@ export declare class AppContext {
|
|
|
13
13
|
db: Database;
|
|
14
14
|
cfg: ServerConfig;
|
|
15
15
|
shutdown: AbortSignal;
|
|
16
|
-
events:
|
|
16
|
+
events: TypedEmitter.default<AppEvents>;
|
|
17
17
|
constructor(opts: AppContextOptions);
|
|
18
18
|
static fromConfig(cfg: ServerConfig, shutdown: AbortSignal, overrides?: Partial<AppContextOptions>): Promise<AppContext>;
|
|
19
19
|
}
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,YAAY,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAEjE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,QAAQ,CAAA;IACZ,GAAG,EAAE,YAAY,CAAA;IACjB,QAAQ,EAAE,WAAW,CAAA;CACtB,CAAA;AAED,qBAAa,UAAU;IACrB,EAAE,EAAE,QAAQ,CAAA;IACZ,GAAG,EAAE,YAAY,CAAA;IACjB,QAAQ,EAAE,WAAW,CAAA;IACrB,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;gBAE3B,IAAI,EAAE,iBAAiB;WAOtB,UAAU,CACrB,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,WAAW,EACrB,SAAS,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACrC,OAAO,CAAC,UAAU,CAAC;CAUvB;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAA;IACjC,CAAC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAA;IAClC,CAAC,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAA;CACrC,CAAA"}
|
package/dist/context.js
CHANGED
|
@@ -1,44 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const notif_op_1 = require("./db/schema/notif_op");
|
|
8
|
-
const operation_1 = require("./db/schema/operation");
|
|
9
|
-
class AppContext {
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { Database } from './db/index.js';
|
|
3
|
+
import { createMuteOpChannel } from './db/schema/mute_op.js';
|
|
4
|
+
import { createNotifOpChannel } from './db/schema/notif_op.js';
|
|
5
|
+
import { createOperationChannel } from './db/schema/operation.js';
|
|
6
|
+
export class AppContext {
|
|
10
7
|
constructor(opts) {
|
|
11
|
-
Object.defineProperty(this, "db", {
|
|
12
|
-
enumerable: true,
|
|
13
|
-
configurable: true,
|
|
14
|
-
writable: true,
|
|
15
|
-
value: void 0
|
|
16
|
-
});
|
|
17
|
-
Object.defineProperty(this, "cfg", {
|
|
18
|
-
enumerable: true,
|
|
19
|
-
configurable: true,
|
|
20
|
-
writable: true,
|
|
21
|
-
value: void 0
|
|
22
|
-
});
|
|
23
|
-
Object.defineProperty(this, "shutdown", {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
writable: true,
|
|
27
|
-
value: void 0
|
|
28
|
-
});
|
|
29
|
-
Object.defineProperty(this, "events", {
|
|
30
|
-
enumerable: true,
|
|
31
|
-
configurable: true,
|
|
32
|
-
writable: true,
|
|
33
|
-
value: void 0
|
|
34
|
-
});
|
|
35
8
|
this.db = opts.db;
|
|
36
9
|
this.cfg = opts.cfg;
|
|
37
10
|
this.shutdown = opts.shutdown;
|
|
38
|
-
this.events = new
|
|
11
|
+
this.events = new EventEmitter();
|
|
39
12
|
}
|
|
40
13
|
static async fromConfig(cfg, shutdown, overrides) {
|
|
41
|
-
const db = new
|
|
14
|
+
const db = new Database({
|
|
42
15
|
url: cfg.db.url,
|
|
43
16
|
schema: cfg.db.schema,
|
|
44
17
|
poolSize: cfg.db.poolSize,
|
|
@@ -48,5 +21,4 @@ class AppContext {
|
|
|
48
21
|
return new AppContext({ db, cfg, shutdown, ...overrides });
|
|
49
22
|
}
|
|
50
23
|
}
|
|
51
|
-
exports.AppContext = AppContext;
|
|
52
24
|
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAQjE,MAAM,OAAO,UAAU;IAMrB,YAAY,IAAuB;QACjC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAA;QACjB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;QACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,YAAY,EAAqC,CAAA;IACrE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,UAAU,CACrB,GAAiB,EACjB,QAAqB,EACrB,SAAsC;QAEtC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC;YACtB,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG;YACf,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM;YACrB,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,QAAQ;YACzB,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC,WAAW;YAC/B,iBAAiB,EAAE,GAAG,CAAC,EAAE,CAAC,iBAAiB;SAC5C,CAAC,CAAA;QACF,OAAO,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC,CAAA;IAC5D,CAAC;CACF","sourcesContent":["import { EventEmitter } from 'node:events'\nimport type TypedEmitter from 'typed-emitter'\nimport { ServerConfig } from './config.js'\nimport { Database } from './db/index.js'\nimport { createMuteOpChannel } from './db/schema/mute_op.js'\nimport { createNotifOpChannel } from './db/schema/notif_op.js'\nimport { createOperationChannel } from './db/schema/operation.js'\n\nexport type AppContextOptions = {\n db: Database\n cfg: ServerConfig\n shutdown: AbortSignal\n}\n\nexport class AppContext {\n db: Database\n cfg: ServerConfig\n shutdown: AbortSignal\n events: TypedEmitter.default<AppEvents>\n\n constructor(opts: AppContextOptions) {\n this.db = opts.db\n this.cfg = opts.cfg\n this.shutdown = opts.shutdown\n this.events = new EventEmitter() as TypedEmitter.default<AppEvents>\n }\n\n static async fromConfig(\n cfg: ServerConfig,\n shutdown: AbortSignal,\n overrides?: Partial<AppContextOptions>,\n ): Promise<AppContext> {\n const db = new Database({\n url: cfg.db.url,\n schema: cfg.db.schema,\n poolSize: cfg.db.poolSize,\n poolMaxUses: cfg.db.poolMaxUses,\n poolIdleTimeoutMs: cfg.db.poolIdleTimeoutMs,\n })\n return new AppContext({ db, cfg, shutdown, ...overrides })\n }\n}\n\nexport type AppEvents = {\n [createMuteOpChannel]: () => void\n [createNotifOpChannel]: () => void\n [createOperationChannel]: () => void\n}\n"]}
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Migrator } from 'kysely';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
2
|
+
import pg from 'pg';
|
|
3
|
+
declare const PgPool: typeof pg.Pool;
|
|
4
|
+
type PgPool = InstanceType<typeof PgPool>;
|
|
5
|
+
import type TypedEmitter from 'typed-emitter';
|
|
6
|
+
import { DatabaseSchema } from './schema/index.js';
|
|
7
|
+
import { PgOptions } from './types.js';
|
|
6
8
|
export declare class Database {
|
|
7
9
|
opts: PgOptions;
|
|
8
10
|
pool: PgPool;
|
|
@@ -25,7 +27,7 @@ export declare class Database {
|
|
|
25
27
|
migrateToLatestOrThrow(): Promise<import("kysely").MigrationResult[]>;
|
|
26
28
|
}
|
|
27
29
|
export default Database;
|
|
28
|
-
type TxnEmitter = TypedEmitter<TxnEvents>;
|
|
30
|
+
type TxnEmitter = TypedEmitter.default<TxnEvents>;
|
|
29
31
|
type TxnEvents = {
|
|
30
32
|
commit: () => void;
|
|
31
33
|
};
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,QAAQ,EAOT,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,QAAQ,EAOT,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,QAAA,MAAc,MAAM,gBAAuB,CAAA;AAC3C,KAAK,MAAM,GAAG,YAAY,CAAC,OAAO,MAAM,CAAC,CAAA;AACzC,OAAO,KAAK,YAAY,MAAM,eAAe,CAAA;AAI7C,OAAO,EAAE,cAAc,EAAsB,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,qBAAa,QAAQ;IAQV,IAAI,EAAE,SAAS;IAPxB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,cAAc,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,EAAyB,UAAU,CAAA;IACxC,SAAS,UAAQ;gBAGR,IAAI,EAAE,SAAS,EACtB,SAAS,CAAC,EAAE;QAAE,EAAE,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAkDlD,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAE/B;IAED,IAAI,aAAa,YAEhB;IAED,iBAAiB;IAIjB,oBAAoB;IAId,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAwBlE,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI;IAKjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,gBAAgB,CAAC,SAAS,EAAE,MAAM;IAclC,sBAAsB;CAa7B;AAED,eAAe,QAAQ,CAAA;AA6BvB,KAAK,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AAEjD,KAAK,SAAS,GAAG;IACf,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA"}
|
package/dist/db/index.js
CHANGED
|
@@ -1,87 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.Database = void 0;
|
|
40
|
-
const node_assert_1 = __importDefault(require("node:assert"));
|
|
41
|
-
const node_stream_1 = require("node:stream");
|
|
42
|
-
const kysely_1 = require("kysely");
|
|
43
|
-
const pg_1 = require("pg");
|
|
44
|
-
const logger_1 = require("../logger");
|
|
45
|
-
const migrations = __importStar(require("./migrations"));
|
|
46
|
-
const provider_1 = require("./migrations/provider");
|
|
47
|
-
class Database {
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import { Kysely, Migrator, PostgresDialect, } from 'kysely';
|
|
4
|
+
// eslint-disable-next-line import/default
|
|
5
|
+
import pg from 'pg';
|
|
6
|
+
// eslint-disable-next-line import/no-named-as-default-member
|
|
7
|
+
const { Pool: PgPool, types: pgTypes } = pg;
|
|
8
|
+
import { dbLogger } from '../logger.js';
|
|
9
|
+
import * as migrations from './migrations/index.js';
|
|
10
|
+
import { DbMigrationProvider } from './migrations/provider.js';
|
|
11
|
+
export class Database {
|
|
48
12
|
constructor(opts, instances) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
writable: true,
|
|
53
|
-
value: opts
|
|
54
|
-
});
|
|
55
|
-
Object.defineProperty(this, "pool", {
|
|
56
|
-
enumerable: true,
|
|
57
|
-
configurable: true,
|
|
58
|
-
writable: true,
|
|
59
|
-
value: void 0
|
|
60
|
-
});
|
|
61
|
-
Object.defineProperty(this, "db", {
|
|
62
|
-
enumerable: true,
|
|
63
|
-
configurable: true,
|
|
64
|
-
writable: true,
|
|
65
|
-
value: void 0
|
|
66
|
-
});
|
|
67
|
-
Object.defineProperty(this, "migrator", {
|
|
68
|
-
enumerable: true,
|
|
69
|
-
configurable: true,
|
|
70
|
-
writable: true,
|
|
71
|
-
value: void 0
|
|
72
|
-
});
|
|
73
|
-
Object.defineProperty(this, "txEvt", {
|
|
74
|
-
enumerable: true,
|
|
75
|
-
configurable: true,
|
|
76
|
-
writable: true,
|
|
77
|
-
value: new node_stream_1.EventEmitter()
|
|
78
|
-
});
|
|
79
|
-
Object.defineProperty(this, "destroyed", {
|
|
80
|
-
enumerable: true,
|
|
81
|
-
configurable: true,
|
|
82
|
-
writable: true,
|
|
83
|
-
value: false
|
|
84
|
-
});
|
|
13
|
+
this.opts = opts;
|
|
14
|
+
this.txEvt = new EventEmitter();
|
|
15
|
+
this.destroyed = false;
|
|
85
16
|
// if instances are provided, use those
|
|
86
17
|
if (instances) {
|
|
87
18
|
this.db = instances.db;
|
|
@@ -91,14 +22,14 @@ class Database {
|
|
|
91
22
|
// else create a pool & connect
|
|
92
23
|
const { schema, url } = opts;
|
|
93
24
|
const pool = opts.pool ??
|
|
94
|
-
new
|
|
25
|
+
new PgPool({
|
|
95
26
|
connectionString: url,
|
|
96
27
|
max: opts.poolSize,
|
|
97
28
|
maxUses: opts.poolMaxUses,
|
|
98
29
|
idleTimeoutMillis: opts.poolIdleTimeoutMs,
|
|
99
30
|
});
|
|
100
31
|
// Select count(*) and other pg bigints as js integer
|
|
101
|
-
|
|
32
|
+
pgTypes.setTypeParser(pgTypes.builtins.INT8, (n) => parseInt(n, 10));
|
|
102
33
|
// Setup schema usage, primarily for test parallelism (each test suite runs in its own pg schema)
|
|
103
34
|
if (schema && !/^[a-z_]+$/i.test(schema)) {
|
|
104
35
|
throw new Error(`Postgres schema must only contain [A-Za-z_]: ${schema}`);
|
|
@@ -112,14 +43,14 @@ class Database {
|
|
|
112
43
|
}
|
|
113
44
|
});
|
|
114
45
|
this.pool = pool;
|
|
115
|
-
this.db = new
|
|
116
|
-
dialect: new
|
|
46
|
+
this.db = new Kysely({
|
|
47
|
+
dialect: new PostgresDialect({ pool }),
|
|
117
48
|
});
|
|
118
49
|
}
|
|
119
|
-
this.migrator = new
|
|
50
|
+
this.migrator = new Migrator({
|
|
120
51
|
db: this.db,
|
|
121
52
|
migrationTableSchema: opts.schema,
|
|
122
|
-
provider: new
|
|
53
|
+
provider: new DbMigrationProvider(migrations),
|
|
123
54
|
});
|
|
124
55
|
}
|
|
125
56
|
get schema() {
|
|
@@ -129,10 +60,10 @@ class Database {
|
|
|
129
60
|
return this.db.isTransaction;
|
|
130
61
|
}
|
|
131
62
|
assertTransaction() {
|
|
132
|
-
(
|
|
63
|
+
assert(this.isTransaction, 'Transaction required');
|
|
133
64
|
}
|
|
134
65
|
assertNotTransaction() {
|
|
135
|
-
(
|
|
66
|
+
assert(!this.isTransaction, 'Cannot be in a transaction');
|
|
136
67
|
}
|
|
137
68
|
async transaction(fn) {
|
|
138
69
|
const leakyTxPlugin = new LeakyTxPlugin();
|
|
@@ -194,20 +125,14 @@ class Database {
|
|
|
194
125
|
return results;
|
|
195
126
|
}
|
|
196
127
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
const onClientError = (err) => logger_1.dbLogger.error({ err }, 'db client error');
|
|
128
|
+
export default Database;
|
|
129
|
+
const onPoolError = (err) => dbLogger.error({ err }, 'db pool error');
|
|
130
|
+
const onClientError = (err) => dbLogger.error({ err }, 'db client error');
|
|
201
131
|
// utils
|
|
202
132
|
// -------
|
|
203
133
|
class LeakyTxPlugin {
|
|
204
134
|
constructor() {
|
|
205
|
-
|
|
206
|
-
enumerable: true,
|
|
207
|
-
configurable: true,
|
|
208
|
-
writable: true,
|
|
209
|
-
value: false
|
|
210
|
-
});
|
|
135
|
+
this.txOver = false;
|
|
211
136
|
}
|
|
212
137
|
endTx() {
|
|
213
138
|
this.txOver = true;
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { EventEmitter } from 'node:stream'\nimport {\n Kysely,\n KyselyPlugin,\n Migrator,\n PluginTransformQueryArgs,\n PluginTransformResultArgs,\n PostgresDialect,\n QueryResult,\n RootOperationNode,\n UnknownRow,\n} from 'kysely'\nimport { Pool as PgPool, types as pgTypes } from 'pg'\nimport TypedEmitter from 'typed-emitter'\nimport { dbLogger } from '../logger'\nimport * as migrations from './migrations'\nimport { DbMigrationProvider } from './migrations/provider'\nimport { DatabaseSchema, DatabaseSchemaType } from './schema'\nimport { PgOptions } from './types'\n\nexport class Database {\n pool: PgPool\n db: DatabaseSchema\n migrator: Migrator\n txEvt = new EventEmitter() as TxnEmitter\n destroyed = false\n\n constructor(\n public opts: PgOptions,\n instances?: { db: DatabaseSchema; pool: PgPool },\n ) {\n // if instances are provided, use those\n if (instances) {\n this.db = instances.db\n this.pool = instances.pool\n } else {\n // else create a pool & connect\n const { schema, url } = opts\n const pool =\n opts.pool ??\n new PgPool({\n connectionString: url,\n max: opts.poolSize,\n maxUses: opts.poolMaxUses,\n idleTimeoutMillis: opts.poolIdleTimeoutMs,\n })\n\n // Select count(*) and other pg bigints as js integer\n pgTypes.setTypeParser(pgTypes.builtins.INT8, (n) => parseInt(n, 10))\n\n // Setup schema usage, primarily for test parallelism (each test suite runs in its own pg schema)\n if (schema && !/^[a-z_]+$/i.test(schema)) {\n throw new Error(\n `Postgres schema must only contain [A-Za-z_]: ${schema}`,\n )\n }\n\n pool.on('error', onPoolError)\n pool.on('connect', (client) => {\n client.on('error', onClientError)\n if (schema) {\n // Shared objects such as extensions will go in the public schema\n client.query(`SET search_path TO \"${schema}\",public;`)\n }\n })\n\n this.pool = pool\n this.db = new Kysely<DatabaseSchemaType>({\n dialect: new PostgresDialect({ pool }),\n })\n }\n\n this.migrator = new Migrator({\n db: this.db,\n migrationTableSchema: opts.schema,\n provider: new DbMigrationProvider(migrations),\n })\n }\n\n get schema(): string | undefined {\n return this.opts.schema\n }\n\n get isTransaction() {\n return this.db.isTransaction\n }\n\n assertTransaction() {\n assert(this.isTransaction, 'Transaction required')\n }\n\n assertNotTransaction() {\n assert(!this.isTransaction, 'Cannot be in a transaction')\n }\n\n async transaction<T>(fn: (db: Database) => Promise<T>): Promise<T> {\n const leakyTxPlugin = new LeakyTxPlugin()\n const { dbTxn, txRes } = await this.db\n .withPlugin(leakyTxPlugin)\n .transaction()\n .execute(async (txn) => {\n const dbTxn = new Database(this.opts, {\n db: txn,\n pool: this.pool,\n })\n const txRes = await fn(dbTxn)\n .catch(async (err) => {\n leakyTxPlugin.endTx()\n // ensure that all in-flight queries are flushed & the connection is open\n await dbTxn.db.getExecutor().provideConnection(noopAsync)\n throw err\n })\n .finally(() => leakyTxPlugin.endTx())\n return { dbTxn, txRes }\n })\n dbTxn?.txEvt.emit('commit')\n return txRes\n }\n\n onCommit(fn: () => void) {\n this.assertTransaction()\n this.txEvt.once('commit', fn)\n }\n\n async close(): Promise<void> {\n if (this.destroyed) return\n await this.db.destroy()\n this.destroyed = true\n }\n\n async migrateToOrThrow(migration: string) {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateTo(migration)\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n\n async migrateToLatestOrThrow() {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateToLatest()\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n}\n\nexport default Database\n\nconst onPoolError = (err: Error) => dbLogger.error({ err }, 'db pool error')\nconst onClientError = (err: Error) => dbLogger.error({ err }, 'db client error')\n\n// utils\n// -------\n\nclass LeakyTxPlugin implements KyselyPlugin {\n private txOver = false\n\n endTx() {\n this.txOver = true\n }\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n if (this.txOver) {\n throw new Error('tx already failed')\n }\n return args.node\n }\n\n async transformResult(\n args: PluginTransformResultArgs,\n ): Promise<QueryResult<UnknownRow>> {\n return args.result\n }\n}\n\ntype TxnEmitter = TypedEmitter<TxnEvents>\n\ntype TxnEvents = {\n commit: () => void\n}\n\nconst noopAsync = async () => {}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { EventEmitter } from 'node:events'\nimport {\n Kysely,\n KyselyPlugin,\n Migrator,\n PluginTransformQueryArgs,\n PluginTransformResultArgs,\n PostgresDialect,\n QueryResult,\n RootOperationNode,\n UnknownRow,\n} from 'kysely'\n// eslint-disable-next-line import/default\nimport pg from 'pg'\n// eslint-disable-next-line import/no-named-as-default-member\nconst { Pool: PgPool, types: pgTypes } = pg\ntype PgPool = InstanceType<typeof PgPool>\nimport type TypedEmitter from 'typed-emitter'\nimport { dbLogger } from '../logger.js'\nimport * as migrations from './migrations/index.js'\nimport { DbMigrationProvider } from './migrations/provider.js'\nimport { DatabaseSchema, DatabaseSchemaType } from './schema/index.js'\nimport { PgOptions } from './types.js'\n\nexport class Database {\n pool: PgPool\n db: DatabaseSchema\n migrator: Migrator\n txEvt = new EventEmitter() as TxnEmitter\n destroyed = false\n\n constructor(\n public opts: PgOptions,\n instances?: { db: DatabaseSchema; pool: PgPool },\n ) {\n // if instances are provided, use those\n if (instances) {\n this.db = instances.db\n this.pool = instances.pool\n } else {\n // else create a pool & connect\n const { schema, url } = opts\n const pool =\n opts.pool ??\n new PgPool({\n connectionString: url,\n max: opts.poolSize,\n maxUses: opts.poolMaxUses,\n idleTimeoutMillis: opts.poolIdleTimeoutMs,\n })\n\n // Select count(*) and other pg bigints as js integer\n pgTypes.setTypeParser(pgTypes.builtins.INT8, (n) => parseInt(n, 10))\n\n // Setup schema usage, primarily for test parallelism (each test suite runs in its own pg schema)\n if (schema && !/^[a-z_]+$/i.test(schema)) {\n throw new Error(\n `Postgres schema must only contain [A-Za-z_]: ${schema}`,\n )\n }\n\n pool.on('error', onPoolError)\n pool.on('connect', (client) => {\n client.on('error', onClientError)\n if (schema) {\n // Shared objects such as extensions will go in the public schema\n client.query(`SET search_path TO \"${schema}\",public;`)\n }\n })\n\n this.pool = pool\n this.db = new Kysely<DatabaseSchemaType>({\n dialect: new PostgresDialect({ pool }),\n })\n }\n\n this.migrator = new Migrator({\n db: this.db,\n migrationTableSchema: opts.schema,\n provider: new DbMigrationProvider(migrations),\n })\n }\n\n get schema(): string | undefined {\n return this.opts.schema\n }\n\n get isTransaction() {\n return this.db.isTransaction\n }\n\n assertTransaction() {\n assert(this.isTransaction, 'Transaction required')\n }\n\n assertNotTransaction() {\n assert(!this.isTransaction, 'Cannot be in a transaction')\n }\n\n async transaction<T>(fn: (db: Database) => Promise<T>): Promise<T> {\n const leakyTxPlugin = new LeakyTxPlugin()\n const { dbTxn, txRes } = await this.db\n .withPlugin(leakyTxPlugin)\n .transaction()\n .execute(async (txn) => {\n const dbTxn = new Database(this.opts, {\n db: txn,\n pool: this.pool,\n })\n const txRes = await fn(dbTxn)\n .catch(async (err) => {\n leakyTxPlugin.endTx()\n // ensure that all in-flight queries are flushed & the connection is open\n await dbTxn.db.getExecutor().provideConnection(noopAsync)\n throw err\n })\n .finally(() => leakyTxPlugin.endTx())\n return { dbTxn, txRes }\n })\n dbTxn?.txEvt.emit('commit')\n return txRes\n }\n\n onCommit(fn: () => void) {\n this.assertTransaction()\n this.txEvt.once('commit', fn)\n }\n\n async close(): Promise<void> {\n if (this.destroyed) return\n await this.db.destroy()\n this.destroyed = true\n }\n\n async migrateToOrThrow(migration: string) {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateTo(migration)\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n\n async migrateToLatestOrThrow() {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateToLatest()\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n}\n\nexport default Database\n\nconst onPoolError = (err: Error) => dbLogger.error({ err }, 'db pool error')\nconst onClientError = (err: Error) => dbLogger.error({ err }, 'db client error')\n\n// utils\n// -------\n\nclass LeakyTxPlugin implements KyselyPlugin {\n private txOver = false\n\n endTx() {\n this.txOver = true\n }\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n if (this.txOver) {\n throw new Error('tx already failed')\n }\n return args.node\n }\n\n async transformResult(\n args: PluginTransformResultArgs,\n ): Promise<QueryResult<UnknownRow>> {\n return args.result\n }\n}\n\ntype TxnEmitter = TypedEmitter.default<TxnEvents>\n\ntype TxnEvents = {\n commit: () => void\n}\n\nconst noopAsync = async () => {}\n"]}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.up = up;
|
|
4
|
-
exports.down = down;
|
|
5
|
-
const kysely_1 = require("kysely");
|
|
6
|
-
async function up(db) {
|
|
1
|
+
import { sql } from 'kysely';
|
|
2
|
+
export async function up(db) {
|
|
7
3
|
await db.schema
|
|
8
4
|
.createTable('mute_op')
|
|
9
5
|
.addColumn('id', 'bigserial', (col) => col.primaryKey())
|
|
10
6
|
.addColumn('type', 'int2', (col) => col.notNull()) // integer enum: 0->add, 1->remove, 2->clear
|
|
11
7
|
.addColumn('actorDid', 'varchar', (col) => col.notNull())
|
|
12
8
|
.addColumn('subject', 'varchar', (col) => col.notNull())
|
|
13
|
-
.addColumn('createdAt', 'timestamptz', (col) => col.notNull().defaultTo(
|
|
9
|
+
.addColumn('createdAt', 'timestamptz', (col) => col.notNull().defaultTo(sql `CURRENT_TIMESTAMP`))
|
|
14
10
|
.execute();
|
|
15
11
|
await db.schema
|
|
16
12
|
.createTable('mute_item')
|
|
@@ -20,7 +16,7 @@ async function up(db) {
|
|
|
20
16
|
.addPrimaryKeyConstraint('mute_item_pkey', ['actorDid', 'subject'])
|
|
21
17
|
.execute();
|
|
22
18
|
}
|
|
23
|
-
async function down(db) {
|
|
19
|
+
export async function down(db) {
|
|
24
20
|
await db.schema.dropTable('mute_item').execute();
|
|
25
21
|
await db.schema.dropTable('mute_op').execute();
|
|
26
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"20240108T220751294Z-init.js","sourceRoot":"","sources":["../../../src/db/migrations/20240108T220751294Z-init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"20240108T220751294Z-init.js","sourceRoot":"","sources":["../../../src/db/migrations/20240108T220751294Z-init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,GAAG,EAAE,MAAM,QAAQ,CAAA;AAEpC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB;IAC1C,MAAM,EAAE,CAAC,MAAM;SACZ,WAAW,CAAC,SAAS,CAAC;SACtB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;SACvD,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,4CAA4C;SAC9F,SAAS,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACxD,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACvD,SAAS,CAAC,WAAW,EAAE,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAC7C,GAAG,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,GAAG,CAAA,mBAAmB,CAAC,CAChD;SACA,OAAO,EAAE,CAAA;IACZ,MAAM,EAAE,CAAC,MAAM;SACZ,WAAW,CAAC,WAAW,CAAC;SACxB,SAAS,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACxD,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACvD,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACrD,uBAAuB,CAAC,gBAAgB,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;SAClE,OAAO,EAAE,CAAA;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,EAAmB;IAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAA;IAChD,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAA;AAChD,CAAC","sourcesContent":["import { Kysely, sql } from 'kysely'\n\nexport async function up(db: Kysely<unknown>): Promise<void> {\n await db.schema\n .createTable('mute_op')\n .addColumn('id', 'bigserial', (col) => col.primaryKey())\n .addColumn('type', 'int2', (col) => col.notNull()) // integer enum: 0->add, 1->remove, 2->clear\n .addColumn('actorDid', 'varchar', (col) => col.notNull())\n .addColumn('subject', 'varchar', (col) => col.notNull())\n .addColumn('createdAt', 'timestamptz', (col) =>\n col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`),\n )\n .execute()\n await db.schema\n .createTable('mute_item')\n .addColumn('actorDid', 'varchar', (col) => col.notNull())\n .addColumn('subject', 'varchar', (col) => col.notNull())\n .addColumn('fromId', 'bigint', (col) => col.notNull())\n .addPrimaryKeyConstraint('mute_item_pkey', ['actorDid', 'subject'])\n .execute()\n}\n\nexport async function down(db: Kysely<unknown>): Promise<void> {\n await db.schema.dropTable('mute_item').execute()\n await db.schema.dropTable('mute_op').execute()\n}\n"]}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.up = up;
|
|
4
|
-
exports.down = down;
|
|
5
|
-
const kysely_1 = require("kysely");
|
|
6
|
-
async function up(db) {
|
|
1
|
+
import { sql } from 'kysely';
|
|
2
|
+
export async function up(db) {
|
|
7
3
|
await db.schema
|
|
8
4
|
.createTable('notif_op')
|
|
9
5
|
.addColumn('id', 'bigserial', (col) => col.primaryKey())
|
|
10
6
|
.addColumn('actorDid', 'varchar', (col) => col.notNull())
|
|
11
7
|
.addColumn('priority', 'boolean')
|
|
12
|
-
.addColumn('createdAt', 'timestamptz', (col) => col.notNull().defaultTo(
|
|
8
|
+
.addColumn('createdAt', 'timestamptz', (col) => col.notNull().defaultTo(sql `CURRENT_TIMESTAMP`))
|
|
13
9
|
.execute();
|
|
14
10
|
await db.schema
|
|
15
11
|
.createTable('notif_item')
|
|
@@ -18,7 +14,7 @@ async function up(db) {
|
|
|
18
14
|
.addColumn('fromId', 'bigint', (col) => col.notNull())
|
|
19
15
|
.execute();
|
|
20
16
|
}
|
|
21
|
-
async function down(db) {
|
|
17
|
+
export async function down(db) {
|
|
22
18
|
await db.schema.dropTable('notif_item').execute();
|
|
23
19
|
await db.schema.dropTable('notif_op').execute();
|
|
24
20
|
}
|