@powersync/common 1.36.0 → 1.37.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.
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Helper function for sanitizing UUID input strings.
3
+ * Typically used with {@link sanitizeSQL}.
4
+ */
5
+ export declare function sanitizeUUID(uuid: string): string;
6
+ /**
7
+ * SQL string template function for {@link TrackDiffOptions#when} and {@link CreateDiffTriggerOptions#when}.
8
+ *
9
+ * This function performs basic string interpolation for SQLite WHEN clauses.
10
+ *
11
+ * **String placeholders:**
12
+ * - All string values passed as placeholders are automatically wrapped in single quotes (`'`).
13
+ * - Do not manually wrap placeholders in single quotes in your template string; the function will handle quoting and escaping for you.
14
+ * - Any single quotes within the string value are escaped by doubling them (`''`), as required by SQL syntax.
15
+ *
16
+ * **Other types:**
17
+ * - `null` and `undefined` are converted to SQL `NULL`.
18
+ * - Objects are stringified using `JSON.stringify()` and wrapped in single quotes, with any single quotes inside the stringified value escaped.
19
+ * - Numbers and other primitive types are inserted directly.
20
+ *
21
+ * **Usage example:**
22
+ * ```typescript
23
+ * const myID = "O'Reilly";
24
+ * const clause = sanitizeSQL`New.id = ${myID}`;
25
+ * // Result: "New.id = 'O''Reilly'"
26
+ * ```
27
+ *
28
+ * Avoid manually quoting placeholders:
29
+ * ```typescript
30
+ * // Incorrect:
31
+ * sanitizeSQL`New.id = '${myID}'` // Produces double quotes: New.id = ''O''Reilly''
32
+ * ```
33
+ */
34
+ export declare function sanitizeSQL(strings: TemplateStringsArray, ...values: any[]): string;
@@ -0,0 +1,68 @@
1
+ function sanitizeString(input) {
2
+ return `'${input.replace(/'/g, "''")}'`;
3
+ }
4
+ /**
5
+ * Helper function for sanitizing UUID input strings.
6
+ * Typically used with {@link sanitizeSQL}.
7
+ */
8
+ export function sanitizeUUID(uuid) {
9
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
10
+ const isValid = uuidRegex.test(uuid);
11
+ if (!isValid) {
12
+ throw new Error(`${uuid} is not a valid UUID`);
13
+ }
14
+ return uuid;
15
+ }
16
+ /**
17
+ * SQL string template function for {@link TrackDiffOptions#when} and {@link CreateDiffTriggerOptions#when}.
18
+ *
19
+ * This function performs basic string interpolation for SQLite WHEN clauses.
20
+ *
21
+ * **String placeholders:**
22
+ * - All string values passed as placeholders are automatically wrapped in single quotes (`'`).
23
+ * - Do not manually wrap placeholders in single quotes in your template string; the function will handle quoting and escaping for you.
24
+ * - Any single quotes within the string value are escaped by doubling them (`''`), as required by SQL syntax.
25
+ *
26
+ * **Other types:**
27
+ * - `null` and `undefined` are converted to SQL `NULL`.
28
+ * - Objects are stringified using `JSON.stringify()` and wrapped in single quotes, with any single quotes inside the stringified value escaped.
29
+ * - Numbers and other primitive types are inserted directly.
30
+ *
31
+ * **Usage example:**
32
+ * ```typescript
33
+ * const myID = "O'Reilly";
34
+ * const clause = sanitizeSQL`New.id = ${myID}`;
35
+ * // Result: "New.id = 'O''Reilly'"
36
+ * ```
37
+ *
38
+ * Avoid manually quoting placeholders:
39
+ * ```typescript
40
+ * // Incorrect:
41
+ * sanitizeSQL`New.id = '${myID}'` // Produces double quotes: New.id = ''O''Reilly''
42
+ * ```
43
+ */
44
+ export function sanitizeSQL(strings, ...values) {
45
+ let result = '';
46
+ strings.forEach((str, i) => {
47
+ result += str;
48
+ if (i < values.length) {
49
+ // For SQL, escape single quotes in string values
50
+ const value = values[i];
51
+ if (typeof value == 'string') {
52
+ result += sanitizeString(value);
53
+ }
54
+ else if (value == null) {
55
+ result += 'NULL';
56
+ }
57
+ else if (typeof value == 'object') {
58
+ // Stringify the object and escape single quotes in the result
59
+ const stringified = JSON.stringify(value);
60
+ result += sanitizeString(stringified);
61
+ }
62
+ else {
63
+ result += value;
64
+ }
65
+ }
66
+ });
67
+ return result;
68
+ }
package/lib/index.d.ts CHANGED
@@ -30,6 +30,8 @@ export * from './db/schema/Schema.js';
30
30
  export * from './db/schema/Table.js';
31
31
  export * from './db/schema/TableV2.js';
32
32
  export * from './client/Query.js';
33
+ export * from './client/triggers/sanitizeSQL.js';
34
+ export * from './client/triggers/TriggerManager.js';
33
35
  export * from './client/watched/GetAllQuery.js';
34
36
  export * from './client/watched/processors/AbstractQueryProcessor.js';
35
37
  export * from './client/watched/processors/comparators.js';
package/lib/index.js CHANGED
@@ -30,6 +30,8 @@ export * from './db/schema/Schema.js';
30
30
  export * from './db/schema/Table.js';
31
31
  export * from './db/schema/TableV2.js';
32
32
  export * from './client/Query.js';
33
+ export * from './client/triggers/sanitizeSQL.js';
34
+ export * from './client/triggers/TriggerManager.js';
33
35
  export * from './client/watched/GetAllQuery.js';
34
36
  export * from './client/watched/processors/AbstractQueryProcessor.js';
35
37
  export * from './client/watched/processors/comparators.js';
@@ -1,3 +1,12 @@
1
+ /**
2
+ * A ponyfill for `Symbol.asyncIterator` that is compatible with the
3
+ * [recommended polyfill](https://github.com/Azure/azure-sdk-for-js/blob/%40azure/core-asynciterator-polyfill_1.0.2/sdk/core/core-asynciterator-polyfill/src/index.ts#L4-L6)
4
+ * we recommend for React Native.
5
+ *
6
+ * As long as we use this symbol (instead of `for await` and `async *`) in this package, we can be compatible with async
7
+ * iterators without requiring them.
8
+ */
9
+ export declare const symbolAsyncIterator: typeof Symbol.asyncIterator;
1
10
  /**
2
11
  * Throttle a function to be called at most once every "wait" milliseconds,
3
12
  * on the trailing edge.
@@ -1,3 +1,12 @@
1
+ /**
2
+ * A ponyfill for `Symbol.asyncIterator` that is compatible with the
3
+ * [recommended polyfill](https://github.com/Azure/azure-sdk-for-js/blob/%40azure/core-asynciterator-polyfill_1.0.2/sdk/core/core-asynciterator-polyfill/src/index.ts#L4-L6)
4
+ * we recommend for React Native.
5
+ *
6
+ * As long as we use this symbol (instead of `for await` and `async *`) in this package, we can be compatible with async
7
+ * iterators without requiring them.
8
+ */
9
+ export const symbolAsyncIterator = Symbol.asyncIterator ?? Symbol.for('Symbol.asyncIterator');
1
10
  /**
2
11
  * Throttle a function to be called at most once every "wait" milliseconds,
3
12
  * on the trailing edge.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powersync/common",
3
- "version": "1.36.0",
3
+ "version": "1.37.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"