@joymerrevent/porters-connect 0.21.0 → 0.22.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 +53 -11
- package/README.md +45 -41
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +26 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,46 @@
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.22.0] - 2026-09-23
|
|
9
|
+
|
|
10
|
+
**読み取りの値の検証を 1 つ増やし、使い方ドキュメントを組み直した版**です。破壊的変更はありませんが、
|
|
11
|
+
**宣言が実際の項目と合っていないと、これまで通っていた読み取りがエラーになることがあります**(下の Changed)。
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **数値でない文字列を `Number` として読まなくなりました**。`Number` / `System[Id]` の項目と
|
|
16
|
+
`Link` のスカラ形(Contact の ID)に数値として読めない値が来ると、`PortersResourceError`
|
|
17
|
+
(`category: "validation"`・項目名つき)で失敗します。これまでは `Number("社内候補")` の結果=**`NaN`** が
|
|
18
|
+
黙って読み取り値に入り、`typeof === "number"` と `null` 判定の両方を通り、そのまま `update` に戻すと
|
|
19
|
+
`<Alias>NaN</Alias>` を送っていました。
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
U_score: declared Number, but "社内候補" is not a PORTERS Number value
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- 起きるのは**宣言が違うとき**です(テキストの項目を `f.number()` と宣言した、など)。PORTERS が
|
|
26
|
+
Number 項目に数値以外を返す書式は出典にありません。日時(`f.date()` 等)が 0.15.0 から同じ形で
|
|
27
|
+
エラーになるのと揃えました。
|
|
28
|
+
- 数値として読める値(`"87"` / `"-1.25"` / 前後の空白)と空(`null`)は変わりません。
|
|
29
|
+
- 書き込み側は変えていません(`NaN` を渡す JS コードはこれまでどおりそのまま送られます)。
|
|
30
|
+
- 上げる前に宣言を確かめるなら、これまでどおり `verifyFields` です。
|
|
31
|
+
|
|
32
|
+
- **使い方ドキュメント(`docs/usage/`)を 7 章に組み直しました**。導入/主題別/クライアント/リソース別/
|
|
33
|
+
関数/実践例/リファレンスの順で、目次(`docs/usage/index.md`)から章を辿ります。
|
|
34
|
+
- **リソース別**は 18 種に 1 ページずつで、どのページも「呼べるメソッド → 固有の注意 → 新規作成の必須項目 →
|
|
35
|
+
項目と型」の同じ順に並びます。
|
|
36
|
+
- **クライアント**(`PortersClient` の構築オプション・`porters.auth` の 6 メソッド・`tenant(id)` のスコープ)と
|
|
37
|
+
**関数**(宣言と突合・上限と接続・値の変換)の章を新設し、導入と主題別に散らばっていた一覧をまとめました。
|
|
38
|
+
- **主題別**(検索・書き込み・認証・カスタム項目・上限など)は「まず知ること → 使い方 → 細かい規則」の順に
|
|
39
|
+
書き直し、言い回しを平易にしています。内容の食い違い(`Promise` を返さない関数の一覧の漏れなど)も直しました。
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- **単件の `create` / `update` が、`of()` で指定済みの項目(Phase の `Resource`)を渡されたとき、
|
|
44
|
+
同期 throw していました**。`Promise` を返すほかの公開メソッドと同じく、reject で届くようにしました。
|
|
45
|
+
入力型が `Resource` を受け付けないので、TypeScript から普通に書く限り起きません(`as any` を通した場合と
|
|
46
|
+
JavaScript から呼んだ場合だけ)。例外の種類・`message`・`category` は変わりません。
|
|
47
|
+
|
|
8
48
|
## [0.21.0] - 2026-09-21
|
|
9
49
|
|
|
10
50
|
**カスタム項目の宣言を、partition を束ねる `tenant(id)` で受け取るようにした版**です。
|
|
@@ -20,8 +60,9 @@
|
|
|
20
60
|
|
|
21
61
|
カスタム項目(`U_` / `A_`)は **partition(Company DB)ごとのもの**です — 出典の各リソース記事が
|
|
22
62
|
「テナント毎に異なる」としています。これまで宣言は client に 1 つしか持てず、項目構成の違う
|
|
23
|
-
テナントを同じ client
|
|
24
|
-
|
|
63
|
+
テナントを同じ client で扱うと、**別テナントの宣言が黙って適用される**形でした(ずれは読み取り時の
|
|
64
|
+
`validation` エラーで見えますが〔0.15.0〕、どのテナントの宣言を当てたのかをライブラリは知らないので、
|
|
65
|
+
正しい宣言に取り替える手掛かりがありません)。partition を束ねる `tenant(id)` が、
|
|
25
66
|
その partition の項目の形も束ねます。
|
|
26
67
|
|
|
27
68
|
```ts
|
|
@@ -1245,7 +1286,7 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
|
|
|
1245
1286
|
- **エラー対処ガイド**: [docs/howto/handle-failures.md][guide](症状別早見表+2 系統のコード対応表)。
|
|
1246
1287
|
- **配布**: ESM / Node.js 18+ / 型定義同梱 / MIT。`X-P-ConnectAPI-Version: 2` を既定送信(PORTERS 8.x・9.x 想定)。
|
|
1247
1288
|
|
|
1248
|
-
[guide]: docs/usage/
|
|
1289
|
+
[guide]: docs/usage/topics/errors.md
|
|
1249
1290
|
[adr44]: docs/adr/0044-http-status-handling.md
|
|
1250
1291
|
[adr45]: docs/adr/0045-write-response-root-code.md
|
|
1251
1292
|
[adr46]: docs/adr/0046-guard-error-contract.md
|
|
@@ -1254,12 +1295,12 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
|
|
|
1254
1295
|
[adr50]: docs/adr/0050-auth-http-status-handling.md
|
|
1255
1296
|
[adr51]: docs/adr/0051-read-envelope-identification.md
|
|
1256
1297
|
[adr47]: docs/adr/0047-access-point-scheme.md
|
|
1257
|
-
[oauth-guide]: docs/usage/
|
|
1298
|
+
[oauth-guide]: docs/usage/topics/auth.md
|
|
1258
1299
|
[adr19]: docs/adr/0019-static-resource-types.md
|
|
1259
1300
|
[adr20]: docs/adr/0020-read-field-default.md
|
|
1260
1301
|
[adr35]: docs/adr/0035-usage-documentation-structure.md
|
|
1261
|
-
[custom-fields-guide]: docs/usage/
|
|
1262
|
-
[read-query-guide]: docs/usage/
|
|
1302
|
+
[custom-fields-guide]: docs/usage/topics/custom-fields.md
|
|
1303
|
+
[read-query-guide]: docs/usage/topics/query.md
|
|
1263
1304
|
[adr55]: docs/adr/0055-partition-binding-guard.md
|
|
1264
1305
|
[adr56]: docs/adr/0056-deleted-flag-typing.md
|
|
1265
1306
|
[adr57]: docs/adr/0057-itemstate-existing-explicit.md
|
|
@@ -1272,7 +1313,7 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
|
|
|
1272
1313
|
[rv22]: docs/reviews/rv/0022-ratelimit-create-no-retry.md
|
|
1273
1314
|
[rv32]: docs/reviews/rv/0032-searchall-query-mutation.md
|
|
1274
1315
|
[rv44]: docs/reviews/rv/0044-fields-excluded-from-coverage.md
|
|
1275
|
-
[write-constraints]: docs/usage/
|
|
1316
|
+
[write-constraints]: docs/usage/topics/limits.md
|
|
1276
1317
|
[adr68]: docs/adr/0068-api-reference-tooling.md
|
|
1277
1318
|
[adr69]: docs/adr/0069-tenant-field-catalog-tooling.md
|
|
1278
1319
|
[adr73]: docs/adr/0073-throttle-sharing.md
|
|
@@ -1285,14 +1326,15 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
|
|
|
1285
1326
|
[adr80]: docs/adr/0080-resource-parameter-binding.md
|
|
1286
1327
|
[adr81]: docs/adr/0081-attachment-read-parameters.md
|
|
1287
1328
|
[adr82]: docs/adr/0082-module-format-and-node-baseline.md
|
|
1288
|
-
[limits]: docs/usage/
|
|
1289
|
-
[failures]: docs/usage/
|
|
1329
|
+
[limits]: docs/usage/topics/limits.md
|
|
1330
|
+
[failures]: docs/usage/topics/errors.md
|
|
1290
1331
|
[adr85]: docs/adr/0085-option-alias-validation.md
|
|
1291
1332
|
[lv]: docs/live-verification.md
|
|
1292
1333
|
[ref]: docs/usage/reference/README.md
|
|
1293
1334
|
[kac]: https://keepachangelog.com/en/1.1.0/
|
|
1294
1335
|
[semver]: https://semver.org/
|
|
1295
|
-
[unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.
|
|
1336
|
+
[unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.22.0...HEAD
|
|
1337
|
+
[0.22.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.21.0...v0.22.0
|
|
1296
1338
|
[0.21.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.20.1...v0.21.0
|
|
1297
1339
|
[0.20.1]: https://github.com/Joymerrevent/porters-connect/compare/v0.20.0...v0.20.1
|
|
1298
1340
|
[0.20.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.19.1...v0.20.0
|
|
@@ -1330,5 +1372,5 @@ Attachment)あるのに、受け口の形が 3 つとも違っていました
|
|
|
1330
1372
|
[fastcheck]: https://github.com/dubzzz/fast-check
|
|
1331
1373
|
[adr86]: docs/adr/0086-time-of-day-fields.md
|
|
1332
1374
|
[adr87]: docs/adr/0087-tenant-scoped-field-declarations.md
|
|
1333
|
-
[howto-custom-fields]: docs/usage/
|
|
1375
|
+
[howto-custom-fields]: docs/usage/topics/custom-fields.md
|
|
1334
1376
|
[ref-department]: docs/usage/reference/resource-api/resources/department.md
|
package/README.md
CHANGED
|
@@ -10,36 +10,35 @@ PORTERS Connect API(旧 HRBC)を **TypeScript から型安全・簡単に**
|
|
|
10
10
|
> 利用には **PORTERS の契約 + Connect API オプション契約**が必要です(ホスト名・App ID/Secret は契約時に通知されます)。
|
|
11
11
|
|
|
12
12
|
XML レスポンスを型付きオブジェクトに変換し、独自仕様の OAuth・レート制御・エラー整理を内側に隠します。
|
|
13
|
-
**薄く・堅く**を方針に、フェイルセーフ(壊れたときに安全側へ倒れる)設計です。
|
|
14
13
|
|
|
15
14
|
---
|
|
16
15
|
|
|
17
16
|
## 特徴
|
|
18
17
|
|
|
19
|
-
- **型安全**:リソース・項目の値を型で表現。`any`
|
|
20
|
-
- **XML
|
|
21
|
-
- **独自 OAuth
|
|
22
|
-
-
|
|
18
|
+
- **型安全**:リソース・項目の値を型で表現。`any` を使いません。
|
|
19
|
+
- **XML を外に出さない**:返り値は型付きオブジェクト、入力もふつうの JS の値。
|
|
20
|
+
- **独自 OAuth を意識させない**:`code_direct` によるトークン取得・キャッシュ・更新を自動化。
|
|
21
|
+
- **上限を守る**:スロットリング・リトライ(指数バックオフ)・リクエストの長さの検査を内蔵。
|
|
23
22
|
- **日時は ISO 8601(UTC)に正規化**。業務タイムゾーン変換はしません(利用側の責務)。
|
|
24
|
-
- **PORTERS の全リソースに対応**:データ系 13 種(Phase・Attachment を含む)+
|
|
23
|
+
- **PORTERS の全リソースに対応**:データ系 13 種(Phase・Attachment を含む)+ マスタ系 5 種(読み取り専用)。
|
|
25
24
|
|
|
26
25
|
## 前提
|
|
27
26
|
|
|
28
|
-
繋ぐ前に、**PORTERS 側で 4 つ**が要ります。揃っていないと
|
|
27
|
+
繋ぐ前に、**PORTERS 側で 4 つ**が要ります。揃っていないと PORTERS を呼べません。
|
|
29
28
|
|
|
30
29
|
1. **PORTERS 契約 + Connect API オプション契約**(オプションは別契約)。
|
|
31
30
|
2. **API アプリの登録**。ここで Redirect URL を決め、**ホスト名・App ID・App Secret** が
|
|
32
|
-
|
|
31
|
+
通知されます(いずれも機密情報なので、コードに直接書かず環境変数で渡します)。
|
|
33
32
|
3. **初回のみブラウザで権限付与**(人手・Company DB ごとに 1 回)。以降はライブラリが
|
|
34
33
|
`code_direct`(サーバ間)で無人運用します。
|
|
35
34
|
4. **付与するスコープ**の決定(リソース別に `_r` / `_w`。Read でも複数要ることがあります)。
|
|
36
35
|
|
|
37
36
|
揃えかたは[始める前に][s-prereq]に、権限付与の手順は[認証を通して、疎通を確認する][s-auth]に
|
|
38
|
-
あります。実行環境は **Node.js 22.12
|
|
39
|
-
CJS
|
|
37
|
+
あります。実行環境は **Node.js 22.12 以上**で、型定義は同梱です。ビルド済みの JavaScript ファイルは ESM(`import`)の 1 つですが、
|
|
38
|
+
CJS(`require`)からも `require("@joymerrevent/porters-connect")` で読めます([CJS から使う][s-cjs])。
|
|
40
39
|
|
|
41
40
|
契約や権限付与を**待っている間**も、PORTERS に繋がずにコードとテストは書けます
|
|
42
|
-
([
|
|
41
|
+
([契約なしでテストする][test-without-contract])。
|
|
43
42
|
|
|
44
43
|
## インストール
|
|
45
44
|
|
|
@@ -55,12 +54,12 @@ npm i @joymerrevent/porters-connect
|
|
|
55
54
|
import { PortersClient } from "@joymerrevent/porters-connect";
|
|
56
55
|
|
|
57
56
|
const porters = new PortersClient({
|
|
58
|
-
hostname: process.env.PORTERS_HOST ?? "", //
|
|
57
|
+
hostname: process.env.PORTERS_HOST ?? "", // 契約時に通知される値。コードに直接書かず環境変数で渡す
|
|
59
58
|
appId: process.env.PORTERS_APP_ID ?? "",
|
|
60
59
|
appSecret: process.env.PORTERS_APP_SECRET ?? "",
|
|
61
60
|
});
|
|
62
61
|
|
|
63
|
-
// partition(Company DB)は tenant
|
|
62
|
+
// partition(Company DB)は tenant(id) で指定する(既定の Partition は無い)。単一テナントでも同じ書き方
|
|
64
63
|
const t = porters.tenant(456);
|
|
65
64
|
|
|
66
65
|
const page = await t.candidate.search({
|
|
@@ -73,7 +72,7 @@ const page = await t.candidate.search({
|
|
|
73
72
|
console.log(page.total, page.items[0]?.P_Name);
|
|
74
73
|
```
|
|
75
74
|
|
|
76
|
-
続きは[
|
|
75
|
+
続きは[導入][s-prereq](6 ページ)へ。準備・認証・読み取り・書き込み・本番に出す前の確認まで順に進みます。
|
|
77
76
|
|
|
78
77
|
## リソースと操作
|
|
79
78
|
|
|
@@ -87,46 +86,51 @@ console.log(page.total, page.items[0]?.P_Name);
|
|
|
87
86
|
| `t.opportunity` | 商談管理 | `t.phase` | フェーズ履歴 |
|
|
88
87
|
| `t.activity` | アクティビティ | | |
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
マスタ系は `porters.partition` / `t.user` / `t.department` / `t.field` / `t.option` の 5 種(読み取り専用)。
|
|
91
90
|
|
|
92
|
-
**どのメソッドが呼べるかはリソースごとに違います**(`searchAll` が無いもの、先に `of()`
|
|
93
|
-
|
|
94
|
-
[API リファレンス][api-ref]
|
|
91
|
+
**どのメソッドが呼べるかはリソースごとに違います**(`searchAll` が無いもの、先に `of("candidate")` のように
|
|
92
|
+
対象リソースを指定するもの(Field・Phase・Attachment)があります)。一覧は[リソースと操作][docs-resources]、引数・戻り値・項目の一覧は
|
|
93
|
+
[API リファレンス][api-ref]が正確な定義です。
|
|
95
94
|
|
|
96
95
|
## ドキュメント
|
|
97
96
|
|
|
98
|
-
**[docs/usage][docs-index] が目次**です。
|
|
97
|
+
**[docs/usage][docs-index] が目次**です。7 つの章に分かれていて、順に読むのは導入だけです。
|
|
99
98
|
|
|
100
|
-
|
|
|
101
|
-
| ---------------- |
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
99
|
+
| 章 | 何が書いてあるか |
|
|
100
|
+
| ---------------- | ------------------------------------------------------------------------------------------- |
|
|
101
|
+
| **導入** | 順に読む 6 ページ。準備 → インストール → 認証と疎通 → 読み → 書き → 本番前 |
|
|
102
|
+
| **主題別** | 認証・検索・書き込み・カスタム項目・上限……の 11 主題を、考え方から細かい規則まで 1 ページで |
|
|
103
|
+
| **クライアント** | `PortersClient`・`auth`・`tenant(id)` のスコープ。構築オプションと呼べるメソッド |
|
|
104
|
+
| **リソース別** | 18 リソースを 1 ページずつ。呼べるメソッド・固有の注意・必須項目・型 |
|
|
105
|
+
| **関数** | `import` して呼ぶ関数を用途別に。宣言と突合・上限と接続・値の変換 |
|
|
106
|
+
| **実践例** | 毎日の差分同期・複数テナントなど、用途に沿った組み立て |
|
|
107
|
+
| **リファレンス** | [公開 API リファレンス][api-ref](JSDoc から生成)と [PORTERS API の事実][ref] |
|
|
108
|
+
|
|
109
|
+
目次の末尾に「〜したい → 読む場所」の索引表があります。
|
|
106
110
|
|
|
107
111
|
## PORTERS 固有の注意
|
|
108
112
|
|
|
109
113
|
このライブラリを使ううえで、**PORTERS 側の前提**として先に知っておくと迷いません。詳しくは
|
|
110
|
-
|
|
114
|
+
それぞれの主題ページの「まず知ること」にあります。
|
|
111
115
|
|
|
112
|
-
- **削除 API が存在しない**。`delete()`
|
|
113
|
-
- **日時は UTC 前提**。ISO 8601(`…Z`)で入出力し、JST 等への変換はしません([
|
|
114
|
-
- **データは Partition に分かれる**。`tenant(id)`
|
|
116
|
+
- **削除 API が存在しない**。`delete()` は型の上でも用意していません([削除と削除済みデータ][c-no-delete])。
|
|
117
|
+
- **日時は UTC 前提**。ISO 8601(`…Z`)で入出力し、JST 等への変換はしません([日時と時分型][c-datetime])。
|
|
118
|
+
- **データは Partition に分かれる**。`tenant(id)` で毎回指定します([Partition とテナントスコープ][c-partition])。
|
|
115
119
|
- **上限がある**。リクエスト長 約 15000 文字・1 リクエスト 200 件・1 分あたり Read 2000 / Write 500 は
|
|
116
|
-
|
|
120
|
+
ライブラリが守りますが、**月 15 万アクセスは契約条件**で利用側の運用責務です([上限とレート][c-limits])。
|
|
117
121
|
- **ホスト名は非公開**。`PORTERS_HOST` で受け取り、ハードコードしません。
|
|
118
122
|
|
|
119
123
|
## 対応バージョン
|
|
120
124
|
|
|
121
|
-
-
|
|
122
|
-
- **PORTERS 製品 8.x / 9.x は参考**:v2
|
|
125
|
+
- **互換性の基準は Connect API Version 2**:`X-P-ConnectAPI-Version: 2` を既定で送信し、**v2 を動作の前提**とします(担当者型・部署型の参照項目(Link)などは v2 が必要)。互換性はこの **API version** で明示します。
|
|
126
|
+
- **PORTERS 製品 8.x / 9.x は参考**:v2 が提供される製品世代です(個別マイナーの動作保証はしません)。**正しい情報の出どころは [PORTERS API の事実][ref]**(PORTERS の公式ドキュメントに基づく)。
|
|
123
127
|
|
|
124
128
|
## リンク
|
|
125
129
|
|
|
126
|
-
**この README
|
|
130
|
+
**この README は「最短で動かす」ところまで**です。全体は目次から読めます<!-- 根拠: ADR-0070 -->。
|
|
127
131
|
|
|
128
|
-
- 利用者向け:[docs/usage][docs-index](目次)/[公開 API
|
|
129
|
-
- 開発・保守:[docs/README.md][docs-readme](ADR
|
|
132
|
+
- 利用者向け:[docs/usage][docs-index](目次)/[公開 API リファレンス][api-ref]/[PORTERS API の事実][ref]
|
|
133
|
+
- 開発・保守:[docs/README.md][docs-readme](ADR(設計判断の記録)・基本設計・ロードマップ・台帳)
|
|
130
134
|
- 提供元:[Joymerrevent][joymerrevent]
|
|
131
135
|
|
|
132
136
|
## コントリビュート / セキュリティ
|
|
@@ -156,15 +160,15 @@ console.log(page.total, page.items[0]?.P_Name);
|
|
|
156
160
|
[coc]: ./CODE_OF_CONDUCT.md
|
|
157
161
|
[issues]: https://github.com/Joymerrevent/porters-connect/issues
|
|
158
162
|
[api-ref]: docs/usage/api/index.md
|
|
159
|
-
[c-datetime]: docs/usage/
|
|
160
|
-
[c-limits]: docs/usage/
|
|
161
|
-
[c-no-delete]: docs/usage/
|
|
162
|
-
[c-partition]: docs/usage/
|
|
163
|
+
[c-datetime]: docs/usage/topics/datetime.md
|
|
164
|
+
[c-limits]: docs/usage/topics/limits.md
|
|
165
|
+
[c-no-delete]: docs/usage/topics/deleted.md
|
|
166
|
+
[c-partition]: docs/usage/topics/tenant.md
|
|
163
167
|
[s-auth]: docs/usage/start/authenticate.md
|
|
164
168
|
[s-cjs]: docs/usage/start/install.md#cjs-から-require-する
|
|
165
169
|
[s-prereq]: docs/usage/start/prerequisites.md
|
|
166
|
-
[test-without-contract]: docs/usage/
|
|
170
|
+
[test-without-contract]: docs/usage/topics/testing.md
|
|
167
171
|
[docs-index]: docs/usage/index.md
|
|
168
|
-
[docs-resources]: docs/usage/
|
|
172
|
+
[docs-resources]: docs/usage/resources/README.md
|
|
169
173
|
[docs-readme]: ./docs/README.md
|
|
170
174
|
[ref]: docs/usage/reference/README.md
|
package/dist/index.d.cts
CHANGED
|
@@ -1745,7 +1745,7 @@ type SalesSearchQuery = SearchQuery<typeof FIELDS$8, typeof REFERENCES$2>;
|
|
|
1745
1745
|
/**
|
|
1746
1746
|
* Fields for `create`: only `P_Owner` is unconditionally required. The six references are
|
|
1747
1747
|
* required *conditionally* (a dependency chain PORTERS validates server-side), so they stay
|
|
1748
|
-
* optional here — see docs/usage/
|
|
1748
|
+
* optional here — see docs/usage/topics/limits.md.
|
|
1749
1749
|
*/
|
|
1750
1750
|
type SalesCreateInput = CreateInput<typeof FIELDS$8, (typeof REQUIRED_ON_CREATE$3)[number]>;
|
|
1751
1751
|
/** Fields for `update`: all optional (`null` omits, `""` clears a text field). */
|
package/dist/index.d.ts
CHANGED
|
@@ -1745,7 +1745,7 @@ type SalesSearchQuery = SearchQuery<typeof FIELDS$8, typeof REFERENCES$2>;
|
|
|
1745
1745
|
/**
|
|
1746
1746
|
* Fields for `create`: only `P_Owner` is unconditionally required. The six references are
|
|
1747
1747
|
* required *conditionally* (a dependency chain PORTERS validates server-side), so they stay
|
|
1748
|
-
* optional here — see docs/usage/
|
|
1748
|
+
* optional here — see docs/usage/topics/limits.md.
|
|
1749
1749
|
*/
|
|
1750
1750
|
type SalesCreateInput = CreateInput<typeof FIELDS$8, (typeof REQUIRED_ON_CREATE$3)[number]>;
|
|
1751
1751
|
/** Fields for `update`: all optional (`null` omits, `""` clears a text field). */
|
package/dist/index.js
CHANGED
|
@@ -846,9 +846,21 @@ var decodeImage = (outer) => {
|
|
|
846
846
|
}
|
|
847
847
|
return out;
|
|
848
848
|
};
|
|
849
|
-
var
|
|
849
|
+
var numeric = (alias, type, value) => {
|
|
850
|
+
const n = Number(value);
|
|
851
|
+
if (Number.isFinite(n)) return n;
|
|
852
|
+
throw new PortersResourceError(
|
|
853
|
+
`${alias}: declared ${type}, but ${JSON.stringify(value)} is not a PORTERS ${type} value`,
|
|
854
|
+
{
|
|
855
|
+
category: "validation",
|
|
856
|
+
hint: `${type === "Link" ? "A scalar Link is a Contact id, which PORTERS sends as a plain number" : `PORTERS sends ${type} as a plain number`}. Check the Data Type declared for "${alias}" against Field Read (verifyFields).`,
|
|
857
|
+
context: { operation: "decode" }
|
|
858
|
+
}
|
|
859
|
+
);
|
|
860
|
+
};
|
|
861
|
+
var decodeLink = (raw, alias) => {
|
|
850
862
|
const scalar2 = asString(raw);
|
|
851
|
-
if (scalar2 !== void 0) return
|
|
863
|
+
if (scalar2 !== void 0) return numeric(alias, "Link", scalar2);
|
|
852
864
|
const outer = asRecord(raw);
|
|
853
865
|
if (!outer) return null;
|
|
854
866
|
if ("User" in outer) return decodeUser(outer);
|
|
@@ -889,7 +901,7 @@ var converted = (alias, type, value, convert) => {
|
|
|
889
901
|
var decodeField = (type, raw, alias) => {
|
|
890
902
|
if (raw === "" || raw === void 0 || raw === null) return null;
|
|
891
903
|
if (type === null) return asString(raw) ?? null;
|
|
892
|
-
if (type === "Link") return decodeLink(raw);
|
|
904
|
+
if (type === "Link") return decodeLink(raw, alias);
|
|
893
905
|
if (isRecordShaped(type)) {
|
|
894
906
|
const outer = asRecord(raw);
|
|
895
907
|
if (outer === void 0) throw mismatch(alias, type, "a nested record");
|
|
@@ -912,7 +924,7 @@ var decodeField = (type, raw, alias) => {
|
|
|
912
924
|
switch (scalarType) {
|
|
913
925
|
case "System[Id]":
|
|
914
926
|
case "Number":
|
|
915
|
-
return
|
|
927
|
+
return numeric(alias, scalarType, value);
|
|
916
928
|
// String Data Types share one decode (a plain string); they stay distinct
|
|
917
929
|
// labels for fidelity / future per-type validation (ADR-0016).
|
|
918
930
|
case "SinglelineText":
|
|
@@ -1578,8 +1590,8 @@ var createResource = (config, deps) => {
|
|
|
1578
1590
|
{ write: true, idempotent, ...hasImage ? { unboundedBody: true } : {} }
|
|
1579
1591
|
);
|
|
1580
1592
|
};
|
|
1581
|
-
const create = (input) => write(withDefaults({ ...input, [idAlias]: -1 }), false);
|
|
1582
|
-
const update = (id, input) => write(withDefaults({ ...input, [idAlias]: id }), true);
|
|
1593
|
+
const create = async (input) => write(withDefaults({ ...input, [idAlias]: -1 }), false);
|
|
1594
|
+
const update = async (id, input) => write(withDefaults({ ...input, [idAlias]: id }), true);
|
|
1583
1595
|
const target = {
|
|
1584
1596
|
name: config.name,
|
|
1585
1597
|
prefix: config.prefix,
|
|
@@ -2883,18 +2895,17 @@ var FIELD_TYPES = [
|
|
|
2883
2895
|
{ value: 18, dataType: "Image", label: "Image", reverse: true },
|
|
2884
2896
|
{ value: 20, dataType: "Link", label: "Link", reverse: true }
|
|
2885
2897
|
];
|
|
2886
|
-
var
|
|
2887
|
-
(
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
/* @__PURE__ */ new Map()
|
|
2893
|
-
);
|
|
2894
|
-
var BY_DATA_TYPE = FIELD_TYPES.reduce(
|
|
2898
|
+
var forwardIndex = (rows) => rows.reduce((acc, row) => {
|
|
2899
|
+
const seen = acc.get(row.value);
|
|
2900
|
+
if (seen === void 0 || row.forward === true) acc.set(row.value, row);
|
|
2901
|
+
return acc;
|
|
2902
|
+
}, /* @__PURE__ */ new Map());
|
|
2903
|
+
var reverseIndex = (rows) => rows.reduce(
|
|
2895
2904
|
(acc, row) => row.reverse === true && row.dataType !== null ? acc.set(row.dataType, row.value) : acc,
|
|
2896
2905
|
/* @__PURE__ */ new Map()
|
|
2897
2906
|
);
|
|
2907
|
+
var BY_VALUE = forwardIndex(FIELD_TYPES);
|
|
2908
|
+
var BY_DATA_TYPE = reverseIndex(FIELD_TYPES);
|
|
2898
2909
|
var dataTypeOfFieldType = (value) => BY_VALUE.get(value)?.dataType;
|
|
2899
2910
|
var fieldTypeLabel = (value) => BY_VALUE.get(value)?.label;
|
|
2900
2911
|
|