@powersync/service-core 0.0.0-dev-20250117095455 → 0.0.0-dev-20250122110924
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -8
- package/dist/auth/RemoteJWKSCollector.d.ts +3 -0
- package/dist/auth/RemoteJWKSCollector.js +8 -4
- package/dist/auth/RemoteJWKSCollector.js.map +1 -1
- package/dist/entry/cli-entry.js +2 -0
- package/dist/entry/cli-entry.js.map +1 -1
- package/dist/entry/commands/teardown-action.js +2 -1
- package/dist/entry/commands/teardown-action.js.map +1 -1
- package/dist/entry/commands/test-connection-action.d.ts +2 -0
- package/dist/entry/commands/test-connection-action.js +32 -0
- package/dist/entry/commands/test-connection-action.js.map +1 -0
- package/dist/metrics/Metrics.js +2 -2
- package/dist/metrics/Metrics.js.map +1 -1
- package/dist/replication/AbstractReplicator.d.ts +2 -0
- package/dist/replication/AbstractReplicator.js.map +1 -1
- package/dist/replication/ReplicationEngine.d.ts +2 -0
- package/dist/replication/ReplicationEngine.js +3 -0
- package/dist/replication/ReplicationEngine.js.map +1 -1
- package/dist/replication/ReplicationModule.d.ts +8 -2
- package/dist/replication/ReplicationModule.js +6 -11
- package/dist/replication/ReplicationModule.js.map +1 -1
- package/dist/routes/endpoints/admin.js +3 -3
- package/dist/routes/endpoints/admin.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +5 -5
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-rules.js +9 -9
- package/dist/routes/endpoints/sync-rules.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.js +5 -5
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/routes/route-register.js +4 -4
- package/dist/routes/route-register.js.map +1 -1
- package/dist/util/utils.js +2 -1
- package/dist/util/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/auth/RemoteJWKSCollector.ts +18 -5
- package/src/entry/cli-entry.ts +2 -0
- package/src/entry/commands/teardown-action.ts +2 -1
- package/src/entry/commands/test-connection-action.ts +41 -0
- package/src/metrics/Metrics.ts +2 -2
- package/src/replication/AbstractReplicator.ts +3 -0
- package/src/replication/ReplicationEngine.ts +5 -0
- package/src/replication/ReplicationModule.ts +15 -13
- package/src/routes/endpoints/admin.ts +3 -3
- package/src/routes/endpoints/socket-route.ts +5 -5
- package/src/routes/endpoints/sync-rules.ts +9 -9
- package/src/routes/endpoints/sync-stream.ts +5 -5
- package/src/routes/route-register.ts +4 -4
- package/src/util/utils.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { errors, logger, router, schema } from '@powersync/lib-services-framework';
|
|
1
|
+
import { ErrorCode, errors, logger, router, schema } from '@powersync/lib-services-framework';
|
|
2
2
|
import { RequestParameters } from '@powersync/service-sync-rules';
|
|
3
3
|
import { Readable } from 'stream';
|
|
4
4
|
import * as sync from '../../sync/sync-index.js';
|
|
@@ -22,9 +22,9 @@ export const syncStreamed = routeDefinition({
|
|
|
22
22
|
const userAgent = headers['x-user-agent'] ?? headers['user-agent'];
|
|
23
23
|
const clientId = payload.params.client_id;
|
|
24
24
|
if (routerEngine.closed) {
|
|
25
|
-
throw new errors.
|
|
25
|
+
throw new errors.ServiceError({
|
|
26
26
|
status: 503,
|
|
27
|
-
code:
|
|
27
|
+
code: ErrorCode.PSYNC_S2003,
|
|
28
28
|
description: 'Service temporarily unavailable'
|
|
29
29
|
});
|
|
30
30
|
}
|
|
@@ -33,9 +33,9 @@ export const syncStreamed = routeDefinition({
|
|
|
33
33
|
// Sanity check before we start the stream
|
|
34
34
|
const cp = await storageEngine.activeBucketStorage.getActiveCheckpoint();
|
|
35
35
|
if (!cp.hasSyncRules()) {
|
|
36
|
-
throw new errors.
|
|
36
|
+
throw new errors.ServiceError({
|
|
37
37
|
status: 500,
|
|
38
|
-
code:
|
|
38
|
+
code: ErrorCode.PSYNC_S2302,
|
|
39
39
|
description: 'No sync rules available'
|
|
40
40
|
});
|
|
41
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-stream.js","sourceRoot":"","sources":["../../../src/routes/endpoints/sync-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-stream.js","sourceRoot":"","sources":["../../../src/routes/endpoints/sync-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,15 +47,15 @@ export function registerFastifyRoutes(app, contextProvider, endpoints) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
catch (ex) {
|
|
50
|
-
const
|
|
51
|
-
logger.error(`Request failed`,
|
|
50
|
+
const serviceError = errors.asServiceError(ex);
|
|
51
|
+
logger.error(`Request failed`, serviceError);
|
|
52
52
|
response = new router.RouterResponse({
|
|
53
|
-
status:
|
|
53
|
+
status: serviceError.errorData.status || 500,
|
|
54
54
|
headers: {
|
|
55
55
|
'Content-Type': 'application/json'
|
|
56
56
|
},
|
|
57
57
|
data: {
|
|
58
|
-
error:
|
|
58
|
+
error: serviceError.errorData
|
|
59
59
|
}
|
|
60
60
|
});
|
|
61
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-register.js","sourceRoot":"","sources":["../../src/routes/route-register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAc,MAAM,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAQvF;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAA4B,EAC5B,eAAgC,EAChC,SAA+C;IAE/C,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,sCAAsC;QACtC,GAAG,CAAC,QAAQ,CAAC,KAAK,WAAW,OAAO;YAClC,OAAO,CAAC,KAAK,CAAC;gBACZ,GAAG,EAAE,CAAC,CAAC,IAAI;gBACX,MAAM,EAAE,CAAC,CAAC,MAAoB;gBAC9B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;oBAChC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;oBAC7B,IAAI,QAA+B,CAAC;oBACpC,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;wBAE/C,IAAI,QAAQ,GAAG;4BACb,GAAI,OAAO,CAAC,MAAc;4BAC1B,GAAI,OAAO,CAAC,KAAa;yBAC1B,CAAC;wBAEF,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;4BACvG,QAAQ,GAAG;gCACT,GAAG,QAAQ;gCACX,GAAG,OAAO,CAAC,IAAI;6BAChB,CAAC;wBACJ,CAAC;wBAED,MAAM,OAAO,GAAkC;4BAC7C,OAAO,EAAE,OAAO;4BAChB,MAAM,EAAE,QAAQ;4BAChB,OAAO;yBACR,CAAC;wBAEF,MAAM,gBAAgB,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;wBAElE,IAAI,MAAM,CAAC,cAAc,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,CAAC;4BAC7D,QAAQ,GAAG,gBAAgB,CAAC;wBAC9B,CAAC;6BAAM,IAAI,MAAM,CAAC,eAAe,CAAC,gBAAgB,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;4BACzF,QAAQ,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC;gCACnC,MAAM,EAAE,GAAG;gCACX,IAAI,EAAE,gBAAgB;6BACvB,CAAC,CAAC;wBACL,CAAC;6BAAM,CAAC;4BACN,QAAQ,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC;gCACnC,MAAM,EAAE,GAAG;gCACX,IAAI,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;6BACjC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAAC,OAAO,EAAE,EAAE,CAAC;wBACZ,MAAM,YAAY,GAAG,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"route-register.js","sourceRoot":"","sources":["../../src/routes/route-register.ts"],"names":[],"mappings":"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"}
|
package/dist/util/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as bson from 'bson';
|
|
2
2
|
import crypto from 'crypto';
|
|
3
3
|
import * as uuid from 'uuid';
|
|
4
|
+
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
4
5
|
export const ID_NAMESPACE = 'a396dd91-09fc-4017-a28d-3df722f651e9';
|
|
5
6
|
export function escapeIdentifier(identifier) {
|
|
6
7
|
return `"${identifier.replace(/"/g, '""').replace(/\./g, '"."')}"`;
|
|
@@ -21,7 +22,7 @@ export function timestampToOpId(ts) {
|
|
|
21
22
|
// Dynamic values are passed in in some cases, so we make extra sure that the
|
|
22
23
|
// number is a bigint and not number or Long.
|
|
23
24
|
if (typeof ts != 'bigint') {
|
|
24
|
-
throw new
|
|
25
|
+
throw new ServiceAssertionError(`bigint expected, got: ${ts} (${typeof ts})`);
|
|
25
26
|
}
|
|
26
27
|
return ts.toString(10);
|
|
27
28
|
}
|
package/dist/util/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/util/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/util/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"version": "0.0.0-dev-
|
|
8
|
+
"version": "0.0.0-dev-20250122110924",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"license": "FSL-1.1-Apache-2.0",
|
|
11
11
|
"type": "module",
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"uuid": "^9.0.1",
|
|
33
33
|
"winston": "^3.13.0",
|
|
34
34
|
"yaml": "^2.3.2",
|
|
35
|
-
"@powersync/lib-services-framework": "0.0.0-dev-
|
|
35
|
+
"@powersync/lib-services-framework": "0.0.0-dev-20250122110924",
|
|
36
36
|
"@powersync/service-jsonbig": "0.17.10",
|
|
37
|
-
"@powersync/service-rsocket-router": "0.0.0-dev-
|
|
38
|
-
"@powersync/service-sync-rules": "0.
|
|
39
|
-
"@powersync/service-types": "0.0.0-dev-
|
|
37
|
+
"@powersync/service-rsocket-router": "0.0.0-dev-20250122110924",
|
|
38
|
+
"@powersync/service-sync-rules": "0.0.0-dev-20250122110924",
|
|
39
|
+
"@powersync/service-types": "0.0.0-dev-20250122110924"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/async": "^3.2.24",
|
|
@@ -3,7 +3,13 @@ import * as https from 'https';
|
|
|
3
3
|
import * as jose from 'jose';
|
|
4
4
|
import fetch from 'node-fetch';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
ErrorCode,
|
|
8
|
+
LookupOptions,
|
|
9
|
+
makeHostnameLookupFunction,
|
|
10
|
+
ServiceAssertionError,
|
|
11
|
+
ServiceError
|
|
12
|
+
} from '@powersync/lib-services-framework';
|
|
7
13
|
import { KeyCollector, KeyResult } from './KeyCollector.js';
|
|
8
14
|
import { KeySpec } from './KeySpec.js';
|
|
9
15
|
|
|
@@ -24,14 +30,17 @@ export class RemoteJWKSCollector implements KeyCollector {
|
|
|
24
30
|
) {
|
|
25
31
|
try {
|
|
26
32
|
this.url = new URL(url);
|
|
27
|
-
} catch (e) {
|
|
28
|
-
throw new
|
|
33
|
+
} catch (e: any) {
|
|
34
|
+
throw new ServiceError(ErrorCode.PSYNC_S3102, `Invalid jwks_uri: ${JSON.stringify(url)} Details: ${e.message}`);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
// We do support http here for self-hosting use cases.
|
|
32
38
|
// Management service restricts this to https for hosted versions.
|
|
33
39
|
if (this.url.protocol != 'https:' && this.url.protocol != 'http:') {
|
|
34
|
-
throw new
|
|
40
|
+
throw new ServiceError(
|
|
41
|
+
ErrorCode.PSYNC_S3103,
|
|
42
|
+
`Only http(s) is supported for jwks_uri, got: ${JSON.stringify(url)}`
|
|
43
|
+
);
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
this.agent = this.resolveAgent();
|
|
@@ -96,6 +105,9 @@ export class RemoteJWKSCollector implements KeyCollector {
|
|
|
96
105
|
|
|
97
106
|
/**
|
|
98
107
|
* Agent that uses a custom lookup function.
|
|
108
|
+
*
|
|
109
|
+
* This will synchronously raise an error if the URL contains an IP in the reject list.
|
|
110
|
+
* For domain names resolving to a rejected IP, that will fail when making the request.
|
|
99
111
|
*/
|
|
100
112
|
resolveAgent(): http.Agent | https.Agent {
|
|
101
113
|
const lookupOptions = this.options?.lookupOptions ?? { reject_ip_ranges: [] };
|
|
@@ -111,6 +123,7 @@ export class RemoteJWKSCollector implements KeyCollector {
|
|
|
111
123
|
case 'https:':
|
|
112
124
|
return new https.Agent(options);
|
|
113
125
|
}
|
|
114
|
-
|
|
126
|
+
// Already validated the URL before, so this is not expected
|
|
127
|
+
throw new ServiceAssertionError('http or or https is required for JWKS protocol');
|
|
115
128
|
}
|
|
116
129
|
}
|
package/src/entry/cli-entry.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { registerCompactAction } from './commands/compact-action.js';
|
|
|
6
6
|
import { registerMigrationAction } from './commands/migrate-action.js';
|
|
7
7
|
import { registerStartAction } from './commands/start-action.js';
|
|
8
8
|
import { registerTearDownAction } from './commands/teardown-action.js';
|
|
9
|
+
import { registerTestConnectionAction } from './commands/test-connection-action.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Generates a Commander program which serves as the entry point
|
|
@@ -20,6 +21,7 @@ export function generateEntryProgram(startHandlers?: Record<utils.ServiceRunner,
|
|
|
20
21
|
registerTearDownAction(entryProgram);
|
|
21
22
|
registerMigrationAction(entryProgram);
|
|
22
23
|
registerCompactAction(entryProgram);
|
|
24
|
+
registerTestConnectionAction(entryProgram);
|
|
23
25
|
|
|
24
26
|
if (startHandlers) {
|
|
25
27
|
registerStartAction(entryProgram, startHandlers);
|
|
@@ -2,6 +2,7 @@ import { Command } from 'commander';
|
|
|
2
2
|
|
|
3
3
|
import { teardown } from '../../runner/teardown.js';
|
|
4
4
|
import { extractRunnerOptions, wrapConfigCommand } from './config-command.js';
|
|
5
|
+
import { ErrorCode, ServiceError } from '@powersync/lib-services-framework';
|
|
5
6
|
|
|
6
7
|
const COMMAND_NAME = 'teardown';
|
|
7
8
|
|
|
@@ -15,7 +16,7 @@ export function registerTearDownAction(program: Command) {
|
|
|
15
16
|
.description('Terminate all replicating sync rules, clear remote configuration and remove all data')
|
|
16
17
|
.action(async (ack, options) => {
|
|
17
18
|
if (ack !== 'TEARDOWN') {
|
|
18
|
-
throw new
|
|
19
|
+
throw new ServiceError(ErrorCode.PSYNC_S0102, 'TEARDOWN was not acknowledged.');
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
await teardown(extractRunnerOptions(options));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
|
|
3
|
+
import { container, logger } from '@powersync/lib-services-framework';
|
|
4
|
+
import * as system from '../../system/system-index.js';
|
|
5
|
+
import * as utils from '../../util/util-index.js';
|
|
6
|
+
|
|
7
|
+
import { modules, ReplicationEngine } from '../../index.js';
|
|
8
|
+
import { extractRunnerOptions, wrapConfigCommand } from './config-command.js';
|
|
9
|
+
|
|
10
|
+
const COMMAND_NAME = 'test-connection';
|
|
11
|
+
|
|
12
|
+
export function registerTestConnectionAction(program: Command) {
|
|
13
|
+
const testConnectionCommand = program.command(COMMAND_NAME);
|
|
14
|
+
|
|
15
|
+
wrapConfigCommand(testConnectionCommand);
|
|
16
|
+
|
|
17
|
+
return testConnectionCommand.description('Test connection').action(async (options) => {
|
|
18
|
+
try {
|
|
19
|
+
const config = await utils.loadConfig(extractRunnerOptions(options));
|
|
20
|
+
const serviceContext = new system.ServiceContextContainer(config);
|
|
21
|
+
|
|
22
|
+
const replication = new ReplicationEngine();
|
|
23
|
+
serviceContext.register(ReplicationEngine, replication);
|
|
24
|
+
|
|
25
|
+
// Register modules in order to load the correct config
|
|
26
|
+
const moduleManager = container.getImplementation(modules.ModuleManager);
|
|
27
|
+
await moduleManager.initialize(serviceContext);
|
|
28
|
+
|
|
29
|
+
// Start the storage engine in order to create the appropriate BucketStorage
|
|
30
|
+
await serviceContext.lifeCycleEngine.start();
|
|
31
|
+
|
|
32
|
+
logger.info('Testing connection...');
|
|
33
|
+
const results = await replication.testConnection();
|
|
34
|
+
logger.info(`Connection succeeded to ${results.map((r) => r.connectionDescription).join(', ')}`);
|
|
35
|
+
process.exit(0);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
logger.error(`Connection failed: ${e.message}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
package/src/metrics/Metrics.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
|
|
|
3
3
|
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
|
|
4
4
|
import { Resource } from '@opentelemetry/resources';
|
|
5
5
|
import { MeterProvider, MetricReader, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
|
|
6
|
-
import { logger } from '@powersync/lib-services-framework';
|
|
6
|
+
import { logger, ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
7
7
|
import * as storage from '../storage/storage-index.js';
|
|
8
8
|
import * as util from '../util/util-index.js';
|
|
9
9
|
|
|
@@ -132,7 +132,7 @@ export class Metrics {
|
|
|
132
132
|
|
|
133
133
|
public static getInstance(): Metrics {
|
|
134
134
|
if (!Metrics.instance) {
|
|
135
|
-
throw new
|
|
135
|
+
throw new ServiceAssertionError('Metrics have not been initialized');
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
return Metrics.instance;
|
|
@@ -6,6 +6,7 @@ import { StorageEngine } from '../storage/storage-index.js';
|
|
|
6
6
|
import { SyncRulesProvider } from '../util/config/sync-rules/sync-rules-provider.js';
|
|
7
7
|
import { AbstractReplicationJob } from './AbstractReplicationJob.js';
|
|
8
8
|
import { ErrorRateLimiter } from './ErrorRateLimiter.js';
|
|
9
|
+
import { ConnectionTestResult } from './ReplicationModule.js';
|
|
9
10
|
|
|
10
11
|
// 5 minutes
|
|
11
12
|
const PING_INTERVAL = 1_000_000_000n * 300n;
|
|
@@ -225,4 +226,6 @@ export abstract class AbstractReplicator<T extends AbstractReplicationJob = Abst
|
|
|
225
226
|
this.logger.warn(`Failed clean up replication config for sync rules: ${syncRuleStorage.group_id}`, e);
|
|
226
227
|
}
|
|
227
228
|
}
|
|
229
|
+
|
|
230
|
+
abstract testConnection(): Promise<ConnectionTestResult>;
|
|
228
231
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { logger } from '@powersync/lib-services-framework';
|
|
2
2
|
import { AbstractReplicator } from './AbstractReplicator.js';
|
|
3
|
+
import { ConnectionTestResult } from './ReplicationModule.js';
|
|
3
4
|
|
|
4
5
|
export class ReplicationEngine {
|
|
5
6
|
private readonly replicators: Map<string, AbstractReplicator> = new Map();
|
|
@@ -40,4 +41,8 @@ export class ReplicationEngine {
|
|
|
40
41
|
}
|
|
41
42
|
logger.info('Successfully shut down Replication Engine.');
|
|
42
43
|
}
|
|
44
|
+
|
|
45
|
+
public async testConnection(): Promise<ConnectionTestResult[]> {
|
|
46
|
+
return await Promise.all([...this.replicators.values()].map((replicator) => replicator.testConnection()));
|
|
47
|
+
}
|
|
43
48
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { DataSourceConfig } from '@powersync/service-types/dist/config/PowerSyncConfig.js';
|
|
2
2
|
import * as t from 'ts-codec';
|
|
3
3
|
|
|
4
|
+
import { schema } from '@powersync/lib-services-framework';
|
|
4
5
|
import * as types from '@powersync/service-types';
|
|
5
6
|
import * as api from '../api/api-index.js';
|
|
6
7
|
import * as modules from '../modules/modules-index.js';
|
|
7
8
|
import * as system from '../system/system-index.js';
|
|
8
|
-
import { schema } from '@powersync/lib-services-framework';
|
|
9
9
|
import { AbstractReplicator } from './AbstractReplicator.js';
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
export interface ConnectionTestResult {
|
|
12
|
+
/**
|
|
13
|
+
* Connection URI or hostname.
|
|
14
|
+
*/
|
|
15
|
+
connectionDescription: string;
|
|
16
|
+
}
|
|
11
17
|
|
|
12
18
|
/**
|
|
13
19
|
* Provides a common interface for testing the connection to a DataSource.
|
|
@@ -17,7 +23,7 @@ export interface ConnectionTester<TConfig extends DataSourceConfig> {
|
|
|
17
23
|
* Confirm if a connection can be established to the datasource for the provided datasource configuration
|
|
18
24
|
* @param config
|
|
19
25
|
*/
|
|
20
|
-
testConnection(config: TConfig): Promise<
|
|
26
|
+
testConnection(config: TConfig): Promise<ConnectionTestResult>;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
export interface ReplicationModuleOptions extends modules.AbstractModuleOptions {
|
|
@@ -58,7 +64,7 @@ export abstract class ReplicationModule<TConfig extends DataSourceConfig>
|
|
|
58
64
|
*/
|
|
59
65
|
protected abstract createReplicator(context: system.ServiceContext): AbstractReplicator;
|
|
60
66
|
|
|
61
|
-
public abstract testConnection(config: TConfig): Promise<
|
|
67
|
+
public abstract testConnection(config: TConfig): Promise<ConnectionTestResult>;
|
|
62
68
|
|
|
63
69
|
/**
|
|
64
70
|
* Register this module's Replicators and RouteAPI adapters if the required configuration is present.
|
|
@@ -81,16 +87,12 @@ export abstract class ReplicationModule<TConfig extends DataSourceConfig>
|
|
|
81
87
|
);
|
|
82
88
|
}
|
|
83
89
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this.decodeConfig(baseMatchingConfig);
|
|
90
|
+
const baseMatchingConfig = matchingConfig[0] as TConfig;
|
|
91
|
+
// If decoding fails, this will raise a hard error, and stop the service.
|
|
92
|
+
this.decodeConfig(baseMatchingConfig);
|
|
88
93
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
} catch (e) {
|
|
92
|
-
this.logger.error('Failed to initialize.', e);
|
|
93
|
-
}
|
|
94
|
+
context.replicationEngine?.register(this.createReplicator(context));
|
|
95
|
+
context.routerEngine?.registerAPI(this.createRouteAPIAdapter());
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
protected decodeConfig(config: TConfig): void {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { errors, router, schema } from '@powersync/lib-services-framework';
|
|
1
|
+
import { ErrorCode, errors, router, schema } from '@powersync/lib-services-framework';
|
|
2
2
|
import { SqlSyncRules, StaticSchema } from '@powersync/service-sync-rules';
|
|
3
3
|
import { internal_routes } from '@powersync/service-types';
|
|
4
4
|
|
|
@@ -120,9 +120,9 @@ export const reprocess = routeDefinition({
|
|
|
120
120
|
|
|
121
121
|
const active = await activeBucketStorage.getActiveSyncRules(apiHandler.getParseSyncRulesOptions());
|
|
122
122
|
if (active == null) {
|
|
123
|
-
throw new errors.
|
|
123
|
+
throw new errors.ServiceError({
|
|
124
124
|
status: 422,
|
|
125
|
-
code:
|
|
125
|
+
code: ErrorCode.PSYNC_S4104,
|
|
126
126
|
description: 'No active sync rules'
|
|
127
127
|
});
|
|
128
128
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { errors, logger, schema } from '@powersync/lib-services-framework';
|
|
1
|
+
import { ErrorCode, errors, logger, schema } from '@powersync/lib-services-framework';
|
|
2
2
|
import { RequestParameters } from '@powersync/service-sync-rules';
|
|
3
3
|
import { serialize } from 'bson';
|
|
4
4
|
|
|
@@ -34,9 +34,9 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
34
34
|
|
|
35
35
|
if (routerEngine!.closed) {
|
|
36
36
|
responder.onError(
|
|
37
|
-
new errors.
|
|
37
|
+
new errors.ServiceError({
|
|
38
38
|
status: 503,
|
|
39
|
-
code:
|
|
39
|
+
code: ErrorCode.PSYNC_S2003,
|
|
40
40
|
description: 'Service temporarily unavailable'
|
|
41
41
|
})
|
|
42
42
|
);
|
|
@@ -53,9 +53,9 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
53
53
|
const cp = await activeBucketStorage.getActiveCheckpoint();
|
|
54
54
|
if (!cp.hasSyncRules()) {
|
|
55
55
|
responder.onError(
|
|
56
|
-
new errors.
|
|
56
|
+
new errors.ServiceError({
|
|
57
57
|
status: 500,
|
|
58
|
-
code:
|
|
58
|
+
code: ErrorCode.PSYNC_S2302,
|
|
59
59
|
description: 'No sync rules available'
|
|
60
60
|
})
|
|
61
61
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { errors, router, schema } from '@powersync/lib-services-framework';
|
|
1
|
+
import { ErrorCode, errors, router, schema } from '@powersync/lib-services-framework';
|
|
2
2
|
import { SqlSyncRules, SyncRulesErrors } from '@powersync/service-sync-rules';
|
|
3
3
|
import type { FastifyPluginAsync } from 'fastify';
|
|
4
4
|
import * as t from 'ts-codec';
|
|
@@ -43,9 +43,9 @@ export const deploySyncRules = routeDefinition({
|
|
|
43
43
|
|
|
44
44
|
if (service_context.configuration.sync_rules.present) {
|
|
45
45
|
// If sync rules are configured via the config, disable deploy via the API.
|
|
46
|
-
throw new errors.
|
|
46
|
+
throw new errors.ServiceError({
|
|
47
47
|
status: 422,
|
|
48
|
-
code:
|
|
48
|
+
code: ErrorCode.PSYNC_S4105,
|
|
49
49
|
description: 'Sync rules API disabled',
|
|
50
50
|
details: 'Use the management API to deploy sync rules'
|
|
51
51
|
});
|
|
@@ -60,9 +60,9 @@ export const deploySyncRules = routeDefinition({
|
|
|
60
60
|
schema: undefined
|
|
61
61
|
});
|
|
62
62
|
} catch (e) {
|
|
63
|
-
throw new errors.
|
|
63
|
+
throw new errors.ServiceError({
|
|
64
64
|
status: 422,
|
|
65
|
-
code:
|
|
65
|
+
code: ErrorCode.PSYNC_R0001,
|
|
66
66
|
description: 'Sync rules parsing failed',
|
|
67
67
|
details: e.message
|
|
68
68
|
});
|
|
@@ -112,9 +112,9 @@ export const currentSyncRules = routeDefinition({
|
|
|
112
112
|
|
|
113
113
|
const sync_rules = await activeBucketStorage.getActiveSyncRulesContent();
|
|
114
114
|
if (!sync_rules) {
|
|
115
|
-
throw new errors.
|
|
115
|
+
throw new errors.ServiceError({
|
|
116
116
|
status: 422,
|
|
117
|
-
code:
|
|
117
|
+
code: ErrorCode.PSYNC_S4104,
|
|
118
118
|
description: 'No active sync rules'
|
|
119
119
|
});
|
|
120
120
|
}
|
|
@@ -159,9 +159,9 @@ export const reprocessSyncRules = routeDefinition({
|
|
|
159
159
|
const apiHandler = payload.context.service_context.routerEngine!.getAPI();
|
|
160
160
|
const sync_rules = await activeBucketStorage.getActiveSyncRules(apiHandler.getParseSyncRulesOptions());
|
|
161
161
|
if (sync_rules == null) {
|
|
162
|
-
throw new errors.
|
|
162
|
+
throw new errors.ServiceError({
|
|
163
163
|
status: 422,
|
|
164
|
-
code:
|
|
164
|
+
code: ErrorCode.PSYNC_S4104,
|
|
165
165
|
description: 'No active sync rules'
|
|
166
166
|
});
|
|
167
167
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { errors, logger, router, schema } from '@powersync/lib-services-framework';
|
|
1
|
+
import { ErrorCode, errors, logger, router, schema } from '@powersync/lib-services-framework';
|
|
2
2
|
import { RequestParameters } from '@powersync/service-sync-rules';
|
|
3
3
|
import { Readable } from 'stream';
|
|
4
4
|
|
|
@@ -26,9 +26,9 @@ export const syncStreamed = routeDefinition({
|
|
|
26
26
|
const clientId = payload.params.client_id;
|
|
27
27
|
|
|
28
28
|
if (routerEngine!.closed) {
|
|
29
|
-
throw new errors.
|
|
29
|
+
throw new errors.ServiceError({
|
|
30
30
|
status: 503,
|
|
31
|
-
code:
|
|
31
|
+
code: ErrorCode.PSYNC_S2003,
|
|
32
32
|
description: 'Service temporarily unavailable'
|
|
33
33
|
});
|
|
34
34
|
}
|
|
@@ -39,9 +39,9 @@ export const syncStreamed = routeDefinition({
|
|
|
39
39
|
// Sanity check before we start the stream
|
|
40
40
|
const cp = await storageEngine.activeBucketStorage.getActiveCheckpoint();
|
|
41
41
|
if (!cp.hasSyncRules()) {
|
|
42
|
-
throw new errors.
|
|
42
|
+
throw new errors.ServiceError({
|
|
43
43
|
status: 500,
|
|
44
|
-
code:
|
|
44
|
+
code: ErrorCode.PSYNC_S2302,
|
|
45
45
|
description: 'No sync rules available'
|
|
46
46
|
});
|
|
47
47
|
}
|
|
@@ -62,16 +62,16 @@ export function registerFastifyRoutes(
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
} catch (ex) {
|
|
65
|
-
const
|
|
66
|
-
logger.error(`Request failed`,
|
|
65
|
+
const serviceError = errors.asServiceError(ex);
|
|
66
|
+
logger.error(`Request failed`, serviceError);
|
|
67
67
|
|
|
68
68
|
response = new router.RouterResponse({
|
|
69
|
-
status:
|
|
69
|
+
status: serviceError.errorData.status || 500,
|
|
70
70
|
headers: {
|
|
71
71
|
'Content-Type': 'application/json'
|
|
72
72
|
},
|
|
73
73
|
data: {
|
|
74
|
-
error:
|
|
74
|
+
error: serviceError.errorData
|
|
75
75
|
}
|
|
76
76
|
});
|
|
77
77
|
}
|
package/src/util/utils.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { BucketChecksum, OpId, OplogEntry } from './protocol-types.js';
|
|
|
7
7
|
import * as storage from '../storage/storage-index.js';
|
|
8
8
|
|
|
9
9
|
import { PartialChecksum } from '../storage/ChecksumCache.js';
|
|
10
|
+
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
10
11
|
|
|
11
12
|
export type ChecksumMap = Map<string, BucketChecksum>;
|
|
12
13
|
|
|
@@ -34,7 +35,7 @@ export function timestampToOpId(ts: bigint): OpId {
|
|
|
34
35
|
// Dynamic values are passed in in some cases, so we make extra sure that the
|
|
35
36
|
// number is a bigint and not number or Long.
|
|
36
37
|
if (typeof ts != 'bigint') {
|
|
37
|
-
throw new
|
|
38
|
+
throw new ServiceAssertionError(`bigint expected, got: ${ts} (${typeof ts})`);
|
|
38
39
|
}
|
|
39
40
|
return ts.toString(10);
|
|
40
41
|
}
|