@shaxpir/squilt 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +133 -0
  3. package/dist/ast/Abstractions.d.ts +14 -0
  4. package/dist/ast/Abstractions.js +11 -0
  5. package/dist/ast/Alias.d.ts +11 -0
  6. package/dist/ast/Alias.js +23 -0
  7. package/dist/ast/BinaryExpression.d.ts +13 -0
  8. package/dist/ast/BinaryExpression.js +26 -0
  9. package/dist/ast/CaseExpression.d.ts +14 -0
  10. package/dist/ast/CaseExpression.js +22 -0
  11. package/dist/ast/Column.d.ts +17 -0
  12. package/dist/ast/Column.js +38 -0
  13. package/dist/ast/Concat.d.ts +8 -0
  14. package/dist/ast/Concat.js +19 -0
  15. package/dist/ast/ExistsExpression.d.ts +9 -0
  16. package/dist/ast/ExistsExpression.js +18 -0
  17. package/dist/ast/From.d.ts +33 -0
  18. package/dist/ast/From.js +60 -0
  19. package/dist/ast/FunctionExpression.d.ts +13 -0
  20. package/dist/ast/FunctionExpression.js +27 -0
  21. package/dist/ast/FunctionName.d.ts +1 -0
  22. package/dist/ast/FunctionName.js +3 -0
  23. package/dist/ast/InExpression.d.ts +13 -0
  24. package/dist/ast/InExpression.js +35 -0
  25. package/dist/ast/InsertQuery.d.ts +17 -0
  26. package/dist/ast/InsertQuery.js +42 -0
  27. package/dist/ast/Join.d.ts +21 -0
  28. package/dist/ast/Join.js +37 -0
  29. package/dist/ast/Literals.d.ts +31 -0
  30. package/dist/ast/Literals.js +65 -0
  31. package/dist/ast/Operator.d.ts +18 -0
  32. package/dist/ast/Operator.js +23 -0
  33. package/dist/ast/OrderBy.d.ts +14 -0
  34. package/dist/ast/OrderBy.js +25 -0
  35. package/dist/ast/SelectQuery.d.ts +39 -0
  36. package/dist/ast/SelectQuery.js +109 -0
  37. package/dist/ast/UnaryExpression.d.ts +11 -0
  38. package/dist/ast/UnaryExpression.js +22 -0
  39. package/dist/ast/With.d.ts +11 -0
  40. package/dist/ast/With.js +21 -0
  41. package/dist/builder/QueryBuilder.d.ts +8 -0
  42. package/dist/builder/QueryBuilder.js +20 -0
  43. package/dist/builder/Shorthand.d.ts +77 -0
  44. package/dist/builder/Shorthand.js +375 -0
  45. package/dist/index.d.ts +32 -0
  46. package/dist/index.js +133 -0
  47. package/dist/renderer/CompactQueryRenderer.d.ts +45 -0
  48. package/dist/renderer/CompactQueryRenderer.js +192 -0
  49. package/dist/renderer/IndentedQueryRenderer.d.ts +51 -0
  50. package/dist/renderer/IndentedQueryRenderer.js +230 -0
  51. package/dist/renderer/QueryRenderer.d.ts +8 -0
  52. package/dist/renderer/QueryRenderer.js +77 -0
  53. package/dist/validate/CommonQueryValidator.d.ts +50 -0
  54. package/dist/validate/CommonQueryValidator.js +262 -0
  55. package/dist/validate/QueryValidator.d.ts +6 -0
  56. package/dist/validate/QueryValidator.js +3 -0
  57. package/dist/validate/SQLiteQueryValidator.d.ts +27 -0
  58. package/dist/validate/SQLiteQueryValidator.js +96 -0
  59. package/dist/visitor/ParamCollector.d.ts +46 -0
  60. package/dist/visitor/ParamCollector.js +129 -0
  61. package/dist/visitor/QueryIdentityTransformer.d.ts +45 -0
  62. package/dist/visitor/QueryIdentityTransformer.js +173 -0
  63. package/dist/visitor/QueryParamRewriteTransformer.d.ts +11 -0
  64. package/dist/visitor/QueryParamRewriteTransformer.js +26 -0
  65. package/dist/visitor/SqlTreeNodeTransformer.d.ts +5 -0
  66. package/dist/visitor/SqlTreeNodeTransformer.js +3 -0
  67. package/dist/visitor/SqlTreeNodeVisitor.d.ts +45 -0
  68. package/dist/visitor/SqlTreeNodeVisitor.js +47 -0
  69. package/package.json +36 -0
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.quoteIdentifier = quoteIdentifier;
4
+ exports.shouldQuoteIdentifier = shouldQuoteIdentifier;
5
+ // Comprehensive list of SQLite reserved keywords (case-insensitive)
6
+ const RESERVED_KEYWORDS = new Set([
7
+ 'ABORT', 'ACTION', 'ADD', 'AFTER', 'ALL', 'ALTER', 'ALWAYS', 'ANALYZE', 'AND',
8
+ 'AS', 'ASC', 'ATTACH', 'AUTOINCREMENT', 'BEFORE', 'BEGIN', 'BETWEEN', 'BY',
9
+ 'CASCADE', 'CASE', 'CAST', 'CHECK', 'COLLATE', 'COLUMN', 'COMMIT', 'CONFLICT',
10
+ 'CONSTRAINT', 'CREATE', 'CROSS', 'CURRENT', 'CURRENT_DATE', 'CURRENT_TIME',
11
+ 'CURRENT_TIMESTAMP', 'DATABASE', 'DEFAULT', 'DEFERRED', 'DEFERRABLE', 'DELETE',
12
+ 'DESC', 'DETACH', 'DISTINCT', 'DO', 'DROP', 'EACH', 'ELSE', 'END', 'ESCAPE',
13
+ 'EXCEPT', 'EXCLUDE', 'EXCLUSIVE', 'EXISTS', 'EXPLAIN', 'FAIL', 'FILTER', 'FIRST',
14
+ 'FOLLOWING', 'FOR', 'FOREIGN', 'FROM', 'FULL', 'GENERATED', 'GLOB', 'GROUP',
15
+ 'GROUPS', 'HAVING', 'IF', 'IGNORE', 'IMMEDIATE', 'IN', 'INDEX', 'INDEXED',
16
+ 'INITIALLY', 'INNER', 'INSERT', 'INSTEAD', 'INTERSECT', 'INTO', 'IS', 'ISNULL',
17
+ 'JOIN', 'KEY', 'LAST', 'LEFT', 'LIKE', 'LIMIT', 'MATCH', 'MATERIALIZED', 'NATURAL',
18
+ 'NO', 'NOT', 'NOTHING', 'NOTNULL', 'NULL', 'NULLS', 'OF', 'OFFSET', 'ON', 'OR',
19
+ 'ORDER', 'OTHERS', 'OUTER', 'OVER', 'PARTITION', 'PLAN', 'PRAGMA', 'PRECEDING',
20
+ 'PRIMARY', 'QUERY', 'RAISE', 'RANGE', 'RECURSIVE', 'REFERENCES', 'REGEXP',
21
+ 'REINDEX', 'RELEASE', 'RENAME', 'REPLACE', 'RESTRICT', 'RETURNING', 'RIGHT',
22
+ 'ROLLBACK', 'ROW', 'ROWS', 'SAVEPOINT', 'SELECT', 'SET', 'TABLE', 'TEMP',
23
+ 'TEMPORARY', 'THEN', 'TIES', 'TO', 'TRANSACTION', 'TRIGGER', 'UNBOUNDED',
24
+ 'UNION', 'UNIQUE', 'UPDATE', 'USING', 'VACUUM', 'VALUES', 'VIEW', 'VIRTUAL',
25
+ 'WHEN', 'WHERE', 'WINDOW', 'WITH', 'WITHOUT'
26
+ ]);
27
+ // Utility function to quote identifiers, escaping inner quotes
28
+ function quoteIdentifier(identifier) {
29
+ if (identifier === '*') {
30
+ return identifier; // Do not quote '*'
31
+ }
32
+ // Handle database-qualified identifiers (e.g., "database.table")
33
+ if (identifier.includes('.')) {
34
+ const parts = identifier.split('.');
35
+ if (parts.length === 2) {
36
+ // Quote each part individually if needed (except for asterisk), then join with dot
37
+ const quotedParts = parts.map(part => {
38
+ if (part === '*') {
39
+ return part; // Don't quote asterisk
40
+ }
41
+ return shouldQuoteIdentifier(part) ? `"${part.replace(/"/g, '""')}"` : part;
42
+ });
43
+ return quotedParts.join('.');
44
+ }
45
+ }
46
+ if (shouldQuoteIdentifier(identifier)) {
47
+ // Escape double-quotes by doubling them (e.g., " becomes "")
48
+ const escaped = identifier.replace(/"/g, '""');
49
+ return `"${escaped}"`;
50
+ }
51
+ return identifier; // Return unquoted if no quoting is needed
52
+ }
53
+ function shouldQuoteIdentifier(identifier) {
54
+ // Check for empty or invalid input
55
+ if (!identifier || identifier.trim() === '') {
56
+ return true; // Empty or invalid identifiers should be quoted to avoid errors
57
+ }
58
+ // Check if the identifier is a reserved keyword (case-insensitive)
59
+ if (RESERVED_KEYWORDS.has(identifier.toUpperCase())) {
60
+ return true;
61
+ }
62
+ // Check if the identifier contains special characters or spaces
63
+ // Valid unquoted identifiers: letters, digits, underscores; must not start with a digit
64
+ const validIdentifierPattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
65
+ if (!validIdentifierPattern.test(identifier)) {
66
+ return true;
67
+ }
68
+ // Check for case sensitivity (if identifier has uppercase letters)
69
+ // SQLite is case-insensitive by default, but quoting preserves case
70
+ const hasUpperCase = /[A-Z]/.test(identifier);
71
+ if (hasUpperCase) {
72
+ return true; // Quote if case sensitivity is desired
73
+ }
74
+ // No quotes needed for simple, lowercase, non-reserved identifiers
75
+ return false;
76
+ }
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUXVlcnlSZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZW5kZXJlci9RdWVyeVJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNkJBLDBDQTBCQztBQU1ELHNEQTJCQztBQW5GRCxvRUFBb0U7QUFDcEUsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNoQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLEtBQUs7SUFDN0UsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUk7SUFDMUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVU7SUFDN0UsWUFBWSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxjQUFjO0lBQzFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxRQUFRO0lBQzlFLE1BQU0sRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUTtJQUMzRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTztJQUNoRixXQUFXLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsT0FBTztJQUMzRSxRQUFRLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLElBQUksRUFB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Z0VBQWdFO0lBQy9FLENBQUM7SUFFRCxtRUFBbUU7SUFDbkUsSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNsRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsZ0VBQWdFO0lBQ2hFLHdGQUF3RjtJQUN4RixNQUFNLHNCQUFzQixHQUFHLDBCQUEwQixDQUFDO0lBQzFELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUMzQyxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsbUVBQW1FO0lBQ25FLG9FQUFvRTtJQUNwRSxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlDLElBQUksWUFBWSxFQUFFLENBQUM7UUFDZixPQUFPLElBQUksQ0FBQyxDQUFDLHVDQUF1QztJQUN4RCxDQUFDO0lBRUQsbUVBQW1FO0lBQ25FLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluc2VydFF1ZXJ5IH0gZnJvbSBcIi4uL2FzdC9JbnNlcnRRdWVyeVwiO1xuaW1wb3J0IHsgU2VsZWN0UXVlcnkgfSBmcm9tIFwiLi4vYXN0L1NlbGVjdFF1ZXJ5XCI7XG5pbXBvcnQgeyBTcWxUcmVlTm9kZVZpc2l0b3IgfSBmcm9tIFwiLi4vdmlzaXRvci9TcWxUcmVlTm9kZVZpc2l0b3JcIjtcblxuXG4vLyBDb21wcmVoZW5zaXZlIGxpc3Qgb2YgU1FMaXRlIHJlc2VydmVkIGtleXdvcmRzIChjYXNlLWluc2Vuc2l0aXZlKVxuY29uc3QgUkVTRVJWRURfS0VZV09SRFMgPSBuZXcgU2V0KFtcbiAgJ0FCT1JUJywgJ0FDVElPTicsICdBREQnLCAnQUZURVInLCAnQUxMJywgJ0FMVEVSJywgJ0FMV0FZUycsICdBTkFMWVpFJywgJ0FORCcsXG4gICdBUycsICdBU0MnLCAnQVRUQUNIJywgJ0FVVE9JTkNSRU1FTlQnLCAnQkVGT1JFJywgJ0JFR0lOJywgJ0JFVFdFRU4nLCAnQlknLFxuICAnQ0FTQ0FERScsICdDQVNFJywgJ0NBU1QnLCAnQ0hFQ0snLCAnQ09MTEFURScsICdDT0xVTU4nLCAnQ09NTUlUJywgJ0NPTkZMSUNUJyxcbiAgJ0NPTlNUUkFJTlQnLCAnQ1JFQVRFJywgJ0NST1NTJywgJ0NVUlJFTlQnLCAnQ1VSUkVOVF9EQVRFJywgJ0NVUlJFTlRfVElNRScsXG4gICdDVVJSRU5UX1RJTUVTVEFNUCcsICdEQVRBQkFTRScsICdERUZBVUxUJywgJ0RFRkVSUkVEJywgJ0RFRkVSUkFCTEUnLCAnREVMRVRFJyxcbiAgJ0RFU0MnLCAnREVUQUNIJywgJ0RJU1RJTkNUJywgJ0RPJywgJ0RST1AnLCAnRUFDSCcsICdFTFNFJywgJ0VORCcsICdFU0NBUEUnLFxuICAnRVhDRVBUJywgJ0VYQ0xVREUnLCAnRVhDTFVTSVZFJywgJ0VYSVNUUycsICdFWFBMQUlOJywgJ0ZBSUwnLCAnRklMVEVSJywgJ0ZJUlNUJyxcbiAgJ0ZPTExPV0lORycsICdGT1InLCAnRk9SRUlHTicsICdGUk9NJywgJ0ZVTEwnLCAnR0VORVJBVEVEJywgJ0dMT0InLCAnR1JPVVAnLFxuICAnR1JPVVBTJywgJ0hBVklORycsICdJRicsICdJR05PUkUnLCAnSU1NRURJQVRFJywgJ0lOJywgJ0lOREVYJywgJ0lOREVYRUQnLFxuICAnSU5JVElBTExZJywgJ0lOTkVSJywgJ0lOU0VSVCcsICdJTlNURUFEJywgJ0lOVEVSU0VDVCcsICdJTlRPJywgJ0lTJywgJ0lTTlVMTCcsXG4gICdKT0lOJywgJ0tFWScsICdMQVNUJywgJ0xFRlQnLCAnTElLRScsICdMSU1JVCcsICdNQVRDSCcsICdNQVRFUklBTElaRUQnLCAnTkFUVVJBTCcsXG4gICdOTycsICdOT1QnLCAnTk9USElORycsICdOT1ROVUxMJywgJ05VTEwnLCAnTlVMTFMnLCAnT0YnLCAnT0ZGU0VUJywgJ09OJywgJ09SJyxcbiAgJ09SREVSJywgJ09USEVSUycsICdPVVRFUicsICdPVkVSJywgJ1BBUlRJVElPTicsICdQTEFOJywgJ1BSQUdNQScsICdQUkVDRURJTkcnLFxuICAnUFJJTUFSWScsICdRVUVSWScsICdSQUlTRScsICdSQU5HRScsICdSRUNVUlNJVkUnLCAnUkVGRVJFTkNFUycsICdSRUdFWFAnLFxuICAnUkVJTkRFWCcsICdSRUxFQVNFJywgJ1JFTkFNRScsICdSRVBMQUNFJywgJ1JFU1RSSUNUJywgJ1JFVFVSTklORycsICdSSUdIVCcsXG4gICdST0xMQkFDSycsICdST1cnLCAnUk9XUycsICdTQVZFUE9JTlQnLCAnU0VMRUNUJywgJ1NFVCcsICdUQUJMRScsICdURU1QJyxcbiAgJ1RFTVBPUkFSWScsICdUSEVOJywgJ1RJRVMnLCAnVE8nLCAnVFJBTlNBQ1RJT04nLCAnVFJJR0dFUicsICdVTkJPVU5ERUQnLFxuICAnVU5JT04nLCAnVU5JUVVFJywgJ1VQREFURScsICdVU0lORycsICdWQUNVVU0nLCAnVkFMVUVTJywgJ1ZJRVcnLCAnVklSVFVBTCcsXG4gICdXSEVOJywgJ1dIRVJFJywgJ1dJTkRPVycsICdXSVRIJywgJ1dJVEhPVVQnXG5dKTtcblxuLy8gVXRpbGl0eSBmdW5jdGlvbiB0byBxdW90ZSBpZGVudGlmaWVycywgZXNjYXBpbmcgaW5uZXIgcXVvdGVzXG5leHBvcnQgZnVuY3Rpb24gcXVvdGVJZGVudGlmaWVyKGlkZW50aWZpZXI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChpZGVudGlmaWVyID09PSAnKicpIHtcbiAgICByZXR1cm4gaWRlbnRpZmllcjsgLy8gRG8gbm90IHF1b3RlICcqJ1xuICB9XG5cbiAgLy8gSGFuZGxlIGRhdGFiYXNlLXF1YWxpZmllZCBpZGVudGlmaWVycyAoZS5nLiwgXCJkYXRhYmFzZS50YWJsZVwiKVxuICBpZiAoaWRlbnRpZmllci5pbmNsdWRlcygnLicpKSB7XG4gICAgY29uc3QgcGFydHMgPSBpZGVudGlmaWVyLnNwbGl0KCcuJyk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgLy8gUXVvdGUgZWFjaCBwYXJ0IGluZGl2aWR1YWxseSBpZiBuZWVkZWQgKGV4Y2VwdCBmb3IgYXN0ZXJpc2spLCB0aGVuIGpvaW4gd2l0aCBkb3RcbiAgICAgIGNvbnN0IHF1b3RlZFBhcnRzID0gcGFydHMubWFwKHBhcnQgPT4ge1xuICAgICAgICBpZiAocGFydCA9PT0gJyonKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnQ7IC8vIERvbid0IHF1b3RlIGFzdGVyaXNrXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNob3VsZFF1b3RlSWRlbnRpZmllcihwYXJ0KSA/IGBcIiR7cGFydC5yZXBsYWNlKC9cIi9nLCAnXCJcIicpfVwiYCA6IHBhcnQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBxdW90ZWRQYXJ0cy5qb2luKCcuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNob3VsZFF1b3RlSWRlbnRpZmllcihpZGVudGlmaWVyKSkge1xuICAgIC8vIEVzY2FwZSBkb3VibGUtcXVvdGVzIGJ5IGRvdWJsaW5nIHRoZW0gKGUuZy4sIFwiIGJlY29tZXMgXCJcIilcbiAgICBjb25zdCBlc2NhcGVkID0gaWRlbnRpZmllci5yZXBsYWNlKC9cIi9nLCAnXCJcIicpO1xuICAgIHJldHVybiBgXCIke2VzY2FwZWR9XCJgO1xuICB9XG4gIHJldHVybiBpZGVudGlmaWVyOyAvLyBSZXR1cm4gdW5xdW90ZWQgaWYgbm8gcXVvdGluZyBpcyBuZWVkZWRcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdWVyeVJlbmRlcmVyIGV4dGVuZHMgU3FsVHJlZU5vZGVWaXNpdG9yPHN0cmluZz4ge1xuICByZW5kZXIobm9kZTogU2VsZWN0UXVlcnkgfCBJbnNlcnRRdWVyeSk6IHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZFF1b3RlSWRlbnRpZmllcihpZGVudGlmaWVyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgLy8gQ2hlY2sgZm9yIGVtcHR5IG9yIGludmFsaWQgaW5wdXRcbiAgaWYgKCFpZGVudGlmaWVyIHx8IGlkZW50aWZpZXIudHJpbSgpID09PSAnJykge1xuICAgIHJldHVybiB0cnVlOyAvLyBFbXB0eSBvciBpbnZhbGlkIGlkZW50aWZpZXJzIHNob3VsZCBiZSBxdW90ZWQgdG8gYXZvaWQgZXJyb3JzXG4gIH1cblxuICAvLyBDaGVjayBpZiB0aGUgaWRlbnRpZmllciBpcyBhIHJlc2VydmVkIGtleXdvcmQgKGNhc2UtaW5zZW5zaXRpdmUpXG4gIGlmIChSRVNFUlZFRF9LRVlXT1JEUy5oYXMoaWRlbnRpZmllci50b1VwcGVyQ2FzZSgpKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBDaGVjayBpZiB0aGUgaWRlbnRpZmllciBjb250YWlucyBzcGVjaWFsIGNoYXJhY3RlcnMgb3Igc3BhY2VzXG4gIC8vIFZhbGlkIHVucXVvdGVkIGlkZW50aWZpZXJzOiBsZXR0ZXJzLCBkaWdpdHMsIHVuZGVyc2NvcmVzOyBtdXN0IG5vdCBzdGFydCB3aXRoIGEgZGlnaXRcbiAgY29uc3QgdmFsaWRJZGVudGlmaWVyUGF0dGVybiA9IC9eW2EtekEtWl9dW2EtekEtWjAtOV9dKiQvO1xuICBpZiAoIXZhbGlkSWRlbnRpZmllclBhdHRlcm4udGVzdChpZGVudGlmaWVyKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBDaGVjayBmb3IgY2FzZSBzZW5zaXRpdml0eSAoaWYgaWRlbnRpZmllciBoYXMgdXBwZXJjYXNlIGxldHRlcnMpXG4gIC8vIFNRTGl0ZSBpcyBjYXNlLWluc2Vuc2l0aXZlIGJ5IGRlZmF1bHQsIGJ1dCBxdW90aW5nIHByZXNlcnZlcyBjYXNlXG4gIGNvbnN0IGhhc1VwcGVyQ2FzZSA9IC9bQS1aXS8udGVzdChpZGVudGlmaWVyKTtcbiAgaWYgKGhhc1VwcGVyQ2FzZSkge1xuICAgICAgcmV0dXJuIHRydWU7IC8vIFF1b3RlIGlmIGNhc2Ugc2Vuc2l0aXZpdHkgaXMgZGVzaXJlZFxuICB9XG5cbiAgLy8gTm8gcXVvdGVzIG5lZWRlZCBmb3Igc2ltcGxlLCBsb3dlcmNhc2UsIG5vbi1yZXNlcnZlZCBpZGVudGlmaWVyc1xuICByZXR1cm4gZmFsc2U7XG59XG4iXX0=
@@ -0,0 +1,50 @@
1
+ import { AliasableExpression } from "../ast/Abstractions";
2
+ import { Alias } from "../ast/Alias";
3
+ import { BinaryExpression } from "../ast/BinaryExpression";
4
+ import { CaseExpression } from "../ast/CaseExpression";
5
+ import { Column } from "../ast/Column";
6
+ import { Concat } from "../ast/Concat";
7
+ import { ExistsExpression } from "../ast/ExistsExpression";
8
+ import { From, JsonEachFrom, SubqueryFrom, TableFrom } from "../ast/From";
9
+ import { FunctionExpression } from "../ast/FunctionExpression";
10
+ import { InExpression } from "../ast/InExpression";
11
+ import { InsertQuery } from "../ast/InsertQuery";
12
+ import { Join } from "../ast/Join";
13
+ import { NullLiteral, NumberLiteral, Param, StringLiteral } from "../ast/Literals";
14
+ import { OrderBy } from "../ast/OrderBy";
15
+ import { SelectQuery } from "../ast/SelectQuery";
16
+ import { UnaryExpression } from "../ast/UnaryExpression";
17
+ import { With } from "../ast/With";
18
+ import { ColumnLikeVisitorAcceptor, FromLikeAndJoinVisitorAcceptor, SqlTreeNodeVisitor } from "../visitor/SqlTreeNodeVisitor";
19
+ import { QueryValidator } from "./QueryValidator";
20
+ export declare class CommonQueryValidator implements QueryValidator, SqlTreeNodeVisitor<void> {
21
+ protected fromLikeAndJoinAcceptor: FromLikeAndJoinVisitorAcceptor<void>;
22
+ protected columnLikeAcceptor: ColumnLikeVisitorAcceptor<void>;
23
+ private columnCount;
24
+ private isGrouped;
25
+ validate(query: SelectQuery | InsertQuery): void;
26
+ protected reset(): void;
27
+ private validateAlias;
28
+ private validateIdentifier;
29
+ visitInsertQuery(node: InsertQuery): void;
30
+ visitSelectQuery(node: SelectQuery): void;
31
+ visitTableFrom(node: TableFrom): void;
32
+ visitSubqueryFrom(node: SubqueryFrom): void;
33
+ visitJsonEachFrom(node: JsonEachFrom): void;
34
+ visitColumn(node: Column): void;
35
+ visitAlias(node: Alias<From | AliasableExpression>): void;
36
+ visitJoinClause(node: Join): void;
37
+ visitOrderBy(node: OrderBy): void;
38
+ visitWithClause(node: With): void;
39
+ visitBinaryExpression(node: BinaryExpression): void;
40
+ visitUnaryExpression(node: UnaryExpression): void;
41
+ visitInExpression(node: InExpression): void;
42
+ visitConcat(node: Concat): void;
43
+ visitCaseExpression(node: CaseExpression): void;
44
+ visitFunctionExpression(node: FunctionExpression): void;
45
+ visitParamExpression(_node: Param): void;
46
+ visitStringLiteral(node: StringLiteral): void;
47
+ visitNumberLiteral(node: NumberLiteral): void;
48
+ visitNullLiteral(_node: NullLiteral): void;
49
+ visitExistsExpression(node: ExistsExpression): void;
50
+ }
@@ -0,0 +1,262 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommonQueryValidator = void 0;
4
+ const Abstractions_1 = require("../ast/Abstractions");
5
+ const Column_1 = require("../ast/Column");
6
+ const From_1 = require("../ast/From");
7
+ const Join_1 = require("../ast/Join");
8
+ const SelectQuery_1 = require("../ast/SelectQuery");
9
+ const SqlTreeNodeVisitor_1 = require("../visitor/SqlTreeNodeVisitor");
10
+ const RESERVED_KEYWORDS = new Set([
11
+ 'SELECT', 'FROM', 'WHERE', 'JOIN', 'ON', 'GROUP', 'BY', 'HAVING', 'UNION',
12
+ 'ORDER', 'LIMIT', 'OFFSET', 'TABLE', 'INDEX', 'VIEW', 'TRIGGER', 'KEY',
13
+ 'COLUMN', 'CONSTRAINT', 'PRIMARY', 'FOREIGN', 'CHECK', 'DEFAULT', 'NULL',
14
+ 'NOT', 'AND', 'OR', 'LIKE', 'IN', 'IS', 'BETWEEN', 'CASE', 'WHEN', 'THEN',
15
+ 'ELSE', 'END', 'INSERT', 'INTO', 'VALUES', 'EXISTS'
16
+ ]);
17
+ class CommonQueryValidator {
18
+ constructor() {
19
+ this.fromLikeAndJoinAcceptor = new SqlTreeNodeVisitor_1.FromLikeAndJoinVisitorAcceptor();
20
+ this.columnLikeAcceptor = new SqlTreeNodeVisitor_1.ColumnLikeVisitorAcceptor();
21
+ this.columnCount = null;
22
+ this.isGrouped = false;
23
+ }
24
+ validate(query) {
25
+ this.reset();
26
+ query.accept(this);
27
+ }
28
+ reset() {
29
+ this.columnCount = null;
30
+ this.isGrouped = false;
31
+ }
32
+ validateAlias(alias, context) {
33
+ if (alias && !alias.trim()) {
34
+ throw new Error(`Empty alias in ${context}`);
35
+ }
36
+ if (alias && RESERVED_KEYWORDS.has(alias.toUpperCase())) {
37
+ throw new Error(`Alias '${alias}' in ${context} is a reserved SQLite keyword`);
38
+ }
39
+ }
40
+ validateIdentifier(name, context) {
41
+ if (!name || !name.trim()) {
42
+ throw new Error(`${context} name cannot be empty`);
43
+ }
44
+ if (RESERVED_KEYWORDS.has(name.toUpperCase())) {
45
+ throw new Error(`${context} name '${name}' is a reserved SQLite keyword`);
46
+ }
47
+ }
48
+ visitInsertQuery(node) {
49
+ this.validateIdentifier(node['_tableName'], 'InsertQuery');
50
+ if (node['_columns'].length === 0) {
51
+ throw new Error('InsertQuery must specify at least one column');
52
+ }
53
+ if (node['_columns'].length !== node['_values'].length) {
54
+ throw new Error('InsertQuery must have the same number of columns and values');
55
+ }
56
+ node['_columns'].forEach(col => this.validateIdentifier(col, 'InsertQuery column'));
57
+ node['_values'].forEach(val => val.accept(this));
58
+ }
59
+ visitSelectQuery(node) {
60
+ if (node['_columns'].length > 0 && node['_fromsAndJoins'].length === 0) {
61
+ throw new Error('SELECT query with columns must have at least one FROM clause');
62
+ }
63
+ const prevCount = this.columnCount;
64
+ this.columnCount = node['_columns'].length > 0 ? node['_columns'].length : 1;
65
+ node['_with'].forEach(w => w.accept(this));
66
+ node['_fromsAndJoins'].forEach(item => this.fromLikeAndJoinAcceptor.accept(this, item));
67
+ node['_columns'].forEach(c => this.columnLikeAcceptor.accept(this, c));
68
+ if (node['_where']) {
69
+ node['_where'].accept(this);
70
+ }
71
+ if (node['_groupBy'].length > 0) {
72
+ this.isGrouped = true;
73
+ node['_groupBy'].forEach(c => c.accept(this));
74
+ }
75
+ if (node['_having'] && !this.isGrouped) {
76
+ throw new Error('HAVING clause requires GROUP BY');
77
+ }
78
+ if (node['_having']) {
79
+ node['_having'].accept(this);
80
+ }
81
+ if (node['_union'].length > 0) {
82
+ if (node['_columns'].length === 0 && node['_fromsAndJoins'].length === 0) {
83
+ throw new Error("A query with UNION subqueries must have columns and a FROM clause in the main query");
84
+ }
85
+ let columnCounts = [];
86
+ if (node['_columns'].length > 0) {
87
+ columnCounts.push(node['_columns'].length); // Include main query
88
+ }
89
+ columnCounts = columnCounts.concat(node['_union'].map(u => u['_columns'].length || 1));
90
+ if (columnCounts.length > 1) {
91
+ const firstCount = columnCounts[0];
92
+ if (columnCounts.some(count => count !== firstCount)) {
93
+ throw new Error('UNION queries must have the same number of columns');
94
+ }
95
+ }
96
+ }
97
+ node['_orderBy'].forEach(o => o.accept(this));
98
+ if (node['_limit'] !== null && node['_limit'] !== undefined && node['_limit'] < 0) {
99
+ throw new Error('LIMIT must be non-negative');
100
+ }
101
+ if (node['_offset'] !== null && node['_offset'] !== undefined && node['_offset'] < 0) {
102
+ throw new Error('OFFSET must be non-negative');
103
+ }
104
+ this.columnCount = prevCount; // Restore parent context if nested
105
+ }
106
+ visitTableFrom(node) {
107
+ this.validateIdentifier(node.tableName, 'TableFrom');
108
+ }
109
+ visitSubqueryFrom(node) {
110
+ const prevCount = this.columnCount;
111
+ this.columnCount = null; // Reset for subquery
112
+ node.subquery.accept(this);
113
+ this.columnCount = prevCount; // Restore parent count
114
+ }
115
+ visitJsonEachFrom(node) {
116
+ node.jsonExpression.accept(this);
117
+ if (node.jsonPath) {
118
+ node.jsonPath.accept(this);
119
+ }
120
+ }
121
+ visitColumn(node) {
122
+ if (node.hasTableName()) {
123
+ this.validateIdentifier(node.tableName, 'Column');
124
+ }
125
+ this.validateIdentifier(node.columnName, 'Column');
126
+ }
127
+ visitAlias(node) {
128
+ if (!node.alias || !node.alias.trim()) {
129
+ throw new Error('Alias must have a non-empty name');
130
+ }
131
+ if (node.referent instanceof Join_1.Join) {
132
+ this.validateAlias(node.alias, 'Join');
133
+ }
134
+ else if (node.referent instanceof Column_1.Column) {
135
+ this.validateAlias(node.alias, 'Column');
136
+ }
137
+ else if (node.referent instanceof From_1.TableFrom) {
138
+ this.validateAlias(node.alias, 'TableFrom');
139
+ }
140
+ else if (node.referent instanceof From_1.SubqueryFrom) {
141
+ this.validateAlias(node.alias, 'SubqueryFrom');
142
+ }
143
+ else if (node.referent instanceof From_1.JsonEachFrom) {
144
+ this.validateAlias(node.alias, 'JsonEachFrom');
145
+ }
146
+ else if (node.referent instanceof Abstractions_1.AliasableExpression) {
147
+ this.validateAlias(node.alias, 'Expression');
148
+ }
149
+ node.referent.accept(this);
150
+ }
151
+ visitJoinClause(node) {
152
+ this.validateIdentifier(node.tableName, 'JoinClause');
153
+ if (!node.on) {
154
+ throw new Error('JoinClause must have an ON condition');
155
+ }
156
+ node.on.accept(this);
157
+ }
158
+ visitOrderBy(node) {
159
+ node.column.accept(this);
160
+ }
161
+ visitWithClause(node) {
162
+ this.validateIdentifier(node.name, 'WithClause');
163
+ const prevCount = this.columnCount;
164
+ this.columnCount = null; // Reset for subquery
165
+ node.query.accept(this);
166
+ this.columnCount = prevCount; // Restore parent count
167
+ }
168
+ visitBinaryExpression(node) {
169
+ if (!node.operator) {
170
+ throw new Error('BinaryExpression must have a valid operator');
171
+ }
172
+ if (!node.left) {
173
+ throw new Error('BinaryExpression must have a valid left operand');
174
+ }
175
+ if (!node.right) {
176
+ throw new Error('BinaryExpression must have a valid right operand');
177
+ }
178
+ node.left.accept(this);
179
+ node.right.accept(this);
180
+ }
181
+ visitUnaryExpression(node) {
182
+ if (!node.operator) {
183
+ throw new Error('UnaryExpression must have a valid operator');
184
+ }
185
+ if (!node.operand) {
186
+ throw new Error('UnaryExpression must have a valid operand');
187
+ }
188
+ node.operand.accept(this);
189
+ }
190
+ visitInExpression(node) {
191
+ if (node.left.length === 0) {
192
+ throw new Error('IN expression must have at least one left expression');
193
+ }
194
+ node.left.forEach(l => l.accept(this));
195
+ if (node.values instanceof SelectQuery_1.SelectQuery) {
196
+ node.values.accept(this);
197
+ }
198
+ else {
199
+ if (node.values.length === 0) {
200
+ throw new Error('IN expression must have at least one value set');
201
+ }
202
+ node.values.forEach(set => {
203
+ if (set.length !== node.left.length) {
204
+ throw new Error('Value sets in IN expression must match the number of left expressions');
205
+ }
206
+ set.forEach(v => v.accept(this));
207
+ });
208
+ }
209
+ }
210
+ visitConcat(node) {
211
+ if (node.expressions.length < 2) {
212
+ throw new Error('Concat must have at least two expressions');
213
+ }
214
+ node.expressions.forEach(e => e.accept(this));
215
+ }
216
+ visitCaseExpression(node) {
217
+ if (node.cases.length === 0) {
218
+ throw new Error('CaseExpression must have at least one WHEN/THEN pair');
219
+ }
220
+ node.cases.forEach(c => {
221
+ c.when.accept(this);
222
+ c.then.accept(this);
223
+ });
224
+ if (node.else) {
225
+ node.else.accept(this);
226
+ }
227
+ }
228
+ visitFunctionExpression(node) {
229
+ const noArgFunctions = ['RANDOM'];
230
+ if (!noArgFunctions.includes(node.name) && node.args.length === 0) {
231
+ throw new Error(`Function ${node.name} requires at least one argument`);
232
+ }
233
+ node.args.forEach(a => a.accept(this));
234
+ }
235
+ visitParamExpression(_node) {
236
+ // No specific validation needed
237
+ }
238
+ visitStringLiteral(node) {
239
+ if (node.value === null || node.value === undefined) {
240
+ throw new Error('StringLiteral value cannot be null or undefined');
241
+ }
242
+ }
243
+ visitNumberLiteral(node) {
244
+ if (isNaN(node.value)) {
245
+ throw new Error('NumberLiteral value must be a valid number');
246
+ }
247
+ }
248
+ visitNullLiteral(_node) {
249
+ // No specific validation needed
250
+ }
251
+ visitExistsExpression(node) {
252
+ if (!node.subquery) {
253
+ throw new Error('ExistsExpression must have a valid subquery');
254
+ }
255
+ const prevCount = this.columnCount;
256
+ this.columnCount = null; // Reset for subquery
257
+ node.subquery.accept(this);
258
+ this.columnCount = prevCount; // Restore parent count
259
+ }
260
+ }
261
+ exports.CommonQueryValidator = CommonQueryValidator;
262
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29tbW9uUXVlcnlWYWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGUvQ29tbW9uUXVlcnlWYWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0RBQTBEO0FBSTFELDBDQUF1QztBQUd2QyxzQ0FBMEU7QUFJMUUsc0NBQW1DO0FBR25DLG9EQUFpRDtBQUdqRCxzRUFBOEg7QUFHOUgsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNoQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE9BQU87SUFDekUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEtBQUs7SUFDdEUsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTTtJQUN4RSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNO0lBQ3pFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsUUFBUTtDQUNwRCxDQUFDLENBQUM7QUFFSCxNQUFhLG9CQUFvQjtJQUFqQztRQUNZLDRCQUF1QixHQUFHLElBQUksbURBQThCLEVBQVEsQ0FBQztRQUNyRSx1QkFBa0IsR0FBRyxJQUFJLDhDQUF5QixFQUFRLENBQUM7UUFFN0QsZ0JBQVcsR0FBa0IsSUFBSSxDQUFDO1FBQ2xDLGNBQVMsR0FBWSxLQUFLLENBQUM7SUFtUXJDLENBQUM7SUFqUVEsUUFBUSxDQUFDLEtBQWdDO1FBQzlDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FB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LENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNuQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLHFCQUFxQjtRQUM5QyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxDQUFDLHVCQUF1QjtJQUN2RCxDQUFDO0NBQ0Y7QUF4UUQsb0RBd1FDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWxpYXNhYmxlRXhwcmVzc2lvbiB9IGZyb20gXCIuLi9hc3QvQWJzdHJhY3Rpb25zXCI7XG5pbXBvcnQgeyBBbGlhcyB9IGZyb20gXCIuLi9hc3QvQWxpYXNcIjtcbmltcG9ydCB7IEJpbmFyeUV4cHJlc3Npb24gfSBmcm9tIFwiLi4vYXN0L0JpbmFyeUV4cHJlc3Npb25cIjtcbmltcG9ydCB7IENhc2VFeHByZXNzaW9uIH0gZnJvbSBcIi4uL2FzdC9DYXNlRXhwcmVzc2lvblwiO1xuaW1wb3J0IHsgQ29sdW1uIH0gZnJvbSBcIi4uL2FzdC9Db2x1bW5cIjtcbmltcG9ydCB7IENvbmNhdCB9IGZyb20gXCIuLi9hc3QvQ29uY2F0XCI7XG5pbXBvcnQgeyBFeGlzdHNFeHByZXNzaW9uIH0gZnJvbSBcIi4uL2FzdC9FeGlzdHNFeHByZXNzaW9uXCI7XG5pbXBvcnQgeyBGcm9tLCBKc29uRWFjaEZyb20sIFN1YnF1ZXJ5RnJvbSwgVGFibGVGcm9tIH0gZnJvbSBcIi4uL2FzdC9Gcm9tXCI7XG5pbXBvcnQgeyBGdW5jdGlvbkV4cHJlc3Npb24gfSBmcm9tIFwiLi4vYXN0L0Z1bmN0aW9uRXhwcmVzc2lvblwiO1xuaW1wb3J0IHsgSW5FeHByZXNzaW9uIH0gZnJvbSBcIi4uL2FzdC9JbkV4cHJlc3Npb25cIjtcbmltcG9ydCB7IEluc2VydFF1ZXJ5IH0gZnJvbSBcIi4uL2FzdC9JbnNlcnRRdWVyeVwiO1xuaW1wb3J0IHsgSm9pbiB9IGZyb20gXCIuLi9hc3QvSm9pblwiO1xuaW1wb3J0IHsgTnVsbExpdGVyYWwsIE51bWJlckxpdGVyYWwsIFBhcmFtLCBTdHJpbmdMaXRlcmFsIH0gZnJvbSBcIi4uL2FzdC9MaXRlcmFsc1wiO1xuaW1wb3J0IHsgT3JkZXJCeSB9IGZyb20gXCIuLi9hc3QvT3JkZXJCeVwiO1xuaW1wb3J0IHsgU2VsZWN0UXVlcnkgfSBmcm9tIFwiLi4vYXN0L1NlbGVjdFF1ZXJ5XCI7XG5pbXBvcnQgeyBVbmFyeUV4cHJlc3Npb24gfSBmcm9tIFwiLi4vYXN0L1VuYXJ5RXhwcmVzc2lvblwiO1xuaW1wb3J0IHsgV2l0aCB9IGZyb20gXCIuLi9hc3QvV2l0aFwiO1xuaW1wb3J0IHsgQ29sdW1uTGlrZVZpc2l0b3JBY2NlcHRvciwgRnJvbUxpa2VBbmRKb2luVmlzaXRvckFjY2VwdG9yLCBTcWxUcmVlTm9kZVZpc2l0b3IgfSBmcm9tIFwiLi4vdmlzaXRvci9TcWxUcmVlTm9kZVZpc2l0b3JcIjtcbmltcG9ydCB7IFF1ZXJ5VmFsaWRhdG9yIH0gZnJvbSBcIi4vUXVlcnlWYWxpZGF0b3JcIjtcblxuY29uc3QgUkVTRVJWRURfS0VZV09SRFMgPSBuZXcgU2V0KFtcbiAgJ1NFTEVDVCcsICdGUk9NJywgJ1dIRVJFJywgJ0pPSU4nLCAnT04nLCAnR1JPVVAnLCAnQlknLCAnSEFWSU5HJywgJ1VOSU9OJyxcbiAgJ09SREVSJywgJ0xJTUlUJywgJ09GRlNFVCcsICdUQUJMRScsICdJTkRFWCcsICdWSUVXJywgJ1RSSUdHRVInLCAnS0VZJyxcbiAgJ0NPTFVNTicsICdDT05TVFJBSU5UJywgJ1BSSU1BUlknLCAnRk9SRUlHTicsICdDSEVDSycsICdERUZBVUxUJywgJ05VTEwnLFxuICAnTk9UJywgJ0FORCcsICdPUicsICdMSUtFJywgJ0lOJywgJ0lTJywgJ0JFVFdFRU4nLCAnQ0FTRScsICdXSEVOJywgJ1RIRU4nLFxuICAnRUxTRScsICdFTkQnLCAnSU5TRVJUJywgJ0lOVE8nLCAnVkFMVUVTJywgJ0VYSVNUUydcbl0pO1xuXG5leHBvcnQgY2xhc3MgQ29tbW9uUXVlcnlWYWxpZGF0b3IgaW1wbGVtZW50cyBRdWVyeVZhbGlkYXRvciwgU3FsVHJlZU5vZGVWaXNpdG9yPHZvaWQ+IHtcbiAgcHJvdGVjdGVkIGZyb21MaWtlQW5kSm9pbkFjY2VwdG9yID0gbmV3IEZyb21MaWtlQW5kSm9pblZpc2l0b3JBY2NlcHRvcjx2b2lkPigpO1xuICBwcm90ZWN0ZWQgY29sdW1uTGlrZUFjY2VwdG9yID0gbmV3IENvbHVtbkxpa2VWaXNpdG9yQWNjZXB0b3I8dm9pZD4oKTtcblxuICBwcml2YXRlIGNvbHVtbkNvdW50OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBpc0dyb3VwZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwdWJsaWMgdmFsaWRhdGUocXVlcnk6IFNlbGVjdFF1ZXJ5IHwgSW5zZXJ0UXVlcnkpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2V0KCk7XG4gICAgcXVlcnkuYWNjZXB0KHRoaXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuY29sdW1uQ291bnQgPSBudWxsO1xuICAgIHRoaXMuaXNHcm91cGVkID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlQWxpYXMoYWxpYXM6IHN0cmluZyB8IHVuZGVmaW5lZCwgY29udGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKGFsaWFzICYmICFhbGlhcy50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRW1wdHkgYWxpYXMgaW4gJHtjb250ZXh0fWApO1xuICAgIH1cbiAgICBpZiAoYWxpYXMgJiYgUkVTRVJWRURfS0VZV09SRFMuaGFzKGFsaWFzLnRvVXBwZXJDYXNlKCkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFsaWFzICcke2FsaWFzfScgaW4gJHtjb250ZXh0fSBpcyBhIHJlc2VydmVkIFNRTGl0ZSBrZXl3b3JkYCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUlkZW50aWZpZXIobmFtZTogc3RyaW5nLCBjb250ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIW5hbWUgfHwgIW5hbWUudHJpbSgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH0gbmFtZSBjYW5ub3QgYmUgZW1wdHlgKTtcbiAgICB9XG4gICAgaWYgKFJFU0VSVkVEX0tFWVdPUkRTLmhhcyhuYW1lLnRvVXBwZXJDYXNlKCkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH0gbmFtZSAnJHtuYW1lfScgaXMgYSByZXNlcnZlZCBTUUxpdGUga2V5d29yZGApO1xuICAgIH1cbiAgfVxuXG4gIHZpc2l0SW5zZXJ0UXVlcnkobm9kZTogSW5zZXJ0UXVlcnkpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlSWRlbnRpZmllcihub2RlWydfdGFibGVOYW1lJ10sICdJbnNlcnRRdWVyeScpO1xuICAgIGlmIChub2RlWydfY29sdW1ucyddLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnNlcnRRdWVyeSBtdXN0IHNwZWNpZnkgYXQgbGVhc3Qgb25lIGNvbHVtbicpO1xuICAgIH1cbiAgICBpZiAobm9kZVsnX2NvbHVtbnMnXS5sZW5ndGggIT09IG5vZGVbJ192YWx1ZXMnXS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5zZXJ0UXVlcnkgbXVzdCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBjb2x1bW5zIGFuZCB2YWx1ZXMnKTtcbiAgICB9XG4gICAgbm9kZVsnX2NvbHVtbnMnXS5mb3JFYWNoKGNvbCA9PiB0aGlzLnZhbGlkYXRlSWRlbnRpZmllcihjb2wsICdJbnNlcnRRdWVyeSBjb2x1bW4nKSk7XG4gICAgbm9kZVsnX3ZhbHVlcyddLmZvckVhY2godmFsID0+IHZhbC5hY2NlcHQodGhpcykpO1xuICB9XG5cbiAgdmlzaXRTZWxlY3RRdWVyeShub2RlOiBTZWxlY3RRdWVyeSk6IHZvaWQge1xuICAgIGlmIChub2RlWydfY29sdW1ucyddLmxlbmd0aCA+IDAgJiYgbm9kZVsnX2Zyb21zQW5kSm9pbnMnXS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU0VMRUNUIHF1ZXJ5IHdpdGggY29sdW1ucyBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIEZST00gY2xhdXNlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldkNvdW50ID0gdGhpcy5jb2x1bW5Db3VudDtcbiAgICB0aGlzLmNvbHVtbkNvdW50ID0gbm9kZVsnX2NvbHVtbnMnXS5sZW5ndGggPiAwID8gbm9kZVsnX2NvbHVtbnMnXS5sZW5ndGggOiAxO1xuXG4gICAgbm9kZVsnX3dpdGgnXS5mb3JFYWNoKHcgPT4gdy5hY2NlcHQodGhpcykpO1xuICAgIG5vZGVbJ19mcm9tc0FuZEpvaW5zJ10uZm9yRWFjaChpdGVtID0+IHRoaXMuZnJvbUxpa2VBbmRKb2luQWNjZXB0b3IuYWNjZXB0KHRoaXMsIGl0ZW0pKTtcbiAgICBub2RlWydfY29sdW1ucyddLmZvckVhY2goYyA9PiB0aGlzLmNvbHVtbkxpa2VBY2NlcHRvci5hY2NlcHQodGhpcywgYykpO1xuICAgIGlmIChub2RlWydfd2hlcmUnXSkge1xuICAgICAgbm9kZVsnX3doZXJlJ10uYWNjZXB0KHRoaXMpO1xuICAgIH1cbiAgICBpZiAobm9kZVsnX2dyb3VwQnknXS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmlzR3JvdXBlZCA9IHRydWU7XG4gICAgICBub2RlWydfZ3JvdXBCeSddLmZvckVhY2goYyA9PiBjLmFjY2VwdCh0aGlzKSk7XG4gICAgfVxuICAgIGlmIChub2RlWydfaGF2aW5nJ10gJiYgIXRoaXMuaXNHcm91cGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0hBVklORyBjbGF1c2UgcmVxdWlyZXMgR1JPVVAgQlknKTtcbiAgICB9XG4gICAgaWYgKG5vZGVbJ19oYXZpbmcnXSkge1xuICAgICAgbm9kZVsnX2hhdmluZyddLmFjY2VwdCh0aGlzKTtcbiAgICB9XG4gICAgaWYgKG5vZGVbJ191bmlvbiddLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmIChub2RlWydfY29sdW1ucyddLmxlbmd0aCA9PT0gMCAmJiBub2RlWydfZnJvbXNBbmRKb2lucyddLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHF1ZXJ5IHdpdGggVU5JT04gc3VicXVlcmllcyBtdXN0IGhhdmUgY29sdW1ucyBhbmQgYSBGUk9NIGNsYXVzZSBpbiB0aGUgbWFpbiBxdWVyeVwiKTtcbiAgICAgIH1cbiAgICAgIGxldCBjb2x1bW5Db3VudHMgPSBbXTtcbiAgICAgIGlmIChub2RlWydfY29sdW1ucyddLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29sdW1uQ291bnRzLnB1c2gobm9kZVsnX2NvbHVtbnMnXS5sZW5ndGgpOyAvLyBJbmNsdWRlIG1haW4gcXVlcnlcbiAgICAgIH1cbiAgICAgIGNvbHVtbkNvdW50cyA9IGNvbHVtbkNvdW50cy5jb25jYXQobm9kZVsnX3VuaW9uJ10ubWFwKHUgPT4gdVsnX2NvbHVtbnMnXS5sZW5ndGggfHwgMSkpO1xuICAgICAgaWYgKGNvbHVtbkNvdW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0Q291bnQgPSBjb2x1bW5Db3VudHNbMF07XG4gICAgICAgIGlmIChjb2x1bW5Db3VudHMuc29tZShjb3VudCA9PiBjb3VudCAhPT0gZmlyc3RDb3VudCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VOSU9OIHF1ZXJpZXMgbXVzdCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBjb2x1bW5zJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgbm9kZVsnX29yZGVyQnknXS5mb3JFYWNoKG8gPT4gby5hY2NlcHQodGhpcykpO1xuICAgIGlmIChub2RlWydfbGltaXQnXSAhPT0gbnVsbCAmJiBub2RlWydfbGltaXQnXSAhPT0gdW5kZWZpbmVkICYmIG5vZGVbJ19saW1pdCddIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdMSU1JVCBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpO1xuICAgIH1cbiAgICBpZiAobm9kZVsnX29mZnNldCddICE9PSBudWxsICYmIG5vZGVbJ19vZmZzZXQnXSAhPT0gdW5kZWZpbmVkICYmIG5vZGVbJ19vZmZzZXQnXSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT0ZGU0VUIG11c3QgYmUgbm9uLW5lZ2F0aXZlJyk7XG4gICAgfVxuXG4gICAgdGhpcy5jb2x1bW5Db3VudCA9IHByZXZDb3VudDsgLy8gUmVzdG9yZSBwYXJlbnQgY29udGV4dCBpZiBuZXN0ZWRcbiAgfVxuXG4gIHZpc2l0VGFibGVGcm9tKG5vZGU6IFRhYmxlRnJvbSk6IHZvaWQge1xuICAgIHRoaXMudmFsaWRhdGVJZGVudGlmaWVyKG5vZGUudGFibGVOYW1lLCAnVGFibGVGcm9tJyk7XG4gIH1cblxuICB2aXNpdFN1YnF1ZXJ5RnJvbShub2RlOiBTdWJxdWVyeUZyb20pOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2Q291bnQgPSB0aGlzLmNvbHVtbkNvdW50O1xuICAgIHRoaXMuY29sdW1uQ291bnQgPSBudWxsOyAvLyBSZXNldCBmb3Igc3VicXVlcnlcbiAgICBub2RlLnN1YnF1ZXJ5LmFjY2VwdCh0aGlzKTtcbiAgICB0aGlzLmNvbHVtbkNvdW50ID0gcHJldkNvdW50OyAvLyBSZXN0b3JlIHBhcmVudCBjb3VudFxuICB9XG5cbiAgdmlzaXRKc29uRWFjaEZyb20obm9kZTogSnNvbkVhY2hGcm9tKTogdm9pZCB7XG4gICAgbm9kZS5qc29uRXhwcmVzc2lvbi5hY2NlcHQodGhpcyk7XG4gICAgaWYgKG5vZGUuanNvblBhdGgpIHtcbiAgICAgIG5vZGUuanNvblBhdGguYWNjZXB0KHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIHZpc2l0Q29sdW1uKG5vZGU6IENvbHVtbik6IHZvaWQge1xuICAgIGlmIChub2RlLmhhc1RhYmxlTmFtZSgpKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlSWRlbnRpZmllcihub2RlLnRhYmxlTmFtZSBhcyBzdHJpbmcsICdDb2x1bW4nKTtcbiAgICB9XG4gICAgdGhpcy52YWxpZGF0ZUlkZW50aWZpZXIobm9kZS5jb2x1bW5OYW1lLCAnQ29sdW1uJyk7XG4gIH1cblxuICB2aXNpdEFsaWFzKG5vZGU6IEFsaWFzPEZyb20gfCBBbGlhc2FibGVFeHByZXNzaW9uPik6IHZvaWQge1xuICAgIGlmICghbm9kZS5hbGlhcyB8fCAhbm9kZS5hbGlhcy50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWxpYXMgbXVzdCBoYXZlIGEgbm9uLWVtcHR5IG5hbWUnKTtcbiAgICB9XG4gICAgaWYgKG5vZGUucmVmZXJlbnQgaW5zdGFuY2VvZiBKb2luKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlQWxpYXMobm9kZS5hbGlhcywgJ0pvaW4nKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUucmVmZXJlbnQgaW5zdGFuY2VvZiBDb2x1bW4pIHtcbiAgICAgIHRoaXMudmFsaWRhdGVBbGlhcyhub2RlLmFsaWFzLCAnQ29sdW1uJyk7XG4gICAgfSBlbHNlIGlmIChub2RlLnJlZmVyZW50IGluc3RhbmNlb2YgVGFibGVGcm9tKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlQWxpYXMobm9kZS5hbGlhcywgJ1RhYmxlRnJvbScpO1xuICAgIH0gZWxzZSBpZiAobm9kZS5yZWZlcmVudCBpbnN0YW5jZW9mIFN1YnF1ZXJ5RnJvbSkge1xuICAgICAgdGhpcy52YWxpZGF0ZUFsaWFzKG5vZGUuYWxpYXMsICdTdWJxdWVyeUZyb20nKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUucmVmZXJlbnQgaW5zdGFuY2VvZiBKc29uRWFjaEZyb20pIHtcbiAgICAgIHRoaXMudmFsaWRhdGVBbGlhcyhub2RlLmFsaWFzLCAnSnNvbkVhY2hGcm9tJyk7XG4gICAgfSBlbHNlIGlmIChub2RlLnJlZmVyZW50IGluc3RhbmNlb2YgQWxpYXNhYmxlRXhwcmVzc2lvbikge1xuICAgICAgdGhpcy52YWxpZGF0ZUFsaWFzKG5vZGUuYWxpYXMsICdFeHByZXNzaW9uJyk7XG4gICAgfVxuICAgIG5vZGUucmVmZXJlbnQuYWNjZXB0KHRoaXMpO1xuICB9XG5cbiAgdmlzaXRKb2luQ2xhdXNlKG5vZGU6IEpvaW4pOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlSWRlbnRpZmllcihub2RlLnRhYmxlTmFtZSwgJ0pvaW5DbGF1c2UnKTtcbiAgICBpZiAoIW5vZGUub24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSm9pbkNsYXVzZSBtdXN0IGhhdmUgYW4gT04gY29uZGl0aW9uJyk7XG4gICAgfVxuICAgIG5vZGUub24uYWNjZXB0KHRoaXMpO1xuICB9XG5cbiAgdmlzaXRPcmRlckJ5KG5vZGU6IE9yZGVyQnkpOiB2b2lkIHtcbiAgICBub2RlLmNvbHVtbi5hY2NlcHQodGhpcyk7XG4gIH1cblxuICB2aXNpdFdpdGhDbGF1c2Uobm9kZTogV2l0aCk6IHZvaWQge1xuICAgIHRoaXMudmFsaWRhdGVJZGVudGlmaWVyKG5vZGUubmFtZSwgJ1dpdGhDbGF1c2UnKTtcbiAgICBjb25zdCBwcmV2Q291bnQgPSB0aGlzLmNvbHVtbkNvdW50O1xuICAgIHRoaXMuY29sdW1uQ291bnQgPSBudWxsOyAvLyBSZXNldCBmb3Igc3VicXVlcnlcbiAgICBub2RlLnF1ZXJ5LmFjY2VwdCh0aGlzKTtcbiAgICB0aGlzLmNvbHVtbkNvdW50ID0gcHJldkNvdW50OyAvLyBSZXN0b3JlIHBhcmVudCBjb3VudFxuICB9XG5cbiAgdmlzaXRCaW5hcnlFeHByZXNzaW9uKG5vZGU6IEJpbmFyeUV4cHJlc3Npb24pOiB2b2lkIHtcbiAgICBpZiAoIW5vZGUub3BlcmF0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQmluYXJ5RXhwcmVzc2lvbiBtdXN0IGhhdmUgYSB2YWxpZCBvcGVyYXRvcicpO1xuICAgIH1cbiAgICBpZiAoIW5vZGUubGVmdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCaW5hcnlFeHByZXNzaW9uIG11c3QgaGF2ZSBhIHZhbGlkIGxlZnQgb3BlcmFuZCcpO1xuICAgIH1cbiAgICBpZiAoIW5vZGUucmlnaHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQmluYXJ5RXhwcmVzc2lvbiBtdXN0IGhhdmUgYSB2YWxpZCByaWdodCBvcGVyYW5kJyk7XG4gICAgfVxuICAgIG5vZGUubGVmdC5hY2NlcHQodGhpcyk7XG4gICAgbm9kZS5yaWdodC5hY2NlcHQodGhpcyk7XG4gIH1cblxuICB2aXNpdFVuYXJ5RXhwcmVzc2lvbihub2RlOiBVbmFyeUV4cHJlc3Npb24pOiB2b2lkIHtcbiAgICBpZiAoIW5vZGUub3BlcmF0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hcnlFeHByZXNzaW9uIG11c3QgaGF2ZSBhIHZhbGlkIG9wZXJhdG9yJyk7XG4gICAgfVxuICAgIGlmICghbm9kZS5vcGVyYW5kKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYXJ5RXhwcmVzc2lvbiBtdXN0IGhhdmUgYSB2YWxpZCBvcGVyYW5kJyk7XG4gICAgfVxuICAgIG5vZGUub3BlcmFuZC5hY2NlcHQodGhpcyk7XG4gIH1cblxuICB2aXNpdEluRXhwcmVzc2lvbihub2RlOiBJbkV4cHJlc3Npb24pOiB2b2lkIHtcbiAgICBpZiAobm9kZS5sZWZ0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJTiBleHByZXNzaW9uIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgbGVmdCBleHByZXNzaW9uJyk7XG4gICAgfVxuICAgIG5vZGUubGVmdC5mb3JFYWNoKGwgPT4gbC5hY2NlcHQodGhpcykpO1xuICAgIGlmIChub2RlLnZhbHVlcyBpbnN0YW5jZW9mIFNlbGVjdFF1ZXJ5KSB7XG4gICAgICBub2RlLnZhbHVlcy5hY2NlcHQodGhpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChub2RlLnZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJTiBleHByZXNzaW9uIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgdmFsdWUgc2V0Jyk7XG4gICAgICB9XG4gICAgICBub2RlLnZhbHVlcy5mb3JFYWNoKHNldCA9PiB7XG4gICAgICAgIGlmIChzZXQubGVuZ3RoICE9PSBub2RlLmxlZnQubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdWYWx1ZSBzZXRzIGluIElOIGV4cHJlc3Npb24gbXVzdCBtYXRjaCB0aGUgbnVtYmVyIG9mIGxlZnQgZXhwcmVzc2lvbnMnKTtcbiAgICAgICAgfVxuICAgICAgICBzZXQuZm9yRWFjaCh2ID0+IHYuYWNjZXB0KHRoaXMpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHZpc2l0Q29uY2F0KG5vZGU6IENvbmNhdCk6IHZvaWQge1xuICAgIGlmIChub2RlLmV4cHJlc3Npb25zLmxlbmd0aCA8IDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29uY2F0IG11c3QgaGF2ZSBhdCBsZWFzdCB0d28gZXhwcmVzc2lvbnMnKTtcbiAgICB9XG4gICAgbm9kZS5leHByZXNzaW9ucy5mb3JFYWNoKGUgPT4gZS5hY2NlcHQodGhpcykpO1xuICB9XG5cbiAgdmlzaXRDYXNlRXhwcmVzc2lvbihub2RlOiBDYXNlRXhwcmVzc2lvbik6IHZvaWQge1xuICAgIGlmIChub2RlLmNhc2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYXNlRXhwcmVzc2lvbiBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIFdIRU4vVEhFTiBwYWlyJyk7XG4gICAgfVxuICAgIG5vZGUuY2FzZXMuZm9yRWFjaChjID0+IHtcbiAgICAgIGMud2hlbi5hY2NlcHQodGhpcyk7XG4gICAgICBjLnRoZW4uYWNjZXB0KHRoaXMpO1xuICAgIH0pO1xuICAgIGlmIChub2RlLmVsc2UpIHtcbiAgICAgIG5vZGUuZWxzZS5hY2NlcHQodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgdmlzaXRGdW5jdGlvbkV4cHJlc3Npb24obm9kZTogRnVuY3Rpb25FeHByZXNzaW9uKTogdm9pZCB7XG4gICAgY29uc3Qgbm9BcmdGdW5jdGlvbnMgPSBbJ1JBTkRPTSddO1xuICAgIGlmICghbm9BcmdGdW5jdGlvbnMuaW5jbHVkZXMobm9kZS5uYW1lKSAmJiBub2RlLmFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZ1bmN0aW9uICR7bm9kZS5uYW1lfSByZXF1aXJlcyBhdCBsZWFzdCBvbmUgYXJndW1lbnRgKTtcbiAgICB9XG4gICAgbm9kZS5hcmdzLmZvckVhY2goYSA9PiBhLmFjY2VwdCh0aGlzKSk7XG4gIH1cblxuICB2aXNpdFBhcmFtRXhwcmVzc2lvbihfbm9kZTogUGFyYW0pOiB2b2lkIHtcbiAgICAvLyBObyBzcGVjaWZpYyB2YWxpZGF0aW9uIG5lZWRlZFxuICB9XG5cbiAgdmlzaXRTdHJpbmdMaXRlcmFsKG5vZGU6IFN0cmluZ0xpdGVyYWwpOiB2b2lkIHtcbiAgICBpZiAobm9kZS52YWx1ZSA9PT0gbnVsbCB8fCBub2RlLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU3RyaW5nTGl0ZXJhbCB2YWx1ZSBjYW5ub3QgYmUgbnVsbCBvciB1bmRlZmluZWQnKTtcbiAgICB9XG4gIH1cblxuICB2aXNpdE51bWJlckxpdGVyYWwobm9kZTogTnVtYmVyTGl0ZXJhbCk6IHZvaWQge1xuICAgIGlmIChpc05hTihub2RlLnZhbHVlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOdW1iZXJMaXRlcmFsIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBudW1iZXInKTtcbiAgICB9XG4gIH1cblxuICB2aXNpdE51bGxMaXRlcmFsKF9ub2RlOiBOdWxsTGl0ZXJhbCk6IHZvaWQge1xuICAgIC8vIE5vIHNwZWNpZmljIHZhbGlkYXRpb24gbmVlZGVkXG4gIH1cblxuICB2aXNpdEV4aXN0c0V4cHJlc3Npb24obm9kZTogRXhpc3RzRXhwcmVzc2lvbik6IHZvaWQge1xuICAgIGlmICghbm9kZS5zdWJxdWVyeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeGlzdHNFeHByZXNzaW9uIG11c3QgaGF2ZSBhIHZhbGlkIHN1YnF1ZXJ5Jyk7XG4gICAgfVxuICAgIGNvbnN0IHByZXZDb3VudCA9IHRoaXMuY29sdW1uQ291bnQ7XG4gICAgdGhpcy5jb2x1bW5Db3VudCA9IG51bGw7IC8vIFJlc2V0IGZvciBzdWJxdWVyeVxuICAgIG5vZGUuc3VicXVlcnkuYWNjZXB0KHRoaXMpO1xuICAgIHRoaXMuY29sdW1uQ291bnQgPSBwcmV2Q291bnQ7IC8vIFJlc3RvcmUgcGFyZW50IGNvdW50XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,6 @@
1
+ import { InsertQuery } from "../ast/InsertQuery";
2
+ import { SelectQuery } from "../ast/SelectQuery";
3
+ import { SqlTreeNodeVisitor } from "../visitor/SqlTreeNodeVisitor";
4
+ export interface QueryValidator extends SqlTreeNodeVisitor<void> {
5
+ validate(node: SelectQuery | InsertQuery): void;
6
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUXVlcnlWYWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGUvUXVlcnlWYWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluc2VydFF1ZXJ5IH0gZnJvbSBcIi4uL2FzdC9JbnNlcnRRdWVyeVwiO1xuaW1wb3J0IHsgU2VsZWN0UXVlcnkgfSBmcm9tIFwiLi4vYXN0L1NlbGVjdFF1ZXJ5XCI7XG5pbXBvcnQgeyBTcWxUcmVlTm9kZVZpc2l0b3IgfSBmcm9tIFwiLi4vdmlzaXRvci9TcWxUcmVlTm9kZVZpc2l0b3JcIjtcblxuZXhwb3J0IGludGVyZmFjZSBRdWVyeVZhbGlkYXRvciBleHRlbmRzIFNxbFRyZWVOb2RlVmlzaXRvcjx2b2lkPiB7XG4gIHZhbGlkYXRlKG5vZGU6IFNlbGVjdFF1ZXJ5IHwgSW5zZXJ0UXVlcnkpOiB2b2lkO1xufVxuIl19
@@ -0,0 +1,27 @@
1
+ import { JsonEachFrom, TableFrom } from "../ast/From";
2
+ import { FunctionExpression } from "../ast/FunctionExpression";
3
+ import { InExpression } from "../ast/InExpression";
4
+ import { InsertQuery } from "../ast/InsertQuery";
5
+ import { Join } from "../ast/Join";
6
+ import { SelectQuery } from "../ast/SelectQuery";
7
+ import { UnaryExpression } from "../ast/UnaryExpression";
8
+ import { With } from "../ast/With";
9
+ import { SqlTreeNodeVisitor } from "../visitor/SqlTreeNodeVisitor";
10
+ import { CommonQueryValidator } from "./CommonQueryValidator";
11
+ import { QueryValidator } from "./QueryValidator";
12
+ export declare class SQLiteQueryValidator extends CommonQueryValidator implements QueryValidator, SqlTreeNodeVisitor<void> {
13
+ private supportedFunctions;
14
+ private supportedUnaryOperators;
15
+ private isWithRecursive;
16
+ validate(query: SelectQuery | InsertQuery): void;
17
+ protected reset(): void;
18
+ visitInsertQuery(node: InsertQuery): void;
19
+ visitSelectQuery(node: SelectQuery): void;
20
+ visitJoinClause(node: Join): void;
21
+ visitWithClause(node: With): void;
22
+ visitFunctionExpression(node: FunctionExpression): void;
23
+ visitTableFrom(node: TableFrom): void;
24
+ visitJsonEachFrom(node: JsonEachFrom): void;
25
+ visitUnaryExpression(node: UnaryExpression): void;
26
+ visitInExpression(node: InExpression): void;
27
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SQLiteQueryValidator = void 0;
4
+ const Join_1 = require("../ast/Join");
5
+ const Operator_1 = require("../ast/Operator");
6
+ const CommonQueryValidator_1 = require("./CommonQueryValidator");
7
+ class SQLiteQueryValidator extends CommonQueryValidator_1.CommonQueryValidator {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.supportedFunctions = new Set([
11
+ // Core scalar functions
12
+ 'ABS', 'CEIL', 'FLOOR', 'ROUND', 'TRUNC', 'RANDOM', 'RANDOMBLOB',
13
+ 'LOWER', 'UPPER', 'LENGTH', 'SUBSTR', 'TRIM', 'LTRIM', 'RTRIM',
14
+ 'REPLACE', 'INSTR', 'QUOTE', 'CHAR', 'UNICODE', 'HEX', 'ZEROBLOB',
15
+ 'COALESCE', 'IFNULL', 'NULLIF', 'TYPEOF', 'TOTAL_CHANGES', 'CHANGES',
16
+ 'LAST_INSERT_ROWID',
17
+ // Aggregate functions
18
+ 'COUNT', 'SUM', 'AVG', 'MIN', 'MAX', 'TOTAL', 'GROUP_CONCAT',
19
+ // Date and time functions
20
+ 'DATE', 'TIME', 'DATETIME', 'JULIANDAY', 'STRFTIME',
21
+ // JSON1 functions
22
+ 'json', 'json_array', 'json_object', 'json_extract', 'json_insert',
23
+ 'json_replace', 'json_set', 'json_remove', 'json_type', 'json_valid',
24
+ 'json_quote', 'json_patch', 'json_array_length', 'json_group_array',
25
+ 'json_group_object', 'json_each', 'json_tree'
26
+ ]);
27
+ this.supportedUnaryOperators = new Set([
28
+ Operator_1.Operator.NOT, Operator_1.Operator.PLUS, Operator_1.Operator.MINUS,
29
+ Operator_1.Operator.IS_NULL, Operator_1.Operator.IS_NOT_NULL,
30
+ ]);
31
+ this.isWithRecursive = false;
32
+ }
33
+ validate(query) {
34
+ this.reset();
35
+ query.accept(this);
36
+ }
37
+ reset() {
38
+ super.reset();
39
+ this.isWithRecursive = false;
40
+ }
41
+ visitInsertQuery(node) {
42
+ super.visitInsertQuery(node);
43
+ // SQLite-specific validation (if any) can be added here
44
+ }
45
+ visitSelectQuery(node) {
46
+ super.visitSelectQuery(node);
47
+ if (node['_limit'] !== null && node['_limit'] !== undefined && !Number.isInteger(node['_limit'])) {
48
+ throw new Error('SQLite LIMIT must be an integer');
49
+ }
50
+ if (node['_offset'] !== null && node['_offset'] !== undefined && !Number.isInteger(node['_offset'])) {
51
+ throw new Error('SQLite OFFSET must be an integer');
52
+ }
53
+ }
54
+ visitJoinClause(node) {
55
+ if (node.type === Join_1.JoinType.RIGHT || node.type === Join_1.JoinType.FULL) {
56
+ throw new Error(`SQLite does not support ${node.type} JOIN`);
57
+ }
58
+ super.visitJoinClause(node);
59
+ }
60
+ visitWithClause(node) {
61
+ const prevRecursive = this.isWithRecursive;
62
+ this.isWithRecursive = false;
63
+ node.query.accept(this);
64
+ if (this.isWithRecursive) {
65
+ throw new Error('Recursive WITH clauses are not supported in this validator');
66
+ }
67
+ this.isWithRecursive = prevRecursive;
68
+ super.visitWithClause(node);
69
+ }
70
+ visitFunctionExpression(node) {
71
+ if (!this.supportedFunctions.has(node.name)) {
72
+ throw new Error(`Function ${node.name} is not supported in SQLite`);
73
+ }
74
+ super.visitFunctionExpression(node);
75
+ }
76
+ visitTableFrom(node) {
77
+ if (this.isWithRecursive) {
78
+ throw new Error('Recursive reference to WITH clause detected');
79
+ }
80
+ super.visitTableFrom(node);
81
+ }
82
+ visitJsonEachFrom(node) {
83
+ super.visitJsonEachFrom(node);
84
+ }
85
+ visitUnaryExpression(node) {
86
+ if (!this.supportedUnaryOperators.has(node.operator)) {
87
+ throw new Error(`Unary operator ${node.operator} is not supported in SQLite`);
88
+ }
89
+ super.visitUnaryExpression(node);
90
+ }
91
+ visitInExpression(node) {
92
+ super.visitInExpression(node);
93
+ }
94
+ }
95
+ exports.SQLiteQueryValidator = SQLiteQueryValidator;
96
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU1FMaXRlUXVlcnlWYWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGUvU1FMaXRlUXVlcnlWYWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBS0Esc0NBQTZDO0FBQzdDLDhDQUEyQztBQUszQyxpRUFBOEQ7QUFHOUQsTUFBYSxvQkFDWCxTQUFRLDJDQUFvQjtJQUQ5Qjs7UUFJVSx1QkFBa0IsR0FBc0IsSUFBSSxHQUFHLENBQUM7WUFDdEQsd0JBQXdCO1lBQ3hCLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFlBQVk7WUFDaEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTztZQUM5RCxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVO1lBQ2pFLFVBQVUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsU0FBUztZQUNwRSxtQkFBbUI7WUFDbkIsc0JBQXNCO1lBQ3RCLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLGNBQWM7WUFDNUQsMEJBQTBCO1lBQzFCLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxVQUFVO1lBQ25ELGtCQUFrQjtZQUNsQixNQUFNLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsYUFBYTtZQUNsRSxjQUFjLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsWUFBWTtZQUNwRSxZQUFZLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLGtCQUFrQjtZQUNuRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsV0FBVztTQUM5QyxD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Q3pCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBQ0QsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQsaUJBQWlCLENBQUMsSUFBa0I7UUFDbEMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxJQUFxQjtRQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLGtCQUFrQixJQUFJLENBQUMsUUFBUSw2QkFBNkIsQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFDRCxLQUFLLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELGlCQUFpQixDQUFDLElBQWtCO1FBQ2xDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxDQUFDO0NBQ0Y7QUFwR0Qsb0RBb0dDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSnNvbkVhY2hGcm9tLCBUYWJsZUZyb20gfSBmcm9tIFwiLi4vYXN0L0Zyb21cIjtcbmltcG9ydCB7IEZ1bmN0aW9uRXhwcmVzc2lvbiB9IGZyb20gXCIuLi9hc3QvRnVuY3Rpb25FeHByZXNzaW9uXCI7XG5pbXBvcnQgeyBGdW5jdGlvbk5hbWUgfSBmcm9tIFwiLi4vYXN0L0Z1bmN0aW9uTmFtZVwiO1xuaW1wb3J0IHsgSW5FeHByZXNzaW9uIH0gZnJvbSBcIi4uL2FzdC9JbkV4cHJlc3Npb25cIjtcbmltcG9ydCB7IEluc2VydFF1ZXJ5IH0gZnJvbSBcIi4uL2FzdC9JbnNlcnRRdWVyeVwiO1xuaW1wb3J0IHsgSm9pbiwgSm9pblR5cGUgfSBmcm9tIFwiLi4vYXN0L0pvaW5cIjtcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSBcIi4uL2FzdC9PcGVyYXRvclwiO1xuaW1wb3J0IHsgU2VsZWN0UXVlcnkgfSBmcm9tIFwiLi4vYXN0L1NlbGVjdFF1ZXJ5XCI7XG5pbXBvcnQgeyBVbmFyeUV4cHJlc3Npb24gfSBmcm9tIFwiLi4vYXN0L1VuYXJ5RXhwcmVzc2lvblwiO1xuaW1wb3J0IHsgV2l0aCB9IGZyb20gXCIuLi9hc3QvV2l0aFwiO1xuaW1wb3J0IHsgU3FsVHJlZU5vZGVWaXNpdG9yIH0gZnJvbSBcIi4uL3Zpc2l0b3IvU3FsVHJlZU5vZGVWaXNpdG9yXCI7XG5pbXBvcnQgeyBDb21tb25RdWVyeVZhbGlkYXRvciB9IGZyb20gXCIuL0NvbW1vblF1ZXJ5VmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBRdWVyeVZhbGlkYXRvciB9IGZyb20gXCIuL1F1ZXJ5VmFsaWRhdG9yXCI7XG5cbmV4cG9ydCBjbGFzcyBTUUxpdGVRdWVyeVZhbGlkYXRvclxuICBleHRlbmRzIENvbW1vblF1ZXJ5VmFsaWRhdG9yXG4gIGltcGxlbWVudHMgUXVlcnlWYWxpZGF0b3IsIFNxbFRyZWVOb2RlVmlzaXRvcjx2b2lkPlxue1xuICBwcml2YXRlIHN1cHBvcnRlZEZ1bmN0aW9uczogU2V0PEZ1bmN0aW9uTmFtZT4gPSBuZXcgU2V0KFtcbiAgICAvLyBDb3JlIHNjYWxhciBmdW5jdGlvbnNcbiAgICAnQUJTJywgJ0NFSUwnLCAnRkxPT1InLCAnUk9VTkQnLCAnVFJVTkMnLCAnUkFORE9NJywgJ1JBTkRPTUJMT0InLFxuICAgICdMT1dFUicsICdVUFBFUicsICdMRU5HVEgnLCAnU1VCU1RSJywgJ1RSSU0nLCAnTFRSSU0nLCAnUlRSSU0nLFxuICAgICdSRVBMQUNFJywgJ0lOU1RSJywgJ1FVT1RFJywgJ0NIQVInLCAnVU5JQ09ERScsICdIRVgnLCAnWkVST0JMT0InLFxuICAgICdDT0FMRVNDRScsICdJRk5VTEwnLCAnTlVMTElGJywgJ1RZUEVPRicsICdUT1RBTF9DSEFOR0VTJywgJ0NIQU5HRVMnLFxuICAgICdMQVNUX0lOU0VSVF9ST1dJRCcsXG4gICAgLy8gQWdncmVnYXRlIGZ1bmN0aW9uc1xuICAgICdDT1VOVCcsICdTVU0nLCAnQVZHJywgJ01JTicsICdNQVgnLCAnVE9UQUwnLCAnR1JPVVBfQ09OQ0FUJyxcbiAgICAvLyBEYXRlIGFuZCB0aW1lIGZ1bmN0aW9uc1xuICAgICdEQVRFJywgJ1RJTUUnLCAnREFURVRJTUUnLCAnSlVMSUFOREFZJywgJ1NUUkZUSU1FJyxcbiAgICAvLyBKU09OMSBmdW5jdGlvbnNcbiAgICAnanNvbicsICdqc29uX2FycmF5JywgJ2pzb25fb2JqZWN0JywgJ2pzb25fZXh0cmFjdCcsICdqc29uX2luc2VydCcsXG4gICAgJ2pzb25fcmVwbGFjZScsICdqc29uX3NldCcsICdqc29uX3JlbW92ZScsICdqc29uX3R5cGUnLCAnanNvbl92YWxpZCcsXG4gICAgJ2pzb25fcXVvdGUnLCAnanNvbl9wYXRjaCcsICdqc29uX2FycmF5X2xlbmd0aCcsICdqc29uX2dyb3VwX2FycmF5JyxcbiAgICAnanNvbl9ncm91cF9vYmplY3QnLCAnanNvbl9lYWNoJywgJ2pzb25fdHJlZSdcbiAgXSk7XG5cbiAgcHJpdmF0ZSBzdXBwb3J0ZWRVbmFyeU9wZXJhdG9yczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KFtcbiAgICBPcGVyYXRvci5OT1QsIE9wZXJhdG9yLlBMVVMsIE9wZXJhdG9yLk1JTlVTLFxuICAgIE9wZXJhdG9yLklTX05VTEwsIE9wZXJhdG9yLklTX05PVF9OVUxMLFxuICBdKTtcblxuICBwcml2YXRlIGlzV2l0aFJlY3Vyc2l2ZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHB1YmxpYyB2YWxpZGF0ZShxdWVyeTogU2VsZWN0UXVlcnkgfCBJbnNlcnRRdWVyeSk6IHZvaWQge1xuICAgIHRoaXMucmVzZXQoKTtcbiAgICBxdWVyeS5hY2NlcHQodGhpcyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVzZXQoKTogdm9pZCB7XG4gICAgc3VwZXIucmVzZXQoKTtcbiAgICB0aGlzLmlzV2l0aFJlY3Vyc2l2ZSA9IGZhbHNlO1xuICB9XG5cbiAgdmlzaXRJbnNlcnRRdWVyeShub2RlOiBJbnNlcnRRdWVyeSk6IHZvaWQge1xuICAgIHN1cGVyLnZpc2l0SW5zZXJ0UXVlcnkobm9kZSk7XG4gICAgLy8gU1FMaXRlLXNwZWNpZmljIHZhbGlkYXRpb24gKGlmIGFueSkgY2FuIGJlIGFkZGVkIGhlcmVcbiAgfVxuXG4gIHZpc2l0U2VsZWN0UXVlcnkobm9kZTogU2VsZWN0UXVlcnkpOiB2b2lkIHtcbiAgICBzdXBlci52aXNpdFNlbGVjdFF1ZXJ5KG5vZGUpO1xuICAgIGlmIChub2RlWydfbGltaXQnXSAhPT0gbnVsbCAmJiBub2RlWydfbGltaXQnXSAhPT0gdW5kZWZpbmVkICYmICFOdW1iZXIuaXNJbnRlZ2VyKG5vZGVbJ19saW1pdCddKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTUUxpdGUgTElNSVQgbXVzdCBiZSBhbiBpbnRlZ2VyJyk7XG4gICAgfVxuICAgIGlmIChub2RlWydfb2Zmc2V0J10gIT09IG51bGwgJiYgbm9kZVsnX29mZnNldCddICE9PSB1bmRlZmluZWQgJiYgIU51bWJlci5pc0ludGVnZXIobm9kZVsnX29mZnNldCddKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTUUxpdGUgT0ZGU0VUIG11c3QgYmUgYW4gaW50ZWdlcicpO1xuICAgIH1cbiAgfVxuXG4gIHZpc2l0Sm9pbkNsYXVzZShub2RlOiBKb2luKTogdm9pZCB7XG4gICAgaWYgKG5vZGUudHlwZSA9PT0gSm9pblR5cGUuUklHSFQgfHwgbm9kZS50eXBlID09PSBKb2luVHlwZS5GVUxMKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNRTGl0ZSBkb2VzIG5vdCBzdXBwb3J0ICR7bm9kZS50eXBlfSBKT0lOYCk7XG4gICAgfVxuICAgIHN1cGVyLnZpc2l0Sm9pbkNsYXVzZShub2RlKTtcbiAgfVxuXG4gIHZpc2l0V2l0aENsYXVzZShub2RlOiBXaXRoKTogdm9pZCB7XG4gICAgY29uc3QgcHJldlJlY3Vyc2l2ZSA9IHRoaXMuaXNXaXRoUmVjdXJzaXZlO1xuICAgIHRoaXMuaXNXaXRoUmVjdXJzaXZlID0gZmFsc2U7XG4gICAgbm9kZS5xdWVyeS5hY2NlcHQodGhpcyk7XG4gICAgaWYgKHRoaXMuaXNXaXRoUmVjdXJzaXZlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlY3Vyc2l2ZSBXSVRIIGNsYXVzZXMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyB2YWxpZGF0b3InKTtcbiAgICB9XG4gICAgdGhpcy5pc1dpdGhSZWN1cnNpdmUgPSBwcmV2UmVjdXJzaXZlO1xuICAgIHN1cGVyLnZpc2l0V2l0aENsYXVzZShub2RlKTtcbiAgfVxuXG4gIHZpc2l0RnVuY3Rpb25FeHByZXNzaW9uKG5vZGU6IEZ1bmN0aW9uRXhwcmVzc2lvbik6IHZvaWQge1xuICAgIGlmICghdGhpcy5zdXBwb3J0ZWRGdW5jdGlvbnMuaGFzKG5vZGUubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRnVuY3Rpb24gJHtub2RlLm5hbWV9IGlzIG5vdCBzdXBwb3J0ZWQgaW4gU1FMaXRlYCk7XG4gICAgfVxuICAgIHN1cGVyLnZpc2l0RnVuY3Rpb25FeHByZXNzaW9uKG5vZGUpO1xuICB9XG5cbiAgdmlzaXRUYWJsZUZyb20obm9kZTogVGFibGVGcm9tKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNXaXRoUmVjdXJzaXZlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlY3Vyc2l2ZSByZWZlcmVuY2UgdG8gV0lUSCBjbGF1c2UgZGV0ZWN0ZWQnKTtcbiAgICB9XG4gICAgc3VwZXIudmlzaXRUYWJsZUZyb20obm9kZSk7XG4gIH1cblxuICB2aXNpdEpzb25FYWNoRnJvbShub2RlOiBKc29uRWFjaEZyb20pOiB2b2lkIHtcbiAgICBzdXBlci52aXNpdEpzb25FYWNoRnJvbShub2RlKTtcbiAgfVxuXG4gIHZpc2l0VW5hcnlFeHByZXNzaW9uKG5vZGU6IFVuYXJ5RXhwcmVzc2lvbik6IHZvaWQge1xuICAgIGlmICghdGhpcy5zdXBwb3J0ZWRVbmFyeU9wZXJhdG9ycy5oYXMobm9kZS5vcGVyYXRvcikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hcnkgb3BlcmF0b3IgJHtub2RlLm9wZXJhdG9yfSBpcyBub3Qgc3VwcG9ydGVkIGluIFNRTGl0ZWApO1xuICAgIH1cbiAgICBzdXBlci52aXNpdFVuYXJ5RXhwcmVzc2lvbihub2RlKTtcbiAgfVxuXG4gIHZpc2l0SW5FeHByZXNzaW9uKG5vZGU6IEluRXhwcmVzc2lvbik6IHZvaWQge1xuICAgIHN1cGVyLnZpc2l0SW5FeHByZXNzaW9uKG5vZGUpO1xuICB9XG59XG4iXX0=