@mtcute/postgres 0.29.1
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/LICENSE +8 -0
- package/README.md +89 -0
- package/_utils.cjs +15 -0
- package/_utils.d.cts +2 -0
- package/_utils.d.ts +2 -0
- package/_utils.js +10 -0
- package/driver.cjs +110 -0
- package/driver.d.cts +49 -0
- package/driver.d.ts +49 -0
- package/driver.js +105 -0
- package/index.cjs +32 -0
- package/index.d.cts +20 -0
- package/index.d.ts +20 -0
- package/index.js +27 -0
- package/package.json +30 -0
- package/postgres.test-d.d.cts +1 -0
- package/postgres.test-d.d.ts +1 -0
- package/postgres.test.d.cts +1 -0
- package/postgres.test.d.ts +1 -0
- package/repository/auth-keys.cjs +79 -0
- package/repository/auth-keys.d.cts +14 -0
- package/repository/auth-keys.d.ts +14 -0
- package/repository/auth-keys.js +74 -0
- package/repository/kv.cjs +40 -0
- package/repository/kv.d.cts +11 -0
- package/repository/kv.d.ts +11 -0
- package/repository/kv.js +35 -0
- package/repository/peers.cjs +97 -0
- package/repository/peers.d.cts +14 -0
- package/repository/peers.d.ts +14 -0
- package/repository/peers.js +92 -0
- package/repository/ref-messages.cjs +55 -0
- package/repository/ref-messages.d.cts +12 -0
- package/repository/ref-messages.d.ts +12 -0
- package/repository/ref-messages.js +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Copyright 2023 alina sireneva
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
8
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @mtcute/postgres
|
|
2
|
+
|
|
3
|
+
PostgreSQL storage provider for mtcute. Uses any `pg`-compatible client (Pool, Client, or PoolClient).
|
|
4
|
+
|
|
5
|
+
All tables are created in a dedicated schema (`mtcute` by default), with automatic migrations.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @mtcute/postgres pg
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { TelegramClient } from '@mtcute/node'
|
|
17
|
+
import { PostgresStorage } from '@mtcute/postgres'
|
|
18
|
+
import pg from 'pg'
|
|
19
|
+
|
|
20
|
+
const pool = new pg.Pool({ connectionString: 'postgres://localhost/mydb' })
|
|
21
|
+
|
|
22
|
+
const tg = new TelegramClient({
|
|
23
|
+
apiId: 12345,
|
|
24
|
+
apiHash: 'abcdef',
|
|
25
|
+
storage: new PostgresStorage(pool),
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const self = await tg.start()
|
|
29
|
+
console.log(`logged in as ${self.displayName}`)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Options
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
new PostgresStorage(pool, {
|
|
36
|
+
// PostgreSQL schema to use for all tables (default: 'mtcute')
|
|
37
|
+
schema: 'my_schema',
|
|
38
|
+
// Whether to automatically close the client when the storage is destroyed (default: true)
|
|
39
|
+
// Calls .end(), .release(), or .close() depending on what the client supports
|
|
40
|
+
autoClose: true,
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Using with PGlite
|
|
45
|
+
|
|
46
|
+
You can use [PGlite](https://github.com/electric-sql/pglite) for an embedded PostgreSQL instance that requires no external server:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { PGlite } from '@electric-sql/pglite'
|
|
50
|
+
import { PostgresStorage } from '@mtcute/postgres'
|
|
51
|
+
|
|
52
|
+
const pglite = await PGlite.create()
|
|
53
|
+
const storage = new PostgresStorage(pglite)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
PGlite satisfies the `PgClient` interface out of the box, so no adapters are needed.
|
|
57
|
+
|
|
58
|
+
## Using with an existing connection
|
|
59
|
+
|
|
60
|
+
You can pass any object that satisfies the `PgClient` interface (a `query` method matching `pg`'s signature):
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { PostgresStorage } from '@mtcute/postgres'
|
|
64
|
+
|
|
65
|
+
// with a single client
|
|
66
|
+
const client = new pg.Client({ connectionString: '...' })
|
|
67
|
+
await client.connect()
|
|
68
|
+
const storage = new PostgresStorage(client)
|
|
69
|
+
|
|
70
|
+
// with a pool client
|
|
71
|
+
const poolClient = await pool.connect()
|
|
72
|
+
const storage = new PostgresStorage(poolClient)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
> **Note:** By default, mtcute will automatically close the client (via `.end()`, `.release()`, or `.close()`)
|
|
76
|
+
> when the storage is destroyed. Set `autoClose: false` if you want to manage the connection lifecycle yourself.
|
|
77
|
+
|
|
78
|
+
## Database schema
|
|
79
|
+
|
|
80
|
+
All tables are created under the configured schema (default `mtcute`). The following tables are used:
|
|
81
|
+
|
|
82
|
+
| Table | Purpose |
|
|
83
|
+
|-------|---------|
|
|
84
|
+
| `migrations` | Tracks migration versions per repository |
|
|
85
|
+
| `auth_keys` | Persistent authorization keys per DC |
|
|
86
|
+
| `temp_auth_keys` | Temporary authorization keys with expiry |
|
|
87
|
+
| `key_value` | General-purpose key-value store |
|
|
88
|
+
| `peers` | Cached peer information (users, chats, channels) |
|
|
89
|
+
| `message_refs` | Reference messages for peer access hash resolution |
|
package/_utils.cjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/postgres] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/postgres] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
function parseBigint(value) {
|
|
9
|
+
return typeof value === "string" ? Number(value) : value;
|
|
10
|
+
}
|
|
11
|
+
function parseJsonb(value) {
|
|
12
|
+
return typeof value === "string" ? JSON.parse(value) : value;
|
|
13
|
+
}
|
|
14
|
+
exports.parseBigint = parseBigint;
|
|
15
|
+
exports.parseJsonb = parseJsonb;
|
package/_utils.d.cts
ADDED
package/_utils.d.ts
ADDED
package/_utils.js
ADDED
package/driver.cjs
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/postgres] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/postgres] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
const core = require("@mtcute/core");
|
|
9
|
+
class PostgresStorageDriver extends core.BaseStorageDriver {
|
|
10
|
+
client;
|
|
11
|
+
schema;
|
|
12
|
+
_cleanup;
|
|
13
|
+
_migrations = /* @__PURE__ */ new Map();
|
|
14
|
+
_maxVersion = /* @__PURE__ */ new Map();
|
|
15
|
+
_onLoadCallbacks = /* @__PURE__ */ new Set();
|
|
16
|
+
_autoClose = true;
|
|
17
|
+
constructor(client, options) {
|
|
18
|
+
super();
|
|
19
|
+
this.client = client;
|
|
20
|
+
this.schema = options?.schema ?? "mtcute";
|
|
21
|
+
this._autoClose = options?.autoClose ?? true;
|
|
22
|
+
}
|
|
23
|
+
/** Returns a schema-qualified table name, safe for interpolation into SQL */
|
|
24
|
+
tableName(name) {
|
|
25
|
+
return `"${this.schema}"."${name}"`;
|
|
26
|
+
}
|
|
27
|
+
setup(log, platform) {
|
|
28
|
+
super.setup(log, platform);
|
|
29
|
+
this._log = log.create("postgres");
|
|
30
|
+
}
|
|
31
|
+
registerMigration(repo, version, migration) {
|
|
32
|
+
if (this.loaded) {
|
|
33
|
+
throw new Error("Cannot register migrations after loading");
|
|
34
|
+
}
|
|
35
|
+
let map = this._migrations.get(repo);
|
|
36
|
+
if (!map) {
|
|
37
|
+
map = /* @__PURE__ */ new Map();
|
|
38
|
+
this._migrations.set(repo, map);
|
|
39
|
+
}
|
|
40
|
+
if (map.has(version)) {
|
|
41
|
+
throw new Error(`Migration for ${repo} version ${version} is already registered`);
|
|
42
|
+
}
|
|
43
|
+
map.set(version, migration);
|
|
44
|
+
const prevMax = this._maxVersion.get(repo) ?? 0;
|
|
45
|
+
if (version > prevMax) {
|
|
46
|
+
this._maxVersion.set(repo, version);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
onLoad(cb) {
|
|
50
|
+
if (this.loaded) {
|
|
51
|
+
cb();
|
|
52
|
+
} else {
|
|
53
|
+
this._onLoadCallbacks.add(cb);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async _runMigrations() {
|
|
57
|
+
const migrationsTable = this.tableName("migrations");
|
|
58
|
+
await this.client.query(`create schema if not exists "${this.schema}"`);
|
|
59
|
+
await this.client.query(`
|
|
60
|
+
create table if not exists ${migrationsTable} (
|
|
61
|
+
repo text not null primary key,
|
|
62
|
+
version integer not null
|
|
63
|
+
)
|
|
64
|
+
`);
|
|
65
|
+
for (const repo of this._migrations.keys()) {
|
|
66
|
+
const res = await this.client.query(
|
|
67
|
+
`select version from ${migrationsTable} where repo = $1`,
|
|
68
|
+
[repo]
|
|
69
|
+
);
|
|
70
|
+
const startVersion = res.rows[0]?.version ?? 0;
|
|
71
|
+
let fromVersion = startVersion;
|
|
72
|
+
const migrations = this._migrations.get(repo);
|
|
73
|
+
const targetVer = this._maxVersion.get(repo);
|
|
74
|
+
while (fromVersion < targetVer) {
|
|
75
|
+
const nextVersion = fromVersion + 1;
|
|
76
|
+
const migration = migrations.get(nextVersion);
|
|
77
|
+
if (!migration) {
|
|
78
|
+
throw new Error(`No migration for ${repo} to version ${nextVersion}`);
|
|
79
|
+
}
|
|
80
|
+
await migration(this.client);
|
|
81
|
+
fromVersion = nextVersion;
|
|
82
|
+
}
|
|
83
|
+
if (fromVersion !== startVersion) {
|
|
84
|
+
await this.client.query(
|
|
85
|
+
`insert into ${migrationsTable} (repo, version) values ($1, $2)
|
|
86
|
+
on conflict (repo) do update set version = $2`,
|
|
87
|
+
[repo, targetVer]
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async _load() {
|
|
93
|
+
await this._runMigrations();
|
|
94
|
+
this._cleanup = this._platform.beforeExit(() => {
|
|
95
|
+
void this._destroy();
|
|
96
|
+
});
|
|
97
|
+
for (const cb of this._onLoadCallbacks) cb();
|
|
98
|
+
}
|
|
99
|
+
_save() {
|
|
100
|
+
}
|
|
101
|
+
async _destroy() {
|
|
102
|
+
this._cleanup?.();
|
|
103
|
+
this._cleanup = void 0;
|
|
104
|
+
if (this._autoClose) {
|
|
105
|
+
const fn = this.client.end ?? this.client.release ?? this.client.close;
|
|
106
|
+
if (fn) await fn.call(this.client);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.PostgresStorageDriver = PostgresStorageDriver;
|
package/driver.d.cts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ICorePlatform, MaybePromise, BaseStorageDriver } from '@mtcute/core';
|
|
2
|
+
import { Logger } from '@mtcute/core/utils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Minimal interface for a pg-compatible client.
|
|
5
|
+
* Satisfied by `pg.Pool`, `pg.Client`, and `pg.PoolClient`, as well as `PGlite`.
|
|
6
|
+
*/
|
|
7
|
+
export interface PgClient {
|
|
8
|
+
query<T>(query: string, values?: unknown[]): Promise<{
|
|
9
|
+
rows: T[];
|
|
10
|
+
}>;
|
|
11
|
+
close?(): MaybePromise<void>;
|
|
12
|
+
end?(): MaybePromise<void>;
|
|
13
|
+
release?(): MaybePromise<void>;
|
|
14
|
+
}
|
|
15
|
+
type MigrationFunction = (client: PgClient) => Promise<void>;
|
|
16
|
+
export interface PostgresStorageDriverOptions {
|
|
17
|
+
/**
|
|
18
|
+
* PostgreSQL schema to use for all tables.
|
|
19
|
+
*
|
|
20
|
+
* @default 'mtcute'
|
|
21
|
+
*/
|
|
22
|
+
schema?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether to automatically close the client when the driver is destroyed.
|
|
25
|
+
*
|
|
26
|
+
* @default true
|
|
27
|
+
*/
|
|
28
|
+
autoClose?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare class PostgresStorageDriver extends BaseStorageDriver {
|
|
31
|
+
readonly client: PgClient;
|
|
32
|
+
readonly schema: string;
|
|
33
|
+
private _cleanup?;
|
|
34
|
+
private _migrations;
|
|
35
|
+
private _maxVersion;
|
|
36
|
+
private _onLoadCallbacks;
|
|
37
|
+
private _autoClose;
|
|
38
|
+
constructor(client: PgClient, options?: PostgresStorageDriverOptions);
|
|
39
|
+
/** Returns a schema-qualified table name, safe for interpolation into SQL */
|
|
40
|
+
tableName(name: string): string;
|
|
41
|
+
setup(log: Logger, platform: ICorePlatform): void;
|
|
42
|
+
registerMigration(repo: string, version: number, migration: MigrationFunction): void;
|
|
43
|
+
onLoad(cb: () => void): void;
|
|
44
|
+
private _runMigrations;
|
|
45
|
+
_load(): Promise<void>;
|
|
46
|
+
_save(): void;
|
|
47
|
+
_destroy(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
package/driver.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ICorePlatform, MaybePromise, BaseStorageDriver } from '@mtcute/core';
|
|
2
|
+
import { Logger } from '@mtcute/core/utils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Minimal interface for a pg-compatible client.
|
|
5
|
+
* Satisfied by `pg.Pool`, `pg.Client`, and `pg.PoolClient`, as well as `PGlite`.
|
|
6
|
+
*/
|
|
7
|
+
export interface PgClient {
|
|
8
|
+
query<T>(query: string, values?: unknown[]): Promise<{
|
|
9
|
+
rows: T[];
|
|
10
|
+
}>;
|
|
11
|
+
close?(): MaybePromise<void>;
|
|
12
|
+
end?(): MaybePromise<void>;
|
|
13
|
+
release?(): MaybePromise<void>;
|
|
14
|
+
}
|
|
15
|
+
type MigrationFunction = (client: PgClient) => Promise<void>;
|
|
16
|
+
export interface PostgresStorageDriverOptions {
|
|
17
|
+
/**
|
|
18
|
+
* PostgreSQL schema to use for all tables.
|
|
19
|
+
*
|
|
20
|
+
* @default 'mtcute'
|
|
21
|
+
*/
|
|
22
|
+
schema?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether to automatically close the client when the driver is destroyed.
|
|
25
|
+
*
|
|
26
|
+
* @default true
|
|
27
|
+
*/
|
|
28
|
+
autoClose?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare class PostgresStorageDriver extends BaseStorageDriver {
|
|
31
|
+
readonly client: PgClient;
|
|
32
|
+
readonly schema: string;
|
|
33
|
+
private _cleanup?;
|
|
34
|
+
private _migrations;
|
|
35
|
+
private _maxVersion;
|
|
36
|
+
private _onLoadCallbacks;
|
|
37
|
+
private _autoClose;
|
|
38
|
+
constructor(client: PgClient, options?: PostgresStorageDriverOptions);
|
|
39
|
+
/** Returns a schema-qualified table name, safe for interpolation into SQL */
|
|
40
|
+
tableName(name: string): string;
|
|
41
|
+
setup(log: Logger, platform: ICorePlatform): void;
|
|
42
|
+
registerMigration(repo: string, version: number, migration: MigrationFunction): void;
|
|
43
|
+
onLoad(cb: () => void): void;
|
|
44
|
+
private _runMigrations;
|
|
45
|
+
_load(): Promise<void>;
|
|
46
|
+
_save(): void;
|
|
47
|
+
_destroy(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
package/driver.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { BaseStorageDriver } from "@mtcute/core";
|
|
2
|
+
class PostgresStorageDriver extends BaseStorageDriver {
|
|
3
|
+
client;
|
|
4
|
+
schema;
|
|
5
|
+
_cleanup;
|
|
6
|
+
_migrations = /* @__PURE__ */ new Map();
|
|
7
|
+
_maxVersion = /* @__PURE__ */ new Map();
|
|
8
|
+
_onLoadCallbacks = /* @__PURE__ */ new Set();
|
|
9
|
+
_autoClose = true;
|
|
10
|
+
constructor(client, options) {
|
|
11
|
+
super();
|
|
12
|
+
this.client = client;
|
|
13
|
+
this.schema = options?.schema ?? "mtcute";
|
|
14
|
+
this._autoClose = options?.autoClose ?? true;
|
|
15
|
+
}
|
|
16
|
+
/** Returns a schema-qualified table name, safe for interpolation into SQL */
|
|
17
|
+
tableName(name) {
|
|
18
|
+
return `"${this.schema}"."${name}"`;
|
|
19
|
+
}
|
|
20
|
+
setup(log, platform) {
|
|
21
|
+
super.setup(log, platform);
|
|
22
|
+
this._log = log.create("postgres");
|
|
23
|
+
}
|
|
24
|
+
registerMigration(repo, version, migration) {
|
|
25
|
+
if (this.loaded) {
|
|
26
|
+
throw new Error("Cannot register migrations after loading");
|
|
27
|
+
}
|
|
28
|
+
let map = this._migrations.get(repo);
|
|
29
|
+
if (!map) {
|
|
30
|
+
map = /* @__PURE__ */ new Map();
|
|
31
|
+
this._migrations.set(repo, map);
|
|
32
|
+
}
|
|
33
|
+
if (map.has(version)) {
|
|
34
|
+
throw new Error(`Migration for ${repo} version ${version} is already registered`);
|
|
35
|
+
}
|
|
36
|
+
map.set(version, migration);
|
|
37
|
+
const prevMax = this._maxVersion.get(repo) ?? 0;
|
|
38
|
+
if (version > prevMax) {
|
|
39
|
+
this._maxVersion.set(repo, version);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
onLoad(cb) {
|
|
43
|
+
if (this.loaded) {
|
|
44
|
+
cb();
|
|
45
|
+
} else {
|
|
46
|
+
this._onLoadCallbacks.add(cb);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async _runMigrations() {
|
|
50
|
+
const migrationsTable = this.tableName("migrations");
|
|
51
|
+
await this.client.query(`create schema if not exists "${this.schema}"`);
|
|
52
|
+
await this.client.query(`
|
|
53
|
+
create table if not exists ${migrationsTable} (
|
|
54
|
+
repo text not null primary key,
|
|
55
|
+
version integer not null
|
|
56
|
+
)
|
|
57
|
+
`);
|
|
58
|
+
for (const repo of this._migrations.keys()) {
|
|
59
|
+
const res = await this.client.query(
|
|
60
|
+
`select version from ${migrationsTable} where repo = $1`,
|
|
61
|
+
[repo]
|
|
62
|
+
);
|
|
63
|
+
const startVersion = res.rows[0]?.version ?? 0;
|
|
64
|
+
let fromVersion = startVersion;
|
|
65
|
+
const migrations = this._migrations.get(repo);
|
|
66
|
+
const targetVer = this._maxVersion.get(repo);
|
|
67
|
+
while (fromVersion < targetVer) {
|
|
68
|
+
const nextVersion = fromVersion + 1;
|
|
69
|
+
const migration = migrations.get(nextVersion);
|
|
70
|
+
if (!migration) {
|
|
71
|
+
throw new Error(`No migration for ${repo} to version ${nextVersion}`);
|
|
72
|
+
}
|
|
73
|
+
await migration(this.client);
|
|
74
|
+
fromVersion = nextVersion;
|
|
75
|
+
}
|
|
76
|
+
if (fromVersion !== startVersion) {
|
|
77
|
+
await this.client.query(
|
|
78
|
+
`insert into ${migrationsTable} (repo, version) values ($1, $2)
|
|
79
|
+
on conflict (repo) do update set version = $2`,
|
|
80
|
+
[repo, targetVer]
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async _load() {
|
|
86
|
+
await this._runMigrations();
|
|
87
|
+
this._cleanup = this._platform.beforeExit(() => {
|
|
88
|
+
void this._destroy();
|
|
89
|
+
});
|
|
90
|
+
for (const cb of this._onLoadCallbacks) cb();
|
|
91
|
+
}
|
|
92
|
+
_save() {
|
|
93
|
+
}
|
|
94
|
+
async _destroy() {
|
|
95
|
+
this._cleanup?.();
|
|
96
|
+
this._cleanup = void 0;
|
|
97
|
+
if (this._autoClose) {
|
|
98
|
+
const fn = this.client.end ?? this.client.release ?? this.client.close;
|
|
99
|
+
if (fn) await fn.call(this.client);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
PostgresStorageDriver
|
|
105
|
+
};
|
package/index.cjs
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/postgres] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/postgres] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
const driver = require("./driver.cjs");
|
|
9
|
+
const authKeys = require("./repository/auth-keys.cjs");
|
|
10
|
+
const kv = require("./repository/kv.cjs");
|
|
11
|
+
const peers = require("./repository/peers.cjs");
|
|
12
|
+
const refMessages = require("./repository/ref-messages.cjs");
|
|
13
|
+
class PostgresStorage {
|
|
14
|
+
driver;
|
|
15
|
+
authKeys;
|
|
16
|
+
kv;
|
|
17
|
+
peers;
|
|
18
|
+
refMessages;
|
|
19
|
+
constructor(client, options) {
|
|
20
|
+
this.driver = new driver.PostgresStorageDriver(client, options);
|
|
21
|
+
this.authKeys = new authKeys.PostgresAuthKeysRepository(this.driver);
|
|
22
|
+
this.kv = new kv.PostgresKeyValueRepository(this.driver);
|
|
23
|
+
this.peers = new peers.PostgresPeersRepository(this.driver);
|
|
24
|
+
this.refMessages = new refMessages.PostgresRefMessagesRepository(this.driver);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.PostgresStorageDriver = driver.PostgresStorageDriver;
|
|
28
|
+
exports.PostgresAuthKeysRepository = authKeys.PostgresAuthKeysRepository;
|
|
29
|
+
exports.PostgresKeyValueRepository = kv.PostgresKeyValueRepository;
|
|
30
|
+
exports.PostgresPeersRepository = peers.PostgresPeersRepository;
|
|
31
|
+
exports.PostgresRefMessagesRepository = refMessages.PostgresRefMessagesRepository;
|
|
32
|
+
exports.PostgresStorage = PostgresStorage;
|
package/index.d.cts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IMtStorageProvider, ITelegramStorageProvider } from '@mtcute/core';
|
|
2
|
+
import { PgClient, PostgresStorageDriverOptions, PostgresStorageDriver } from './driver.js';
|
|
3
|
+
import { PostgresAuthKeysRepository } from './repository/auth-keys.js';
|
|
4
|
+
import { PostgresKeyValueRepository } from './repository/kv.js';
|
|
5
|
+
import { PostgresPeersRepository } from './repository/peers.js';
|
|
6
|
+
import { PostgresRefMessagesRepository } from './repository/ref-messages.js';
|
|
7
|
+
export type { PgClient, PostgresStorageDriverOptions } from './driver.js';
|
|
8
|
+
export { PostgresStorageDriver } from './driver.js';
|
|
9
|
+
export { PostgresAuthKeysRepository } from './repository/auth-keys.js';
|
|
10
|
+
export { PostgresKeyValueRepository } from './repository/kv.js';
|
|
11
|
+
export { PostgresPeersRepository } from './repository/peers.js';
|
|
12
|
+
export { PostgresRefMessagesRepository } from './repository/ref-messages.js';
|
|
13
|
+
export declare class PostgresStorage implements IMtStorageProvider, ITelegramStorageProvider {
|
|
14
|
+
readonly driver: PostgresStorageDriver;
|
|
15
|
+
readonly authKeys: PostgresAuthKeysRepository;
|
|
16
|
+
readonly kv: PostgresKeyValueRepository;
|
|
17
|
+
readonly peers: PostgresPeersRepository;
|
|
18
|
+
readonly refMessages: PostgresRefMessagesRepository;
|
|
19
|
+
constructor(client: PgClient, options?: PostgresStorageDriverOptions);
|
|
20
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IMtStorageProvider, ITelegramStorageProvider } from '@mtcute/core';
|
|
2
|
+
import { PgClient, PostgresStorageDriverOptions, PostgresStorageDriver } from './driver.js';
|
|
3
|
+
import { PostgresAuthKeysRepository } from './repository/auth-keys.js';
|
|
4
|
+
import { PostgresKeyValueRepository } from './repository/kv.js';
|
|
5
|
+
import { PostgresPeersRepository } from './repository/peers.js';
|
|
6
|
+
import { PostgresRefMessagesRepository } from './repository/ref-messages.js';
|
|
7
|
+
export type { PgClient, PostgresStorageDriverOptions } from './driver.js';
|
|
8
|
+
export { PostgresStorageDriver } from './driver.js';
|
|
9
|
+
export { PostgresAuthKeysRepository } from './repository/auth-keys.js';
|
|
10
|
+
export { PostgresKeyValueRepository } from './repository/kv.js';
|
|
11
|
+
export { PostgresPeersRepository } from './repository/peers.js';
|
|
12
|
+
export { PostgresRefMessagesRepository } from './repository/ref-messages.js';
|
|
13
|
+
export declare class PostgresStorage implements IMtStorageProvider, ITelegramStorageProvider {
|
|
14
|
+
readonly driver: PostgresStorageDriver;
|
|
15
|
+
readonly authKeys: PostgresAuthKeysRepository;
|
|
16
|
+
readonly kv: PostgresKeyValueRepository;
|
|
17
|
+
readonly peers: PostgresPeersRepository;
|
|
18
|
+
readonly refMessages: PostgresRefMessagesRepository;
|
|
19
|
+
constructor(client: PgClient, options?: PostgresStorageDriverOptions);
|
|
20
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { PostgresStorageDriver } from "./driver.js";
|
|
2
|
+
import { PostgresAuthKeysRepository } from "./repository/auth-keys.js";
|
|
3
|
+
import { PostgresKeyValueRepository } from "./repository/kv.js";
|
|
4
|
+
import { PostgresPeersRepository } from "./repository/peers.js";
|
|
5
|
+
import { PostgresRefMessagesRepository } from "./repository/ref-messages.js";
|
|
6
|
+
class PostgresStorage {
|
|
7
|
+
driver;
|
|
8
|
+
authKeys;
|
|
9
|
+
kv;
|
|
10
|
+
peers;
|
|
11
|
+
refMessages;
|
|
12
|
+
constructor(client, options) {
|
|
13
|
+
this.driver = new PostgresStorageDriver(client, options);
|
|
14
|
+
this.authKeys = new PostgresAuthKeysRepository(this.driver);
|
|
15
|
+
this.kv = new PostgresKeyValueRepository(this.driver);
|
|
16
|
+
this.peers = new PostgresPeersRepository(this.driver);
|
|
17
|
+
this.refMessages = new PostgresRefMessagesRepository(this.driver);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
PostgresAuthKeysRepository,
|
|
22
|
+
PostgresKeyValueRepository,
|
|
23
|
+
PostgresPeersRepository,
|
|
24
|
+
PostgresRefMessagesRepository,
|
|
25
|
+
PostgresStorage,
|
|
26
|
+
PostgresStorageDriver
|
|
27
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mtcute/postgres",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.29.1",
|
|
5
|
+
"description": "PostgreSQL storage for mtcute",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@mtcute/core": "^0.29.1"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"default": "./index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./index.d.cts",
|
|
18
|
+
"default": "./index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"author": "alina sireneva <alina@tei.su>",
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"homepage": "https://mtcute.dev",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/mtcute/mtcute.git"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {}
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/postgres] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/postgres] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
class PostgresAuthKeysRepository {
|
|
9
|
+
constructor(_driver) {
|
|
10
|
+
this._driver = _driver;
|
|
11
|
+
this._authKeys = _driver.tableName("auth_keys");
|
|
12
|
+
this._tempAuthKeys = _driver.tableName("temp_auth_keys");
|
|
13
|
+
_driver.registerMigration("auth_keys", 1, async (client) => {
|
|
14
|
+
await client.query(`
|
|
15
|
+
create table if not exists ${this._authKeys} (
|
|
16
|
+
dc integer primary key,
|
|
17
|
+
key bytea not null
|
|
18
|
+
);
|
|
19
|
+
`);
|
|
20
|
+
await client.query(`
|
|
21
|
+
create table if not exists ${this._tempAuthKeys} (
|
|
22
|
+
dc integer not null,
|
|
23
|
+
idx integer not null,
|
|
24
|
+
key bytea not null,
|
|
25
|
+
expires integer not null,
|
|
26
|
+
primary key (dc, idx)
|
|
27
|
+
);
|
|
28
|
+
`);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
_authKeys;
|
|
32
|
+
_tempAuthKeys;
|
|
33
|
+
async set(dc, key) {
|
|
34
|
+
if (!key) {
|
|
35
|
+
await this._driver.client.query(`delete from ${this._authKeys} where dc = $1`, [dc]);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
await this._driver.client.query(
|
|
39
|
+
`insert into ${this._authKeys} (dc, key) values ($1, $2) on conflict (dc) do update set key = $2`,
|
|
40
|
+
[dc, key]
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
async get(dc) {
|
|
44
|
+
const res = await this._driver.client.query(`select key from ${this._authKeys} where dc = $1`, [dc]);
|
|
45
|
+
if (!res.rows[0]) return null;
|
|
46
|
+
return new Uint8Array(res.rows[0].key);
|
|
47
|
+
}
|
|
48
|
+
async setTemp(dc, idx, key, expires) {
|
|
49
|
+
if (!key) {
|
|
50
|
+
await this._driver.client.query(
|
|
51
|
+
`delete from ${this._tempAuthKeys} where dc = $1 and idx = $2`,
|
|
52
|
+
[dc, idx]
|
|
53
|
+
);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
await this._driver.client.query(
|
|
57
|
+
`insert into ${this._tempAuthKeys} (dc, idx, key, expires) values ($1, $2, $3, $4)
|
|
58
|
+
on conflict (dc, idx) do update set key = $3, expires = $4`,
|
|
59
|
+
[dc, idx, key, expires]
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
async getTemp(dc, idx, now) {
|
|
63
|
+
const res = await this._driver.client.query(
|
|
64
|
+
`select key from ${this._tempAuthKeys} where dc = $1 and idx = $2 and expires > $3`,
|
|
65
|
+
[dc, idx, now]
|
|
66
|
+
);
|
|
67
|
+
if (!res.rows[0]) return null;
|
|
68
|
+
return new Uint8Array(res.rows[0].key);
|
|
69
|
+
}
|
|
70
|
+
async deleteByDc(dc) {
|
|
71
|
+
await this._driver.client.query(`delete from ${this._authKeys} where dc = $1`, [dc]);
|
|
72
|
+
await this._driver.client.query(`delete from ${this._tempAuthKeys} where dc = $1`, [dc]);
|
|
73
|
+
}
|
|
74
|
+
async deleteAll() {
|
|
75
|
+
await this._driver.client.query(`delete from ${this._authKeys}`);
|
|
76
|
+
await this._driver.client.query(`delete from ${this._tempAuthKeys}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.PostgresAuthKeysRepository = PostgresAuthKeysRepository;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IAuthKeysRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresAuthKeysRepository implements IAuthKeysRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _authKeys;
|
|
6
|
+
private _tempAuthKeys;
|
|
7
|
+
constructor(_driver: PostgresStorageDriver);
|
|
8
|
+
set(dc: number, key: Uint8Array | null): Promise<void>;
|
|
9
|
+
get(dc: number): Promise<Uint8Array | null>;
|
|
10
|
+
setTemp(dc: number, idx: number, key: Uint8Array | null, expires: number): Promise<void>;
|
|
11
|
+
getTemp(dc: number, idx: number, now: number): Promise<Uint8Array | null>;
|
|
12
|
+
deleteByDc(dc: number): Promise<void>;
|
|
13
|
+
deleteAll(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IAuthKeysRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresAuthKeysRepository implements IAuthKeysRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _authKeys;
|
|
6
|
+
private _tempAuthKeys;
|
|
7
|
+
constructor(_driver: PostgresStorageDriver);
|
|
8
|
+
set(dc: number, key: Uint8Array | null): Promise<void>;
|
|
9
|
+
get(dc: number): Promise<Uint8Array | null>;
|
|
10
|
+
setTemp(dc: number, idx: number, key: Uint8Array | null, expires: number): Promise<void>;
|
|
11
|
+
getTemp(dc: number, idx: number, now: number): Promise<Uint8Array | null>;
|
|
12
|
+
deleteByDc(dc: number): Promise<void>;
|
|
13
|
+
deleteAll(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
class PostgresAuthKeysRepository {
|
|
2
|
+
constructor(_driver) {
|
|
3
|
+
this._driver = _driver;
|
|
4
|
+
this._authKeys = _driver.tableName("auth_keys");
|
|
5
|
+
this._tempAuthKeys = _driver.tableName("temp_auth_keys");
|
|
6
|
+
_driver.registerMigration("auth_keys", 1, async (client) => {
|
|
7
|
+
await client.query(`
|
|
8
|
+
create table if not exists ${this._authKeys} (
|
|
9
|
+
dc integer primary key,
|
|
10
|
+
key bytea not null
|
|
11
|
+
);
|
|
12
|
+
`);
|
|
13
|
+
await client.query(`
|
|
14
|
+
create table if not exists ${this._tempAuthKeys} (
|
|
15
|
+
dc integer not null,
|
|
16
|
+
idx integer not null,
|
|
17
|
+
key bytea not null,
|
|
18
|
+
expires integer not null,
|
|
19
|
+
primary key (dc, idx)
|
|
20
|
+
);
|
|
21
|
+
`);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
_authKeys;
|
|
25
|
+
_tempAuthKeys;
|
|
26
|
+
async set(dc, key) {
|
|
27
|
+
if (!key) {
|
|
28
|
+
await this._driver.client.query(`delete from ${this._authKeys} where dc = $1`, [dc]);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
await this._driver.client.query(
|
|
32
|
+
`insert into ${this._authKeys} (dc, key) values ($1, $2) on conflict (dc) do update set key = $2`,
|
|
33
|
+
[dc, key]
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
async get(dc) {
|
|
37
|
+
const res = await this._driver.client.query(`select key from ${this._authKeys} where dc = $1`, [dc]);
|
|
38
|
+
if (!res.rows[0]) return null;
|
|
39
|
+
return new Uint8Array(res.rows[0].key);
|
|
40
|
+
}
|
|
41
|
+
async setTemp(dc, idx, key, expires) {
|
|
42
|
+
if (!key) {
|
|
43
|
+
await this._driver.client.query(
|
|
44
|
+
`delete from ${this._tempAuthKeys} where dc = $1 and idx = $2`,
|
|
45
|
+
[dc, idx]
|
|
46
|
+
);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
await this._driver.client.query(
|
|
50
|
+
`insert into ${this._tempAuthKeys} (dc, idx, key, expires) values ($1, $2, $3, $4)
|
|
51
|
+
on conflict (dc, idx) do update set key = $3, expires = $4`,
|
|
52
|
+
[dc, idx, key, expires]
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
async getTemp(dc, idx, now) {
|
|
56
|
+
const res = await this._driver.client.query(
|
|
57
|
+
`select key from ${this._tempAuthKeys} where dc = $1 and idx = $2 and expires > $3`,
|
|
58
|
+
[dc, idx, now]
|
|
59
|
+
);
|
|
60
|
+
if (!res.rows[0]) return null;
|
|
61
|
+
return new Uint8Array(res.rows[0].key);
|
|
62
|
+
}
|
|
63
|
+
async deleteByDc(dc) {
|
|
64
|
+
await this._driver.client.query(`delete from ${this._authKeys} where dc = $1`, [dc]);
|
|
65
|
+
await this._driver.client.query(`delete from ${this._tempAuthKeys} where dc = $1`, [dc]);
|
|
66
|
+
}
|
|
67
|
+
async deleteAll() {
|
|
68
|
+
await this._driver.client.query(`delete from ${this._authKeys}`);
|
|
69
|
+
await this._driver.client.query(`delete from ${this._tempAuthKeys}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
PostgresAuthKeysRepository
|
|
74
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/postgres] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/postgres] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
class PostgresKeyValueRepository {
|
|
9
|
+
constructor(_driver) {
|
|
10
|
+
this._driver = _driver;
|
|
11
|
+
this._table = _driver.tableName("key_value");
|
|
12
|
+
_driver.registerMigration("kv", 1, async (client) => {
|
|
13
|
+
await client.query(`
|
|
14
|
+
create table if not exists ${this._table} (
|
|
15
|
+
key text primary key,
|
|
16
|
+
value bytea not null
|
|
17
|
+
);
|
|
18
|
+
`);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
_table;
|
|
22
|
+
async set(key, value) {
|
|
23
|
+
await this._driver.client.query(
|
|
24
|
+
`insert into ${this._table} (key, value) values ($1, $2) on conflict (key) do update set value = $2`,
|
|
25
|
+
[key, value]
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
async get(key) {
|
|
29
|
+
const res = await this._driver.client.query(`select value from ${this._table} where key = $1`, [key]);
|
|
30
|
+
if (!res.rows[0]) return null;
|
|
31
|
+
return new Uint8Array(res.rows[0].value);
|
|
32
|
+
}
|
|
33
|
+
async delete(key) {
|
|
34
|
+
await this._driver.client.query(`delete from ${this._table} where key = $1`, [key]);
|
|
35
|
+
}
|
|
36
|
+
async deleteAll() {
|
|
37
|
+
await this._driver.client.query(`delete from ${this._table}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.PostgresKeyValueRepository = PostgresKeyValueRepository;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IKeyValueRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresKeyValueRepository implements IKeyValueRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _table;
|
|
6
|
+
constructor(_driver: PostgresStorageDriver);
|
|
7
|
+
set(key: string, value: Uint8Array): Promise<void>;
|
|
8
|
+
get(key: string): Promise<Uint8Array | null>;
|
|
9
|
+
delete(key: string): Promise<void>;
|
|
10
|
+
deleteAll(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IKeyValueRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresKeyValueRepository implements IKeyValueRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _table;
|
|
6
|
+
constructor(_driver: PostgresStorageDriver);
|
|
7
|
+
set(key: string, value: Uint8Array): Promise<void>;
|
|
8
|
+
get(key: string): Promise<Uint8Array | null>;
|
|
9
|
+
delete(key: string): Promise<void>;
|
|
10
|
+
deleteAll(): Promise<void>;
|
|
11
|
+
}
|
package/repository/kv.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class PostgresKeyValueRepository {
|
|
2
|
+
constructor(_driver) {
|
|
3
|
+
this._driver = _driver;
|
|
4
|
+
this._table = _driver.tableName("key_value");
|
|
5
|
+
_driver.registerMigration("kv", 1, async (client) => {
|
|
6
|
+
await client.query(`
|
|
7
|
+
create table if not exists ${this._table} (
|
|
8
|
+
key text primary key,
|
|
9
|
+
value bytea not null
|
|
10
|
+
);
|
|
11
|
+
`);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
_table;
|
|
15
|
+
async set(key, value) {
|
|
16
|
+
await this._driver.client.query(
|
|
17
|
+
`insert into ${this._table} (key, value) values ($1, $2) on conflict (key) do update set value = $2`,
|
|
18
|
+
[key, value]
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
async get(key) {
|
|
22
|
+
const res = await this._driver.client.query(`select value from ${this._table} where key = $1`, [key]);
|
|
23
|
+
if (!res.rows[0]) return null;
|
|
24
|
+
return new Uint8Array(res.rows[0].value);
|
|
25
|
+
}
|
|
26
|
+
async delete(key) {
|
|
27
|
+
await this._driver.client.query(`delete from ${this._table} where key = $1`, [key]);
|
|
28
|
+
}
|
|
29
|
+
async deleteAll() {
|
|
30
|
+
await this._driver.client.query(`delete from ${this._table}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
PostgresKeyValueRepository
|
|
35
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/postgres] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/postgres] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
const core = require("@mtcute/core");
|
|
9
|
+
const _utils = require("../_utils.cjs");
|
|
10
|
+
function mapPeerDto(dto) {
|
|
11
|
+
return {
|
|
12
|
+
id: Number(dto.id),
|
|
13
|
+
accessHash: dto.hash,
|
|
14
|
+
isMin: dto.is_min,
|
|
15
|
+
usernames: _utils.parseJsonb(dto.usernames),
|
|
16
|
+
updated: _utils.parseBigint(dto.updated),
|
|
17
|
+
phone: dto.phone || void 0,
|
|
18
|
+
complete: new Uint8Array(dto.complete)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
class PostgresPeersRepository {
|
|
22
|
+
constructor(_driver) {
|
|
23
|
+
this._driver = _driver;
|
|
24
|
+
this._table = _driver.tableName("peers");
|
|
25
|
+
_driver.registerMigration("peers", 1, async (client) => {
|
|
26
|
+
await client.query(`
|
|
27
|
+
create table if not exists ${this._table} (
|
|
28
|
+
id bigint primary key,
|
|
29
|
+
hash text not null,
|
|
30
|
+
is_min boolean not null default false,
|
|
31
|
+
usernames jsonb not null,
|
|
32
|
+
updated bigint not null,
|
|
33
|
+
phone text,
|
|
34
|
+
complete bytea
|
|
35
|
+
);
|
|
36
|
+
`);
|
|
37
|
+
await client.query(`
|
|
38
|
+
create index if not exists idx_peers_phone on ${this._table} (phone);
|
|
39
|
+
`);
|
|
40
|
+
});
|
|
41
|
+
_driver.onLoad(() => {
|
|
42
|
+
this._loaded = true;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
_loaded = false;
|
|
46
|
+
_table;
|
|
47
|
+
_ensureLoaded() {
|
|
48
|
+
if (!this._loaded) {
|
|
49
|
+
throw new core.MtcuteError("Peers repository is not loaded. Have you called client.start() (or similar)?");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async store(peer) {
|
|
53
|
+
await this._driver.client.query(
|
|
54
|
+
`insert into ${this._table} (id, hash, is_min, usernames, updated, phone, complete)
|
|
55
|
+
values ($1, $2, $3, $4, $5, $6, $7)
|
|
56
|
+
on conflict (id) do update set
|
|
57
|
+
hash = $2, is_min = $3, usernames = $4, updated = $5, phone = $6, complete = $7`,
|
|
58
|
+
[
|
|
59
|
+
peer.id,
|
|
60
|
+
peer.accessHash,
|
|
61
|
+
peer.isMin,
|
|
62
|
+
JSON.stringify(peer.usernames),
|
|
63
|
+
peer.updated,
|
|
64
|
+
peer.phone ?? null,
|
|
65
|
+
peer.complete
|
|
66
|
+
]
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
async getById(id) {
|
|
70
|
+
this._ensureLoaded();
|
|
71
|
+
const res = await this._driver.client.query(`select * from ${this._table} where id = $1`, [id]);
|
|
72
|
+
if (!res.rows[0]) return null;
|
|
73
|
+
return mapPeerDto(res.rows[0]);
|
|
74
|
+
}
|
|
75
|
+
async getByUsername(username) {
|
|
76
|
+
this._ensureLoaded();
|
|
77
|
+
const res = await this._driver.client.query(
|
|
78
|
+
`select * from ${this._table} where usernames ? $1 and is_min = false`,
|
|
79
|
+
[username]
|
|
80
|
+
);
|
|
81
|
+
if (!res.rows[0]) return null;
|
|
82
|
+
return mapPeerDto(res.rows[0]);
|
|
83
|
+
}
|
|
84
|
+
async getByPhone(phone) {
|
|
85
|
+
this._ensureLoaded();
|
|
86
|
+
const res = await this._driver.client.query(
|
|
87
|
+
`select * from ${this._table} where phone = $1 and is_min = false`,
|
|
88
|
+
[phone]
|
|
89
|
+
);
|
|
90
|
+
if (!res.rows[0]) return null;
|
|
91
|
+
return mapPeerDto(res.rows[0]);
|
|
92
|
+
}
|
|
93
|
+
async deleteAll() {
|
|
94
|
+
await this._driver.client.query(`delete from ${this._table}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.PostgresPeersRepository = PostgresPeersRepository;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IPeersRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresPeersRepository implements IPeersRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _loaded;
|
|
6
|
+
private _table;
|
|
7
|
+
constructor(_driver: PostgresStorageDriver);
|
|
8
|
+
private _ensureLoaded;
|
|
9
|
+
store(peer: IPeersRepository.PeerInfo): Promise<void>;
|
|
10
|
+
getById(id: number): Promise<IPeersRepository.PeerInfo | null>;
|
|
11
|
+
getByUsername(username: string): Promise<IPeersRepository.PeerInfo | null>;
|
|
12
|
+
getByPhone(phone: string): Promise<IPeersRepository.PeerInfo | null>;
|
|
13
|
+
deleteAll(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IPeersRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresPeersRepository implements IPeersRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _loaded;
|
|
6
|
+
private _table;
|
|
7
|
+
constructor(_driver: PostgresStorageDriver);
|
|
8
|
+
private _ensureLoaded;
|
|
9
|
+
store(peer: IPeersRepository.PeerInfo): Promise<void>;
|
|
10
|
+
getById(id: number): Promise<IPeersRepository.PeerInfo | null>;
|
|
11
|
+
getByUsername(username: string): Promise<IPeersRepository.PeerInfo | null>;
|
|
12
|
+
getByPhone(phone: string): Promise<IPeersRepository.PeerInfo | null>;
|
|
13
|
+
deleteAll(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { MtcuteError } from "@mtcute/core";
|
|
2
|
+
import { parseBigint, parseJsonb } from "../_utils.js";
|
|
3
|
+
function mapPeerDto(dto) {
|
|
4
|
+
return {
|
|
5
|
+
id: Number(dto.id),
|
|
6
|
+
accessHash: dto.hash,
|
|
7
|
+
isMin: dto.is_min,
|
|
8
|
+
usernames: parseJsonb(dto.usernames),
|
|
9
|
+
updated: parseBigint(dto.updated),
|
|
10
|
+
phone: dto.phone || void 0,
|
|
11
|
+
complete: new Uint8Array(dto.complete)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
class PostgresPeersRepository {
|
|
15
|
+
constructor(_driver) {
|
|
16
|
+
this._driver = _driver;
|
|
17
|
+
this._table = _driver.tableName("peers");
|
|
18
|
+
_driver.registerMigration("peers", 1, async (client) => {
|
|
19
|
+
await client.query(`
|
|
20
|
+
create table if not exists ${this._table} (
|
|
21
|
+
id bigint primary key,
|
|
22
|
+
hash text not null,
|
|
23
|
+
is_min boolean not null default false,
|
|
24
|
+
usernames jsonb not null,
|
|
25
|
+
updated bigint not null,
|
|
26
|
+
phone text,
|
|
27
|
+
complete bytea
|
|
28
|
+
);
|
|
29
|
+
`);
|
|
30
|
+
await client.query(`
|
|
31
|
+
create index if not exists idx_peers_phone on ${this._table} (phone);
|
|
32
|
+
`);
|
|
33
|
+
});
|
|
34
|
+
_driver.onLoad(() => {
|
|
35
|
+
this._loaded = true;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
_loaded = false;
|
|
39
|
+
_table;
|
|
40
|
+
_ensureLoaded() {
|
|
41
|
+
if (!this._loaded) {
|
|
42
|
+
throw new MtcuteError("Peers repository is not loaded. Have you called client.start() (or similar)?");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async store(peer) {
|
|
46
|
+
await this._driver.client.query(
|
|
47
|
+
`insert into ${this._table} (id, hash, is_min, usernames, updated, phone, complete)
|
|
48
|
+
values ($1, $2, $3, $4, $5, $6, $7)
|
|
49
|
+
on conflict (id) do update set
|
|
50
|
+
hash = $2, is_min = $3, usernames = $4, updated = $5, phone = $6, complete = $7`,
|
|
51
|
+
[
|
|
52
|
+
peer.id,
|
|
53
|
+
peer.accessHash,
|
|
54
|
+
peer.isMin,
|
|
55
|
+
JSON.stringify(peer.usernames),
|
|
56
|
+
peer.updated,
|
|
57
|
+
peer.phone ?? null,
|
|
58
|
+
peer.complete
|
|
59
|
+
]
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
async getById(id) {
|
|
63
|
+
this._ensureLoaded();
|
|
64
|
+
const res = await this._driver.client.query(`select * from ${this._table} where id = $1`, [id]);
|
|
65
|
+
if (!res.rows[0]) return null;
|
|
66
|
+
return mapPeerDto(res.rows[0]);
|
|
67
|
+
}
|
|
68
|
+
async getByUsername(username) {
|
|
69
|
+
this._ensureLoaded();
|
|
70
|
+
const res = await this._driver.client.query(
|
|
71
|
+
`select * from ${this._table} where usernames ? $1 and is_min = false`,
|
|
72
|
+
[username]
|
|
73
|
+
);
|
|
74
|
+
if (!res.rows[0]) return null;
|
|
75
|
+
return mapPeerDto(res.rows[0]);
|
|
76
|
+
}
|
|
77
|
+
async getByPhone(phone) {
|
|
78
|
+
this._ensureLoaded();
|
|
79
|
+
const res = await this._driver.client.query(
|
|
80
|
+
`select * from ${this._table} where phone = $1 and is_min = false`,
|
|
81
|
+
[phone]
|
|
82
|
+
);
|
|
83
|
+
if (!res.rows[0]) return null;
|
|
84
|
+
return mapPeerDto(res.rows[0]);
|
|
85
|
+
}
|
|
86
|
+
async deleteAll() {
|
|
87
|
+
await this._driver.client.query(`delete from ${this._table}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
PostgresPeersRepository
|
|
92
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/postgres] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/postgres] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
const _utils = require("../_utils.cjs");
|
|
9
|
+
class PostgresRefMessagesRepository {
|
|
10
|
+
constructor(_driver) {
|
|
11
|
+
this._driver = _driver;
|
|
12
|
+
this._table = _driver.tableName("message_refs");
|
|
13
|
+
_driver.registerMigration("ref_messages", 1, async (client) => {
|
|
14
|
+
await client.query(`
|
|
15
|
+
create table if not exists ${this._table} (
|
|
16
|
+
peer_id bigint not null,
|
|
17
|
+
chat_id bigint not null,
|
|
18
|
+
msg_id integer not null
|
|
19
|
+
);
|
|
20
|
+
`);
|
|
21
|
+
await client.query(`create index if not exists idx_message_refs_peer on ${this._table} (peer_id);`);
|
|
22
|
+
await client.query(`create index if not exists idx_message_refs on ${this._table} (chat_id, msg_id);`);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
_table;
|
|
26
|
+
async store(peerId, chatId, msgId) {
|
|
27
|
+
await this._driver.client.query(
|
|
28
|
+
`insert into ${this._table} (peer_id, chat_id, msg_id) values ($1, $2, $3)`,
|
|
29
|
+
[peerId, chatId, msgId]
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
async getByPeer(peerId) {
|
|
33
|
+
const res = await this._driver.client.query(
|
|
34
|
+
`select chat_id, msg_id from ${this._table} where peer_id = $1 limit 1`,
|
|
35
|
+
[peerId]
|
|
36
|
+
);
|
|
37
|
+
if (!res.rows[0]) return null;
|
|
38
|
+
const row = res.rows[0];
|
|
39
|
+
return [_utils.parseBigint(row.chat_id), row.msg_id];
|
|
40
|
+
}
|
|
41
|
+
async delete(chatId, msgIds) {
|
|
42
|
+
if (msgIds.length === 0) return;
|
|
43
|
+
await this._driver.client.query(
|
|
44
|
+
`delete from ${this._table} where chat_id = $1 and msg_id = any($2)`,
|
|
45
|
+
[chatId, msgIds]
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
async deleteByPeer(peerId) {
|
|
49
|
+
await this._driver.client.query(`delete from ${this._table} where peer_id = $1`, [peerId]);
|
|
50
|
+
}
|
|
51
|
+
async deleteAll() {
|
|
52
|
+
await this._driver.client.query(`delete from ${this._table}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.PostgresRefMessagesRepository = PostgresRefMessagesRepository;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IReferenceMessagesRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresRefMessagesRepository implements IReferenceMessagesRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _table;
|
|
6
|
+
constructor(_driver: PostgresStorageDriver);
|
|
7
|
+
store(peerId: number, chatId: number, msgId: number): Promise<void>;
|
|
8
|
+
getByPeer(peerId: number): Promise<[number, number] | null>;
|
|
9
|
+
delete(chatId: number, msgIds: number[]): Promise<void>;
|
|
10
|
+
deleteByPeer(peerId: number): Promise<void>;
|
|
11
|
+
deleteAll(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IReferenceMessagesRepository } from '@mtcute/core';
|
|
2
|
+
import { PostgresStorageDriver } from '../driver.js';
|
|
3
|
+
export declare class PostgresRefMessagesRepository implements IReferenceMessagesRepository {
|
|
4
|
+
readonly _driver: PostgresStorageDriver;
|
|
5
|
+
private _table;
|
|
6
|
+
constructor(_driver: PostgresStorageDriver);
|
|
7
|
+
store(peerId: number, chatId: number, msgId: number): Promise<void>;
|
|
8
|
+
getByPeer(peerId: number): Promise<[number, number] | null>;
|
|
9
|
+
delete(chatId: number, msgIds: number[]): Promise<void>;
|
|
10
|
+
deleteByPeer(peerId: number): Promise<void>;
|
|
11
|
+
deleteAll(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { parseBigint } from "../_utils.js";
|
|
2
|
+
class PostgresRefMessagesRepository {
|
|
3
|
+
constructor(_driver) {
|
|
4
|
+
this._driver = _driver;
|
|
5
|
+
this._table = _driver.tableName("message_refs");
|
|
6
|
+
_driver.registerMigration("ref_messages", 1, async (client) => {
|
|
7
|
+
await client.query(`
|
|
8
|
+
create table if not exists ${this._table} (
|
|
9
|
+
peer_id bigint not null,
|
|
10
|
+
chat_id bigint not null,
|
|
11
|
+
msg_id integer not null
|
|
12
|
+
);
|
|
13
|
+
`);
|
|
14
|
+
await client.query(`create index if not exists idx_message_refs_peer on ${this._table} (peer_id);`);
|
|
15
|
+
await client.query(`create index if not exists idx_message_refs on ${this._table} (chat_id, msg_id);`);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
_table;
|
|
19
|
+
async store(peerId, chatId, msgId) {
|
|
20
|
+
await this._driver.client.query(
|
|
21
|
+
`insert into ${this._table} (peer_id, chat_id, msg_id) values ($1, $2, $3)`,
|
|
22
|
+
[peerId, chatId, msgId]
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
async getByPeer(peerId) {
|
|
26
|
+
const res = await this._driver.client.query(
|
|
27
|
+
`select chat_id, msg_id from ${this._table} where peer_id = $1 limit 1`,
|
|
28
|
+
[peerId]
|
|
29
|
+
);
|
|
30
|
+
if (!res.rows[0]) return null;
|
|
31
|
+
const row = res.rows[0];
|
|
32
|
+
return [parseBigint(row.chat_id), row.msg_id];
|
|
33
|
+
}
|
|
34
|
+
async delete(chatId, msgIds) {
|
|
35
|
+
if (msgIds.length === 0) return;
|
|
36
|
+
await this._driver.client.query(
|
|
37
|
+
`delete from ${this._table} where chat_id = $1 and msg_id = any($2)`,
|
|
38
|
+
[chatId, msgIds]
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
async deleteByPeer(peerId) {
|
|
42
|
+
await this._driver.client.query(`delete from ${this._table} where peer_id = $1`, [peerId]);
|
|
43
|
+
}
|
|
44
|
+
async deleteAll() {
|
|
45
|
+
await this._driver.client.query(`delete from ${this._table}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
PostgresRefMessagesRepository
|
|
50
|
+
};
|