@powersync/service-sync-rules 0.0.0-dev-20240708103353

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 (75) hide show
  1. package/LICENSE +67 -0
  2. package/README.md +129 -0
  3. package/dist/DartSchemaGenerator.d.ts +12 -0
  4. package/dist/DartSchemaGenerator.js +39 -0
  5. package/dist/DartSchemaGenerator.js.map +1 -0
  6. package/dist/ExpressionType.d.ts +33 -0
  7. package/dist/ExpressionType.js +61 -0
  8. package/dist/ExpressionType.js.map +1 -0
  9. package/dist/IdSequence.d.ts +4 -0
  10. package/dist/IdSequence.js +9 -0
  11. package/dist/IdSequence.js.map +1 -0
  12. package/dist/JsSchemaGenerator.d.ts +12 -0
  13. package/dist/JsSchemaGenerator.js +42 -0
  14. package/dist/JsSchemaGenerator.js.map +1 -0
  15. package/dist/SchemaGenerator.d.ts +14 -0
  16. package/dist/SchemaGenerator.js +26 -0
  17. package/dist/SchemaGenerator.js.map +1 -0
  18. package/dist/SourceTableInterface.d.ts +5 -0
  19. package/dist/SourceTableInterface.js +2 -0
  20. package/dist/SourceTableInterface.js.map +1 -0
  21. package/dist/SqlBucketDescriptor.d.ts +37 -0
  22. package/dist/SqlBucketDescriptor.js +111 -0
  23. package/dist/SqlBucketDescriptor.js.map +1 -0
  24. package/dist/SqlDataQuery.d.ts +39 -0
  25. package/dist/SqlDataQuery.js +239 -0
  26. package/dist/SqlDataQuery.js.map +1 -0
  27. package/dist/SqlParameterQuery.d.ts +85 -0
  28. package/dist/SqlParameterQuery.js +311 -0
  29. package/dist/SqlParameterQuery.js.map +1 -0
  30. package/dist/SqlSyncRules.d.ts +52 -0
  31. package/dist/SqlSyncRules.js +264 -0
  32. package/dist/SqlSyncRules.js.map +1 -0
  33. package/dist/StaticSchema.d.ts +26 -0
  34. package/dist/StaticSchema.js +61 -0
  35. package/dist/StaticSchema.js.map +1 -0
  36. package/dist/StaticSqlParameterQuery.d.ts +27 -0
  37. package/dist/StaticSqlParameterQuery.js +96 -0
  38. package/dist/StaticSqlParameterQuery.js.map +1 -0
  39. package/dist/TablePattern.d.ts +17 -0
  40. package/dist/TablePattern.js +56 -0
  41. package/dist/TablePattern.js.map +1 -0
  42. package/dist/TableQuerySchema.d.ts +9 -0
  43. package/dist/TableQuerySchema.js +34 -0
  44. package/dist/TableQuerySchema.js.map +1 -0
  45. package/dist/errors.d.ts +22 -0
  46. package/dist/errors.js +58 -0
  47. package/dist/errors.js.map +1 -0
  48. package/dist/generators.d.ts +6 -0
  49. package/dist/generators.js +7 -0
  50. package/dist/generators.js.map +1 -0
  51. package/dist/index.d.ts +19 -0
  52. package/dist/index.js +20 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/json_schema.d.ts +3 -0
  55. package/dist/json_schema.js +52 -0
  56. package/dist/json_schema.js.map +1 -0
  57. package/dist/request_functions.d.ts +17 -0
  58. package/dist/request_functions.js +41 -0
  59. package/dist/request_functions.js.map +1 -0
  60. package/dist/sql_filters.d.ts +125 -0
  61. package/dist/sql_filters.js +599 -0
  62. package/dist/sql_filters.js.map +1 -0
  63. package/dist/sql_functions.d.ts +61 -0
  64. package/dist/sql_functions.js +863 -0
  65. package/dist/sql_functions.js.map +1 -0
  66. package/dist/sql_support.d.ts +25 -0
  67. package/dist/sql_support.js +254 -0
  68. package/dist/sql_support.js.map +1 -0
  69. package/dist/types.d.ts +262 -0
  70. package/dist/types.js +28 -0
  71. package/dist/types.js.map +1 -0
  72. package/dist/utils.d.ts +44 -0
  73. package/dist/utils.js +167 -0
  74. package/dist/utils.js.map +1 -0
  75. package/package.json +32 -0
@@ -0,0 +1,311 @@
1
+ import { parse } from 'pgsql-ast-parser';
2
+ import { SqlRuleError } from './errors.js';
3
+ import { SqlTools } from './sql_filters.js';
4
+ import { checkUnsupportedFeatures, isClauseError, isParameterValueClause } from './sql_support.js';
5
+ import { StaticSqlParameterQuery } from './StaticSqlParameterQuery.js';
6
+ import { TablePattern } from './TablePattern.js';
7
+ import { TableQuerySchema } from './TableQuerySchema.js';
8
+ import { filterJsonRow, getBucketId, isJsonValue, isSelectStatement } from './utils.js';
9
+ /**
10
+ * Represents a parameter query, such as:
11
+ *
12
+ * SELECT id as user_id FROM users WHERE users.user_id = token_parameters.user_id
13
+ * SELECT id as user_id, token_parameters.is_admin as is_admin FROM users WHERE users.user_id = token_parameters.user_id
14
+ */
15
+ export class SqlParameterQuery {
16
+ static fromSql(descriptor_name, sql, schema, options) {
17
+ const parsed = parse(sql, { locationTracking: true });
18
+ const rows = new SqlParameterQuery();
19
+ if (parsed.length > 1) {
20
+ throw new SqlRuleError('Only a single SELECT statement is supported', sql, parsed[1]?._location);
21
+ }
22
+ const q = parsed[0];
23
+ if (!isSelectStatement(q)) {
24
+ throw new SqlRuleError('Only SELECT statements are supported', sql, q._location);
25
+ }
26
+ if (q.from == null) {
27
+ // E.g. SELECT token_parameters.user_id as user_id WHERE token_parameters.is_admin
28
+ return StaticSqlParameterQuery.fromSql(descriptor_name, sql, q, options);
29
+ }
30
+ rows.errors.push(...checkUnsupportedFeatures(sql, q));
31
+ if (q.from.length != 1 || q.from[0].type != 'table') {
32
+ throw new SqlRuleError('Must SELECT from a single table', sql, q.from?.[0]._location);
33
+ }
34
+ const tableRef = q.from?.[0].name;
35
+ if (tableRef?.name == null) {
36
+ throw new SqlRuleError('Must SELECT from a single table', sql, q.from?.[0]._location);
37
+ }
38
+ const alias = q.from?.[0].name.alias ?? tableRef.name;
39
+ if (tableRef.name != alias) {
40
+ rows.errors.push(new SqlRuleError('Table aliases not supported in parameter queries', sql, q.from?.[0]._location));
41
+ }
42
+ const sourceTable = new TablePattern(tableRef.schema, tableRef.name);
43
+ let querySchema = undefined;
44
+ if (schema) {
45
+ const tables = schema.getTables(sourceTable);
46
+ if (tables.length == 0) {
47
+ const e = new SqlRuleError(`Table ${sourceTable.schema}.${sourceTable.tablePattern} not found`, sql, q.from?.[0]?._location);
48
+ e.type = 'warning';
49
+ rows.errors.push(e);
50
+ }
51
+ else {
52
+ querySchema = new TableQuerySchema(tables, alias);
53
+ }
54
+ }
55
+ const tools = new SqlTools({
56
+ table: alias,
57
+ parameter_tables: ['token_parameters', 'user_parameters'],
58
+ sql,
59
+ supports_expanding_parameters: true,
60
+ supports_parameter_expressions: true,
61
+ schema: querySchema
62
+ });
63
+ const where = q.where;
64
+ const filter = tools.compileWhereClause(where);
65
+ const bucket_parameters = (q.columns ?? []).map((column) => tools.getOutputName(column));
66
+ rows.sourceTable = sourceTable;
67
+ rows.table = alias;
68
+ rows.sql = sql;
69
+ rows.filter = filter;
70
+ rows.descriptor_name = descriptor_name;
71
+ rows.bucket_parameters = bucket_parameters;
72
+ rows.input_parameters = filter.inputParameters;
73
+ const expandedParams = rows.input_parameters.filter((param) => param.expands);
74
+ if (expandedParams.length > 1) {
75
+ rows.errors.push(new SqlRuleError('Cannot have multiple array input parameters', sql));
76
+ }
77
+ rows.expanded_input_parameter = expandedParams[0];
78
+ rows.columns = q.columns ?? [];
79
+ rows.static_columns = [];
80
+ rows.lookup_columns = [];
81
+ for (let column of q.columns ?? []) {
82
+ const name = tools.getSpecificOutputName(column);
83
+ if (tools.isTableRef(column.expr)) {
84
+ rows.lookup_columns.push(column);
85
+ const extractor = tools.compileRowValueExtractor(column.expr);
86
+ if (isClauseError(extractor)) {
87
+ // Error logged already
88
+ continue;
89
+ }
90
+ rows.lookup_extractors[name] = extractor;
91
+ }
92
+ else {
93
+ rows.static_columns.push(column);
94
+ const extractor = tools.compileParameterValueExtractor(column.expr);
95
+ if (isClauseError(extractor)) {
96
+ // Error logged already
97
+ continue;
98
+ }
99
+ rows.parameter_extractors[name] = extractor;
100
+ }
101
+ }
102
+ rows.tools = tools;
103
+ rows.errors.push(...tools.errors);
104
+ if (rows.usesDangerousRequestParameters && !options?.accept_potentially_dangerous_queries) {
105
+ let err = new SqlRuleError('Pontially dangerous query based on unauthenticated client parameters', sql);
106
+ err.type = 'warning';
107
+ rows.errors.push(err);
108
+ }
109
+ return rows;
110
+ }
111
+ constructor() {
112
+ /**
113
+ * Example: SELECT *user.id* FROM users WHERE ...
114
+ */
115
+ this.lookup_extractors = {};
116
+ /**
117
+ * Example: SELECT *token_parameters.user_id*
118
+ */
119
+ this.parameter_extractors = {};
120
+ this.errors = [];
121
+ }
122
+ applies(table) {
123
+ return this.sourceTable.matches(table);
124
+ }
125
+ evaluateParameterRow(row) {
126
+ const tables = {
127
+ [this.table]: row
128
+ };
129
+ try {
130
+ const filterParameters = this.filter.filterRow(tables);
131
+ let result = [];
132
+ for (let filterParamSet of filterParameters) {
133
+ let lookup = [this.descriptor_name, this.id];
134
+ lookup.push(...this.input_parameters.map((param) => {
135
+ return param.filteredRowToLookupValue(filterParamSet);
136
+ }));
137
+ const data = this.transformRows(row);
138
+ const role = {
139
+ bucket_parameters: data.map((row) => filterJsonRow(row)),
140
+ lookup: lookup
141
+ };
142
+ result.push(role);
143
+ }
144
+ return result;
145
+ }
146
+ catch (e) {
147
+ return [{ error: e.message ?? `Evaluating parameter query failed` }];
148
+ }
149
+ }
150
+ transformRows(row) {
151
+ const tables = { [this.table]: row };
152
+ let result = {};
153
+ for (let key in this.lookup_extractors) {
154
+ const extractor = this.lookup_extractors[key];
155
+ result[key] = extractor.evaluate(tables);
156
+ }
157
+ return [result];
158
+ }
159
+ /**
160
+ * Given partial parameter rows, turn into bucket ids.
161
+ */
162
+ resolveBucketIds(bucketParameters, parameters) {
163
+ // Filters have already been applied and gotten us the set of bucketParameters - don't attempt to filter again.
164
+ // We _do_ need to evaluate the output columns here, using a combination of precomputed bucketParameters,
165
+ // and values from token parameters.
166
+ return bucketParameters
167
+ .map((lookup) => {
168
+ let result = {};
169
+ for (let name of this.bucket_parameters) {
170
+ if (name in this.lookup_extractors) {
171
+ result[`bucket.${name}`] = lookup[name];
172
+ }
173
+ else {
174
+ const value = this.parameter_extractors[name].lookupParameterValue(parameters);
175
+ if (!isJsonValue(value)) {
176
+ // Not valid - exclude.
177
+ // Should we error instead?
178
+ return null;
179
+ }
180
+ else {
181
+ result[`bucket.${name}`] = value;
182
+ }
183
+ }
184
+ }
185
+ return getBucketId(this.descriptor_name, this.bucket_parameters, result);
186
+ })
187
+ .filter((lookup) => lookup != null);
188
+ }
189
+ /**
190
+ * Given sync parameters, get lookups we need to perform on the database.
191
+ *
192
+ * Each lookup is [bucket definition name, parameter query index, ...lookup values]
193
+ */
194
+ getLookups(parameters) {
195
+ if (!this.expanded_input_parameter) {
196
+ let lookup = [this.descriptor_name, this.id];
197
+ let valid = true;
198
+ lookup.push(...this.input_parameters.map((param) => {
199
+ // Scalar value
200
+ const value = param.parametersToLookupValue(parameters);
201
+ if (isJsonValue(value)) {
202
+ return value;
203
+ }
204
+ else {
205
+ valid = false;
206
+ return null;
207
+ }
208
+ }));
209
+ if (!valid) {
210
+ return [];
211
+ }
212
+ return [lookup];
213
+ }
214
+ else {
215
+ const arrayString = this.expanded_input_parameter.parametersToLookupValue(parameters);
216
+ if (arrayString == null || typeof arrayString != 'string') {
217
+ return [];
218
+ }
219
+ let values;
220
+ try {
221
+ values = JSON.parse(arrayString);
222
+ if (!Array.isArray(values)) {
223
+ return [];
224
+ }
225
+ }
226
+ catch (e) {
227
+ return [];
228
+ }
229
+ return values
230
+ .map((expandedValue) => {
231
+ let lookup = [this.descriptor_name, this.id];
232
+ let valid = true;
233
+ lookup.push(...this.input_parameters.map((param) => {
234
+ if (param == this.expanded_input_parameter) {
235
+ // Expand array value
236
+ return expandedValue;
237
+ }
238
+ else {
239
+ // Scalar value
240
+ const value = param.parametersToLookupValue(parameters);
241
+ if (isJsonValue(value)) {
242
+ return value;
243
+ }
244
+ else {
245
+ valid = false;
246
+ return null;
247
+ }
248
+ }
249
+ }));
250
+ if (!valid) {
251
+ return null;
252
+ }
253
+ return lookup;
254
+ })
255
+ .filter((lookup) => lookup != null);
256
+ }
257
+ }
258
+ /**
259
+ * Given sync parameters (token and user parameters), return bucket ids.
260
+ *
261
+ * This is done in three steps:
262
+ * 1. Given the parameters, get lookups we need to perform on the database.
263
+ * 2. Perform the lookups, returning parameter sets (partial rows).
264
+ * 3. Given the parameter sets, resolve bucket ids.
265
+ */
266
+ async queryBucketIds(options) {
267
+ let lookups = this.getLookups(options.parameters);
268
+ if (lookups.length == 0) {
269
+ return [];
270
+ }
271
+ const parameters = await options.getParameterSets(lookups);
272
+ return this.resolveBucketIds(parameters, options.parameters);
273
+ }
274
+ get hasAuthenticatedBucketParameters() {
275
+ // select request.user_id() as user_id where ...
276
+ const authenticatedExtractor = Object.values(this.parameter_extractors).find((clause) => isParameterValueClause(clause) && clause.usesAuthenticatedRequestParameters) != null;
277
+ return authenticatedExtractor;
278
+ }
279
+ get hasAuthenticatedMatchClause() {
280
+ // select ... where user_id = request.user_id()
281
+ this.filter?.inputParameters.find;
282
+ const authenticatedInputParameter = this.filter.usesAuthenticatedRequestParameters;
283
+ return authenticatedInputParameter;
284
+ }
285
+ get usesUnauthenticatedRequestParameters() {
286
+ // select ... where request.parameters() ->> 'include_comments'
287
+ const unauthenticatedInputParameter = this.filter.usesUnauthenticatedRequestParameters;
288
+ // select request.parameters() ->> 'project_id'
289
+ const unauthenticatedExtractor = Object.values(this.parameter_extractors).find((clause) => isParameterValueClause(clause) && clause.usesUnauthenticatedRequestParameters) != null;
290
+ return unauthenticatedInputParameter || unauthenticatedExtractor;
291
+ }
292
+ /**
293
+ * Safe:
294
+ * SELECT id as user_id FROM users WHERE users.user_id = request.user_id()
295
+ * SELECT request.jwt() ->> 'org_id' as org_id, id as project_id FROM projects WHERE id = request.parameters() ->> 'project_id'
296
+ * SELECT id as project_id FROM projects WHERE org_id = request.jwt() ->> 'org_id' AND id = request.parameters() ->> 'project_id'
297
+ * SELECT id as category_id FROM categories
298
+ *
299
+ * Dangerous:
300
+ * SELECT id as project_id FROM projects WHERE id = request.parameters() ->> 'project_id'
301
+ * SELECT id as project_id FROM projects WHERE id = request.parameters() ->> 'project_id' AND request.jwt() ->> 'role' = 'authenticated'
302
+ * SELECT id as category_id, request.parameters() ->> 'project_id' as project_id FROM categories
303
+ * SELECT id as category_id FROM categories WHERE request.parameters() ->> 'include_categories'
304
+ */
305
+ get usesDangerousRequestParameters() {
306
+ return (this.usesUnauthenticatedRequestParameters &&
307
+ !this.hasAuthenticatedBucketParameters &&
308
+ !this.hasAuthenticatedMatchClause);
309
+ }
310
+ }
311
+ //# sourceMappingURL=SqlParameterQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlParameterQuery.js","sourceRoot":"","sources":["../src/SqlParameterQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAiBzD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAExF;;;;;GAKG;AACH,MAAM,OAAO,iBAAiB;IAC5B,MAAM,CAAC,OAAO,CACZ,eAAuB,EACvB,GAAW,EACX,MAAqB,EACrB,OAA2B;QAE3B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,iBAAiB,EAAE,CAAC;QAErC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,MAAM,IAAI,YAAY,CAAC,6CAA6C,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;SAClG;QACD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;YACzB,MAAM,IAAI,YAAY,CAAC,sCAAsC,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;SAClF;QAED,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE;YAClB,kFAAkF;YAClF,OAAO,uBAAuB,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;SAC1E;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,wBAAwB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAEtD,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,EAAE;YACnD,MAAM,IAAI,YAAY,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;SACvF;QAED,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAClC,IAAI,QAAQ,EAAE,IAAI,IAAI,IAAI,EAAE;YAC1B,MAAM,IAAI,YAAY,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;SACvF;QACD,MAAM,KAAK,GAAW,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC;QAC9D,IAAI,QAAQ,CAAC,IAAI,IAAI,KAAK,EAAE;YAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,IAAI,YAAY,CAAC,kDAAkD,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CACjG,CAAC;SACH;QACD,MAAM,WAAW,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrE,IAAI,WAAW,GAA4B,SAAS,CAAC;QACrD,IAAI,MAAM,EAAE;YACV,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE;gBACtB,MAAM,CAAC,GAAG,IAAI,YAAY,CACxB,SAAS,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,YAAY,YAAY,EACnE,GAAG,EACH,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CACvB,CAAC;gBACF,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;gBAEnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACrB;iBAAM;gBACL,WAAW,GAAG,IAAI,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;aACnD;SACF;QAED,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC;YACzB,KAAK,EAAE,KAAK;YACZ,gBAAgB,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;YACzD,GAAG;YACH,6BAA6B,EAAE,IAAI;YACnC,8BAA8B,EAAE,IAAI;YACpC,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QACtB,MAAM,MAAM,GAAG,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAE/C,MAAM,iBAAiB,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;QACzF,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,eAAgB,CAAC;QAChD,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAiB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/E,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,6CAA6C,EAAE,GAAG,CAAC,CAAC,CAAC;SACxF;QACD,IAAI,CAAC,wBAAwB,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QAEzB,KAAK,IAAI,MAAM,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;YACjD,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBACjC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACjC,MAAM,SAAS,GAAG,KAAK,CAAC,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC9D,IAAI,aAAa,CAAC,SAAS,CAAC,EAAE;oBAC5B,uBAAuB;oBACvB,SAAS;iBACV;gBACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;aAC1C;iBAAM;gBACL,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACjC,MAAM,SAAS,GAAG,KAAK,CAAC,8BAA8B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACpE,IAAI,aAAa,CAAC,SAAS,CAAC,EAAE;oBAC5B,uBAAuB;oBACvB,SAAS;iBACV;gBACD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;aAC7C;SACF;QACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAElC,IAAI,IAAI,CAAC,8BAA8B,IAAI,CAAC,OAAO,EAAE,oCAAoC,EAAE;YACzF,IAAI,GAAG,GAAG,IAAI,YAAY,CAAC,sEAAsE,EAAE,GAAG,CAAC,CAAC;YACxG,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACvB;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAwCD;QA/BA;;WAEG;QACH,sBAAiB,GAAmC,EAAE,CAAC;QAEvD;;WAEG;QACH,yBAAoB,GAAyC,EAAE,CAAC;QAqBhE,WAAM,GAAmB,EAAE,CAAC;IAEb,CAAC;IAEhB,OAAO,CAAC,KAA2B;QACjC,OAAO,IAAI,CAAC,WAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,oBAAoB,CAAC,GAAc;QACjC,MAAM,MAAM,GAAG;YACb,CAAC,IAAI,CAAC,KAAM,CAAC,EAAE,GAAG;SACnB,CAAC;QACF,IAAI;YACF,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACxD,IAAI,MAAM,GAAgC,EAAE,CAAC;YAC7C,KAAK,IAAI,cAAc,IAAI,gBAAgB,EAAE;gBAC3C,IAAI,MAAM,GAAsB,CAAC,IAAI,CAAC,eAAgB,EAAE,IAAI,CAAC,EAAG,CAAC,CAAC;gBAClE,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,CAAC,gBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBACtC,OAAO,KAAK,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;gBACxD,CAAC,CAAC,CACH,CAAC;gBAEF,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gBAErC,MAAM,IAAI,GAAwB;oBAChC,iBAAiB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;oBACxD,MAAM,EAAE,MAAM;iBACf,CAAC;gBACF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACnB;YACD,OAAO,MAAM,CAAC;SACf;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,IAAI,mCAAmC,EAAE,CAAC,CAAC;SACtE;IACH,CAAC;IAED,aAAa,CAAC,GAAc;QAC1B,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC,KAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QACtC,IAAI,MAAM,GAAc,EAAE,CAAC;QAC3B,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,iBAAiB,EAAE;YACtC,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SAC1C;QACD,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,gBAAiC,EAAE,UAA6B;QAC/E,+GAA+G;QAC/G,yGAAyG;QACzG,oCAAoC;QAEpC,OAAO,gBAAgB;aACpB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACd,IAAI,MAAM,GAAoC,EAAE,CAAC;YACjD,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,iBAAkB,EAAE;gBACxC,IAAI,IAAI,IAAI,IAAI,CAAC,iBAAiB,EAAE;oBAClC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;iBACzC;qBAAM;oBACL,MAAM,KAAK,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;oBAC/E,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;wBACvB,uBAAuB;wBACvB,2BAA2B;wBAC3B,OAAO,IAAI,CAAC;qBACb;yBAAM;wBACL,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC;qBAClC;iBACF;aACF;YAED,OAAO,WAAW,CAAC,IAAI,CAAC,eAAgB,EAAE,IAAI,CAAC,iBAAkB,EAAE,MAAM,CAAC,CAAC;QAC7E,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,IAAI,CAAa,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,UAA6B;QACtC,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE;YAClC,IAAI,MAAM,GAAsB,CAAC,IAAI,CAAC,eAAgB,EAAE,IAAI,CAAC,EAAG,CAAC,CAAC;YAElE,IAAI,KAAK,GAAG,IAAI,CAAC;YACjB,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,CAAC,gBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAmB,EAAE;gBACvD,eAAe;gBACf,MAAM,KAAK,GAAG,KAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;gBAExD,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE;oBACtB,OAAO,KAAK,CAAC;iBACd;qBAAM;oBACL,KAAK,GAAG,KAAK,CAAC;oBACd,OAAO,IAAI,CAAC;iBACb;YACH,CAAC,CAAC,CACH,CAAC;YACF,IAAI,CAAC,KAAK,EAAE;gBACV,OAAO,EAAE,CAAC;aACX;YACD,OAAO,CAAC,MAAM,CAAC,CAAC;SACjB;aAAM;YACL,MAAM,WAAW,GAAG,IAAI,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;YAEtF,IAAI,WAAW,IAAI,IAAI,IAAI,OAAO,WAAW,IAAI,QAAQ,EAAE;gBACzD,OAAO,EAAE,CAAC;aACX;YACD,IAAI,MAAyB,CAAC;YAC9B,IAAI;gBACF,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;oBAC1B,OAAO,EAAE,CAAC;iBACX;aACF;YAAC,OAAO,CAAC,EAAE;gBACV,OAAO,EAAE,CAAC;aACX;YAED,OAAO,MAAM;iBACV,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE;gBACrB,IAAI,MAAM,GAAsB,CAAC,IAAI,CAAC,eAAgB,EAAE,IAAI,CAAC,EAAG,CAAC,CAAC;gBAClE,IAAI,KAAK,GAAG,IAAI,CAAC;gBACjB,MAAM,CAAC,IAAI,CACT,GAAG,IAAI,CAAC,gBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAmB,EAAE;oBACvD,IAAI,KAAK,IAAI,IAAI,CAAC,wBAAwB,EAAE;wBAC1C,qBAAqB;wBACrB,OAAO,aAAa,CAAC;qBACtB;yBAAM;wBACL,eAAe;wBACf,MAAM,KAAK,GAAG,KAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;wBAExD,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE;4BACtB,OAAO,KAAK,CAAC;yBACd;6BAAM;4BACL,KAAK,GAAG,KAAK,CAAC;4BACd,OAAO,IAAI,CAAC;yBACb;qBACF;gBACH,CAAC,CAAC,CACH,CAAC;gBACF,IAAI,CAAC,KAAK,EAAE;oBACV,OAAO,IAAI,CAAC;iBACb;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC,CAAC;iBACD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,IAAI,CAAwB,CAAC;SAC9D;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAAC,OAA6B;QAChD,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE;YACvB,OAAO,EAAE,CAAC;SACX;QAED,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,gCAAgC;QAClC,gDAAgD;QAChD,MAAM,sBAAsB,GAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,kCAAkC,CACxF,IAAI,IAAI,CAAC;QACZ,OAAO,sBAAsB,CAAC;IAChC,CAAC;IAED,IAAI,2BAA2B;QAC7B,+CAA+C;QAC/C,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,IAAI,CAAC;QAClC,MAAM,2BAA2B,GAAG,IAAI,CAAC,MAAO,CAAC,kCAAkC,CAAC;QACpF,OAAO,2BAA2B,CAAC;IACrC,CAAC;IAED,IAAI,oCAAoC;QACtC,+DAA+D;QAC/D,MAAM,6BAA6B,GAAG,IAAI,CAAC,MAAO,CAAC,oCAAoC,CAAC;QAExF,+CAA+C;QAC/C,MAAM,wBAAwB,GAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,oCAAoC,CAC1F,IAAI,IAAI,CAAC;QAEZ,OAAO,6BAA6B,IAAI,wBAAwB,CAAC;IACnE,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,IAAI,8BAA8B;QAChC,OAAO,CACL,IAAI,CAAC,oCAAoC;YACzC,CAAC,IAAI,CAAC,gCAAgC;YACtC,CAAC,IAAI,CAAC,2BAA2B,CAClC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ import { Scalar } from 'yaml';
2
+ import { YamlError } from './errors.js';
3
+ import { IdSequence } from './IdSequence.js';
4
+ import { SourceTableInterface } from './SourceTableInterface.js';
5
+ import { QueryParseResult, SqlBucketDescriptor } from './SqlBucketDescriptor.js';
6
+ import { TablePattern } from './TablePattern.js';
7
+ import { EvaluatedParameters, EvaluatedRow, EvaluateRowOptions, EvaluationError, QueryBucketIdOptions, RequestParameters, SourceSchema, SqliteRow, SyncRules } from './types.js';
8
+ export declare class SqlSyncRules implements SyncRules {
9
+ bucket_descriptors: SqlBucketDescriptor[];
10
+ idSequence: IdSequence;
11
+ content: string;
12
+ errors: YamlError[];
13
+ static validate(yaml: string, options?: {
14
+ schema?: SourceSchema;
15
+ }): YamlError[];
16
+ static fromYaml(yaml: string, options?: {
17
+ throwOnError?: boolean;
18
+ schema?: SourceSchema;
19
+ }): SqlSyncRules;
20
+ throwOnError(): void;
21
+ static tokenError(token: any, message: string): YamlError;
22
+ withScalar(scalar: Scalar, cb: (value: string) => QueryParseResult): QueryParseResult;
23
+ constructor(content: string);
24
+ /**
25
+ * Throws errors.
26
+ */
27
+ evaluateRow(options: EvaluateRowOptions): EvaluatedRow[];
28
+ evaluateRowWithErrors(options: EvaluateRowOptions): {
29
+ results: EvaluatedRow[];
30
+ errors: EvaluationError[];
31
+ };
32
+ /**
33
+ * Throws errors.
34
+ */
35
+ evaluateParameterRow(table: SourceTableInterface, row: SqliteRow): EvaluatedParameters[];
36
+ evaluateParameterRowWithErrors(table: SourceTableInterface, row: SqliteRow): {
37
+ results: EvaluatedParameters[];
38
+ errors: EvaluationError[];
39
+ };
40
+ /**
41
+ * @deprecated For testing only.
42
+ */
43
+ getStaticBucketIds(parameters: RequestParameters): string[];
44
+ /**
45
+ * Note: This can error hard.
46
+ */
47
+ queryBucketIds(options: QueryBucketIdOptions): Promise<string[]>;
48
+ getSourceTables(): TablePattern[];
49
+ tableSyncsData(table: SourceTableInterface): boolean;
50
+ tableSyncsParameters(table: SourceTableInterface): boolean;
51
+ debugGetOutputTables(): Record<string, any[]>;
52
+ }
@@ -0,0 +1,264 @@
1
+ import { LineCounter, parseDocument, Scalar, YAMLSeq } from 'yaml';
2
+ import { SqlRuleError, SyncRulesErrors, YamlError } from './errors.js';
3
+ import { IdSequence } from './IdSequence.js';
4
+ import { validateSyncRulesSchema } from './json_schema.js';
5
+ import { SqlBucketDescriptor } from './SqlBucketDescriptor.js';
6
+ import { isEvaluatedParameters, isEvaluatedRow, isEvaluationError } from './types.js';
7
+ const ACCEPT_POTENTIALLY_DANGEROUS_QUERIES = Symbol('ACCEPT_POTENTIALLY_DANGEROUS_QUERIES');
8
+ export class SqlSyncRules {
9
+ static validate(yaml, options) {
10
+ try {
11
+ const rules = this.fromYaml(yaml, options);
12
+ return rules.errors;
13
+ }
14
+ catch (e) {
15
+ if (e instanceof SyncRulesErrors) {
16
+ return e.errors;
17
+ }
18
+ else if (e instanceof YamlError) {
19
+ return [e];
20
+ }
21
+ else {
22
+ return [new YamlError(e)];
23
+ }
24
+ }
25
+ }
26
+ static fromYaml(yaml, options) {
27
+ const throwOnError = options?.throwOnError ?? true;
28
+ const schema = options?.schema;
29
+ const lineCounter = new LineCounter();
30
+ const parsed = parseDocument(yaml, {
31
+ schema: 'core',
32
+ keepSourceTokens: true,
33
+ lineCounter,
34
+ customTags: [
35
+ {
36
+ tag: '!accept_potentially_dangerous_queries',
37
+ resolve(_text, _onError) {
38
+ return ACCEPT_POTENTIALLY_DANGEROUS_QUERIES;
39
+ }
40
+ }
41
+ ]
42
+ });
43
+ const rules = new SqlSyncRules(yaml);
44
+ if (parsed.errors.length > 0) {
45
+ rules.errors.push(...parsed.errors.map((error) => {
46
+ return new YamlError(error);
47
+ }));
48
+ if (throwOnError) {
49
+ rules.throwOnError();
50
+ }
51
+ return rules;
52
+ }
53
+ const bucketMap = parsed.get('bucket_definitions');
54
+ if (bucketMap == null) {
55
+ rules.errors.push(new YamlError(new Error(`'bucket_definitions' is required`)));
56
+ if (throwOnError) {
57
+ rules.throwOnError();
58
+ }
59
+ return rules;
60
+ }
61
+ for (let entry of bucketMap.items) {
62
+ const { key: keyScalar, value } = entry;
63
+ const key = keyScalar.toString();
64
+ const accept_potentially_dangerous_queries = value.get('accept_potentially_dangerous_queries', true)?.value == true;
65
+ const options = {
66
+ accept_potentially_dangerous_queries
67
+ };
68
+ const parameters = value.get('parameters', true);
69
+ const dataQueries = value.get('data', true);
70
+ const descriptor = new SqlBucketDescriptor(key, rules.idSequence);
71
+ if (parameters instanceof Scalar) {
72
+ rules.withScalar(parameters, (q) => {
73
+ return descriptor.addParameterQuery(q, schema, options);
74
+ });
75
+ }
76
+ else if (parameters instanceof YAMLSeq) {
77
+ for (let item of parameters.items) {
78
+ rules.withScalar(item, (q) => {
79
+ return descriptor.addParameterQuery(q, schema, options);
80
+ });
81
+ }
82
+ }
83
+ else {
84
+ descriptor.addParameterQuery('SELECT', schema, options);
85
+ }
86
+ if (!(dataQueries instanceof YAMLSeq)) {
87
+ rules.errors.push(this.tokenError(dataQueries ?? value, `'data' must be an array`));
88
+ continue;
89
+ }
90
+ for (let query of dataQueries.items) {
91
+ rules.withScalar(query, (q) => {
92
+ return descriptor.addDataQuery(q, schema);
93
+ });
94
+ }
95
+ rules.bucket_descriptors.push(descriptor);
96
+ }
97
+ // Validate that there are no additional properties.
98
+ // Since these errors don't contain line numbers, do this last.
99
+ const valid = validateSyncRulesSchema(parsed.toJSON());
100
+ if (!valid) {
101
+ rules.errors.push(...validateSyncRulesSchema.errors.map((e) => {
102
+ return new YamlError(e);
103
+ }));
104
+ }
105
+ if (throwOnError) {
106
+ rules.throwOnError();
107
+ }
108
+ return rules;
109
+ }
110
+ throwOnError() {
111
+ if (this.errors.filter((e) => e.type != 'warning').length > 0) {
112
+ throw new SyncRulesErrors(this.errors);
113
+ }
114
+ }
115
+ static tokenError(token, message) {
116
+ const start = token?.srcToken?.offset ?? 0;
117
+ const end = start + 1;
118
+ return new YamlError(new Error(message), { start, end });
119
+ }
120
+ withScalar(scalar, cb) {
121
+ const value = scalar.toString();
122
+ const wrapped = (value) => {
123
+ try {
124
+ return cb(value);
125
+ }
126
+ catch (e) {
127
+ return {
128
+ parsed: false,
129
+ errors: [e]
130
+ };
131
+ }
132
+ };
133
+ const result = wrapped(value);
134
+ for (let err of result.errors) {
135
+ let sourceOffset = scalar.srcToken.offset;
136
+ if (scalar.type == Scalar.QUOTE_DOUBLE || scalar.type == Scalar.QUOTE_SINGLE) {
137
+ // TODO: Is there a better way to do this?
138
+ sourceOffset += 1;
139
+ }
140
+ let offset;
141
+ let end;
142
+ if (err instanceof SqlRuleError && err.location) {
143
+ offset = err.location.start + sourceOffset;
144
+ end = err.location.end + sourceOffset;
145
+ }
146
+ else if (typeof err.token?._location?.start == 'number') {
147
+ offset = sourceOffset + err.token?._location?.start;
148
+ end = sourceOffset + err.token?._location?.end;
149
+ }
150
+ else {
151
+ offset = sourceOffset;
152
+ end = sourceOffset + Math.max(value.length, 1);
153
+ }
154
+ const pos = { start: offset, end };
155
+ this.errors.push(new YamlError(err, pos));
156
+ }
157
+ return result;
158
+ }
159
+ constructor(content) {
160
+ this.bucket_descriptors = [];
161
+ this.idSequence = new IdSequence();
162
+ this.errors = [];
163
+ this.content = content;
164
+ }
165
+ /**
166
+ * Throws errors.
167
+ */
168
+ evaluateRow(options) {
169
+ const { results, errors } = this.evaluateRowWithErrors(options);
170
+ if (errors.length > 0) {
171
+ throw new Error(errors[0].error);
172
+ }
173
+ return results;
174
+ }
175
+ evaluateRowWithErrors(options) {
176
+ let rawResults = [];
177
+ for (let query of this.bucket_descriptors) {
178
+ rawResults.push(...query.evaluateRow(options));
179
+ }
180
+ const results = rawResults.filter(isEvaluatedRow);
181
+ const errors = rawResults.filter(isEvaluationError);
182
+ return { results, errors };
183
+ }
184
+ /**
185
+ * Throws errors.
186
+ */
187
+ evaluateParameterRow(table, row) {
188
+ const { results, errors } = this.evaluateParameterRowWithErrors(table, row);
189
+ if (errors.length > 0) {
190
+ throw new Error(errors[0].error);
191
+ }
192
+ return results;
193
+ }
194
+ evaluateParameterRowWithErrors(table, row) {
195
+ let rawResults = [];
196
+ for (let query of this.bucket_descriptors) {
197
+ rawResults.push(...query.evaluateParameterRow(table, row));
198
+ }
199
+ const results = rawResults.filter(isEvaluatedParameters);
200
+ const errors = rawResults.filter(isEvaluationError);
201
+ return { results, errors };
202
+ }
203
+ /**
204
+ * @deprecated For testing only.
205
+ */
206
+ getStaticBucketIds(parameters) {
207
+ let results = [];
208
+ for (let bucket of this.bucket_descriptors) {
209
+ results.push(...bucket.getStaticBucketIds(parameters));
210
+ }
211
+ return results;
212
+ }
213
+ /**
214
+ * Note: This can error hard.
215
+ */
216
+ async queryBucketIds(options) {
217
+ let results = [];
218
+ for (let bucket of this.bucket_descriptors) {
219
+ results.push(...(await bucket.queryBucketIds(options)));
220
+ }
221
+ return results;
222
+ }
223
+ getSourceTables() {
224
+ let sourceTables = new Map();
225
+ for (let bucket of this.bucket_descriptors) {
226
+ for (let r of bucket.getSourceTables()) {
227
+ const key = `${r.connectionTag}.${r.schema}.${r.tablePattern}`;
228
+ sourceTables.set(key, r);
229
+ }
230
+ }
231
+ return [...sourceTables.values()];
232
+ }
233
+ tableSyncsData(table) {
234
+ for (let bucket of this.bucket_descriptors) {
235
+ if (bucket.tableSyncsData(table)) {
236
+ return true;
237
+ }
238
+ }
239
+ return false;
240
+ }
241
+ tableSyncsParameters(table) {
242
+ for (let bucket of this.bucket_descriptors) {
243
+ if (bucket.tableSyncsParameters(table)) {
244
+ return true;
245
+ }
246
+ }
247
+ return false;
248
+ }
249
+ debugGetOutputTables() {
250
+ var _a;
251
+ let result = {};
252
+ for (let bucket of this.bucket_descriptors) {
253
+ for (let q of bucket.data_queries) {
254
+ result[_a = q.table] ?? (result[_a] = []);
255
+ const r = {
256
+ query: q.sql
257
+ };
258
+ result[q.table].push(r);
259
+ }
260
+ }
261
+ return result;
262
+ }
263
+ }
264
+ //# sourceMappingURL=SqlSyncRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlSyncRules.js","sourceRoot":"","sources":["../src/SqlSyncRules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAW,OAAO,EAAE,MAAM,MAAM,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAoB,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EAOL,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EAOlB,MAAM,YAAY,CAAC;AAEpB,MAAM,oCAAoC,GAAG,MAAM,CAAC,sCAAsC,CAAC,CAAC;AAE5F,MAAM,OAAO,YAAY;IAQvB,MAAM,CAAC,QAAQ,CAAC,IAAY,EAAE,OAAmC;QAC/D,IAAI;YACF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC,MAAM,CAAC;SACrB;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,YAAY,eAAe,EAAE;gBAChC,OAAO,CAAC,CAAC,MAAM,CAAC;aACjB;iBAAM,IAAI,CAAC,YAAY,SAAS,EAAE;gBACjC,OAAO,CAAC,CAAC,CAAC,CAAC;aACZ;iBAAM;gBACL,OAAO,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B;SACF;IACH,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,IAAY,EAAE,OAA2D;QACvF,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,IAAI,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;QAE/B,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,gBAAgB,EAAE,IAAI;YACtB,WAAW;YACX,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,uCAAuC;oBAC5C,OAAO,CAAC,KAAa,EAAE,QAAiC;wBACtD,OAAO,oCAAoC,CAAC;oBAC9C,CAAC;iBACF;aACF;SACF,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;QAErC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YAC5B,KAAK,CAAC,MAAM,CAAC,IAAI,CACf,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC7B,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC,CAAC,CACH,CAAC;YAEF,IAAI,YAAY,EAAE;gBAChB,KAAK,CAAC,YAAY,EAAE,CAAC;aACtB;YACD,OAAO,KAAK,CAAC;SACd;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAY,CAAC;QAC9D,IAAI,SAAS,IAAI,IAAI,EAAE;YACrB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC,CAAC;YAEhF,IAAI,YAAY,EAAE;gBAChB,KAAK,CAAC,YAAY,EAAE,CAAC;aACtB;YACD,OAAO,KAAK,CAAC;SACd;QAED,KAAK,IAAI,KAAK,IAAI,SAAS,CAAC,KAAK,EAAE;YACjC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAwC,CAAC;YAC3E,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;YAEjC,MAAM,oCAAoC,GACxC,KAAK,CAAC,GAAG,CAAC,sCAAsC,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;YACzE,MAAM,OAAO,GAAsB;gBACjC,oCAAoC;aACrC,CAAC;YACF,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAY,CAAC;YAC5D,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAY,CAAC;YAEvD,MAAM,UAAU,GAAG,IAAI,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YAElE,IAAI,UAAU,YAAY,MAAM,EAAE;gBAChC,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE;oBACjC,OAAO,UAAU,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC1D,CAAC,CAAC,CAAC;aACJ;iBAAM,IAAI,UAAU,YAAY,OAAO,EAAE;gBACxC,KAAK,IAAI,IAAI,IAAI,UAAU,CAAC,KAAK,EAAE;oBACjC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;wBAC3B,OAAO,UAAU,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;oBAC1D,CAAC,CAAC,CAAC;iBACJ;aACF;iBAAM;gBACL,UAAU,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;aACzD;YAED,IAAI,CAAC,CAAC,WAAW,YAAY,OAAO,CAAC,EAAE;gBACrC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,IAAI,KAAK,EAAE,yBAAyB,CAAC,CAAC,CAAC;gBACpF,SAAS;aACV;YACD,KAAK,IAAI,KAAK,IAAI,WAAW,CAAC,KAAK,EAAE;gBACnC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;oBAC5B,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC;aACJ;YACD,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;SAC3C;QAED,oDAAoD;QACpD,+DAA+D;QAC/D,MAAM,KAAK,GAAG,uBAAuB,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,EAAE;YACV,KAAK,CAAC,MAAM,CAAC,IAAI,CACf,GAAG,uBAAuB,CAAC,MAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;gBAChD,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC,CAAC,CACH,CAAC;SACH;QAED,IAAI,YAAY,EAAE;YAChB,KAAK,CAAC,YAAY,EAAE,CAAC;SACtB;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7D,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SACxC;IACH,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAU,EAAE,OAAe;QAC3C,MAAM,KAAK,GAAG,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;QACtB,OAAO,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,UAAU,CAAC,MAAc,EAAE,EAAuC;QAChE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAEhC,MAAM,OAAO,GAAG,CAAC,KAAa,EAAoB,EAAE;YAClD,IAAI;gBACF,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;aAClB;YAAC,OAAO,CAAC,EAAE;gBACV,OAAO;oBACL,MAAM,EAAE,KAAK;oBACb,MAAM,EAAE,CAAC,CAAC,CAAC;iBACZ,CAAC;aACH;QACH,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE;YAC7B,IAAI,YAAY,GAAG,MAAM,CAAC,QAAS,CAAC,MAAM,CAAC;YAC3C,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE;gBAC5E,0CAA0C;gBAC1C,YAAY,IAAI,CAAC,CAAC;aACnB;YACD,IAAI,MAAc,CAAC;YACnB,IAAI,GAAW,CAAC;YAChB,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,QAAQ,EAAE;gBAC/C,MAAM,GAAG,GAAG,CAAC,QAAS,CAAC,KAAK,GAAG,YAAY,CAAC;gBAC5C,GAAG,GAAG,GAAG,CAAC,QAAS,CAAC,GAAG,GAAG,YAAY,CAAC;aACxC;iBAAM,IAAI,OAAQ,GAAW,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,QAAQ,EAAE;gBAClE,MAAM,GAAG,YAAY,GAAI,GAAW,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC;gBAC7D,GAAG,GAAG,YAAY,GAAI,GAAW,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC;aACzD;iBAAM;gBACL,MAAM,GAAG,YAAY,CAAC;gBACtB,GAAG,GAAG,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;aAChD;YAED,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;SAC3C;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,YAAY,OAAe;QAhL3B,uBAAkB,GAA0B,EAAE,CAAC;QAC/C,eAAU,GAAG,IAAI,UAAU,EAAE,CAAC;QAI9B,WAAM,GAAgB,EAAE,CAAC;QA4KvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,OAA2B;QACrC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAChE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;SAClC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,qBAAqB,CAAC,OAA2B;QAC/C,IAAI,UAAU,GAAuB,EAAE,CAAC;QACxC,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC,kBAAkB,EAAE;YACzC,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;SAChD;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,cAAc,CAAmB,CAAC;QACpE,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,iBAAiB,CAAsB,CAAC;QAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,oBAAoB,CAAC,KAA2B,EAAE,GAAc;QAC9D,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,8BAA8B,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC5E,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;SAClC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,8BAA8B,CAC5B,KAA2B,EAC3B,GAAc;QAEd,IAAI,UAAU,GAAgC,EAAE,CAAC;QACjD,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC,kBAAkB,EAAE;YACzC,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;SAC5D;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,qBAAqB,CAA0B,CAAC;QAClF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,iBAAiB,CAAsB,CAAC;QACzE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,UAA6B;QAC9C,IAAI,OAAO,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC;SACxD;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,OAA6B;QAChD,IAAI,OAAO,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SACzD;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,eAAe;QACb,IAAI,YAAY,GAAG,IAAI,GAAG,EAAwB,CAAC;QACnD,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC1C,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,eAAe,EAAE,EAAE;gBACtC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;gBAC/D,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;aAC1B;SACF;QACD,OAAO,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,cAAc,CAAC,KAA2B;QACxC,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC1C,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;gBAChC,OAAO,IAAI,CAAC;aACb;SACF;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB,CAAC,KAA2B;QAC9C,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC1C,IAAI,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE;gBACtC,OAAO,IAAI,CAAC;aACb;SACF;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB;;QAClB,IAAI,MAAM,GAA0B,EAAE,CAAC;QACvC,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC1C,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE;gBACjC,MAAM,MAAC,CAAC,CAAC,KAAM,MAAf,MAAM,OAAe,EAAE,EAAC;gBACxB,MAAM,CAAC,GAAG;oBACR,KAAK,EAAE,CAAC,CAAC,GAAG;iBACb,CAAC;gBAEF,MAAM,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAC1B;SACF;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}