@powersync/service-sync-rules 0.28.0 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +3 -3
- package/dist/BaseSqlDataQuery.d.ts +9 -1
- package/dist/BaseSqlDataQuery.js +42 -0
- package/dist/BaseSqlDataQuery.js.map +1 -1
- package/dist/BucketDescription.d.ts +16 -0
- package/dist/BucketParameterQuerier.d.ts +19 -3
- package/dist/BucketParameterQuerier.js.map +1 -1
- package/dist/BucketSource.d.ts +72 -0
- package/dist/BucketSource.js +6 -0
- package/dist/BucketSource.js.map +1 -0
- package/dist/ExpressionType.d.ts +2 -1
- package/dist/ExpressionType.js +1 -1
- package/dist/ExpressionType.js.map +1 -1
- package/dist/SqlBucketDescriptor.d.ts +40 -8
- package/dist/SqlBucketDescriptor.js +78 -10
- package/dist/SqlBucketDescriptor.js.map +1 -1
- package/dist/SqlDataQuery.d.ts +4 -3
- package/dist/SqlDataQuery.js +10 -30
- package/dist/SqlDataQuery.js.map +1 -1
- package/dist/SqlParameterQuery.d.ts +4 -4
- package/dist/SqlParameterQuery.js +9 -4
- package/dist/SqlParameterQuery.js.map +1 -1
- package/dist/SqlSyncRules.d.ts +55 -7
- package/dist/SqlSyncRules.js +126 -47
- package/dist/SqlSyncRules.js.map +1 -1
- package/dist/StaticSqlParameterQuery.d.ts +2 -2
- package/dist/StaticSqlParameterQuery.js +3 -2
- package/dist/StaticSqlParameterQuery.js.map +1 -1
- package/dist/TableValuedFunctionSqlParameterQuery.d.ts +2 -2
- package/dist/TableValuedFunctionSqlParameterQuery.js +11 -10
- package/dist/TableValuedFunctionSqlParameterQuery.js.map +1 -1
- package/dist/TableValuedFunctions.d.ts +2 -2
- package/dist/TableValuedFunctions.js +38 -35
- package/dist/TableValuedFunctions.js.map +1 -1
- package/dist/compatibility.d.ts +40 -0
- package/dist/compatibility.js +56 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/events/SqlEventDescriptor.d.ts +3 -1
- package/dist/events/SqlEventDescriptor.js +4 -2
- package/dist/events/SqlEventDescriptor.js.map +1 -1
- package/dist/events/SqlEventSourceQuery.d.ts +2 -1
- package/dist/events/SqlEventSourceQuery.js +3 -2
- package/dist/events/SqlEventSourceQuery.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/json_schema.js +54 -1
- package/dist/json_schema.js.map +1 -1
- package/dist/request_functions.d.ts +24 -4
- package/dist/request_functions.js +68 -17
- package/dist/request_functions.js.map +1 -1
- package/dist/schema-generators/SchemaGenerator.js +2 -12
- package/dist/schema-generators/SchemaGenerator.js.map +1 -1
- package/dist/sql_filters.d.ts +25 -2
- package/dist/sql_filters.js +223 -119
- package/dist/sql_filters.js.map +1 -1
- package/dist/sql_functions.d.ts +13 -31
- package/dist/sql_functions.js +191 -114
- package/dist/sql_functions.js.map +1 -1
- package/dist/sql_support.d.ts +20 -0
- package/dist/sql_support.js +67 -14
- package/dist/sql_support.js.map +1 -1
- package/dist/streams/filter.d.ts +148 -0
- package/dist/streams/filter.js +426 -0
- package/dist/streams/filter.js.map +1 -0
- package/dist/streams/from_sql.d.ts +4 -0
- package/dist/streams/from_sql.js +375 -0
- package/dist/streams/from_sql.js.map +1 -0
- package/dist/streams/functions.d.ts +2 -0
- package/dist/streams/functions.js +38 -0
- package/dist/streams/functions.js.map +1 -0
- package/dist/streams/parameter.d.ts +67 -0
- package/dist/streams/parameter.js +2 -0
- package/dist/streams/parameter.js.map +1 -0
- package/dist/streams/stream.d.ts +40 -0
- package/dist/streams/stream.js +139 -0
- package/dist/streams/stream.js.map +1 -0
- package/dist/streams/utils.d.ts +1 -0
- package/dist/streams/utils.js +13 -0
- package/dist/streams/utils.js.map +1 -0
- package/dist/streams/variant.d.ts +122 -0
- package/dist/streams/variant.js +266 -0
- package/dist/streams/variant.js.map +1 -0
- package/dist/types/custom_sqlite_value.d.ts +38 -0
- package/dist/types/custom_sqlite_value.js +50 -0
- package/dist/types/custom_sqlite_value.js.map +1 -0
- package/dist/types/time.d.ts +33 -0
- package/dist/types/time.js +67 -0
- package/dist/types/time.js.map +1 -0
- package/dist/types.d.ts +52 -9
- package/dist/types.js +28 -2
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +9 -6
- package/dist/utils.js +42 -17
- package/dist/utils.js.map +1 -1
- package/package.json +3 -3
- package/schema/sync_rules.json +84 -2
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SqliteValueType } from '../ExpressionType.js';
|
|
2
|
+
import { CompatibilityContext } from '../compatibility.js';
|
|
3
|
+
import { SqliteValue } from '../types.js';
|
|
4
|
+
import { CustomSqliteValue } from './custom_sqlite_value.js';
|
|
5
|
+
/**
|
|
6
|
+
* In old versions of the sync service, timestamp values were formatted with a space between the date and time
|
|
7
|
+
* components.
|
|
8
|
+
*
|
|
9
|
+
* This is not ISO 6801 compatible, but changing it would be breaking existing users. So, this option is opt-in and
|
|
10
|
+
* disabled by default until a major upgrade.
|
|
11
|
+
*/
|
|
12
|
+
export declare class DateTimeValue extends CustomSqliteValue {
|
|
13
|
+
readonly iso8601Representation: string;
|
|
14
|
+
private readonly fixedLegacyRepresentation;
|
|
15
|
+
constructor(iso8601Representation: string, fixedLegacyRepresentation?: string | undefined);
|
|
16
|
+
get legacyRepresentation(): string;
|
|
17
|
+
get sqliteType(): SqliteValueType;
|
|
18
|
+
toSqliteValue(context: CompatibilityContext): string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* In old versions of the sync service, time values didn't consistently contain a sub-second interval.
|
|
22
|
+
*
|
|
23
|
+
* A value like `12:13:14.156789` would be represented as-is, but `12:13:14.000000` would be synced as `12:13:14`. This
|
|
24
|
+
* is undesirable because it means that sorting values alphabetically doesn't preserve their value.
|
|
25
|
+
*/
|
|
26
|
+
export declare class TimeValue extends CustomSqliteValue {
|
|
27
|
+
readonly timeSeconds: string;
|
|
28
|
+
readonly fraction: string | undefined;
|
|
29
|
+
constructor(timeSeconds: string, fraction?: string | undefined);
|
|
30
|
+
static parse(value: string): TimeValue | null;
|
|
31
|
+
toSqliteValue(context: CompatibilityContext): SqliteValue;
|
|
32
|
+
get sqliteType(): SqliteValueType;
|
|
33
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { CompatibilityOption } from '../compatibility.js';
|
|
2
|
+
import { CustomSqliteValue } from './custom_sqlite_value.js';
|
|
3
|
+
/**
|
|
4
|
+
* In old versions of the sync service, timestamp values were formatted with a space between the date and time
|
|
5
|
+
* components.
|
|
6
|
+
*
|
|
7
|
+
* This is not ISO 6801 compatible, but changing it would be breaking existing users. So, this option is opt-in and
|
|
8
|
+
* disabled by default until a major upgrade.
|
|
9
|
+
*/
|
|
10
|
+
export class DateTimeValue extends CustomSqliteValue {
|
|
11
|
+
iso8601Representation;
|
|
12
|
+
fixedLegacyRepresentation;
|
|
13
|
+
// YYYY-MM-DDThh:mm:ss.sss / YYYY-MM-DDThh:mm:ss.sssZ
|
|
14
|
+
constructor(iso8601Representation, fixedLegacyRepresentation = undefined) {
|
|
15
|
+
super();
|
|
16
|
+
this.iso8601Representation = iso8601Representation;
|
|
17
|
+
this.fixedLegacyRepresentation = fixedLegacyRepresentation;
|
|
18
|
+
}
|
|
19
|
+
// YYYY-MM-DD hh:mm:ss.sss / YYYY-MM-DD hh:mm:ss.sssZ
|
|
20
|
+
get legacyRepresentation() {
|
|
21
|
+
return this.fixedLegacyRepresentation ?? this.iso8601Representation.replace('T', ' ');
|
|
22
|
+
}
|
|
23
|
+
get sqliteType() {
|
|
24
|
+
return 'text';
|
|
25
|
+
}
|
|
26
|
+
toSqliteValue(context) {
|
|
27
|
+
return context.isEnabled(CompatibilityOption.timestampsIso8601)
|
|
28
|
+
? this.iso8601Representation
|
|
29
|
+
: this.legacyRepresentation;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* In old versions of the sync service, time values didn't consistently contain a sub-second interval.
|
|
34
|
+
*
|
|
35
|
+
* A value like `12:13:14.156789` would be represented as-is, but `12:13:14.000000` would be synced as `12:13:14`. This
|
|
36
|
+
* is undesirable because it means that sorting values alphabetically doesn't preserve their value.
|
|
37
|
+
*/
|
|
38
|
+
export class TimeValue extends CustomSqliteValue {
|
|
39
|
+
timeSeconds;
|
|
40
|
+
fraction;
|
|
41
|
+
constructor(timeSeconds, fraction = undefined) {
|
|
42
|
+
super();
|
|
43
|
+
this.timeSeconds = timeSeconds;
|
|
44
|
+
this.fraction = fraction;
|
|
45
|
+
}
|
|
46
|
+
static parse(value) {
|
|
47
|
+
const match = /^([\d:]+)(\.\d+)?$/.exec(value);
|
|
48
|
+
if (match == null) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const [_, timeSeconds, fraction] = match;
|
|
52
|
+
return new TimeValue(timeSeconds, fraction);
|
|
53
|
+
}
|
|
54
|
+
toSqliteValue(context) {
|
|
55
|
+
if (context.isEnabled(CompatibilityOption.timestampsIso8601)) {
|
|
56
|
+
const fraction = this.fraction?.padEnd(7, '0') ?? '.000000';
|
|
57
|
+
return `${this.timeSeconds}${fraction}`;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return `${this.timeSeconds}${this.fraction ?? ''}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
get sqliteType() {
|
|
64
|
+
return 'text';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/types/time.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,OAAO,aAAc,SAAQ,iBAAiB;IAIvC;IACQ;IAJnB,qDAAqD;IAErD,YACW,qBAA6B,EACrB,4BAAgD,SAAS;QAE1E,KAAK,EAAE,CAAC;QAHC,0BAAqB,GAArB,qBAAqB,CAAQ;QACrB,8BAAyB,GAAzB,yBAAyB,CAAgC;IAG5E,CAAC;IAED,qDAAqD;IACrD,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,yBAAyB,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxF,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,aAAa,CAAC,OAA6B;QACzC,OAAO,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,iBAAiB,CAAC;YAC7D,CAAC,CAAC,IAAI,CAAC,qBAAqB;YAC5B,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC;IAChC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,SAAU,SAAQ,iBAAiB;IAEnC;IACA;IAFX,YACW,WAAmB,EACnB,WAA+B,SAAS;QAEjD,KAAK,EAAE,CAAC;QAHC,gBAAW,GAAX,WAAW,CAAQ;QACnB,aAAQ,GAAR,QAAQ,CAAgC;IAGnD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAa;QACxB,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,KAAY,CAAC;QAChD,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,aAAa,CAAC,OAA6B;QACzC,IAAI,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;YAC5D,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;IACH,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { SyncRulesOptions } from './SqlSyncRules.js';
|
|
|
5
5
|
import { TablePattern } from './TablePattern.js';
|
|
6
6
|
import { BucketPriority } from './BucketDescription.js';
|
|
7
7
|
import { ParameterLookup } from './BucketParameterQuerier.js';
|
|
8
|
+
import { CustomSqliteValue } from './types/custom_sqlite_value.js';
|
|
9
|
+
import { CompatibilityContext } from './compatibility.js';
|
|
8
10
|
export interface SyncRules {
|
|
9
11
|
evaluateRow(options: EvaluateRowOptions): EvaluationResult[];
|
|
10
12
|
evaluateParameterRow(table: SourceTableInterface, row: SqliteRow): EvaluatedParametersResult[];
|
|
@@ -12,6 +14,10 @@ export interface SyncRules {
|
|
|
12
14
|
export interface QueryParseOptions extends SyncRulesOptions {
|
|
13
15
|
accept_potentially_dangerous_queries?: boolean;
|
|
14
16
|
priority?: BucketPriority;
|
|
17
|
+
compatibility: CompatibilityContext;
|
|
18
|
+
}
|
|
19
|
+
export interface StreamParseOptions extends QueryParseOptions {
|
|
20
|
+
auto_subscribe?: boolean;
|
|
15
21
|
}
|
|
16
22
|
export interface EvaluatedParameters {
|
|
17
23
|
lookup: ParameterLookup;
|
|
@@ -54,10 +60,17 @@ export interface ParameterValueSet {
|
|
|
54
60
|
* JSON string of raw request parameters.
|
|
55
61
|
*/
|
|
56
62
|
rawUserParameters: string;
|
|
63
|
+
userParameters: SqliteJsonRow;
|
|
64
|
+
/**
|
|
65
|
+
* For streams, the raw JSON string of stream parameters.
|
|
66
|
+
*/
|
|
67
|
+
rawStreamParameters: string | null;
|
|
68
|
+
streamParameters: SqliteJsonRow | null;
|
|
57
69
|
/**
|
|
58
70
|
* JSON string of raw request parameters.
|
|
59
71
|
*/
|
|
60
72
|
rawTokenPayload: string;
|
|
73
|
+
tokenParameters: SqliteJsonRow;
|
|
61
74
|
userId: string;
|
|
62
75
|
}
|
|
63
76
|
export declare class RequestParameters implements ParameterValueSet {
|
|
@@ -67,13 +80,17 @@ export declare class RequestParameters implements ParameterValueSet {
|
|
|
67
80
|
* JSON string of raw request parameters.
|
|
68
81
|
*/
|
|
69
82
|
rawUserParameters: string;
|
|
83
|
+
streamParameters: SqliteJsonRow | null;
|
|
84
|
+
rawStreamParameters: string | null;
|
|
70
85
|
/**
|
|
71
86
|
* JSON string of raw request parameters.
|
|
72
87
|
*/
|
|
73
88
|
rawTokenPayload: string;
|
|
74
89
|
userId: string;
|
|
75
90
|
constructor(tokenPayload: RequestJwtPayload, clientParameters: Record<string, any>);
|
|
91
|
+
constructor(params: RequestParameters);
|
|
76
92
|
lookup(table: string, column: string): SqliteJsonValue;
|
|
93
|
+
withAddedStreamParameters(params: Record<string, any>): RequestParameters;
|
|
77
94
|
}
|
|
78
95
|
/**
|
|
79
96
|
* A value that is both SQLite and JSON-compatible.
|
|
@@ -85,6 +102,11 @@ export type SqliteJsonValue = number | string | bigint | null;
|
|
|
85
102
|
* A value supported by the SQLite type system.
|
|
86
103
|
*/
|
|
87
104
|
export type SqliteValue = number | string | null | bigint | Uint8Array;
|
|
105
|
+
/**
|
|
106
|
+
* A value that is either supported by SQLite natively, or one that can be lowered into a SQLite-value given additional
|
|
107
|
+
* context.
|
|
108
|
+
*/
|
|
109
|
+
export type SqliteInputValue = SqliteValue | CustomSqliteValue;
|
|
88
110
|
/**
|
|
89
111
|
* A set of values that are both SQLite and JSON-compatible.
|
|
90
112
|
*
|
|
@@ -97,22 +119,21 @@ export type SqliteJsonRow = {
|
|
|
97
119
|
* SQLite-compatible row (NULL, TEXT, INTEGER, REAL, BLOB).
|
|
98
120
|
* JSON is represented as TEXT.
|
|
99
121
|
*/
|
|
100
|
-
export type SqliteRow = {
|
|
101
|
-
[column: string]:
|
|
122
|
+
export type SqliteRow<T = SqliteValue> = {
|
|
123
|
+
[column: string]: T;
|
|
102
124
|
};
|
|
125
|
+
export type SqliteInputRow = SqliteRow<SqliteInputValue>;
|
|
103
126
|
/**
|
|
104
127
|
* SQLite-compatible row (NULL, TEXT, INTEGER, REAL, BLOB).
|
|
105
128
|
* JSON is represented as TEXT.
|
|
106
129
|
*
|
|
107
130
|
* Toasted values are `undefined`.
|
|
108
131
|
*/
|
|
109
|
-
export type ToastableSqliteRow =
|
|
110
|
-
[column: string]: SqliteValue | undefined;
|
|
111
|
-
};
|
|
132
|
+
export type ToastableSqliteRow<V = SqliteInputValue> = SqliteRow<V | undefined>;
|
|
112
133
|
/**
|
|
113
134
|
* A value as received from the database.
|
|
114
135
|
*/
|
|
115
|
-
export type DatabaseInputValue = SqliteValue | boolean | DatabaseInputValue[] | JsonContainer | {
|
|
136
|
+
export type DatabaseInputValue = SqliteValue | boolean | DatabaseInputValue[] | JsonContainer | CustomSqliteValue | {
|
|
116
137
|
[key: string]: DatabaseInputValue;
|
|
117
138
|
};
|
|
118
139
|
/**
|
|
@@ -166,12 +187,31 @@ export interface InputParameter {
|
|
|
166
187
|
*/
|
|
167
188
|
parametersToLookupValue(parameters: ParameterValueSet): SqliteValue;
|
|
168
189
|
}
|
|
169
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Transforms bucket ids generated when evaluating the row by e.g. encoding version information.
|
|
192
|
+
*
|
|
193
|
+
* Because buckets are recreated on a sync rule redeploy, it makes sense to use different bucket ids (otherwise, clients
|
|
194
|
+
* may run into checksum errors causing a sync to take longer than necessary or breaking progress).
|
|
195
|
+
*
|
|
196
|
+
* So, this transformer receives the original bucket id as generated by defined sync rules, and can prepend a version
|
|
197
|
+
* identifier.
|
|
198
|
+
*
|
|
199
|
+
* Note that this transformation has not been present in older versions of the sync service. To preserve backwards
|
|
200
|
+
* compatibility, sync rules will not use this function without an opt-in.
|
|
201
|
+
*/
|
|
202
|
+
export type BucketIdTransformer = (regularId: string) => string;
|
|
203
|
+
export interface EvaluateRowOptions extends TableRow {
|
|
204
|
+
bucketIdTransformer: BucketIdTransformer;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* A row associated with the table it's coming from.
|
|
208
|
+
*/
|
|
209
|
+
export interface TableRow<R = SqliteRow> {
|
|
170
210
|
sourceTable: SourceTableInterface;
|
|
171
|
-
record:
|
|
211
|
+
record: R;
|
|
172
212
|
}
|
|
173
213
|
/**
|
|
174
|
-
* This is a clause that matches row and parameter values.
|
|
214
|
+
* This is a clause that matches row and parameter values for equality.
|
|
175
215
|
*
|
|
176
216
|
* Example:
|
|
177
217
|
* [WHERE] users.org_id = bucket.org_id
|
|
@@ -186,6 +226,9 @@ export interface ParameterMatchClause {
|
|
|
186
226
|
* * ['token_parameters.user_id'] for a parameter query
|
|
187
227
|
*
|
|
188
228
|
* These parameters are always matched by this clause, and no additional parameters are matched.
|
|
229
|
+
*
|
|
230
|
+
* For a single match clause, this array will have a single element. When match clauses are combined with `AND`,
|
|
231
|
+
* the result is represented as a {@link ParameterMatchClause} with multiple input parameters.
|
|
189
232
|
*/
|
|
190
233
|
inputParameters: InputParameter[];
|
|
191
234
|
/**
|
package/dist/types.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { JSONBig } from '@powersync/service-jsonbig';
|
|
2
2
|
import { toSyncRulesParameters } from './utils.js';
|
|
3
|
+
import { CompatibilityContext } from './compatibility.js';
|
|
3
4
|
export function isEvaluationError(e) {
|
|
4
5
|
return typeof e.error == 'string';
|
|
5
6
|
}
|
|
@@ -16,12 +17,24 @@ export class RequestParameters {
|
|
|
16
17
|
* JSON string of raw request parameters.
|
|
17
18
|
*/
|
|
18
19
|
rawUserParameters;
|
|
20
|
+
streamParameters;
|
|
21
|
+
rawStreamParameters;
|
|
19
22
|
/**
|
|
20
23
|
* JSON string of raw request parameters.
|
|
21
24
|
*/
|
|
22
25
|
rawTokenPayload;
|
|
23
26
|
userId;
|
|
24
27
|
constructor(tokenPayload, clientParameters) {
|
|
28
|
+
if (tokenPayload instanceof RequestParameters) {
|
|
29
|
+
this.tokenParameters = tokenPayload.tokenParameters;
|
|
30
|
+
this.userParameters = tokenPayload.userParameters;
|
|
31
|
+
this.rawUserParameters = tokenPayload.rawUserParameters;
|
|
32
|
+
this.rawTokenPayload = tokenPayload.rawTokenPayload;
|
|
33
|
+
this.streamParameters = tokenPayload.streamParameters;
|
|
34
|
+
this.rawStreamParameters = tokenPayload.rawStreamParameters;
|
|
35
|
+
this.userId = tokenPayload.userId;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
25
38
|
// This type is verified when we verify the token
|
|
26
39
|
const legacyParameters = tokenPayload.parameters;
|
|
27
40
|
const tokenParameters = {
|
|
@@ -29,11 +42,15 @@ export class RequestParameters {
|
|
|
29
42
|
// sub takes presedence over any embedded parameters
|
|
30
43
|
user_id: tokenPayload.sub
|
|
31
44
|
};
|
|
32
|
-
|
|
45
|
+
// Client and token parameters don't contain DateTime values or other custom types, so we don't need to consider
|
|
46
|
+
// compatibility.
|
|
47
|
+
this.tokenParameters = toSyncRulesParameters(tokenParameters, CompatibilityContext.FULL_BACKWARDS_COMPATIBILITY);
|
|
33
48
|
this.userId = tokenPayload.sub;
|
|
34
49
|
this.rawTokenPayload = JSONBig.stringify(tokenPayload);
|
|
35
50
|
this.rawUserParameters = JSONBig.stringify(clientParameters);
|
|
36
|
-
this.userParameters = toSyncRulesParameters(clientParameters);
|
|
51
|
+
this.userParameters = toSyncRulesParameters(clientParameters, CompatibilityContext.FULL_BACKWARDS_COMPATIBILITY);
|
|
52
|
+
this.streamParameters = null;
|
|
53
|
+
this.rawStreamParameters = null;
|
|
37
54
|
}
|
|
38
55
|
lookup(table, column) {
|
|
39
56
|
if (table == 'token_parameters') {
|
|
@@ -42,7 +59,16 @@ export class RequestParameters {
|
|
|
42
59
|
else if (table == 'user_parameters') {
|
|
43
60
|
return this.userParameters[column];
|
|
44
61
|
}
|
|
62
|
+
else if (table == 'subscription_parameters' && this.streamParameters != null) {
|
|
63
|
+
return this.streamParameters[column];
|
|
64
|
+
}
|
|
45
65
|
throw new Error(`Unknown table: ${table}`);
|
|
46
66
|
}
|
|
67
|
+
withAddedStreamParameters(params) {
|
|
68
|
+
const clone = new RequestParameters(this);
|
|
69
|
+
clone.streamParameters = params;
|
|
70
|
+
clone.rawStreamParameters = JSONBig.stringify(params);
|
|
71
|
+
return clone;
|
|
72
|
+
}
|
|
47
73
|
}
|
|
48
74
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,4BAA4B,CAAC;AAKpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Replacer } from '@powersync/service-jsonbig';
|
|
2
2
|
import { SelectFromStatement, Statement } from 'pgsql-ast-parser';
|
|
3
|
-
import { DatabaseInputRow, SqliteJsonRow, SqliteJsonValue, SqliteRow, SqliteValue } from './types.js';
|
|
3
|
+
import { DatabaseInputRow, DatabaseInputValue, SqliteInputValue, SqliteInputRow, SqliteJsonRow, SqliteJsonValue, SqliteRow, SqliteValue, BucketIdTransformer } from './types.js';
|
|
4
|
+
import { CompatibilityContext } from './compatibility.js';
|
|
4
5
|
export declare function isSelectStatement(q: Statement): q is SelectFromStatement;
|
|
5
|
-
export declare function getBucketId(descriptor_id: string, bucket_parameters: string[], params: Record<string, SqliteJsonValue
|
|
6
|
+
export declare function getBucketId(descriptor_id: string, bucket_parameters: string[], params: Record<string, SqliteJsonValue>, transformer: BucketIdTransformer): string;
|
|
6
7
|
/**
|
|
7
8
|
* SqliteRow -> SqliteJsonRow.
|
|
8
9
|
*
|
|
@@ -16,24 +17,26 @@ export declare function filterJsonRow(data: SqliteRow): SqliteJsonRow;
|
|
|
16
17
|
*
|
|
17
18
|
* Types specifically not supported in output are `boolean` and `undefined`.
|
|
18
19
|
*/
|
|
19
|
-
export declare function jsonValueToSqlite(value: null | undefined | string | number | bigint | boolean | any): SqliteValue;
|
|
20
|
+
export declare function jsonValueToSqlite(fixedJsonBehavior: boolean, value: null | undefined | string | number | bigint | boolean | any): SqliteValue;
|
|
20
21
|
export declare function isJsonValue(value: SqliteValue): value is SqliteJsonValue;
|
|
21
22
|
/**
|
|
22
23
|
* Map database row to SqliteRow for use in sync rules.
|
|
23
24
|
*/
|
|
24
|
-
export declare function toSyncRulesRow(row: DatabaseInputRow):
|
|
25
|
+
export declare function toSyncRulesRow(row: DatabaseInputRow): SqliteInputRow;
|
|
25
26
|
/**
|
|
26
27
|
* Convert parameter query input to a SqliteJsonRow.
|
|
27
28
|
*
|
|
28
29
|
* @param parameters Generic JSON input
|
|
29
30
|
*/
|
|
30
|
-
export declare function toSyncRulesParameters(parameters: Record<string, any
|
|
31
|
+
export declare function toSyncRulesParameters(parameters: Record<string, any>, context: CompatibilityContext): SqliteJsonRow;
|
|
31
32
|
/**
|
|
32
33
|
* Convert to a SQLITE-equivalent value: NULL, TEXT, INTEGER, REAL or BLOB.
|
|
33
34
|
*
|
|
34
35
|
* Any object or array is converted to JSON TEXT.
|
|
35
36
|
*/
|
|
36
|
-
export declare function toSyncRulesValue(data:
|
|
37
|
+
export declare function toSyncRulesValue(data: DatabaseInputValue, autoBigNum?: boolean, keepUndefined?: boolean): SqliteInputValue;
|
|
38
|
+
export declare function applyValueContext(value: SqliteInputValue, context: CompatibilityContext): SqliteValue;
|
|
39
|
+
export declare function applyRowContext<MaybeToast extends undefined = never>(value: SqliteRow<SqliteInputValue | MaybeToast>, context: CompatibilityContext): SqliteRow<SqliteValue | MaybeToast>;
|
|
37
40
|
/**
|
|
38
41
|
* Only use this for serializing bucket names. Bucket names should never be parsed except perhaps for debug purposes.
|
|
39
42
|
*
|
package/dist/utils.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { JSONBig, JsonContainer, stringifyRaw } from '@powersync/service-jsonbig';
|
|
2
2
|
import { SQLITE_FALSE, SQLITE_TRUE } from './sql_support.js';
|
|
3
3
|
import { SyncRuleProcessingError as SyncRulesProcessingError } from './errors.js';
|
|
4
|
+
import { CustomArray, CustomObject, CustomSqliteValue } from './types/custom_sqlite_value.js';
|
|
4
5
|
export function isSelectStatement(q) {
|
|
5
6
|
return q.type == 'select';
|
|
6
7
|
}
|
|
7
|
-
export function getBucketId(descriptor_id, bucket_parameters, params) {
|
|
8
|
+
export function getBucketId(descriptor_id, bucket_parameters, params, transformer) {
|
|
8
9
|
// Important: REAL and INTEGER values matching the same number needs the same representation in the bucket name.
|
|
9
10
|
const paramArray = bucket_parameters.map((name) => params[`bucket.${name}`]);
|
|
10
|
-
return `${descriptor_id}${JSONBucketNameSerialize.stringify(paramArray)}
|
|
11
|
+
return transformer(`${descriptor_id}${JSONBucketNameSerialize.stringify(paramArray)}`);
|
|
11
12
|
}
|
|
12
13
|
const DEPTH_LIMIT = 10;
|
|
13
14
|
/**
|
|
@@ -32,11 +33,17 @@ export function filterJsonRow(data) {
|
|
|
32
33
|
*
|
|
33
34
|
* Types specifically not supported in output are `boolean` and `undefined`.
|
|
34
35
|
*/
|
|
35
|
-
export function jsonValueToSqlite(value) {
|
|
36
|
+
export function jsonValueToSqlite(fixedJsonBehavior, value) {
|
|
37
|
+
let isObject = typeof value == 'object';
|
|
38
|
+
if (fixedJsonBehavior) {
|
|
39
|
+
// With the fixed json behavior, make json_extract() not represent a null value as 'null' but instead use a SQL NULL
|
|
40
|
+
// value.
|
|
41
|
+
isObject = isObject && value != null;
|
|
42
|
+
}
|
|
36
43
|
if (typeof value == 'boolean') {
|
|
37
44
|
return value ? SQLITE_TRUE : SQLITE_FALSE;
|
|
38
45
|
}
|
|
39
|
-
else if (
|
|
46
|
+
else if (isObject || Array.isArray(value)) {
|
|
40
47
|
// Objects and arrays must be stringified
|
|
41
48
|
return JSONBig.stringify(value);
|
|
42
49
|
}
|
|
@@ -47,7 +54,7 @@ export function jsonValueToSqlite(value) {
|
|
|
47
54
|
export function isJsonValue(value) {
|
|
48
55
|
return value == null || typeof value == 'string' || typeof value == 'number' || typeof value == 'bigint';
|
|
49
56
|
}
|
|
50
|
-
function filterJsonData(data, depth = 0) {
|
|
57
|
+
function filterJsonData(data, context, depth = 0) {
|
|
51
58
|
if (depth > DEPTH_LIMIT) {
|
|
52
59
|
// This is primarily to prevent infinite recursion
|
|
53
60
|
// TODO: Proper error class
|
|
@@ -68,7 +75,7 @@ function filterJsonData(data, depth = 0) {
|
|
|
68
75
|
return data;
|
|
69
76
|
}
|
|
70
77
|
else if (Array.isArray(data)) {
|
|
71
|
-
return data.map((element) => filterJsonData(element, depth + 1));
|
|
78
|
+
return data.map((element) => filterJsonData(element, context, depth + 1));
|
|
72
79
|
}
|
|
73
80
|
else if (ArrayBuffer.isView(data)) {
|
|
74
81
|
return undefined;
|
|
@@ -77,10 +84,13 @@ function filterJsonData(data, depth = 0) {
|
|
|
77
84
|
// Can be stringified directly when using our JSONBig implementation
|
|
78
85
|
return data;
|
|
79
86
|
}
|
|
87
|
+
else if (data instanceof CustomSqliteValue) {
|
|
88
|
+
return data.toSqliteValue(context);
|
|
89
|
+
}
|
|
80
90
|
else if (typeof data == 'object') {
|
|
81
91
|
let record = {};
|
|
82
92
|
for (let key of Object.keys(data)) {
|
|
83
|
-
record[key] = filterJsonData(data[key], depth + 1);
|
|
93
|
+
record[key] = filterJsonData(data[key], context, depth + 1);
|
|
84
94
|
}
|
|
85
95
|
return record;
|
|
86
96
|
}
|
|
@@ -103,10 +113,10 @@ export function toSyncRulesRow(row) {
|
|
|
103
113
|
*
|
|
104
114
|
* @param parameters Generic JSON input
|
|
105
115
|
*/
|
|
106
|
-
export function toSyncRulesParameters(parameters) {
|
|
116
|
+
export function toSyncRulesParameters(parameters, context) {
|
|
107
117
|
let record = {};
|
|
108
118
|
for (let key of Object.keys(parameters)) {
|
|
109
|
-
record[key] = toSyncRulesValue(parameters[key], true, false);
|
|
119
|
+
record[key] = applyValueContext(toSyncRulesValue(parameters[key], true, false), context);
|
|
110
120
|
}
|
|
111
121
|
return record;
|
|
112
122
|
}
|
|
@@ -141,26 +151,41 @@ export function toSyncRulesValue(data, autoBigNum, keepUndefined) {
|
|
|
141
151
|
return data ? SQLITE_TRUE : SQLITE_FALSE;
|
|
142
152
|
}
|
|
143
153
|
else if (Array.isArray(data)) {
|
|
144
|
-
|
|
145
|
-
return JSONBig.stringify(data.map((element) => filterJsonData(element)));
|
|
154
|
+
return new CustomArray(data, filterJsonData);
|
|
146
155
|
}
|
|
147
|
-
else if (data instanceof Uint8Array) {
|
|
156
|
+
else if (data instanceof Uint8Array || data instanceof CustomSqliteValue) {
|
|
148
157
|
return data;
|
|
149
158
|
}
|
|
150
159
|
else if (data instanceof JsonContainer) {
|
|
151
160
|
return data.toString();
|
|
152
161
|
}
|
|
153
162
|
else if (typeof data == 'object') {
|
|
154
|
-
|
|
155
|
-
for (let key of Object.keys(data)) {
|
|
156
|
-
record[key] = filterJsonData(data[key]);
|
|
157
|
-
}
|
|
158
|
-
return JSONBig.stringify(record);
|
|
163
|
+
return new CustomObject(data, filterJsonData);
|
|
159
164
|
}
|
|
160
165
|
else {
|
|
161
166
|
return null;
|
|
162
167
|
}
|
|
163
168
|
}
|
|
169
|
+
export function applyValueContext(value, context) {
|
|
170
|
+
if (value instanceof CustomSqliteValue) {
|
|
171
|
+
return value.toSqliteValue(context);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
return value;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export function applyRowContext(value, context) {
|
|
178
|
+
let record = {};
|
|
179
|
+
for (let [key, rawValue] of Object.entries(value)) {
|
|
180
|
+
if (rawValue === undefined) {
|
|
181
|
+
record[key] = undefined;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
record[key] = applyValueContext(rawValue, context);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return record;
|
|
188
|
+
}
|
|
164
189
|
/**
|
|
165
190
|
* Only use this for serializing bucket names. Bucket names should never be parsed except perhaps for debug purposes.
|
|
166
191
|
*
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAY,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE5F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/service-sync-rules",
|
|
3
3
|
"repository": "https://github.com/powersync-ja/powersync-service",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.29.1",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
-
"license": "FSL-1.1-
|
|
7
|
+
"license": "FSL-1.1-ALv2",
|
|
8
8
|
"publishConfig": {
|
|
9
9
|
"access": "public"
|
|
10
10
|
},
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"pgsql-ast-parser": "^11.1.0",
|
|
20
20
|
"uuid": "^11.1.0",
|
|
21
21
|
"yaml": "^2.3.1",
|
|
22
|
-
"@powersync/service-jsonbig": "^0.17.
|
|
22
|
+
"@powersync/service-jsonbig": "^0.17.11"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/node": "^22.16.2",
|
package/schema/sync_rules.json
CHANGED
|
@@ -61,6 +61,50 @@
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
|
+
"streams": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"description": "List of stream definitions",
|
|
67
|
+
"examples": [
|
|
68
|
+
{
|
|
69
|
+
"user_details": {
|
|
70
|
+
"query": "select * from users where id = auth.user_id()"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"patternProperties": {
|
|
75
|
+
".*": {
|
|
76
|
+
"type": "object",
|
|
77
|
+
"required": [
|
|
78
|
+
"query"
|
|
79
|
+
],
|
|
80
|
+
"examples": [
|
|
81
|
+
{
|
|
82
|
+
"query": [
|
|
83
|
+
"select * from mytable"
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"properties": {
|
|
88
|
+
"accept_potentially_dangerous_queries": {
|
|
89
|
+
"description": "If true, disables warnings on potentially dangerous queries",
|
|
90
|
+
"type": "boolean"
|
|
91
|
+
},
|
|
92
|
+
"auto_subscribe": {
|
|
93
|
+
"description": "Whether clients will subscribe to this stream by default.",
|
|
94
|
+
"type": "boolean"
|
|
95
|
+
},
|
|
96
|
+
"priority": {
|
|
97
|
+
"description": "Priority for the bucket (lower values indicate higher priority).",
|
|
98
|
+
"type": "integer"
|
|
99
|
+
},
|
|
100
|
+
"query": {
|
|
101
|
+
"description": "The SQL query defining content to sync in this stream.",
|
|
102
|
+
"type": "string"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
64
108
|
"event_definitions": {
|
|
65
109
|
"type": "object",
|
|
66
110
|
"description": "Record of sync replication event definitions",
|
|
@@ -101,10 +145,48 @@
|
|
|
101
145
|
}
|
|
102
146
|
}
|
|
103
147
|
}
|
|
148
|
+
},
|
|
149
|
+
"config": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"description": "Config declaring the compatibility level used to parse these definitions.",
|
|
152
|
+
"properties": {
|
|
153
|
+
"edition": {
|
|
154
|
+
"type": "integer",
|
|
155
|
+
"default": 1,
|
|
156
|
+
"minimum": 1,
|
|
157
|
+
"exclusiveMaximum": 3
|
|
158
|
+
},
|
|
159
|
+
"timestamps_iso8601": {
|
|
160
|
+
"type": "boolean",
|
|
161
|
+
"description": "Enabled by default starting from edition 2: Consistently renders timestamps with an ISO 8601-compatible format (previous versions used a space instead of a T to separate date and time)."
|
|
162
|
+
},
|
|
163
|
+
"versioned_bucket_ids": {
|
|
164
|
+
"type": "boolean",
|
|
165
|
+
"description": "Enabled by default starting from edition 2: Encode the version of sync rules in generated bucket ids, which avoids clients downloading data twice and improves client-side progress estimates."
|
|
166
|
+
},
|
|
167
|
+
"fixed_json_extract": {
|
|
168
|
+
"type": "boolean",
|
|
169
|
+
"description": "Enabled by default starting from edition 2: Old versions of the sync service used to treat `->> 'foo.bar'` as a two-element JSON path. With this compatibility option enabled, it follows modern SQLite and treats it as a single key. The `$.` prefix would be required to split on `.`."
|
|
170
|
+
},
|
|
171
|
+
"custom_postgres_types": {
|
|
172
|
+
"type": "boolean",
|
|
173
|
+
"description": "Enabled by default starting from edition 2: Map custom Postgres types into appropriate structures instead of syncing the raw string."
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"additionalProperties": false
|
|
104
177
|
}
|
|
105
178
|
},
|
|
106
|
-
"
|
|
107
|
-
|
|
179
|
+
"anyOf": [
|
|
180
|
+
{
|
|
181
|
+
"required": [
|
|
182
|
+
"bucket_definitions"
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"required": [
|
|
187
|
+
"streams"
|
|
188
|
+
]
|
|
189
|
+
}
|
|
108
190
|
],
|
|
109
191
|
"additionalProperties": false
|
|
110
192
|
}
|