@joymerrevent/porters-connect 0.19.0 → 0.20.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/CHANGELOG.md CHANGED
@@ -5,6 +5,134 @@
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.20.0] - 2026-09-21
9
+
10
+ **PORTERS ヘルプセンターを再取得して見つかった、追いついていなかった変更 2 つを埋めた版**です。
11
+ 破壊的変更はありません。
12
+
13
+ 2026-06 以来はじめて出典を取り直したところ、**Department - Read API**(2025/03・Connect API 8.2.1)が
14
+ reference にも実装にも無く、**時分型**(2026/08・PORTERS 9.3.0)はライブラリが型として知らない
15
+ 状態でした。前者はマスタ 5 種目として実装し、後者は型を増やさず変換関数で扱います([ADR-0086][adr86])。
16
+
17
+ ### Added
18
+
19
+ - **Department マスタの Read(`t.department`)**。ユーザー部署型(Link)項目や `User.P_Department` が
20
+ 指す部署を、Partition 単位で一覧できます([reference][ref-department])。
21
+
22
+ ```ts
23
+ const t = porters.tenant(123);
24
+ const page = await t.department.search(); // { total, count, start, items }
25
+ for await (const d of t.department.searchAll()) {
26
+ d.P_Id;
27
+ d.P_Name;
28
+ d.P_Hidden;
29
+ d.P_SortNo;
30
+ d.P_RegistrationDate;
31
+ d.P_UpdateDate;
32
+ }
33
+ ```
34
+
35
+ - **読み取り専用**。PORTERS に Write API はありません(お知らせ記事が「read のみ」と明記)。
36
+ - クエリは `field` / `count` / `start` だけ。`condition` / `get(id)` / `request_type` はありません
37
+ (出典が挙げないものは公開しない — 他のマスタと同じ)。
38
+ - **スコープは `user_r`** です。PORTERS は `department_r` を定義していません。
39
+ - `field` 省略時は 6 項目すべてを要求します(省略すると PORTERS は `P_Id` しか返さないため)。
40
+ Link 参照からは読めない `P_Hidden` / `P_SortNo` / 登録日 / 更新日も、ここでは読めます。
41
+ - 型は `Department` / `DepartmentPage` / `DepartmentSearchQuery` / `DepartmentResource` を公開します。
42
+
43
+ - **時分型(PORTERS 9.3.0)の項目を扱う変換関数 `decodeTimeOfDay` / `encodeTimeOfDay`**([ADR-0086][adr86])。
44
+ 時分型は時刻だけ(`00:00`〜`47:59`)を持つカスタム項目ですが、API 上は年月日時分型と同じ
45
+ `DateTime`(Field Type 12)で、`1970/01/01` を基準日にした日時として運ばれます(`26:00` は
46
+ `1970/01/02 02:00:00`)。Field Read からも区別できないため、ライブラリは**型を増やさず**、時分型の
47
+ 項目も `f.dateTime()` のまま宣言して ISO で読み書きします。基準日の規則は、その項目が時分型だと
48
+ 知っているところで変換関数に任せます。
49
+
50
+ ```ts
51
+ const job = await t.job.get(1);
52
+ const start =
53
+ job?.U_startTime == null ? null : decodeTimeOfDay(job.U_startTime); // "09:00"
54
+ await t.job.update(1, { U_startTime: encodeTimeOfDay("26:00") }); // → 1970/01/02 02:00:00
55
+ await t.job.search({
56
+ condition: { U_startTime: { ge: encodeTimeOfDay("15:00") } },
57
+ });
58
+ ```
59
+
60
+ - `encodeTimeOfDay` は `"HH:mm"` / `"HH:mm:ss"`(00:00〜47:59)以外を `PortersConfigError`
61
+ (`category: "validation"`)で**送る前に**止めます(PORTERS の Code 103 / Code 100 を手前で)。
62
+ - `decodeTimeOfDay` は基準日以外の ISO を同じエラーで止めます(その項目はたぶん時分型ではない、
63
+ というヒント付き)。秒が `00` でなければ `"HH:mm:ss"` で保持します。
64
+ - 既存の型・宣言・読み書きは変わりません。変換を呼ぶかどうかは利用者の責務です。
65
+
66
+ ### Changed
67
+
68
+ - **`generateFieldDecls` が Field Type 12 の行に注記を出すようになりました**
69
+ (`f.dateTime(), // FT-12: …`)。時分型は年月日時分型と同じ `12` で Field Read からは区別できないため、
70
+ 宣言が生まれる場所で「時刻だけの項目なら変換関数を」と伝えます。
71
+ - 開発用のフェイクサーバー(npm には同梱しません)に `departments` オプションと `/v1/department` を
72
+ 足しました。
73
+
74
+ ## [0.19.1] - 2026-09-20
75
+
76
+ **定期レビューで見つけた 7 件を塞いだ版**です。破壊的変更はありません。公開 API の形は変わらず、
77
+ **壊れたときの倒れ方**が変わります。
78
+
79
+ いちばん重いのは **Option の選択肢 alias から書き込み XML を注入できた**こと。PORTERS は Option の値を
80
+ **タグ名**として書くため(`<FieldAlias><OptionAlias/></FieldAlias>`)、その値を検証していないと
81
+ **呼び出し側が指定していないレコードが書き換わり**ます。要素名はエスケープできないので、検証して弾く形にしました
82
+ ([ADR-0085][adr85])。
83
+
84
+ ### Security
85
+
86
+ - **Option の選択肢 alias と書き込み項目 alias を、XML の名前として妥当か検証するようになりました**
87
+ ([ADR-0085][adr85])。公開型が `string[]` なので cast なしで到達でき、`<Item>` を閉じて開き直す文字列を
88
+ 渡すと **well-formed な XML に別レコードを名指す `<Item>` を注入**できていました(更新先が
89
+ すり替わる/頼んでいない項目が書き足される)。
90
+
91
+ ```ts
92
+ await t.candidate.update(10001, { P_Phase: [userInput] });
93
+ // 不正なら送信前に PortersConfigError(category: "validation")
94
+ ```
95
+
96
+ 通るのは **XML の `Name`**(英数字・`_`・`-`・`.`・日本語など。先頭に数字や `-` は置けません)。
97
+ 出典が alias の書式を定めていないので**XML が許すものはすべて許します** — `Option.P_東京` のような
98
+ alias も従来どおり書けます。**本文になる値(テキスト項目など)の扱いは変わりません。**
99
+
100
+ ### Fixed
101
+
102
+ - **`createThrottle` が実質 0 件の上限を受け付けて永久に待つのをやめました**。バケットのトークンは
103
+ `floor(上限 × safety)` 個で、既定 `safety` は 0.9。そのため `createThrottle({ readPerMin: 1 })` は
104
+ 容量 0 になり、**すべての呼び出しが返らなく**なっていました(例外もログも無し)。
105
+
106
+ ```ts
107
+ createThrottle({ readPerMin: 1 }); // PortersConfigError(floor(1 × 0.9) = 0)
108
+ createThrottle({ readPerMin: 2 }); // OK(floor(1.8) = 1)
109
+ ```
110
+
111
+ `readPerMin` / `writePerMin` は**正の整数**、`safety` は **0 より大きく 1 以下**。加えて
112
+ **積が 1 以上**であることを見ます。「1 件も通さない」は `take()` が解決しない `Throttle` を
113
+ 自分で渡してください。
114
+
115
+ - **XML の解析に失敗したとき、例外が必ず `PortersError` になるようになりました**。
116
+ `fast-xml-parser` は `prototype` / `constructor` / `__proto__` をタグ名として拒否します。
117
+ これらは妥当な XML Name なので書き込みは通り、**読み取りだけ**が素の `Error` で落ちていました
118
+ — `catch (e) { if (e instanceof PortersError) … }` に**引っかからず**、アプリの最上位まで
119
+ 素通りします。Read は `PortersResourceError`、認証は `PortersAuthError` に包み、パーサ自身の
120
+ 説明は `cause` に残します。壊れた XML も同じ経路になりました。
121
+
122
+ - **公開 API リファレンス**(`docs/usage/api/`)に残っていた日本語を英語に直しました。
123
+ 公開サーフェスの JSDoc は英語、README とガイドは日本語ファースト、という切り分けは変わりません。
124
+
125
+ ### Changed
126
+
127
+ - **CI が `engines` の下限そのものを走らせるようになりました**。`engines.node` は `>=22.12.0` を
128
+ 約束していますが、テストの Node マトリクスは `22`(その時点の 22 系最新に解決される)だったため、
129
+ **22.12.0 は一度も走っていません**でした。Node 22.12.0 で動かしている場合、そのバージョンが
130
+ 実際に検証されるようになります。
131
+
132
+ - 内部の検査を 2 本増やしました(利用者への影響はありません)。契約後に実機確認する仮定と
133
+ コード側のコメントの対応を双方向で見る検査と、リファレンスへの日本語混入を見る検査です。
134
+ 前者では**コードに仮定があるのに一覧に無いもの**が 3 件見つかり、起票しました。
135
+
8
136
  ## [0.19.0] - 2026-09-18
9
137
 
10
138
  **CJS からの入口を開け、Node の下限を 22.12 に上げた版**です。**破壊的変更を 1 つ**含みます
@@ -1062,11 +1190,14 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
1062
1190
  [adr82]: docs/adr/0082-module-format-and-node-baseline.md
1063
1191
  [limits]: docs/usage/concepts/limits.md
1064
1192
  [failures]: docs/usage/howto/handle-failures.md
1193
+ [adr85]: docs/adr/0085-option-alias-validation.md
1065
1194
  [lv]: docs/live-verification.md
1066
1195
  [ref]: docs/usage/reference/README.md
1067
1196
  [kac]: https://keepachangelog.com/en/1.1.0/
1068
1197
  [semver]: https://semver.org/
1069
- [unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.19.0...HEAD
1198
+ [unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.20.0...HEAD
1199
+ [0.20.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.19.1...v0.20.0
1200
+ [0.19.1]: https://github.com/Joymerrevent/porters-connect/compare/v0.19.0...v0.19.1
1070
1201
  [0.19.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.18.0...v0.19.0
1071
1202
  [0.18.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.17.0...v0.18.0
1072
1203
  [0.17.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.16.0...v0.17.0
@@ -1098,3 +1229,5 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
1098
1229
  [gh4]: https://github.com/advisories/GHSA-4mjr-xmp4-gh2g
1099
1230
  [gh5]: https://github.com/advisories/GHSA-7w5x-hrqm-74c2
1100
1231
  [fastcheck]: https://github.com/dubzzz/fast-check
1232
+ [adr86]: docs/adr/0086-time-of-day-fields.md
1233
+ [ref-department]: docs/usage/reference/resource-api/resources/department.md
package/README.md CHANGED
@@ -21,7 +21,7 @@ XML レスポンスを型付きオブジェクトに変換し、独自仕様の
21
21
  - **独自 OAuth を透過**:`code_direct` によるトークン取得・キャッシュ・更新を自動化。
22
22
  - **上限内に自制する**:スロットリング・リトライ(指数バックオフ)・リクエストサイズガード内蔵。
23
23
  - **日時は ISO 8601(UTC)に正規化**。業務タイムゾーン変換はしません(利用側の責務)。
24
- - **PORTERS の全リソースに対応**:データ系 13 種 + Phase + マスタ Read 4 種。
24
+ - **PORTERS の全リソースに対応**:データ系 13 種 + Phase + マスタ Read 5 種。
25
25
 
26
26
  ## 前提
27
27
 
@@ -87,7 +87,7 @@ console.log(page.total, page.items[0]?.P_Name);
87
87
  | `t.opportunity` | 商談管理 | `t.phase` | フェーズ履歴 |
88
88
  | `t.activity` | アクティビティ | | |
89
89
 
90
- マスタ Read は `porters.partition` / `t.user` / `t.field` / `t.option` の 4 種(読み取り専用)。
90
+ マスタ Read は `porters.partition` / `t.user` / `t.department` / `t.field` / `t.option` の 5 種(読み取り専用)。
91
91
 
92
92
  **どのメソッドが呼べるかはリソースごとに違います**(`searchAll` が無いもの、先に `of()` で
93
93
  束ねるものがあります)。一覧は[リソースと操作][docs-resources]、引数・戻り値・項目の一覧は