@backstage/cli-module-search 0.0.0-nightly-20260928023907 → 0.2.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 +6 -4
- package/dist/commands/docsSearch.cjs.js +40 -50
- package/dist/commands/docsSearch.cjs.js.map +1 -1
- package/dist/commands/search.cjs.js +43 -53
- package/dist/commands/search.cjs.js.map +1 -1
- package/dist/lib/intentFormat.cjs.js +31 -1
- package/dist/lib/intentFormat.cjs.js.map +1 -1
- package/dist/lib/resolveAuth.cjs.js +9 -2
- package/dist/lib/resolveAuth.cjs.js.map +1 -1
- package/dist/package.json.cjs.js +4 -4
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @backstage/cli-module-search
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.2.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
@@ -12,15 +12,17 @@
|
|
|
12
12
|
- `@backstage/cli-module-scaffolder`: `template list`, `template execute`, `template dry-run`
|
|
13
13
|
- `@backstage/cli-module-search`: `search`, `docs search`
|
|
14
14
|
|
|
15
|
-
The commands
|
|
15
|
+
The commands take their main input as a positional argument: an entity or template reference, a file path (or `-` for standard input) for `catalog validate` and `template dry-run`, a URL for `catalog register`, and the search terms for `search` and `docs search`. Repeatable `key=value` flags are used for filters, template values, and secrets, and comma-separated lists for `--fields`. Unknown flags are rejected.
|
|
16
|
+
|
|
17
|
+
The commands that list results, `catalog list`, `template list`, `search`, and `docs search`, support `--output human` (the default) or `--output json`, along with `--limit` and `--cursor` for paging. Each command prints a single page. Human output shows how many results were shown and, when more are available, prints the `--cursor` value to continue from. All other commands always print JSON. `catalog validate` checks every entity in a multi-document YAML file and prints a JSON array with one result per entity. `catalog validate` and `template dry-run` exit with a non-zero code when the input is invalid, while connection and authentication problems are reported as errors.
|
|
16
18
|
|
|
17
19
|
`@backstage/cli-node` now provides shared parsers for repeatable `key=value` inputs and comma-separated lists.
|
|
18
20
|
|
|
19
21
|
### Patch Changes
|
|
20
22
|
|
|
21
23
|
- Updated dependencies
|
|
22
|
-
- @backstage/cli-node@0.
|
|
23
|
-
- @backstage/errors@
|
|
24
|
+
- @backstage/cli-node@0.3.5
|
|
25
|
+
- @backstage/errors@1.3.2
|
|
24
26
|
|
|
25
27
|
## 0.2.0-next.0
|
|
26
28
|
|
|
@@ -8,73 +8,63 @@ var resolveAuth = require('../lib/resolveAuth.cjs.js');
|
|
|
8
8
|
var intentFormat = require('../lib/intentFormat.cjs.js');
|
|
9
9
|
|
|
10
10
|
var docsSearch = async ({ args, info }) => {
|
|
11
|
-
const
|
|
12
|
-
const flagArgs = [];
|
|
13
|
-
let skipNext = false;
|
|
14
|
-
for (let i = 0; i < args.length; i++) {
|
|
15
|
-
if (skipNext) {
|
|
16
|
-
skipNext = false;
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
if (args[i].startsWith("-")) {
|
|
20
|
-
flagArgs.push(args[i]);
|
|
21
|
-
if (i + 1 < args.length && !args[i + 1].startsWith("-") && !args[i].includes("=")) {
|
|
22
|
-
flagArgs.push(args[i + 1]);
|
|
23
|
-
skipNext = true;
|
|
24
|
-
}
|
|
25
|
-
} else {
|
|
26
|
-
nonFlagArgs.push(args[i]);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const { flags } = cleye.cli(
|
|
11
|
+
const parsed = cleye.cli(
|
|
30
12
|
{
|
|
31
13
|
name: info.usage,
|
|
14
|
+
strictFlags: true,
|
|
15
|
+
parameters: ["<term...>"],
|
|
32
16
|
flags: {
|
|
33
|
-
|
|
17
|
+
limit: {
|
|
34
18
|
type: Number,
|
|
35
|
-
description: "
|
|
36
|
-
},
|
|
37
|
-
"page-cursor": {
|
|
38
|
-
type: String,
|
|
39
|
-
description: "Pagination cursor"
|
|
19
|
+
description: "Maximum number of results to return per page"
|
|
40
20
|
},
|
|
41
|
-
|
|
21
|
+
cursor: {
|
|
42
22
|
type: String,
|
|
43
|
-
description: "
|
|
23
|
+
description: "Continue from the cursor returned by a previous page"
|
|
44
24
|
},
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
description: "Name of the instance to use"
|
|
48
|
-
}
|
|
25
|
+
...intentFormat.outputFlag,
|
|
26
|
+
...resolveAuth.instanceFlag
|
|
49
27
|
}
|
|
50
28
|
},
|
|
51
29
|
void 0,
|
|
52
|
-
|
|
30
|
+
args
|
|
53
31
|
);
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
throw new Error("Search term is required. Usage: docs search <term>");
|
|
57
|
-
}
|
|
32
|
+
const { flags } = parsed;
|
|
33
|
+
const term = parsed._.term.join(" ");
|
|
58
34
|
const mode = intentFormat.parseOutputFlag(flags);
|
|
59
35
|
const { accessToken, baseUrl } = await resolveAuth.resolveAuth(flags.instance);
|
|
60
36
|
const client = new SearchClient.SearchClient(baseUrl, accessToken);
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
37
|
+
const fetchPage = async (cursor) => {
|
|
38
|
+
const response = await client.query({
|
|
39
|
+
term,
|
|
40
|
+
types: ["techdocs"],
|
|
41
|
+
pageLimit: flags.limit,
|
|
42
|
+
pageCursor: cursor
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
results: response.results,
|
|
46
|
+
nextPageCursor: response.nextPageCursor,
|
|
47
|
+
totalItems: response.numberOfResults,
|
|
48
|
+
hasMoreResults: response.nextPageCursor !== void 0
|
|
49
|
+
};
|
|
72
50
|
};
|
|
73
51
|
if (mode === "json") {
|
|
74
|
-
intentFormat.writeJson(
|
|
75
|
-
|
|
76
|
-
process.stdout.write(intentFormat.formatSearchResults(result.results));
|
|
52
|
+
intentFormat.writeJson(await fetchPage(flags.cursor));
|
|
53
|
+
return;
|
|
77
54
|
}
|
|
55
|
+
await intentFormat.printPage(
|
|
56
|
+
async (cursor) => {
|
|
57
|
+
const page = await fetchPage(cursor);
|
|
58
|
+
return {
|
|
59
|
+
...page,
|
|
60
|
+
count: page.results.length,
|
|
61
|
+
total: page.totalItems,
|
|
62
|
+
nextCursor: page.nextPageCursor
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
(page) => process.stdout.write(intentFormat.formatSearchResults(page.results)),
|
|
66
|
+
flags.cursor
|
|
67
|
+
);
|
|
78
68
|
};
|
|
79
69
|
|
|
80
70
|
exports.default = docsSearch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docsSearch.cjs.js","sources":["../../src/commands/docsSearch.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { SearchClient } from '../lib/SearchClient';\nimport { resolveAuth } from '../lib/resolveAuth';\nimport {\n parseOutputFlag,\n writeJson,\n formatSearchResults,\n} from '../lib/intentFormat';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const
|
|
1
|
+
{"version":3,"file":"docsSearch.cjs.js","sources":["../../src/commands/docsSearch.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { SearchClient } from '../lib/SearchClient';\nimport { instanceFlag, resolveAuth } from '../lib/resolveAuth';\nimport {\n outputFlag,\n printPage,\n parseOutputFlag,\n writeJson,\n formatSearchResults,\n} from '../lib/intentFormat';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const parsed = cli(\n {\n name: info.usage,\n strictFlags: true,\n parameters: ['<term...>'],\n flags: {\n limit: {\n type: Number,\n description: 'Maximum number of results to return per page',\n },\n cursor: {\n type: String,\n description: 'Continue from the cursor returned by a previous page',\n },\n ...outputFlag,\n ...instanceFlag,\n },\n },\n undefined,\n args,\n );\n const { flags } = parsed;\n\n const term = parsed._.term.join(' ');\n const mode = parseOutputFlag(flags as Record<string, unknown>);\n\n const { accessToken, baseUrl } = await resolveAuth(flags.instance);\n const client = new SearchClient(baseUrl, accessToken);\n\n const fetchPage = async (cursor?: string) => {\n const response = await client.query({\n term,\n types: ['techdocs'],\n pageLimit: flags.limit,\n pageCursor: cursor,\n });\n return {\n results: response.results,\n nextPageCursor: response.nextPageCursor,\n totalItems: response.numberOfResults,\n hasMoreResults: response.nextPageCursor !== undefined,\n };\n };\n\n if (mode === 'json') {\n writeJson(await fetchPage(flags.cursor));\n return;\n }\n\n await printPage(\n async cursor => {\n const page = await fetchPage(cursor);\n return {\n ...page,\n count: page.results.length,\n total: page.totalItems,\n nextCursor: page.nextPageCursor,\n };\n },\n page => process.stdout.write(formatSearchResults(page.results)),\n flags.cursor,\n );\n};\n"],"names":["cli","outputFlag","instanceFlag","parseOutputFlag","resolveAuth","SearchClient","writeJson","printPage","formatSearchResults"],"mappings":";;;;;;;;;AA4BA,iBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM,MAAA,GAASA,SAAA;AAAA,IACb;AAAA,MACE,MAAM,IAAA,CAAK,KAAA;AAAA,MACX,WAAA,EAAa,IAAA;AAAA,MACb,UAAA,EAAY,CAAC,WAAW,CAAA;AAAA,MACxB,KAAA,EAAO;AAAA,QACL,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,GAAGC,uBAAA;AAAA,QACH,GAAGC;AAAA;AACL,KACF;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAElB,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAA;AACnC,EAAA,MAAM,IAAA,GAAOC,6BAAgB,KAAgC,CAAA;AAE7D,EAAA,MAAM,EAAE,WAAA,EAAa,OAAA,KAAY,MAAMC,uBAAA,CAAY,MAAM,QAAQ,CAAA;AACjE,EAAA,MAAM,MAAA,GAAS,IAAIC,yBAAA,CAAa,OAAA,EAAS,WAAW,CAAA;AAEpD,EAAA,MAAM,SAAA,GAAY,OAAO,MAAA,KAAoB;AAC3C,IAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,KAAA,CAAM;AAAA,MAClC,IAAA;AAAA,MACA,KAAA,EAAO,CAAC,UAAU,CAAA;AAAA,MAClB,WAAW,KAAA,CAAM,KAAA;AAAA,MACjB,UAAA,EAAY;AAAA,KACb,CAAA;AACD,IAAA,OAAO;AAAA,MACL,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB,gBAAgB,QAAA,CAAS,cAAA;AAAA,MACzB,YAAY,QAAA,CAAS,eAAA;AAAA,MACrB,cAAA,EAAgB,SAAS,cAAA,KAAmB;AAAA,KAC9C;AAAA,EACF,CAAA;AAEA,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAAC,sBAAA,CAAU,MAAM,SAAA,CAAU,KAAA,CAAM,MAAM,CAAC,CAAA;AACvC,IAAA;AAAA,EACF;AAEA,EAAA,MAAMC,sBAAA;AAAA,IACJ,OAAM,MAAA,KAAU;AACd,MAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,MAAM,CAAA;AACnC,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,KAAA,EAAO,KAAK,OAAA,CAAQ,MAAA;AAAA,QACpB,OAAO,IAAA,CAAK,UAAA;AAAA,QACZ,YAAY,IAAA,CAAK;AAAA,OACnB;AAAA,IACF,CAAA;AAAA,IACA,UAAQ,OAAA,CAAQ,MAAA,CAAO,MAAMC,gCAAA,CAAoB,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,IAC9D,KAAA,CAAM;AAAA,GACR;AACF,CAAA;;"}
|
|
@@ -9,86 +9,76 @@ var resolveAuth = require('../lib/resolveAuth.cjs.js');
|
|
|
9
9
|
var intentFormat = require('../lib/intentFormat.cjs.js');
|
|
10
10
|
|
|
11
11
|
var search = async ({ args, info }) => {
|
|
12
|
-
const nonFlagArgs = [];
|
|
13
|
-
let skipNext = false;
|
|
14
|
-
for (let i = 0; i < args.length; i++) {
|
|
15
|
-
if (skipNext) {
|
|
16
|
-
skipNext = false;
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
if (args[i].startsWith("-")) {
|
|
20
|
-
if (i + 1 < args.length && !args[i + 1].startsWith("-") && !args[i].includes("=")) {
|
|
21
|
-
skipNext = true;
|
|
22
|
-
}
|
|
23
|
-
} else {
|
|
24
|
-
nonFlagArgs.push(args[i]);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
12
|
const parsed = cleye.cli(
|
|
28
13
|
{
|
|
29
14
|
name: info.usage,
|
|
30
15
|
strictFlags: true,
|
|
31
16
|
parameters: ["<term...>"],
|
|
32
17
|
flags: {
|
|
33
|
-
|
|
34
|
-
type: String,
|
|
35
|
-
description: "
|
|
18
|
+
type: {
|
|
19
|
+
type: [String],
|
|
20
|
+
description: "Only search documents of this type, for example techdocs (repeatable)",
|
|
21
|
+
default: []
|
|
36
22
|
},
|
|
37
23
|
filter: {
|
|
38
24
|
type: [String],
|
|
39
|
-
description: "
|
|
25
|
+
description: "Filter results by a field, as key=value (repeatable)",
|
|
40
26
|
default: []
|
|
41
27
|
},
|
|
42
|
-
|
|
28
|
+
limit: {
|
|
43
29
|
type: Number,
|
|
44
|
-
description: "
|
|
30
|
+
description: "Maximum number of results to return per page"
|
|
45
31
|
},
|
|
46
|
-
|
|
32
|
+
cursor: {
|
|
47
33
|
type: String,
|
|
48
|
-
description: "
|
|
34
|
+
description: "Continue from the cursor returned by a previous page"
|
|
49
35
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
description: "Output format: human (default), json"
|
|
53
|
-
},
|
|
54
|
-
instance: {
|
|
55
|
-
type: String,
|
|
56
|
-
description: "Name of the instance to use"
|
|
57
|
-
}
|
|
36
|
+
...intentFormat.outputFlag,
|
|
37
|
+
...resolveAuth.instanceFlag
|
|
58
38
|
}
|
|
59
39
|
},
|
|
60
40
|
void 0,
|
|
61
41
|
args
|
|
62
42
|
);
|
|
63
43
|
const { flags } = parsed;
|
|
64
|
-
const
|
|
65
|
-
const term = termParts.join(" ");
|
|
66
|
-
if (!term) {
|
|
67
|
-
throw new Error(
|
|
68
|
-
"Search term is required. Usage: search <term> [--types techdocs]"
|
|
69
|
-
);
|
|
70
|
-
}
|
|
44
|
+
const term = parsed._.term.join(" ");
|
|
71
45
|
const mode = intentFormat.parseOutputFlag(flags);
|
|
46
|
+
const types = flags.type.length > 0 ? flags.type : void 0;
|
|
47
|
+
const filters = cliNode.parseKeyValuePairs(flags.filter);
|
|
72
48
|
const { accessToken, baseUrl } = await resolveAuth.resolveAuth(flags.instance);
|
|
73
49
|
const client = new SearchClient.SearchClient(baseUrl, accessToken);
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
50
|
+
const fetchPage = async (cursor) => {
|
|
51
|
+
const response = await client.query({
|
|
52
|
+
term,
|
|
53
|
+
types,
|
|
54
|
+
filters,
|
|
55
|
+
pageLimit: flags.limit,
|
|
56
|
+
pageCursor: cursor
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
results: response.results,
|
|
60
|
+
nextPageCursor: response.nextPageCursor,
|
|
61
|
+
totalItems: response.numberOfResults,
|
|
62
|
+
hasMoreResults: response.nextPageCursor !== void 0
|
|
63
|
+
};
|
|
86
64
|
};
|
|
87
65
|
if (mode === "json") {
|
|
88
|
-
intentFormat.writeJson(
|
|
89
|
-
|
|
90
|
-
process.stdout.write(intentFormat.formatSearchResults(result.results));
|
|
66
|
+
intentFormat.writeJson(await fetchPage(flags.cursor));
|
|
67
|
+
return;
|
|
91
68
|
}
|
|
69
|
+
await intentFormat.printPage(
|
|
70
|
+
async (cursor) => {
|
|
71
|
+
const page = await fetchPage(cursor);
|
|
72
|
+
return {
|
|
73
|
+
...page,
|
|
74
|
+
count: page.results.length,
|
|
75
|
+
total: page.totalItems,
|
|
76
|
+
nextCursor: page.nextPageCursor
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
(page) => process.stdout.write(intentFormat.formatSearchResults(page.results)),
|
|
80
|
+
flags.cursor
|
|
81
|
+
);
|
|
92
82
|
};
|
|
93
83
|
|
|
94
84
|
exports.default = search;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.cjs.js","sources":["../../src/commands/search.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport {\n
|
|
1
|
+
{"version":3,"file":"search.cjs.js","sources":["../../src/commands/search.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport {\n parseKeyValuePairs,\n type CliCommandContext,\n} from '@backstage/cli-node';\nimport { SearchClient } from '../lib/SearchClient';\nimport { instanceFlag, resolveAuth } from '../lib/resolveAuth';\nimport {\n outputFlag,\n printPage,\n parseOutputFlag,\n writeJson,\n formatSearchResults,\n} from '../lib/intentFormat';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const parsed = cli(\n {\n name: info.usage,\n strictFlags: true,\n parameters: ['<term...>'],\n flags: {\n type: {\n type: [String] as const,\n description:\n 'Only search documents of this type, for example techdocs (repeatable)',\n default: [] as string[],\n },\n filter: {\n type: [String] as const,\n description: 'Filter results by a field, as key=value (repeatable)',\n default: [] as string[],\n },\n limit: {\n type: Number,\n description: 'Maximum number of results to return per page',\n },\n cursor: {\n type: String,\n description: 'Continue from the cursor returned by a previous page',\n },\n ...outputFlag,\n ...instanceFlag,\n },\n },\n undefined,\n args,\n );\n const { flags } = parsed;\n\n const term = parsed._.term.join(' ');\n const mode = parseOutputFlag(flags as Record<string, unknown>);\n const types = flags.type.length > 0 ? flags.type : undefined;\n const filters = parseKeyValuePairs(flags.filter);\n\n const { accessToken, baseUrl } = await resolveAuth(flags.instance);\n const client = new SearchClient(baseUrl, accessToken);\n\n const fetchPage = async (cursor?: string) => {\n const response = await client.query({\n term,\n types,\n filters,\n pageLimit: flags.limit,\n pageCursor: cursor,\n });\n return {\n results: response.results,\n nextPageCursor: response.nextPageCursor,\n totalItems: response.numberOfResults,\n hasMoreResults: response.nextPageCursor !== undefined,\n };\n };\n\n if (mode === 'json') {\n writeJson(await fetchPage(flags.cursor));\n return;\n }\n\n await printPage(\n async cursor => {\n const page = await fetchPage(cursor);\n return {\n ...page,\n count: page.results.length,\n total: page.totalItems,\n nextCursor: page.nextPageCursor,\n };\n },\n page => process.stdout.write(formatSearchResults(page.results)),\n flags.cursor,\n );\n};\n"],"names":["cli","outputFlag","instanceFlag","parseOutputFlag","parseKeyValuePairs","resolveAuth","SearchClient","writeJson","printPage","formatSearchResults"],"mappings":";;;;;;;;;;AA+BA,aAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM,MAAA,GAASA,SAAA;AAAA,IACb;AAAA,MACE,MAAM,IAAA,CAAK,KAAA;AAAA,MACX,WAAA,EAAa,IAAA;AAAA,MACb,UAAA,EAAY,CAAC,WAAW,CAAA;AAAA,MACxB,KAAA,EAAO;AAAA,QACL,IAAA,EAAM;AAAA,UACJ,IAAA,EAAM,CAAC,MAAM,CAAA;AAAA,UACb,WAAA,EACE,uEAAA;AAAA,UACF,SAAS;AAAC,SACZ;AAAA,QACA,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,CAAC,MAAM,CAAA;AAAA,UACb,WAAA,EAAa,sDAAA;AAAA,UACb,SAAS;AAAC,SACZ;AAAA,QACA,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,GAAGC,uBAAA;AAAA,QACH,GAAGC;AAAA;AACL,KACF;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAElB,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAA;AACnC,EAAA,MAAM,IAAA,GAAOC,6BAAgB,KAAgC,CAAA;AAC7D,EAAA,MAAM,QAAQ,KAAA,CAAM,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,MAAM,IAAA,GAAO,MAAA;AACnD,EAAA,MAAM,OAAA,GAAUC,0BAAA,CAAmB,KAAA,CAAM,MAAM,CAAA;AAE/C,EAAA,MAAM,EAAE,WAAA,EAAa,OAAA,KAAY,MAAMC,uBAAA,CAAY,MAAM,QAAQ,CAAA;AACjE,EAAA,MAAM,MAAA,GAAS,IAAIC,yBAAA,CAAa,OAAA,EAAS,WAAW,CAAA;AAEpD,EAAA,MAAM,SAAA,GAAY,OAAO,MAAA,KAAoB;AAC3C,IAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,KAAA,CAAM;AAAA,MAClC,IAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA;AAAA,MACA,WAAW,KAAA,CAAM,KAAA;AAAA,MACjB,UAAA,EAAY;AAAA,KACb,CAAA;AACD,IAAA,OAAO;AAAA,MACL,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB,gBAAgB,QAAA,CAAS,cAAA;AAAA,MACzB,YAAY,QAAA,CAAS,eAAA;AAAA,MACrB,cAAA,EAAgB,SAAS,cAAA,KAAmB;AAAA,KAC9C;AAAA,EACF,CAAA;AAEA,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAAC,sBAAA,CAAU,MAAM,SAAA,CAAU,KAAA,CAAM,MAAM,CAAC,CAAA;AACvC,IAAA;AAAA,EACF;AAEA,EAAA,MAAMC,sBAAA;AAAA,IACJ,OAAM,MAAA,KAAU;AACd,MAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,MAAM,CAAA;AACnC,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,KAAA,EAAO,KAAK,OAAA,CAAQ,MAAA;AAAA,QACpB,OAAO,IAAA,CAAK,UAAA;AAAA,QACZ,YAAY,IAAA,CAAK;AAAA,OACnB;AAAA,IACF,CAAA;AAAA,IACA,UAAQ,OAAA,CAAQ,MAAA,CAAO,MAAMC,gCAAA,CAAoB,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,IAC9D,KAAA,CAAM;AAAA,GACR;AACF,CAAA;;"}
|
|
@@ -6,8 +6,36 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
|
|
|
6
6
|
|
|
7
7
|
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
|
|
8
8
|
|
|
9
|
+
const outputFlag = {
|
|
10
|
+
output: {
|
|
11
|
+
type: String,
|
|
12
|
+
description: 'Output format: "human" (default) or "json"'
|
|
13
|
+
}
|
|
14
|
+
};
|
|
9
15
|
function parseOutputFlag(flags) {
|
|
10
|
-
|
|
16
|
+
const output = flags.output;
|
|
17
|
+
if (output === void 0 || output === "human") return "human";
|
|
18
|
+
if (output === "json") return "json";
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Invalid --output value "${String(output)}", expected "human" or "json"`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
async function printPage(fetchPage, render, cursor) {
|
|
24
|
+
const page = await fetchPage(cursor);
|
|
25
|
+
render(page);
|
|
26
|
+
if (page.count > 0) {
|
|
27
|
+
const total = page.total === void 0 ? "" : ` of ${page.total}`;
|
|
28
|
+
process.stdout.write(`${chalk__default.default.dim(`Showing ${page.count}${total}`)}
|
|
29
|
+
`);
|
|
30
|
+
}
|
|
31
|
+
if (page.nextCursor) {
|
|
32
|
+
process.stdout.write(
|
|
33
|
+
`${chalk__default.default.dim(
|
|
34
|
+
`More results available, use --cursor ${page.nextCursor} to show them`
|
|
35
|
+
)}
|
|
36
|
+
`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
11
39
|
}
|
|
12
40
|
function writeJson(data) {
|
|
13
41
|
process.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
@@ -34,6 +62,8 @@ function formatSearchResults(results) {
|
|
|
34
62
|
}
|
|
35
63
|
|
|
36
64
|
exports.formatSearchResults = formatSearchResults;
|
|
65
|
+
exports.outputFlag = outputFlag;
|
|
37
66
|
exports.parseOutputFlag = parseOutputFlag;
|
|
67
|
+
exports.printPage = printPage;
|
|
38
68
|
exports.writeJson = writeJson;
|
|
39
69
|
//# sourceMappingURL=intentFormat.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intentFormat.cjs.js","sources":["../../src/lib/intentFormat.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport chalk from 'chalk';\n\nexport type OutputMode = 'human' | 'json';\n\nexport function parseOutputFlag(flags: Record<string, unknown>): OutputMode {\n
|
|
1
|
+
{"version":3,"file":"intentFormat.cjs.js","sources":["../../src/lib/intentFormat.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport chalk from 'chalk';\n\nexport type OutputMode = 'human' | 'json';\n\n/**\n * Shared `--output` flag definition for commands that support both formats.\n */\nexport const outputFlag = {\n output: {\n type: String,\n description: 'Output format: \"human\" (default) or \"json\"',\n },\n};\n\nexport function parseOutputFlag(flags: Record<string, unknown>): OutputMode {\n const output = flags.output;\n if (output === undefined || output === 'human') return 'human';\n if (output === 'json') return 'json';\n throw new Error(\n `Invalid --output value \"${String(output)}\", expected \"human\" or \"json\"`,\n );\n}\n\n/**\n * Describes one fetched page of a paginated list.\n */\nexport type PageResult = {\n /** Number of items in this page */\n count: number;\n /** Total number of items across all pages, if known */\n total?: number;\n /** Cursor for the next page, if there is one */\n nextCursor?: string;\n};\n\n/**\n * Prints a single page of results followed by a footer with the number of\n * results shown, unless the page is empty. When more results exist, a hint with the `--cursor` value to\n * continue from is printed.\n */\nexport async function printPage<T extends PageResult>(\n fetchPage: (cursor?: string) => Promise<T>,\n render: (page: T) => void,\n cursor?: string,\n): Promise<void> {\n const page = await fetchPage(cursor);\n render(page);\n\n if (page.count > 0) {\n const total = page.total === undefined ? '' : ` of ${page.total}`;\n process.stdout.write(`${chalk.dim(`Showing ${page.count}${total}`)}\\n`);\n }\n if (page.nextCursor) {\n process.stdout.write(\n `${chalk.dim(\n `More results available, use --cursor ${page.nextCursor} to show them`,\n )}\\n`,\n );\n }\n}\n\nexport function writeJson(data: unknown): void {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n}\n\nexport function formatSearchResults(\n results: Array<Record<string, unknown>>,\n): string {\n if (results.length === 0) {\n return `${chalk.yellow('No results found.')}\\n`;\n }\n\n const lines: string[] = [];\n for (const result of results) {\n const doc = result.document as Record<string, unknown> | undefined;\n const title = String(doc?.title ?? result.title ?? '');\n const location = String(doc?.location ?? result.location ?? '');\n const text = String(doc?.text ?? result.text ?? '');\n const snippet = text.length > 120 ? `${text.slice(0, 120)}...` : text;\n\n lines.push(chalk.bold(title));\n if (location) lines.push(` ${chalk.dim(location)}`);\n if (snippet) lines.push(` ${snippet}`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n"],"names":["chalk"],"mappings":";;;;;;;;AAuBO,MAAM,UAAA,GAAa;AAAA,EACxB,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,MAAA;AAAA,IACN,WAAA,EAAa;AAAA;AAEjB;AAEO,SAAS,gBAAgB,KAAA,EAA4C;AAC1E,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,EAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,OAAA,EAAS,OAAO,OAAA;AACvD,EAAA,IAAI,MAAA,KAAW,QAAQ,OAAO,MAAA;AAC9B,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,wBAAA,EAA2B,MAAA,CAAO,MAAM,CAAC,CAAA,6BAAA;AAAA,GAC3C;AACF;AAmBA,eAAsB,SAAA,CACpB,SAAA,EACA,MAAA,EACA,MAAA,EACe;AACf,EAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,MAAM,CAAA;AACnC,EAAA,MAAA,CAAO,IAAI,CAAA;AAEX,EAAA,IAAI,IAAA,CAAK,QAAQ,CAAA,EAAG;AAClB,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,KAAU,SAAY,EAAA,GAAK,CAAA,IAAA,EAAO,KAAK,KAAK,CAAA,CAAA;AAC/D,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAGA,sBAAA,CAAM,GAAA,CAAI,CAAA,QAAA,EAAW,IAAA,CAAK,KAAK,CAAA,EAAG,KAAK,CAAA,CAAE,CAAC;AAAA,CAAI,CAAA;AAAA,EACxE;AACA,EAAA,IAAI,KAAK,UAAA,EAAY;AACnB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb,GAAGA,sBAAA,CAAM,GAAA;AAAA,QACP,CAAA,qCAAA,EAAwC,KAAK,UAAU,CAAA,aAAA;AAAA,OACxD;AAAA;AAAA,KACH;AAAA,EACF;AACF;AAEO,SAAS,UAAU,IAAA,EAAqB;AAC7C,EAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,EAAG,IAAA,CAAK,UAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAC;AAAA,CAAI,CAAA;AAC3D;AAEO,SAAS,oBACd,OAAA,EACQ;AACR,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,CAAA,EAAGA,sBAAA,CAAM,MAAA,CAAO,mBAAmB,CAAC;AAAA,CAAA;AAAA,EAC7C;AAEA,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,MAAM,MAAA,CAAO,QAAA;AACnB,IAAA,MAAM,QAAQ,MAAA,CAAO,GAAA,EAAK,KAAA,IAAS,MAAA,CAAO,SAAS,EAAE,CAAA;AACrD,IAAA,MAAM,WAAW,MAAA,CAAO,GAAA,EAAK,QAAA,IAAY,MAAA,CAAO,YAAY,EAAE,CAAA;AAC9D,IAAA,MAAM,OAAO,MAAA,CAAO,GAAA,EAAK,IAAA,IAAQ,MAAA,CAAO,QAAQ,EAAE,CAAA;AAClD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,GAAS,GAAA,GAAM,CAAA,EAAG,KAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA,GAAA,CAAA,GAAQ,IAAA;AAEjE,IAAA,KAAA,CAAM,IAAA,CAAKA,sBAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAA;AAC5B,IAAA,IAAI,QAAA,QAAgB,IAAA,CAAK,CAAA,EAAA,EAAKA,uBAAM,GAAA,CAAI,QAAQ,CAAC,CAAA,CAAE,CAAA;AACnD,IAAA,IAAI,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,OAAO,CAAA,CAAE,CAAA;AACtC,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACf;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;;;;;;"}
|
|
@@ -2,11 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
var cliNode = require('@backstage/cli-node');
|
|
4
4
|
|
|
5
|
-
async function resolveAuth(
|
|
6
|
-
const auth = await cliNode.CliAuth.create({ instanceName:
|
|
5
|
+
async function resolveAuth(instanceFlag2) {
|
|
6
|
+
const auth = await cliNode.CliAuth.create({ instanceName: instanceFlag2 });
|
|
7
7
|
const accessToken = await auth.getAccessToken();
|
|
8
8
|
return { baseUrl: auth.getBaseUrl(), accessToken };
|
|
9
9
|
}
|
|
10
|
+
const instanceFlag = {
|
|
11
|
+
instance: {
|
|
12
|
+
type: String,
|
|
13
|
+
description: 'Name of the Backstage instance to use (defaults to the one chosen with "auth select")'
|
|
14
|
+
}
|
|
15
|
+
};
|
|
10
16
|
|
|
17
|
+
exports.instanceFlag = instanceFlag;
|
|
11
18
|
exports.resolveAuth = resolveAuth;
|
|
12
19
|
//# sourceMappingURL=resolveAuth.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveAuth.cjs.js","sources":["../../src/lib/resolveAuth.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CliAuth } from '@backstage/cli-node';\n\nexport async function resolveAuth(instanceFlag?: string): Promise<{\n baseUrl: string;\n accessToken: string;\n}> {\n const auth = await CliAuth.create({ instanceName: instanceFlag });\n const accessToken = await auth.getAccessToken();\n return { baseUrl: auth.getBaseUrl(), accessToken };\n}\n"],"names":["CliAuth"],"mappings":";;;;AAkBA,eAAsB,
|
|
1
|
+
{"version":3,"file":"resolveAuth.cjs.js","sources":["../../src/lib/resolveAuth.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CliAuth } from '@backstage/cli-node';\n\nexport async function resolveAuth(instanceFlag?: string): Promise<{\n baseUrl: string;\n accessToken: string;\n}> {\n const auth = await CliAuth.create({ instanceName: instanceFlag });\n const accessToken = await auth.getAccessToken();\n return { baseUrl: auth.getBaseUrl(), accessToken };\n}\n\n/**\n * Shared `--instance` flag definition, to be spread into each command's flags.\n */\nexport const instanceFlag = {\n instance: {\n type: String,\n description:\n 'Name of the Backstage instance to use (defaults to the one chosen with \"auth select\")',\n },\n};\n"],"names":["instanceFlag","CliAuth"],"mappings":";;;;AAkBA,eAAsB,YAAYA,aAAAA,EAG/B;AACD,EAAA,MAAM,OAAO,MAAMC,eAAA,CAAQ,OAAO,EAAE,YAAA,EAAcD,eAAc,CAAA;AAChE,EAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,cAAA,EAAe;AAC9C,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,CAAK,UAAA,IAAc,WAAA,EAAY;AACnD;AAKO,MAAM,YAAA,GAAe;AAAA,EAC1B,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,MAAA;AAAA,IACN,WAAA,EACE;AAAA;AAEN;;;"}
|
package/dist/package.json.cjs.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var name = "@backstage/cli-module-search";
|
|
6
|
-
var version = "0.
|
|
6
|
+
var version = "0.2.0";
|
|
7
7
|
var description = "CLI module for searching Backstage content";
|
|
8
8
|
var backstage = {
|
|
9
9
|
role: "cli-module"
|
|
@@ -36,13 +36,13 @@ var scripts = {
|
|
|
36
36
|
test: "backstage-cli package test"
|
|
37
37
|
};
|
|
38
38
|
var dependencies = {
|
|
39
|
-
"@backstage/cli-node": "workspace
|
|
40
|
-
"@backstage/errors": "workspace
|
|
39
|
+
"@backstage/cli-node": "workspace:^",
|
|
40
|
+
"@backstage/errors": "workspace:^",
|
|
41
41
|
chalk: "^4.0.0",
|
|
42
42
|
cleye: "^2.6.0"
|
|
43
43
|
};
|
|
44
44
|
var devDependencies = {
|
|
45
|
-
"@backstage/cli": "workspace
|
|
45
|
+
"@backstage/cli": "workspace:^"
|
|
46
46
|
};
|
|
47
47
|
var packageJson = {
|
|
48
48
|
name: name,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/cli-module-search",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI module for searching Backstage content",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "cli-module"
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"test": "backstage-cli package test"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@backstage/cli-node": "0.
|
|
37
|
-
"@backstage/errors": "
|
|
36
|
+
"@backstage/cli-node": "^0.3.5",
|
|
37
|
+
"@backstage/errors": "^1.3.2",
|
|
38
38
|
"chalk": "^4.0.0",
|
|
39
39
|
"cleye": "^2.6.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@backstage/cli": "0.
|
|
42
|
+
"@backstage/cli": "^0.36.7"
|
|
43
43
|
},
|
|
44
44
|
"typesVersions": {
|
|
45
45
|
"*": {
|