monday-cli 0.7.1 → 0.8.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 +249 -49
- package/README.md +87 -45
- package/dist/api/assets.d.ts +3 -3
- package/dist/api/column-types.d.ts +14 -7
- package/dist/api/column-types.d.ts.map +1 -1
- package/dist/api/column-types.js +14 -7
- package/dist/api/column-types.js.map +1 -1
- package/dist/api/error-decoration.d.ts +124 -0
- package/dist/api/error-decoration.d.ts.map +1 -0
- package/dist/api/error-decoration.js +161 -0
- package/dist/api/error-decoration.js.map +1 -0
- package/dist/api/fetch-transport-helpers.d.ts +97 -0
- package/dist/api/fetch-transport-helpers.d.ts.map +1 -0
- package/dist/api/fetch-transport-helpers.js +175 -0
- package/dist/api/fetch-transport-helpers.js.map +1 -0
- package/dist/api/file-column-set.d.ts +388 -82
- package/dist/api/file-column-set.d.ts.map +1 -1
- package/dist/api/file-column-set.js +466 -88
- package/dist/api/file-column-set.js.map +1 -1
- package/dist/api/multipart-transport.d.ts +95 -60
- package/dist/api/multipart-transport.d.ts.map +1 -1
- package/dist/api/multipart-transport.js +102 -120
- package/dist/api/multipart-transport.js.map +1 -1
- package/dist/api/transport.d.ts.map +1 -1
- package/dist/api/transport.js +2 -99
- package/dist/api/transport.js.map +1 -1
- package/dist/cli/program.js +1 -1
- package/dist/cli/program.js.map +1 -1
- package/dist/commands/auth/login.js +1 -1
- package/dist/commands/auth/login.js.map +1 -1
- package/dist/commands/auth/logout.js +1 -1
- package/dist/commands/auth/logout.js.map +1 -1
- package/dist/commands/board/column-create.d.ts +20 -2
- package/dist/commands/board/column-create.d.ts.map +1 -1
- package/dist/commands/board/column-create.js +191 -20
- package/dist/commands/board/column-create.js.map +1 -1
- package/dist/commands/completion.js +1 -1
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/dev/configure.js +1 -1
- package/dist/commands/dev/configure.js.map +1 -1
- package/dist/commands/dev/discover.js +1 -1
- package/dist/commands/dev/discover.js.map +1 -1
- package/dist/commands/dev/doctor.js +1 -1
- package/dist/commands/dev/doctor.js.map +1 -1
- package/dist/commands/dev/epic/items.js +2 -2
- package/dist/commands/dev/epic/items.js.map +1 -1
- package/dist/commands/dev/epic/list.js +2 -2
- package/dist/commands/dev/epic/list.js.map +1 -1
- package/dist/commands/dev/release/list.js +2 -2
- package/dist/commands/dev/release/list.js.map +1 -1
- package/dist/commands/dev/sprint/current.js +2 -2
- package/dist/commands/dev/sprint/current.js.map +1 -1
- package/dist/commands/dev/sprint/items.js +2 -2
- package/dist/commands/dev/sprint/items.js.map +1 -1
- package/dist/commands/dev/sprint/list.js +2 -2
- package/dist/commands/dev/sprint/list.js.map +1 -1
- package/dist/commands/dev/task/block.js +2 -2
- package/dist/commands/dev/task/block.js.map +1 -1
- package/dist/commands/dev/task/done.js +2 -2
- package/dist/commands/dev/task/done.js.map +1 -1
- package/dist/commands/dev/task/list.js +2 -2
- package/dist/commands/dev/task/list.js.map +1 -1
- package/dist/commands/dev/task/start.js +2 -2
- package/dist/commands/dev/task/start.js.map +1 -1
- package/dist/commands/doc/get.js +1 -1
- package/dist/commands/doc/get.js.map +1 -1
- package/dist/commands/doc/list.js +1 -1
- package/dist/commands/doc/list.js.map +1 -1
- package/dist/commands/item/clear.d.ts.map +1 -1
- package/dist/commands/item/clear.js +15 -41
- package/dist/commands/item/clear.js.map +1 -1
- package/dist/commands/item/create.d.ts +93 -1
- package/dist/commands/item/create.d.ts.map +1 -1
- package/dist/commands/item/create.js +474 -53
- package/dist/commands/item/create.js.map +1 -1
- package/dist/commands/item/search.js +7 -7
- package/dist/commands/item/search.js.map +1 -1
- package/dist/commands/item/set.d.ts +1 -0
- package/dist/commands/item/set.d.ts.map +1 -1
- package/dist/commands/item/set.js +94 -1
- package/dist/commands/item/set.js.map +1 -1
- package/dist/commands/item/time-track/start.js +2 -2
- package/dist/commands/item/time-track/start.js.map +1 -1
- package/dist/commands/item/time-track/stop.js +2 -2
- package/dist/commands/item/time-track/stop.js.map +1 -1
- package/dist/commands/item/update.d.ts +128 -11
- package/dist/commands/item/update.d.ts.map +1 -1
- package/dist/commands/item/update.js +784 -82
- package/dist/commands/item/update.js.map +1 -1
- package/dist/commands/item/upload.js +5 -5
- package/dist/commands/item/upload.js.map +1 -1
- package/dist/commands/item/watch.js +2 -2
- package/dist/commands/item/watch.js.map +1 -1
- package/dist/commands/notification/send.js +1 -1
- package/dist/commands/notification/send.js.map +1 -1
- package/dist/commands/update/body-source.d.ts +38 -0
- package/dist/commands/update/body-source.d.ts.map +1 -0
- package/dist/commands/update/body-source.js +80 -0
- package/dist/commands/update/body-source.js.map +1 -0
- package/dist/commands/update/upload.js +3 -3
- package/dist/commands/update/upload.js.map +1 -1
- package/dist/commands/user/team-add-members.js +1 -1
- package/dist/commands/user/team-add-members.js.map +1 -1
- package/dist/commands/user/team-create.js +1 -1
- package/dist/commands/user/team-create.js.map +1 -1
- package/dist/commands/user/team-remove-members.js +1 -1
- package/dist/commands/user/team-remove-members.js.map +1 -1
- package/dist/commands/webhook/create.js +1 -1
- package/dist/commands/webhook/create.js.map +1 -1
- package/dist/commands/webhook/delete.js +1 -1
- package/dist/commands/webhook/delete.js.map +1 -1
- package/dist/commands/webhook/list.js +1 -1
- package/dist/commands/webhook/list.js.map +1 -1
- package/dist/utils/file-source.d.ts +109 -0
- package/dist/utils/file-source.d.ts.map +1 -1
- package/dist/utils/file-source.js +123 -0
- package/dist/utils/file-source.js.map +1 -1
- package/dist/utils/output/table.d.ts +7 -6
- package/dist/utils/output/table.d.ts.map +1 -1
- package/dist/utils/output/table.js +32 -5
- package/dist/utils/output/table.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutation-path catch-arm error decoration helpers
|
|
3
|
+
* (`docs/v0.8-plan.md` §3 "v0.8 refactor cluster" + §22 R-v0.7-NEW-5 /
|
|
4
|
+
* R-v0.8-NEW-6; full pattern detail in `docs/v0.7-plan.md` §22
|
|
5
|
+
* R-v0.7-NEW-5).
|
|
6
|
+
*
|
|
7
|
+
* **Status: SHIPPED at the v0.8 refactor-cluster IMPL.** Both runtime
|
|
8
|
+
* bodies below replace the pre-flight c8-ignored stub throws; the 7
|
|
9
|
+
* inline sites (4 `reThrowDecorated`, 3 `projectCauseForEnvelope`) now
|
|
10
|
+
* delegate the lifted surface, and the focused unit suite
|
|
11
|
+
* (`tests/unit/api/error-decoration.test.ts`) drives the coverage
|
|
12
|
+
* ratchet (the conditional-spread arms that previously dragged
|
|
13
|
+
* `item/update.ts` to ~80%). This was a pure internal lift — no probe,
|
|
14
|
+
* no new ERROR_CODES, no cli-design section, no new command,
|
|
15
|
+
* byte-for-byte behaviour-preserving at every site. The pre-flight
|
|
16
|
+
* shape mirrored v0.6-M38 `file-column-set.ts` (stub-then-IMPL, minus
|
|
17
|
+
* the wire/argv surface); R-NEW-76's parseArgv-BEFORE-c8 boundary rule
|
|
18
|
+
* did NOT apply here because the helpers have no argv surface.
|
|
19
|
+
*
|
|
20
|
+
* **Why a dedicated cluster (not folded into a feature milestone).**
|
|
21
|
+
* `reThrowDecorated` spans 4 unrelated mutation paths (item-clear-bulk
|
|
22
|
+
* / JSON-bulk / M42 file-bulk / M46 file-bulk-multi) — too broad to
|
|
23
|
+
* ride one feature's IMPL, and 3 of the 4 are unrelated to M47/M48's
|
|
24
|
+
* feature work. The lift landed ahead of M47 specifically so the
|
|
25
|
+
* fail-fast scaffold was consolidated BEFORE M47 would add a 5th touch.
|
|
26
|
+
*
|
|
27
|
+
* ---
|
|
28
|
+
*
|
|
29
|
+
* ## R-v0.7-NEW-5 — `reThrowDecorated` (fail-fast-scaffold lift)
|
|
30
|
+
*
|
|
31
|
+
* The post-`foldAndRemap` typed split-and-rebuild is byte-identical
|
|
32
|
+
* across **4 consumers**:
|
|
33
|
+
*
|
|
34
|
+
* 1. item-clear-bulk `src/commands/item/clear.ts` (the c8-ignored arms)
|
|
35
|
+
* 2. JSON-bulk `src/commands/item/update.ts` (per-item fail-fast)
|
|
36
|
+
* 3. M42 file-bulk `src/commands/item/update.ts` (`runItemUpdateBulkFileDispatch`)
|
|
37
|
+
* 4. M46 file-bulk-multi `src/commands/item/update.ts` (multi-file bulk)
|
|
38
|
+
*
|
|
39
|
+
* **LIFTED (the invariant):** the typed split —
|
|
40
|
+
* `if (remapped.code === 'usage_error') → new UsageError(...)`
|
|
41
|
+
* `else → new ApiError(remapped.code, ...)` — with the 5
|
|
42
|
+
* conditional-spread metadata arms (`cause` on both arms;
|
|
43
|
+
* `httpStatus` / `mondayCode` / `requestId` / `retryAfterSeconds`
|
|
44
|
+
* plus the unconditional `retryable: remapped.retryable` on the
|
|
45
|
+
* ApiError arm). These spreads were the uncovered branches that
|
|
46
|
+
* dragged `item/update.ts` to 79.42% — consolidating them into ONE
|
|
47
|
+
* helper + ONE focused unit test recovered the margin (the 4-path
|
|
48
|
+
* ratchet; `item/update.ts` branches 79.42% → 87.27%).
|
|
49
|
+
*
|
|
50
|
+
* **STAYS INLINE (the over-fit boundary — each site's own work):** the
|
|
51
|
+
* `foldAndRemap` call, `const existing = remapped.details ?? {}`, and
|
|
52
|
+
* the per-site decoration object built from `existing` + the
|
|
53
|
+
* site-specific slots (`applied_count` / `applied_to` /
|
|
54
|
+
* `failed_at_item` / `matched_count` shared by all 4; plus
|
|
55
|
+
* `applied_file_columns_per_item` / `failed_file_column` /
|
|
56
|
+
* `file_count` / `file_column_ids` on the M46-multi site). Each site
|
|
57
|
+
* assembles its own `details` record, then delegates the typed split.
|
|
58
|
+
*
|
|
59
|
+
* ## R-v0.8-NEW-6 — `projectCauseForEnvelope` (cause-projection builder)
|
|
60
|
+
*
|
|
61
|
+
* Adjacent, bundled (both live in mutation-path catch arms) but a
|
|
62
|
+
* SEPARATE helper — NOT merged into `reThrowDecorated`. Recurs across
|
|
63
|
+
* **3 orphan-warn sites**:
|
|
64
|
+
*
|
|
65
|
+
* 1. M43 create-time leg-2 `src/commands/item/create.ts` (`create_then_file_upload_partial_failure`)
|
|
66
|
+
* 2. M46 create-time multi `src/commands/item/create.ts` (same + `applied_file_columns`)
|
|
67
|
+
* 3. M46 single-item multi `src/commands/item/update.ts` (`multi_file_update_partial_failure`)
|
|
68
|
+
*
|
|
69
|
+
* **LIFTED:** ONLY the ~4-line projection builder — seed
|
|
70
|
+
* `{ code, message }` from the (already-remapped, or raw-`MondayCliError`)
|
|
71
|
+
* error, then conditionally attach `details`. (At the two create
|
|
72
|
+
* sites the `if (err.details !== undefined)` arm was c8-ignored as
|
|
73
|
+
* defensive while inlined; the builder's own unit test now drives
|
|
74
|
+
* both a details-present and a details-absent error, so this lift
|
|
75
|
+
* dropped those c8-ignore directives and genuinely covers both arms.)
|
|
76
|
+
*
|
|
77
|
+
* **STAYS INLINE (why this is structurally distinct from
|
|
78
|
+
* `reThrowDecorated`, not the same lift):** the surrounding
|
|
79
|
+
* orphan-warn decoration diverges per site — the outer code is ALWAYS
|
|
80
|
+
* `internal_error` (not the preserved remapped code), the
|
|
81
|
+
* `details.reason` literal differs, the decoration slots differ
|
|
82
|
+
* (`created_item_id` vs `item_id`; `applied_file_columns` present on
|
|
83
|
+
* the M46 sites), and the hint text differs. The genuinely-shared
|
|
84
|
+
* surface is JUST the projection builder. Merging the two helpers
|
|
85
|
+
* would force parameterising outer-code policy + decoration shape +
|
|
86
|
+
* cause-projection-vs-in-place-merge, collapsing each helper's value
|
|
87
|
+
* to "shared `foldAndRemap` call site" (already factored). See
|
|
88
|
+
* `docs/v0.7-plan.md` §22 R-v0.7-NEW-5 "M43 IMPL outcome" for the
|
|
89
|
+
* full distinctness argument.
|
|
90
|
+
*/
|
|
91
|
+
import { type MondayCliError } from '../utils/errors.js';
|
|
92
|
+
/**
|
|
93
|
+
* Re-throws a `foldAndRemap`-decorated bulk/fail-fast error, rebuilding
|
|
94
|
+
* it as the right typed class with its wire metadata preserved.
|
|
95
|
+
*
|
|
96
|
+
* The caller has already folded resolver-warnings + applied the
|
|
97
|
+
* `validation_failed → column_archived` stale-cache remap, and has
|
|
98
|
+
* assembled the full `details` decoration (its `...existing` spread
|
|
99
|
+
* plus the per-site progress slots). This helper owns ONLY the typed
|
|
100
|
+
* split: `usage_error` rebuilds as {@link UsageError}; any other code
|
|
101
|
+
* rebuilds as {@link ApiError} preserving the wire metadata
|
|
102
|
+
* (`httpStatus` / `mondayCode` / `requestId` / `retryAfterSeconds` /
|
|
103
|
+
* `retryable`) via conditional spreads. Always throws — return type is
|
|
104
|
+
* `never` so callers don't need a trailing unreachable statement.
|
|
105
|
+
*
|
|
106
|
+
* @param remapped the post-`foldAndRemap` error whose typed code +
|
|
107
|
+
* wire metadata drive the rebuild
|
|
108
|
+
* @param details the fully-assembled decoration record (already
|
|
109
|
+
* including the `...existing` spread of `remapped.details`)
|
|
110
|
+
*/
|
|
111
|
+
export declare function reThrowDecorated(remapped: MondayCliError, details: Record<string, unknown>): never;
|
|
112
|
+
/**
|
|
113
|
+
* Builds the JSON `details.cause` projection for an orphan-warn
|
|
114
|
+
* envelope: a `{ code, message }` seed plus an optional `details`
|
|
115
|
+
* passthrough. The surrounding always-`internal_error` wrap +
|
|
116
|
+
* `details.reason` discriminator + hint text stay inline at each call
|
|
117
|
+
* site (they diverge); this owns only the shared projection shape.
|
|
118
|
+
*
|
|
119
|
+
* @param err the (remapped, or raw) `MondayCliError` whose surface is
|
|
120
|
+
* projected into the agent-inspectable `details.cause` slot
|
|
121
|
+
* @returns the projection record for embedding under `details.cause`
|
|
122
|
+
*/
|
|
123
|
+
export declare function projectCauseForEnvelope(err: MondayCliError): Record<string, unknown>;
|
|
124
|
+
//# sourceMappingURL=error-decoration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-decoration.d.ts","sourceRoot":"","sources":["../../src/api/error-decoration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AAEH,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,KAAK,CAwBP;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,cAAc,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutation-path catch-arm error decoration helpers
|
|
3
|
+
* (`docs/v0.8-plan.md` §3 "v0.8 refactor cluster" + §22 R-v0.7-NEW-5 /
|
|
4
|
+
* R-v0.8-NEW-6; full pattern detail in `docs/v0.7-plan.md` §22
|
|
5
|
+
* R-v0.7-NEW-5).
|
|
6
|
+
*
|
|
7
|
+
* **Status: SHIPPED at the v0.8 refactor-cluster IMPL.** Both runtime
|
|
8
|
+
* bodies below replace the pre-flight c8-ignored stub throws; the 7
|
|
9
|
+
* inline sites (4 `reThrowDecorated`, 3 `projectCauseForEnvelope`) now
|
|
10
|
+
* delegate the lifted surface, and the focused unit suite
|
|
11
|
+
* (`tests/unit/api/error-decoration.test.ts`) drives the coverage
|
|
12
|
+
* ratchet (the conditional-spread arms that previously dragged
|
|
13
|
+
* `item/update.ts` to ~80%). This was a pure internal lift — no probe,
|
|
14
|
+
* no new ERROR_CODES, no cli-design section, no new command,
|
|
15
|
+
* byte-for-byte behaviour-preserving at every site. The pre-flight
|
|
16
|
+
* shape mirrored v0.6-M38 `file-column-set.ts` (stub-then-IMPL, minus
|
|
17
|
+
* the wire/argv surface); R-NEW-76's parseArgv-BEFORE-c8 boundary rule
|
|
18
|
+
* did NOT apply here because the helpers have no argv surface.
|
|
19
|
+
*
|
|
20
|
+
* **Why a dedicated cluster (not folded into a feature milestone).**
|
|
21
|
+
* `reThrowDecorated` spans 4 unrelated mutation paths (item-clear-bulk
|
|
22
|
+
* / JSON-bulk / M42 file-bulk / M46 file-bulk-multi) — too broad to
|
|
23
|
+
* ride one feature's IMPL, and 3 of the 4 are unrelated to M47/M48's
|
|
24
|
+
* feature work. The lift landed ahead of M47 specifically so the
|
|
25
|
+
* fail-fast scaffold was consolidated BEFORE M47 would add a 5th touch.
|
|
26
|
+
*
|
|
27
|
+
* ---
|
|
28
|
+
*
|
|
29
|
+
* ## R-v0.7-NEW-5 — `reThrowDecorated` (fail-fast-scaffold lift)
|
|
30
|
+
*
|
|
31
|
+
* The post-`foldAndRemap` typed split-and-rebuild is byte-identical
|
|
32
|
+
* across **4 consumers**:
|
|
33
|
+
*
|
|
34
|
+
* 1. item-clear-bulk `src/commands/item/clear.ts` (the c8-ignored arms)
|
|
35
|
+
* 2. JSON-bulk `src/commands/item/update.ts` (per-item fail-fast)
|
|
36
|
+
* 3. M42 file-bulk `src/commands/item/update.ts` (`runItemUpdateBulkFileDispatch`)
|
|
37
|
+
* 4. M46 file-bulk-multi `src/commands/item/update.ts` (multi-file bulk)
|
|
38
|
+
*
|
|
39
|
+
* **LIFTED (the invariant):** the typed split —
|
|
40
|
+
* `if (remapped.code === 'usage_error') → new UsageError(...)`
|
|
41
|
+
* `else → new ApiError(remapped.code, ...)` — with the 5
|
|
42
|
+
* conditional-spread metadata arms (`cause` on both arms;
|
|
43
|
+
* `httpStatus` / `mondayCode` / `requestId` / `retryAfterSeconds`
|
|
44
|
+
* plus the unconditional `retryable: remapped.retryable` on the
|
|
45
|
+
* ApiError arm). These spreads were the uncovered branches that
|
|
46
|
+
* dragged `item/update.ts` to 79.42% — consolidating them into ONE
|
|
47
|
+
* helper + ONE focused unit test recovered the margin (the 4-path
|
|
48
|
+
* ratchet; `item/update.ts` branches 79.42% → 87.27%).
|
|
49
|
+
*
|
|
50
|
+
* **STAYS INLINE (the over-fit boundary — each site's own work):** the
|
|
51
|
+
* `foldAndRemap` call, `const existing = remapped.details ?? {}`, and
|
|
52
|
+
* the per-site decoration object built from `existing` + the
|
|
53
|
+
* site-specific slots (`applied_count` / `applied_to` /
|
|
54
|
+
* `failed_at_item` / `matched_count` shared by all 4; plus
|
|
55
|
+
* `applied_file_columns_per_item` / `failed_file_column` /
|
|
56
|
+
* `file_count` / `file_column_ids` on the M46-multi site). Each site
|
|
57
|
+
* assembles its own `details` record, then delegates the typed split.
|
|
58
|
+
*
|
|
59
|
+
* ## R-v0.8-NEW-6 — `projectCauseForEnvelope` (cause-projection builder)
|
|
60
|
+
*
|
|
61
|
+
* Adjacent, bundled (both live in mutation-path catch arms) but a
|
|
62
|
+
* SEPARATE helper — NOT merged into `reThrowDecorated`. Recurs across
|
|
63
|
+
* **3 orphan-warn sites**:
|
|
64
|
+
*
|
|
65
|
+
* 1. M43 create-time leg-2 `src/commands/item/create.ts` (`create_then_file_upload_partial_failure`)
|
|
66
|
+
* 2. M46 create-time multi `src/commands/item/create.ts` (same + `applied_file_columns`)
|
|
67
|
+
* 3. M46 single-item multi `src/commands/item/update.ts` (`multi_file_update_partial_failure`)
|
|
68
|
+
*
|
|
69
|
+
* **LIFTED:** ONLY the ~4-line projection builder — seed
|
|
70
|
+
* `{ code, message }` from the (already-remapped, or raw-`MondayCliError`)
|
|
71
|
+
* error, then conditionally attach `details`. (At the two create
|
|
72
|
+
* sites the `if (err.details !== undefined)` arm was c8-ignored as
|
|
73
|
+
* defensive while inlined; the builder's own unit test now drives
|
|
74
|
+
* both a details-present and a details-absent error, so this lift
|
|
75
|
+
* dropped those c8-ignore directives and genuinely covers both arms.)
|
|
76
|
+
*
|
|
77
|
+
* **STAYS INLINE (why this is structurally distinct from
|
|
78
|
+
* `reThrowDecorated`, not the same lift):** the surrounding
|
|
79
|
+
* orphan-warn decoration diverges per site — the outer code is ALWAYS
|
|
80
|
+
* `internal_error` (not the preserved remapped code), the
|
|
81
|
+
* `details.reason` literal differs, the decoration slots differ
|
|
82
|
+
* (`created_item_id` vs `item_id`; `applied_file_columns` present on
|
|
83
|
+
* the M46 sites), and the hint text differs. The genuinely-shared
|
|
84
|
+
* surface is JUST the projection builder. Merging the two helpers
|
|
85
|
+
* would force parameterising outer-code policy + decoration shape +
|
|
86
|
+
* cause-projection-vs-in-place-merge, collapsing each helper's value
|
|
87
|
+
* to "shared `foldAndRemap` call site" (already factored). See
|
|
88
|
+
* `docs/v0.7-plan.md` §22 R-v0.7-NEW-5 "M43 IMPL outcome" for the
|
|
89
|
+
* full distinctness argument.
|
|
90
|
+
*/
|
|
91
|
+
import { ApiError, UsageError } from '../utils/errors.js';
|
|
92
|
+
/**
|
|
93
|
+
* Re-throws a `foldAndRemap`-decorated bulk/fail-fast error, rebuilding
|
|
94
|
+
* it as the right typed class with its wire metadata preserved.
|
|
95
|
+
*
|
|
96
|
+
* The caller has already folded resolver-warnings + applied the
|
|
97
|
+
* `validation_failed → column_archived` stale-cache remap, and has
|
|
98
|
+
* assembled the full `details` decoration (its `...existing` spread
|
|
99
|
+
* plus the per-site progress slots). This helper owns ONLY the typed
|
|
100
|
+
* split: `usage_error` rebuilds as {@link UsageError}; any other code
|
|
101
|
+
* rebuilds as {@link ApiError} preserving the wire metadata
|
|
102
|
+
* (`httpStatus` / `mondayCode` / `requestId` / `retryAfterSeconds` /
|
|
103
|
+
* `retryable`) via conditional spreads. Always throws — return type is
|
|
104
|
+
* `never` so callers don't need a trailing unreachable statement.
|
|
105
|
+
*
|
|
106
|
+
* @param remapped the post-`foldAndRemap` error whose typed code +
|
|
107
|
+
* wire metadata drive the rebuild
|
|
108
|
+
* @param details the fully-assembled decoration record (already
|
|
109
|
+
* including the `...existing` spread of `remapped.details`)
|
|
110
|
+
*/
|
|
111
|
+
export function reThrowDecorated(remapped, details) {
|
|
112
|
+
// usage_error rebuilds as UsageError — the only metadata it carries
|
|
113
|
+
// is the optional `cause` chain. Every other code rebuilds as
|
|
114
|
+
// ApiError preserving the wire metadata via conditional spreads
|
|
115
|
+
// (each `?? :` attaches a field only when the source error carried
|
|
116
|
+
// it; the per-Monday-error permutations of httpStatus / mondayCode /
|
|
117
|
+
// requestId / retryAfterSeconds set-or-unset aren't all exercised by
|
|
118
|
+
// any single call site, which is why they lived as uncovered branches
|
|
119
|
+
// before this lift folded them into one tested helper).
|
|
120
|
+
if (remapped.code === 'usage_error') {
|
|
121
|
+
throw new UsageError(remapped.message, {
|
|
122
|
+
...(remapped.cause === undefined ? {} : { cause: remapped.cause }),
|
|
123
|
+
details,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
throw new ApiError(remapped.code, remapped.message, {
|
|
127
|
+
...(remapped.cause === undefined ? {} : { cause: remapped.cause }),
|
|
128
|
+
...(remapped.httpStatus === undefined ? {} : { httpStatus: remapped.httpStatus }),
|
|
129
|
+
...(remapped.mondayCode === undefined ? {} : { mondayCode: remapped.mondayCode }),
|
|
130
|
+
...(remapped.requestId === undefined ? {} : { requestId: remapped.requestId }),
|
|
131
|
+
retryable: remapped.retryable,
|
|
132
|
+
...(remapped.retryAfterSeconds === undefined ? {} : { retryAfterSeconds: remapped.retryAfterSeconds }),
|
|
133
|
+
details,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Builds the JSON `details.cause` projection for an orphan-warn
|
|
138
|
+
* envelope: a `{ code, message }` seed plus an optional `details`
|
|
139
|
+
* passthrough. The surrounding always-`internal_error` wrap +
|
|
140
|
+
* `details.reason` discriminator + hint text stay inline at each call
|
|
141
|
+
* site (they diverge); this owns only the shared projection shape.
|
|
142
|
+
*
|
|
143
|
+
* @param err the (remapped, or raw) `MondayCliError` whose surface is
|
|
144
|
+
* projected into the agent-inspectable `details.cause` slot
|
|
145
|
+
* @returns the projection record for embedding under `details.cause`
|
|
146
|
+
*/
|
|
147
|
+
export function projectCauseForEnvelope(err) {
|
|
148
|
+
const projection = {
|
|
149
|
+
code: err.code,
|
|
150
|
+
message: err.message,
|
|
151
|
+
};
|
|
152
|
+
// `details` is optional on MondayCliError; attach it only when the
|
|
153
|
+
// source error carried one. Both arms are driven by the helper's
|
|
154
|
+
// focused unit test, so the two create-site call sites can drop the
|
|
155
|
+
// c8-ignore that previously masked the details-absent arm.
|
|
156
|
+
if (err.details !== undefined) {
|
|
157
|
+
projection.details = err.details;
|
|
158
|
+
}
|
|
159
|
+
return projection;
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=error-decoration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-decoration.js","sourceRoot":"","sources":["../../src/api/error-decoration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AAEH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAuB,MAAM,oBAAoB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAwB,EACxB,OAAgC;IAEhC,oEAAoE;IACpE,8DAA8D;IAC9D,gEAAgE;IAChE,mEAAmE;IACnE,qEAAqE;IACrE,qEAAqE;IACrE,sEAAsE;IACtE,wDAAwD;IACxD,IAAI,QAAQ,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACpC,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,EAAE;YACrC,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;YAClE,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IACD,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE;QAClD,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClE,GAAG,CAAC,QAAQ,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;QACjF,GAAG,CAAC,QAAQ,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;QACjF,GAAG,CAAC,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC9E,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,GAAG,CAAC,QAAQ,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QACtG,OAAO;KACR,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAAmB;IAEnB,MAAM,UAAU,GAA4B;QAC1C,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;KACrB,CAAC;IACF,mEAAmE;IACnE,iEAAiE;IACjE,oEAAoE;IACpE,2DAA2D;IAC3D,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9B,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IACnC,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared fetch-transport helpers (R-v0.8-NEW-11, v0.8). Both transport
|
|
3
|
+
* seams — the JSON `client.request`-over-`fetch` seam in
|
|
4
|
+
* `transport.ts` and the multipart `add_file_to_column`-over-`/v2/file`
|
|
5
|
+
* seam in `multipart-transport.ts` — need the same four primitives:
|
|
6
|
+
* a URL-/token-free fetch-error descriptor, an abort-vs-real-error
|
|
7
|
+
* discriminator, a `Headers` → record flattener, and an N-way
|
|
8
|
+
* `AbortSignal` combiner. Before this lift each module carried a
|
|
9
|
+
* verbatim-or-near-verbatim private copy; the multipart docstrings
|
|
10
|
+
* literally read "Mirrors `transport.ts:describeFetchError`" /
|
|
11
|
+
* "Mirrors `transport.ts:combineSignals`".
|
|
12
|
+
*
|
|
13
|
+
* **Why consolidate — not just tidy-up dedupe:**
|
|
14
|
+
*
|
|
15
|
+
* 1. **One test set covers the shared defensive branches once.** The
|
|
16
|
+
* `describeFetchError` TLS `UNABLE_TO_*` arm + `combineSignals`'s
|
|
17
|
+
* empty-input guard were uncovered in BOTH copies — duplicated
|
|
18
|
+
* uncovered branches that dragged global branch coverage below the
|
|
19
|
+
* 95.45% floor (R-v0.8-NEW-10, CI red). A single direct unit test
|
|
20
|
+
* on the shared module exercises every arm once instead of
|
|
21
|
+
* relying on two transports to drive each copy through `fetch`.
|
|
22
|
+
* 2. **The two `combineSignals` had already DRIFTED.**
|
|
23
|
+
* `transport.ts` hedged behind `typeof AbortSignal.any ===
|
|
24
|
+
* 'function'` + a legacy Node-<19 controller fallback;
|
|
25
|
+
* `multipart-transport.ts` assumed `AbortSignal.any` exists. The
|
|
26
|
+
* lift keeps `transport.ts`'s fallback — the safer SUPERSET — so a
|
|
27
|
+
* downstream embedder on an older Node still gets correct signal
|
|
28
|
+
* combination (R-v0.8-NEW-11 over-fit watch: the divergence is
|
|
29
|
+
* real, not cosmetic; do NOT collapse to multipart's narrower
|
|
30
|
+
* form).
|
|
31
|
+
* 3. **The fetch-error vocabulary is a contract surface.** Agents
|
|
32
|
+
* reading either transport's `error.message` see the SAME
|
|
33
|
+
* `connection refused` / `dns lookup failed` / `tls error`
|
|
34
|
+
* strings regardless of which seam issued the call — convergence
|
|
35
|
+
* was already an explicit goal in the old multipart docstring
|
|
36
|
+
* ("keep messaging stable across the JSON + multipart paths").
|
|
37
|
+
*
|
|
38
|
+
* This is helper-sharing, NOT a merge of the two transport seams —
|
|
39
|
+
* they keep separate modules + separate `Transport` /
|
|
40
|
+
* `MultipartTransport` interfaces per their different bodies (JSON
|
|
41
|
+
* `body: JSON.stringify(...)` vs `FormData` multipart). See
|
|
42
|
+
* `docs/architecture.md` "Wire-vs-CLI semantics documentation
|
|
43
|
+
* conventions" (R-NEW-41) for why the seams stay split.
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* True for `fetch` rejections that mean "the request was aborted"
|
|
47
|
+
* (caller cancellation OR `AbortSignal.timeout`) rather than a real
|
|
48
|
+
* network failure. Callers use it to discriminate timeout from
|
|
49
|
+
* network_error: the timeout signal won iff the caller's own signal
|
|
50
|
+
* didn't fire first.
|
|
51
|
+
*/
|
|
52
|
+
export declare const isAbortError: (err: unknown) => boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Builds a generic, URL-free message for a thrown `fetch` exception.
|
|
55
|
+
*
|
|
56
|
+
* Why not `err.message`. Node's undici embeds the request URL into
|
|
57
|
+
* the messages of common transport errors — `ECONNREFUSED https://
|
|
58
|
+
* api.example/v2?token=...`, `getaddrinfo ENOTFOUND api.example`, etc.
|
|
59
|
+
* If `MONDAY_API_URL` is misconfigured to carry the token (or any
|
|
60
|
+
* other secret), the literal token lands in `ApiError.message`. The
|
|
61
|
+
* runner's redactor would catch it on emit, but `security.md` forbids
|
|
62
|
+
* the token entering `Error.message` in the first place — the rule is
|
|
63
|
+
* defence-in-depth, not "we'll fix it downstream". The original error
|
|
64
|
+
* is still attached via `cause`, which a future debug log surfaces
|
|
65
|
+
* through `redact()` (key + value scan) rather than verbatim.
|
|
66
|
+
*
|
|
67
|
+
* Maps the common shapes to short, stable codes:
|
|
68
|
+
* - DNS / hostname unresolvable → `dns lookup failed`
|
|
69
|
+
* - ECONNREFUSED / ECONNRESET → `connection refused`
|
|
70
|
+
* - SSL/TLS issue → `tls error`
|
|
71
|
+
* - generic Error → `fetch failed`
|
|
72
|
+
* - non-Error throw → `fetch failed`
|
|
73
|
+
*/
|
|
74
|
+
export declare const describeFetchError: (err: unknown) => string;
|
|
75
|
+
/**
|
|
76
|
+
* Flattens a `fetch` `Headers` instance into a plain record so the
|
|
77
|
+
* transport's `TransportResponse` / `MultipartTransportResponse` carry
|
|
78
|
+
* an inert snapshot (not a live `Headers` object) past the transport
|
|
79
|
+
* boundary.
|
|
80
|
+
*/
|
|
81
|
+
export declare const headersToRecord: (headers: Headers) => Readonly<Record<string, string>>;
|
|
82
|
+
/**
|
|
83
|
+
* Combines N optional `AbortSignal`s into one. The repo's Node 22+ pin
|
|
84
|
+
* always provides the platform `AbortSignal.any`, so that is the live,
|
|
85
|
+
* tested path; a legacy controller fallback ({@link combineSignalsLegacy})
|
|
86
|
+
* is kept for hypothetical downstream embedders on Node < 19.
|
|
87
|
+
*
|
|
88
|
+
* The fallback is `transport.ts`'s original — the safer SUPERSET kept
|
|
89
|
+
* deliberately over `multipart-transport.ts`'s narrower "assume
|
|
90
|
+
* `AbortSignal.any` exists" form (R-v0.8-NEW-11 over-fit watch). Only
|
|
91
|
+
* the feature-detect guard + the unreachable fallback are c8-ignored;
|
|
92
|
+
* the reachable `AbortSignal.any(real)` path stays counted so a
|
|
93
|
+
* regression in the multi-signal combination surfaces in coverage
|
|
94
|
+
* (Codex R1 P2-1).
|
|
95
|
+
*/
|
|
96
|
+
export declare const combineSignals: (...signals: readonly (AbortSignal | undefined)[]) => AbortSignal;
|
|
97
|
+
//# sourceMappingURL=fetch-transport-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-transport-helpers.d.ts","sourceRoot":"","sources":["../../src/api/fetch-transport-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAIH;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,OAAO,KAAG,OAK3C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,OAAO,KAAG,MA8BjD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,OAAO,KACf,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMjC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,GACzB,GAAG,SAAS,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,KAC/C,WAkBF,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared fetch-transport helpers (R-v0.8-NEW-11, v0.8). Both transport
|
|
3
|
+
* seams — the JSON `client.request`-over-`fetch` seam in
|
|
4
|
+
* `transport.ts` and the multipart `add_file_to_column`-over-`/v2/file`
|
|
5
|
+
* seam in `multipart-transport.ts` — need the same four primitives:
|
|
6
|
+
* a URL-/token-free fetch-error descriptor, an abort-vs-real-error
|
|
7
|
+
* discriminator, a `Headers` → record flattener, and an N-way
|
|
8
|
+
* `AbortSignal` combiner. Before this lift each module carried a
|
|
9
|
+
* verbatim-or-near-verbatim private copy; the multipart docstrings
|
|
10
|
+
* literally read "Mirrors `transport.ts:describeFetchError`" /
|
|
11
|
+
* "Mirrors `transport.ts:combineSignals`".
|
|
12
|
+
*
|
|
13
|
+
* **Why consolidate — not just tidy-up dedupe:**
|
|
14
|
+
*
|
|
15
|
+
* 1. **One test set covers the shared defensive branches once.** The
|
|
16
|
+
* `describeFetchError` TLS `UNABLE_TO_*` arm + `combineSignals`'s
|
|
17
|
+
* empty-input guard were uncovered in BOTH copies — duplicated
|
|
18
|
+
* uncovered branches that dragged global branch coverage below the
|
|
19
|
+
* 95.45% floor (R-v0.8-NEW-10, CI red). A single direct unit test
|
|
20
|
+
* on the shared module exercises every arm once instead of
|
|
21
|
+
* relying on two transports to drive each copy through `fetch`.
|
|
22
|
+
* 2. **The two `combineSignals` had already DRIFTED.**
|
|
23
|
+
* `transport.ts` hedged behind `typeof AbortSignal.any ===
|
|
24
|
+
* 'function'` + a legacy Node-<19 controller fallback;
|
|
25
|
+
* `multipart-transport.ts` assumed `AbortSignal.any` exists. The
|
|
26
|
+
* lift keeps `transport.ts`'s fallback — the safer SUPERSET — so a
|
|
27
|
+
* downstream embedder on an older Node still gets correct signal
|
|
28
|
+
* combination (R-v0.8-NEW-11 over-fit watch: the divergence is
|
|
29
|
+
* real, not cosmetic; do NOT collapse to multipart's narrower
|
|
30
|
+
* form).
|
|
31
|
+
* 3. **The fetch-error vocabulary is a contract surface.** Agents
|
|
32
|
+
* reading either transport's `error.message` see the SAME
|
|
33
|
+
* `connection refused` / `dns lookup failed` / `tls error`
|
|
34
|
+
* strings regardless of which seam issued the call — convergence
|
|
35
|
+
* was already an explicit goal in the old multipart docstring
|
|
36
|
+
* ("keep messaging stable across the JSON + multipart paths").
|
|
37
|
+
*
|
|
38
|
+
* This is helper-sharing, NOT a merge of the two transport seams —
|
|
39
|
+
* they keep separate modules + separate `Transport` /
|
|
40
|
+
* `MultipartTransport` interfaces per their different bodies (JSON
|
|
41
|
+
* `body: JSON.stringify(...)` vs `FormData` multipart). See
|
|
42
|
+
* `docs/architecture.md` "Wire-vs-CLI semantics documentation
|
|
43
|
+
* conventions" (R-NEW-41) for why the seams stay split.
|
|
44
|
+
*/
|
|
45
|
+
import { errorCode } from '../utils/errors.js';
|
|
46
|
+
/**
|
|
47
|
+
* True for `fetch` rejections that mean "the request was aborted"
|
|
48
|
+
* (caller cancellation OR `AbortSignal.timeout`) rather than a real
|
|
49
|
+
* network failure. Callers use it to discriminate timeout from
|
|
50
|
+
* network_error: the timeout signal won iff the caller's own signal
|
|
51
|
+
* didn't fire first.
|
|
52
|
+
*/
|
|
53
|
+
export const isAbortError = (err) => {
|
|
54
|
+
if (err instanceof Error) {
|
|
55
|
+
return err.name === 'AbortError' || err.name === 'TimeoutError';
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Builds a generic, URL-free message for a thrown `fetch` exception.
|
|
61
|
+
*
|
|
62
|
+
* Why not `err.message`. Node's undici embeds the request URL into
|
|
63
|
+
* the messages of common transport errors — `ECONNREFUSED https://
|
|
64
|
+
* api.example/v2?token=...`, `getaddrinfo ENOTFOUND api.example`, etc.
|
|
65
|
+
* If `MONDAY_API_URL` is misconfigured to carry the token (or any
|
|
66
|
+
* other secret), the literal token lands in `ApiError.message`. The
|
|
67
|
+
* runner's redactor would catch it on emit, but `security.md` forbids
|
|
68
|
+
* the token entering `Error.message` in the first place — the rule is
|
|
69
|
+
* defence-in-depth, not "we'll fix it downstream". The original error
|
|
70
|
+
* is still attached via `cause`, which a future debug log surfaces
|
|
71
|
+
* through `redact()` (key + value scan) rather than verbatim.
|
|
72
|
+
*
|
|
73
|
+
* Maps the common shapes to short, stable codes:
|
|
74
|
+
* - DNS / hostname unresolvable → `dns lookup failed`
|
|
75
|
+
* - ECONNREFUSED / ECONNRESET → `connection refused`
|
|
76
|
+
* - SSL/TLS issue → `tls error`
|
|
77
|
+
* - generic Error → `fetch failed`
|
|
78
|
+
* - non-Error throw → `fetch failed`
|
|
79
|
+
*/
|
|
80
|
+
export const describeFetchError = (err) => {
|
|
81
|
+
if (err instanceof Error) {
|
|
82
|
+
const code = errorCode(err);
|
|
83
|
+
if (code !== undefined) {
|
|
84
|
+
if (code.startsWith('ENOTFOUND') || code.startsWith('EAI_')) {
|
|
85
|
+
return 'fetch failed: dns lookup failed';
|
|
86
|
+
}
|
|
87
|
+
if (code === 'ECONNREFUSED' || code === 'ECONNRESET') {
|
|
88
|
+
return 'fetch failed: connection refused';
|
|
89
|
+
}
|
|
90
|
+
if (code === 'CERT_HAS_EXPIRED' || code.startsWith('UNABLE_TO_')) {
|
|
91
|
+
return 'fetch failed: tls error';
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Sniff the message for the same common shapes when err.code
|
|
95
|
+
// isn't surfaced (older fetch impls, wrapped TypeErrors).
|
|
96
|
+
const lower = err.message.toLowerCase();
|
|
97
|
+
if (lower.includes('econnrefused') || lower.includes('connection refused')) {
|
|
98
|
+
return 'fetch failed: connection refused';
|
|
99
|
+
}
|
|
100
|
+
if (lower.includes('enotfound') ||
|
|
101
|
+
lower.includes('eai_again') ||
|
|
102
|
+
lower.includes('getaddrinfo')) {
|
|
103
|
+
return 'fetch failed: dns lookup failed';
|
|
104
|
+
}
|
|
105
|
+
return 'fetch failed';
|
|
106
|
+
}
|
|
107
|
+
return 'fetch failed';
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Flattens a `fetch` `Headers` instance into a plain record so the
|
|
111
|
+
* transport's `TransportResponse` / `MultipartTransportResponse` carry
|
|
112
|
+
* an inert snapshot (not a live `Headers` object) past the transport
|
|
113
|
+
* boundary.
|
|
114
|
+
*/
|
|
115
|
+
export const headersToRecord = (headers) => {
|
|
116
|
+
const out = {};
|
|
117
|
+
headers.forEach((value, key) => {
|
|
118
|
+
out[key] = value;
|
|
119
|
+
});
|
|
120
|
+
return out;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Combines N optional `AbortSignal`s into one. The repo's Node 22+ pin
|
|
124
|
+
* always provides the platform `AbortSignal.any`, so that is the live,
|
|
125
|
+
* tested path; a legacy controller fallback ({@link combineSignalsLegacy})
|
|
126
|
+
* is kept for hypothetical downstream embedders on Node < 19.
|
|
127
|
+
*
|
|
128
|
+
* The fallback is `transport.ts`'s original — the safer SUPERSET kept
|
|
129
|
+
* deliberately over `multipart-transport.ts`'s narrower "assume
|
|
130
|
+
* `AbortSignal.any` exists" form (R-v0.8-NEW-11 over-fit watch). Only
|
|
131
|
+
* the feature-detect guard + the unreachable fallback are c8-ignored;
|
|
132
|
+
* the reachable `AbortSignal.any(real)` path stays counted so a
|
|
133
|
+
* regression in the multi-signal combination surfaces in coverage
|
|
134
|
+
* (Codex R1 P2-1).
|
|
135
|
+
*/
|
|
136
|
+
export const combineSignals = (...signals) => {
|
|
137
|
+
const real = signals.filter((s) => s !== undefined);
|
|
138
|
+
const [first, ...rest] = real;
|
|
139
|
+
if (first === undefined) {
|
|
140
|
+
return new AbortController().signal;
|
|
141
|
+
}
|
|
142
|
+
if (rest.length === 0) {
|
|
143
|
+
return first;
|
|
144
|
+
}
|
|
145
|
+
// Node 22+ always has `AbortSignal.any`; the feature-detect guard +
|
|
146
|
+
// its legacy branch are unreachable on the pin, so the guard line is
|
|
147
|
+
// c8-ignored — but `AbortSignal.any(real)` below is NOT, so the
|
|
148
|
+
// multi-signal path is still coverage-counted.
|
|
149
|
+
/* c8 ignore next 3 */
|
|
150
|
+
if (typeof AbortSignal.any !== 'function') {
|
|
151
|
+
return combineSignalsLegacy(real);
|
|
152
|
+
}
|
|
153
|
+
return AbortSignal.any(real);
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Pre-`AbortSignal.any` controller fallback (Node < 19). Unreachable on
|
|
157
|
+
* the repo's Node 22+ pin — kept as the safer superset for downstream
|
|
158
|
+
* embedders and c8-ignored as a block (testing.md block-wrap rule).
|
|
159
|
+
*/
|
|
160
|
+
/* c8 ignore start */
|
|
161
|
+
const combineSignalsLegacy = (real) => {
|
|
162
|
+
const ctrl = new AbortController();
|
|
163
|
+
for (const s of real) {
|
|
164
|
+
if (s.aborted) {
|
|
165
|
+
ctrl.abort(s.reason);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
s.addEventListener('abort', () => {
|
|
169
|
+
ctrl.abort(s.reason);
|
|
170
|
+
}, { once: true });
|
|
171
|
+
}
|
|
172
|
+
return ctrl.signal;
|
|
173
|
+
};
|
|
174
|
+
/* c8 ignore stop */
|
|
175
|
+
//# sourceMappingURL=fetch-transport-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-transport-helpers.js","sourceRoot":"","sources":["../../src/api/fetch-transport-helpers.ts"],"names":[],"mappings":"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"}
|