@backstage/cli-module-search 0.0.0-nightly-20260920023043
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 +23 -0
- package/bin/backstage-cli-module-search +32 -0
- package/dist/commands/docsSearch.cjs.js +81 -0
- package/dist/commands/docsSearch.cjs.js.map +1 -0
- package/dist/commands/search.cjs.js +95 -0
- package/dist/commands/search.cjs.js.map +1 -0
- package/dist/index.cjs.js +25 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/lib/SearchClient.cjs.js +39 -0
- package/dist/lib/SearchClient.cjs.js.map +1 -0
- package/dist/lib/httpJson.cjs.js +26 -0
- package/dist/lib/httpJson.cjs.js.map +1 -0
- package/dist/lib/intentFormat.cjs.js +39 -0
- package/dist/lib/intentFormat.cjs.js.map +1 -0
- package/dist/lib/resolveAuth.cjs.js +12 -0
- package/dist/lib/resolveAuth.cjs.js.map +1 -0
- package/dist/package.json.cjs.js +81 -0
- package/dist/package.json.cjs.js.map +1 -0
- package/package.json +51 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @backstage/cli-module-search
|
|
2
|
+
|
|
3
|
+
## 0.0.0-nightly-20260920023043
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3d6721d: Add intent-based CLI modules for catalog, scaffolder, and search.
|
|
8
|
+
|
|
9
|
+
New modules provide domain-oriented subcommands that talk directly to the corresponding plugins' REST APIs:
|
|
10
|
+
|
|
11
|
+
- `@backstage/cli-module-catalog`: `catalog list`, `catalog get`, `catalog validate`, `catalog register`, `catalog unregister`
|
|
12
|
+
- `@backstage/cli-module-scaffolder`: `template list`, `template execute`, `template dry-run`
|
|
13
|
+
- `@backstage/cli-module-search`: `search`, `docs search`
|
|
14
|
+
|
|
15
|
+
The commands support human-readable and JSON output, positional entity and template references, repeatable `key=value` filters and inputs, comma-separated fields and search types, and file-based catalog entity and template input.
|
|
16
|
+
|
|
17
|
+
`@backstage/cli-node` now provides shared parsers for repeatable `key=value` inputs and comma-separated lists.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @backstage/cli-node@0.0.0-nightly-20260920023043
|
|
23
|
+
- @backstage/errors@0.0.0-nightly-20260920023043
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2025 The Backstage Authors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
|
|
20
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
21
|
+
const isLocal = require('node:fs').existsSync(
|
|
22
|
+
path.resolve(__dirname, '../src'),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
if (isLocal) {
|
|
26
|
+
require('@backstage/cli-node/config/nodeTransform.cjs');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { runCli } = require('@backstage/cli-node');
|
|
30
|
+
const cliModule = require(isLocal ? '../src/index' : '..').default;
|
|
31
|
+
const pkg = require('../package.json');
|
|
32
|
+
runCli({ modules: [cliModule], name: pkg.name, version: pkg.version });
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cleye = require('cleye');
|
|
6
|
+
var SearchClient = require('../lib/SearchClient.cjs.js');
|
|
7
|
+
var resolveAuth = require('../lib/resolveAuth.cjs.js');
|
|
8
|
+
var intentFormat = require('../lib/intentFormat.cjs.js');
|
|
9
|
+
|
|
10
|
+
var docsSearch = async ({ args, info }) => {
|
|
11
|
+
const nonFlagArgs = [];
|
|
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(
|
|
30
|
+
{
|
|
31
|
+
name: info.usage,
|
|
32
|
+
flags: {
|
|
33
|
+
"page-limit": {
|
|
34
|
+
type: Number,
|
|
35
|
+
description: "Results per page (default: 10)"
|
|
36
|
+
},
|
|
37
|
+
"page-cursor": {
|
|
38
|
+
type: String,
|
|
39
|
+
description: "Pagination cursor"
|
|
40
|
+
},
|
|
41
|
+
output: {
|
|
42
|
+
type: String,
|
|
43
|
+
description: "Output format: human (default), json"
|
|
44
|
+
},
|
|
45
|
+
instance: {
|
|
46
|
+
type: String,
|
|
47
|
+
description: "Name of the instance to use"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
void 0,
|
|
52
|
+
flagArgs
|
|
53
|
+
);
|
|
54
|
+
const term = nonFlagArgs.join(" ");
|
|
55
|
+
if (!term) {
|
|
56
|
+
throw new Error("Search term is required. Usage: docs search <term>");
|
|
57
|
+
}
|
|
58
|
+
const mode = intentFormat.parseOutputFlag(flags);
|
|
59
|
+
const { accessToken, baseUrl } = await resolveAuth.resolveAuth(flags.instance);
|
|
60
|
+
const client = new SearchClient.SearchClient(baseUrl, accessToken);
|
|
61
|
+
const response = await client.query({
|
|
62
|
+
term,
|
|
63
|
+
types: ["techdocs"],
|
|
64
|
+
pageLimit: flags["page-limit"],
|
|
65
|
+
pageCursor: flags["page-cursor"]
|
|
66
|
+
});
|
|
67
|
+
const result = {
|
|
68
|
+
results: response.results,
|
|
69
|
+
nextPageCursor: response.nextPageCursor,
|
|
70
|
+
totalItems: response.numberOfResults,
|
|
71
|
+
hasMoreResults: response.nextPageCursor !== void 0
|
|
72
|
+
};
|
|
73
|
+
if (mode === "json") {
|
|
74
|
+
intentFormat.writeJson(result);
|
|
75
|
+
} else {
|
|
76
|
+
process.stdout.write(intentFormat.formatSearchResults(result.results));
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
exports.default = docsSearch;
|
|
81
|
+
//# sourceMappingURL=docsSearch.cjs.js.map
|
|
@@ -0,0 +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 nonFlagArgs: string[] = [];\n const flagArgs: string[] = [];\n let skipNext = false;\n\n for (let i = 0; i < args.length; i++) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n if (args[i].startsWith('-')) {\n flagArgs.push(args[i]);\n if (\n i + 1 < args.length &&\n !args[i + 1].startsWith('-') &&\n !args[i].includes('=')\n ) {\n flagArgs.push(args[i + 1]);\n skipNext = true;\n }\n } else {\n nonFlagArgs.push(args[i]);\n }\n }\n\n const { flags } = cli(\n {\n name: info.usage,\n flags: {\n 'page-limit': {\n type: Number,\n description: 'Results per page (default: 10)',\n },\n 'page-cursor': {\n type: String,\n description: 'Pagination cursor',\n },\n output: {\n type: String,\n description: 'Output format: human (default), json',\n },\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n },\n },\n undefined,\n flagArgs,\n );\n\n const term = nonFlagArgs.join(' ');\n if (!term) {\n throw new Error('Search term is required. Usage: docs search <term>');\n }\n\n const mode = parseOutputFlag(flags as Record<string, unknown>);\n const { accessToken, baseUrl } = await resolveAuth(flags.instance);\n const client = new SearchClient(baseUrl, accessToken);\n\n const response = await client.query({\n term,\n types: ['techdocs'],\n pageLimit: flags['page-limit'],\n pageCursor: flags['page-cursor'],\n });\n const result = {\n results: response.results,\n nextPageCursor: response.nextPageCursor,\n totalItems: response.numberOfResults,\n hasMoreResults: response.nextPageCursor !== undefined,\n };\n\n if (mode === 'json') {\n writeJson(result);\n } else {\n process.stdout.write(formatSearchResults(result.results));\n }\n};\n"],"names":["cli","parseOutputFlag","resolveAuth","SearchClient","writeJson","formatSearchResults"],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cleye = require('cleye');
|
|
6
|
+
var cliNode = require('@backstage/cli-node');
|
|
7
|
+
var SearchClient = require('../lib/SearchClient.cjs.js');
|
|
8
|
+
var resolveAuth = require('../lib/resolveAuth.cjs.js');
|
|
9
|
+
var intentFormat = require('../lib/intentFormat.cjs.js');
|
|
10
|
+
|
|
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
|
+
const parsed = cleye.cli(
|
|
28
|
+
{
|
|
29
|
+
name: info.usage,
|
|
30
|
+
strictFlags: true,
|
|
31
|
+
parameters: ["<term...>"],
|
|
32
|
+
flags: {
|
|
33
|
+
types: {
|
|
34
|
+
type: String,
|
|
35
|
+
description: "Comma-separated document types"
|
|
36
|
+
},
|
|
37
|
+
filter: {
|
|
38
|
+
type: [String],
|
|
39
|
+
description: "Query filter as repeatable key=value input",
|
|
40
|
+
default: []
|
|
41
|
+
},
|
|
42
|
+
"page-limit": {
|
|
43
|
+
type: Number,
|
|
44
|
+
description: "Results per page (default: 10)"
|
|
45
|
+
},
|
|
46
|
+
"page-cursor": {
|
|
47
|
+
type: String,
|
|
48
|
+
description: "Pagination cursor"
|
|
49
|
+
},
|
|
50
|
+
output: {
|
|
51
|
+
type: String,
|
|
52
|
+
description: "Output format: human (default), json"
|
|
53
|
+
},
|
|
54
|
+
instance: {
|
|
55
|
+
type: String,
|
|
56
|
+
description: "Name of the instance to use"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
void 0,
|
|
61
|
+
args
|
|
62
|
+
);
|
|
63
|
+
const { flags } = parsed;
|
|
64
|
+
const termParts = parsed._?.term ?? nonFlagArgs;
|
|
65
|
+
const term = termParts.join(" ");
|
|
66
|
+
if (!term) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
"Search term is required. Usage: search <term> [--types techdocs]"
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
const mode = intentFormat.parseOutputFlag(flags);
|
|
72
|
+
const { accessToken, baseUrl } = await resolveAuth.resolveAuth(flags.instance);
|
|
73
|
+
const client = new SearchClient.SearchClient(baseUrl, accessToken);
|
|
74
|
+
const response = await client.query({
|
|
75
|
+
term,
|
|
76
|
+
types: cliNode.parseCommaSeparatedList(flags.types),
|
|
77
|
+
filters: cliNode.parseKeyValuePairs(flags.filter),
|
|
78
|
+
pageLimit: flags["page-limit"],
|
|
79
|
+
pageCursor: flags["page-cursor"]
|
|
80
|
+
});
|
|
81
|
+
const result = {
|
|
82
|
+
results: response.results,
|
|
83
|
+
nextPageCursor: response.nextPageCursor,
|
|
84
|
+
totalItems: response.numberOfResults,
|
|
85
|
+
hasMoreResults: response.nextPageCursor !== void 0
|
|
86
|
+
};
|
|
87
|
+
if (mode === "json") {
|
|
88
|
+
intentFormat.writeJson(result);
|
|
89
|
+
} else {
|
|
90
|
+
process.stdout.write(intentFormat.formatSearchResults(result.results));
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
exports.default = search;
|
|
95
|
+
//# sourceMappingURL=search.cjs.js.map
|
|
@@ -0,0 +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 parseCommaSeparatedList,\n parseKeyValuePairs,\n type CliCommandContext,\n} 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 nonFlagArgs: string[] = [];\n let skipNext = false;\n\n for (let i = 0; i < args.length; i++) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n if (args[i].startsWith('-')) {\n if (\n i + 1 < args.length &&\n !args[i + 1].startsWith('-') &&\n !args[i].includes('=')\n ) {\n skipNext = true;\n }\n } else {\n nonFlagArgs.push(args[i]);\n }\n }\n\n const parsed = cli(\n {\n name: info.usage,\n strictFlags: true,\n parameters: ['<term...>'],\n flags: {\n types: {\n type: String,\n description: 'Comma-separated document types',\n },\n filter: {\n type: [String] as const,\n description: 'Query filter as repeatable key=value input',\n default: [] as string[],\n },\n 'page-limit': {\n type: Number,\n description: 'Results per page (default: 10)',\n },\n 'page-cursor': {\n type: String,\n description: 'Pagination cursor',\n },\n output: {\n type: String,\n description: 'Output format: human (default), json',\n },\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n },\n },\n undefined,\n args,\n );\n const { flags } = parsed;\n\n const termParts = parsed._?.term ?? nonFlagArgs;\n const term = termParts.join(' ');\n if (!term) {\n throw new Error(\n 'Search term is required. Usage: search <term> [--types techdocs]',\n );\n }\n\n const mode = parseOutputFlag(flags as Record<string, unknown>);\n const { accessToken, baseUrl } = await resolveAuth(flags.instance);\n const client = new SearchClient(baseUrl, accessToken);\n\n const response = await client.query({\n term,\n types: parseCommaSeparatedList(flags.types),\n filters: parseKeyValuePairs(flags.filter),\n pageLimit: flags['page-limit'],\n pageCursor: flags['page-cursor'],\n });\n const result = {\n results: response.results,\n nextPageCursor: response.nextPageCursor,\n totalItems: response.numberOfResults,\n hasMoreResults: response.nextPageCursor !== undefined,\n };\n\n if (mode === 'json') {\n writeJson(result);\n } else {\n process.stdout.write(formatSearchResults(result.results));\n }\n};\n"],"names":["cli","parseOutputFlag","resolveAuth","SearchClient","parseCommaSeparatedList","parseKeyValuePairs","writeJson","formatSearchResults"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cliNode = require('@backstage/cli-node');
|
|
6
|
+
var _package = require('./package.json.cjs.js');
|
|
7
|
+
|
|
8
|
+
var index = cliNode.createCliModule({
|
|
9
|
+
packageJson: _package.default,
|
|
10
|
+
init: async (reg) => {
|
|
11
|
+
reg.addCommand({
|
|
12
|
+
path: ["search"],
|
|
13
|
+
description: "Search across all content types (catalog, TechDocs, templates)",
|
|
14
|
+
execute: { loader: () => import('./commands/search.cjs.js') }
|
|
15
|
+
});
|
|
16
|
+
reg.addCommand({
|
|
17
|
+
path: ["docs", "search"],
|
|
18
|
+
description: "Search TechDocs content",
|
|
19
|
+
execute: { loader: () => import('./commands/docsSearch.cjs.js') }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
exports.default = index;
|
|
25
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/index.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 { createCliModule } from '@backstage/cli-node';\nimport packageJson from '../package.json';\n\nexport default createCliModule({\n packageJson,\n init: async reg => {\n reg.addCommand({\n path: ['search'],\n description:\n 'Search across all content types (catalog, TechDocs, templates)',\n execute: { loader: () => import('./commands/search') },\n });\n reg.addCommand({\n path: ['docs', 'search'],\n description: 'Search TechDocs content',\n execute: { loader: () => import('./commands/docsSearch') },\n });\n },\n});\n"],"names":["createCliModule","packageJson"],"mappings":";;;;;;;AAmBA,YAAeA,uBAAA,CAAgB;AAAA,eAC7BC,gBAAA;AAAA,EACA,IAAA,EAAM,OAAM,GAAA,KAAO;AACjB,IAAA,GAAA,CAAI,UAAA,CAAW;AAAA,MACb,IAAA,EAAM,CAAC,QAAQ,CAAA;AAAA,MACf,WAAA,EACE,gEAAA;AAAA,MACF,SAAS,EAAE,MAAA,EAAQ,MAAM,OAAO,0BAAmB,CAAA;AAAE,KACtD,CAAA;AACD,IAAA,GAAA,CAAI,UAAA,CAAW;AAAA,MACb,IAAA,EAAM,CAAC,MAAA,EAAQ,QAAQ,CAAA;AAAA,MACvB,WAAA,EAAa,yBAAA;AAAA,MACb,SAAS,EAAE,MAAA,EAAQ,MAAM,OAAO,8BAAuB,CAAA;AAAE,KAC1D,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var httpJson = require('./httpJson.cjs.js');
|
|
4
|
+
|
|
5
|
+
function buildQueryUrl(baseUrl, input) {
|
|
6
|
+
const url = new URL("/api/search/query", baseUrl);
|
|
7
|
+
url.searchParams.set("term", input.term);
|
|
8
|
+
for (const type of input.types ?? []) {
|
|
9
|
+
url.searchParams.append("types", type);
|
|
10
|
+
}
|
|
11
|
+
if (input.pageLimit !== void 0) {
|
|
12
|
+
url.searchParams.set("pageLimit", String(input.pageLimit));
|
|
13
|
+
}
|
|
14
|
+
if (input.pageCursor) {
|
|
15
|
+
url.searchParams.set("pageCursor", input.pageCursor);
|
|
16
|
+
}
|
|
17
|
+
for (const [key, value] of Object.entries(input.filters ?? {})) {
|
|
18
|
+
url.searchParams.set(`filters[${key}]`, String(value));
|
|
19
|
+
}
|
|
20
|
+
return url.toString();
|
|
21
|
+
}
|
|
22
|
+
class SearchClient {
|
|
23
|
+
constructor(baseUrl, accessToken) {
|
|
24
|
+
this.baseUrl = baseUrl;
|
|
25
|
+
this.accessToken = accessToken;
|
|
26
|
+
}
|
|
27
|
+
baseUrl;
|
|
28
|
+
accessToken;
|
|
29
|
+
async query(input) {
|
|
30
|
+
return httpJson.httpJson(buildQueryUrl(this.baseUrl, input), {
|
|
31
|
+
method: "GET",
|
|
32
|
+
headers: { Authorization: `Bearer ${this.accessToken}` },
|
|
33
|
+
signal: AbortSignal.timeout(3e4)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
exports.SearchClient = SearchClient;
|
|
39
|
+
//# sourceMappingURL=SearchClient.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchClient.cjs.js","sources":["../../src/lib/SearchClient.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 { httpJson } from './httpJson';\n\nexport type SearchQueryInput = {\n term: string;\n types?: string[];\n filters?: Record<string, unknown>;\n pageLimit?: number;\n pageCursor?: string;\n};\n\nexport type SearchQueryResult = {\n results: Array<Record<string, unknown>>;\n nextPageCursor?: string;\n numberOfResults?: number;\n};\n\nfunction buildQueryUrl(baseUrl: string, input: SearchQueryInput): string {\n const url = new URL('/api/search/query', baseUrl);\n url.searchParams.set('term', input.term);\n for (const type of input.types ?? []) {\n url.searchParams.append('types', type);\n }\n if (input.pageLimit !== undefined) {\n url.searchParams.set('pageLimit', String(input.pageLimit));\n }\n if (input.pageCursor) {\n url.searchParams.set('pageCursor', input.pageCursor);\n }\n for (const [key, value] of Object.entries(input.filters ?? {})) {\n url.searchParams.set(`filters[${key}]`, String(value));\n }\n return url.toString();\n}\n\n/**\n * A thin client that talks directly to the search plugin's REST API of the\n * given Backstage instance.\n */\nexport class SearchClient {\n constructor(\n private readonly baseUrl: string,\n private readonly accessToken: string,\n ) {}\n\n async query(input: SearchQueryInput): Promise<SearchQueryResult> {\n return httpJson<SearchQueryResult>(buildQueryUrl(this.baseUrl, input), {\n method: 'GET',\n headers: { Authorization: `Bearer ${this.accessToken}` },\n signal: AbortSignal.timeout(30_000),\n });\n }\n}\n"],"names":["httpJson"],"mappings":";;;;AAgCA,SAAS,aAAA,CAAc,SAAiB,KAAA,EAAiC;AACvE,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,mBAAA,EAAqB,OAAO,CAAA;AAChD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,KAAA,CAAM,IAAI,CAAA;AACvC,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,KAAA,IAAS,EAAC,EAAG;AACpC,IAAA,GAAA,CAAI,YAAA,CAAa,MAAA,CAAO,OAAA,EAAS,IAAI,CAAA;AAAA,EACvC;AACA,EAAA,IAAI,KAAA,CAAM,cAAc,MAAA,EAAW;AACjC,IAAA,GAAA,CAAI,aAAa,GAAA,CAAI,WAAA,EAAa,MAAA,CAAO,KAAA,CAAM,SAAS,CAAC,CAAA;AAAA,EAC3D;AACA,EAAA,IAAI,MAAM,UAAA,EAAY;AACpB,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,KAAA,CAAM,UAAU,CAAA;AAAA,EACrD;AACA,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,MAAA,CAAO,QAAQ,KAAA,CAAM,OAAA,IAAW,EAAE,CAAA,EAAG;AAC9D,IAAA,GAAA,CAAI,aAAa,GAAA,CAAI,CAAA,QAAA,EAAW,GAAG,CAAA,CAAA,CAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EACvD;AACA,EAAA,OAAO,IAAI,QAAA,EAAS;AACtB;AAMO,MAAM,YAAA,CAAa;AAAA,EACxB,WAAA,CACmB,SACA,WAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA,EAChB;AAAA,EAFgB,OAAA;AAAA,EACA,WAAA;AAAA,EAGnB,MAAM,MAAM,KAAA,EAAqD;AAC/D,IAAA,OAAOA,iBAAA,CAA4B,aAAA,CAAc,IAAA,CAAK,OAAA,EAAS,KAAK,CAAA,EAAG;AAAA,MACrE,MAAA,EAAQ,KAAA;AAAA,MACR,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA,CAAA,EAAG;AAAA,MACvD,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAM;AAAA,KACnC,CAAA;AAAA,EACH;AACF;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('@backstage/errors');
|
|
4
|
+
|
|
5
|
+
async function httpJson(url, init) {
|
|
6
|
+
const res = await fetch(url, {
|
|
7
|
+
...init,
|
|
8
|
+
body: init?.body ? JSON.stringify(init.body) : void 0,
|
|
9
|
+
headers: {
|
|
10
|
+
...init?.body ? { "Content-Type": "application/json" } : {},
|
|
11
|
+
...init?.headers
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
if (!res.ok) {
|
|
15
|
+
const responseError = await errors.ResponseError.fromResponse(res);
|
|
16
|
+
const causeMessage = responseError.cause?.message;
|
|
17
|
+
throw new Error(
|
|
18
|
+
causeMessage || `Request failed with ${res.status} ${res.statusText}`,
|
|
19
|
+
{ cause: responseError }
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return await res.json();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.httpJson = httpJson;
|
|
26
|
+
//# sourceMappingURL=httpJson.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpJson.cjs.js","sources":["../../src/lib/httpJson.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 { ResponseError } from '@backstage/errors';\n\ntype HttpInit = {\n headers?: Record<string, string>;\n method?: string;\n body?: any;\n signal?: AbortSignal;\n};\n\nexport async function httpJson<T>(url: string, init?: HttpInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n body: init?.body ? JSON.stringify(init.body) : undefined,\n headers: {\n ...(init?.body ? { 'Content-Type': 'application/json' } : {}),\n ...init?.headers,\n },\n });\n if (!res.ok) {\n const responseError = await ResponseError.fromResponse(res);\n const causeMessage = responseError.cause?.message;\n throw new Error(\n causeMessage || `Request failed with ${res.status} ${res.statusText}`,\n { cause: responseError },\n );\n }\n return (await res.json()) as T;\n}\n"],"names":["ResponseError"],"mappings":";;;;AAyBA,eAAsB,QAAA,CAAY,KAAa,IAAA,EAA6B;AAC1E,EAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAC3B,GAAG,IAAA;AAAA,IACH,MAAM,IAAA,EAAM,IAAA,GAAO,KAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA;AAAA,IAC/C,OAAA,EAAS;AAAA,MACP,GAAI,IAAA,EAAM,IAAA,GAAO,EAAE,cAAA,EAAgB,kBAAA,KAAuB,EAAC;AAAA,MAC3D,GAAG,IAAA,EAAM;AAAA;AACX,GACD,CAAA;AACD,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,IAAA,MAAM,aAAA,GAAgB,MAAMA,oBAAA,CAAc,YAAA,CAAa,GAAG,CAAA;AAC1D,IAAA,MAAM,YAAA,GAAe,cAAc,KAAA,EAAO,OAAA;AAC1C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,gBAAgB,CAAA,oBAAA,EAAuB,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,IAAI,UAAU,CAAA,CAAA;AAAA,MACnE,EAAE,OAAO,aAAA;AAAc,KACzB;AAAA,EACF;AACA,EAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AACzB;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
|
|
8
|
+
|
|
9
|
+
function parseOutputFlag(flags) {
|
|
10
|
+
return flags.output === "json" ? "json" : "human";
|
|
11
|
+
}
|
|
12
|
+
function writeJson(data) {
|
|
13
|
+
process.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
14
|
+
`);
|
|
15
|
+
}
|
|
16
|
+
function formatSearchResults(results) {
|
|
17
|
+
if (results.length === 0) {
|
|
18
|
+
return `${chalk__default.default.yellow("No results found.")}
|
|
19
|
+
`;
|
|
20
|
+
}
|
|
21
|
+
const lines = [];
|
|
22
|
+
for (const result of results) {
|
|
23
|
+
const doc = result.document;
|
|
24
|
+
const title = String(doc?.title ?? result.title ?? "");
|
|
25
|
+
const location = String(doc?.location ?? result.location ?? "");
|
|
26
|
+
const text = String(doc?.text ?? result.text ?? "");
|
|
27
|
+
const snippet = text.length > 120 ? `${text.slice(0, 120)}...` : text;
|
|
28
|
+
lines.push(chalk__default.default.bold(title));
|
|
29
|
+
if (location) lines.push(` ${chalk__default.default.dim(location)}`);
|
|
30
|
+
if (snippet) lines.push(` ${snippet}`);
|
|
31
|
+
lines.push("");
|
|
32
|
+
}
|
|
33
|
+
return lines.join("\n");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
exports.formatSearchResults = formatSearchResults;
|
|
37
|
+
exports.parseOutputFlag = parseOutputFlag;
|
|
38
|
+
exports.writeJson = writeJson;
|
|
39
|
+
//# sourceMappingURL=intentFormat.cjs.js.map
|
|
@@ -0,0 +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 return flags.output === 'json' ? 'json' : 'human';\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":";;;;;;;;AAoBO,SAAS,gBAAgB,KAAA,EAA4C;AAC1E,EAAA,OAAO,KAAA,CAAM,MAAA,KAAW,MAAA,GAAS,MAAA,GAAS,OAAA;AAC5C;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;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var cliNode = require('@backstage/cli-node');
|
|
4
|
+
|
|
5
|
+
async function resolveAuth(instanceFlag) {
|
|
6
|
+
const auth = await cliNode.CliAuth.create({ instanceName: instanceFlag });
|
|
7
|
+
const accessToken = await auth.getAccessToken();
|
|
8
|
+
return { baseUrl: auth.getBaseUrl(), accessToken };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exports.resolveAuth = resolveAuth;
|
|
12
|
+
//# sourceMappingURL=resolveAuth.cjs.js.map
|
|
@@ -0,0 +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,YAAY,YAAA,EAG/B;AACD,EAAA,MAAM,OAAO,MAAMA,eAAA,CAAQ,OAAO,EAAE,YAAA,EAAc,cAAc,CAAA;AAChE,EAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,cAAA,EAAe;AAC9C,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,CAAK,UAAA,IAAc,WAAA,EAAY;AACnD;;"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var name = "@backstage/cli-module-search";
|
|
6
|
+
var version = "0.0.0-nightly-20260920023043";
|
|
7
|
+
var description = "CLI module for searching Backstage content";
|
|
8
|
+
var backstage = {
|
|
9
|
+
role: "cli-module"
|
|
10
|
+
};
|
|
11
|
+
var publishConfig = {
|
|
12
|
+
access: "public",
|
|
13
|
+
main: "dist/index.cjs.js",
|
|
14
|
+
types: "dist/index.d.ts"
|
|
15
|
+
};
|
|
16
|
+
var homepage = "https://backstage.io";
|
|
17
|
+
var repository = {
|
|
18
|
+
type: "git",
|
|
19
|
+
url: "https://github.com/backstage/backstage",
|
|
20
|
+
directory: "packages/cli-module-search"
|
|
21
|
+
};
|
|
22
|
+
var license = "Apache-2.0";
|
|
23
|
+
var main = "src/index.ts";
|
|
24
|
+
var types = "src/index.ts";
|
|
25
|
+
var bin = "bin/backstage-cli-module-search";
|
|
26
|
+
var files = [
|
|
27
|
+
"dist",
|
|
28
|
+
"bin"
|
|
29
|
+
];
|
|
30
|
+
var scripts = {
|
|
31
|
+
build: "backstage-cli package build",
|
|
32
|
+
clean: "backstage-cli package clean",
|
|
33
|
+
lint: "backstage-cli package lint",
|
|
34
|
+
prepack: "backstage-cli package prepack",
|
|
35
|
+
postpack: "backstage-cli package postpack",
|
|
36
|
+
test: "backstage-cli package test"
|
|
37
|
+
};
|
|
38
|
+
var dependencies = {
|
|
39
|
+
"@backstage/cli-node": "workspace:*",
|
|
40
|
+
"@backstage/errors": "workspace:*",
|
|
41
|
+
chalk: "^4.0.0",
|
|
42
|
+
cleye: "^2.6.0"
|
|
43
|
+
};
|
|
44
|
+
var devDependencies = {
|
|
45
|
+
"@backstage/cli": "workspace:*"
|
|
46
|
+
};
|
|
47
|
+
var packageJson = {
|
|
48
|
+
name: name,
|
|
49
|
+
version: version,
|
|
50
|
+
description: description,
|
|
51
|
+
backstage: backstage,
|
|
52
|
+
publishConfig: publishConfig,
|
|
53
|
+
homepage: homepage,
|
|
54
|
+
repository: repository,
|
|
55
|
+
license: license,
|
|
56
|
+
main: main,
|
|
57
|
+
types: types,
|
|
58
|
+
bin: bin,
|
|
59
|
+
files: files,
|
|
60
|
+
scripts: scripts,
|
|
61
|
+
dependencies: dependencies,
|
|
62
|
+
devDependencies: devDependencies
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
exports.backstage = backstage;
|
|
66
|
+
exports.bin = bin;
|
|
67
|
+
exports.default = packageJson;
|
|
68
|
+
exports.dependencies = dependencies;
|
|
69
|
+
exports.description = description;
|
|
70
|
+
exports.devDependencies = devDependencies;
|
|
71
|
+
exports.files = files;
|
|
72
|
+
exports.homepage = homepage;
|
|
73
|
+
exports.license = license;
|
|
74
|
+
exports.main = main;
|
|
75
|
+
exports.name = name;
|
|
76
|
+
exports.publishConfig = publishConfig;
|
|
77
|
+
exports.repository = repository;
|
|
78
|
+
exports.scripts = scripts;
|
|
79
|
+
exports.types = types;
|
|
80
|
+
exports.version = version;
|
|
81
|
+
//# sourceMappingURL=package.json.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage/cli-module-search",
|
|
3
|
+
"version": "0.0.0-nightly-20260920023043",
|
|
4
|
+
"description": "CLI module for searching Backstage content",
|
|
5
|
+
"backstage": {
|
|
6
|
+
"role": "cli-module"
|
|
7
|
+
},
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public",
|
|
10
|
+
"main": "dist/index.cjs.js",
|
|
11
|
+
"types": "dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://backstage.io",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/backstage/backstage",
|
|
17
|
+
"directory": "packages/cli-module-search"
|
|
18
|
+
},
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"main": "dist/index.cjs.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"bin": "bin/backstage-cli-module-search",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"bin"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "backstage-cli package build",
|
|
29
|
+
"clean": "backstage-cli package clean",
|
|
30
|
+
"lint": "backstage-cli package lint",
|
|
31
|
+
"prepack": "backstage-cli package prepack",
|
|
32
|
+
"postpack": "backstage-cli package postpack",
|
|
33
|
+
"test": "backstage-cli package test"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@backstage/cli-node": "0.0.0-nightly-20260920023043",
|
|
37
|
+
"@backstage/errors": "0.0.0-nightly-20260920023043",
|
|
38
|
+
"chalk": "^4.0.0",
|
|
39
|
+
"cleye": "^2.6.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@backstage/cli": "0.0.0-nightly-20260920023043"
|
|
43
|
+
},
|
|
44
|
+
"typesVersions": {
|
|
45
|
+
"*": {
|
|
46
|
+
"package.json": [
|
|
47
|
+
"package.json"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|