@digitalwalletcorp/sql-builder 1.6.1 → 2.1.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.
package/README.md CHANGED
@@ -2,27 +2,68 @@
2
2
 
3
3
  [![NPM Version](https://img.shields.io/npm/v/%40digitalwalletcorp%2Fsql-builder)](https://www.npmjs.com/package/@digitalwalletcorp/sql-builder) [![License](https://img.shields.io/npm/l/%40digitalwalletcorp%2Fsql-builder)](https://opensource.org/licenses/MIT) [![Build Status](https://img.shields.io/github/actions/workflow/status/digitalwalletcorp/sql-builder/ci.yml?branch=main)](https://github.com/digitalwalletcorp/sql-builder/actions) [![Test Coverage](https://img.shields.io/codecov/c/github/digitalwalletcorp/sql-builder.svg)](https://codecov.io/gh/digitalwalletcorp/sql-builder)
4
4
 
5
- Inspired by Java's S2Dao, this TypeScript/JavaScript library dynamically generates SQL. It embeds entity objects into SQL templates, simplifying complex query construction and enhancing readability. Ideal for flexible, type-safe SQL generation without a full ORM. It efficiently handles dynamic `WHERE` clauses, parameter binding, and looping, reducing boilerplate code.
5
+ Inspired by Java's **S2Dao its successor Doma**, this TypeScript/JavaScript library dynamically generates SQL. It embeds entity objects into SQL templates, simplifying complex query construction and enhancing readability. Ideal for flexible, type-safe SQL generation without a full ORM. It efficiently handles dynamic `WHERE` clauses, parameter binding, and looping, reducing boilerplate code.
6
6
 
7
7
  The core mechanism involves parsing special SQL comments (`/*IF ...*/`, `/*BEGIN...*/`, etc.) in a template and generating a final query based on a provided data object.
8
8
 
9
- ### Features
9
+ ### ⚠️ Breaking Change in IN Clause Behavior (v1 → v2)
10
+
11
+ **v2.0.0 introduces a breaking change in how arrays are rendered for `IN` clauses.**
12
+
13
+ - **v1.x behavior:** The bind array was automatically output with surrounding parentheses, so the template **did not need to include parentheses**.
14
+ - **v2.x behavior:** Only the array values are output. You must **include parentheses in the template** to form a valid `IN` clause.
15
+
16
+ **v1.x Example (no parentheses in template)**
17
+ ```sql
18
+ SELECT *
19
+ FROM activity
20
+ WHERE project_name IN /*projectNames*/('project1')
21
+ ```
22
+
23
+ ```typescript
24
+ const bindEntity = { projectNames: ['api', 'batch'] };
25
+ const sql = builder.generateSQL(template, bindEntity);
26
+ console.log(sql);
27
+
28
+ // Output (v1.x)
29
+ // project_name IN ('api','batch') ← parentheses added automatically
30
+ ```
31
+
32
+ **v2.x Example (parentheses required in template)**
33
+ ```sql
34
+ SELECT *
35
+ FROM activity
36
+ WHERE project_name IN (/*projectNames*/'project1')
37
+ ```
38
+
39
+ ```typescript
40
+ const bindEntity = { projectNames: ['api', 'batch'] };
41
+ const sql = builder.generateSQL(template, bindEntity);
42
+ console.log(sql);
43
+
44
+ // Output (v2.x)
45
+ // project_name IN ('api','batch') ← only values are inserted
46
+ ```
47
+
48
+ > 💡 Tip: If you upgrade a template from v1.x to v2.x, make sure to add parentheses around any IN bind variables to avoid SQL syntax errors.
49
+
50
+ #### ✨ Features
10
51
 
11
52
  * Dynamic Query Generation: Build complex SQL queries dynamically at runtime.
12
- * Conditional Logic (`/*IF...*/`): Automatically include or exclude SQL fragments based on JavaScript conditions evaluated against your data.
53
+ * Conditional Logic (`/*IF...*/`, `/*ELSEIF...*/`, `/*ELSE...*/`): Robust conditional branching. Support for complex `if-elseif-else` structures, including nesting.
13
54
  * Optional Blocks (`/*BEGIN...*/`): Wrap entire clauses (like `WHERE`) that are only included if at least one inner `/*IF...*/` condition is met.
14
55
  * Looping (`/*FOR...*/`): Generate repetitive SQL snippets by iterating over arrays in your data (e.g., for multiple `LIKE` or `OR` conditions).
15
56
  * Simple Parameter Binding: Easily bind values from your data object into the SQL query.
16
57
  * Zero Dependencies: A single, lightweight class with no external library requirements.
17
58
 
18
- ### ✅ Compatibility
59
+ #### ✅ Compatibility
19
60
 
20
61
  This library is written in pure, environment-agnostic JavaScript/TypeScript and has zero external dependencies, allowing it to run in various environments.
21
62
 
22
63
  - ✅ **Node.js**: Designed and optimized for server-side use in any modern Node.js environment. This is the **primary and recommended** use case.
23
64
  - ⚠️ **Browser-like Environments (Advanced)**: While technically capable of running in browsers (e.g., for use with in-browser databases like SQLite via WebAssembly), generating SQL on the client-side to be sent to a server **is a significant security risk and is strongly discouraged** in typical web applications.
24
65
 
25
- ### 📦 Instllation
66
+ #### 📦 Installation
26
67
 
27
68
  ```bash
28
69
  npm install @digitalwalletcorp/sql-builder
@@ -48,8 +89,8 @@ SELECT
48
89
  FROM activity
49
90
  /*BEGIN*/WHERE
50
91
  1 = 1
51
- /*IF projectNames != null && projectNames.length*/AND project_name IN /*projectNames*/('project1')/*END*/
52
- /*IF statuses != null && statuses.length*/AND status IN /*statuses*/(1)/*END*/
92
+ /*IF projectNames != null && projectNames.length*/AND project_name IN (/*projectNames*/'project1')/*END*/
93
+ /*IF statuses != null && statuses.length*/AND status IN (/*statuses*/1)/*END*/
53
94
  /*END*/
54
95
  ORDER BY started_at DESC
55
96
  LIMIT /*limit*/100
@@ -110,7 +151,75 @@ ORDER BY started_at DESC
110
151
  LIMIT 100
111
152
  ```
112
153
 
113
- ##### Example 2: FOR Loop
154
+ ##### Example 2: Dynamic WHERE Clause with `ELSEIF/ELSE`
155
+
156
+ **Template:**
157
+
158
+ ```sql
159
+ SELECT
160
+ *
161
+ FROM users
162
+ WHERE
163
+ 1 = 1
164
+ /*IF role === 'admin'*/
165
+ AND access_level = 99
166
+ /*ELSEIF role === 'editor'*/
167
+ AND access_level = 50
168
+ /*ELSE*/
169
+ AND access_level = 1
170
+ /*END*/
171
+ ```
172
+
173
+ **Code:**
174
+
175
+ ```typescript
176
+ import { SQLBuilder } from '@digitalwalletcorp/sql-builder';
177
+
178
+ const builder = new SQLBuilder();
179
+
180
+ const template = `...`; // The SQL template from above
181
+
182
+ const bindEntity1 = {
183
+ role: 'editor'
184
+ };
185
+
186
+ // SCENARIO A: Matched with ELSEIF condition
187
+ const sql = builder.generateSQL(template, bindEntity1);
188
+ console.log(sql1);
189
+
190
+ // SCENARIO B: Matched with ELSE condition
191
+ const bindEntity2 = {
192
+ role: 'read'
193
+ };
194
+ const sql2 = builder.generateSQL(template, bindEntity2);
195
+ console.log(sql2);
196
+ ```
197
+
198
+ **Resulting SQL:**
199
+
200
+ * SQL 1 (Scenario A)
201
+
202
+ ```sql
203
+ SELECT
204
+ *
205
+ FROM users
206
+ WHERE
207
+ 1 = 1
208
+ AND access_level = 50
209
+ ```
210
+
211
+ * SQL 2 (Scenario B)
212
+
213
+ ```sql
214
+ SELECT
215
+ *
216
+ FROM users
217
+ WHERE
218
+ 1 = 1
219
+ AND access_level = 1
220
+ ```
221
+
222
+ ##### Example 3: FOR Loop
114
223
 
115
224
  Use a `/*FOR...*/` block to iterate over an array and generate SQL for each item. This is useful for building multiple `LIKE` conditions.
116
225
 
@@ -190,7 +299,8 @@ If you need to use database-specific features, use `generateParameterizedSQL` wi
190
299
 
191
300
  ##### `generateParameterizedSQL(template: string, entity: Record<string, any>, bindType?: 'postgres' | 'mysql' | 'oracle' | 'mssql'): [string, Array<any> | Record<string, any>]`
192
301
 
193
- Generates a SQL string with placeholders for prepared statements and returns an array of bind parameters. This method is crucial for preventing SQL injection.
302
+ Generates a SQL string with placeholders for prepared statements and returns bind parameters.
303
+ This method prevents SQL injection for value bindings by using parameterized queries.
194
304
 
195
305
  * `template`: The SQL template string containing S2Dao-style comments.
196
306
  * `entity`: A data object whose properties are used for evaluating conditions (`/*IF...*/`) and binding values.
@@ -200,7 +310,7 @@ Generates a SQL string with placeholders for prepared statements and returns an
200
310
  * `sql`: The generated SQL query with appropriate placeholders.
201
311
  * `bindParams`: An array of values (for PostgreSQL/MySQL) or an object of named values (for Oracle/SQL Server) to bind to the placeholders.
202
312
 
203
- ##### Example 3: Parameterized SQL with PostgreSQL
313
+ ##### Example 4: Parameterized SQL with PostgreSQL
204
314
 
205
315
  **Template:**
206
316
 
@@ -212,7 +322,7 @@ FROM users
212
322
  /*BEGIN*/WHERE
213
323
  1 = 1
214
324
  /*IF userId != null*/AND user_id = /*userId*/0/*END*/
215
- /*IF projectNames.length*/AND project_name IN /*projectNames*/('default_project')/*END*/
325
+ /*IF projectNames.length*/AND project_name IN (/*projectNames*/'default_project')/*END*/
216
326
  /*END*/
217
327
  ```
218
328
 
@@ -236,7 +346,7 @@ console.log('Parameters:', params);
236
346
 
237
347
  **Resulting SQL & Parameters:**
238
348
 
239
- ```
349
+ ```sql
240
350
  SQL:
241
351
  SELECT
242
352
  id,
@@ -251,31 +361,7 @@ Parameters:
251
361
  [ 123, 'project_a', 'project_b' ]
252
362
  ```
253
363
 
254
- ###### ⚠️ PostgreSQL-specific notes
255
-
256
- When using PostgreSQL-specific features such as `ANY` with array parameters,
257
- the SQL template must be written in a form that is valid PostgreSQL SQL by itself.
258
-
259
- For example, to use `ANY` with a text array, write the array literal directly in the template.
260
- The builder will replace the **entire array literal** with a single bind placeholder:
261
-
262
- ```sql
263
- AND user_id = ANY (/*userIds*/ARRAY['U100','U101']::text[])
264
- ```
265
-
266
- This will be rendered as:
267
-
268
- ```sql
269
- AND user_id = ANY ($1::text[])
270
- ```
271
-
272
- with the following bind parameters:
273
-
274
- ```typescript
275
- [ ['U100', 'U101'] ]
276
- ```
277
-
278
- ##### Example 4: INSERT with NULL normalization
364
+ ##### Example 5: INSERT with NULL normalization
279
365
 
280
366
  **Template:**
281
367
 
@@ -328,7 +414,7 @@ console.log('Parameters2:', params2);
328
414
 
329
415
  **Result:**
330
416
 
331
- ```text
417
+ ```sql
332
418
  SQL1:
333
419
  INSERT INTO users (
334
420
  user_id,
@@ -361,10 +447,8 @@ Parameters2:
361
447
 
362
448
  **Notes:**
363
449
 
364
- - For both `generateSQL` and `generateParameterizedSQL`,
365
- `undefined` and `null` values are normalized to SQL `NULL`.
366
- - This behavior is especially important for INSERT / UPDATE statements,
367
- where the number of columns and values must always match.
450
+ - For both `generateSQL` and `generateParameterizedSQL`, `undefined` and `null` values are normalized to SQL `NULL`.
451
+ - This behavior is especially important for INSERT / UPDATE statements, where the number of columns and values must always match.
368
452
  - NOT NULL constraint violations are intentionally left to the database.
369
453
  - If you need to handle `IS NULL` conditions explicitly, you can use `/*IF */` blocks as shown below:
370
454
 
@@ -385,9 +469,11 @@ WHERE
385
469
  | Tag | Syntax | Description |
386
470
  | --- | --- | --- |
387
471
  | IF | `/*IF condition*/ ... /*END*/` | Includes the enclosed SQL fragment only if the `condition` evaluates to a truthy value. The condition is a JavaScript expression evaluated against the `entity` object. |
388
- | BEGIN | `/*BEGIN*/ ... /*END*/` | A wrapper block, typically for a `WHERE` clause. The entire block is included only if at least one `/*IF...*/` statement inside it is evaluated as true. This intelligently removes the `WHERE` keyword if no filters apply. |
472
+ | ELSEIF | `/*ELSEIF condition*/ ...` | Evaluates only if the preceding `IF` or `ELSEIF` was false. Must be placed inside an `IF` block. |
473
+ | ELSE | `/*ELSE*/ ...` | Included if all preceding `IF` and `ELSEIF` conditions in the block were false. |
474
+ | BEGIN | `/*BEGIN*/ ... /*END*/` | A wrapper block, typically for a `WHERE` clause. The entire block is included only if at least one inner `IF/ELSEIF/ELSE` or `FOR` block is active. This intelligently removes the `WHERE` keyword if no filters apply. |
389
475
  | FOR | `/*FOR item:collection*/ ... /*END*/` | Iterates over the `collection` array from the `entity`. For each loop, the enclosed SQL is generated, and the current value is available as the `item` variable for binding. |
390
- | Bind Variable | `/*variable*/` | Binds a value from the `entity`. It automatically formats values: strings are quoted (`'value'`), numbers are left as is (`123`), and arrays are turned into comma-separated lists in parentheses (`('a','b',123)`). |
476
+ | Bind Variable | `/*variable*/` | Binds a value from the `entity`. Strings are quoted `'value'`, numbers are rendered as-is `123`. When the value is an array, elements are expanded into a comma-separated list. The template may contain zero or one dummy expression after a bind tag. If present, only a single SQL expression is allowed. Multiple comma-separated dummy values are not supported. |
391
477
  | END | `/*END*/` | Marks the end of an `IF`, `BEGIN`, or `FOR` block. |
392
478
 
393
479
  ---
@@ -433,16 +519,105 @@ The `condition` inside an `/*IF ...*/` tag is evaluated as a JavaScript expressi
433
519
 
434
520
  ---
435
521
 
436
- ### 📜 License
522
+ #### Vendor Dependency TIPS
437
523
 
438
- This project is licensed under the MIT License. See the [LICENSE](https://opensource.org/licenses/MIT) file for details.
524
+ **PostgreSQL**
439
525
 
440
- ### 🎓 Advanced Usage & Examples
526
+ When using PostgreSQL-specific features such as `ANY` with array parameters,
527
+ the SQL template must be written in a form that is valid PostgreSQL SQL by itself.
528
+
529
+ For example, to use `ANY` with a text array, write the array literal directly in the template.
530
+ The builder will replace the **entire array literal** with a single bind placeholder:
441
531
 
442
- This README covers the basic usage of the library. For more advanced use cases and a comprehensive look at how to verify its behavior, the test suite serves as practical and up-to-date documentation.
532
+ ```sql
533
+ AND user_id = ANY (/*userIds*/ARRAY['U100','U101']::text[])
534
+ ```
443
535
 
444
- We recommend Browse the test files to understand how to handle and verify the sequential, race-condition-free execution in various scenarios.
536
+ This will be rendered as:
445
537
 
446
- You can find the test case in the `/test/specs` directory of our GitHub repository.
538
+ ```sql
539
+ AND user_id = ANY ($1::text[])
540
+ ```
541
+
542
+ with the following bind parameters:
543
+
544
+ ```typescript
545
+ [ ['U100', 'U101'] ]
546
+ ```
447
547
 
448
- - **[Explore our Test Suite for Advanced Examples](https://github.com/digitalwalletcorp/sql-builder/tree/main/test/specs)**
548
+ **MSSQL**
549
+
550
+ When working with a large number of values for an IN condition in SQL Server, directly expanding them into:
551
+
552
+ ```sql
553
+ WHERE UserID IN (1, 2, 3, ..., N)
554
+ ```
555
+
556
+ may lead to:
557
+
558
+ * **No Parameter Limits:** Counts as only 1 parameter regardless of array size.
559
+ * **Better Performance:** Avoids the overhead of parsing thousands of individual parameters.
560
+ * **Type Safety:** `OPENJSON` allows explicit type mapping (e.g., `INT`, `UNIQUEIDENTIFIER`).
561
+
562
+ SQL Server has a maximum limit of 2,100 parameters per RPC request. When using large IN (...) clauses via drivers like `Tedious`, each item in the list is typically treated as a separate parameter.
563
+
564
+ **Template:**
565
+
566
+ ```sql
567
+ DECLARE @jsonUserIds NVARCHAR(MAX) = N'[/*userIds*/100]';
568
+
569
+ WITH T AS (
570
+ SELECT value AS UserID
571
+ FROM OPENJSON(@jsonUserIds)
572
+ )
573
+ SELECT
574
+ U.UserID,
575
+ U.Status,
576
+ U.CreatedAt,
577
+ U.UpdatedAt
578
+ FROM Users U
579
+ JOIN T
580
+ ON U.UserID = T.UserID
581
+ ```
582
+
583
+ **Code:**
584
+
585
+ ```typescript
586
+ const template = '...'; // above SQL
587
+ const builder = new SQLBuilder();
588
+ const [sql, params] = builder.generateParameterizedSQL(template, { userIds: [100, 101, 102, 103] }, 'mssql');
589
+ console.log(sql, params);
590
+ ```
591
+
592
+ **Result:**
593
+
594
+ ```sql
595
+ SQL:
596
+ DECLARE @jsonUserIds NVARCHAR(MAX) = @userIds;
597
+
598
+ WITH T AS (
599
+ SELECT value AS UserID
600
+ FROM OPENJSON(@jsonUserIds)
601
+ )
602
+ SELECT
603
+ U.UserID,
604
+ U.Status,
605
+ U.CreatedAt,
606
+ U.UpdatedAt
607
+ FROM Users U
608
+ JOIN T
609
+ ON U.UserID = T.UserID
610
+
611
+ Parameters:
612
+ {
613
+ userIds: '[100,101,102,103]'
614
+ }
615
+ ```
616
+
617
+ By passing the array as a single JSON parameter and expanding it with OPENJSON, you can avoid large IN (...) lists and handle arbitrarily large collections in a clean and scalable way.
618
+
619
+ ---
620
+
621
+ #### 📜 License
622
+
623
+ This project is licensed under the MIT License. See the [LICENSE](https://opensource.org/licenses/MIT) file for details.
@@ -31,7 +31,7 @@ export declare class AbstractSyntaxTree {
31
31
  /**
32
32
  * 与えられた条件文字列を構文解析し、entityに対する条件として成立するか評価する
33
33
  *
34
- * @param {string} condition "params != null && params.length > 10" のような条件
34
+ * @param {string} condition 'params != null && params.length > 10' のような条件
35
35
  * @param {Record<string, any>} entity
36
36
  * @returns {boolean}
37
37
  */
@@ -57,7 +57,7 @@ class AbstractSyntaxTree {
57
57
  /**
58
58
  * 与えられた条件文字列を構文解析し、entityに対する条件として成立するか評価する
59
59
  *
60
- * @param {string} condition "params != null && params.length > 10" のような条件
60
+ * @param {string} condition 'params != null && params.length > 10' のような条件
61
61
  * @param {Record<string, any>} entity
62
62
  * @returns {boolean}
63
63
  */
@@ -69,9 +69,8 @@ class AbstractSyntaxTree {
69
69
  return result;
70
70
  }
71
71
  catch (error) {
72
- error.condition = condition;
73
- error.entity = entity;
74
- throw error;
72
+ const enhancedMessage = `[SQLBuilder] Failed to evaluate IF condition: '/*IF ${condition}*/'. ${error.message}`;
73
+ throw new Error(enhancedMessage);
75
74
  }
76
75
  }
77
76
  /**
@@ -252,7 +251,8 @@ class AbstractSyntaxTree {
252
251
  output.push(op);
253
252
  }
254
253
  if (!foundLeftParen) {
255
- throw new Error('[SQLBuilder.AbstractSyntaxTree] Mismatched parentheses');
254
+ throw new Error(`[SQLBuilder.AST] Mismatched parentheses: Found closing ')' without a matching '('. Check your IF condition syntax.`);
255
+ ;
256
256
  }
257
257
  }
258
258
  break;
@@ -262,7 +262,7 @@ class AbstractSyntaxTree {
262
262
  while (operatorStack.length) {
263
263
  const op = operatorStack.pop();
264
264
  if (op.value === '(' || op.value === ')') {
265
- throw new Error('[SQLBuilder.AbstractSyntaxTree] Mismatched parentheses');
265
+ throw new Error(`[SQLBuilder.AST] Mismatched parentheses: An extra '${op.value}' was found or a matching '(' is missing.`);
266
266
  }
267
267
  output.push(op);
268
268
  }
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-syntax-tree.js","sourceRoot":"","sources":["../src/abstract-syntax-tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"abstract-syntax-tree.js","sourceRoot":"","sources":["../src/abstract-syntax-tree.ts"],"names":[],"mappings":"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"}
package/lib/common.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ type PropertyResult = {
2
+ exists: boolean;
3
+ value: any;
4
+ };
1
5
  /**
2
6
  * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
3
7
  *
@@ -6,3 +10,20 @@
6
10
  * @returns {any}
7
11
  */
8
12
  export declare function getProperty(entity: Record<string, any>, property: string): any;
13
+ /**
14
+ * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値が存在するかチェックする
15
+ *
16
+ * @param {Record<string, any>} entity
17
+ * @param {string} property
18
+ * @returns {boolean}
19
+ */
20
+ export declare function hasProperty(entity: Record<string, any>, property: string): boolean;
21
+ /**
22
+ * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
23
+ *
24
+ * @param {Record<string, any>} entity
25
+ * @param {string} property
26
+ * @returns {PropertyResult}
27
+ */
28
+ export declare function getPropertyResult(entity: Record<string, any>, property: string): PropertyResult;
29
+ export {};
package/lib/common.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getProperty = getProperty;
4
+ exports.hasProperty = hasProperty;
5
+ exports.getPropertyResult = getPropertyResult;
4
6
  /**
5
7
  * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
6
8
  *
@@ -9,16 +11,42 @@ exports.getProperty = getProperty;
9
11
  * @returns {any}
10
12
  */
11
13
  function getProperty(entity, property) {
14
+ return getPropertyResult(entity, property).value;
15
+ }
16
+ /**
17
+ * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値が存在するかチェックする
18
+ *
19
+ * @param {Record<string, any>} entity
20
+ * @param {string} property
21
+ * @returns {boolean}
22
+ */
23
+ function hasProperty(entity, property) {
24
+ return getPropertyResult(entity, property).exists;
25
+ }
26
+ /**
27
+ * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
28
+ *
29
+ * @param {Record<string, any>} entity
30
+ * @param {string} property
31
+ * @returns {PropertyResult}
32
+ */
33
+ function getPropertyResult(entity, property) {
12
34
  // `?.` または `.` でパスを分割
13
35
  const propertyPath = property.split(/(\?\.)|\./).filter(Boolean);
14
36
  // 再帰呼び出し用のヘルパー関数
15
37
  const get = (obj, keys) => {
16
38
  if (keys.length === 0) {
17
- return obj;
39
+ return {
40
+ exists: true,
41
+ value: obj
42
+ };
18
43
  }
19
44
  // オプショナルチェイニングのチェック
20
45
  if (obj == null) {
21
- return undefined;
46
+ return {
47
+ exists: false,
48
+ value: undefined
49
+ };
22
50
  }
23
51
  const currentKey = keys[0];
24
52
  const remainingKeys = keys.slice(1);
@@ -27,8 +55,11 @@ function getProperty(entity, property) {
27
55
  return get(obj, remainingKeys);
28
56
  }
29
57
  // プロパティが存在しない場合は undefined を返す
30
- if (!obj.hasOwnProperty(currentKey)) {
31
- return undefined;
58
+ if (!Object.prototype.hasOwnProperty.call(obj, currentKey)) {
59
+ return {
60
+ exists: false,
61
+ value: undefined
62
+ };
32
63
  }
33
64
  return get(obj[currentKey], remainingKeys);
34
65
  };
package/lib/common.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;AAOA,kCA4BC;AAnCD;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,MAA2B,EAAE,QAAgB;IACvE,sBAAsB;IACtB,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjE,iBAAiB;IACjB,MAAM,GAAG,GAAG,CAAC,GAAwB,EAAE,IAAc,EAAO,EAAE;QAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEpC,kBAAkB;QAClB,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACjC,CAAC;QACD,+BAA+B;QAC/B,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,OAAO,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;AAYA,kCAEC;AASD,kCAEC;AASD,8CAqCC;AAlED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,MAA2B,EAAE,QAAgB;IACvE,OAAO,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,MAA2B,EAAE,QAAgB;IACvE,OAAO,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,MAA2B,EAAE,QAAgB;IAC7E,sBAAsB;IACtB,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjE,iBAAiB;IACjB,MAAM,GAAG,GAAG,CAAC,GAAwB,EAAE,IAAc,EAAO,EAAE;QAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,GAAG;aACO,CAAC;QACtB,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE,SAAS;aACC,CAAC;QACtB,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEpC,kBAAkB;QAClB,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACjC,CAAC;QACD,+BAA+B;QAC/B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC;YAC3D,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE,SAAS;aACC,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,OAAO,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACnC,CAAC"}
@@ -90,7 +90,7 @@ export declare class SQLBuilder {
90
90
  * @param {SharedIndex} pos 現在処理している文字列の先頭インデックス
91
91
  * @param {string} template
92
92
  * @param {Record<string, any>} entity
93
- * @param {TagContext[]} tagContexts
93
+ * @param {(TagContext | ParentTagContext)[]} tagContexts
94
94
  * @param {*} [options]
95
95
  * ├ bindType BindType
96
96
  * ├ bindIndex number
@@ -98,6 +98,26 @@ export declare class SQLBuilder {
98
98
  * @returns {string}
99
99
  */
100
100
  private parse;
101
+ /**
102
+ * 指定したタグから親を遡り、指定したタグタイプのタグコンテキストを返す
103
+ * 見つからない場合はundefinedを返す
104
+ *
105
+ * @param {TagContext | ParentTagContext | null} tagContext
106
+ * @param {T} tagType
107
+ * @returns {(TagContext & { type: T }) | undefined}
108
+ */
109
+ private findParentTagContext;
110
+ /**
111
+ * 指定したタグの兄弟をたどり、指定したタグタイプのタグコンテキストを返す
112
+ * 見つからない場合はundefinedを返す
113
+ * ユースケースとしては、ELSEIF/ELSEから同じIFに属するENDを探す
114
+ *
115
+ * @param {TagContext} tagContext
116
+ * @param {TagType | TagType[]} tagType
117
+ * @param {'previous' | 'next'} direction
118
+ * @returns {TagContext | undefined}
119
+ */
120
+ private seekSiblingTagContext;
101
121
  /**
102
122
  * ダミーパラメータの終了インデックスを返す
103
123
  *