@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalwalletcorp/sql-builder",
3
- "version": "1.6.1",
3
+ "version": "2.1.0",
4
4
  "description": "This is a library for building SQL",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -16,8 +16,13 @@
16
16
  },
17
17
  "keywords": [
18
18
  "sql",
19
+ "template",
20
+ "builder",
19
21
  "dynamic",
20
- "S2Dao"
22
+ "parameterized",
23
+ "placeholder",
24
+ "S2Dao",
25
+ "Doma"
21
26
  ],
22
27
  "author": "satoshi kotaki",
23
28
  "license": "MIT",
@@ -39,7 +39,7 @@ export class AbstractSyntaxTree {
39
39
  /**
40
40
  * 与えられた条件文字列を構文解析し、entityに対する条件として成立するか評価する
41
41
  *
42
- * @param {string} condition "params != null && params.length > 10" のような条件
42
+ * @param {string} condition 'params != null && params.length > 10' のような条件
43
43
  * @param {Record<string, any>} entity
44
44
  * @returns {boolean}
45
45
  */
@@ -50,9 +50,8 @@ export class AbstractSyntaxTree {
50
50
  const result = this.evaluateRpn(rpnTokens, entity);
51
51
  return result;
52
52
  } catch (error: any) {
53
- error.condition = condition;
54
- error.entity = entity;
55
- throw error;
53
+ const enhancedMessage = `[SQLBuilder] Failed to evaluate IF condition: '/*IF ${condition}*/'. ${error.message}`;
54
+ throw new Error(enhancedMessage);
56
55
  }
57
56
  }
58
57
 
@@ -239,7 +238,7 @@ export class AbstractSyntaxTree {
239
238
  output.push(op);
240
239
  }
241
240
  if (!foundLeftParen) {
242
- throw new Error('[SQLBuilder.AbstractSyntaxTree] Mismatched parentheses');
241
+ throw new Error(`[SQLBuilder.AST] Mismatched parentheses: Found closing ')' without a matching '('. Check your IF condition syntax.`);;
243
242
  }
244
243
  }
245
244
  break;
@@ -250,7 +249,7 @@ export class AbstractSyntaxTree {
250
249
  while (operatorStack.length) {
251
250
  const op = operatorStack.pop()!;
252
251
  if (op.value === '(' || op.value === ')') {
253
- throw new Error('[SQLBuilder.AbstractSyntaxTree] Mismatched parentheses');
252
+ throw new Error(`[SQLBuilder.AST] Mismatched parentheses: An extra '${op.value}' was found or a matching '(' is missing.`);
254
253
  }
255
254
  output.push(op);
256
255
  }
package/src/common.ts CHANGED
@@ -1,3 +1,8 @@
1
+ type PropertyResult = {
2
+ exists: boolean;
3
+ value: any;
4
+ }
5
+
1
6
  /**
2
7
  * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
3
8
  *
@@ -6,17 +11,45 @@
6
11
  * @returns {any}
7
12
  */
8
13
  export function getProperty(entity: Record<string, any>, property: string): any {
14
+ return getPropertyResult(entity, property).value;
15
+ }
16
+
17
+ /**
18
+ * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値が存在するかチェックする
19
+ *
20
+ * @param {Record<string, any>} entity
21
+ * @param {string} property
22
+ * @returns {boolean}
23
+ */
24
+ export function hasProperty(entity: Record<string, any>, property: string): boolean {
25
+ return getPropertyResult(entity, property).exists;
26
+ }
27
+
28
+ /**
29
+ * entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
30
+ *
31
+ * @param {Record<string, any>} entity
32
+ * @param {string} property
33
+ * @returns {PropertyResult}
34
+ */
35
+ export function getPropertyResult(entity: Record<string, any>, property: string): PropertyResult {
9
36
  // `?.` または `.` でパスを分割
10
37
  const propertyPath = property.split(/(\?\.)|\./).filter(Boolean);
11
38
 
12
39
  // 再帰呼び出し用のヘルパー関数
13
40
  const get = (obj: Record<string, any>, keys: string[]): any => {
14
41
  if (keys.length === 0) {
15
- return obj;
42
+ return {
43
+ exists: true,
44
+ value: obj
45
+ } as PropertyResult;
16
46
  }
17
47
  // オプショナルチェイニングのチェック
18
48
  if (obj == null) {
19
- return undefined;
49
+ return {
50
+ exists: false,
51
+ value: undefined
52
+ } as PropertyResult;
20
53
  }
21
54
 
22
55
  const currentKey = keys[0];
@@ -27,8 +60,11 @@ export function getProperty(entity: Record<string, any>, property: string): any
27
60
  return get(obj, remainingKeys);
28
61
  }
29
62
  // プロパティが存在しない場合は undefined を返す
30
- if (!obj.hasOwnProperty(currentKey)) {
31
- return undefined;
63
+ if (!Object.prototype.hasOwnProperty.call(obj, currentKey)) {
64
+ return {
65
+ exists: false,
66
+ value: undefined
67
+ } as PropertyResult;
32
68
  }
33
69
  return get(obj[currentKey], remainingKeys);
34
70
  };