@enrichlayer/el-linear 1.2.0 → 1.5.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/README.md +128 -2
- package/dist/auth/oauth-callback.d.ts +40 -0
- package/dist/auth/oauth-callback.js +142 -0
- package/dist/auth/oauth-client.d.ts +55 -0
- package/dist/auth/oauth-client.js +134 -0
- package/dist/auth/oauth-fs.d.ts +1 -0
- package/dist/auth/oauth-fs.js +29 -0
- package/dist/auth/oauth-headless.d.ts +38 -0
- package/dist/auth/oauth-headless.js +50 -0
- package/dist/auth/oauth-storage.d.ts +51 -0
- package/dist/auth/oauth-storage.js +87 -0
- package/dist/auth/oauth-token.d.ts +70 -0
- package/dist/auth/oauth-token.js +141 -0
- package/dist/auth/token-resolver.d.ts +48 -0
- package/dist/auth/token-resolver.js +95 -0
- package/dist/commands/init/index.d.ts +7 -0
- package/dist/commands/init/index.js +27 -1
- package/dist/commands/init/oauth.d.ts +85 -0
- package/dist/commands/init/oauth.js +308 -0
- package/dist/commands/init/shared.js +30 -5
- package/dist/commands/profile/migrate-legacy.d.ts +96 -0
- package/dist/commands/profile/migrate-legacy.js +272 -0
- package/dist/commands/profile.d.ts +46 -0
- package/dist/commands/profile.js +191 -0
- package/dist/commands/refs.d.ts +18 -0
- package/dist/commands/refs.js +95 -0
- package/dist/config/config.d.ts +2 -0
- package/dist/config/config.js +20 -5
- package/dist/config/paths.d.ts +27 -0
- package/dist/config/paths.js +77 -0
- package/dist/main.js +14 -1
- package/dist/utils/auth.js +25 -3
- package/dist/utils/graphql-service.d.ts +16 -1
- package/dist/utils/graphql-service.js +19 -7
- package/dist/utils/issue-reference-wrapper.d.ts +19 -5
- package/dist/utils/issue-reference-wrapper.js +33 -6
- package/dist/utils/legacy-config-detection.d.ts +47 -0
- package/dist/utils/legacy-config-detection.js +90 -0
- package/dist/utils/migration-hint.d.ts +46 -0
- package/dist/utils/migration-hint.js +90 -0
- package/package.json +4 -4
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Once-per-process stderr hint for legacy-config drift.
|
|
3
|
+
*
|
|
4
|
+
* Wired into the auth-failure path in `auth.ts`. When the legacy single-file
|
|
5
|
+
* config exists but no token can be found anywhere (the >=1.4 post-upgrade
|
|
6
|
+
* scenario), we emit one stderr line pointing the user at
|
|
7
|
+
* `el-linear profile migrate-legacy` *before* the regular "No API token
|
|
8
|
+
* found" error fires.
|
|
9
|
+
*
|
|
10
|
+
* Constraints:
|
|
11
|
+
*
|
|
12
|
+
* - **stderr only** — stdout is reserved for the JSON error payload that
|
|
13
|
+
* machine callers parse, and the hint must not corrupt that stream.
|
|
14
|
+
* - **Once per process** — even if a script invokes el-linear in a tight
|
|
15
|
+
* loop within a single Node process (uncommon but possible), only the
|
|
16
|
+
* first failure prints. Anything more is noise.
|
|
17
|
+
* - **Suppressible** — `EL_LINEAR_SKIP_MIGRATION_HINT=1` silences the hint
|
|
18
|
+
* for users who've decided to stay on the legacy layout intentionally.
|
|
19
|
+
* The env var is read at *emission time*, not module load, so toggling
|
|
20
|
+
* it in tests works without re-importing.
|
|
21
|
+
* - **Non-blocking** — never throws, never delays the underlying auth
|
|
22
|
+
* error. The hint is purely informational.
|
|
23
|
+
*/
|
|
24
|
+
import { detectLegacyDrift, } from "./legacy-config-detection.js";
|
|
25
|
+
let hintAlreadyEmitted = false;
|
|
26
|
+
/**
|
|
27
|
+
* Test seam — resets the once-per-process latch so each test starts fresh.
|
|
28
|
+
* Production code never calls this.
|
|
29
|
+
*/
|
|
30
|
+
export function _resetMigrationHintForTests() {
|
|
31
|
+
hintAlreadyEmitted = false;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Emit the migration hint to stderr if (and only if) legacy drift is
|
|
35
|
+
* detected, the latch hasn't fired this process, and the suppress env var
|
|
36
|
+
* isn't set. Returns the detection state so callers can branch (or log).
|
|
37
|
+
*
|
|
38
|
+
* Optional `fsImpl` lets tests drive detection without touching disk.
|
|
39
|
+
* Optional `stderr` lets tests capture the output without spying on the
|
|
40
|
+
* global stream.
|
|
41
|
+
*/
|
|
42
|
+
export function maybeEmitMigrationHint(fsImpl, stderr = process.stderr) {
|
|
43
|
+
const state = detectLegacyDrift(fsImpl);
|
|
44
|
+
// Read the env var at call time — the suppress flag may be flipped between
|
|
45
|
+
// commands in long-lived test processes.
|
|
46
|
+
if (process.env.EL_LINEAR_SKIP_MIGRATION_HINT === "1") {
|
|
47
|
+
return state;
|
|
48
|
+
}
|
|
49
|
+
if (hintAlreadyEmitted) {
|
|
50
|
+
return state;
|
|
51
|
+
}
|
|
52
|
+
const message = formatHint(state);
|
|
53
|
+
if (message === null) {
|
|
54
|
+
return state;
|
|
55
|
+
}
|
|
56
|
+
hintAlreadyEmitted = true;
|
|
57
|
+
stderr.write(`${message}\n`);
|
|
58
|
+
return state;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Render the hint string for a given state. Returns null when no hint
|
|
62
|
+
* should be emitted (no-drift). Exported for unit testing.
|
|
63
|
+
*/
|
|
64
|
+
export function formatHint(state) {
|
|
65
|
+
if (state.kind === "no-drift")
|
|
66
|
+
return null;
|
|
67
|
+
if (state.kind === "broken-active-profile") {
|
|
68
|
+
return [
|
|
69
|
+
`el-linear: active profile "${state.pointedAt}" doesn't exist.`,
|
|
70
|
+
"Switch with:",
|
|
71
|
+
"",
|
|
72
|
+
" el-linear profile use <name>",
|
|
73
|
+
"",
|
|
74
|
+
"Or list available profiles:",
|
|
75
|
+
"",
|
|
76
|
+
" el-linear profile list",
|
|
77
|
+
"",
|
|
78
|
+
"Or suppress this hint with EL_LINEAR_SKIP_MIGRATION_HINT=1.",
|
|
79
|
+
].join("\n");
|
|
80
|
+
}
|
|
81
|
+
// legacy-no-token
|
|
82
|
+
return [
|
|
83
|
+
`el-linear: legacy config detected at ${state.legacyConfigPath}`,
|
|
84
|
+
"but no token. Migrate with:",
|
|
85
|
+
"",
|
|
86
|
+
" el-linear profile migrate-legacy [--name <profile>]",
|
|
87
|
+
"",
|
|
88
|
+
"Or suppress this hint with EL_LINEAR_SKIP_MIGRATION_HINT=1.",
|
|
89
|
+
].join("\n");
|
|
90
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enrichlayer/el-linear",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.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",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"picocolors": "^1.1.1"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@biomejs/biome": "^2.4.
|
|
55
|
+
"@biomejs/biome": "^2.4.14",
|
|
56
56
|
"@types/node": "^25.0.0",
|
|
57
57
|
"graphql": "^16.0.0",
|
|
58
|
-
"tsx": "^4.
|
|
59
|
-
"typescript": "^
|
|
58
|
+
"tsx": "^4.21.0",
|
|
59
|
+
"typescript": "^6.0.3",
|
|
60
60
|
"vitest": "^4.0.18"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|