@joymerrevent/porters-connect 0.16.0 → 0.17.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 +92 -0
- package/dist/index.d.ts +85 -12
- package/dist/index.js +40 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,92 @@
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.17.0] - 2026-09-16
|
|
9
|
+
|
|
10
|
+
**添付ファイルの運び方を決め、出典に無いパラメータを型から外した版**です。**破壊的変更を 2 つ**
|
|
11
|
+
含みます(添付の本体は `get` でだけ取れる/Phase の Read から `keywords` / `itemstate` が消える)。
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`t.attachment.searchAll()`** — 200 件を超える添付を、`start` を自分で回さずに順に見られます
|
|
16
|
+
([ADR-0075][adr75])。ほかの 15 エンドポイントと同じ語彙になりました。
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
for await (const a of t.attachment.searchAll({
|
|
20
|
+
condition: { "Resource:eq": "17" },
|
|
21
|
+
})) {
|
|
22
|
+
console.log(a.fileName, a.contentType);
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
流れるのは**メタデータだけ**なので、全部を歩いてもファイル本体はダウンロードされません。
|
|
27
|
+
|
|
28
|
+
- **`createFetchTransport`** — 既定の transport を公開しました([ADR-0077][adr77])。
|
|
29
|
+
1 リクエストのタイムアウト(既定 **30 秒**)を変えられます。
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import {
|
|
33
|
+
PortersClient,
|
|
34
|
+
createFetchTransport,
|
|
35
|
+
} from "@joymerrevent/porters-connect";
|
|
36
|
+
|
|
37
|
+
const porters = new PortersClient({
|
|
38
|
+
host,
|
|
39
|
+
appId,
|
|
40
|
+
appSecret,
|
|
41
|
+
transport: createFetchTransport({ timeoutMs: 120_000 }), // 2 分
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
この 30 秒は**接続から本文の受信完了まで**で、**1 リクエストごと**に数えます(自動リトライを
|
|
46
|
+
含めると最悪 `maxRetries + 1` 倍)。レートの待ち時間は含みません。`timeoutMs` は**正の整数**だけを
|
|
47
|
+
受け、`0`(=即中断で「無制限」ではない)は構築時に `PortersConfigError` で弾きます。
|
|
48
|
+
これまで変えるには `Transport` の自前実装が必要で、`PortersNetworkError` への分類まで
|
|
49
|
+
書き直すことになっていました。
|
|
50
|
+
|
|
51
|
+
- 公開した型: `AttachmentMetaField` / `AttachmentWalkQuery` / `FetchTransportOptions`。
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- **(破壊的)添付の本体(`content`)は `get` でだけ取れます**([ADR-0075][adr75])。
|
|
56
|
+
`search` / `searchAll` の `field` に `"Content"` は書けません。
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
await t.attachment.search({ field: ["Id", "Content"] });
|
|
60
|
+
// ^^^^^^^^^ 型エラーになります
|
|
61
|
+
const file = await t.attachment.get(900); // 本体はこちら
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
1 ページは最大 200 件で、PORTERS は 1 ファイル 10MB まで許します。本体を混ぜた一覧は
|
|
65
|
+
**読める大きさを越えることがあります** — 1 ファイル 2MB 超 × 200 件で V8 の文字列上限
|
|
66
|
+
(536,870,888 文字)に当たり、`RangeError` になって再送しても直りません。しかも Attachment は
|
|
67
|
+
**ファイルサイズを返さない**ので、「何件までなら安全か」を呼び出し側が判断することもできません。
|
|
68
|
+
そこで件数ではなく**メソッド**で分けました。型を外して渡した場合も、送信前に
|
|
69
|
+
`PortersConfigError` で止まります。
|
|
70
|
+
|
|
71
|
+
- **(破壊的)Phase の Read クエリから `keywords` / `itemstate` が消えました**([ADR-0076][adr76])。
|
|
72
|
+
PORTERS の `Phase - Read` はこの 2 つを Input Variables に挙げていません。Read 記事 17 本を
|
|
73
|
+
数えると、共通語彙のデータ系 11 本は両方を載せ、**Phase / Attachment / マスタ 4 種は 1 本も
|
|
74
|
+
載せていません**(11/11 対 0/6)ので、記事側の省略ではなく**エンドポイントごとに取るものが
|
|
75
|
+
違う**と読めます。出典に無いパラメータは、無視されるのではなく **Read 全体を失敗させうる**
|
|
76
|
+
(Result Code 100 / 102)ため、型の側で閉じました。
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
await t.phase.of("client").search({ keywords: ["山田"] });
|
|
80
|
+
// ^^^^^^^^ 型エラーになります
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**実行時は変えていません**。cast すれば今までどおり送られます(契約環境で「実は受け付ける」と
|
|
84
|
+
分かったときに確かめられるように残しました)。
|
|
85
|
+
|
|
86
|
+
- **エンドポイント × 機能のマトリクスを起こしました**。PORTERS が取るものとライブラリが送るものを
|
|
87
|
+
表に並べ、**reference ↔ 表 ↔ 実装を両方向で突き合わせる検査**(94 件)を足しています。
|
|
88
|
+
ずれているセルには必ず根拠(ADR / ライブ検証)が要る形で、今回の 2 つの破壊的変更も
|
|
89
|
+
この表から出てきました。パッケージの中身は変わりません。
|
|
90
|
+
|
|
91
|
+
- **既定 30 秒のタイムアウトをドキュメントに明文化しました**([上限][limits]・[失敗の扱い][failures])。
|
|
92
|
+
これまでどこにも書かれていませんでした。パッケージの中身は変わりません。
|
|
93
|
+
|
|
8
94
|
## [0.16.0] - 2026-09-15
|
|
9
95
|
|
|
10
96
|
**カスタム項目を「宣言してから使う」に揃えた版**です。**破壊的変更**(`field` が未宣言の
|
|
@@ -798,11 +884,17 @@
|
|
|
798
884
|
[adr69]: docs/adr/0069-tenant-field-catalog-tooling.md
|
|
799
885
|
[adr73]: docs/adr/0073-throttle-sharing.md
|
|
800
886
|
[adr74]: docs/adr/0074-custom-field-declaration-required.md
|
|
887
|
+
[adr75]: docs/adr/0075-attachment-search-all.md
|
|
888
|
+
[adr76]: docs/adr/0076-phase-read-query-surface.md
|
|
889
|
+
[adr77]: docs/adr/0077-fetch-transport-timeout.md
|
|
890
|
+
[limits]: docs/usage/concepts/limits.md
|
|
891
|
+
[failures]: docs/usage/howto/handle-failures.md
|
|
801
892
|
[lv]: docs/live-verification.md
|
|
802
893
|
[ref]: docs/usage/reference/README.md
|
|
803
894
|
[kac]: https://keepachangelog.com/en/1.1.0/
|
|
804
895
|
[semver]: https://semver.org/
|
|
805
896
|
[unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.16.0...HEAD
|
|
897
|
+
[0.17.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.16.0...v0.17.0
|
|
806
898
|
[0.16.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.15.1...v0.16.0
|
|
807
899
|
[0.15.1]: https://github.com/Joymerrevent/porters-connect/compare/v0.15.0...v0.15.1
|
|
808
900
|
[0.15.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.14.0...v0.15.0
|
package/dist/index.d.ts
CHANGED
|
@@ -52,6 +52,26 @@ type PartitionId = number;
|
|
|
52
52
|
*/
|
|
53
53
|
type Scheme = "https" | "http";
|
|
54
54
|
|
|
55
|
+
type FetchTransportOptions = {
|
|
56
|
+
/**
|
|
57
|
+
* How long one request may take, in milliseconds. Default 30,000.
|
|
58
|
+
*
|
|
59
|
+
* **It covers the whole exchange** — connect, send, and reading the response body to the end —
|
|
60
|
+
* because the abort signal is handed to `fetch` itself. A large download therefore hits it even
|
|
61
|
+
* when the headers came back instantly. It is **per request**, so a retried call can take
|
|
62
|
+
* `maxRetries + 1` times this (plus backoff), and it does not include waiting for a throttle
|
|
63
|
+
* slot (throttling sits above the transport).
|
|
64
|
+
*
|
|
65
|
+
* Raise it to read large attachments over a slow link; lower it to fail fast in an interactive
|
|
66
|
+
* tool. Must be a positive integer — `0` would abort every request immediately, which reads
|
|
67
|
+
* like "no timeout" and is not (ADR-0077).
|
|
68
|
+
*/
|
|
69
|
+
timeoutMs?: number;
|
|
70
|
+
/** Injectable fetch (tests / custom dispatcher). Default global fetch. */
|
|
71
|
+
fetchImpl?: typeof fetch;
|
|
72
|
+
};
|
|
73
|
+
declare const createFetchTransport: (opts?: FetchTransportOptions) => Transport;
|
|
74
|
+
|
|
55
75
|
/** A mock reply: an XML body string (HTTP 200), or an explicit status + body. */
|
|
56
76
|
type MockReply = string | {
|
|
57
77
|
status?: number;
|
|
@@ -638,13 +658,38 @@ type UpdateInput<F extends FieldCatalog> = {
|
|
|
638
658
|
* {@link EmptyReferences}. With no keys, `ImageReadRecord` collapses back to the record it wrapped.
|
|
639
659
|
*/
|
|
640
660
|
type EmptyImages = Record<never, never>;
|
|
641
|
-
|
|
642
|
-
|
|
661
|
+
/**
|
|
662
|
+
* A query with `K` taken out — and **kept out**. `Omit` alone only stops a fresh object literal
|
|
663
|
+
* (excess-property checking); a variable that happens to carry the key still assigns. Re-declaring
|
|
664
|
+
* each removed key as `?: never` closes that hole, so `search(query)` fails whichever way the
|
|
665
|
+
* object was built. The runtime is unaffected: the key can still arrive through a cast (ADR-0074).
|
|
666
|
+
*
|
|
667
|
+
* Only the **endpoint-level** exclusions (`Unsupported`) get this treatment. `searchAll` keeps a
|
|
668
|
+
* plain `Omit` for `count` / `start`: those are not "PORTERS does not take this", they are
|
|
669
|
+
* "the walk decides them", and tightening that is a different decision from ADR-0076.
|
|
670
|
+
*/
|
|
671
|
+
type WithoutQueryKeys<Q, K extends keyof Q> = Omit<Q, K> & {
|
|
672
|
+
[P in K]?: never;
|
|
673
|
+
};
|
|
674
|
+
type Resource<F extends FieldCatalog, Req extends keyof F, R extends ReferenceMap = EmptyReferences,
|
|
675
|
+
/**
|
|
676
|
+
* Query keys **this endpoint does not take** (ADR-0076). The common Read vocabulary is not
|
|
677
|
+
* universal: PORTERS lists `keywords` / `itemstate` for the 11 common data resources and for
|
|
678
|
+
* none of the others, so a resource on this factory can say which of them its own endpoint
|
|
679
|
+
* leaves out. `never` — the default — means "takes the whole vocabulary".
|
|
680
|
+
*
|
|
681
|
+
* Sending a parameter the endpoint does not list can fail the *whole* Read (Result Code 100 /
|
|
682
|
+
* 102), so the safe side is not to offer it. The runtime stays permissive (ADR-0074): a key
|
|
683
|
+
* forced in through a cast is still sent, which is how a live contract can test whether
|
|
684
|
+
* PORTERS accepts it at all.
|
|
685
|
+
*/
|
|
686
|
+
Unsupported extends keyof SearchQuery<F, R> = never> = {
|
|
687
|
+
search<const E extends Expand<R> = EmptyReferences, const I extends ImageOption<F> = EmptyImages>(query?: WithoutQueryKeys<SearchQuery<F, R>, Unsupported> & {
|
|
643
688
|
expand?: E;
|
|
644
689
|
image?: I;
|
|
645
690
|
}): Promise<ResourcePageOf<ImageReadRecord<ExpandedReadRecord<F, R, E>, I>>>;
|
|
646
691
|
/** Auto-paginating search: yields every matching record (200 per page). */
|
|
647
|
-
searchAll<const E extends Expand<R> = EmptyReferences, const I extends ImageOption<F> = EmptyImages>(query?: Omit<SearchQuery<F, R>, "count" | "start"> & {
|
|
692
|
+
searchAll<const E extends Expand<R> = EmptyReferences, const I extends ImageOption<F> = EmptyImages>(query?: Omit<WithoutQueryKeys<SearchQuery<F, R>, Unsupported>, "count" | "start"> & {
|
|
648
693
|
expand?: E;
|
|
649
694
|
image?: I;
|
|
650
695
|
}): AsyncIterable<ImageReadRecord<ExpandedReadRecord<F, R, E>, I>>;
|
|
@@ -1734,13 +1779,23 @@ declare const REQUIRED_ON_CREATE$2: readonly ["ResourceId"];
|
|
|
1734
1779
|
/** A decoded Phase entry: known aliases, each requested field `value | null`. */
|
|
1735
1780
|
type Phase = ReadRecord<typeof FIELDS$6>;
|
|
1736
1781
|
type PhasePage = ResourcePage<typeof FIELDS$6>;
|
|
1737
|
-
type
|
|
1782
|
+
type PhaseUnsupportedQuery = "keywords" | "itemstate";
|
|
1783
|
+
/**
|
|
1784
|
+
* Phase's Read query: the common vocabulary **minus `keywords` / `itemstate`**, which
|
|
1785
|
+
* `Phase - Read` does not list (ADR-0076).
|
|
1786
|
+
*/
|
|
1787
|
+
type PhaseSearchQuery = Omit<SearchQuery<typeof FIELDS$6>, PhaseUnsupportedQuery> & {
|
|
1788
|
+
[K in PhaseUnsupportedQuery]?: never;
|
|
1789
|
+
};
|
|
1738
1790
|
/** Fields for `create`: `ResourceId` required (`Id` and `Resource` are supplied for you). */
|
|
1739
1791
|
type PhaseCreateInput = CreateInput<typeof FIELDS$6, (typeof REQUIRED_ON_CREATE$2)[number]>;
|
|
1740
1792
|
/** Fields for `update`: all optional (`null` omits, `""` clears a text field). */
|
|
1741
1793
|
type PhaseUpdateInput = UpdateInput<typeof FIELDS$6>;
|
|
1742
|
-
/**
|
|
1743
|
-
|
|
1794
|
+
/**
|
|
1795
|
+
* The Phase accessor for one bound resource — the same shape as every other resource, except that
|
|
1796
|
+
* `search` / `searchAll` do not take `keywords` / `itemstate` (ADR-0076).
|
|
1797
|
+
*/
|
|
1798
|
+
type PhaseResource = Resource<typeof FIELDS$6, (typeof REQUIRED_ON_CREATE$2)[number], EmptyReferences, PhaseUnsupportedQuery>;
|
|
1744
1799
|
/**
|
|
1745
1800
|
* Phase is reached through the resource whose history you want (ADR-0061 案2a):
|
|
1746
1801
|
*
|
|
@@ -2188,6 +2243,11 @@ type ResumeUpdateInput = UpdateInput<typeof FIELDS$4>;
|
|
|
2188
2243
|
/** The Resume accessor; `C` is the declared custom-field catalog merged on (ADR-0023). */
|
|
2189
2244
|
type ResumeResource<C extends FieldCatalog = EmptyCatalog> = Resource<typeof FIELDS$4 & C, (typeof REQUIRED_ON_CREATE)[number], typeof REFERENCES>;
|
|
2190
2245
|
|
|
2246
|
+
/**
|
|
2247
|
+
* Every Attachment field **except** the body: what a listing may ask for (ADR-0075).
|
|
2248
|
+
* These are the aliases `search` / `searchAll` accept.
|
|
2249
|
+
*/
|
|
2250
|
+
type AttachmentMetaField = "Id" | "Resource" | "ResourceId" | "ContentType" | "FileName";
|
|
2191
2251
|
/** A decoded Attachment. A field is `null` unless it was returned (see `field`). */
|
|
2192
2252
|
type Attachment = {
|
|
2193
2253
|
id: number | null;
|
|
@@ -2208,16 +2268,19 @@ type AttachmentPage = {
|
|
|
2208
2268
|
};
|
|
2209
2269
|
type AttachmentSearchQuery = {
|
|
2210
2270
|
/**
|
|
2211
|
-
* Output fields
|
|
2212
|
-
* ContentType / FileName)
|
|
2213
|
-
*
|
|
2214
|
-
*
|
|
2271
|
+
* Output fields — **metadata only**. Omit for all five (Id / Resource / ResourceId /
|
|
2272
|
+
* ContentType / FileName), or pass `[]` for the API-native primary-key-only response.
|
|
2273
|
+
*
|
|
2274
|
+
* The file body is **not** on this list: a listing never carries it, whatever the count
|
|
2275
|
+
* (ADR-0075). Read a body with {@link AttachmentResource.get}, one record at a time.
|
|
2215
2276
|
*/
|
|
2216
|
-
field?:
|
|
2277
|
+
field?: AttachmentMetaField[];
|
|
2217
2278
|
condition?: Record<string, string>;
|
|
2218
2279
|
count?: number;
|
|
2219
2280
|
start?: number;
|
|
2220
2281
|
};
|
|
2282
|
+
/** A walking Read: `count` / `start` are the walk's to decide. */
|
|
2283
|
+
type AttachmentWalkQuery = Omit<AttachmentSearchQuery, "count" | "start">;
|
|
2221
2284
|
/** Fields for creating an Attachment. `content` is the Base64 file body. */
|
|
2222
2285
|
type AttachmentCreate = {
|
|
2223
2286
|
resource: number;
|
|
@@ -2234,6 +2297,16 @@ type AttachmentUpdate = {
|
|
|
2234
2297
|
};
|
|
2235
2298
|
type AttachmentResource = {
|
|
2236
2299
|
search(query?: AttachmentSearchQuery): Promise<AttachmentPage>;
|
|
2300
|
+
/**
|
|
2301
|
+
* Auto-paginating search: yields every matching attachment (200 per page). Metadata only —
|
|
2302
|
+
* the body stays behind {@link AttachmentResource.get} (ADR-0075), so walking every attachment
|
|
2303
|
+
* in a partition never drags the files along with it.
|
|
2304
|
+
*/
|
|
2305
|
+
searchAll(query?: AttachmentWalkQuery): AsyncIterable<Attachment>;
|
|
2306
|
+
/**
|
|
2307
|
+
* Read one attachment **with its body** (`content`). This is the only method that carries it:
|
|
2308
|
+
* one record at a time is a size PORTERS' own 10MB-per-file limit keeps readable (ADR-0075).
|
|
2309
|
+
*/
|
|
2237
2310
|
get(id: number): Promise<Attachment | undefined>;
|
|
2238
2311
|
/** Create an Attachment; resolves to the newly assigned id. */
|
|
2239
2312
|
create(input: AttachmentCreate): Promise<number>;
|
|
@@ -2827,4 +2900,4 @@ declare const bytesToBase64: (bytes: Uint8Array) => string;
|
|
|
2827
2900
|
/** Decode a Base64 string back to raw bytes. */
|
|
2828
2901
|
declare const base64ToBytes: (b64: string) => Uint8Array;
|
|
2829
2902
|
|
|
2830
|
-
export { type Activity, type ActivityCreateInput, type ActivityPage, type ActivityResource, type ActivitySearchQuery, type ActivityUpdateInput, type Attachment, type AttachmentCreate, type AttachmentPage, type AttachmentResource, type AttachmentSearchQuery, type AttachmentUpdate, 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 DefinedFields, type DepartmentRef, type ErrorCategory, type Expand, type ExpandedReadRecord, type Field, type FieldBuilder, type FieldCatalogSource, type FieldDecls, type FieldDef, type FieldPage, type FieldResource, type FieldSearchQuery, type FieldTypeMismatch, type FieldValue, type FieldVerification, type GenerateFieldDeclsOptions, type GetAccessTokenOptions, type ImageContentType, type ImageOption, type ImageReadRecord, type ImageSelectedValue, type ImageSubField, type ImageValue, type ImageWriteValue, 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 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 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, createMockTransport, createThrottle, defineFields, generateFieldDecls, rawValue, readCustomCatalog, verifyFields };
|
|
2903
|
+
export { type Activity, type ActivityCreateInput, type ActivityPage, type ActivityResource, type ActivitySearchQuery, type ActivityUpdateInput, type Attachment, type AttachmentCreate, type AttachmentMetaField, 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 DefinedFields, type DepartmentRef, type ErrorCategory, type Expand, type ExpandedReadRecord, type FetchTransportOptions, type Field, type FieldBuilder, type FieldCatalogSource, type FieldDecls, type FieldDef, type FieldPage, type FieldResource, type FieldSearchQuery, type FieldTypeMismatch, type FieldValue, type FieldVerification, type GenerateFieldDeclsOptions, type GetAccessTokenOptions, type ImageContentType, type ImageOption, type ImageReadRecord, type ImageSelectedValue, type ImageSubField, type ImageValue, type ImageWriteValue, 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 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 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, defineFields, generateFieldDecls, rawValue, readCustomCatalog, verifyFields };
|
package/dist/index.js
CHANGED
|
@@ -185,9 +185,19 @@ var processWarner = createInsecureSchemeWarner();
|
|
|
185
185
|
var warnIfInsecureScheme = (scheme, host) => processWarner.warn(scheme, host);
|
|
186
186
|
|
|
187
187
|
// src/http/fetch-transport.ts
|
|
188
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
188
189
|
var createFetchTransport = (opts = {}) => {
|
|
189
190
|
const doFetch = opts.fetchImpl ?? fetch;
|
|
190
|
-
const timeoutMs = opts.timeoutMs ??
|
|
191
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
192
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
|
|
193
|
+
throw new PortersConfigError(
|
|
194
|
+
`timeoutMs must be a positive integer, got ${JSON.stringify(opts.timeoutMs)}`,
|
|
195
|
+
{
|
|
196
|
+
category: "config",
|
|
197
|
+
hint: `Pass milliseconds (default ${DEFAULT_TIMEOUT_MS}). Raise it for large attachments; there is no "no timeout" value.`
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}
|
|
191
201
|
return {
|
|
192
202
|
send: async (req) => {
|
|
193
203
|
try {
|
|
@@ -2161,21 +2171,16 @@ var createPhaseAccessor = (deps) => ({
|
|
|
2161
2171
|
// src/resources/attachment.ts
|
|
2162
2172
|
var MAX_CONTENT_CHARS = 14e6;
|
|
2163
2173
|
var ATTACHMENT_RESOURCE = "Attachment";
|
|
2164
|
-
var
|
|
2165
|
-
|
|
2166
|
-
"Resource",
|
|
2167
|
-
"ResourceId",
|
|
2168
|
-
"ContentType",
|
|
2169
|
-
"FileName",
|
|
2170
|
-
"Content"
|
|
2171
|
-
];
|
|
2172
|
-
var DEFAULT_FIELDS = [
|
|
2174
|
+
var CONTENT = "Content";
|
|
2175
|
+
var META_FIELDS = [
|
|
2173
2176
|
"Id",
|
|
2174
2177
|
"Resource",
|
|
2175
2178
|
"ResourceId",
|
|
2176
2179
|
"ContentType",
|
|
2177
2180
|
"FileName"
|
|
2178
2181
|
];
|
|
2182
|
+
var ATTACHMENT_FIELD_NAMES = [...META_FIELDS, CONTENT];
|
|
2183
|
+
var DEFAULT_FIELDS = META_FIELDS;
|
|
2179
2184
|
var buildAttachmentReadUrl = (accessPoint, partition, q) => {
|
|
2180
2185
|
const p = new URLSearchParams();
|
|
2181
2186
|
p.set("partition", String(partition));
|
|
@@ -2200,6 +2205,16 @@ var decodeAttachment = (item) => ({
|
|
|
2200
2205
|
content: asString(item.Content) ?? null
|
|
2201
2206
|
});
|
|
2202
2207
|
var tag = (name, value) => `<${name}>${encodeField("SinglelineText", String(value), name)}</${name}>`;
|
|
2208
|
+
var guardNoContentInListing = (field, method) => {
|
|
2209
|
+
if (field?.includes(CONTENT) !== true) return;
|
|
2210
|
+
throw new PortersConfigError(
|
|
2211
|
+
`${method} cannot request "${CONTENT}": a listing never carries the file body`,
|
|
2212
|
+
{
|
|
2213
|
+
category: "config",
|
|
2214
|
+
hint: "Read the body one record at a time with get(id); search/searchAll return metadata (fileName, contentType, \u2026)."
|
|
2215
|
+
}
|
|
2216
|
+
);
|
|
2217
|
+
};
|
|
2203
2218
|
var guardContent = (content) => {
|
|
2204
2219
|
if (content !== void 0 && content.length > MAX_CONTENT_CHARS) {
|
|
2205
2220
|
throw new PortersConfigError(
|
|
@@ -2209,13 +2224,10 @@ var guardContent = (content) => {
|
|
|
2209
2224
|
}
|
|
2210
2225
|
};
|
|
2211
2226
|
var createAttachmentResource = (deps) => {
|
|
2212
|
-
const
|
|
2227
|
+
const read = (params) => deps.requester.request(
|
|
2213
2228
|
{
|
|
2214
2229
|
method: "GET",
|
|
2215
|
-
url: buildAttachmentReadUrl(deps.accessPoint, deps.partition,
|
|
2216
|
-
...query,
|
|
2217
|
-
field: query.field ?? DEFAULT_FIELDS
|
|
2218
|
-
}),
|
|
2230
|
+
url: buildAttachmentReadUrl(deps.accessPoint, deps.partition, params),
|
|
2219
2231
|
headers: {}
|
|
2220
2232
|
},
|
|
2221
2233
|
(body) => {
|
|
@@ -2228,8 +2240,18 @@ var createAttachmentResource = (deps) => {
|
|
|
2228
2240
|
};
|
|
2229
2241
|
}
|
|
2230
2242
|
);
|
|
2243
|
+
const search = async (query = {}) => {
|
|
2244
|
+
guardNoContentInListing(query.field, "search");
|
|
2245
|
+
return read({ ...query, field: query.field ?? DEFAULT_FIELDS });
|
|
2246
|
+
};
|
|
2247
|
+
const searchAll = (query = {}) => paginateOnce(() => {
|
|
2248
|
+
guardNoContentInListing(query.field, "searchAll");
|
|
2249
|
+
const field = query.field ?? DEFAULT_FIELDS;
|
|
2250
|
+
const condition = query.condition;
|
|
2251
|
+
return (count, start) => read({ field, condition, count, start });
|
|
2252
|
+
});
|
|
2231
2253
|
const get = async (id) => {
|
|
2232
|
-
const page = await
|
|
2254
|
+
const page = await read({
|
|
2233
2255
|
field: ATTACHMENT_FIELD_NAMES,
|
|
2234
2256
|
condition: { "Id:eq": String(id) },
|
|
2235
2257
|
count: 1
|
|
@@ -2261,7 +2283,7 @@ var createAttachmentResource = (deps) => {
|
|
|
2261
2283
|
if (input.content !== void 0) inner += tag("Content", input.content);
|
|
2262
2284
|
return write(inner, true);
|
|
2263
2285
|
};
|
|
2264
|
-
return { search, get, create, update };
|
|
2286
|
+
return { search, searchAll, get, create, update };
|
|
2265
2287
|
};
|
|
2266
2288
|
|
|
2267
2289
|
// src/resources/partition.ts
|
|
@@ -2918,6 +2940,7 @@ export {
|
|
|
2918
2940
|
assertFieldsMatch,
|
|
2919
2941
|
base64ToBytes,
|
|
2920
2942
|
bytesToBase64,
|
|
2943
|
+
createFetchTransport,
|
|
2921
2944
|
createMockTransport,
|
|
2922
2945
|
createThrottle,
|
|
2923
2946
|
defineFields,
|