monday-cli 0.5.0 → 0.6.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 +277 -0
- package/README.md +96 -35
- package/dist/api/column-types.d.ts +48 -19
- package/dist/api/column-types.d.ts.map +1 -1
- package/dist/api/column-types.js +25 -11
- package/dist/api/column-types.js.map +1 -1
- package/dist/api/column-values.d.ts +17 -10
- package/dist/api/column-values.d.ts.map +1 -1
- package/dist/api/column-values.js +33 -19
- package/dist/api/column-values.js.map +1 -1
- package/dist/api/file-column-set.d.ts +507 -0
- package/dist/api/file-column-set.d.ts.map +1 -0
- package/dist/api/file-column-set.js +510 -0
- package/dist/api/file-column-set.js.map +1 -0
- package/dist/api/raw-write.d.ts +27 -17
- package/dist/api/raw-write.d.ts.map +1 -1
- package/dist/api/raw-write.js +40 -25
- package/dist/api/raw-write.js.map +1 -1
- package/dist/api/resolver-error-fold.d.ts +25 -0
- package/dist/api/resolver-error-fold.d.ts.map +1 -1
- package/dist/api/resolver-error-fold.js +56 -0
- package/dist/api/resolver-error-fold.js.map +1 -1
- package/dist/commands/board/column-create.d.ts +8 -3
- package/dist/commands/board/column-create.d.ts.map +1 -1
- package/dist/commands/board/column-create.js +16 -8
- package/dist/commands/board/column-create.js.map +1 -1
- package/dist/commands/item/create.d.ts.map +1 -1
- package/dist/commands/item/create.js +131 -33
- package/dist/commands/item/create.js.map +1 -1
- package/dist/commands/item/set.d.ts +33 -3
- package/dist/commands/item/set.d.ts.map +1 -1
- package/dist/commands/item/set.js +193 -15
- package/dist/commands/item/set.js.map +1 -1
- package/dist/commands/item/update.d.ts +34 -3
- package/dist/commands/item/update.d.ts.map +1 -1
- package/dist/commands/item/update.js +346 -67
- package/dist/commands/item/update.js.map +1 -1
- package/dist/commands/item/upload.d.ts.map +1 -1
- package/dist/commands/item/upload.js +16 -69
- package/dist/commands/item/upload.js.map +1 -1
- package/dist/commands/update/upload.d.ts.map +1 -1
- package/dist/commands/update/upload.js +9 -59
- package/dist/commands/update/upload.js.map +1 -1
- package/dist/utils/file-source.d.ts +93 -0
- package/dist/utils/file-source.d.ts.map +1 -0
- package/dist/utils/file-source.js +140 -0
- package/dist/utils/file-source.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files-shaped friendly `--set` dispatch (`cli-design.md` §5.3
|
|
3
|
+
* writer-expansion roadmap "files" row + §13 v0.6 entry,
|
|
4
|
+
* `v0.6-plan.md` §3 M38).
|
|
5
|
+
*
|
|
6
|
+
* **Status: runtime bodies shipped at v0.6-M38 IMPL.** The dispatch
|
|
7
|
+
* type signatures + the per-mutex-rejection error shape + the
|
|
8
|
+
* fetcher wrapping M31's `addFileToColumn` all landed at pre-flight;
|
|
9
|
+
* IMPL swaps the c8-ignored stub bodies for runtime logic. No new
|
|
10
|
+
* wire fetcher (M38 reuses the v0.4-M31 multipart wire verbatim);
|
|
11
|
+
* no new transport seam.
|
|
12
|
+
*
|
|
13
|
+
* **Wire surface.** Zero net change. When `monday item set <iid>
|
|
14
|
+
* <file-col>=<path>` OR `monday item update <iid> --set
|
|
15
|
+
* <file-col>=<path>` resolves to a `file`-typed column, the
|
|
16
|
+
* command action body branches OFF the standard JSON-translator
|
|
17
|
+
* path INTO M31's multipart `addFileToColumn` fetcher via
|
|
18
|
+
* `executeFileColumnSet` below. The translator
|
|
19
|
+
* (`translateColumnValueAsync` in `column-values.ts`) stays
|
|
20
|
+
* JSON-output-shaped for the 13 existing writable types — the
|
|
21
|
+
* file-column dispatch is a SIBLING leg routed at the command
|
|
22
|
+
* action body level, NOT a new payload format inside the
|
|
23
|
+
* translator union.
|
|
24
|
+
*
|
|
25
|
+
* **Why a sibling leg, not a translator widening.** Three reasons
|
|
26
|
+
* pin the design (cli-design §5.3 step 4 + step 5 prose):
|
|
27
|
+
*
|
|
28
|
+
* 1. The wire surface is fundamentally different — multipart
|
|
29
|
+
* `add_file_to_column` vs JSON `change_column_value` /
|
|
30
|
+
* `change_multiple_column_values`. Folding the file payload
|
|
31
|
+
* into `ColumnValuePayload` would require a `format: 'file'`
|
|
32
|
+
* union variant that `selectMutation` can't bundle into the
|
|
33
|
+
* multi-mutation (each `add_file_to_column` is a single
|
|
34
|
+
* per-column multipart round-trip; bundling N file uploads
|
|
35
|
+
* into one mutation isn't a Monday wire shape).
|
|
36
|
+
* 2. The atomicity contract differs — the 13 existing types
|
|
37
|
+
* bundle atomically via `change_multiple_column_values` when
|
|
38
|
+
* ≥2 columns target the same item. File-column writes are
|
|
39
|
+
* single-column-per-call only on Monday's wire; mixing a
|
|
40
|
+
* file-column `--set` with any value `--set` / `--set-raw` /
|
|
41
|
+
* `--name` in the same call would force a multi-leg dispatch
|
|
42
|
+
* that breaks the existing atomicity guarantee. M38 enforces
|
|
43
|
+
* single-file-only via the mutex rules below (D2 closure) —
|
|
44
|
+
* the existing atomicity contract stays intact.
|
|
45
|
+
* 3. The translator's input contract is "value-string-to-JSON-
|
|
46
|
+
* payload" — file columns take a file path, not a value
|
|
47
|
+
* string. Path validation + `fs.stat` + `fs.access(R_OK)` +
|
|
48
|
+
* Blob construction don't fit the translator's pure-function
|
|
49
|
+
* shape; routing the path through the sibling leg keeps each
|
|
50
|
+
* helper focused.
|
|
51
|
+
*
|
|
52
|
+
* **Reuse from v0.4-M31.** The wire dispatch reuses
|
|
53
|
+
* `addFileToColumn` from `src/api/assets.ts` verbatim — same
|
|
54
|
+
* `MultipartTransport.request(...)` round-trip, same `withRetry`
|
|
55
|
+
* shape, same `file_too_large` rewrap-inside-retry-thunk pattern
|
|
56
|
+
* (R-v0.4-W2 axis 7 "non-retryable rewrap placement" carries
|
|
57
|
+
* through safely-by-construction since the dispatch goes through
|
|
58
|
+
* the existing fetcher rather than a re-implementation).
|
|
59
|
+
*
|
|
60
|
+
* **Consumer counts post v0.6-M38 IMPL close** (runtime bodies
|
|
61
|
+
* shipped at `e749931` + the R-v0.6-NEW-1 lift at `3c2a9b0`;
|
|
62
|
+
* pre-flight stubs collapsed):
|
|
63
|
+
*
|
|
64
|
+
* - `addFileToColumn` (M31): 2 consumers (M31's `item upload`
|
|
65
|
+
* action body + M38's `executeFileColumnSet` runtime body).
|
|
66
|
+
* - `MultipartTransport` via `ResolvedClient.multipart`: 2
|
|
67
|
+
* consumers (the same test seam pattern; M31's two upload
|
|
68
|
+
* verbs + M38's dispatch share the slot).
|
|
69
|
+
* - `sniffContentType` from `src/utils/mime.ts`: 2 consumers
|
|
70
|
+
* post-lift (M31's `item upload` + M31's `update upload` —
|
|
71
|
+
* both via {@link buildBlobFromPath}; M38 routes through
|
|
72
|
+
* `buildBlobFromPath` rather than calling `sniffContentType`
|
|
73
|
+
* directly).
|
|
74
|
+
* - **R-v0.6-NEW-1 SHIPPED at IMPL kickoff**: the file-pre-check
|
|
75
|
+
* + Blob-construction pattern lifted to `src/utils/file-source
|
|
76
|
+
* .ts` (`precheckLocalFile` + `buildBlobFromPath` — 3 consumers
|
|
77
|
+
* post-lift: M31's `item upload`, M31's `update upload`, M38's
|
|
78
|
+
* `executeFileColumnSet`).
|
|
79
|
+
*
|
|
80
|
+
* **Mutex rules (D2 closure).** Enforced at the column-resolution
|
|
81
|
+
* boundary (parse-time can't know — column types only resolve
|
|
82
|
+
* after metadata loads). When any resolved column has `type ===
|
|
83
|
+
* 'file'`:
|
|
84
|
+
*
|
|
85
|
+
* - Exactly ONE file `--set` entry allowed per call (M38 single-
|
|
86
|
+
* file scope; multi-file dispatch defers to v0.6.x).
|
|
87
|
+
* - NO other value `--set` / `--set-raw` / `--name` flags
|
|
88
|
+
* allowed (mixing would force non-atomic multi-leg dispatch).
|
|
89
|
+
* - Bulk `item update --where ... --set <file-col>=<path>`
|
|
90
|
+
* REJECTED at resolution-time per D5 closure (defers to
|
|
91
|
+
* v0.6.x — per-item file dispatch + partial-success envelope +
|
|
92
|
+
* `--concurrency` interaction each carry additional design
|
|
93
|
+
* dimensions).
|
|
94
|
+
* - `item create --set <file-col>=<path>` REJECTED at resolution-
|
|
95
|
+
* time per D6 closure (defers to v0.6.x — non-atomic post-
|
|
96
|
+
* create wire shape would break §5.8 state safety).
|
|
97
|
+
*
|
|
98
|
+
* Rejection surfaces share the `usage_error.details.reason`
|
|
99
|
+
* discriminator pattern from M14 / M27 / M31:
|
|
100
|
+
*
|
|
101
|
+
* - `'mixed_file_and_value_sets'` — file `--set` + any value
|
|
102
|
+
* `--set` / `--set-raw` / `--name` in same call.
|
|
103
|
+
* - `'multi_file_set_unsupported'` — 2+ file `--set` entries
|
|
104
|
+
* in same call.
|
|
105
|
+
* - `'file_set_on_create_unsupported'` — `item create --set
|
|
106
|
+
* <file-col>=<path>`.
|
|
107
|
+
* - `'file_set_on_bulk_unsupported'` — bulk `item update
|
|
108
|
+
* --where ... --set <file-col>=<path>`.
|
|
109
|
+
*
|
|
110
|
+
* **D3 closure — `--set-raw <file-col>=<json>` STAYS REJECTED.**
|
|
111
|
+
* Files have no JSON wire shape Monday's `change_column_value`
|
|
112
|
+
* accepts; the escape-hatch contract "user supplies the JSON
|
|
113
|
+
* `change_column_value` accepts" doesn't compose with the
|
|
114
|
+
* multipart wire. The existing rejection at
|
|
115
|
+
* `raw-write.ts:translateRawColumnValue` stays unchanged; the
|
|
116
|
+
* prose flips slightly to note "M38 ships the friendly `--set
|
|
117
|
+
* <file-col>=<path>` form but `--set-raw` for files stays
|
|
118
|
+
* rejected".
|
|
119
|
+
*
|
|
120
|
+
* **D7 closure — `<path>='-'` stdin support OUT OF SCOPE.**
|
|
121
|
+
* Mirrors M31 `monday item upload`'s rejection rationale — no
|
|
122
|
+
* clean `--filename` companion shape pinned for `--set
|
|
123
|
+
* <file-col>=-` syntax (stdin reads byte-anonymously; the
|
|
124
|
+
* filename is the load-bearing handle for Monday's wire
|
|
125
|
+
* `Asset.name` slot). Defers to v0.6.x extension shape.
|
|
126
|
+
*
|
|
127
|
+
* **No new ERROR_CODE (D8 closure; registry stays at 29).** All
|
|
128
|
+
* M38-specific rejections route through existing `usage_error`
|
|
129
|
+
* with `details.reason` discrimination.
|
|
130
|
+
*
|
|
131
|
+
* **R-NEW-41 4th supporting site filed at M38 pre-flight.** The
|
|
132
|
+
* `--set` syntax is type-uniform from the agent's view
|
|
133
|
+
* (`<col>=<value>`), but for file columns the value is a path
|
|
134
|
+
* and the dispatch transitions silently from JSON to multipart at
|
|
135
|
+
* the translator boundary. The asymmetry is at the AGENT-INPUT
|
|
136
|
+
* boundary, NOT at the wire boundary (M31's multipart-vs-JSON
|
|
137
|
+
* asymmetry #3 is wire-boundary-only). See `docs/architecture.md`
|
|
138
|
+
* "Wire-vs-CLI semantics documentation conventions" for the
|
|
139
|
+
* canonical cross-link.
|
|
140
|
+
*/
|
|
141
|
+
import { z } from 'zod';
|
|
142
|
+
import { type Asset } from './assets.js';
|
|
143
|
+
import { type ResolverWarning } from './columns.js';
|
|
144
|
+
import type { Complexity } from '../utils/output/envelope.js';
|
|
145
|
+
import type { MondayClient } from './client.js';
|
|
146
|
+
import type { MultipartTransport } from './multipart-transport.js';
|
|
147
|
+
/**
|
|
148
|
+
* Post-resolution entry shape for a file-column `--set <col>=<path>`
|
|
149
|
+
* dispatch leg. Produced by the action body's column-resolution +
|
|
150
|
+
* file-pre-check pipeline; consumed by {@link executeFileColumnSet}.
|
|
151
|
+
*
|
|
152
|
+
* The `columnId` slot carries the RESOLVED Monday column ID (not
|
|
153
|
+
* the argv token); the `rawValue` slot preserves the argv-derived
|
|
154
|
+
* path (preserved for dry-run envelope echo per D4 — mirrors M31
|
|
155
|
+
* `item upload`'s `parsed.file` argv-derived shape per the round-2
|
|
156
|
+
* P3-2 fix).
|
|
157
|
+
*
|
|
158
|
+
* `filename` is `basename(filePath)` — the load-bearing handle for
|
|
159
|
+
* Monday's wire `Asset.name` slot.
|
|
160
|
+
*
|
|
161
|
+
* `fileSizeBytes` is the local `fs.stat()` measurement captured at
|
|
162
|
+
* pre-check time. Echoed in the dry-run envelope + threaded into
|
|
163
|
+
* the `file_too_large` rewrap's `details.file_size_bytes` slot on
|
|
164
|
+
* Monday's server-side size-cap rejection (mirrors M31's pattern).
|
|
165
|
+
*/
|
|
166
|
+
export interface FileColumnSetEntry {
|
|
167
|
+
/** Resolved Monday column ID (post-`resolveColumnWithRefresh`). */
|
|
168
|
+
readonly columnId: string;
|
|
169
|
+
/** Resolved column type — narrowed to the files-shaped literal. */
|
|
170
|
+
readonly columnType: 'file';
|
|
171
|
+
/** The argv-derived path token (relative or absolute as the agent typed it). */
|
|
172
|
+
readonly rawValue: string;
|
|
173
|
+
/** Resolved absolute path (post `path.resolve(process.cwd(), rawValue)`). */
|
|
174
|
+
readonly filePath: string;
|
|
175
|
+
/** `basename(filePath)` — Monday's wire `Asset.name` source. */
|
|
176
|
+
readonly filename: string;
|
|
177
|
+
/** Local `fs.stat()` size at pre-check time. */
|
|
178
|
+
readonly fileSizeBytes: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Output envelope shape for the file-column `--set` dispatch leg.
|
|
182
|
+
* Mirrors `itemUploadOutputSchema` from `src/api/assets.ts` so the
|
|
183
|
+
* envelope shape is byte-equivalent to M31 `monday item upload` for
|
|
184
|
+
* an agent reading the result — the dispatch source differs
|
|
185
|
+
* (`monday item set` / `monday item update` vs `monday item upload`)
|
|
186
|
+
* but the envelope payload structure is identical.
|
|
187
|
+
*
|
|
188
|
+
* The `operation` slot pins `'add_file_to_column'` literally
|
|
189
|
+
* (mirroring M31's envelope discriminator); agents reading
|
|
190
|
+
* `data.operation` can branch uniformly on the wire mutation
|
|
191
|
+
* regardless of which CLI verb routed there.
|
|
192
|
+
*/
|
|
193
|
+
export declare const fileColumnSetOutputSchema: z.ZodObject<{
|
|
194
|
+
operation: z.ZodLiteral<"add_file_to_column">;
|
|
195
|
+
item_id: z.ZodString;
|
|
196
|
+
column_id: z.ZodString;
|
|
197
|
+
filename: z.ZodString;
|
|
198
|
+
file_size_bytes: z.ZodNumber;
|
|
199
|
+
asset: z.ZodObject<{
|
|
200
|
+
id: z.ZodString;
|
|
201
|
+
name: z.ZodString;
|
|
202
|
+
url: z.ZodString;
|
|
203
|
+
public_url: z.ZodString;
|
|
204
|
+
file_extension: z.ZodString;
|
|
205
|
+
file_size: z.ZodNumber;
|
|
206
|
+
created_at: z.ZodNullable<z.ZodString>;
|
|
207
|
+
uploaded_by: z.ZodObject<{
|
|
208
|
+
id: z.ZodString;
|
|
209
|
+
name: z.ZodString;
|
|
210
|
+
}, z.core.$strict>;
|
|
211
|
+
original_geometry: z.ZodNullable<z.ZodString>;
|
|
212
|
+
url_thumbnail: z.ZodNullable<z.ZodString>;
|
|
213
|
+
}, z.core.$strict>;
|
|
214
|
+
}, z.core.$strict>;
|
|
215
|
+
export type FileColumnSetOutput = z.infer<typeof fileColumnSetOutputSchema>;
|
|
216
|
+
/**
|
|
217
|
+
* Inputs for the M38 file-column dispatch fetcher. Wraps M31's
|
|
218
|
+
* `addFileToColumn` (`src/api/assets.ts`) verbatim — no new wire
|
|
219
|
+
* mutation, no new transport seam.
|
|
220
|
+
*
|
|
221
|
+
* The runtime body (below in this module) reads:
|
|
222
|
+
*
|
|
223
|
+
* 1. Construct a `Blob` from the local file at
|
|
224
|
+
* `inputs.entry.filePath` via {@link buildBlobFromPath} (read
|
|
225
|
+
* bytes via `fs/promises.readFile` + sniff content-type from
|
|
226
|
+
* filename); the caller already ran {@link precheckLocalFile}
|
|
227
|
+
* so the path is known good + size known non-zero.
|
|
228
|
+
* 2. Call `addFileToColumn({client, multipart, itemId, columnId,
|
|
229
|
+
* file, filename, signal, retries})` — M31's fetcher already
|
|
230
|
+
* wraps the multipart dispatch in `withRetry(...)` + handles
|
|
231
|
+
* the file_too_large rewrap-inside-retry-thunk pattern.
|
|
232
|
+
* 3. Project the result into {@link FileColumnSetOutput} shape
|
|
233
|
+
* with the `operation: 'add_file_to_column'` literal +
|
|
234
|
+
* agent-supplied slots (item_id, column_id, filename,
|
|
235
|
+
* file_size_bytes) — emitted by the action body after this
|
|
236
|
+
* fetcher returns.
|
|
237
|
+
*/
|
|
238
|
+
export interface ExecuteFileColumnSetInputs {
|
|
239
|
+
readonly client: MondayClient;
|
|
240
|
+
readonly multipart: MultipartTransport;
|
|
241
|
+
readonly itemId: string;
|
|
242
|
+
readonly entry: FileColumnSetEntry;
|
|
243
|
+
/** Combined runner signal — same threading as M31's `addFileToColumn`. */
|
|
244
|
+
readonly signal: AbortSignal;
|
|
245
|
+
/** Retry budget — threaded into `withRetry(...)` at IMPL via M31's fetcher. */
|
|
246
|
+
readonly retries: number;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Result of the M38 file-column dispatch fetcher. Mirrors M31's
|
|
250
|
+
* `AddFileToColumnResult` shape — the dispatch is a thin wrapper
|
|
251
|
+
* around M31's existing fetcher so the result projection stays
|
|
252
|
+
* identical.
|
|
253
|
+
*/
|
|
254
|
+
export interface ExecuteFileColumnSetResult {
|
|
255
|
+
readonly asset: Asset;
|
|
256
|
+
readonly source: 'live';
|
|
257
|
+
readonly cacheAgeSeconds: null;
|
|
258
|
+
readonly complexity: Complexity | null;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Reads the local file at `inputs.entry.filePath`, constructs a Blob
|
|
262
|
+
* via {@link buildBlobFromPath} (with `Content-Type` sniffed from the
|
|
263
|
+
* filename), and dispatches the multipart upload through M31's
|
|
264
|
+
* {@link addFileToColumn} fetcher (cli-design §5.3 step 5 + the
|
|
265
|
+
* module docstring above pin the load-bearing design).
|
|
266
|
+
*
|
|
267
|
+
* **Status: runtime body shipped at v0.6-M38 IMPL.** Wraps M31's
|
|
268
|
+
* fetcher verbatim — same `operationName: 'AddFileToColumn'`, same
|
|
269
|
+
* `withRetry(...)` retry semantics, same rewrap-inside-retry-thunk
|
|
270
|
+
* pattern for `file_too_large` (R-v0.4-W2 axis 7 carries through
|
|
271
|
+
* safely-by-construction since the dispatch goes through the
|
|
272
|
+
* existing fetcher rather than a re-implementation).
|
|
273
|
+
*
|
|
274
|
+
* The action-body caller (in `item set` / `item update`) is
|
|
275
|
+
* responsible for:
|
|
276
|
+
*
|
|
277
|
+
* 1. Parsing argv + collecting `--set` / `--set-raw` / `--name`
|
|
278
|
+
* entries.
|
|
279
|
+
* 2. Resolving columns via `resolveColumnWithRefresh`.
|
|
280
|
+
* 3. Calling {@link enforceSingleFileColumnSet} to detect the
|
|
281
|
+
* file-column dispatch leg + enforce the mutex rules.
|
|
282
|
+
* 4. Running {@link precheckLocalFile} from
|
|
283
|
+
* `src/utils/file-source.ts` on the agent-supplied path to
|
|
284
|
+
* build a {@link FileColumnSetEntry} (the precheck surfaces
|
|
285
|
+
* `usage_error.details.reason: 'file_not_readable'` /
|
|
286
|
+
* `'file_empty'` before any wire activity per the M31
|
|
287
|
+
* ordering invariant).
|
|
288
|
+
* 5. Calling this fetcher for the wire dispatch.
|
|
289
|
+
* 6. Emitting the envelope per `fileColumnSetOutputSchema`
|
|
290
|
+
* (mirrors M31 `item upload` envelope verbatim).
|
|
291
|
+
*/
|
|
292
|
+
export declare const executeFileColumnSet: (inputs: ExecuteFileColumnSetInputs) => Promise<ExecuteFileColumnSetResult>;
|
|
293
|
+
/**
|
|
294
|
+
* Mutex enforcement at the column-resolution boundary. Takes the
|
|
295
|
+
* resolved column-type information for every `--set` / `--set-raw`
|
|
296
|
+
* entry + the `--name` presence flag + the call shape (single-item
|
|
297
|
+
* vs bulk vs create), and either:
|
|
298
|
+
*
|
|
299
|
+
* - Returns `{ kind: 'json' }` when NO file-column entries are
|
|
300
|
+
* present in `setEntries` — the standard JSON translator path
|
|
301
|
+
* applies and the action body proceeds unchanged.
|
|
302
|
+
* - Returns `{ kind: 'file', columnId, rawValue }` when a clean
|
|
303
|
+
* file-column dispatch path applies (exactly one file `--set`,
|
|
304
|
+
* no other value flags, single-item non-create call). The
|
|
305
|
+
* caller runs {@link buildBlobFromPath} via
|
|
306
|
+
* {@link precheckLocalFile} from `src/utils/file-source.ts` to
|
|
307
|
+
* build a {@link FileColumnSetEntry} + invokes
|
|
308
|
+
* {@link executeFileColumnSet}.
|
|
309
|
+
* - Throws `ApiError('usage_error', ...)` with a
|
|
310
|
+
* `details.reason` discriminator when a mutex violation is
|
|
311
|
+
* detected: `'file_set_on_bulk_unsupported'` (D5 closure),
|
|
312
|
+
* `'file_set_on_create_unsupported'` (D6 closure),
|
|
313
|
+
* `'multi_file_set_unsupported'` (D2 multi-file leg),
|
|
314
|
+
* `'mixed_file_and_value_sets'` (D2 mixed leg).
|
|
315
|
+
*
|
|
316
|
+
* Pure synchronous check — no I/O, no side effects. The caller
|
|
317
|
+
* resolves columns first (via `resolveColumnWithRefresh` or the
|
|
318
|
+
* existing `resolveAndTranslate` helper's resolution leg) and
|
|
319
|
+
* passes the resolved column types here.
|
|
320
|
+
*
|
|
321
|
+
* **Status: runtime body shipped at v0.6-M38 IMPL.** Per R-NEW-76
|
|
322
|
+
* graduated discipline, callers invoke `parseArgv` BEFORE this
|
|
323
|
+
* function so argv-level failures surface as `usage_error` from
|
|
324
|
+
* the parse boundary (this function itself runs AFTER argv parse
|
|
325
|
+
* + column resolution).
|
|
326
|
+
*/
|
|
327
|
+
export type FileColumnSetEnforcementResult = {
|
|
328
|
+
readonly kind: 'json';
|
|
329
|
+
} | {
|
|
330
|
+
readonly kind: 'file';
|
|
331
|
+
readonly columnId: string;
|
|
332
|
+
readonly rawValue: string;
|
|
333
|
+
};
|
|
334
|
+
export interface EnforceSingleFileColumnSetInputs {
|
|
335
|
+
/**
|
|
336
|
+
* The call shape — determines which mutex rejections apply.
|
|
337
|
+
*
|
|
338
|
+
* - `'item_set'` — single-column `monday item set`. Only the
|
|
339
|
+
* single positional `<col>=<value>` is in play; the rejection
|
|
340
|
+
* surface is limited to the file-vs-set-raw mutex (`--set-raw
|
|
341
|
+
* <file-col>=<json>` stays rejected by `raw-write.ts:
|
|
342
|
+
* translateRawColumnValue` per D3 — no new mutex needed here).
|
|
343
|
+
* - `'item_update_single'` — single-item `monday item update
|
|
344
|
+
* <iid>`. Multiple `--set` + `--set-raw` + `--name` flags are
|
|
345
|
+
* accepted; M38 mutex enforces "single file `--set` + no
|
|
346
|
+
* other value flags".
|
|
347
|
+
* - `'item_update_bulk'` — `monday item update --where ...`.
|
|
348
|
+
* Any file `--set` rejects with
|
|
349
|
+
* `'file_set_on_bulk_unsupported'` per D5.
|
|
350
|
+
* - `'item_create'` — `monday item create`. Any file `--set`
|
|
351
|
+
* rejects with `'file_set_on_create_unsupported'` per D6.
|
|
352
|
+
*/
|
|
353
|
+
readonly callShape: 'item_set' | 'item_update_single' | 'item_update_bulk' | 'item_create';
|
|
354
|
+
/**
|
|
355
|
+
* Resolved column entries — one per `--set` token, in argv order.
|
|
356
|
+
* Each carries the resolved column ID + type discriminator + the
|
|
357
|
+
* agent-supplied raw value (path or value-string).
|
|
358
|
+
*/
|
|
359
|
+
readonly setEntries: readonly {
|
|
360
|
+
readonly columnId: string;
|
|
361
|
+
readonly columnType: string;
|
|
362
|
+
readonly rawValue: string;
|
|
363
|
+
}[];
|
|
364
|
+
/**
|
|
365
|
+
* Resolved `--set-raw` entries — one per `--set-raw` token, in
|
|
366
|
+
* argv order. Carries the resolved column ID + type (after
|
|
367
|
+
* `resolveColumnWithRefresh`). Used for the mutex check ONLY —
|
|
368
|
+
* the actual `--set-raw` rejection for file types stays in
|
|
369
|
+
* `raw-write.ts:translateRawColumnValue` per D3.
|
|
370
|
+
*/
|
|
371
|
+
readonly setRawEntries: readonly {
|
|
372
|
+
readonly columnId: string;
|
|
373
|
+
readonly columnType: string;
|
|
374
|
+
}[];
|
|
375
|
+
/** True when `--name <n>` was passed (`item update` only). */
|
|
376
|
+
readonly hasName: boolean;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Iterates `inputs.setEntries`, identifies entries with
|
|
380
|
+
* `columnType === 'file'`, applies the mutex rules per D2 / D5 / D6
|
|
381
|
+
* closures, and returns either `{ kind: 'json' }` (no file entries),
|
|
382
|
+
* `{ kind: 'file', columnId, rawValue }` (clean dispatch path), or
|
|
383
|
+
* throws `ApiError('usage_error', ...)` on a mutex violation.
|
|
384
|
+
*
|
|
385
|
+
* Mutex priority (ratified at M38 pre-flight, applied here in IMPL):
|
|
386
|
+
*
|
|
387
|
+
* 1. **callShape gates first** — `'item_update_bulk'` rejects ALL
|
|
388
|
+
* file `--set` entries with `'file_set_on_bulk_unsupported'`
|
|
389
|
+
* (D5; defers per-item file dispatch + concurrency interaction
|
|
390
|
+
* to v0.6.x). `'item_create'` rejects with
|
|
391
|
+
* `'file_set_on_create_unsupported'` (D6; defers create-time
|
|
392
|
+
* file upload to v0.6.x — non-atomic post-create wire shape
|
|
393
|
+
* breaks §5.8 state safety).
|
|
394
|
+
* 2. **multi-file leg** — 2+ file `--set` entries on a non-rejected
|
|
395
|
+
* callShape surface `'multi_file_set_unsupported'` (M38 defers
|
|
396
|
+
* multi-file dispatch to v0.6.x).
|
|
397
|
+
* 3. **mixed leg** — 1 file `--set` + any value `--set` /
|
|
398
|
+
* `--set-raw` / `--name` surface `'mixed_file_and_value_sets'`
|
|
399
|
+
* (mixing forces non-atomic multi-leg dispatch that breaks the
|
|
400
|
+
* existing atomicity contract).
|
|
401
|
+
* 4. **clean leg** — 1 file `--set`, no other value flags, single-
|
|
402
|
+
* item non-create call → return `{ kind: 'file', columnId,
|
|
403
|
+
* rawValue }` for downstream {@link precheckLocalFile} +
|
|
404
|
+
* {@link executeFileColumnSet}.
|
|
405
|
+
*
|
|
406
|
+
* The function is sync + pure. No I/O. Path validation lives at a
|
|
407
|
+
* SEPARATE step (`precheckLocalFile` from `src/utils/file-source.ts`)
|
|
408
|
+
* that the caller runs AFTER this function returns a `kind: 'file'`
|
|
409
|
+
* result.
|
|
410
|
+
*/
|
|
411
|
+
export declare const enforceSingleFileColumnSet: (inputs: EnforceSingleFileColumnSetInputs) => FileColumnSetEnforcementResult;
|
|
412
|
+
/**
|
|
413
|
+
* Argv-level setEntry shape (`<token>=<value>` split, pre-resolution).
|
|
414
|
+
* Used as input to {@link preCheckM38FileDispatch}.
|
|
415
|
+
*/
|
|
416
|
+
export interface ArgvSetEntry {
|
|
417
|
+
readonly token: string;
|
|
418
|
+
readonly value: string;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Result of {@link preCheckM38FileDispatch}. On the `'json'` branch
|
|
422
|
+
* the action body proceeds with the standard `resolveAndTranslate` /
|
|
423
|
+
* `planChanges` path (cache is warm from this pre-check). On the
|
|
424
|
+
* `'file'` branch the action body runs {@link precheckLocalFile} +
|
|
425
|
+
* {@link executeFileColumnSet} for the live path, or emits the D4
|
|
426
|
+
* dry-run envelope.
|
|
427
|
+
*
|
|
428
|
+
* `warnings` + `source` + `cacheAgeSeconds` aggregate the
|
|
429
|
+
* resolveColumnWithRefresh legs the pre-check fired; callers thread
|
|
430
|
+
* these into the downstream success envelope (json branch into the
|
|
431
|
+
* standard path's existing aggregation seeds; file branch into the
|
|
432
|
+
* file-dispatch envelope's `warnings` + `meta.source` slots).
|
|
433
|
+
*/
|
|
434
|
+
export type PreCheckM38FileDispatchResult = {
|
|
435
|
+
readonly kind: 'json';
|
|
436
|
+
readonly warnings: readonly ResolverWarning[];
|
|
437
|
+
readonly source: 'live' | 'cache' | 'mixed' | undefined;
|
|
438
|
+
readonly cacheAgeSeconds: number | null;
|
|
439
|
+
} | {
|
|
440
|
+
readonly kind: 'file';
|
|
441
|
+
readonly columnId: string;
|
|
442
|
+
readonly rawValue: string;
|
|
443
|
+
readonly token: string;
|
|
444
|
+
readonly warnings: readonly ResolverWarning[];
|
|
445
|
+
readonly source: 'live' | 'cache' | 'mixed' | undefined;
|
|
446
|
+
readonly cacheAgeSeconds: number | null;
|
|
447
|
+
};
|
|
448
|
+
export interface PreCheckM38FileDispatchInputs {
|
|
449
|
+
readonly client: MondayClient;
|
|
450
|
+
readonly boardId: string;
|
|
451
|
+
readonly setEntries: readonly ArgvSetEntry[];
|
|
452
|
+
/**
|
|
453
|
+
* Count of `--set-raw` entries the call carries. Only the count
|
|
454
|
+
* matters for the mutex check ("file --set + ANY --set-raw"); the
|
|
455
|
+
* setRawEntries' column types do NOT need pre-resolution here.
|
|
456
|
+
* `--set-raw <file-col>=<json>` rejection stays at
|
|
457
|
+
* `translateRawColumnValue` per D3 (permanent rejection); the
|
|
458
|
+
* pre-check never routes a `--set-raw` path through M38 dispatch.
|
|
459
|
+
*/
|
|
460
|
+
readonly setRawCount: number;
|
|
461
|
+
readonly hasName: boolean;
|
|
462
|
+
readonly callShape: 'item_update_single' | 'item_update_bulk' | 'item_create';
|
|
463
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
464
|
+
readonly noCache?: boolean;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Resolves `setEntries` column types and runs the v0.6-M38 mutex
|
|
468
|
+
* check (per cli-design §5.3 step 5 "File-column dispatch leg —
|
|
469
|
+
* mutex rules"). The discipline: **enforce mutex at the column-
|
|
470
|
+
* resolution boundary**, not at the translator-rejection boundary.
|
|
471
|
+
* Pre-flight P2-1 + IMPL round-1 P2-2 both surfaced the
|
|
472
|
+
* translator-order-dependent priority drift that this resolution-
|
|
473
|
+
* boundary check fixes.
|
|
474
|
+
*
|
|
475
|
+
* **Why the pre-check fires at the action-body level rather than
|
|
476
|
+
* inside `resolveAndTranslate`.** The shared resolver helper is
|
|
477
|
+
* used by 5 sites (item set, item update single + bulk, item
|
|
478
|
+
* create); the M38 dispatch only applies to 3 (item update single
|
|
479
|
+
* + bulk + item create — item set has its own column resolution at
|
|
480
|
+
* the action body level for the single-positional shape). Folding
|
|
481
|
+
* M38 dispatch into `resolveAndTranslate` would couple the
|
|
482
|
+
* resolver helper to the file-dispatch leg; the action-body level
|
|
483
|
+
* pre-check keeps `resolveAndTranslate` translator-only.
|
|
484
|
+
*
|
|
485
|
+
* **Discriminating friendly `--set` vs `--set-raw`** — the
|
|
486
|
+
* pre-check operates on setEntries only. `--set-raw <file-col>=<json>`
|
|
487
|
+
* rejections come from `translateRawColumnValue` (D3 permanent
|
|
488
|
+
* rejection); the pre-check returns `kind: 'json'` for `--set-raw`
|
|
489
|
+
* file paths and the standard path's `resolveAndTranslate` /
|
|
490
|
+
* `planChanges` then surfaces the D3 `unsupported_column_type`
|
|
491
|
+
* rejection. The pre-check NEVER hijacks `--set-raw` paths into
|
|
492
|
+
* M38 dispatch.
|
|
493
|
+
*
|
|
494
|
+
* **Source aggregation contract.** Each resolveColumnWithRefresh
|
|
495
|
+
* call returns its own `source` / `cacheAgeSeconds`; the pre-check
|
|
496
|
+
* aggregates across `setEntries`. On the `'json'` branch the
|
|
497
|
+
* downstream `resolveAndTranslate` will re-resolve setEntries
|
|
498
|
+
* (cache hit) and produce another aggregation leg — the action
|
|
499
|
+
* body merges both aggregations so the final envelope reflects
|
|
500
|
+
* every wire / cache leg that fired. The `meta.source` of a
|
|
501
|
+
* non-file path with a single `--set` may surface as `'mixed'`
|
|
502
|
+
* (live pre-check + cache downstream) rather than `'live'`; this
|
|
503
|
+
* is correct per §6.1 source-aggregation rules — the second leg
|
|
504
|
+
* IS a cache hit.
|
|
505
|
+
*/
|
|
506
|
+
export declare const preCheckM38FileDispatch: (inputs: PreCheckM38FileDispatchInputs) => Promise<PreCheckM38FileDispatchResult>;
|
|
507
|
+
//# sourceMappingURL=file-column-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-column-set.d.ts","sourceRoot":"","sources":["../../src/api/file-column-set.ts"],"names":[],"mappings":"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"}
|