@powersync/service-sync-rules 0.0.0-dev-20261005120023 → 0.0.0-dev-20261015071128

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.
Files changed (49) hide show
  1. package/dist/HydratedSyncConfig.js +4 -1
  2. package/dist/HydratedSyncConfig.js.map +1 -1
  3. package/dist/SourceTableConfig.d.ts +15 -6
  4. package/dist/SourceTableConfig.js +50 -33
  5. package/dist/SourceTableConfig.js.map +1 -1
  6. package/dist/SqlSyncRules.d.ts +11 -12
  7. package/dist/SqlSyncRules.js +1 -2
  8. package/dist/SqlSyncRules.js.map +1 -1
  9. package/dist/SyncConfig.d.ts +0 -5
  10. package/dist/SyncConfig.js +0 -4
  11. package/dist/SyncConfig.js.map +1 -1
  12. package/dist/SyncConfigDiagnostics.d.ts +12 -0
  13. package/dist/SyncConfigDiagnostics.js +2 -0
  14. package/dist/SyncConfigDiagnostics.js.map +1 -0
  15. package/dist/from_yaml.d.ts +2 -13
  16. package/dist/from_yaml.js +98 -72
  17. package/dist/from_yaml.js.map +1 -1
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.js +3 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/json_schema.d.ts +1 -2
  22. package/dist/json_schema.js +6 -9
  23. package/dist/json_schema.js.map +1 -1
  24. package/dist/legacy/streams/from_sql.js +1 -1
  25. package/dist/legacy/streams/from_sql.js.map +1 -1
  26. package/dist/mongo/MongoBsonValidators.d.ts +78 -0
  27. package/dist/mongo/MongoBsonValidators.js +129 -0
  28. package/dist/mongo/MongoBsonValidators.js.map +1 -0
  29. package/dist/mongo/MongoFilterExpression.d.ts +65 -0
  30. package/dist/mongo/MongoFilterExpression.js +183 -0
  31. package/dist/mongo/MongoFilterExpression.js.map +1 -0
  32. package/dist/mongo/MongoFilterValidation.d.ts +28 -0
  33. package/dist/mongo/MongoFilterValidation.js +47 -0
  34. package/dist/mongo/MongoFilterValidation.js.map +1 -0
  35. package/dist/sync_plan/evaluator/index.js +0 -1
  36. package/dist/sync_plan/evaluator/index.js.map +1 -1
  37. package/dist/sync_plan/plan.d.ts +0 -4
  38. package/dist/sync_plan/serialize.d.ts +0 -5
  39. package/dist/sync_plan/serialize.js +1 -20
  40. package/dist/sync_plan/serialize.js.map +1 -1
  41. package/dist/yaml_source_locations.d.ts +2 -2
  42. package/dist/yaml_source_locations.js +7 -12
  43. package/dist/yaml_source_locations.js.map +1 -1
  44. package/package.json +4 -2
  45. package/schema/sync_config.json +371 -4
  46. package/schema/sync_rules.json +371 -4
  47. package/dist/SyncConfigParserHooks.d.ts +0 -103
  48. package/dist/SyncConfigParserHooks.js +0 -11
  49. package/dist/SyncConfigParserHooks.js.map +0 -1
@@ -1,9 +1,366 @@
1
1
  {
2
2
  "type": "object",
3
+ "definitions": {
4
+ "mongodb_filter_expression": {
5
+ "allOf": [
6
+ {
7
+ "$ref": "#/definitions/__schema0"
8
+ }
9
+ ]
10
+ },
11
+ "__schema0": {
12
+ "anyOf": [
13
+ {
14
+ "type": "object",
15
+ "properties": {
16
+ "$eq": {
17
+ "type": "array",
18
+ "items": [
19
+ {
20
+ "$ref": "#/definitions/__schema1"
21
+ },
22
+ {
23
+ "$ref": "#/definitions/__schema2"
24
+ }
25
+ ],
26
+ "additionalItems": false,
27
+ "minItems": 2,
28
+ "maxItems": 2,
29
+ "description": "Compare a source field with a scalar constant.",
30
+ "examples": [
31
+ [
32
+ "$$doc.status",
33
+ "active"
34
+ ]
35
+ ]
36
+ }
37
+ },
38
+ "required": [
39
+ "$eq"
40
+ ],
41
+ "additionalProperties": false
42
+ },
43
+ {
44
+ "type": "object",
45
+ "properties": {
46
+ "$in": {
47
+ "type": "array",
48
+ "items": [
49
+ {
50
+ "$ref": "#/definitions/__schema1"
51
+ },
52
+ {
53
+ "$ref": "#/definitions/__schema6"
54
+ }
55
+ ],
56
+ "additionalItems": false,
57
+ "minItems": 2,
58
+ "maxItems": 2,
59
+ "examples": [
60
+ [
61
+ "$$doc.status",
62
+ [
63
+ "pending",
64
+ "shipped"
65
+ ]
66
+ ]
67
+ ]
68
+ }
69
+ },
70
+ "required": [
71
+ "$in"
72
+ ],
73
+ "additionalProperties": false
74
+ },
75
+ {
76
+ "type": "object",
77
+ "properties": {
78
+ "$and": {
79
+ "minItems": 1,
80
+ "type": "array",
81
+ "items": {
82
+ "$ref": "#/definitions/mongodb_filter_expression"
83
+ },
84
+ "examples": [
85
+ [
86
+ {
87
+ "$eq": [
88
+ "$$doc.active",
89
+ true
90
+ ]
91
+ }
92
+ ]
93
+ ]
94
+ }
95
+ },
96
+ "required": [
97
+ "$and"
98
+ ],
99
+ "additionalProperties": false
100
+ },
101
+ {
102
+ "type": "object",
103
+ "properties": {
104
+ "$or": {
105
+ "minItems": 1,
106
+ "type": "array",
107
+ "items": {
108
+ "$ref": "#/definitions/mongodb_filter_expression"
109
+ },
110
+ "examples": [
111
+ [
112
+ {
113
+ "$eq": [
114
+ "$$doc.status",
115
+ "pending"
116
+ ]
117
+ },
118
+ {
119
+ "$eq": [
120
+ "$$doc.priority",
121
+ true
122
+ ]
123
+ }
124
+ ]
125
+ ]
126
+ }
127
+ },
128
+ "required": [
129
+ "$or"
130
+ ],
131
+ "additionalProperties": false
132
+ }
133
+ ]
134
+ },
135
+ "__schema1": {
136
+ "type": "string",
137
+ "pattern": "^\\$\\$doc(?:\\.(?![0-9]+(?:\\.|$))[^.$][^.]*)+$"
138
+ },
139
+ "__schema2": {
140
+ "anyOf": [
141
+ {
142
+ "type": "boolean"
143
+ },
144
+ {
145
+ "type": "number"
146
+ },
147
+ {
148
+ "type": "string",
149
+ "pattern": "^(?!\\$)"
150
+ },
151
+ {
152
+ "anyOf": [
153
+ {
154
+ "type": "object",
155
+ "properties": {
156
+ "$literal": {
157
+ "type": "string"
158
+ }
159
+ },
160
+ "required": [
161
+ "$literal"
162
+ ],
163
+ "additionalProperties": false
164
+ },
165
+ {
166
+ "type": "object",
167
+ "properties": {
168
+ "$oid": {
169
+ "type": "string",
170
+ "pattern": "^[0-9a-fA-F]{24}$"
171
+ }
172
+ },
173
+ "required": [
174
+ "$oid"
175
+ ],
176
+ "additionalProperties": false
177
+ },
178
+ {
179
+ "type": "object",
180
+ "properties": {
181
+ "$numberInt": {
182
+ "allOf": [
183
+ {
184
+ "$ref": "#/definitions/__schema3"
185
+ }
186
+ ]
187
+ }
188
+ },
189
+ "required": [
190
+ "$numberInt"
191
+ ],
192
+ "additionalProperties": false
193
+ },
194
+ {
195
+ "type": "object",
196
+ "properties": {
197
+ "$numberLong": {
198
+ "allOf": [
199
+ {
200
+ "$ref": "#/definitions/__schema3"
201
+ }
202
+ ]
203
+ }
204
+ },
205
+ "required": [
206
+ "$numberLong"
207
+ ],
208
+ "additionalProperties": false
209
+ },
210
+ {
211
+ "type": "object",
212
+ "properties": {
213
+ "$numberDouble": {
214
+ "type": "string",
215
+ "pattern": "^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$"
216
+ }
217
+ },
218
+ "required": [
219
+ "$numberDouble"
220
+ ],
221
+ "additionalProperties": false
222
+ },
223
+ {
224
+ "type": "object",
225
+ "properties": {
226
+ "$numberDecimal": {
227
+ "type": "string"
228
+ }
229
+ },
230
+ "required": [
231
+ "$numberDecimal"
232
+ ],
233
+ "additionalProperties": false
234
+ },
235
+ {
236
+ "type": "object",
237
+ "properties": {
238
+ "$uuid": {
239
+ "type": "string",
240
+ "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
241
+ }
242
+ },
243
+ "required": [
244
+ "$uuid"
245
+ ],
246
+ "additionalProperties": false
247
+ },
248
+ {
249
+ "type": "object",
250
+ "properties": {
251
+ "$date": {
252
+ "anyOf": [
253
+ {
254
+ "type": "string",
255
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$"
256
+ },
257
+ {
258
+ "type": "object",
259
+ "properties": {
260
+ "$numberLong": {
261
+ "allOf": [
262
+ {
263
+ "$ref": "#/definitions/__schema3"
264
+ }
265
+ ]
266
+ }
267
+ },
268
+ "required": [
269
+ "$numberLong"
270
+ ],
271
+ "additionalProperties": false
272
+ }
273
+ ]
274
+ }
275
+ },
276
+ "required": [
277
+ "$date"
278
+ ],
279
+ "additionalProperties": false
280
+ },
281
+ {
282
+ "type": "object",
283
+ "properties": {
284
+ "$timestamp": {
285
+ "type": "object",
286
+ "properties": {
287
+ "t": {
288
+ "type": "integer",
289
+ "minimum": 0,
290
+ "maximum": 4294967295
291
+ },
292
+ "i": {
293
+ "type": "integer",
294
+ "minimum": 0,
295
+ "maximum": 4294967295
296
+ }
297
+ },
298
+ "required": [
299
+ "t",
300
+ "i"
301
+ ],
302
+ "additionalProperties": false
303
+ }
304
+ },
305
+ "required": [
306
+ "$timestamp"
307
+ ],
308
+ "additionalProperties": false
309
+ },
310
+ {
311
+ "type": "object",
312
+ "properties": {
313
+ "$binary": {
314
+ "type": "object",
315
+ "properties": {
316
+ "base64": {
317
+ "$ref": "#/definitions/__schema4"
318
+ },
319
+ "subType": {
320
+ "$ref": "#/definitions/__schema5"
321
+ }
322
+ },
323
+ "required": [
324
+ "base64",
325
+ "subType"
326
+ ],
327
+ "additionalProperties": false
328
+ }
329
+ },
330
+ "required": [
331
+ "$binary"
332
+ ],
333
+ "additionalProperties": false
334
+ }
335
+ ]
336
+ }
337
+ ]
338
+ },
339
+ "__schema3": {
340
+ "type": "string",
341
+ "pattern": "^-?(?:0|[1-9][0-9]*)$"
342
+ },
343
+ "__schema4": {
344
+ "type": "string",
345
+ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/][AQgw]==|[A-Za-z0-9+/]{2}[AEIMQUYcgkosw048]=)?$"
346
+ },
347
+ "__schema5": {
348
+ "type": "string",
349
+ "pattern": "^[0-9a-fA-F]{2}$"
350
+ },
351
+ "__schema6": {
352
+ "minItems": 1,
353
+ "type": "array",
354
+ "items": {
355
+ "$ref": "#/definitions/__schema2"
356
+ }
357
+ }
358
+ },
3
359
  "properties": {
4
360
  "bucket_definitions": {
5
361
  "type": "object",
6
- "description": "List of bucket definitions",
362
+ "deprecated": true,
363
+ "description": "Deprecated: legacy Sync Rules bucket definitions. They will be removed in the next major version of the PowerSync Service. Use `streams:` (Sync Streams) instead: https://docs.powersync.com/sync/rules/migrate-to-sync-streams",
7
364
  "examples": [
8
365
  {
9
366
  "global": {
@@ -176,12 +533,22 @@
176
533
  "type": "object",
177
534
  "propertyNames": {
178
535
  "minLength": 1,
179
- "pattern": "^(?:[^.\"]+|\"(?:[^\"]|\"\")+\")(?:\\.(?:[^.\"]+|\"(?:[^\"]|\"\")+\")){0,2}$",
180
- "patternErrorMessage": "Use <table>, <database>.<table>, or <connection>.<database>.<table>. Double-quote names containing dots or quotes."
536
+ "pattern": "^(?:[^.\"]+|\"(?:[^\"]|\"\")+\")(?:\\.(?:[^.\"]+|\"(?:[^\"]|\"\")+\")){0,2}$"
181
537
  },
182
538
  "additionalProperties": {
183
539
  "type": "object",
184
- "properties": {},
540
+ "properties": {
541
+ "mongodb_filter_expression": {
542
+ "anyOf": [
543
+ {
544
+ "$ref": "#/definitions/mongodb_filter_expression"
545
+ },
546
+ {
547
+ "const": "disabled"
548
+ }
549
+ ]
550
+ }
551
+ },
185
552
  "additionalProperties": false
186
553
  }
187
554
  },
@@ -1,103 +0,0 @@
1
- import type { JsonObject } from './json.js';
2
- import type { SyncConfig } from './SyncConfig.js';
3
- import type { TablePattern } from './TablePattern.js';
4
- /**
5
- * A decoded config path, for example `['config', 'source_table_options', 'orders', 'option']`.
6
- */
7
- export type SyncConfigSourcePath = readonly (string | number)[];
8
- export type SyncConfigSourceLocationTarget = 'key' | 'value';
9
- /**
10
- * Offsets into the authored config, compatible with locations returned by service diagnostics.
11
- */
12
- export interface SyncConfigSourceSpan {
13
- start_offset: number;
14
- end_offset: number;
15
- }
16
- /**
17
- * A parser warning or failure, optionally pointing to the relevant config key or value.
18
- */
19
- export interface SyncConfigDiagnostic {
20
- level: 'warning' | 'fatal';
21
- message: string;
22
- location?: SyncConfigSourceSpan;
23
- }
24
- export interface SyncConfigSourceLocationResolver {
25
- /**
26
- * Resolve a field to its source span, falling back to its nearest existing ancestor.
27
- */
28
- getLocation(path: SyncConfigSourcePath, target?: SyncConfigSourceLocationTarget): SyncConfigSourceSpan | undefined;
29
- }
30
- /**
31
- * Context for parsing input sync config.
32
- */
33
- export interface SyncConfigParserContext {
34
- readonly defaultSchema: string;
35
- /**
36
- * Candidate being assembled. With throwOnError: false, a partial config may be returned with fatal diagnostics.
37
- * Store options on the appropriate config fields.
38
- */
39
- parsedConfig: SyncConfig;
40
- /**
41
- * Sources selected by SQL. Additional parsers may inspect these, but cannot add replication sources.
42
- */
43
- sourceTables: readonly TablePattern[];
44
- /**
45
- * Utility helpers for determining source locations.
46
- */
47
- sourceLocations: SyncConfigSourceLocationResolver;
48
- /**
49
- * Report a diagnostic found while parsing.
50
- */
51
- reportDiagnostic(diagnostic: SyncConfigDiagnostic): void;
52
- }
53
- /**
54
- * Context for validating persisted sync config.
55
- */
56
- export interface PersistedSyncConfigParserContext {
57
- /**
58
- * Default schema used to resolve unqualified table names during validation.
59
- * Some callers supply a placeholder; do not persist names qualified using this value.
60
- */
61
- readonly defaultSchema: string;
62
- /**
63
- * Report a warning or fatal error found while validating the persisted config.
64
- * Include a config source location when available. Fatal errors prevent the config from loading.
65
- */
66
- reportDiagnostic(diagnostic: SyncConfigDiagnostic): void;
67
- }
68
- /**
69
- * Additional deterministic parsing/validation, registered per service rather than globally or by source type.
70
- * A hook identifies its own fields and leaves unrelated input alone. Source I/O belongs in source validation.
71
- */
72
- export interface AdditionalSyncConfigParser {
73
- /**
74
- * A unique ID for the parser. Persisted sync configs store these IDs to validate
75
- * if modules which created the persisted config are present.
76
- */
77
- readonly id: string;
78
- /**
79
- * Mutates an isolated schema before parsing.
80
- */
81
- extendJsonSchema?(options: {
82
- schema: JsonObject;
83
- }): void;
84
- /**
85
- * `config` is decoded sync config. Everything else needed to parse it is supplied through `context`.
86
- * Parse module-owned input into context.parsedConfig, including sourceTableConfig entries for this module.
87
- * Core does not copy source-table options from the input or normalize the parser's output here.
88
- * For a PrecompiledSyncConfig, add this parser's ID to parsedConfig.plan.moduleData with a null value
89
- * when the config requires this module. The plan's keys determine which parsers must be present on reload.
90
- */
91
- parse(options: {
92
- config: unknown;
93
- context: SyncConfigParserContext;
94
- }): void;
95
- /**
96
- * Validate saved config fields without reparsing their original config or requiring config source locations.
97
- */
98
- validatePersisted?(options: {
99
- config: SyncConfig;
100
- context: PersistedSyncConfigParserContext;
101
- }): void;
102
- }
103
- export declare function validateAdditionalSyncConfigParsers(parsers: readonly AdditionalSyncConfigParser[]): void;
@@ -1,11 +0,0 @@
1
- export function validateAdditionalSyncConfigParsers(parsers) {
2
- const ids = new Set();
3
- for (const parser of parsers) {
4
- if (!parser.id)
5
- throw new Error('A sync config parser id must not be empty.');
6
- if (ids.has(parser.id))
7
- throw new Error(`A sync config parser is already registered with id '${parser.id}'.`);
8
- ids.add(parser.id);
9
- }
10
- }
11
- //# sourceMappingURL=SyncConfigParserHooks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SyncConfigParserHooks.js","sourceRoot":"","sources":["../src/SyncConfigParserHooks.ts"],"names":[],"mappings":"AAyGA,MAAM,UAAU,mCAAmC,CAAC,OAA8C;IAChG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC9E,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9G,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}