@backstage/plugin-scaffolder-node 0.12.6-next.0 → 0.13.0-next.2
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 +29 -0
- package/dist/actions/util.cjs.js +5 -4
- package/dist/actions/util.cjs.js.map +1 -1
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/scaffolderService.cjs.js +141 -0
- package/dist/scaffolderService.cjs.js.map +1 -0
- package/dist/testUtils/scaffolderServiceMock.cjs.js +25 -0
- package/dist/testUtils/scaffolderServiceMock.cjs.js.map +1 -0
- package/dist/testUtils.cjs.js +11 -0
- package/dist/testUtils.cjs.js.map +1 -0
- package/dist/testUtils.d.ts +20 -0
- package/dist/types/scaffolderService.d-BC_MUrKh.d.ts +71 -0
- package/package.json +24 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-node
|
|
2
2
|
|
|
3
|
+
## 0.13.0-next.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/backend-test-utils@1.11.1-next.2
|
|
9
|
+
- @backstage/backend-plugin-api@1.8.0-next.1
|
|
10
|
+
- @backstage/integration@2.0.0-next.2
|
|
11
|
+
- @backstage/plugin-scaffolder-common@2.0.0-next.2
|
|
12
|
+
|
|
13
|
+
## 0.13.0-next.1
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- e27bd4e: **BREAKING** Removed deprecated `bitbucket` integration from being used in the `parseRepoUrl` function. It will use the `bitbucketCloud` or `bitbucketServer` integrations instead.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- f598909: Added `scaffolderServiceRef` and `ScaffolderService` interface for backend plugins that need to interact with the scaffolder API using `BackstageCredentials` instead of raw tokens.
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @backstage/backend-test-utils@1.11.1-next.1
|
|
24
|
+
- @backstage/integration@2.0.0-next.1
|
|
25
|
+
- @backstage/plugin-scaffolder-common@2.0.0-next.1
|
|
26
|
+
- @backstage/backend-plugin-api@1.7.1-next.0
|
|
27
|
+
- @backstage/catalog-model@1.7.6
|
|
28
|
+
- @backstage/errors@1.2.7
|
|
29
|
+
- @backstage/types@1.2.2
|
|
30
|
+
- @backstage/plugin-permission-common@0.9.6
|
|
31
|
+
|
|
3
32
|
## 0.12.6-next.0
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/dist/actions/util.cjs.js
CHANGED
|
@@ -48,10 +48,11 @@ const parseRepoUrl = (repoUrl, integrations) => {
|
|
|
48
48
|
])
|
|
49
49
|
);
|
|
50
50
|
switch (type) {
|
|
51
|
-
case "
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
case "bitbucketCloud": {
|
|
52
|
+
checkRequiredParams(parsed, "workspace", "project", "repo");
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case "bitbucketServer": {
|
|
55
56
|
checkRequiredParams(parsed, "project", "repo");
|
|
56
57
|
break;
|
|
57
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.cjs.js","sources":["../../src/actions/util.ts"],"sourcesContent":["/*\n * Copyright 2021 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 { InputError } from '@backstage/errors';\nimport { isChildPath } from '@backstage/backend-plugin-api';\nimport { join as joinPath, normalize as normalizePath } from 'node:path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { TemplateActionOptions } from './createTemplateAction';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { z } from 'zod';\nimport { Schema } from 'jsonschema';\nimport { trim } from 'lodash';\n\n/**\n * @public\n */\nexport const getRepoSourceDirectory = (\n workspacePath: string,\n sourcePath: string | undefined,\n) => {\n if (sourcePath) {\n const safeSuffix = normalizePath(sourcePath).replace(\n /^(\\.\\.(\\/|\\\\|$))+/,\n '',\n );\n const path = joinPath(workspacePath, safeSuffix);\n if (!isChildPath(workspacePath, path)) {\n throw new Error('Invalid source path');\n }\n return path;\n }\n return workspacePath;\n};\n\n/**\n * @public\n */\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): {\n repo: string;\n host: string;\n owner?: string;\n organization?: string;\n workspace?: string;\n project?: string;\n} => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n const host = parsed.host;\n const type = integrations.byHost(host)?.type;\n\n if (!type) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n const { owner, organization, workspace, project, repo } = Object.fromEntries(\n ['owner', 'organization', 'workspace', 'project', 'repo'].map(param => [\n param,\n parsed.searchParams.has(param)\n ? trim(parsed.searchParams.get(param)!, '/')\n : undefined,\n ]),\n );\n switch (type) {\n case '
|
|
1
|
+
{"version":3,"file":"util.cjs.js","sources":["../../src/actions/util.ts"],"sourcesContent":["/*\n * Copyright 2021 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 { InputError } from '@backstage/errors';\nimport { isChildPath } from '@backstage/backend-plugin-api';\nimport { join as joinPath, normalize as normalizePath } from 'node:path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { TemplateActionOptions } from './createTemplateAction';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { z } from 'zod';\nimport { Schema } from 'jsonschema';\nimport { trim } from 'lodash';\n\n/**\n * @public\n */\nexport const getRepoSourceDirectory = (\n workspacePath: string,\n sourcePath: string | undefined,\n) => {\n if (sourcePath) {\n const safeSuffix = normalizePath(sourcePath).replace(\n /^(\\.\\.(\\/|\\\\|$))+/,\n '',\n );\n const path = joinPath(workspacePath, safeSuffix);\n if (!isChildPath(workspacePath, path)) {\n throw new Error('Invalid source path');\n }\n return path;\n }\n return workspacePath;\n};\n\n/**\n * @public\n */\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): {\n repo: string;\n host: string;\n owner?: string;\n organization?: string;\n workspace?: string;\n project?: string;\n} => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n const host = parsed.host;\n const type = integrations.byHost(host)?.type;\n\n if (!type) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n const { owner, organization, workspace, project, repo } = Object.fromEntries(\n ['owner', 'organization', 'workspace', 'project', 'repo'].map(param => [\n param,\n parsed.searchParams.has(param)\n ? trim(parsed.searchParams.get(param)!, '/')\n : undefined,\n ]),\n );\n switch (type) {\n case 'bitbucketCloud': {\n checkRequiredParams(parsed, 'workspace', 'project', 'repo');\n break;\n }\n case 'bitbucketServer': {\n checkRequiredParams(parsed, 'project', 'repo');\n break;\n }\n case 'azure': {\n checkRequiredParams(parsed, 'project', 'repo');\n break;\n }\n case 'gitlab': {\n // project is the projectID, and if defined, owner and repo won't be needed.\n if (!project) {\n checkRequiredParams(parsed, 'owner', 'repo');\n }\n break;\n }\n case 'gitea': {\n checkRequiredParams(parsed, 'repo');\n break;\n }\n case 'gerrit': {\n checkRequiredParams(parsed, 'repo');\n break;\n }\n default: {\n checkRequiredParams(parsed, 'repo', 'owner');\n break;\n }\n }\n return { host, owner, repo: repo!, organization, workspace, project };\n};\n\nfunction checkRequiredParams(repoUrl: URL, ...params: string[]) {\n for (let i = 0; i < params.length; i++) {\n if (!repoUrl.searchParams.get(params[i])) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl.toString()}, missing ${\n params[i]\n }`,\n );\n }\n }\n}\n\nconst isKeyValueZodCallback = (\n schema: unknown,\n): schema is { [key in string]: (zImpl: typeof z) => z.ZodType } => {\n return (\n typeof schema === 'object' &&\n !!schema &&\n Object.values(schema).every(v => typeof v === 'function')\n );\n};\n\nconst isZodFunctionDefinition = (\n schema: unknown,\n): schema is (zImpl: typeof z) => z.ZodType => {\n return typeof schema === 'function';\n};\n\nexport const parseSchemas = (\n action: TemplateActionOptions<any, any, any>,\n): { inputSchema?: Schema; outputSchema?: Schema } => {\n if (!action.schema) {\n return { inputSchema: undefined, outputSchema: undefined };\n }\n\n if (isKeyValueZodCallback(action.schema.input)) {\n const input = z.object(\n Object.fromEntries(\n Object.entries(action.schema.input).map(([k, v]) => [k, v(z)]),\n ),\n );\n\n return {\n inputSchema: zodToJsonSchema(input) as Schema,\n outputSchema: isKeyValueZodCallback(action.schema.output)\n ? (zodToJsonSchema(\n z.object(\n Object.fromEntries(\n Object.entries(action.schema.output).map(([k, v]) => [k, v(z)]),\n ),\n ),\n ) as Schema)\n : undefined,\n };\n }\n\n if (isZodFunctionDefinition(action.schema.input)) {\n return {\n inputSchema: zodToJsonSchema(action.schema.input(z)) as Schema,\n outputSchema: isZodFunctionDefinition(action.schema.output)\n ? (zodToJsonSchema(action.schema.output(z)) as Schema)\n : undefined,\n };\n }\n\n return {\n inputSchema: undefined,\n outputSchema: undefined,\n };\n};\n\n/**\n * Filter function to exclude the .git directory and its contents\n * while keeping other files like .gitignore\n * @public\n */\nexport function isNotGitDirectoryOrContents(path: string): boolean {\n return !(path.endsWith('.git') || path.includes('.git/'));\n}\n"],"names":["normalizePath","path","joinPath","isChildPath","InputError","trim","z","zodToJsonSchema"],"mappings":"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"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -8,6 +8,7 @@ var util = require('./actions/util.cjs.js');
|
|
|
8
8
|
var serializeDirectoryContents = require('./files/serializeDirectoryContents.cjs.js');
|
|
9
9
|
var deserializeDirectoryContents = require('./files/deserializeDirectoryContents.cjs.js');
|
|
10
10
|
var extensions = require('./extensions.cjs.js');
|
|
11
|
+
var scaffolderService = require('./scaffolderService.cjs.js');
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
|
|
@@ -27,4 +28,5 @@ exports.parseRepoUrl = util.parseRepoUrl;
|
|
|
27
28
|
exports.serializeDirectoryContents = serializeDirectoryContents.serializeDirectoryContents;
|
|
28
29
|
exports.deserializeDirectoryContents = deserializeDirectoryContents.deserializeDirectoryContents;
|
|
29
30
|
exports.scaffolderActionsExtensionPoint = extensions.scaffolderActionsExtensionPoint;
|
|
31
|
+
exports.scaffolderServiceRef = scaffolderService.scaffolderServiceRef;
|
|
30
32
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { SpawnOptionsWithoutStdio } from 'node:child_process';
|
|
|
11
11
|
import { Writable } from 'node:stream';
|
|
12
12
|
import { ScmIntegrations, ScmIntegrationRegistry } from '@backstage/integration';
|
|
13
13
|
export { T as TemplateFilter, a as TemplateGlobal } from './types/types.d-C0fXdKnD.js';
|
|
14
|
+
export { a as ScaffolderService, S as ScaffolderServiceRequestOptions, s as scaffolderServiceRef } from './types/scaffolderService.d-BC_MUrKh.js';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* TaskSecrets
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
var errors = require('@backstage/errors');
|
|
5
|
+
var integration = require('@backstage/integration');
|
|
6
|
+
var pluginScaffolderCommon = require('@backstage/plugin-scaffolder-common');
|
|
7
|
+
|
|
8
|
+
class DefaultScaffolderService {
|
|
9
|
+
#auth;
|
|
10
|
+
#client;
|
|
11
|
+
#discovery;
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.#auth = options.auth;
|
|
14
|
+
this.#client = options.client;
|
|
15
|
+
this.#discovery = options.discovery;
|
|
16
|
+
}
|
|
17
|
+
async getTemplateParameterSchema(request, options) {
|
|
18
|
+
return this.#client.getTemplateParameterSchema(
|
|
19
|
+
request.templateRef,
|
|
20
|
+
await this.#getOptions(options)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
async scaffold(request, options) {
|
|
24
|
+
return this.#client.scaffold(request, await this.#getOptions(options));
|
|
25
|
+
}
|
|
26
|
+
async getTask(request, options) {
|
|
27
|
+
return this.#client.getTask(
|
|
28
|
+
request.taskId,
|
|
29
|
+
await this.#getOptions(options)
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
async cancelTask(request, options) {
|
|
33
|
+
return this.#client.cancelTask(
|
|
34
|
+
request.taskId,
|
|
35
|
+
await this.#getOptions(options)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
async retry(request, options) {
|
|
39
|
+
return this.#client.retry(request.taskId, await this.#getOptions(options));
|
|
40
|
+
}
|
|
41
|
+
async listTasks(request, options) {
|
|
42
|
+
const { token } = await this.#getOptions(options);
|
|
43
|
+
const baseUrl = await this.#discovery.getBaseUrl("scaffolder");
|
|
44
|
+
const params = new URLSearchParams();
|
|
45
|
+
if (request.createdBy) {
|
|
46
|
+
params.set("createdBy", request.createdBy);
|
|
47
|
+
}
|
|
48
|
+
if (request.limit !== void 0) {
|
|
49
|
+
params.set("limit", String(request.limit));
|
|
50
|
+
}
|
|
51
|
+
if (request.offset !== void 0) {
|
|
52
|
+
params.set("offset", String(request.offset));
|
|
53
|
+
}
|
|
54
|
+
const query = params.toString();
|
|
55
|
+
const url = `${baseUrl}/v2/tasks${query ? `?${query}` : ""}`;
|
|
56
|
+
const response = await fetch(url, {
|
|
57
|
+
headers: {
|
|
58
|
+
"Content-Type": "application/json",
|
|
59
|
+
...token && { Authorization: `Bearer ${token}` }
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
throw await errors.ResponseError.fromResponse(response);
|
|
64
|
+
}
|
|
65
|
+
const body = await response.json();
|
|
66
|
+
return {
|
|
67
|
+
items: body.tasks,
|
|
68
|
+
totalItems: body.totalTasks ?? 0
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async listActions(_request, options) {
|
|
72
|
+
return this.#client.listActions(
|
|
73
|
+
options ? await this.#getOptions(options) : {}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
async listTemplatingExtensions(_request, options) {
|
|
77
|
+
return this.#client.listTemplatingExtensions(
|
|
78
|
+
options ? await this.#getOptions(options) : {}
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
async getLogs(request, options) {
|
|
82
|
+
const { token } = await this.#getOptions(options);
|
|
83
|
+
const baseUrl = await this.#discovery.getBaseUrl("scaffolder");
|
|
84
|
+
const params = new URLSearchParams();
|
|
85
|
+
if (request.after !== void 0) {
|
|
86
|
+
params.set("after", String(request.after));
|
|
87
|
+
}
|
|
88
|
+
const query = params.toString();
|
|
89
|
+
const taskId = encodeURIComponent(request.taskId);
|
|
90
|
+
const url = `${baseUrl}/v2/tasks/${taskId}/events${query ? `?${query}` : ""}`;
|
|
91
|
+
const response = await fetch(url, {
|
|
92
|
+
headers: {
|
|
93
|
+
"Content-Type": "application/json",
|
|
94
|
+
...token && { Authorization: `Bearer ${token}` }
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
throw await errors.ResponseError.fromResponse(response);
|
|
99
|
+
}
|
|
100
|
+
return response.json();
|
|
101
|
+
}
|
|
102
|
+
async dryRun(request, options) {
|
|
103
|
+
return this.#client.dryRun(request, await this.#getOptions(options));
|
|
104
|
+
}
|
|
105
|
+
async autocomplete(request, options) {
|
|
106
|
+
return this.#client.autocomplete(request, await this.#getOptions(options));
|
|
107
|
+
}
|
|
108
|
+
async #getOptions(options) {
|
|
109
|
+
return this.#auth.getPluginRequestToken({
|
|
110
|
+
onBehalfOf: options.credentials,
|
|
111
|
+
targetPluginId: "scaffolder"
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const scaffolderServiceRef = backendPluginApi.createServiceRef({
|
|
116
|
+
id: "scaffolder-client",
|
|
117
|
+
defaultFactory: async (service) => backendPluginApi.createServiceFactory({
|
|
118
|
+
service,
|
|
119
|
+
deps: {
|
|
120
|
+
auth: backendPluginApi.coreServices.auth,
|
|
121
|
+
discovery: backendPluginApi.coreServices.discovery,
|
|
122
|
+
config: backendPluginApi.coreServices.rootConfig
|
|
123
|
+
},
|
|
124
|
+
async factory({ auth, discovery, config }) {
|
|
125
|
+
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
126
|
+
const client = new pluginScaffolderCommon.ScaffolderClient({
|
|
127
|
+
discoveryApi: discovery,
|
|
128
|
+
fetchApi: { fetch },
|
|
129
|
+
scmIntegrationsApi: integrations
|
|
130
|
+
});
|
|
131
|
+
return new DefaultScaffolderService({
|
|
132
|
+
auth,
|
|
133
|
+
client,
|
|
134
|
+
discovery
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
exports.scaffolderServiceRef = scaffolderServiceRef;
|
|
141
|
+
//# sourceMappingURL=scaffolderService.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffolderService.cjs.js","sources":["../src/scaffolderService.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 {\n AuthService,\n BackstageCredentials,\n coreServices,\n createServiceFactory,\n createServiceRef,\n DiscoveryService,\n} from '@backstage/backend-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderClient,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderRequestOptions,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderTask,\n ScaffolderTaskStatus,\n} from '@backstage/plugin-scaffolder-common';\nimport type { TemplateParameterSchema } from '@backstage/plugin-scaffolder-common';\n\n/**\n * @public\n */\nexport interface ScaffolderServiceRequestOptions {\n credentials: BackstageCredentials;\n}\n\n/**\n * A backend service interface for the scaffolder that uses\n * {@link @backstage/backend-plugin-api#BackstageCredentials} instead of tokens.\n *\n * @public\n */\nexport interface ScaffolderService {\n getTemplateParameterSchema(\n request: { templateRef: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<TemplateParameterSchema>;\n\n scaffold(\n request: ScaffolderScaffoldOptions,\n options: ScaffolderServiceRequestOptions,\n ): Promise<ScaffolderScaffoldResponse>;\n\n getTask(\n request: { taskId: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<ScaffolderTask>;\n\n cancelTask(\n request: { taskId: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ status?: ScaffolderTaskStatus }>;\n\n retry(\n request: { taskId: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ id: string }>;\n\n listTasks(\n request: {\n createdBy?: string;\n limit?: number;\n offset?: number;\n },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ items: ScaffolderTask[]; totalItems: number }>;\n\n listActions(\n request?: {},\n options?: ScaffolderServiceRequestOptions,\n ): Promise<ListActionsResponse>;\n\n listTemplatingExtensions(\n request?: {},\n options?: ScaffolderServiceRequestOptions,\n ): Promise<ListTemplatingExtensionsResponse>;\n\n getLogs(\n request: {\n taskId: string;\n after?: number;\n },\n options: ScaffolderServiceRequestOptions,\n ): Promise<LogEvent[]>;\n\n dryRun(\n request: ScaffolderDryRunOptions,\n options: ScaffolderServiceRequestOptions,\n ): Promise<ScaffolderDryRunResponse>;\n\n autocomplete(\n request: {\n token: string;\n provider: string;\n resource: string;\n context: Record<string, string>;\n },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ results: { title?: string; id: string }[] }>;\n}\n\nclass DefaultScaffolderService implements ScaffolderService {\n readonly #auth: AuthService;\n readonly #client: ScaffolderClient;\n readonly #discovery: DiscoveryService;\n\n constructor(options: {\n auth: AuthService;\n client: ScaffolderClient;\n discovery: DiscoveryService;\n }) {\n this.#auth = options.auth;\n this.#client = options.client;\n this.#discovery = options.discovery;\n }\n\n async getTemplateParameterSchema(\n request: { templateRef: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<TemplateParameterSchema> {\n return this.#client.getTemplateParameterSchema(\n request.templateRef,\n await this.#getOptions(options),\n );\n }\n\n async scaffold(\n request: ScaffolderScaffoldOptions,\n options: ScaffolderServiceRequestOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n return this.#client.scaffold(request, await this.#getOptions(options));\n }\n\n async getTask(\n request: { taskId: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<ScaffolderTask> {\n return this.#client.getTask(\n request.taskId,\n await this.#getOptions(options),\n );\n }\n\n async cancelTask(\n request: { taskId: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ status?: ScaffolderTaskStatus }> {\n return this.#client.cancelTask(\n request.taskId,\n await this.#getOptions(options),\n );\n }\n\n async retry(\n request: { taskId: string },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ id: string }> {\n return this.#client.retry(request.taskId, await this.#getOptions(options));\n }\n\n async listTasks(\n request: {\n createdBy?: string;\n limit?: number;\n offset?: number;\n },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ items: ScaffolderTask[]; totalItems: number }> {\n const { token } = await this.#getOptions(options);\n const baseUrl = await this.#discovery.getBaseUrl('scaffolder');\n\n const params = new URLSearchParams();\n if (request.createdBy) {\n params.set('createdBy', request.createdBy);\n }\n if (request.limit !== undefined) {\n params.set('limit', String(request.limit));\n }\n if (request.offset !== undefined) {\n params.set('offset', String(request.offset));\n }\n\n const query = params.toString();\n const url = `${baseUrl}/v2/tasks${query ? `?${query}` : ''}`;\n\n const response = await fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(token && { Authorization: `Bearer ${token}` }),\n },\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const body = await response.json();\n return {\n items: body.tasks,\n totalItems: body.totalTasks ?? 0,\n };\n }\n\n async listActions(\n _request?: {},\n options?: ScaffolderServiceRequestOptions,\n ): Promise<ListActionsResponse> {\n return this.#client.listActions(\n options ? await this.#getOptions(options) : {},\n );\n }\n\n async listTemplatingExtensions(\n _request?: {},\n options?: ScaffolderServiceRequestOptions,\n ): Promise<ListTemplatingExtensionsResponse> {\n return this.#client.listTemplatingExtensions(\n options ? await this.#getOptions(options) : {},\n );\n }\n\n async getLogs(\n request: {\n taskId: string;\n after?: number;\n },\n options: ScaffolderServiceRequestOptions,\n ): Promise<LogEvent[]> {\n const { token } = await this.#getOptions(options);\n const baseUrl = await this.#discovery.getBaseUrl('scaffolder');\n\n const params = new URLSearchParams();\n if (request.after !== undefined) {\n params.set('after', String(request.after));\n }\n\n const query = params.toString();\n const taskId = encodeURIComponent(request.taskId);\n const url = `${baseUrl}/v2/tasks/${taskId}/events${\n query ? `?${query}` : ''\n }`;\n\n const response = await fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(token && { Authorization: `Bearer ${token}` }),\n },\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n async dryRun(\n request: ScaffolderDryRunOptions,\n options: ScaffolderServiceRequestOptions,\n ): Promise<ScaffolderDryRunResponse> {\n return this.#client.dryRun(request, await this.#getOptions(options));\n }\n\n async autocomplete(\n request: {\n token: string;\n provider: string;\n resource: string;\n context: Record<string, string>;\n },\n options: ScaffolderServiceRequestOptions,\n ): Promise<{ results: { title?: string; id: string }[] }> {\n return this.#client.autocomplete(request, await this.#getOptions(options));\n }\n\n async #getOptions(\n options: ScaffolderServiceRequestOptions,\n ): Promise<ScaffolderRequestOptions> {\n return this.#auth.getPluginRequestToken({\n onBehalfOf: options.credentials,\n targetPluginId: 'scaffolder',\n });\n }\n}\n\n/**\n * A service ref for the scaffolder client, to be used by backend plugins\n * and modules that need to interact with the scaffolder API.\n *\n * @public\n */\nexport const scaffolderServiceRef = createServiceRef<ScaffolderService>({\n id: 'scaffolder-client',\n defaultFactory: async service =>\n createServiceFactory({\n service,\n deps: {\n auth: coreServices.auth,\n discovery: coreServices.discovery,\n config: coreServices.rootConfig,\n },\n async factory({ auth, discovery, config }) {\n const integrations = ScmIntegrations.fromConfig(config);\n const client = new ScaffolderClient({\n discoveryApi: discovery,\n fetchApi: { fetch },\n scmIntegrationsApi: integrations,\n });\n return new DefaultScaffolderService({\n auth,\n client,\n discovery,\n });\n },\n }),\n});\n"],"names":["ResponseError","createServiceRef","createServiceFactory","coreServices","ScmIntegrations","ScaffolderClient"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendTestUtils = require('@backstage/backend-test-utils');
|
|
4
|
+
var scaffolderService = require('../scaffolderService.cjs.js');
|
|
5
|
+
|
|
6
|
+
exports.scaffolderServiceMock = void 0;
|
|
7
|
+
((scaffolderServiceMock2) => {
|
|
8
|
+
scaffolderServiceMock2.mock = backendTestUtils.createServiceMock(
|
|
9
|
+
scaffolderService.scaffolderServiceRef,
|
|
10
|
+
() => ({
|
|
11
|
+
getTemplateParameterSchema: jest.fn(),
|
|
12
|
+
scaffold: jest.fn(),
|
|
13
|
+
getTask: jest.fn(),
|
|
14
|
+
cancelTask: jest.fn(),
|
|
15
|
+
retry: jest.fn(),
|
|
16
|
+
listTasks: jest.fn(),
|
|
17
|
+
listActions: jest.fn(),
|
|
18
|
+
listTemplatingExtensions: jest.fn(),
|
|
19
|
+
getLogs: jest.fn(),
|
|
20
|
+
dryRun: jest.fn(),
|
|
21
|
+
autocomplete: jest.fn()
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
})(exports.scaffolderServiceMock || (exports.scaffolderServiceMock = {}));
|
|
25
|
+
//# sourceMappingURL=scaffolderServiceMock.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffolderServiceMock.cjs.js","sources":["../../src/testUtils/scaffolderServiceMock.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 { createServiceMock } from '@backstage/backend-test-utils';\nimport { scaffolderServiceRef, ScaffolderService } from '../scaffolderService';\n\n/**\n * A collection of mock functionality for the scaffolder service.\n *\n * @public\n */\nexport namespace scaffolderServiceMock {\n /**\n * Creates a scaffolder service whose methods are mock functions, possibly with\n * some of them overloaded by the caller.\n */\n export const mock = createServiceMock<ScaffolderService>(\n scaffolderServiceRef,\n () => ({\n getTemplateParameterSchema: jest.fn(),\n scaffold: jest.fn(),\n getTask: jest.fn(),\n cancelTask: jest.fn(),\n retry: jest.fn(),\n listTasks: jest.fn(),\n listActions: jest.fn(),\n listTemplatingExtensions: jest.fn(),\n getLogs: jest.fn(),\n dryRun: jest.fn(),\n autocomplete: jest.fn(),\n }),\n );\n}\n"],"names":["scaffolderServiceMock","createServiceMock","scaffolderServiceRef"],"mappings":";;;;;AAwBiBA;AAAA,CAAV,CAAUA,sBAAAA,KAAV;AAKE,EAAMA,uBAAA,IAAA,GAAOC,kCAAA;AAAA,IAClBC,sCAAA;AAAA,IACA,OAAO;AAAA,MACL,0BAAA,EAA4B,KAAK,EAAA,EAAG;AAAA,MACpC,QAAA,EAAU,KAAK,EAAA,EAAG;AAAA,MAClB,OAAA,EAAS,KAAK,EAAA,EAAG;AAAA,MACjB,UAAA,EAAY,KAAK,EAAA,EAAG;AAAA,MACpB,KAAA,EAAO,KAAK,EAAA,EAAG;AAAA,MACf,SAAA,EAAW,KAAK,EAAA,EAAG;AAAA,MACnB,WAAA,EAAa,KAAK,EAAA,EAAG;AAAA,MACrB,wBAAA,EAA0B,KAAK,EAAA,EAAG;AAAA,MAClC,OAAA,EAAS,KAAK,EAAA,EAAG;AAAA,MACjB,MAAA,EAAQ,KAAK,EAAA,EAAG;AAAA,MAChB,YAAA,EAAc,KAAK,EAAA;AAAG,KACxB;AAAA,GACF;AAAA,CAAA,EApBeF,6BAAA,KAAAA,6BAAA,GAAA,EAAA,CAAA,CAAA;;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var scaffolderServiceMock = require('./testUtils/scaffolderServiceMock.cjs.js');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "scaffolderServiceMock", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return scaffolderServiceMock.scaffolderServiceMock; }
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=testUtils.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testUtils.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { a as ScaffolderService } from './types/scaffolderService.d-BC_MUrKh.js';
|
|
2
|
+
export { S as ScaffolderServiceRequestOptions } from './types/scaffolderService.d-BC_MUrKh.js';
|
|
3
|
+
import * as _backstage_backend_test_utils from '@backstage/backend-test-utils';
|
|
4
|
+
import '@backstage/backend-plugin-api';
|
|
5
|
+
import '@backstage/plugin-scaffolder-common';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A collection of mock functionality for the scaffolder service.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
declare namespace scaffolderServiceMock {
|
|
13
|
+
/**
|
|
14
|
+
* Creates a scaffolder service whose methods are mock functions, possibly with
|
|
15
|
+
* some of them overloaded by the caller.
|
|
16
|
+
*/
|
|
17
|
+
const mock: (partialImpl?: Partial<ScaffolderService> | undefined) => _backstage_backend_test_utils.ServiceMock<ScaffolderService>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { ScaffolderService, scaffolderServiceMock };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
|
+
import { BackstageCredentials } from '@backstage/backend-plugin-api';
|
|
3
|
+
import { TemplateParameterSchema, ScaffolderScaffoldOptions, ScaffolderScaffoldResponse, ScaffolderTask, ScaffolderTaskStatus, ListActionsResponse, ListTemplatingExtensionsResponse, LogEvent, ScaffolderDryRunOptions, ScaffolderDryRunResponse } from '@backstage/plugin-scaffolder-common';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
interface ScaffolderServiceRequestOptions {
|
|
9
|
+
credentials: BackstageCredentials;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A backend service interface for the scaffolder that uses
|
|
13
|
+
* {@link @backstage/backend-plugin-api#BackstageCredentials} instead of tokens.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
interface ScaffolderService {
|
|
18
|
+
getTemplateParameterSchema(request: {
|
|
19
|
+
templateRef: string;
|
|
20
|
+
}, options: ScaffolderServiceRequestOptions): Promise<TemplateParameterSchema>;
|
|
21
|
+
scaffold(request: ScaffolderScaffoldOptions, options: ScaffolderServiceRequestOptions): Promise<ScaffolderScaffoldResponse>;
|
|
22
|
+
getTask(request: {
|
|
23
|
+
taskId: string;
|
|
24
|
+
}, options: ScaffolderServiceRequestOptions): Promise<ScaffolderTask>;
|
|
25
|
+
cancelTask(request: {
|
|
26
|
+
taskId: string;
|
|
27
|
+
}, options: ScaffolderServiceRequestOptions): Promise<{
|
|
28
|
+
status?: ScaffolderTaskStatus;
|
|
29
|
+
}>;
|
|
30
|
+
retry(request: {
|
|
31
|
+
taskId: string;
|
|
32
|
+
}, options: ScaffolderServiceRequestOptions): Promise<{
|
|
33
|
+
id: string;
|
|
34
|
+
}>;
|
|
35
|
+
listTasks(request: {
|
|
36
|
+
createdBy?: string;
|
|
37
|
+
limit?: number;
|
|
38
|
+
offset?: number;
|
|
39
|
+
}, options: ScaffolderServiceRequestOptions): Promise<{
|
|
40
|
+
items: ScaffolderTask[];
|
|
41
|
+
totalItems: number;
|
|
42
|
+
}>;
|
|
43
|
+
listActions(request?: {}, options?: ScaffolderServiceRequestOptions): Promise<ListActionsResponse>;
|
|
44
|
+
listTemplatingExtensions(request?: {}, options?: ScaffolderServiceRequestOptions): Promise<ListTemplatingExtensionsResponse>;
|
|
45
|
+
getLogs(request: {
|
|
46
|
+
taskId: string;
|
|
47
|
+
after?: number;
|
|
48
|
+
}, options: ScaffolderServiceRequestOptions): Promise<LogEvent[]>;
|
|
49
|
+
dryRun(request: ScaffolderDryRunOptions, options: ScaffolderServiceRequestOptions): Promise<ScaffolderDryRunResponse>;
|
|
50
|
+
autocomplete(request: {
|
|
51
|
+
token: string;
|
|
52
|
+
provider: string;
|
|
53
|
+
resource: string;
|
|
54
|
+
context: Record<string, string>;
|
|
55
|
+
}, options: ScaffolderServiceRequestOptions): Promise<{
|
|
56
|
+
results: {
|
|
57
|
+
title?: string;
|
|
58
|
+
id: string;
|
|
59
|
+
}[];
|
|
60
|
+
}>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A service ref for the scaffolder client, to be used by backend plugins
|
|
64
|
+
* and modules that need to interact with the scaffolder API.
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
declare const scaffolderServiceRef: _backstage_backend_plugin_api.ServiceRef<ScaffolderService, "plugin", "singleton">;
|
|
69
|
+
|
|
70
|
+
export { scaffolderServiceRef as s };
|
|
71
|
+
export type { ScaffolderServiceRequestOptions as S, ScaffolderService as a };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0-next.2",
|
|
4
4
|
"description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library",
|
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
"types": "./dist/alpha.d.ts",
|
|
36
36
|
"default": "./dist/alpha.cjs.js"
|
|
37
37
|
},
|
|
38
|
+
"./testUtils": {
|
|
39
|
+
"require": "./dist/testUtils.cjs.js",
|
|
40
|
+
"types": "./dist/testUtils.d.ts",
|
|
41
|
+
"default": "./dist/testUtils.cjs.js"
|
|
42
|
+
},
|
|
38
43
|
"./package.json": "./package.json"
|
|
39
44
|
},
|
|
40
45
|
"main": "./dist/index.cjs.js",
|
|
@@ -44,6 +49,9 @@
|
|
|
44
49
|
"alpha": [
|
|
45
50
|
"dist/alpha.d.ts"
|
|
46
51
|
],
|
|
52
|
+
"testUtils": [
|
|
53
|
+
"dist/testUtils.d.ts"
|
|
54
|
+
],
|
|
47
55
|
"package.json": [
|
|
48
56
|
"package.json"
|
|
49
57
|
]
|
|
@@ -62,12 +70,12 @@
|
|
|
62
70
|
"test": "backstage-cli package test"
|
|
63
71
|
},
|
|
64
72
|
"dependencies": {
|
|
65
|
-
"@backstage/backend-plugin-api": "1.
|
|
73
|
+
"@backstage/backend-plugin-api": "1.8.0-next.1",
|
|
66
74
|
"@backstage/catalog-model": "1.7.6",
|
|
67
75
|
"@backstage/errors": "1.2.7",
|
|
68
|
-
"@backstage/integration": "
|
|
76
|
+
"@backstage/integration": "2.0.0-next.2",
|
|
69
77
|
"@backstage/plugin-permission-common": "0.9.6",
|
|
70
|
-
"@backstage/plugin-scaffolder-common": "
|
|
78
|
+
"@backstage/plugin-scaffolder-common": "2.0.0-next.2",
|
|
71
79
|
"@backstage/types": "1.2.2",
|
|
72
80
|
"@isomorphic-git/pgp-plugin": "^0.0.7",
|
|
73
81
|
"concat-stream": "^2.0.0",
|
|
@@ -84,9 +92,18 @@
|
|
|
84
92
|
"zod-to-json-schema": "^3.25.1"
|
|
85
93
|
},
|
|
86
94
|
"devDependencies": {
|
|
87
|
-
"@backstage/backend-test-utils": "1.11.1-next.
|
|
88
|
-
"@backstage/cli": "0.
|
|
95
|
+
"@backstage/backend-test-utils": "1.11.1-next.2",
|
|
96
|
+
"@backstage/cli": "0.36.0-next.2",
|
|
89
97
|
"@backstage/config": "1.3.6",
|
|
90
|
-
"@types/lodash": "^4.14.151"
|
|
98
|
+
"@types/lodash": "^4.14.151",
|
|
99
|
+
"msw": "^1.0.0"
|
|
100
|
+
},
|
|
101
|
+
"peerDependencies": {
|
|
102
|
+
"@backstage/backend-test-utils": "1.11.1-next.2"
|
|
103
|
+
},
|
|
104
|
+
"peerDependenciesMeta": {
|
|
105
|
+
"@backstage/backend-test-utils": {
|
|
106
|
+
"optional": true
|
|
107
|
+
}
|
|
91
108
|
}
|
|
92
109
|
}
|