@things-factory/shell 10.1.7 → 10.1.16

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.
@@ -18,13 +18,43 @@ function applyDomainInheritanceFilter(qb, alias, domain, inherited = list_param_
18
18
  qb.andWhere(`${alias}.domain = :domain`, { domain: domain.id });
19
19
  }
20
20
  else if (inherited === list_param_js_1.InheritedValueType.Include) {
21
+ /*
22
+ * 이 가지만 `domain.id` 가 **반드시 있다**에 기대고 있다. 없으면 배열이 비고
23
+ * `IN (:...domains)` 가 무너진다. 지금 `domain.id` 가 빈 호출 경로는 없다.
24
+ */
21
25
  qb.andWhere(`${alias}.domain IN (:...domains)`, { domains: [domain.id, domain.parentId].filter(Boolean) });
22
26
  }
23
27
  else if (inherited === list_param_js_1.InheritedValueType.Only) {
24
- qb.andWhere(`${alias}.domain = :domain`, { domain: domain.parentId || 'Impossible' });
28
+ /*
29
+ * 부모가 없으면 물려받은 것도 없다 — **사실이지 오류가 아니다.** 빈 결과가 정답이다.
30
+ *
31
+ * 여기 `{ domain: domain.parentId || 'Impossible' }` 이 있었다. 「아무것도 안 맞는다」는
32
+ * 조건인데 그것을 **값**으로 적었고, 그 값이 uuid 칸의 타입 파서 앞에 섰다. sqlite 는 글자로
33
+ * 비교해 **우연히 의도한 답**을 주고(그래서 2023-06-03 부터 개발 내내 초록이었다), postgres 는
34
+ * 질의를 통째로 거절한다 — `invalid input syntax for type uuid: "Impossible"` (2026-09-15 관측).
35
+ *
36
+ * 값을 바인딩하지 않는다. 조건을 그대로 적는다. `1 = 0` 은 지원 DB 5종에서 다 유효하고
37
+ * 타입 파서를 안 탄다. (`FALSE` 리터럴은 방언이 갈린다 — 쓰지 않는다.)
38
+ */
39
+ if (!domain.parentId) {
40
+ qb.andWhere('1 = 0');
41
+ return;
42
+ }
43
+ qb.andWhere(`${alias}.domain = :domain`, { domain: domain.parentId });
25
44
  }
26
45
  else {
27
- qb.andWhere(`${alias}.domain = :domain`, { domain: 'Impossible' });
46
+ /*
47
+ * 여기는 **고장**이다. 유효한 값 셋 중 어느 것도 아니다.
48
+ *
49
+ * 빈 결과로 돌려주지 않는다. 받는 쪽은 그것을 「해당하는 게 없구나」로 읽고, 오타 난 필터 값이
50
+ * 조용한 0건이 된다. 그리고 이것은 **테넌트 격리 필터**다 — 여기서 고장이 조용하면 다음 사람이
51
+ * 이 가지를 「비는 것이 정상」으로 보고 그 위에 무언가를 얹는다.
52
+ *
53
+ * 로그만 찍고 None 으로 떨어뜨리는 것도 안 된다. 격리 필터가 **넓은 쪽으로 떨어지는 것**이
54
+ * 이 파일이 막는 유일한 사고다.
55
+ */
56
+ throw new Error(`applyDomainInheritanceFilter: unknown inherited value ${JSON.stringify(inherited)}. ` +
57
+ `The values are ${Object.values(list_param_js_1.InheritedValueType).join(', ')}.`);
28
58
  }
29
59
  }
30
60
  //# sourceMappingURL=apply-domain-filter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apply-domain-filter.js","sourceRoot":"","sources":["../../server/utils/apply-domain-filter.ts"],"names":[],"mappings":";;AAeA,oEAeC;AA5BD,yEAA0E;AAE1E;;;;;;;;;;GAUG;AACH,SAAgB,4BAA4B,CAC1C,EAA0B,EAC1B,KAAa,EACb,MAAgD,EAChD,YAAgC,kCAAkB,CAAC,IAAI;IAEvD,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,kCAAkB,CAAC,IAAI,EAAE,CAAC;QACxD,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IACjE,CAAC;SAAM,IAAI,SAAS,KAAK,kCAAkB,CAAC,OAAO,EAAE,CAAC;QACpD,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,0BAA0B,EAAE,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC5G,CAAC;SAAM,IAAI,SAAS,KAAK,kCAAkB,CAAC,IAAI,EAAE,CAAC;QACjD,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,IAAI,YAAY,EAAE,CAAC,CAAA;IACvF,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,mBAAmB,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAA;IACpE,CAAC;AACH,CAAC","sourcesContent":["import { WhereExpressionBuilder } from 'typeorm'\n\nimport { InheritedValueType } from '../service/common-types/list-param.js'\n\n/**\n * 멀티테넌트 도메인 상속 필터를 쿼리에 적용한다.\n *\n * `getQueryBuilderFromListParams` 와 (deprecated) `buildQuery` 양쪽에 동일하게 중복돼 있던\n * 도메인 필터 로직의 단일 소스. 도메인 필터는 테넌트 격리(보안)에 직결되므로 한 곳에서만 정의한다.\n *\n * @param qb 조건을 추가할 대상(WhereExpressionBuilder / SelectQueryBuilder)\n * @param alias 엔티티 alias\n * @param domain 현재 도메인 (id, parentId)\n * @param inherited 상속 방식: None(자기 도메인) / Include(자기+부모) / Only(부모만)\n */\nexport function applyDomainInheritanceFilter(\n qb: WhereExpressionBuilder,\n alias: string,\n domain: { id: string; parentId?: string | null },\n inherited: InheritedValueType = InheritedValueType.None\n): void {\n if (!inherited || inherited === InheritedValueType.None) {\n qb.andWhere(`${alias}.domain = :domain`, { domain: domain.id })\n } else if (inherited === InheritedValueType.Include) {\n qb.andWhere(`${alias}.domain IN (:...domains)`, { domains: [domain.id, domain.parentId].filter(Boolean) })\n } else if (inherited === InheritedValueType.Only) {\n qb.andWhere(`${alias}.domain = :domain`, { domain: domain.parentId || 'Impossible' })\n } else {\n qb.andWhere(`${alias}.domain = :domain`, { domain: 'Impossible' })\n }\n}\n"]}
1
+ {"version":3,"file":"apply-domain-filter.js","sourceRoot":"","sources":["../../server/utils/apply-domain-filter.ts"],"names":[],"mappings":";;AAeA,oEAgDC;AA7DD,yEAA0E;AAE1E;;;;;;;;;;GAUG;AACH,SAAgB,4BAA4B,CAC1C,EAA0B,EAC1B,KAAa,EACb,MAAgD,EAChD,YAAgC,kCAAkB,CAAC,IAAI;IAEvD,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,kCAAkB,CAAC,IAAI,EAAE,CAAC;QACxD,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IACjE,CAAC;SAAM,IAAI,SAAS,KAAK,kCAAkB,CAAC,OAAO,EAAE,CAAC;QACpD;;;WAGG;QACH,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,0BAA0B,EAAE,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC5G,CAAC;SAAM,IAAI,SAAS,KAAK,kCAAkB,CAAC,IAAI,EAAE,CAAC;QACjD;;;;;;;;;;WAUG;QACH,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QAED,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IACvE,CAAC;SAAM,CAAC;QACN;;;;;;;;;WASG;QACH,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI;YACpF,kBAAkB,MAAM,CAAC,MAAM,CAAC,kCAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACpE,CAAA;IACH,CAAC;AACH,CAAC","sourcesContent":["import { WhereExpressionBuilder } from 'typeorm'\n\nimport { InheritedValueType } from '../service/common-types/list-param.js'\n\n/**\n * 멀티테넌트 도메인 상속 필터를 쿼리에 적용한다.\n *\n * `getQueryBuilderFromListParams` 와 (deprecated) `buildQuery` 양쪽에 동일하게 중복돼 있던\n * 도메인 필터 로직의 단일 소스. 도메인 필터는 테넌트 격리(보안)에 직결되므로 한 곳에서만 정의한다.\n *\n * @param qb 조건을 추가할 대상(WhereExpressionBuilder / SelectQueryBuilder)\n * @param alias 엔티티 alias\n * @param domain 현재 도메인 (id, parentId)\n * @param inherited 상속 방식: None(자기 도메인) / Include(자기+부모) / Only(부모만)\n */\nexport function applyDomainInheritanceFilter(\n qb: WhereExpressionBuilder,\n alias: string,\n domain: { id: string; parentId?: string | null },\n inherited: InheritedValueType = InheritedValueType.None\n): void {\n if (!inherited || inherited === InheritedValueType.None) {\n qb.andWhere(`${alias}.domain = :domain`, { domain: domain.id })\n } else if (inherited === InheritedValueType.Include) {\n /*\n * 이 가지만 `domain.id` 가 **반드시 있다**에 기대고 있다. 없으면 배열이 비고\n * `IN (:...domains)` 가 무너진다. 지금 `domain.id` 가 빈 호출 경로는 없다.\n */\n qb.andWhere(`${alias}.domain IN (:...domains)`, { domains: [domain.id, domain.parentId].filter(Boolean) })\n } else if (inherited === InheritedValueType.Only) {\n /*\n * 부모가 없으면 물려받은 것도 없다 — **사실이지 오류가 아니다.** 빈 결과가 정답이다.\n *\n * 여기 `{ domain: domain.parentId || 'Impossible' }` 이 있었다. 「아무것도 안 맞는다」는\n * 조건인데 그것을 **값**으로 적었고, 그 값이 uuid 칸의 타입 파서 앞에 섰다. sqlite 는 글자로\n * 비교해 **우연히 의도한 답**을 주고(그래서 2023-06-03 부터 개발 내내 초록이었다), postgres 는\n * 질의를 통째로 거절한다 — `invalid input syntax for type uuid: \"Impossible\"` (2026-09-15 관측).\n *\n * 값을 바인딩하지 않는다. 조건을 그대로 적는다. `1 = 0` 은 지원 DB 5종에서 다 유효하고\n * 타입 파서를 안 탄다. (`FALSE` 리터럴은 방언이 갈린다 — 쓰지 않는다.)\n */\n if (!domain.parentId) {\n qb.andWhere('1 = 0')\n return\n }\n\n qb.andWhere(`${alias}.domain = :domain`, { domain: domain.parentId })\n } else {\n /*\n * 여기는 **고장**이다. 유효한 값 셋 중 어느 것도 아니다.\n *\n * 빈 결과로 돌려주지 않는다. 받는 쪽은 그것을 「해당하는 게 없구나」로 읽고, 오타 난 필터 값이\n * 조용한 0건이 된다. 그리고 이것은 **테넌트 격리 필터**다 — 여기서 고장이 조용하면 다음 사람이\n * 이 가지를 「비는 것이 정상」으로 보고 그 위에 무언가를 얹는다.\n *\n * 로그만 찍고 None 으로 떨어뜨리는 것도 안 된다. 격리 필터가 **넓은 쪽으로 떨어지는 것**이\n * 이 파일이 막는 유일한 사고다.\n */\n throw new Error(\n `applyDomainInheritanceFilter: unknown inherited value ${JSON.stringify(inherited)}. ` +\n `The values are ${Object.values(InheritedValueType).join(', ')}.`\n )\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/shell",
3
- "version": "10.1.7",
3
+ "version": "10.1.16",
4
4
  "description": "Core module for framework",
5
5
  "bin": {
6
6
  "things-factory": "bin/things-factory",
@@ -126,5 +126,5 @@
126
126
  "pg": "^8.7.3",
127
127
  "sqlite3": "^5.0.8"
128
128
  },
129
- "gitHead": "9a036f83f5751f9e4af9180e9a0018f716a4ba27"
129
+ "gitHead": "aff86bc162b42c1d933711f7bc85a073f1ddcd29"
130
130
  }