@enrichlayer/el-linear 1.22.0 → 1.23.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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig } from "../config/config.js";
|
|
2
2
|
import { resolveTeam } from "../config/resolver.js";
|
|
3
|
-
import { ARCHIVE_PROJECT_MUTATION, CREATE_PROJECT_MUTATION, DELETE_PROJECT_MUTATION, GET_PROJECT_QUERY, GET_PROJECT_TEAM_ISSUES_QUERY, PROJECT_BY_ID_QUERY, SEARCH_PROJECTS_BY_NAME_QUERY, UPDATE_PROJECT_MUTATION, } from "../queries/projects.js";
|
|
3
|
+
import { ARCHIVE_PROJECT_MUTATION, CREATE_PROJECT_MUTATION, DELETE_PROJECT_MUTATION, GET_PROJECT_QUERY, GET_PROJECT_TEAM_ISSUES_QUERY, PROJECT_BY_ID_QUERY, PROJECT_READ_QUERY, SEARCH_PROJECTS_BY_NAME_QUERY, UPDATE_PROJECT_MUTATION, } from "../queries/projects.js";
|
|
4
4
|
import { cached, resolveCacheTTL } from "../utils/disk-cache.js";
|
|
5
5
|
import { createGraphQLService } from "../utils/graphql-service.js";
|
|
6
6
|
import { createLinearService } from "../utils/linear-service.js";
|
|
@@ -413,6 +413,30 @@ async function handleDeleteProject(projectNameOrId, _options, command) {
|
|
|
413
413
|
lastSyncId: payload.lastSyncId,
|
|
414
414
|
});
|
|
415
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Read a single project (DEV-4610). Resolves the identifier through the same
|
|
418
|
+
* `resolveProjectId` path the `--project` flags use (UUID / slug / URL / name),
|
|
419
|
+
* fetches the full project, and emits it. `teams.nodes` is flattened to a plain
|
|
420
|
+
* array so the `--format summary` project renderer (and the JSON shape) match
|
|
421
|
+
* `projects list` — the formatter expects a flat team list, not a `{ nodes }`
|
|
422
|
+
* connection. Replaces the raw-`graphql` workaround for grabbing a project's
|
|
423
|
+
* url / content / lead.
|
|
424
|
+
*/
|
|
425
|
+
async function handleReadProject(projectNameOrId, _options, command) {
|
|
426
|
+
const rootOpts = getRootOpts(command);
|
|
427
|
+
const graphQLService = await createGraphQLService(rootOpts);
|
|
428
|
+
const linearService = await createLinearService(rootOpts);
|
|
429
|
+
const projectId = await linearService.resolveProjectId(projectNameOrId);
|
|
430
|
+
const result = await graphQLService.rawRequest(PROJECT_READ_QUERY, { id: projectId });
|
|
431
|
+
if (!result.project) {
|
|
432
|
+
throw new Error(`Project "${projectNameOrId}" not found`);
|
|
433
|
+
}
|
|
434
|
+
const { teams, ...rest } = result.project;
|
|
435
|
+
outputSuccess({
|
|
436
|
+
...rest,
|
|
437
|
+
teams: teams.nodes.map((t) => ({ id: t.id, key: t.key, name: t.name })),
|
|
438
|
+
});
|
|
439
|
+
}
|
|
416
440
|
export function setupProjectsCommands(program) {
|
|
417
441
|
const projects = program
|
|
418
442
|
.command("projects")
|
|
@@ -435,6 +459,10 @@ export function setupProjectsCommands(program) {
|
|
|
435
459
|
.command("delete <project>")
|
|
436
460
|
.description("Delete (trash) a project (resolves names)")
|
|
437
461
|
.action(handleAsyncCommand(handleDeleteProject));
|
|
462
|
+
projects
|
|
463
|
+
.command("read <project>")
|
|
464
|
+
.description("Read one project's full details (resolves name/slug/URL/ID). `--format summary` shows state, lead, teams, target, progress, url; JSON includes description/content.")
|
|
465
|
+
.action(handleAsyncCommand(handleReadProject));
|
|
438
466
|
projects
|
|
439
467
|
.command("list")
|
|
440
468
|
.description("List projects")
|
|
@@ -34,6 +34,24 @@ interface ProjectWithIssuesNode extends ProjectBaseNode {
|
|
|
34
34
|
export interface ProjectByIdResponse {
|
|
35
35
|
project: ProjectBaseNode | null;
|
|
36
36
|
}
|
|
37
|
+
/** Full project read (`PROJECT_READ_QUERY`) — base fields + summary/JSON fields. */
|
|
38
|
+
interface ProjectReadNode extends ProjectBaseNode {
|
|
39
|
+
state: string;
|
|
40
|
+
progress: number;
|
|
41
|
+
url: string;
|
|
42
|
+
startDate: string | null;
|
|
43
|
+
targetDate: string | null;
|
|
44
|
+
description: string | null;
|
|
45
|
+
content: string | null;
|
|
46
|
+
lead: {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
displayName: string;
|
|
50
|
+
} | null;
|
|
51
|
+
}
|
|
52
|
+
export interface ProjectReadResponse {
|
|
53
|
+
project: ProjectReadNode | null;
|
|
54
|
+
}
|
|
37
55
|
export interface GetProjectResponse {
|
|
38
56
|
projects: {
|
|
39
57
|
nodes: ProjectBaseNode[];
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
export declare const TEAM_LOOKUP_QUERY = "\n query TeamLookup($key: String) {\n teams(filter: { or: [{ key: { eq: $key } }, { name: { eq: $key } }] }, first: 1) {\n nodes { id key name }\n }\n }\n";
|
|
2
2
|
export declare const PROJECT_BY_ID_QUERY = "\n query ProjectById($id: String!) {\n project(id: $id) {\n id\n name\n teams {\n nodes { id key name }\n }\n }\n }\n";
|
|
3
|
+
/**
|
|
4
|
+
* Full single-project read for `el-linear projects read` (DEV-4610). Carries
|
|
5
|
+
* everything the `--format summary` project renderer shows (name, state, lead,
|
|
6
|
+
* teams, target, progress, url) plus the long-form `description`/`content` the
|
|
7
|
+
* JSON envelope exposes — so callers no longer fall back to a raw `graphql`
|
|
8
|
+
* query for a project URL or its content. The `progress` + `teams` fields also
|
|
9
|
+
* make the payload self-describing to the summary kind-inference.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PROJECT_READ_QUERY = "\n query ProjectRead($id: String!) {\n project(id: $id) {\n id\n name\n state\n progress\n url\n startDate\n targetDate\n description\n content\n lead { id name displayName }\n teams {\n nodes { id key name }\n }\n }\n }\n";
|
|
3
12
|
export declare const GET_PROJECT_QUERY = "\n query GetProject($name: String!) {\n projects(filter: { name: { eqIgnoreCase: $name } }, first: 1) {\n nodes {\n id\n name\n teams {\n nodes {\n id\n key\n name\n }\n }\n }\n }\n }\n";
|
|
4
13
|
export declare const GET_PROJECT_TEAM_ISSUES_QUERY = "\n query GetProjectTeamIssues($projectId: String!, $teamId: String!) {\n project(id: $projectId) {\n id\n name\n teams {\n nodes {\n id\n key\n name\n }\n }\n issues(filter: { team: { id: { eq: $teamId } } }, first: 50) {\n nodes {\n id\n identifier\n title\n }\n }\n }\n }\n";
|
|
5
14
|
export declare const SEARCH_PROJECTS_BY_NAME_QUERY = "\n query SearchProjectsByName($name: String!) {\n projects(filter: { name: { containsIgnoreCase: $name } }, first: 10) {\n nodes {\n id\n name\n state\n teams {\n nodes { id key name }\n }\n }\n }\n }\n";
|
package/dist/queries/projects.js
CHANGED
|
@@ -16,6 +16,33 @@ export const PROJECT_BY_ID_QUERY = `
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
`;
|
|
19
|
+
/**
|
|
20
|
+
* Full single-project read for `el-linear projects read` (DEV-4610). Carries
|
|
21
|
+
* everything the `--format summary` project renderer shows (name, state, lead,
|
|
22
|
+
* teams, target, progress, url) plus the long-form `description`/`content` the
|
|
23
|
+
* JSON envelope exposes — so callers no longer fall back to a raw `graphql`
|
|
24
|
+
* query for a project URL or its content. The `progress` + `teams` fields also
|
|
25
|
+
* make the payload self-describing to the summary kind-inference.
|
|
26
|
+
*/
|
|
27
|
+
export const PROJECT_READ_QUERY = `
|
|
28
|
+
query ProjectRead($id: String!) {
|
|
29
|
+
project(id: $id) {
|
|
30
|
+
id
|
|
31
|
+
name
|
|
32
|
+
state
|
|
33
|
+
progress
|
|
34
|
+
url
|
|
35
|
+
startDate
|
|
36
|
+
targetDate
|
|
37
|
+
description
|
|
38
|
+
content
|
|
39
|
+
lead { id name displayName }
|
|
40
|
+
teams {
|
|
41
|
+
nodes { id key name }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
19
46
|
export const GET_PROJECT_QUERY = `
|
|
20
47
|
query GetProject($name: String!) {
|
|
21
48
|
projects(filter: { name: { eqIgnoreCase: $name } }, first: 1) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enrichlayer/el-linear",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.23.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",
|