@enrichlayer/el-linear 1.15.0 → 1.16.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/dist/commands/comments.js +22 -1
- package/dist/output.d.ts +82 -0
- package/dist/output.js +82 -0
- package/package.json +6 -1
|
@@ -196,7 +196,28 @@ async function handleUpdateComment(commentId, options, command) {
|
|
|
196
196
|
else {
|
|
197
197
|
input.body = body;
|
|
198
198
|
}
|
|
199
|
-
|
|
199
|
+
let result;
|
|
200
|
+
try {
|
|
201
|
+
result = await graphQLService.rawRequest(UPDATE_COMMENT_MUTATION, { id: commentId, input });
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
// Same defense-in-depth fallback as `handleCreateComment` above: when
|
|
205
|
+
// Linear rejects `bodyData` (schema drift, unsupported node, validator
|
|
206
|
+
// quirk), retry the mutation with raw markdown `body` so the update
|
|
207
|
+
// goes through even if our prosemirror converter has fallen behind a
|
|
208
|
+
// schema change. The asymmetry between create and update used to mean
|
|
209
|
+
// any future drift would silently break updates while creates kept
|
|
210
|
+
// working — DEV-4261 closes that gap. Two call sites is the floor for
|
|
211
|
+
// extraction; copy-then-refactor on the third per the repo convention.
|
|
212
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
213
|
+
if (input.bodyData && BODY_DATA_ERROR_RE.test(msg)) {
|
|
214
|
+
const fallbackInput = { body };
|
|
215
|
+
result = await graphQLService.rawRequest(UPDATE_COMMENT_MUTATION, { id: commentId, input: fallbackInput });
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
throw err;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
200
221
|
const mutation = result.commentUpdate;
|
|
201
222
|
if (!mutation.success || !mutation.comment) {
|
|
202
223
|
throw new Error("Failed to update comment");
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public output utilities — secondary entry point for cross-CLI reuse.
|
|
3
|
+
*
|
|
4
|
+
* Other Enrich Layer CLIs (el-slack, el-sheets, el-audit, el-git,
|
|
5
|
+
* el-elasticsearch — currently in the `tools` monorepo) should depend on
|
|
6
|
+
* `@enrichlayer/el-linear` and import this module to share the same
|
|
7
|
+
* `--jq` / `--fields` / `--raw` / `--format summary` behavior and the
|
|
8
|
+
* canonical `{ data, meta }` envelope shape. DEV-3799.
|
|
9
|
+
*
|
|
10
|
+
* Why this exists rather than a separate package: linctl is the OSS
|
|
11
|
+
* canonical source of these patterns (DEV-3619, DEV-3637, DEV-3798); it
|
|
12
|
+
* already publishes to npm and ships compiled JS in `dist/`. Treating it
|
|
13
|
+
* as the host of the shared utilities means there is exactly one
|
|
14
|
+
* implementation, exactly one set of tests, and exactly one place where
|
|
15
|
+
* the envelope contract is documented. Tools-repo CLIs pick it up via
|
|
16
|
+
* `pnpm add @enrichlayer/el-linear` and `import { outputSuccess, ... }
|
|
17
|
+
* from "@enrichlayer/el-linear/output"`.
|
|
18
|
+
*
|
|
19
|
+
* Stable API — semver-tracked. Anything re-exported here MUST stay
|
|
20
|
+
* backwards-compatible across minor releases. Adding exports is fine;
|
|
21
|
+
* renaming or removing them is a breaking change.
|
|
22
|
+
*
|
|
23
|
+
* # Wiring (consumer recipe)
|
|
24
|
+
*
|
|
25
|
+
* Each CLI's `main.ts` registers four global options and a `preAction`
|
|
26
|
+
* hook to read them into the shared state:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { Command } from "commander";
|
|
30
|
+
* import {
|
|
31
|
+
* setRawMode, setJqFilter, setFieldsFilter, setOutputFormat,
|
|
32
|
+
* } from "@enrichlayer/el-linear/output";
|
|
33
|
+
*
|
|
34
|
+
* const program = new Command()
|
|
35
|
+
* .option("--raw", "strip { data, meta } wrapper from list output")
|
|
36
|
+
* .option("--jq <filter>", "apply a jq filter to the JSON output")
|
|
37
|
+
* .option("--fields <fields>", "comma-separated field allow-list")
|
|
38
|
+
* .option("--format <fmt>", "json | summary", "json");
|
|
39
|
+
*
|
|
40
|
+
* program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
41
|
+
* const o = actionCommand.optsWithGlobals();
|
|
42
|
+
* if (o.raw) setRawMode(true);
|
|
43
|
+
* if (o.jq) setJqFilter(o.jq);
|
|
44
|
+
* if (o.fields) {
|
|
45
|
+
* setFieldsFilter(o.fields.split(",").map((s: string) => s.trim()));
|
|
46
|
+
* }
|
|
47
|
+
* setOutputFormat(o.format === "summary" ? "summary" : "json");
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Then in each subcommand handler emit results via `outputList(data)` /
|
|
52
|
+
* `outputSingle(data)` / `outputSuccess(payload)`, wrap async actions in
|
|
53
|
+
* `handleAsyncCommand`, and buffer informational messages via
|
|
54
|
+
* `outputWarning`. The shared state in this module takes care of `--jq`,
|
|
55
|
+
* `--fields`, `--raw`, and summary rendering uniformly.
|
|
56
|
+
*
|
|
57
|
+
* Adapt the option names and flags to your CLI's existing conventions —
|
|
58
|
+
* the contract is the four setter calls (`setRawMode`, `setJqFilter`,
|
|
59
|
+
* `setFieldsFilter`, `setOutputFormat`), not the literal `--jq` /
|
|
60
|
+
* `--fields` / `--raw` / `--format` names. A CLI that already exposes
|
|
61
|
+
* `--json` / `--summary` shorthands can keep them as long as the
|
|
62
|
+
* preAction hook ends up calling the same setters with equivalent values.
|
|
63
|
+
*
|
|
64
|
+
* # What is NOT exported
|
|
65
|
+
*
|
|
66
|
+
* - `--format summary` dispatch tables are linctl-specific (Linear
|
|
67
|
+
* resources). Other CLIs that want summary rendering should either
|
|
68
|
+
* ship `--format json` only or register their own per-command summary
|
|
69
|
+
* path that does not consume this module's `setOutputFormat("summary")`.
|
|
70
|
+
* - `outputError` is intentionally internal — it calls `process.exit(1)`
|
|
71
|
+
* directly. Consumers funnel errors through `handleAsyncCommand`, which
|
|
72
|
+
* in turn calls `outputError`. Don't re-export the bare function; the
|
|
73
|
+
* wrapper is the contract.
|
|
74
|
+
* - Token-sanitization (`sanitizeForLog`) is internal to the error path.
|
|
75
|
+
* Consumers that route errors through `handleAsyncCommand` automatically
|
|
76
|
+
* get token redaction on the error path — no separate redactor needed
|
|
77
|
+
* for that case. If a consumer wants sanitization for something OTHER
|
|
78
|
+
* than thrown errors (e.g. a custom debug log), it should pull a small
|
|
79
|
+
* redactor of its own; coupling token redaction to the output layer
|
|
80
|
+
* would make this API surface stickier than it needs to be.
|
|
81
|
+
*/
|
|
82
|
+
export { type CliListEnvelope, getOutputFormat, handleAsyncCommand, type ListExtraMeta, type ListMeta, outputList, outputSingle, outputSuccess, outputWarning, resetWarnings, setFieldsFilter, setJqFilter, setOutputFormat, setRawMode, warnIfTruncated, } from "./utils/output.js";
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public output utilities — secondary entry point for cross-CLI reuse.
|
|
3
|
+
*
|
|
4
|
+
* Other Enrich Layer CLIs (el-slack, el-sheets, el-audit, el-git,
|
|
5
|
+
* el-elasticsearch — currently in the `tools` monorepo) should depend on
|
|
6
|
+
* `@enrichlayer/el-linear` and import this module to share the same
|
|
7
|
+
* `--jq` / `--fields` / `--raw` / `--format summary` behavior and the
|
|
8
|
+
* canonical `{ data, meta }` envelope shape. DEV-3799.
|
|
9
|
+
*
|
|
10
|
+
* Why this exists rather than a separate package: linctl is the OSS
|
|
11
|
+
* canonical source of these patterns (DEV-3619, DEV-3637, DEV-3798); it
|
|
12
|
+
* already publishes to npm and ships compiled JS in `dist/`. Treating it
|
|
13
|
+
* as the host of the shared utilities means there is exactly one
|
|
14
|
+
* implementation, exactly one set of tests, and exactly one place where
|
|
15
|
+
* the envelope contract is documented. Tools-repo CLIs pick it up via
|
|
16
|
+
* `pnpm add @enrichlayer/el-linear` and `import { outputSuccess, ... }
|
|
17
|
+
* from "@enrichlayer/el-linear/output"`.
|
|
18
|
+
*
|
|
19
|
+
* Stable API — semver-tracked. Anything re-exported here MUST stay
|
|
20
|
+
* backwards-compatible across minor releases. Adding exports is fine;
|
|
21
|
+
* renaming or removing them is a breaking change.
|
|
22
|
+
*
|
|
23
|
+
* # Wiring (consumer recipe)
|
|
24
|
+
*
|
|
25
|
+
* Each CLI's `main.ts` registers four global options and a `preAction`
|
|
26
|
+
* hook to read them into the shared state:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { Command } from "commander";
|
|
30
|
+
* import {
|
|
31
|
+
* setRawMode, setJqFilter, setFieldsFilter, setOutputFormat,
|
|
32
|
+
* } from "@enrichlayer/el-linear/output";
|
|
33
|
+
*
|
|
34
|
+
* const program = new Command()
|
|
35
|
+
* .option("--raw", "strip { data, meta } wrapper from list output")
|
|
36
|
+
* .option("--jq <filter>", "apply a jq filter to the JSON output")
|
|
37
|
+
* .option("--fields <fields>", "comma-separated field allow-list")
|
|
38
|
+
* .option("--format <fmt>", "json | summary", "json");
|
|
39
|
+
*
|
|
40
|
+
* program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
41
|
+
* const o = actionCommand.optsWithGlobals();
|
|
42
|
+
* if (o.raw) setRawMode(true);
|
|
43
|
+
* if (o.jq) setJqFilter(o.jq);
|
|
44
|
+
* if (o.fields) {
|
|
45
|
+
* setFieldsFilter(o.fields.split(",").map((s: string) => s.trim()));
|
|
46
|
+
* }
|
|
47
|
+
* setOutputFormat(o.format === "summary" ? "summary" : "json");
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Then in each subcommand handler emit results via `outputList(data)` /
|
|
52
|
+
* `outputSingle(data)` / `outputSuccess(payload)`, wrap async actions in
|
|
53
|
+
* `handleAsyncCommand`, and buffer informational messages via
|
|
54
|
+
* `outputWarning`. The shared state in this module takes care of `--jq`,
|
|
55
|
+
* `--fields`, `--raw`, and summary rendering uniformly.
|
|
56
|
+
*
|
|
57
|
+
* Adapt the option names and flags to your CLI's existing conventions —
|
|
58
|
+
* the contract is the four setter calls (`setRawMode`, `setJqFilter`,
|
|
59
|
+
* `setFieldsFilter`, `setOutputFormat`), not the literal `--jq` /
|
|
60
|
+
* `--fields` / `--raw` / `--format` names. A CLI that already exposes
|
|
61
|
+
* `--json` / `--summary` shorthands can keep them as long as the
|
|
62
|
+
* preAction hook ends up calling the same setters with equivalent values.
|
|
63
|
+
*
|
|
64
|
+
* # What is NOT exported
|
|
65
|
+
*
|
|
66
|
+
* - `--format summary` dispatch tables are linctl-specific (Linear
|
|
67
|
+
* resources). Other CLIs that want summary rendering should either
|
|
68
|
+
* ship `--format json` only or register their own per-command summary
|
|
69
|
+
* path that does not consume this module's `setOutputFormat("summary")`.
|
|
70
|
+
* - `outputError` is intentionally internal — it calls `process.exit(1)`
|
|
71
|
+
* directly. Consumers funnel errors through `handleAsyncCommand`, which
|
|
72
|
+
* in turn calls `outputError`. Don't re-export the bare function; the
|
|
73
|
+
* wrapper is the contract.
|
|
74
|
+
* - Token-sanitization (`sanitizeForLog`) is internal to the error path.
|
|
75
|
+
* Consumers that route errors through `handleAsyncCommand` automatically
|
|
76
|
+
* get token redaction on the error path — no separate redactor needed
|
|
77
|
+
* for that case. If a consumer wants sanitization for something OTHER
|
|
78
|
+
* than thrown errors (e.g. a custom debug log), it should pull a small
|
|
79
|
+
* redactor of its own; coupling token redaction to the output layer
|
|
80
|
+
* would make this API surface stickier than it needs to be.
|
|
81
|
+
*/
|
|
82
|
+
export { getOutputFormat, handleAsyncCommand, outputList, outputSingle, outputSuccess, outputWarning, resetWarnings, setFieldsFilter, setJqFilter, setOutputFormat, setRawMode, warnIfTruncated, } from "./utils/output.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enrichlayer/el-linear",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "A pragmatic CLI for Linear.app — deterministic team/label/member resolution, structured issue validation, configurable term enforcement, and a GraphQL escape hatch.",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"types": "dist/main.d.ts",
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/main.d.ts",
|
|
11
11
|
"import": "./dist/main.js"
|
|
12
|
+
},
|
|
13
|
+
"./output": {
|
|
14
|
+
"types": "./dist/output.d.ts",
|
|
15
|
+
"import": "./dist/output.js",
|
|
16
|
+
"default": "./dist/output.js"
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
19
|
"sideEffects": false,
|