@undefineds.co/xpod 0.3.25 → 0.3.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/config/cloud.json +6 -5
- package/config/main.json +0 -3
- package/config/xpod.base.json +0 -32
- package/dist/api/container/index.js +3 -0
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/routes.js +2 -0
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +5 -0
- package/dist/api/container/types.js.map +1 -1
- package/dist/authorization/AuthMode.d.ts +8 -0
- package/dist/authorization/AuthMode.js +51 -0
- package/dist/authorization/AuthMode.js.map +1 -0
- package/dist/authorization/PodAuthorizationResources.d.ts +18 -0
- package/dist/authorization/PodAuthorizationResources.js +108 -0
- package/dist/authorization/PodAuthorizationResources.js.map +1 -0
- package/dist/cli/commands/start.js +11 -2
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/components/components.jsonld +3 -2
- package/dist/components/context.jsonld +115 -14
- package/dist/index.d.ts +5 -3
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/main.js +11 -2
- package/dist/main.js.map +1 -1
- package/dist/provision/LocalPodProvisioningService.d.ts +6 -2
- package/dist/provision/LocalPodProvisioningService.js +36 -33
- package/dist/provision/LocalPodProvisioningService.js.map +1 -1
- package/dist/provision/LocalPodProvisioningService.jsonld +65 -8
- package/dist/runtime/XpodRuntime.js +0 -1
- package/dist/runtime/XpodRuntime.js.map +1 -1
- package/dist/runtime/bootstrap.d.ts +4 -2
- package/dist/runtime/bootstrap.js +43 -11
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/css-process.d.ts +6 -1
- package/dist/runtime/css-process.js +18 -6
- package/dist/runtime/css-process.js.map +1 -1
- package/dist/runtime/lifecycle.d.ts +2 -3
- package/dist/runtime/lifecycle.js +2 -2
- package/dist/runtime/lifecycle.js.map +1 -1
- package/dist/runtime/runtime-types.d.ts +2 -1
- package/dist/runtime/runtime-types.js.map +1 -1
- package/dist/storage/accessors/SolidRdfDataAccessor.d.ts +2 -3
- package/dist/storage/accessors/SolidRdfDataAccessor.js +48 -42
- package/dist/storage/accessors/SolidRdfDataAccessor.js.map +1 -1
- package/dist/storage/accessors/SolidRdfDataAccessor.jsonld +1 -1
- package/dist/storage/keyvalue/BaseKeyValueStorage.d.ts +33 -0
- package/dist/storage/keyvalue/BaseKeyValueStorage.js +106 -0
- package/dist/storage/keyvalue/BaseKeyValueStorage.js.map +1 -0
- package/dist/storage/keyvalue/BaseKeyValueStorage.jsonld +177 -0
- package/dist/storage/keyvalue/PostgresKeyValueStorage.d.ts +9 -18
- package/dist/storage/keyvalue/PostgresKeyValueStorage.js +24 -96
- package/dist/storage/keyvalue/PostgresKeyValueStorage.js.map +1 -1
- package/dist/storage/keyvalue/PostgresKeyValueStorage.jsonld +15 -58
- package/dist/storage/keyvalue/SqliteKeyValueStorage.d.ts +9 -15
- package/dist/storage/keyvalue/SqliteKeyValueStorage.js +36 -104
- package/dist/storage/keyvalue/SqliteKeyValueStorage.js.map +1 -1
- package/dist/storage/keyvalue/SqliteKeyValueStorage.jsonld +21 -52
- package/dist/storage/quint/BaseQuintStore.d.ts +4 -1
- package/dist/storage/quint/BaseQuintStore.js +59 -46
- package/dist/storage/quint/BaseQuintStore.js.map +1 -1
- package/dist/storage/quint/PgQuintStore.d.ts +4 -3
- package/dist/storage/quint/PgQuintStore.js.map +1 -1
- package/dist/storage/quint/SqliteQuintStore.d.ts +43 -54
- package/dist/storage/quint/SqliteQuintStore.js +197 -520
- package/dist/storage/quint/SqliteQuintStore.js.map +1 -1
- package/dist/storage/quint/SqliteQuintStore.jsonld +38 -86
- package/dist/storage/rdf/PostgresRdfEngine.d.ts +118 -0
- package/dist/storage/rdf/PostgresRdfEngine.js +2609 -0
- package/dist/storage/rdf/PostgresRdfEngine.js.map +1 -0
- package/dist/storage/rdf/PostgresRdfEngine.jsonld +657 -0
- package/dist/storage/rdf/SolidRdfEngine.d.ts +2 -2
- package/dist/storage/rdf/SolidRdfEngine.js.map +1 -1
- package/dist/storage/rdf/SolidRdfEngine.jsonld +3 -0
- package/dist/storage/rdf/SolidRdfSparqlEngine.d.ts +3 -3
- package/dist/storage/rdf/SolidRdfSparqlEngine.js +20 -20
- package/dist/storage/rdf/SolidRdfSparqlEngine.js.map +1 -1
- package/dist/storage/rdf/SolidRdfSparqlEngine.jsonld +1 -1
- package/dist/storage/rdf/index.d.ts +2 -1
- package/dist/storage/rdf/index.js +3 -1
- package/dist/storage/rdf/index.js.map +1 -1
- package/dist/storage/rdf/types.d.ts +19 -0
- package/dist/storage/rdf/types.js.map +1 -1
- package/dist/storage/rdf/types.jsonld +115 -0
- package/package.json +2 -2
- package/config/runtime-open.json +0 -22
- package/dist/authorization/AuthModeSelector.d.ts +0 -10
- package/dist/authorization/AuthModeSelector.js +0 -27
- package/dist/authorization/AuthModeSelector.js.map +0 -1
- package/dist/authorization/AuthModeSelector.jsonld +0 -81
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseKeyValueStorage.js","sourceRoot":"","sources":["../../../src/storage/keyvalue/BaseKeyValueStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Finalizable,\n Initializable,\n KeyValueStorage,\n} from '@solid/community-server';\nimport { getLoggerFor } from 'global-logger-factory';\n\nexport interface BaseKeyValueStorageOptions {\n tableName?: string;\n namespace?: string;\n}\n\nexport interface BaseKeyValueStorageRow {\n key: string;\n value: unknown;\n}\n\nexport abstract class BaseKeyValueStorage<T = unknown> implements\n KeyValueStorage<string, T>,\n Initializable,\n Finalizable {\n protected readonly logger = getLoggerFor(this);\n protected readonly tableName: string;\n protected readonly namespace: string;\n\n private ready: Promise<void> = Promise.resolve();\n\n protected constructor(options: BaseKeyValueStorageOptions) {\n this.tableName = options.tableName ?? 'internal_kv';\n this.namespace = options.namespace ?? '';\n assertIdentifier(this.tableName);\n }\n\n protected setReady(ready: Promise<void>): void {\n this.ready = ready;\n }\n\n public async initialize(): Promise<void> {\n await this.ready;\n }\n\n public async finalize(): Promise<void> {\n await this.ready;\n await this.closeStorage();\n }\n\n public async has(key: string): Promise<boolean> {\n await this.ready;\n return this.hasValue(this.toStorageKey(key));\n }\n\n public async get(key: string): Promise<T | undefined> {\n await this.ready;\n const raw = await this.selectValue(this.toStorageKey(key));\n if (typeof raw === 'undefined') {\n return undefined;\n }\n return this.parseValue(raw);\n }\n\n public async set(key: string, value: T): Promise<this> {\n await this.ready;\n const storageKey = this.toStorageKey(key);\n\n let payload: string;\n try {\n payload = this.validateAndSerialize(value, key);\n } catch (error: unknown) {\n this.logger.error(`Failed to serialize value for key \"${key}\": ${error}`);\n throw error;\n }\n\n await this.upsertValue(storageKey, payload);\n return this;\n }\n\n public async delete(key: string): Promise<boolean> {\n await this.ready;\n return this.deleteValue(this.toStorageKey(key));\n }\n\n public async *entries(): AsyncIterableIterator<[ string, T ]> {\n await this.ready;\n const prefix = this.namespace;\n const rows = await this.selectEntries(prefix);\n\n for (const row of rows) {\n if (!row.key.startsWith(prefix)) {\n continue;\n }\n\n const logicalKey = row.key.slice(prefix.length);\n const value = this.parseValue(row.value);\n if (typeof value === 'undefined') {\n continue;\n }\n\n yield [ logicalKey, value ];\n }\n }\n\n protected toStorageKey(key: string): string {\n return `${this.namespace}${key}`;\n }\n\n protected validateAndSerialize(value: T, key: string): string {\n try {\n const payload = JSON.stringify(value ?? null);\n if (payload === 'undefined') {\n throw new Error('Cannot serialize undefined value');\n }\n JSON.parse(payload);\n return payload;\n } catch (error: unknown) {\n this.logger.error(`JSON serialization failed for key \"${key}\": ${error}`);\n throw new Error(`JSON serialization failed for key \"${key}\": ${error}`);\n }\n }\n\n protected parseValue(raw: unknown): T | undefined {\n try {\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n\n if (parsed && typeof parsed === 'object' && 'key' in parsed && 'payload' in parsed) {\n return (parsed as { payload: T }).payload;\n }\n\n return parsed as T;\n } catch (error: unknown) {\n this.logger.error(`Failed to parse stored value: ${error}. Raw value: ${JSON.stringify(raw)}`);\n return undefined;\n }\n }\n\n protected abstract closeStorage(): Promise<void>;\n protected abstract hasValue(key: string): Promise<boolean>;\n protected abstract selectValue(key: string): Promise<unknown | undefined>;\n protected abstract upsertValue(key: string, payload: string): Promise<void>;\n protected abstract deleteValue(key: string): Promise<boolean>;\n protected abstract selectEntries(prefix: string): Promise<BaseKeyValueStorageRow[]>;\n}\n\nfunction assertIdentifier(name: string): void {\n if (!/^[A-Za-z0-9_]+$/u.test(name)) {\n throw new Error(`Invalid identifier: \"${name}\". Only alphanumeric and underscore are allowed.`);\n }\n}\n"]}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": [
|
|
3
|
+
"https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/components/context.jsonld",
|
|
4
|
+
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^8.0.0/components/context.jsonld"
|
|
5
|
+
],
|
|
6
|
+
"@id": "npmd:@undefineds.co/xpod",
|
|
7
|
+
"components": [
|
|
8
|
+
{
|
|
9
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage",
|
|
10
|
+
"@type": "AbstractClass",
|
|
11
|
+
"requireElement": "BaseKeyValueStorage",
|
|
12
|
+
"extends": [
|
|
13
|
+
{
|
|
14
|
+
"@type": "GenericComponentExtension",
|
|
15
|
+
"component": "css:dist/storage/keyvalue/KeyValueStorage.jsonld#KeyValueStorage",
|
|
16
|
+
"genericTypeInstances": [
|
|
17
|
+
"xsd:string",
|
|
18
|
+
{
|
|
19
|
+
"@type": "ParameterRangeGenericTypeReference",
|
|
20
|
+
"parameterRangeGenericType": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__generic_T"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"css:dist/init/Initializable.jsonld#Initializable",
|
|
25
|
+
"css:dist/init/final/Finalizable.jsonld#Finalizable"
|
|
26
|
+
],
|
|
27
|
+
"genericTypeParameters": [
|
|
28
|
+
{
|
|
29
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__generic_T",
|
|
30
|
+
"default": {
|
|
31
|
+
"@type": "ParameterRangeWildcard"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"parameters": [
|
|
36
|
+
{
|
|
37
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage_options_tableName",
|
|
38
|
+
"range": {
|
|
39
|
+
"@type": "ParameterRangeUnion",
|
|
40
|
+
"parameterRangeElements": [
|
|
41
|
+
"xsd:string",
|
|
42
|
+
{
|
|
43
|
+
"@type": "ParameterRangeUndefined"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage_options_namespace",
|
|
50
|
+
"range": {
|
|
51
|
+
"@type": "ParameterRangeUnion",
|
|
52
|
+
"parameterRangeElements": [
|
|
53
|
+
"xsd:string",
|
|
54
|
+
{
|
|
55
|
+
"@type": "ParameterRangeUndefined"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"memberFields": [
|
|
62
|
+
{
|
|
63
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_logger",
|
|
64
|
+
"memberFieldName": "logger",
|
|
65
|
+
"range": {
|
|
66
|
+
"@type": "ParameterRangeWildcard"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_tableName",
|
|
71
|
+
"memberFieldName": "tableName",
|
|
72
|
+
"range": "xsd:string"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_namespace",
|
|
76
|
+
"memberFieldName": "namespace",
|
|
77
|
+
"range": "xsd:string"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_ready",
|
|
81
|
+
"memberFieldName": "ready"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_constructor",
|
|
85
|
+
"memberFieldName": "constructor"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_setReady",
|
|
89
|
+
"memberFieldName": "setReady"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_initialize",
|
|
93
|
+
"memberFieldName": "initialize"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_finalize",
|
|
97
|
+
"memberFieldName": "finalize"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_has",
|
|
101
|
+
"memberFieldName": "has"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_get",
|
|
105
|
+
"memberFieldName": "get"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_set",
|
|
109
|
+
"memberFieldName": "set"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_delete",
|
|
113
|
+
"memberFieldName": "delete"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_entries",
|
|
117
|
+
"memberFieldName": "entries"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_toStorageKey",
|
|
121
|
+
"memberFieldName": "toStorageKey"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_validateAndSerialize",
|
|
125
|
+
"memberFieldName": "validateAndSerialize"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_parseValue",
|
|
129
|
+
"memberFieldName": "parseValue"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_closeStorage",
|
|
133
|
+
"memberFieldName": "closeStorage"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_hasValue",
|
|
137
|
+
"memberFieldName": "hasValue"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_selectValue",
|
|
141
|
+
"memberFieldName": "selectValue"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_upsertValue",
|
|
145
|
+
"memberFieldName": "upsertValue"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_deleteValue",
|
|
149
|
+
"memberFieldName": "deleteValue"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage__member_selectEntries",
|
|
153
|
+
"memberFieldName": "selectEntries"
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"constructorArguments": [
|
|
157
|
+
{
|
|
158
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage_options__constructorArgument",
|
|
159
|
+
"fields": [
|
|
160
|
+
{
|
|
161
|
+
"keyRaw": "tableName",
|
|
162
|
+
"value": {
|
|
163
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage_options_tableName"
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"keyRaw": "namespace",
|
|
168
|
+
"value": {
|
|
169
|
+
"@id": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage_options_namespace"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Pool } from 'pg';
|
|
2
|
-
import
|
|
2
|
+
import { BaseKeyValueStorage, type BaseKeyValueStorageRow } from './BaseKeyValueStorage';
|
|
3
3
|
export interface PostgresKeyValueStorageOptions {
|
|
4
4
|
connectionString: string;
|
|
5
5
|
tableName?: string;
|
|
@@ -10,25 +10,16 @@ export interface PostgresKeyValueStorageOptions {
|
|
|
10
10
|
*/
|
|
11
11
|
pool?: Pool;
|
|
12
12
|
}
|
|
13
|
-
export declare class PostgresKeyValueStorage<T = unknown>
|
|
14
|
-
protected readonly logger: import("global-logger-factory").Logger<unknown>;
|
|
13
|
+
export declare class PostgresKeyValueStorage<T = unknown> extends BaseKeyValueStorage<T> {
|
|
15
14
|
private readonly pool;
|
|
16
|
-
private readonly tableName;
|
|
17
15
|
private readonly quotedTableName;
|
|
18
|
-
private readonly namespace;
|
|
19
|
-
private readonly ready;
|
|
20
16
|
private readonly sharedConnectionString?;
|
|
21
17
|
constructor(options: PostgresKeyValueStorageOptions);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
protected ensureTable(): Promise<void>;
|
|
30
|
-
protected toStorageKey(key: string): string;
|
|
31
|
-
protected formatIdentifier(name: string): string;
|
|
32
|
-
protected validateAndSerialize(value: T, key: string): string;
|
|
33
|
-
protected parseValue(raw: any): T | undefined;
|
|
18
|
+
protected closeStorage(): Promise<void>;
|
|
19
|
+
protected hasValue(key: string): Promise<boolean>;
|
|
20
|
+
protected selectValue(key: string): Promise<unknown | undefined>;
|
|
21
|
+
protected upsertValue(key: string, payload: string): Promise<void>;
|
|
22
|
+
protected deleteValue(key: string): Promise<boolean>;
|
|
23
|
+
protected selectEntries(prefix: string): Promise<BaseKeyValueStorageRow[]>;
|
|
24
|
+
private ensureTable;
|
|
34
25
|
}
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PostgresKeyValueStorage = void 0;
|
|
4
|
-
const global_logger_factory_1 = require("global-logger-factory");
|
|
5
4
|
const PostgresPoolManager_1 = require("../database/PostgresPoolManager");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
throw new Error(`Invalid identifier: "${name}". Only alphanumeric and underscore are allowed.`);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
class PostgresKeyValueStorage {
|
|
5
|
+
const BaseKeyValueStorage_1 = require("./BaseKeyValueStorage");
|
|
6
|
+
class PostgresKeyValueStorage extends BaseKeyValueStorage_1.BaseKeyValueStorage {
|
|
12
7
|
constructor(options) {
|
|
13
|
-
|
|
14
|
-
// 使用共享的连接池,避免多个组件创建独立连接池导致死锁
|
|
8
|
+
super(options);
|
|
15
9
|
if (options.pool) {
|
|
16
10
|
this.pool = options.pool;
|
|
17
11
|
this.sharedConnectionString = undefined;
|
|
@@ -20,78 +14,43 @@ class PostgresKeyValueStorage {
|
|
|
20
14
|
this.sharedConnectionString = options.connectionString;
|
|
21
15
|
this.pool = (0, PostgresPoolManager_1.getSharedPool)({ connectionString: options.connectionString });
|
|
22
16
|
}
|
|
23
|
-
|
|
24
|
-
this.
|
|
25
|
-
|
|
26
|
-
this.quotedTableName = this.formatIdentifier(this.tableName);
|
|
27
|
-
this.ready = this.ensureTable();
|
|
28
|
-
}
|
|
29
|
-
async initialize() {
|
|
30
|
-
await this.ready;
|
|
17
|
+
const tableName = options.tableName ?? 'internal_kv';
|
|
18
|
+
this.quotedTableName = formatIdentifier(tableName);
|
|
19
|
+
this.setReady(this.ensureTable());
|
|
31
20
|
}
|
|
32
|
-
async
|
|
21
|
+
async closeStorage() {
|
|
33
22
|
if (!this.sharedConnectionString) {
|
|
34
23
|
return;
|
|
35
24
|
}
|
|
36
25
|
(0, PostgresPoolManager_1.releaseSharedPool)({ connectionString: this.sharedConnectionString });
|
|
37
26
|
}
|
|
38
|
-
async
|
|
39
|
-
await this.
|
|
40
|
-
const storageKey = this.toStorageKey(key);
|
|
41
|
-
const result = await this.pool.query(`SELECT EXISTS (SELECT 1 FROM ${this.quotedTableName} WHERE key = $1) AS exists`, [storageKey]);
|
|
27
|
+
async hasValue(key) {
|
|
28
|
+
const result = await this.pool.query(`SELECT EXISTS (SELECT 1 FROM ${this.quotedTableName} WHERE key = $1) AS exists`, [key]);
|
|
42
29
|
return result.rows[0]?.exists ?? false;
|
|
43
30
|
}
|
|
44
|
-
async
|
|
45
|
-
await this.
|
|
46
|
-
const storageKey = this.toStorageKey(key);
|
|
47
|
-
const result = await this.pool.query(`SELECT value FROM ${this.quotedTableName} WHERE key = $1 LIMIT 1`, [storageKey]);
|
|
31
|
+
async selectValue(key) {
|
|
32
|
+
const result = await this.pool.query(`SELECT value FROM ${this.quotedTableName} WHERE key = $1 LIMIT 1`, [key]);
|
|
48
33
|
if ((result.rowCount ?? 0) === 0) {
|
|
49
34
|
return undefined;
|
|
50
35
|
}
|
|
51
|
-
|
|
52
|
-
return this.parseValue(result.rows[0].value);
|
|
36
|
+
return result.rows[0]?.value;
|
|
53
37
|
}
|
|
54
|
-
async
|
|
55
|
-
await this.ready;
|
|
56
|
-
const storageKey = this.toStorageKey(key);
|
|
57
|
-
let payload;
|
|
58
|
-
try {
|
|
59
|
-
payload = this.validateAndSerialize(value, key);
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
this.logger.error(`Failed to serialize value for key "${key}": ${error}`);
|
|
63
|
-
throw error;
|
|
64
|
-
}
|
|
38
|
+
async upsertValue(key, payload) {
|
|
65
39
|
await this.pool.query(`INSERT INTO ${this.quotedTableName} (key, value)
|
|
66
40
|
VALUES ($1, $2)
|
|
67
|
-
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()`, [
|
|
68
|
-
return this;
|
|
41
|
+
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()`, [key, payload]);
|
|
69
42
|
}
|
|
70
|
-
async
|
|
71
|
-
await this.
|
|
72
|
-
const storageKey = this.toStorageKey(key);
|
|
73
|
-
const result = await this.pool.query(`DELETE FROM ${this.quotedTableName} WHERE key = $1`, [storageKey]);
|
|
43
|
+
async deleteValue(key) {
|
|
44
|
+
const result = await this.pool.query(`DELETE FROM ${this.quotedTableName} WHERE key = $1`, [key]);
|
|
74
45
|
return (result.rowCount ?? 0) > 0;
|
|
75
46
|
}
|
|
76
|
-
async
|
|
77
|
-
await this.ready;
|
|
78
|
-
const prefix = this.namespace;
|
|
47
|
+
async selectEntries(prefix) {
|
|
79
48
|
const query = prefix.length > 0 ?
|
|
80
49
|
`SELECT key, value FROM ${this.quotedTableName} WHERE key LIKE $1` :
|
|
81
50
|
`SELECT key, value FROM ${this.quotedTableName}`;
|
|
82
51
|
const values = prefix.length > 0 ? [`${prefix}%`] : [];
|
|
83
52
|
const result = await this.pool.query(query, values);
|
|
84
|
-
|
|
85
|
-
if (!row.key.startsWith(prefix)) {
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const logicalKey = row.key.slice(prefix.length);
|
|
89
|
-
const value = this.parseValue(row.value);
|
|
90
|
-
if (typeof value === 'undefined') {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
yield [logicalKey, value];
|
|
94
|
-
}
|
|
53
|
+
return result.rows;
|
|
95
54
|
}
|
|
96
55
|
async ensureTable() {
|
|
97
56
|
await this.pool.query(`
|
|
@@ -102,43 +61,12 @@ class PostgresKeyValueStorage {
|
|
|
102
61
|
)
|
|
103
62
|
`);
|
|
104
63
|
}
|
|
105
|
-
toStorageKey(key) {
|
|
106
|
-
return `${this.namespace}${key}`;
|
|
107
|
-
}
|
|
108
|
-
formatIdentifier(name) {
|
|
109
|
-
return `"${name}"`;
|
|
110
|
-
}
|
|
111
|
-
validateAndSerialize(value, key) {
|
|
112
|
-
try {
|
|
113
|
-
const payload = JSON.stringify(value ?? null);
|
|
114
|
-
// Basic validation
|
|
115
|
-
if (payload === 'undefined') {
|
|
116
|
-
throw new Error(`Cannot serialize undefined value`);
|
|
117
|
-
}
|
|
118
|
-
// Validate JSON can be parsed back
|
|
119
|
-
JSON.parse(payload);
|
|
120
|
-
return payload;
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
this.logger.error(`JSON serialization failed for key "${key}": ${error}`);
|
|
124
|
-
throw new Error(`JSON serialization failed for key "${key}": ${error}`);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
parseValue(raw) {
|
|
128
|
-
try {
|
|
129
|
-
// JSONB column returns object, TEXT column returns string
|
|
130
|
-
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
131
|
-
// Handle CSS internal storage format: {"key": "...", "payload": ...}
|
|
132
|
-
if (parsed && typeof parsed === 'object' && 'key' in parsed && 'payload' in parsed) {
|
|
133
|
-
return parsed.payload;
|
|
134
|
-
}
|
|
135
|
-
return parsed;
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
this.logger.error(`Failed to parse stored value: ${error}. Raw value: ${JSON.stringify(raw)}`);
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
64
|
}
|
|
143
65
|
exports.PostgresKeyValueStorage = PostgresKeyValueStorage;
|
|
66
|
+
function formatIdentifier(name) {
|
|
67
|
+
if (!/^[A-Za-z0-9_]+$/u.test(name)) {
|
|
68
|
+
throw new Error(`Invalid identifier: "${name}". Only alphanumeric and underscore are allowed.`);
|
|
69
|
+
}
|
|
70
|
+
return `"${name}"`;
|
|
71
|
+
}
|
|
144
72
|
//# sourceMappingURL=PostgresKeyValueStorage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresKeyValueStorage.js","sourceRoot":"","sources":["../../../src/storage/keyvalue/PostgresKeyValueStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import { Pool } from 'pg';\nimport type {\n Finalizable,\n Initializable,\n KeyValueStorage,\n} from '@solid/community-server';\nimport { getLoggerFor } from 'global-logger-factory';\nimport { getSharedPool, releaseSharedPool } from '../database/PostgresPoolManager';\n\nexport interface PostgresKeyValueStorageOptions {\n connectionString: string;\n tableName?: string;\n namespace?: string;\n /** \n * 共享的 pg Pool 实例(避免多个组件创建独立连接池导致死锁)\n * 如果提供,将忽略 connectionString\n */\n pool?: Pool;\n}\n\nfunction assertIdentifier(name: string): void {\n if (!/^[A-Za-z0-9_]+$/u.test(name)) {\n throw new Error(`Invalid identifier: \"${name}\". Only alphanumeric and underscore are allowed.`);\n }\n}\n\nexport class PostgresKeyValueStorage<T = unknown> implements\n KeyValueStorage<string, T>,\n Initializable,\n Finalizable {\n protected readonly logger = getLoggerFor(this);\n private readonly pool: Pool;\n private readonly tableName: string;\n private readonly quotedTableName: string;\n private readonly namespace: string;\n private readonly ready: Promise<void>;\n private readonly sharedConnectionString?: string;\n\n public constructor(options: PostgresKeyValueStorageOptions) {\n // 使用共享的连接池,避免多个组件创建独立连接池导致死锁\n if (options.pool) {\n this.pool = options.pool;\n this.sharedConnectionString = undefined;\n } else {\n this.sharedConnectionString = options.connectionString;\n this.pool = getSharedPool({ connectionString: options.connectionString });\n }\n this.tableName = options.tableName ?? 'internal_kv';\n this.namespace = options.namespace ?? '';\n assertIdentifier(this.tableName);\n this.quotedTableName = this.formatIdentifier(this.tableName);\n this.ready = this.ensureTable();\n }\n\n public async initialize(): Promise<void> {\n await this.ready;\n }\n\n public async finalize(): Promise<void> {\n if (!this.sharedConnectionString) {\n return;\n }\n releaseSharedPool({ connectionString: this.sharedConnectionString });\n }\n\n\n public async has(key: string): Promise<boolean> {\n await this.ready;\n const storageKey = this.toStorageKey(key);\n const result = await this.pool.query<{ exists: boolean }>(\n `SELECT EXISTS (SELECT 1 FROM ${this.quotedTableName} WHERE key = $1) AS exists`,\n [ storageKey ],\n );\n return result.rows[0]?.exists ?? false;\n }\n\n public async get(key: string): Promise<T | undefined> {\n await this.ready;\n const storageKey = this.toStorageKey(key);\n const result = await this.pool.query<{ value: any }>(\n `SELECT value FROM ${this.quotedTableName} WHERE key = $1 LIMIT 1`,\n [ storageKey ],\n );\n if ((result.rowCount ?? 0) === 0) {\n return undefined;\n }\n // JSONB column returns object, TEXT column returns string\n return this.parseValue(result.rows[0].value);\n }\n\n public async set(key: string, value: T): Promise<this> {\n await this.ready;\n const storageKey = this.toStorageKey(key);\n \n let payload: string;\n try {\n payload = this.validateAndSerialize(value, key);\n } catch (error: unknown) {\n this.logger.error(`Failed to serialize value for key \"${key}\": ${error}`);\n throw error;\n }\n \n await this.pool.query(\n `INSERT INTO ${this.quotedTableName} (key, value)\n VALUES ($1, $2)\n ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()`,\n [ storageKey, payload ],\n );\n return this;\n }\n\n public async delete(key: string): Promise<boolean> {\n await this.ready;\n const storageKey = this.toStorageKey(key);\n const result = await this.pool.query(\n `DELETE FROM ${this.quotedTableName} WHERE key = $1`,\n [ storageKey ],\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n public async *entries(): AsyncIterableIterator<[ string, T ]> {\n await this.ready;\n const prefix = this.namespace;\n const query = prefix.length > 0 ?\n `SELECT key, value FROM ${this.quotedTableName} WHERE key LIKE $1` :\n `SELECT key, value FROM ${this.quotedTableName}`;\n const values = prefix.length > 0 ? [ `${prefix}%` ] : [];\n const result = await this.pool.query<{ key: string; value: any }>(query, values);\n for (const row of result.rows) {\n if (!row.key.startsWith(prefix)) {\n continue;\n }\n const logicalKey = row.key.slice(prefix.length);\n const value = this.parseValue(row.value);\n if (typeof value === 'undefined') {\n continue;\n }\n yield [ logicalKey, value ];\n }\n }\n\n protected async ensureTable(): Promise<void> {\n await this.pool.query(`\n CREATE TABLE IF NOT EXISTS ${this.quotedTableName} (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n }\n\n protected toStorageKey(key: string): string {\n return `${this.namespace}${key}`;\n }\n\n protected formatIdentifier(name: string): string {\n return `\"${name}\"`;\n }\n\n protected validateAndSerialize(value: T, key: string): string {\n try {\n const payload = JSON.stringify(value ?? null);\n \n // Basic validation\n if (payload === 'undefined') {\n throw new Error(`Cannot serialize undefined value`);\n }\n \n // Validate JSON can be parsed back\n JSON.parse(payload);\n \n return payload;\n } catch (error: unknown) {\n this.logger.error(`JSON serialization failed for key \"${key}\": ${error}`);\n throw new Error(`JSON serialization failed for key \"${key}\": ${error}`);\n }\n }\n\n protected parseValue(raw: any): T | undefined {\n try {\n // JSONB column returns object, TEXT column returns string\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n \n // Handle CSS internal storage format: {\"key\": \"...\", \"payload\": ...}\n if (parsed && typeof parsed === 'object' && 'key' in parsed && 'payload' in parsed) {\n return parsed.payload as T;\n }\n \n return parsed as T;\n } catch (error: unknown) {\n this.logger.error(`Failed to parse stored value: ${error}. Raw value: ${JSON.stringify(raw)}`);\n return undefined;\n }\n }\n\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PostgresKeyValueStorage.js","sourceRoot":"","sources":["../../../src/storage/keyvalue/PostgresKeyValueStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import { Pool } from 'pg';\nimport { getSharedPool, releaseSharedPool } from '../database/PostgresPoolManager';\nimport { BaseKeyValueStorage, type BaseKeyValueStorageRow } from './BaseKeyValueStorage';\n\nexport interface PostgresKeyValueStorageOptions {\n connectionString: string;\n tableName?: string;\n namespace?: string;\n /** \n * 共享的 pg Pool 实例(避免多个组件创建独立连接池导致死锁)\n * 如果提供,将忽略 connectionString\n */\n pool?: Pool;\n}\n\nexport class PostgresKeyValueStorage<T = unknown> extends BaseKeyValueStorage<T> {\n private readonly pool: Pool;\n private readonly quotedTableName: string;\n private readonly sharedConnectionString?: string;\n\n public constructor(options: PostgresKeyValueStorageOptions) {\n super(options);\n\n if (options.pool) {\n this.pool = options.pool;\n this.sharedConnectionString = undefined;\n } else {\n this.sharedConnectionString = options.connectionString;\n this.pool = getSharedPool({ connectionString: options.connectionString });\n }\n\n const tableName = options.tableName ?? 'internal_kv';\n this.quotedTableName = formatIdentifier(tableName);\n this.setReady(this.ensureTable());\n }\n\n protected async closeStorage(): Promise<void> {\n if (!this.sharedConnectionString) {\n return;\n }\n releaseSharedPool({ connectionString: this.sharedConnectionString });\n }\n\n protected async hasValue(key: string): Promise<boolean> {\n const result = await this.pool.query<{ exists: boolean }>(\n `SELECT EXISTS (SELECT 1 FROM ${this.quotedTableName} WHERE key = $1) AS exists`,\n [ key ],\n );\n return result.rows[0]?.exists ?? false;\n }\n\n protected async selectValue(key: string): Promise<unknown | undefined> {\n const result = await this.pool.query<{ value: unknown }>(\n `SELECT value FROM ${this.quotedTableName} WHERE key = $1 LIMIT 1`,\n [ key ],\n );\n if ((result.rowCount ?? 0) === 0) {\n return undefined;\n }\n return result.rows[0]?.value;\n }\n\n protected async upsertValue(key: string, payload: string): Promise<void> {\n await this.pool.query(\n `INSERT INTO ${this.quotedTableName} (key, value)\n VALUES ($1, $2)\n ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()`,\n [ key, payload ],\n );\n }\n\n protected async deleteValue(key: string): Promise<boolean> {\n const result = await this.pool.query(\n `DELETE FROM ${this.quotedTableName} WHERE key = $1`,\n [ key ],\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n protected async selectEntries(prefix: string): Promise<BaseKeyValueStorageRow[]> {\n const query = prefix.length > 0 ?\n `SELECT key, value FROM ${this.quotedTableName} WHERE key LIKE $1` :\n `SELECT key, value FROM ${this.quotedTableName}`;\n const values = prefix.length > 0 ? [ `${prefix}%` ] : [];\n const result = await this.pool.query<BaseKeyValueStorageRow>(query, values);\n return result.rows;\n }\n\n private async ensureTable(): Promise<void> {\n await this.pool.query(`\n CREATE TABLE IF NOT EXISTS ${this.quotedTableName} (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n }\n}\n\nfunction formatIdentifier(name: string): string {\n if (!/^[A-Za-z0-9_]+$/u.test(name)) {\n throw new Error(`Invalid identifier: \"${name}\". Only alphanumeric and underscore are allowed.`);\n }\n return `\"${name}\"`;\n}\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"@context": [
|
|
3
|
-
"https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/components/context.jsonld"
|
|
4
|
-
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^8.0.0/components/context.jsonld"
|
|
3
|
+
"https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/components/context.jsonld"
|
|
5
4
|
],
|
|
6
5
|
"@id": "npmd:@undefineds.co/xpod",
|
|
7
6
|
"components": [
|
|
@@ -12,17 +11,14 @@
|
|
|
12
11
|
"extends": [
|
|
13
12
|
{
|
|
14
13
|
"@type": "GenericComponentExtension",
|
|
15
|
-
"component": "
|
|
14
|
+
"component": "undefineds:dist/storage/keyvalue/BaseKeyValueStorage.jsonld#BaseKeyValueStorage",
|
|
16
15
|
"genericTypeInstances": [
|
|
17
|
-
"xsd:string",
|
|
18
16
|
{
|
|
19
17
|
"@type": "ParameterRangeGenericTypeReference",
|
|
20
18
|
"parameterRangeGenericType": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__generic_T"
|
|
21
19
|
}
|
|
22
20
|
]
|
|
23
|
-
}
|
|
24
|
-
"css:dist/init/Initializable.jsonld#Initializable",
|
|
25
|
-
"css:dist/init/final/Finalizable.jsonld#Finalizable"
|
|
21
|
+
}
|
|
26
22
|
],
|
|
27
23
|
"genericTypeParameters": [
|
|
28
24
|
{
|
|
@@ -76,33 +72,14 @@
|
|
|
76
72
|
}
|
|
77
73
|
],
|
|
78
74
|
"memberFields": [
|
|
79
|
-
{
|
|
80
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_logger",
|
|
81
|
-
"memberFieldName": "logger",
|
|
82
|
-
"range": {
|
|
83
|
-
"@type": "ParameterRangeWildcard"
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
75
|
{
|
|
87
76
|
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_pool",
|
|
88
77
|
"memberFieldName": "pool"
|
|
89
78
|
},
|
|
90
|
-
{
|
|
91
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_tableName",
|
|
92
|
-
"memberFieldName": "tableName"
|
|
93
|
-
},
|
|
94
79
|
{
|
|
95
80
|
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_quotedTableName",
|
|
96
81
|
"memberFieldName": "quotedTableName"
|
|
97
82
|
},
|
|
98
|
-
{
|
|
99
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_namespace",
|
|
100
|
-
"memberFieldName": "namespace"
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_ready",
|
|
104
|
-
"memberFieldName": "ready"
|
|
105
|
-
},
|
|
106
83
|
{
|
|
107
84
|
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_sharedConnectionString",
|
|
108
85
|
"memberFieldName": "sharedConnectionString"
|
|
@@ -112,52 +89,32 @@
|
|
|
112
89
|
"memberFieldName": "constructor"
|
|
113
90
|
},
|
|
114
91
|
{
|
|
115
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#
|
|
116
|
-
"memberFieldName": "
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_finalize",
|
|
120
|
-
"memberFieldName": "finalize"
|
|
92
|
+
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_closeStorage",
|
|
93
|
+
"memberFieldName": "closeStorage"
|
|
121
94
|
},
|
|
122
95
|
{
|
|
123
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#
|
|
124
|
-
"memberFieldName": "
|
|
96
|
+
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_hasValue",
|
|
97
|
+
"memberFieldName": "hasValue"
|
|
125
98
|
},
|
|
126
99
|
{
|
|
127
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#
|
|
128
|
-
"memberFieldName": "
|
|
100
|
+
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_selectValue",
|
|
101
|
+
"memberFieldName": "selectValue"
|
|
129
102
|
},
|
|
130
103
|
{
|
|
131
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#
|
|
132
|
-
"memberFieldName": "
|
|
104
|
+
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_upsertValue",
|
|
105
|
+
"memberFieldName": "upsertValue"
|
|
133
106
|
},
|
|
134
107
|
{
|
|
135
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#
|
|
136
|
-
"memberFieldName": "
|
|
108
|
+
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_deleteValue",
|
|
109
|
+
"memberFieldName": "deleteValue"
|
|
137
110
|
},
|
|
138
111
|
{
|
|
139
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#
|
|
140
|
-
"memberFieldName": "
|
|
112
|
+
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_selectEntries",
|
|
113
|
+
"memberFieldName": "selectEntries"
|
|
141
114
|
},
|
|
142
115
|
{
|
|
143
116
|
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_ensureTable",
|
|
144
117
|
"memberFieldName": "ensureTable"
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_toStorageKey",
|
|
148
|
-
"memberFieldName": "toStorageKey"
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_formatIdentifier",
|
|
152
|
-
"memberFieldName": "formatIdentifier"
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_validateAndSerialize",
|
|
156
|
-
"memberFieldName": "validateAndSerialize"
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
"@id": "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld#PostgresKeyValueStorage__member_parseValue",
|
|
160
|
-
"memberFieldName": "parseValue"
|
|
161
118
|
}
|
|
162
119
|
],
|
|
163
120
|
"constructorArguments": [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseKeyValueStorage, type BaseKeyValueStorageRow } from './BaseKeyValueStorage';
|
|
2
2
|
export interface SqliteKeyValueStorageOptions {
|
|
3
3
|
/** Path to SQLite database file (can be prefixed with sqlite:) */
|
|
4
4
|
path: string;
|
|
@@ -9,24 +9,18 @@ export interface SqliteKeyValueStorageOptions {
|
|
|
9
9
|
* SQLite-backed KeyValueStorage for local deployments.
|
|
10
10
|
* Stores internal CSS data (OIDC tokens, migration status, etc.) in SQLite.
|
|
11
11
|
*/
|
|
12
|
-
export declare class SqliteKeyValueStorage<T = unknown>
|
|
13
|
-
protected readonly logger: import("global-logger-factory").Logger<unknown>;
|
|
12
|
+
export declare class SqliteKeyValueStorage<T = unknown> extends BaseKeyValueStorage<T> {
|
|
14
13
|
private db;
|
|
15
14
|
private readonly path;
|
|
16
|
-
private readonly tableName;
|
|
17
|
-
private readonly namespace;
|
|
18
15
|
private readonly sqliteRuntime;
|
|
19
16
|
constructor(options: SqliteKeyValueStorageOptions);
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
protected closeStorage(): Promise<void>;
|
|
18
|
+
protected hasValue(key: string): Promise<boolean>;
|
|
19
|
+
protected selectValue(key: string): Promise<unknown | undefined>;
|
|
20
|
+
protected upsertValue(key: string, payload: string): Promise<void>;
|
|
21
|
+
protected deleteValue(key: string): Promise<boolean>;
|
|
22
|
+
protected selectEntries(prefix: string): Promise<BaseKeyValueStorageRow[]>;
|
|
23
|
+
private ensureDatabase;
|
|
22
24
|
private getDb;
|
|
23
25
|
private createDatabase;
|
|
24
|
-
has(key: string): Promise<boolean>;
|
|
25
|
-
get(key: string): Promise<T | undefined>;
|
|
26
|
-
set(key: string, value: T): Promise<this>;
|
|
27
|
-
delete(key: string): Promise<boolean>;
|
|
28
|
-
entries(): AsyncIterableIterator<[string, T]>;
|
|
29
|
-
protected toStorageKey(key: string): string;
|
|
30
|
-
protected validateAndSerialize(value: T, key: string): string;
|
|
31
|
-
protected parseValue(raw: string): T | undefined;
|
|
32
26
|
}
|