@powersync/lib-services-framework 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/container.js CHANGED
@@ -2,6 +2,7 @@ import _ from 'lodash';
2
2
  import { NoOpReporter } from './alerts/no-op-reporter.js';
3
3
  import { MigrationManager } from './migrations/MigrationManager.js';
4
4
  import { createFSProbe, createTerminationHandler } from './signals/signals-index.js';
5
+ import { ServiceAssertionError } from '@powersync/service-errors';
5
6
  export var ContainerImplementation;
6
7
  (function (ContainerImplementation) {
7
8
  ContainerImplementation["REPORTER"] = "reporter";
@@ -50,7 +51,7 @@ export class Container {
50
51
  getImplementation(identifier) {
51
52
  const implementation = this.implementations.get(identifier);
52
53
  if (!implementation) {
53
- throw new Error(`Implementation for ${String(identifier)} has not been registered.`);
54
+ throw new ServiceAssertionError(`Implementation for ${String(identifier)} has not been registered.`);
54
55
  }
55
56
  return implementation;
56
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAmC,aAAa,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtH,MAAM,CAAN,IAAY,uBAKX;AALD,WAAY,uBAAuB;IACjC,gDAAqB,CAAA;IACrB,4CAAiB,CAAA;IACjB,sEAA2C,CAAA;IAC3C,kEAAuC,CAAA;AACzC,CAAC,EALW,uBAAuB,KAAvB,uBAAuB,QAKlC;AAiCD,MAAM,kBAAkB,GAA6C;IACnE,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,YAAY;IACtD,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;IACvD,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,wBAAwB,EAAE;IAC/E,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,gBAAgB,EAAE;CAC1E,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,SAAS;IAGpB;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;IAC3E,CAAC;IAED;QACE,IAAI,CAAC,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;IACnC,CAAC;IAWD,iBAAiB,CAAI,UAAgC;QACnD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAWD,WAAW,CAAI,UAAgC;QAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,OAAiC;QAChD,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACzF,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,QAAQ,CAAI,UAAgC,EAAE,cAAiB;QAC7D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACvD,CAAC;CACF;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1 @@
1
- export * from './framework-errors.js';
2
- export * from './utils.js';
1
+ export * from '@powersync/service-errors';
@@ -1,3 +1,2 @@
1
- export * from './framework-errors.js';
2
- export * from './utils.js';
1
+ export * from '@powersync/service-errors';
3
2
  //# sourceMappingURL=errors-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors-index.js","sourceRoot":"","sources":["../../src/errors/errors-index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"errors-index.js","sourceRoot":"","sources":["../../src/errors/errors-index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC"}
package/dist/index.d.ts CHANGED
@@ -20,3 +20,5 @@ export * from './system/LifeCycledSystem.js';
20
20
  export * as system from './system/system-index.js';
21
21
  export * from './utils/utils-index.js';
22
22
  export * as utils from './utils/utils-index.js';
23
+ export * from './ip/ip-index.js';
24
+ export * as ip from './ip/ip-index.js';
package/dist/index.js CHANGED
@@ -20,4 +20,6 @@ export * from './system/LifeCycledSystem.js';
20
20
  export * as system from './system/system-index.js';
21
21
  export * from './utils/utils-index.js';
22
22
  export * as utils from './utils/utils-index.js';
23
+ export * from './ip/ip-index.js';
24
+ export * as ip from './ip/ip-index.js';
23
25
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,wBAAwB,CAAC;AAEjD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,oBAAoB,CAAC;AAEnC,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC;AAEhD,cAAc,kCAAkC,CAAC;AACjD,OAAO,KAAK,UAAU,MAAM,kCAAkC,CAAC;AAE/D,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,4BAA4B,CAAC;AAC3C,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AAEtD,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,8BAA8B,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,wBAAwB,CAAC;AAEjD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,oBAAoB,CAAC;AAEnC,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC;AAEhD,cAAc,kCAAkC,CAAC;AACjD,OAAO,KAAK,UAAU,MAAM,kCAAkC,CAAC;AAE/D,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,4BAA4B,CAAC;AAC3C,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AAEtD,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,8BAA8B,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC;AAEhD,cAAc,kBAAkB,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './lookup.js';
@@ -0,0 +1,2 @@
1
+ export * from './lookup.js';
2
+ //# sourceMappingURL=ip-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-index.js","sourceRoot":"","sources":["../../src/ip/ip-index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1,37 @@
1
+ import * as net from 'node:net';
2
+ import * as dns from 'node:dns';
3
+ export interface LookupOptions {
4
+ reject_ip_ranges: string[];
5
+ reject_ipv6?: boolean;
6
+ }
7
+ /**
8
+ * Generate a custom DNS lookup function, that rejects specific IP ranges.
9
+ *
10
+ * If hostname is an IP, this synchronously validates it.
11
+ *
12
+ * @returns a function to use as the `lookup` option in `net.connect`.
13
+ */
14
+ export declare function makeHostnameLookupFunction(hostname: string, lookupOptions: LookupOptions): net.LookupFunction | undefined;
15
+ /**
16
+ * Generate a custom DNS lookup function, that rejects specific IP ranges.
17
+ *
18
+ * Note: Lookup functions are not used for IPs configured directly.
19
+ * For those, validate the IP directly using validateIpHostname().
20
+ *
21
+ * @param reject_ip_ranges IPv4 and/or IPv6 subnets to reject, or 'local' to reject any IP that isn't public unicast.
22
+ * @returns a function to use as the `lookup` option in `net.connect`, or undefined if no restrictions are applied.
23
+ */
24
+ export declare function makeLookupFunction(lookupOptions: LookupOptions): net.LookupFunction | undefined;
25
+ /**
26
+ * Validate IPs synchronously.
27
+ *
28
+ * If the hostname is not an ip, this does nothing.
29
+ *
30
+ * @param hostname IP or DNS name
31
+ * @param options
32
+ */
33
+ export declare function validateIpHostname(hostname: string, options: LookupOptions): void;
34
+ /**
35
+ * Resolve IP, and check that it is in an allowed range.
36
+ */
37
+ export declare function resolveIp(hostname: string, options: LookupOptions): Promise<dns.LookupAddress>;
@@ -0,0 +1,107 @@
1
+ import * as net from 'node:net';
2
+ import * as dnsp from 'node:dns/promises';
3
+ import ip from 'ipaddr.js';
4
+ import { ErrorCode, ServiceError } from '@powersync/service-errors';
5
+ /**
6
+ * Generate a custom DNS lookup function, that rejects specific IP ranges.
7
+ *
8
+ * If hostname is an IP, this synchronously validates it.
9
+ *
10
+ * @returns a function to use as the `lookup` option in `net.connect`.
11
+ */
12
+ export function makeHostnameLookupFunction(hostname, lookupOptions) {
13
+ validateIpHostname(hostname, lookupOptions);
14
+ return makeLookupFunction(lookupOptions);
15
+ }
16
+ /**
17
+ * Generate a custom DNS lookup function, that rejects specific IP ranges.
18
+ *
19
+ * Note: Lookup functions are not used for IPs configured directly.
20
+ * For those, validate the IP directly using validateIpHostname().
21
+ *
22
+ * @param reject_ip_ranges IPv4 and/or IPv6 subnets to reject, or 'local' to reject any IP that isn't public unicast.
23
+ * @returns a function to use as the `lookup` option in `net.connect`, or undefined if no restrictions are applied.
24
+ */
25
+ export function makeLookupFunction(lookupOptions) {
26
+ if (lookupOptions.reject_ip_ranges.length == 0 && !lookupOptions.reject_ipv6) {
27
+ // No restrictions - use the default behavior
28
+ return undefined;
29
+ }
30
+ return (hostname, options, callback) => {
31
+ resolveIp(hostname, lookupOptions)
32
+ .then((resolvedAddress) => {
33
+ if (options.all) {
34
+ callback(null, [resolvedAddress]);
35
+ }
36
+ else {
37
+ callback(null, resolvedAddress.address, resolvedAddress.family);
38
+ }
39
+ })
40
+ .catch((err) => {
41
+ callback(err, undefined, undefined);
42
+ });
43
+ };
44
+ }
45
+ /**
46
+ * Validate IPs synchronously.
47
+ *
48
+ * If the hostname is not an ip, this does nothing.
49
+ *
50
+ * @param hostname IP or DNS name
51
+ * @param options
52
+ */
53
+ export function validateIpHostname(hostname, options) {
54
+ const { reject_ip_ranges: reject_ranges } = options;
55
+ if (!ip.isValid(hostname)) {
56
+ // Treat as a DNS name.
57
+ return;
58
+ }
59
+ const ipaddr = hostname;
60
+ const parsed = ip.parse(ipaddr);
61
+ const rejectLocal = reject_ranges.includes('local');
62
+ const rejectSubnets = reject_ranges.filter((range) => range != 'local');
63
+ const reject = { blocked: (rejectSubnets ?? []).map((r) => ip.parseCIDR(r)) };
64
+ if (options.reject_ipv6 && parsed.kind() == 'ipv6') {
65
+ throw new ServiceError(ErrorCode.PSYNC_S2202, 'IPv6 support not enabled for JWKS URI');
66
+ }
67
+ if (ip.subnetMatch(parsed, reject) == 'blocked') {
68
+ // Ranges explicitly blocked, e.g. private IPv6 ranges
69
+ throw new ServiceError(ErrorCode.PSYNC_S2203, `IPs in this range are not supported: ${ipaddr}`);
70
+ }
71
+ if (!rejectLocal) {
72
+ return;
73
+ }
74
+ if (parsed.kind() == 'ipv4' && parsed.range() == 'unicast') {
75
+ // IPv4 - All good
76
+ return;
77
+ }
78
+ else if (parsed.kind() == 'ipv6' && parsed.range() == 'unicast') {
79
+ // IPv6 - All good
80
+ return;
81
+ }
82
+ else {
83
+ // Do not connect to any reserved IPs, including loopback and private ranges
84
+ throw new ServiceError(ErrorCode.PSYNC_S2203, `IPs in this range are not supported: ${ipaddr}`);
85
+ }
86
+ }
87
+ /**
88
+ * Resolve IP, and check that it is in an allowed range.
89
+ */
90
+ export async function resolveIp(hostname, options) {
91
+ let resolvedAddress;
92
+ if (net.isIPv4(hostname)) {
93
+ // Direct ipv4 - all good so far
94
+ resolvedAddress = { address: hostname, family: 4 };
95
+ }
96
+ else if (net.isIPv6(hostname) || net.isIPv4(hostname)) {
97
+ // Direct ipv6 - all good so far
98
+ resolvedAddress = { address: hostname, family: 6 };
99
+ }
100
+ else {
101
+ // DNS name - resolve it
102
+ resolvedAddress = await dnsp.lookup(hostname);
103
+ }
104
+ validateIpHostname(resolvedAddress.address, options);
105
+ return resolvedAddress;
106
+ }
107
+ //# sourceMappingURL=lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../src/ip/lookup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powersync/lib-services-framework",
3
3
  "repository": "https://github.com/powersync-ja/powersync-service",
4
- "version": "0.4.0",
4
+ "version": "0.5.0",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
7
7
  "types": "dist/index.d.ts",
@@ -18,11 +18,13 @@
18
18
  "better-ajv-errors": "^1.2.0",
19
19
  "bson": "^6.8.0",
20
20
  "dotenv": "^16.4.5",
21
+ "ipaddr.js": "^2.1.0",
21
22
  "lodash": "^4.17.21",
22
23
  "ts-codec": "^1.3.0",
23
24
  "uuid": "^9.0.1",
24
25
  "winston": "^3.13.0",
25
- "zod": "^3.23.8"
26
+ "zod": "^3.23.8",
27
+ "@powersync/service-errors": "0.1.1"
26
28
  },
27
29
  "devDependencies": {
28
30
  "@types/lodash": "^4.17.5",
@@ -1,51 +0,0 @@
1
- export declare enum ErrorSeverity {
2
- INFO = "info",
3
- WARNING = "warning",
4
- ERROR = "error"
5
- }
6
- export type ErrorData = {
7
- name?: string;
8
- code: string;
9
- description: string;
10
- severity?: ErrorSeverity;
11
- details?: string;
12
- status?: number;
13
- stack?: string;
14
- origin?: string;
15
- trace_id?: string;
16
- };
17
- export declare class JourneyError extends Error {
18
- is_journey_error: boolean;
19
- errorData: ErrorData;
20
- static isJourneyError(input: any): input is JourneyError;
21
- private static errorMessage;
22
- constructor(data: ErrorData);
23
- toString(): string | undefined;
24
- toJSON(): ErrorData;
25
- setTraceId(id: string): void;
26
- }
27
- export declare class ValidationError extends JourneyError {
28
- static CODE: string;
29
- constructor(errors: any);
30
- }
31
- export declare class AuthorizationError extends JourneyError {
32
- static CODE: string;
33
- constructor(errors: any);
34
- }
35
- export declare class InternalServerError extends JourneyError {
36
- static CODE: string;
37
- constructor(err: Error);
38
- }
39
- export declare class ResourceNotFound extends JourneyError {
40
- static CODE: string;
41
- /**
42
- * @deprecated Use the (resource, id) constructor instead.
43
- * @param id
44
- */
45
- constructor(id: string);
46
- constructor(resource: string, id: string);
47
- }
48
- export declare class ResourceConflict extends JourneyError {
49
- static CODE: string;
50
- constructor(details: string);
51
- }
@@ -1,111 +0,0 @@
1
- export var ErrorSeverity;
2
- (function (ErrorSeverity) {
3
- ErrorSeverity["INFO"] = "info";
4
- ErrorSeverity["WARNING"] = "warning";
5
- ErrorSeverity["ERROR"] = "error";
6
- })(ErrorSeverity || (ErrorSeverity = {}));
7
- // Maybe this could be renamed to ServiceError or something similar
8
- export class JourneyError extends Error {
9
- static isJourneyError(input) {
10
- return input instanceof JourneyError || input?.is_journey_error == true;
11
- }
12
- static errorMessage(data) {
13
- let message = `[${data.code}] ${data.description}`;
14
- if (data.details) {
15
- message += `\n ${data.details}`;
16
- }
17
- return message;
18
- }
19
- constructor(data) {
20
- super(JourneyError.errorMessage(data));
21
- this.is_journey_error = true;
22
- this.errorData = data;
23
- if (data.stack) {
24
- this.stack = data.stack;
25
- }
26
- this.name = data.name || this.constructor.name;
27
- this.errorData.name = this.name;
28
- }
29
- toString() {
30
- return this.stack;
31
- }
32
- toJSON() {
33
- if (process.env.NODE_ENV !== 'production') {
34
- return this.errorData;
35
- }
36
- return {
37
- name: this.errorData.name,
38
- code: this.errorData.code,
39
- status: this.errorData.status,
40
- description: this.errorData.description,
41
- details: this.errorData.details,
42
- trace_id: this.errorData.trace_id,
43
- severity: this.errorData.severity,
44
- origin: this.errorData.origin
45
- };
46
- }
47
- setTraceId(id) {
48
- this.errorData.trace_id = id;
49
- }
50
- }
51
- export class ValidationError extends JourneyError {
52
- constructor(errors) {
53
- super({
54
- code: ValidationError.CODE,
55
- status: 400,
56
- description: 'Validation failed',
57
- details: JSON.stringify(errors)
58
- });
59
- }
60
- }
61
- ValidationError.CODE = 'VALIDATION_ERROR';
62
- export class AuthorizationError extends JourneyError {
63
- constructor(errors) {
64
- super({
65
- code: AuthorizationError.CODE,
66
- status: 401,
67
- description: 'Authorization failed',
68
- details: errors
69
- });
70
- }
71
- }
72
- AuthorizationError.CODE = 'AUTHORIZATION';
73
- export class InternalServerError extends JourneyError {
74
- constructor(err) {
75
- super({
76
- code: InternalServerError.CODE,
77
- severity: ErrorSeverity.ERROR,
78
- status: 500,
79
- description: 'Something went wrong',
80
- details: err.message,
81
- stack: process.env.NODE_ENV !== 'production' ? err.stack : undefined
82
- });
83
- }
84
- }
85
- InternalServerError.CODE = 'INTERNAL_SERVER_ERROR';
86
- export class ResourceNotFound extends JourneyError {
87
- constructor(resource, id) {
88
- const combinedId = id ? `${resource}/${id}` : resource;
89
- super({
90
- code: ResourceNotFound.CODE,
91
- status: 404,
92
- description: 'The requested resource does not exist on this server',
93
- details: `The resource ${combinedId} does not exist on this server`,
94
- severity: ErrorSeverity.INFO
95
- });
96
- }
97
- }
98
- ResourceNotFound.CODE = 'RESOURCE_NOT_FOUND';
99
- export class ResourceConflict extends JourneyError {
100
- constructor(details) {
101
- super({
102
- code: ResourceConflict.CODE,
103
- status: 409,
104
- description: 'The specified resource already exists on this server',
105
- details: details,
106
- severity: ErrorSeverity.INFO
107
- });
108
- }
109
- }
110
- ResourceConflict.CODE = 'RESOURCE_CONFLICT';
111
- //# sourceMappingURL=framework-errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"framework-errors.js","sourceRoot":"","sources":["../../src/errors/framework-errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,8BAAa,CAAA;IACb,oCAAmB,CAAA;IACnB,gCAAe,CAAA;AACjB,CAAC,EAJW,aAAa,KAAb,aAAa,QAIxB;AAkBD,mEAAmE;AACnE,MAAM,OAAO,YAAa,SAAQ,KAAK;IAKrC,MAAM,CAAC,cAAc,CAAC,KAAU;QAC9B,OAAO,KAAK,YAAY,YAAY,IAAI,KAAK,EAAE,gBAAgB,IAAI,IAAI,CAAC;IAC1E,CAAC;IAEO,MAAM,CAAC,YAAY,CAAC,IAAe;QACzC,IAAI,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;QACnD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,YAAY,IAAe;QACzB,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAjBzC,qBAAgB,GAAG,IAAI,CAAC;QAmBtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAC/C,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAClC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,MAAM;QACJ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;QACD,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;YACzB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;YACzB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;YAC7B,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW;YACvC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO;YAC/B,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ;YACjC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ;YACjC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;SAC9B,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,EAAE,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAE/C,YAAY,MAAW;QACrB,KAAK,CAAC;YACJ,IAAI,EAAE,eAAe,CAAC,IAAI;YAC1B,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,mBAAmB;YAChC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;;AARM,oBAAI,GAAG,kBAAkB,CAAC;AAWnC,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAElD,YAAY,MAAW;QACrB,KAAK,CAAC;YACJ,IAAI,EAAE,kBAAkB,CAAC,IAAI;YAC7B,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;IACL,CAAC;;AARM,uBAAI,GAAG,eAAe,CAAC;AAWhC,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAEnD,YAAY,GAAU;QACpB,KAAK,CAAC;YACJ,IAAI,EAAE,mBAAmB,CAAC,IAAI;YAC9B,QAAQ,EAAE,aAAa,CAAC,KAAK;YAC7B,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SACrE,CAAC,CAAC;IACL,CAAC;;AAVM,wBAAI,GAAG,uBAAuB,CAAC;AAaxC,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IAUhD,YAAY,QAAgB,EAAE,EAAW;QACvC,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QACvD,KAAK,CAAC;YACJ,IAAI,EAAE,gBAAgB,CAAC,IAAI;YAC3B,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,sDAAsD;YACnE,OAAO,EAAE,gBAAgB,UAAU,gCAAgC;YACnE,QAAQ,EAAE,aAAa,CAAC,IAAI;SAC7B,CAAC,CAAC;IACL,CAAC;;AAlBM,qBAAI,GAAG,oBAAoB,CAAC;AAqBrC,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IAGhD,YAAY,OAAe;QACzB,KAAK,CAAC;YACJ,IAAI,EAAE,gBAAgB,CAAC,IAAI;YAC3B,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,sDAAsD;YACnE,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,aAAa,CAAC,IAAI;SAC7B,CAAC,CAAC;IACL,CAAC;;AAVM,qBAAI,GAAG,mBAAmB,CAAC"}
@@ -1,4 +0,0 @@
1
- import { ErrorData, JourneyError } from './framework-errors.js';
2
- export declare const isJourneyError: (err: any) => err is JourneyError;
3
- export declare const getErrorData: (err: Error | any) => ErrorData | undefined;
4
- export declare const matchesErrorCode: (err: Error | any, code: string) => boolean;
@@ -1,18 +0,0 @@
1
- import { JourneyError } from './framework-errors.js';
2
- export const isJourneyError = (err) => {
3
- const matches = JourneyError.isJourneyError(err);
4
- return !!matches;
5
- };
6
- export const getErrorData = (err) => {
7
- if (!isJourneyError(err)) {
8
- return;
9
- }
10
- return err.toJSON();
11
- };
12
- export const matchesErrorCode = (err, code) => {
13
- if (isJourneyError(err)) {
14
- return err.errorData.code === code;
15
- }
16
- return false;
17
- };
18
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/errors/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAQ,EAAuB,EAAE;IAC9D,MAAM,OAAO,GAAG,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACjD,OAAO,CAAC,CAAC,OAAO,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAgB,EAAyB,EAAE;IACtE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAgB,EAAE,IAAY,EAAE,EAAE;IACjE,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}