@joymerrevent/porters-connect 0.23.0 → 0.25.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 +140 -1
- package/README.md +51 -62
- package/dist/index.d.cts +58 -35
- package/dist/index.d.ts +58 -35
- package/dist/index.js +226 -138
- package/dist/index.js.map +1 -1
- package/dist/requires-newer-typescript.d.cts +1 -1
- package/dist/requires-newer-typescript.d.ts +1 -1
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,137 @@
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.25.0] - 2026-09-25
|
|
9
|
+
|
|
10
|
+
**設定の誤りを黙って通さないようにし、トークンを期限つきで取り出せるようにした版**です。**破壊的変更を 2 つ**含みます
|
|
11
|
+
(定義していないオプションの拒否と、`porters.auth.getToken()` の戻り値)。あわせて、トークンの保存と中央のサービスからの
|
|
12
|
+
受け取りの実践例を足し、README と目次を読みやすく直しました。
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **(破壊的)`new PortersClient(options)` と `porters.tenant(id, options)` は、定義していないオプションのキーを渡すと
|
|
17
|
+
`PortersConfigError`(`category: "config"`)になります**([ADR-0092][adr92])。これまでは打ち間違い(`hostName` など)や
|
|
18
|
+
存在しないオプションを黙って無視し、誤った設定のまま動いていました。
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
new PortersClient({ hostname, appId, appSecret, hostName: "x" });
|
|
22
|
+
// PortersConfigError: PortersClient: unknown option "hostName"
|
|
23
|
+
// hint: Valid options: hostname, port, scheme, appId, appSecret, scopes, tokenProvider, tokenStore, transport, throttle.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- 値が `undefined` のキーは未指定と同じ扱いです(設定をスプレッドで組み立てると混ざりやすいため)。
|
|
27
|
+
- **アプリの設定オブジェクトを丸ごと渡している場合は、使うキーだけを取り出して渡してください。**
|
|
28
|
+
- `tenant(id, options)` に渡せるのは `fields` だけです。
|
|
29
|
+
- `PortersClientOptions` の型から、使えない項目だった `auth` と `fields` を外しました。
|
|
30
|
+
|
|
31
|
+
- **(破壊的)`porters.auth.getToken()` は、Access Token の文字列ではなく `{ token, expiresAt? }`(`IssuedToken`)を
|
|
32
|
+
返すようになりました**([ADR-0093][adr93])。
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
// 変更前
|
|
36
|
+
const token = await porters.auth.getToken();
|
|
37
|
+
// 変更後
|
|
38
|
+
const { token, expiresAt } = await porters.auth.getToken();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- 返すのはリソースの呼び出しに使うのと同じトークンで、期限が近ければ取り直してから返します。`expiresAt` は
|
|
42
|
+
1970-01-01 からのミリ秒で、取り方が期限を返さなかったときは省かれます。
|
|
43
|
+
- 中央のサービスが各アプリの `tokenProvider` にトークンを渡すとき、期限もそのまま渡せます。アプリのクライアントは
|
|
44
|
+
期限切れで失敗する前に取り直せます。
|
|
45
|
+
- Refresh Token はこれまでどおり返しません。
|
|
46
|
+
|
|
47
|
+
- **使い方ドキュメントに実践例を 2 本足しました**:
|
|
48
|
+
[トークンを DB に保存する][recipe-token-store-db](`tokenStore` を Drizzle ORM と PostgreSQL で組む)と、
|
|
49
|
+
[中央のサービスからトークンを受け取る][recipe-central-token-service](App Secret を中央だけに置き、各アプリは
|
|
50
|
+
`tokenProvider` で受け取る)。
|
|
51
|
+
|
|
52
|
+
- **README と目次を見直しました**。README の「リソースと操作」の節を外して入口に絞り、見出し「最短で動かす」を
|
|
53
|
+
「クイックスタート」に、各章の説明を概要の要約にしました。使い方ドキュメントの章の名前を「主題別」から
|
|
54
|
+
「ガイド」に、「リソース別」から「リソース」に改めました(ページの場所は変わりません)。
|
|
55
|
+
`tokenProvider` に渡す関数が、取るのに要るもの(App Secret など)を自分で持つことも書き足しました。
|
|
56
|
+
|
|
57
|
+
- 内部の検査を変えました(利用者への影響はありません)。PR のミューテーションテストは変更したファイルだけに掛け、
|
|
58
|
+
`main` への PR は必ず全体を検査します。
|
|
59
|
+
|
|
60
|
+
## [0.24.0] - 2026-09-24
|
|
61
|
+
|
|
62
|
+
**トークンの取り方と置き場所を別々に渡せるようにした版**です。**破壊的変更を 2 つ**含みます
|
|
63
|
+
(構築オプション `auth` の廃止と、日時(`DateTime`)に渡す値の制限)。あわせて、Refresh Token が拒否されたときに
|
|
64
|
+
回復しなかった不具合を直し、使い方ドキュメントを実装と突き合わせて直しました。
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- **(破壊的)トークンの取り方を `tokenProvider` で、置き場所を `tokenStore` で別々に渡すようになりました**
|
|
69
|
+
([ADR-0091][adr91])。キャッシュ・期限の判断・失効時の取り直し・同時呼び出しの 1 本化・`tokenStore` への保存は、
|
|
70
|
+
既定の取り方でも、渡した取り方でもクライアントが受け持ちます。これまで取り方を差し替えるには
|
|
71
|
+
`getAccessToken` を丸ごと自前で書くしかなく、期限の判断や同時呼び出しのまとめ方まで利用者の実装に任されていました。
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// 変更前
|
|
75
|
+
const porters = new PortersClient({
|
|
76
|
+
hostname,
|
|
77
|
+
auth: { getAccessToken: async () => await myTokenService.get() },
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// 変更後
|
|
81
|
+
const porters = new PortersClient({
|
|
82
|
+
hostname,
|
|
83
|
+
tokenProvider: {
|
|
84
|
+
acquire: async () => ({
|
|
85
|
+
accessToken: { token: await myTokenService.get() },
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- `TokenProvider` は `{ acquire, refresh?, exchange? }` です。`acquire` は必須、`refresh` と `exchange` は
|
|
92
|
+
使うときだけ渡します。期限(`expiresAt`)を返せば、その 60 秒前に取り直します。
|
|
93
|
+
- **構築オプション `auth` は無くなりました**。`auth` や、`getAccessToken` だけを持つ古い形を渡すと、構築時に
|
|
94
|
+
`PortersConfigError`(`category: "config"`)で止まります(型でも弾きます)。
|
|
95
|
+
- **`StoredTokens` の形が変わりました**: `{ accessToken: { token, expiresAt? }, refreshToken?: { token, expiresAt? } }`。
|
|
96
|
+
`tokenStore` に以前の形で保存されていた値は「保存なし」として扱い、上げた直後の 1 回だけ `code_direct` で
|
|
97
|
+
取り直します(保存先を手で消す必要はありません)。
|
|
98
|
+
- `tokenStore` は `tokenProvider` を渡したときも使われます。
|
|
99
|
+
- `porters.auth` の 6 メソッドは、どの取り方でも動きます。`exchangeAuthorizationCode` には `tokenProvider` の
|
|
100
|
+
`exchange` が、`authorizationUrl` / `revokeUrl` には `appId` が要ります。
|
|
101
|
+
- 既定の取り方で `appId` / `appSecret` が無いときは、PORTERS へ何も送らずに `PortersConfigError` になります。
|
|
102
|
+
- 保存済みの Access Token がまだ有効なら、起動直後にも取りに行きません。
|
|
103
|
+
- `GetAccessTokenOptions` を公開 API から外し、`IssuedToken`(`{ token, expiresAt? }`)を足しました。
|
|
104
|
+
- 書き方は[認証とトークン][oauth-guide]の「トークンの取り方を差し替える」にあります。
|
|
105
|
+
|
|
106
|
+
- **(破壊的)日時(`DateTime` / `System[DateTime]`)の項目に書く値と、`condition` に書く値は、時刻とタイムゾーンの
|
|
107
|
+
そろった ISO 8601 だけを受け付けるようになりました**。形は `YYYY-MM-DDTHH:MM[:SS[.sss]]` に `Z` か `±HH:MM` が
|
|
108
|
+
付いたものです。`new Date().toISOString()` の出力はそのまま渡せます。
|
|
109
|
+
|
|
110
|
+
これまでは、次の値が送る前に止まらず、**ずれた値が PORTERS に届いていました**。
|
|
111
|
+
|
|
112
|
+
| 渡した値 | これまで(実行環境が日本時間のとき) | これから |
|
|
113
|
+
| ---------------------------------------- | ------------------------------------ | -------------------- |
|
|
114
|
+
| `"2026/09/10"`(PORTERS の形式) | `2026/09/09 15:00:00` として送る | `PortersConfigError` |
|
|
115
|
+
| `"2026-09-10T12:00:00"`(ゾーン無し) | 実行環境のタイムゾーンで読んで送る | `PortersConfigError` |
|
|
116
|
+
| `"2026-09-10"`(日付だけ) | UTC の 0 時として送る | `PortersConfigError` |
|
|
117
|
+
| `"2026-02-30T00:00:00Z"` / `…T24:00:00Z` | 3/2・翌日に繰り上げて送る | `PortersConfigError` |
|
|
118
|
+
- エラーは `PortersConfigError`(`category: "validation"`)で、`hint` がゾーンの要ることを示します。
|
|
119
|
+
- 日本時間で考えているなら、`"2026-09-10T09:00:00+09:00"` のようにオフセットを付けて渡します。
|
|
120
|
+
- `Date` / `Age` の項目(日付だけ)は変わりません。
|
|
121
|
+
|
|
122
|
+
### Fixed
|
|
123
|
+
|
|
124
|
+
- **既定の取り方で、PORTERS が Refresh Token を受け付けなかったとき(期限切れ・無効)に、`code_direct` で取り直す
|
|
125
|
+
ようになりました**。手元に記録した期限がまだ先だと、これまでは同じ refresh を繰り返して `PortersAuthError` になり、
|
|
126
|
+
`porters.auth.clearTokens()` を呼ぶまで回復しませんでした。同じ `tokenStore` を使う別のプロセスが先に更新して、
|
|
127
|
+
手元の Refresh Token が古くなったときにも起きていました。`PortersAuthError` が返るのは、`code_direct` でも
|
|
128
|
+
取り直せないとき(初回の権限付与が済んでいない・取り消された、App ID / App Secret が違う、など)だけです。
|
|
129
|
+
渡した `tokenProvider` の失敗は、これまでどおりそのまま届けます。
|
|
130
|
+
- トークンの取得が認証 API の 401 / 402 で失敗したときに、Access Token の期限切れと取り違えて、もう一度取り直しを
|
|
131
|
+
強いていたのをやめました(失敗する取得を 2 回送っていました)。
|
|
132
|
+
- **使い方ドキュメントを実装と突き合わせ、挙動と食い違っていた記述を直しました**。主なもの:
|
|
133
|
+
`create` を自動で再送しないのは届いたか分からないときだけ/エラーの型と HTTP ステータスの対応/
|
|
134
|
+
Activity の `P_ResourceId` は `expand` できない/Attachment の `search` で絞れるのは `resourceId` だけ/
|
|
135
|
+
一括書き込みは約 15000 字でも分ける/`base64ToBytes` は読めない文字列で例外を投げる、など。
|
|
136
|
+
トークンの取得や OAuth の URL 作成で出る `PortersConfigError` を、メッセージから
|
|
137
|
+
[トラブルシューティング][troubleshooting]で引けるようにしました。
|
|
138
|
+
|
|
8
139
|
## [0.23.0] - 2026-09-24
|
|
9
140
|
|
|
10
141
|
**カスタム項目を宣言で `create` の必須にできるようにした版**です。あわせて、利用者の TypeScript の下限を
|
|
@@ -1377,7 +1508,9 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
|
|
|
1377
1508
|
[ref]: docs/usage/reference/README.md
|
|
1378
1509
|
[kac]: https://keepachangelog.com/en/1.1.0/
|
|
1379
1510
|
[semver]: https://semver.org/
|
|
1380
|
-
[unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.
|
|
1511
|
+
[unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.25.0...HEAD
|
|
1512
|
+
[0.25.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.24.0...v0.25.0
|
|
1513
|
+
[0.24.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.23.0...v0.24.0
|
|
1381
1514
|
[0.23.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.22.0...v0.23.0
|
|
1382
1515
|
[0.22.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.21.0...v0.22.0
|
|
1383
1516
|
[0.21.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.20.1...v0.21.0
|
|
@@ -1421,3 +1554,9 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
|
|
|
1421
1554
|
[ref-department]: docs/usage/reference/resource-api/resources/department.md
|
|
1422
1555
|
[adr89]: docs/adr/0089-custom-field-required-on-create.md
|
|
1423
1556
|
[adr90]: docs/adr/0090-typescript-floor.md
|
|
1557
|
+
[adr91]: docs/adr/0091-token-provider-and-store.md
|
|
1558
|
+
[adr92]: docs/adr/0092-reject-unknown-options.md
|
|
1559
|
+
[adr93]: docs/adr/0093-get-token-with-expiry.md
|
|
1560
|
+
[recipe-token-store-db]: docs/usage/recipes/token-store-db.md
|
|
1561
|
+
[recipe-central-token-service]: docs/usage/recipes/central-token-service.md
|
|
1562
|
+
[troubleshooting]: docs/usage/reference/troubleshooting.md
|
package/README.md
CHANGED
|
@@ -9,35 +9,39 @@ PORTERS Connect API(旧 HRBC)を **TypeScript から型安全・簡単に**
|
|
|
9
9
|
> これは**非公式**ライブラリです。ポーターズ株式会社とは無関係で、公式ロゴ・商標は使用していません。
|
|
10
10
|
> 利用には **PORTERS の契約 + Connect API オプション契約**が必要です(ホスト名・App ID/Secret は契約時に通知されます)。
|
|
11
11
|
|
|
12
|
-
XML
|
|
12
|
+
PORTERS が返す XML は、型の付いたオブジェクトに変換して返します。PORTERS 独自の OAuth、上限を守るための制御、
|
|
13
|
+
エラーの分類はライブラリが受け持ちます。
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
## 特徴
|
|
17
18
|
|
|
18
|
-
-
|
|
19
|
-
- **XML
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- **日時は ISO 8601(UTC
|
|
23
|
-
- **PORTERS
|
|
19
|
+
- **型安全**:リソースと項目の値に型が付きます。`any` は使いません。
|
|
20
|
+
- **XML を扱わなくてよい**:戻り値は型の付いたオブジェクトで、渡す値もふつうの JavaScript の値です。
|
|
21
|
+
- **OAuth の手続きを自動で行う**:`code_direct` でのトークンの取得・キャッシュ・更新をライブラリが行います。
|
|
22
|
+
- **上限を守る**:スロットリング、リトライ(指数バックオフ)、リクエストの長さの検査を備えています。
|
|
23
|
+
- **日時は ISO 8601(UTC)でやり取りする**:JST などへの変換はしません(利用側で行います)。
|
|
24
|
+
- **PORTERS の全リソースに対応**:マスタ系 5 種(読み取り専用)+ データ系 13 種(Phase・Attachment を含む)。
|
|
25
|
+
一覧と呼べるメソッドは[リソースと操作][docs-resources]にあります。
|
|
24
26
|
|
|
25
27
|
## 前提
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
使い始める前に、次の **4 つ**を済ませておく必要があります。揃っていないと PORTERS を呼べません。
|
|
28
30
|
|
|
29
31
|
1. **PORTERS 契約 + Connect API オプション契約**(オプションは別契約)。
|
|
30
|
-
2. **API アプリの登録**。ここで Redirect URL を決め、**ホスト名・App ID・App Secret** が
|
|
32
|
+
2. **PORTERS への API アプリの登録**。ここで Redirect URL を決め、**ホスト名・App ID・App Secret** が
|
|
31
33
|
通知されます(いずれも機密情報なので、コードに直接書かず環境変数で渡します)。
|
|
32
|
-
3.
|
|
33
|
-
`code_direct
|
|
34
|
-
4.
|
|
34
|
+
3. **初回だけ、ブラウザで権限を付与する**(人の操作が要ります。Company DB ごとに 1 回)。2 回目以降は、ライブラリが
|
|
35
|
+
`code_direct`(サーバ間)で人の操作なしにトークンを取ります。
|
|
36
|
+
4. **付与するスコープを決める**(リソースごとに読み `_r` / 書き `_w`。読み取りだけでも複数のスコープが要ることがあります)。
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
あります。実行環境は **Node.js 22.12 以上**で、型定義は同梱です(型を読むには **TypeScript 5.4 以上**が要ります)。ビルド済みの JavaScript ファイルは ESM(`import`)の 1 つですが、
|
|
38
|
-
CJS(`require`)からも `require("@joymerrevent/porters-connect")` で読めます([CJS から使う][s-cjs])。
|
|
38
|
+
揃え方は[始める前に][s-prereq]に、権限付与の手順は[認証を通して、疎通を確認する][s-auth]にあります。
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
実行環境は **Node.js 22.12 以上**です。型定義は同梱していて、型を読むには **TypeScript 5.4 以上**が要ります。
|
|
41
|
+
配布しているのは ESM(`import`)のファイル 1 つですが、CJS(`require`)からも
|
|
42
|
+
`require("@joymerrevent/porters-connect")` で読み込めます([CJS から使う][s-cjs])。
|
|
43
|
+
|
|
44
|
+
契約や権限付与を**待っている間**も、PORTERS に接続せずにコードとテストを書けます
|
|
41
45
|
([契約なしでテストする][test-without-contract])。
|
|
42
46
|
|
|
43
47
|
## インストール
|
|
@@ -48,7 +52,7 @@ npm i @joymerrevent/porters-connect
|
|
|
48
52
|
# yarn add @joymerrevent/porters-connect
|
|
49
53
|
```
|
|
50
54
|
|
|
51
|
-
##
|
|
55
|
+
## クイックスタート
|
|
52
56
|
|
|
53
57
|
```ts
|
|
54
58
|
import { PortersClient } from "@joymerrevent/porters-connect";
|
|
@@ -59,7 +63,7 @@ const porters = new PortersClient({
|
|
|
59
63
|
appSecret: process.env.PORTERS_APP_SECRET ?? "",
|
|
60
64
|
});
|
|
61
65
|
|
|
62
|
-
//
|
|
66
|
+
// Partition(Company DB)は tenant(id) で指定する(既定の Partition は無い)。テナントが 1 つでも同じ書き方
|
|
63
67
|
const t = porters.tenant(456);
|
|
64
68
|
|
|
65
69
|
const page = await t.candidate.search({
|
|
@@ -72,74 +76,59 @@ const page = await t.candidate.search({
|
|
|
72
76
|
console.log(page.total, page.items[0]?.P_Name);
|
|
73
77
|
```
|
|
74
78
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
## リソースと操作
|
|
78
|
-
|
|
79
|
-
| アクセサ | リソース | アクセサ | リソース |
|
|
80
|
-
| --------------- | -------------- | -------------- | ------------ |
|
|
81
|
-
| `t.candidate` | 個人連絡先 | `t.contract` | 契約 |
|
|
82
|
-
| `t.job` | JOB | `t.sales` | 成約・売上 |
|
|
83
|
-
| `t.client` | 企業 | `t.process` | 選考プロセス |
|
|
84
|
-
| `t.recruiter` | 企業担当者 | `t.resume` | レジュメ |
|
|
85
|
-
| `t.contact` | コンタクト | `t.attachment` | 添付ファイル |
|
|
86
|
-
| `t.opportunity` | 商談管理 | `t.phase` | フェーズ履歴 |
|
|
87
|
-
| `t.activity` | アクティビティ | | |
|
|
88
|
-
|
|
89
|
-
マスタ系は `porters.partition` / `t.user` / `t.department` / `t.field` / `t.option` の 5 種(読み取り専用)。
|
|
90
|
-
|
|
91
|
-
**どのメソッドが呼べるかはリソースごとに違います**(`searchAll` が無いもの、先に `of("candidate")` のように
|
|
92
|
-
対象リソースを指定するもの(Field・Phase・Attachment)があります)。一覧は[リソースと操作][docs-resources]、引数・戻り値・項目の一覧は
|
|
93
|
-
[API リファレンス][api-ref]が正確な定義です。
|
|
79
|
+
README で説明するのはここまでです。認証の準備・書き込み・エラーの扱いなど、使い方の全体は
|
|
80
|
+
[docs/usage][docs-index] の目次から読めます<!-- 根拠: ADR-0070(README は入口に絞る) -->。はじめての人は[導入][s-prereq](6 ページ)から順に進んでください。
|
|
94
81
|
|
|
95
82
|
## ドキュメント
|
|
96
83
|
|
|
97
84
|
**[docs/usage][docs-index] が目次**です。7 つの章に分かれていて、順に読むのは導入だけです。
|
|
98
85
|
|
|
99
|
-
| 章 |
|
|
100
|
-
| ---------------- |
|
|
101
|
-
| **導入** |
|
|
102
|
-
|
|
|
103
|
-
| **クライアント** |
|
|
104
|
-
|
|
|
105
|
-
| **関数** | `import`
|
|
106
|
-
| **実践例** |
|
|
107
|
-
| **リファレンス** | [公開 API リファレンス][api-ref]
|
|
86
|
+
| 章 | 概要 |
|
|
87
|
+
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| **導入** | PORTERS への接続から、データの読み書き、本番での運用までを、6 ページで順に説明します |
|
|
89
|
+
| **ガイド** | Partition・検索・書き込み・認証・上限など、PORTERS を使ううえで欠かせない事柄を 1 ページずつ説明します。PORTERS 側の前提と、ライブラリが受け持つ範囲が分かります |
|
|
90
|
+
| **クライアント** | クライアントの作り方と、クライアントから呼び出せる機能をまとめています |
|
|
91
|
+
| **リソース** | 18 のリソースごとに、使えるメソッド・注意点・新規作成の必須項目をまとめています |
|
|
92
|
+
| **関数** | `import` して使う関数ごとに、使い方と失敗したときの扱いをまとめています |
|
|
93
|
+
| **実践例** | 毎日の差分同期や複数テナントなど、よくある用途ごとに、機能の組み合わせ方をサンプルコードで示します |
|
|
94
|
+
| **リファレンス** | 型やメソッドの正確な定義([公開 API リファレンス][api-ref])と、PORTERS 側の仕様([PORTERS API の事実][ref])をまとめています |
|
|
108
95
|
|
|
109
|
-
|
|
96
|
+
目次の末尾の「目的から探す」から、やりたいことに合うページへ直接進めます。
|
|
110
97
|
|
|
111
98
|
## PORTERS 固有の注意
|
|
112
99
|
|
|
113
|
-
|
|
114
|
-
|
|
100
|
+
PORTERS 側の仕様で、使い始める前に知っておきたいものです。詳しくは、それぞれのガイドのページの「まず知ること」に
|
|
101
|
+
あります。
|
|
115
102
|
|
|
116
|
-
-
|
|
117
|
-
- **日時は UTC
|
|
118
|
-
- **データは Partition
|
|
119
|
-
-
|
|
120
|
-
|
|
121
|
-
|
|
103
|
+
- **PORTERS には削除の API がありません**。このライブラリにも `delete()` はありません([削除と削除済みデータ][c-no-delete])。
|
|
104
|
+
- **日時は UTC です**。ISO 8601(`…Z`)で受け渡しし、JST などへの変換はしません([日時と時分型][c-datetime])。
|
|
105
|
+
- **データは Partition(Company DB)ごとに分かれています**。`tenant(id)` で Partition を指定してから読み書きします
|
|
106
|
+
([Partition とテナントスコープ][c-partition])。
|
|
107
|
+
- **上限があります**。リクエストの長さ(約 15000 文字)・1 リクエスト 200 件・1 分あたり Read 2000 / Write 500 は
|
|
108
|
+
ライブラリが守ります。**月 15 万アクセスは契約の条件**で、数えて守るのは利用側です([上限とレート][c-limits])。
|
|
109
|
+
- **ホスト名は契約時に通知されます**。環境変数(`PORTERS_HOST` など)で渡し、コードに直接書かないでください。
|
|
122
110
|
|
|
123
111
|
## 対応バージョン
|
|
124
112
|
|
|
125
|
-
-
|
|
126
|
-
|
|
113
|
+
- **Connect API Version 2 を前提にしています**。リクエストには `X-P-ConnectAPI-Version: 2` を付けて送ります
|
|
114
|
+
(担当者型・部署型の参照項目(Link)などは v2 が必要です)。互換性は、この Connect API のバージョンで示します。
|
|
115
|
+
- **PORTERS の製品バージョン 8.x / 9.x は参考です**。どちらも v2 を提供している世代ですが、マイナーバージョンごとの動作は
|
|
116
|
+
保証しません。PORTERS 側の仕様は [PORTERS API の事実][ref](PORTERS の公式ドキュメントに基づく)にまとめています。
|
|
127
117
|
|
|
128
118
|
## リンク
|
|
129
119
|
|
|
130
|
-
**この README は「最短で動かす」ところまで**です。全体は目次から読めます<!-- 根拠: ADR-0070 -->。
|
|
131
|
-
|
|
132
120
|
- 利用者向け:[docs/usage][docs-index](目次)/[公開 API リファレンス][api-ref]/[PORTERS API の事実][ref]
|
|
133
121
|
- 開発・保守:[docs/README.md][docs-readme](ADR(設計判断の記録)・基本設計・ロードマップ・台帳)
|
|
134
122
|
- 提供元:[Joymerrevent][joymerrevent]
|
|
135
123
|
|
|
136
124
|
## コントリビュート / セキュリティ
|
|
137
125
|
|
|
138
|
-
- バグ報告・要望・質問は [Issues][issues]
|
|
126
|
+
- バグ報告・要望・質問は [Issues][issues] へお願いします。外部の方からの提案は Issue で受け付けていて、PR を作れるのは
|
|
127
|
+
コラボレーターだけです。詳しくは [CONTRIBUTING][contributing] にあります。
|
|
139
128
|
- 脆弱性は公開 Issue ではなく [セキュリティポリシー][security] の手順で**非公開**で報告してください。
|
|
140
|
-
-
|
|
129
|
+
- 行動規範は [Contributor Covenant][coc] です。
|
|
141
130
|
|
|
142
|
-
>
|
|
131
|
+
> このライブラリは**非公式**です。PORTERS の製品や Connect API そのものの不具合・要望は、PORTERS の公式窓口へお問い合わせください。
|
|
143
132
|
|
|
144
133
|
## ライセンス
|
|
145
134
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1,22 +1,42 @@
|
|
|
1
|
-
/**
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/** One token and, when known, its absolute expiry (epoch ms). No `expiresAt` means "unknown". */
|
|
2
|
+
type IssuedToken = {
|
|
3
|
+
token: string;
|
|
4
|
+
expiresAt?: number;
|
|
5
5
|
};
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Tokens as obtained from a {@link TokenProvider} and persisted by a {@link TokenStore}.
|
|
8
|
+
* `refreshToken` is present only when the issuer hands one out; a value and its expiry always
|
|
9
|
+
* travel together.
|
|
10
|
+
*/
|
|
11
11
|
type StoredTokens = {
|
|
12
|
-
accessToken:
|
|
13
|
-
refreshToken
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
accessToken: IssuedToken;
|
|
13
|
+
refreshToken?: IssuedToken;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Where tokens come from. Pass one as `tokenProvider` to obtain tokens elsewhere (for example
|
|
17
|
+
* from a central service that holds the App Secret); leave it out for the built-in `code_direct`
|
|
18
|
+
* flow. The client caches what these return, renews shortly before expiry, retries once on an
|
|
19
|
+
* expired-token response, collapses concurrent renewals into one, and saves to `tokenStore`.
|
|
20
|
+
*/
|
|
21
|
+
type TokenProvider = {
|
|
22
|
+
/** Obtain tokens from scratch. Called first, and whenever renewal is not possible. */
|
|
23
|
+
acquire(): Promise<StoredTokens>;
|
|
24
|
+
/**
|
|
25
|
+
* Renew tokens. Called instead of {@link TokenProvider.acquire} while `current.refreshToken`
|
|
26
|
+
* is usable — or, when the issuer hands out no refresh token, whenever renewal is needed.
|
|
27
|
+
* Leave it out to renew by calling `acquire` again.
|
|
28
|
+
*/
|
|
29
|
+
refresh?(current: StoredTokens): Promise<StoredTokens>;
|
|
30
|
+
/**
|
|
31
|
+
* Exchange an authorization `code` returned to your redirect URL after the browser grant.
|
|
32
|
+
* Needed only for `porters.auth.exchangeAuthorizationCode`. PORTERS expires a `code` 30 seconds
|
|
33
|
+
* after issuing it, so do not do slow work here.
|
|
34
|
+
*/
|
|
35
|
+
exchange?(code: string): Promise<StoredTokens>;
|
|
16
36
|
};
|
|
17
37
|
/**
|
|
18
38
|
* Pluggable token persistence (default: in-memory). Async so it can back onto
|
|
19
|
-
* redis / DB / file for multi-instance server use.
|
|
39
|
+
* redis / DB / file for multi-instance server use. Used with every token provider.
|
|
20
40
|
*/
|
|
21
41
|
type TokenStore = {
|
|
22
42
|
get(): Promise<StoredTokens | undefined>;
|
|
@@ -146,18 +166,18 @@ type RevokeUrlOptions = AuthorizationUrlOptions;
|
|
|
146
166
|
* The `porters.auth.*` surface. The initial per-Company-DB grant
|
|
147
167
|
* needs a human to open {@link AuthApi.authorizationUrl} in a browser and consent; the
|
|
148
168
|
* library only builds the URL and exchanges the returned `code`. Day-to-day token
|
|
149
|
-
* acquisition
|
|
150
|
-
* touch this surface.
|
|
169
|
+
* acquisition and renewal are handled by the client, whichever token provider is in use, so
|
|
170
|
+
* most callers never touch this surface.
|
|
151
171
|
*/
|
|
152
172
|
type AuthApi = {
|
|
153
173
|
/** Build the browser `code`-grant URL to open for the initial permission grant. */
|
|
154
174
|
authorizationUrl(opts: AuthorizationUrlOptions): string;
|
|
155
175
|
/**
|
|
156
|
-
* Exchange a redirect `?code=` for tokens
|
|
157
|
-
* Resolves `void` on success (
|
|
158
|
-
* {@link AuthApi.getToken});
|
|
159
|
-
*
|
|
160
|
-
* code), or `PortersNetworkError`.
|
|
176
|
+
* Exchange a redirect `?code=` for tokens through the token provider's `exchange`, and save
|
|
177
|
+
* them (cache and `tokenStore`). Resolves `void` on success (inspect via
|
|
178
|
+
* {@link AuthApi.getToken}); rejects with {@link PortersConfigError} when the provider has no
|
|
179
|
+
* `exchange` or the built-in one lacks `appId` / `appSecret`, `PortersAuthError` (token-endpoint
|
|
180
|
+
* error or expired code), or `PortersNetworkError`.
|
|
161
181
|
*/
|
|
162
182
|
exchangeAuthorizationCode(code: string): Promise<void>;
|
|
163
183
|
/**
|
|
@@ -170,8 +190,14 @@ type AuthApi = {
|
|
|
170
190
|
clearTokens(): Promise<void>;
|
|
171
191
|
/** Acquire a token now (startup fail-fast / warm-up); throws if auth is unavailable. */
|
|
172
192
|
ensureAuthenticated(): Promise<void>;
|
|
173
|
-
/**
|
|
174
|
-
|
|
193
|
+
/**
|
|
194
|
+
* The Access Token the client currently uses, with its expiry — renewed first when it is within
|
|
195
|
+
* the refresh margin, exactly as a request would. `expiresAt` is epoch milliseconds, or absent
|
|
196
|
+
* when the token provider did not report one. Use it to hand the token to another process (for
|
|
197
|
+
* example, a central service answering its apps' `tokenProvider.acquire`). The Refresh Token is
|
|
198
|
+
* never exposed.
|
|
199
|
+
*/
|
|
200
|
+
getToken(): Promise<IssuedToken>;
|
|
175
201
|
};
|
|
176
202
|
|
|
177
203
|
type DataType = "System[Id]" | "Number" | "DateTime" | "System[DateTime]" | "Date" | "Age" | "SinglelineText" | "MultilineText" | "Mail" | "Telephone" | "URL" | "User" | "Option" | "System[Reference]" | "System[Department]" | "Image" | "Link";
|
|
@@ -2918,9 +2944,14 @@ type PortersClientOptions = {
|
|
|
2918
2944
|
appId?: string;
|
|
2919
2945
|
appSecret?: string;
|
|
2920
2946
|
scopes?: Scope[];
|
|
2921
|
-
/**
|
|
2922
|
-
|
|
2923
|
-
|
|
2947
|
+
/**
|
|
2948
|
+
* Where tokens come from. Leave it out for the built-in flow (`code_direct` with `appId` /
|
|
2949
|
+
* `appSecret`); pass one to obtain tokens another way — for example from a central service that
|
|
2950
|
+
* holds the App Secret. Either way the client caches, renews before expiry, retries once on an
|
|
2951
|
+
* expired token, and saves to `tokenStore`.
|
|
2952
|
+
*/
|
|
2953
|
+
tokenProvider?: TokenProvider;
|
|
2954
|
+
/** Token persistence, used with every token provider; defaults to in-memory. */
|
|
2924
2955
|
tokenStore?: TokenStore;
|
|
2925
2956
|
/** Injectable HTTP transport; defaults to a fetch-based transport. */
|
|
2926
2957
|
transport?: Transport;
|
|
@@ -2933,14 +2964,6 @@ type PortersClientOptions = {
|
|
|
2933
2964
|
* library leaves that to you. `createThrottle()` builds the default implementation.
|
|
2934
2965
|
*/
|
|
2935
2966
|
throttle?: Throttle;
|
|
2936
|
-
/**
|
|
2937
|
-
* **Not a client option any more.** Custom fields belong to a partition, so the
|
|
2938
|
-
* declaration goes to {@link PortersClient.tenant} as `tenant(id, { fields })`. Typed `never`
|
|
2939
|
-
* so a configuration object that still carries the pre-0.21 `fields` fails to compile even when
|
|
2940
|
-
* it is not a fresh literal; at runtime the constructor rejects it with {@link PortersConfigError}
|
|
2941
|
-
* rather than silently dropping the declaration (the same fail-closed stance as `hostname`).
|
|
2942
|
-
*/
|
|
2943
|
-
fields?: never;
|
|
2944
2967
|
};
|
|
2945
2968
|
/**
|
|
2946
2969
|
* Options for {@link PortersClient.tenant}. `C` is inferred from `fields`.
|
|
@@ -3160,4 +3183,4 @@ declare const decodeTimeOfDay: (iso: string) => string;
|
|
|
3160
3183
|
*/
|
|
3161
3184
|
declare const encodeTimeOfDay: (time: string) => string;
|
|
3162
3185
|
|
|
3163
|
-
export { type Activity, type ActivityCreateInput, type ActivityPage, type ActivityResource, type ActivitySearchQuery, type ActivityUpdateInput, type Attachment, type AttachmentAccessor, type AttachmentCreate, type AttachmentPage, type AttachmentResource, type AttachmentSearchQuery, type AttachmentUpdate, type AttachmentWalkQuery, type AuthApi, type AuthorizationUrlOptions, type BulkWriteResult, type BulkWriteResultItem, type Candidate, type CandidateCreateInput, type CandidatePage, type CandidateResource, type CandidateSearchQuery, type CandidateUpdateInput, type Client, type ClientCreateInput, type ClientPage, type ClientResource, type ClientSearchQuery, type ClientUpdateInput, type Condition, type Contact, type ContactCreateInput, type ContactPage, type ContactResource, type ContactSearchQuery, type ContactUpdateInput, type Contract, type ContractCreateInput, type ContractPage, type ContractResource, type ContractSearchQuery, type ContractUpdateInput, type CustomDataType, type CustomFieldResource, type CustomFor, type DeclaredCatalogs, type DeclaredRequiredOf, type DefinedFields, type Department, type DepartmentPage, type DepartmentRef, type DepartmentResource, type DepartmentSearchQuery, type ErrorCategory, type Expand, type ExpandedReadRecord, type FetchTransportOptions, type Field, type FieldAccessor, type FieldBuilder, type FieldCatalogSource, type FieldDecls, type FieldDef, type FieldOptions, type FieldPage, type FieldResource, type FieldSearchQuery, type FieldTypeMismatch, type FieldValue, type FieldVerification, type GenerateFieldDeclsOptions, type
|
|
3186
|
+
export { type Activity, type ActivityCreateInput, type ActivityPage, type ActivityResource, type ActivitySearchQuery, type ActivityUpdateInput, type Attachment, type AttachmentAccessor, type AttachmentCreate, type AttachmentPage, type AttachmentResource, type AttachmentSearchQuery, type AttachmentUpdate, type AttachmentWalkQuery, type AuthApi, type AuthorizationUrlOptions, type BulkWriteResult, type BulkWriteResultItem, type Candidate, type CandidateCreateInput, type CandidatePage, type CandidateResource, type CandidateSearchQuery, type CandidateUpdateInput, type Client, type ClientCreateInput, type ClientPage, type ClientResource, type ClientSearchQuery, type ClientUpdateInput, type Condition, type Contact, type ContactCreateInput, type ContactPage, type ContactResource, type ContactSearchQuery, type ContactUpdateInput, type Contract, type ContractCreateInput, type ContractPage, type ContractResource, type ContractSearchQuery, type ContractUpdateInput, type CustomDataType, type CustomFieldResource, type CustomFor, type DeclaredCatalogs, type DeclaredRequiredOf, type DefinedFields, type Department, type DepartmentPage, type DepartmentRef, type DepartmentResource, type DepartmentSearchQuery, type ErrorCategory, type Expand, type ExpandedReadRecord, type FetchTransportOptions, type Field, type FieldAccessor, type FieldBuilder, type FieldCatalogSource, type FieldDecls, type FieldDef, type FieldOptions, type FieldPage, type FieldResource, type FieldSearchQuery, type FieldTypeMismatch, type FieldValue, type FieldVerification, type GenerateFieldDeclsOptions, type ImageContentType, type ImageOption, type ImageReadRecord, type ImageSelectedValue, type ImageSubField, type ImageValue, type ImageWriteValue, type IssuedToken, type ItemState, type Job, type JobCreateInput, type JobPage, type JobResource, type JobSearchQuery, type JobUpdateInput, type LinkValue, type MissingField, type MockHandler, type MockReply, type MockTransportOptions, type Opportunity, type OpportunityCreateInput, type OpportunityPage, type OpportunityResource, type OpportunitySearchQuery, type OpportunityUpdateInput, type Option, type OptionResource, type OptionSearchQuery, type Order, type Partition, type PartitionId, type PartitionPage, type PartitionResource, type PartitionSearchQuery, type Phase, type PhaseAccessor, type PhaseCreateInput, type PhasePage, type PhaseResource, type PhaseSearchQuery, type PhaseUpdateInput, PortersAuthError, PortersClient, type PortersClientOptions, PortersConfigError, PortersError, type PortersErrorContext, type PortersErrorOptions, PortersNetworkError, PortersResourceError, type Process, type ProcessCreateInput, type ProcessPage, type ProcessResource, type ProcessSearchQuery, type ProcessUpdateInput, type ReadCustomCatalogOptions, type ReadFieldAlias, type Recruiter, type RecruiterCreateInput, type RecruiterPage, type RecruiterResource, type RecruiterSearchQuery, type RecruiterUpdateInput, type ReferenceMap, type ReferenceRecord, type RequiredFor, type RequiredMismatch, type ResourceName, type ResourcePageOf, type ResourceType, type Resume, type ResumeCreateInput, type ResumePage, type ResumeResource, type ResumeSearchQuery, type ResumeUpdateInput, type RevokeUrlOptions, type Sales, type SalesCreateInput, type SalesPage, type SalesResource, type SalesSearchQuery, type SalesUpdateInput, type Scheme, type Scope, type SearchQuery, type StoredTokens, type TenantCustomCatalog, type TenantOptions, type TenantScope, type Throttle, type ThrottleOptions, type TokenProvider, type TokenStore, type Transport, type TransportRequest, type TransportResponse, type UndeclarableField, type UndeclarableReason, type UndeclarableTenantField, type UndeclaredField, type UnverifiableResource, type User, type UserPage, type UserRef, type UserResource, type UserSearchQuery, type VerifyFieldsOptions, assertFieldsMatch, base64ToBytes, bytesToBase64, createFetchTransport, createMockTransport, createThrottle, decodeTimeOfDay, defineFields, encodeTimeOfDay, generateFieldDecls, rawValue, readCustomCatalog, resourceNameOf, resourceValueOf, verifyFields };
|