@backstage/plugin-scaffolder-common 2.3.0-next.2 → 2.3.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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # @backstage/plugin-scaffolder-common
2
2
 
3
+ ## 2.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1a705ca: Added `templateDryRunPermission`, which allows permission policies to control who can submit inline Software Template dry runs.
8
+
9
+ ### Patch Changes
10
+
11
+ - be0a75a: Exclude internal task data from task responses.
12
+ - ffaca06: Fixed a connection leak in the scaffolder event stream where unsubscribing did not abort the underlying SSE connection. Also changed unexpected server disconnects to signal an error instead of silently completing, enabling consumers to retry.
13
+ - Updated dependencies
14
+ - @backstage/integration@2.1.2
15
+ - @backstage/catalog-model@1.10.1
16
+ - @backstage/plugin-permission-common@0.9.11
17
+
3
18
  ## 2.3.0-next.2
4
19
 
5
20
  ### Patch Changes
@@ -145,11 +145,16 @@ class ScaffolderClient {
145
145
  if (after !== void 0) {
146
146
  params.set("after", String(Number(after)));
147
147
  }
148
+ const ctrl = new AbortController();
148
149
  this.discoveryApi.getBaseUrl("scaffolder").then(
149
150
  (baseUrl) => {
151
+ if (ctrl.signal.aborted) {
152
+ return;
153
+ }
154
+ const query = params.toString();
150
155
  const url = `${baseUrl}/v2/tasks/${encodeURIComponent(
151
156
  taskId
152
- )}/eventstream`;
157
+ )}/eventstream${query ? `?${query}` : ""}`;
153
158
  const processEvent = (event) => {
154
159
  if (event.data) {
155
160
  try {
@@ -159,10 +164,10 @@ class ScaffolderClient {
159
164
  }
160
165
  }
161
166
  };
162
- const ctrl = new AbortController();
163
- void fetchEventSource.fetchEventSource(url, {
167
+ fetchEventSource.fetchEventSource(url, {
164
168
  fetch: this.fetchApi.fetch,
165
169
  signal: ctrl.signal,
170
+ openWhenHidden: true,
166
171
  onmessage(e) {
167
172
  if (e.event === "log") {
168
173
  processEvent(e);
@@ -175,15 +180,22 @@ class ScaffolderClient {
175
180
  }
176
181
  processEvent(e);
177
182
  },
183
+ onclose() {
184
+ subscriber.error(new Error("SSE connection closed unexpectedly"));
185
+ },
178
186
  onerror(err) {
187
+ ctrl.abort();
179
188
  subscriber.error(err);
189
+ throw err;
180
190
  }
191
+ }).catch(() => {
181
192
  });
182
193
  },
183
194
  (error) => {
184
195
  subscriber.error(error);
185
196
  }
186
197
  );
198
+ return () => ctrl.abort();
187
199
  });
188
200
  }
189
201
  streamLogsPolling({
@@ -1 +1 @@
1
- {"version":3,"file":"ScaffolderClient.cjs.js","sources":["../src/ScaffolderClient.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { parseEntityRef } from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { Observable } from '@backstage/types';\nimport {\n EventSourceMessage,\n fetchEventSource,\n} from '@microsoft/fetch-event-source';\nimport ObservableImpl from 'zen-observable';\n\nimport { type TemplateParameterSchema } from './TemplateEntityV1beta3';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderApi,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderGetIntegrationsListOptions,\n ScaffolderGetIntegrationsListResponse,\n ScaffolderRequestOptions,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderStreamLogsOptions,\n ScaffolderTask,\n} from './api';\nimport { DefaultApiClient, TaskStatus, TypedResponse } from './schema/openapi';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n */\nexport class ScaffolderClient implements ScaffolderApi {\n private readonly apiClient: DefaultApiClient;\n private readonly discoveryApi: {\n getBaseUrl(pluginId: string): Promise<string>;\n };\n private readonly scmIntegrationsApi: ScmIntegrationRegistry;\n private readonly fetchApi: { fetch: typeof fetch };\n private readonly identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n private readonly useLongPollingLogs: boolean;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi: { fetch: typeof fetch };\n identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n scmIntegrationsApi: ScmIntegrationRegistry;\n useLongPollingLogs?: boolean;\n }) {\n this.apiClient = new DefaultApiClient(options);\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi ?? { fetch };\n this.scmIntegrationsApi = options.scmIntegrationsApi;\n this.useLongPollingLogs = options.useLongPollingLogs ?? false;\n this.identityApi = options.identityApi;\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTasks}\n */\n async listTasks(\n request: {\n filterByOwnership: 'owned' | 'all';\n limit?: number;\n offset?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> {\n if (!this.identityApi) {\n throw new Error(\n 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method',\n );\n }\n\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n return await this.requestRequired(\n await this.apiClient.listTasks(\n {\n query: {\n createdBy:\n request.filterByOwnership === 'owned'\n ? [userEntityRef]\n : undefined,\n limit: request.limit,\n offset: request.offset,\n },\n },\n options,\n ),\n );\n }\n\n async getIntegrationsList(\n options: ScaffolderGetIntegrationsListOptions,\n ): Promise<ScaffolderGetIntegrationsListResponse> {\n const integrations = [\n ...this.scmIntegrationsApi.azure.list(),\n ...this.scmIntegrationsApi.bitbucketCloud.list(),\n ...this.scmIntegrationsApi.bitbucketServer.list(),\n ...this.scmIntegrationsApi.gerrit.list(),\n ...this.scmIntegrationsApi.gitea.list(),\n ...this.scmIntegrationsApi.github.list(),\n ...this.scmIntegrationsApi.gitlab.list(),\n ]\n .map(c => ({ type: c.type, title: c.title, host: c.config.host }))\n .filter(c => options.allowedHosts.includes(c.host));\n\n return {\n integrations,\n };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTemplateParameterSchema}\n */\n async getTemplateParameterSchema(\n templateRef: string,\n options?: ScaffolderRequestOptions,\n ): Promise<TemplateParameterSchema> {\n return await this.requestRequired(\n await this.apiClient.getTemplateParameterSchema(\n {\n path: parseEntityRef(templateRef, {\n defaultKind: 'template',\n }),\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.scaffold}\n */\n async scaffold(\n request: ScaffolderScaffoldOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n const response = await this.apiClient.scaffold(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 201) {\n const status = `${response.status} ${response.statusText}`;\n const body = await response.text();\n throw new Error(`Backend request failed, ${status} ${body.trim()}`);\n }\n\n const { id } = await response.json();\n return { taskId: id };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTask}\n */\n async getTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderTask> {\n return await this.requestRequired(\n await this.apiClient.getTask(\n {\n path: { taskId },\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.streamLogs}\n */\n streamLogs(\n request: ScaffolderStreamLogsOptions,\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n if (this.useLongPollingLogs) {\n return this.streamLogsPolling(request, options);\n }\n\n return this.streamLogsEventStream(request);\n }\n\n /**\n * {@inheritdoc ScaffolderApi.dryRun}\n */\n async dryRun(\n request: ScaffolderDryRunOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderDryRunResponse> {\n return await this.requestRequired(\n await this.apiClient.dryRun(\n {\n body: {\n template: request.template,\n values: request.values,\n secrets: request.secrets,\n directoryContents: request.directoryContents,\n },\n },\n options,\n ),\n );\n }\n\n private streamLogsEventStream({\n isTaskRecoverable,\n taskId,\n after,\n }: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n return new ObservableImpl(subscriber => {\n const params = new URLSearchParams();\n if (after !== undefined) {\n params.set('after', String(Number(after)));\n }\n\n this.discoveryApi.getBaseUrl('scaffolder').then(\n baseUrl => {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/eventstream`;\n\n const processEvent = (event: any) => {\n if (event.data) {\n try {\n subscriber.next(JSON.parse(event.data));\n } catch (ex) {\n subscriber.error(ex);\n }\n }\n };\n\n const ctrl = new AbortController();\n void fetchEventSource(url, {\n fetch: this.fetchApi.fetch,\n signal: ctrl.signal,\n onmessage(e: EventSourceMessage) {\n if (e.event === 'log') {\n processEvent(e);\n return;\n } else if (e.event === 'completion' && !isTaskRecoverable) {\n processEvent(e);\n subscriber.complete();\n ctrl.abort();\n return;\n }\n processEvent(e);\n },\n onerror(err) {\n subscriber.error(err);\n },\n });\n },\n error => {\n subscriber.error(error);\n },\n );\n });\n }\n\n private streamLogsPolling(\n {\n taskId,\n after: inputAfter,\n }: {\n taskId: string;\n after?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n let after = inputAfter;\n\n return new ObservableImpl(subscriber => {\n (async () => {\n while (!subscriber.closed) {\n const response = await this.apiClient.streamLogsPolling(\n {\n path: { taskId },\n query: { after },\n },\n options,\n );\n\n if (!response.ok) {\n // wait for one second to not run into an\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n const logs = (await response.json()) as LogEvent[];\n\n for (const event of logs) {\n after = Number(event.id);\n\n subscriber.next(event);\n\n if (event.type === 'completion') {\n subscriber.complete();\n return;\n }\n }\n }\n })();\n });\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listActions}\n */\n async listActions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListActionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listActions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTemplatingExtensions}\n */\n async listTemplatingExtensions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListTemplatingExtensionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listTemplatingExtensions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.cancelTask}\n */\n async cancelTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ status?: TaskStatus }> {\n return await this.requestRequired(\n await this.apiClient.cancelTask({ path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async retry(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ id: string }> {\n return await this.requestRequired(\n await this.apiClient.retry({ body: {}, path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async autocomplete(\n {\n token,\n resource,\n provider,\n context,\n }: {\n token: string;\n provider: string;\n resource: string;\n context: Record<string, string>;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ results: { title?: string; id: string }[] }> {\n return await this.requestRequired(\n await this.apiClient.autocomplete(\n {\n path: { provider, resource },\n body: { token, context },\n },\n options,\n ),\n );\n }\n\n //\n // Private methods\n //\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n"],"names":["DefaultApiClient","parseEntityRef","ObservableImpl","fetchEventSource","ResponseError"],"mappings":"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"}
1
+ {"version":3,"file":"ScaffolderClient.cjs.js","sources":["../src/ScaffolderClient.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { parseEntityRef } from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { Observable } from '@backstage/types';\nimport {\n EventSourceMessage,\n fetchEventSource,\n} from '@microsoft/fetch-event-source';\nimport ObservableImpl from 'zen-observable';\n\nimport { type TemplateParameterSchema } from './TemplateEntityV1beta3';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderApi,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderGetIntegrationsListOptions,\n ScaffolderGetIntegrationsListResponse,\n ScaffolderRequestOptions,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderStreamLogsOptions,\n ScaffolderTask,\n} from './api';\nimport { DefaultApiClient, TaskStatus, TypedResponse } from './schema/openapi';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n */\nexport class ScaffolderClient implements ScaffolderApi {\n private readonly apiClient: DefaultApiClient;\n private readonly discoveryApi: {\n getBaseUrl(pluginId: string): Promise<string>;\n };\n private readonly scmIntegrationsApi: ScmIntegrationRegistry;\n private readonly fetchApi: { fetch: typeof fetch };\n private readonly identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n private readonly useLongPollingLogs: boolean;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi: { fetch: typeof fetch };\n identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n scmIntegrationsApi: ScmIntegrationRegistry;\n useLongPollingLogs?: boolean;\n }) {\n this.apiClient = new DefaultApiClient(options);\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi ?? { fetch };\n this.scmIntegrationsApi = options.scmIntegrationsApi;\n this.useLongPollingLogs = options.useLongPollingLogs ?? false;\n this.identityApi = options.identityApi;\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTasks}\n */\n async listTasks(\n request: {\n filterByOwnership: 'owned' | 'all';\n limit?: number;\n offset?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> {\n if (!this.identityApi) {\n throw new Error(\n 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method',\n );\n }\n\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n return await this.requestRequired(\n await this.apiClient.listTasks(\n {\n query: {\n createdBy:\n request.filterByOwnership === 'owned'\n ? [userEntityRef]\n : undefined,\n limit: request.limit,\n offset: request.offset,\n },\n },\n options,\n ),\n );\n }\n\n async getIntegrationsList(\n options: ScaffolderGetIntegrationsListOptions,\n ): Promise<ScaffolderGetIntegrationsListResponse> {\n const integrations = [\n ...this.scmIntegrationsApi.azure.list(),\n ...this.scmIntegrationsApi.bitbucketCloud.list(),\n ...this.scmIntegrationsApi.bitbucketServer.list(),\n ...this.scmIntegrationsApi.gerrit.list(),\n ...this.scmIntegrationsApi.gitea.list(),\n ...this.scmIntegrationsApi.github.list(),\n ...this.scmIntegrationsApi.gitlab.list(),\n ]\n .map(c => ({ type: c.type, title: c.title, host: c.config.host }))\n .filter(c => options.allowedHosts.includes(c.host));\n\n return {\n integrations,\n };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTemplateParameterSchema}\n */\n async getTemplateParameterSchema(\n templateRef: string,\n options?: ScaffolderRequestOptions,\n ): Promise<TemplateParameterSchema> {\n return await this.requestRequired(\n await this.apiClient.getTemplateParameterSchema(\n {\n path: parseEntityRef(templateRef, {\n defaultKind: 'template',\n }),\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.scaffold}\n */\n async scaffold(\n request: ScaffolderScaffoldOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n const response = await this.apiClient.scaffold(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 201) {\n const status = `${response.status} ${response.statusText}`;\n const body = await response.text();\n throw new Error(`Backend request failed, ${status} ${body.trim()}`);\n }\n\n const { id } = await response.json();\n return { taskId: id };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTask}\n */\n async getTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderTask> {\n return await this.requestRequired(\n await this.apiClient.getTask(\n {\n path: { taskId },\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.streamLogs}\n */\n streamLogs(\n request: ScaffolderStreamLogsOptions,\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n if (this.useLongPollingLogs) {\n return this.streamLogsPolling(request, options);\n }\n\n return this.streamLogsEventStream(request);\n }\n\n /**\n * {@inheritdoc ScaffolderApi.dryRun}\n */\n async dryRun(\n request: ScaffolderDryRunOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderDryRunResponse> {\n return await this.requestRequired(\n await this.apiClient.dryRun(\n {\n body: {\n template: request.template,\n values: request.values,\n secrets: request.secrets,\n directoryContents: request.directoryContents,\n },\n },\n options,\n ),\n );\n }\n\n private streamLogsEventStream({\n isTaskRecoverable,\n taskId,\n after,\n }: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n return new ObservableImpl(subscriber => {\n const params = new URLSearchParams();\n if (after !== undefined) {\n params.set('after', String(Number(after)));\n }\n\n const ctrl = new AbortController();\n\n this.discoveryApi.getBaseUrl('scaffolder').then(\n baseUrl => {\n if (ctrl.signal.aborted) {\n return;\n }\n\n const query = params.toString();\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/eventstream${query ? `?${query}` : ''}`;\n\n const processEvent = (event: any) => {\n if (event.data) {\n try {\n subscriber.next(JSON.parse(event.data));\n } catch (ex) {\n subscriber.error(ex);\n }\n }\n };\n\n fetchEventSource(url, {\n fetch: this.fetchApi.fetch,\n signal: ctrl.signal,\n openWhenHidden: true,\n onmessage(e: EventSourceMessage) {\n if (e.event === 'log') {\n processEvent(e);\n return;\n } else if (e.event === 'completion' && !isTaskRecoverable) {\n processEvent(e);\n subscriber.complete();\n ctrl.abort();\n return;\n }\n processEvent(e);\n },\n onclose() {\n subscriber.error(new Error('SSE connection closed unexpectedly'));\n },\n onerror(err) {\n ctrl.abort();\n subscriber.error(err);\n throw err;\n },\n }).catch(() => {\n // The throw in onerror is the documented way to stop fetchEventSource\n // from retrying, but it also rejects this promise. The error is already\n // forwarded via subscriber.error above, so we consume the rejection here.\n });\n },\n error => {\n subscriber.error(error);\n },\n );\n\n return () => ctrl.abort();\n });\n }\n\n private streamLogsPolling(\n {\n taskId,\n after: inputAfter,\n }: {\n taskId: string;\n after?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n let after = inputAfter;\n\n return new ObservableImpl(subscriber => {\n (async () => {\n while (!subscriber.closed) {\n const response = await this.apiClient.streamLogsPolling(\n {\n path: { taskId },\n query: { after },\n },\n options,\n );\n\n if (!response.ok) {\n // wait for one second to not run into an\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n const logs = (await response.json()) as LogEvent[];\n\n for (const event of logs) {\n after = Number(event.id);\n\n subscriber.next(event);\n\n if (event.type === 'completion') {\n subscriber.complete();\n return;\n }\n }\n }\n })();\n });\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listActions}\n */\n async listActions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListActionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listActions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTemplatingExtensions}\n */\n async listTemplatingExtensions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListTemplatingExtensionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listTemplatingExtensions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.cancelTask}\n */\n async cancelTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ status?: TaskStatus }> {\n return await this.requestRequired(\n await this.apiClient.cancelTask({ path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async retry(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ id: string }> {\n return await this.requestRequired(\n await this.apiClient.retry({ body: {}, path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async autocomplete(\n {\n token,\n resource,\n provider,\n context,\n }: {\n token: string;\n provider: string;\n resource: string;\n context: Record<string, string>;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ results: { title?: string; id: string }[] }> {\n return await this.requestRequired(\n await this.apiClient.autocomplete(\n {\n path: { provider, resource },\n body: { token, context },\n },\n options,\n ),\n );\n }\n\n //\n // Private methods\n //\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n"],"names":["DefaultApiClient","parseEntityRef","ObservableImpl","fetchEventSource","ResponseError"],"mappings":"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"}
@@ -139,11 +139,16 @@ class ScaffolderClient {
139
139
  if (after !== void 0) {
140
140
  params.set("after", String(Number(after)));
141
141
  }
142
+ const ctrl = new AbortController();
142
143
  this.discoveryApi.getBaseUrl("scaffolder").then(
143
144
  (baseUrl) => {
145
+ if (ctrl.signal.aborted) {
146
+ return;
147
+ }
148
+ const query = params.toString();
144
149
  const url = `${baseUrl}/v2/tasks/${encodeURIComponent(
145
150
  taskId
146
- )}/eventstream`;
151
+ )}/eventstream${query ? `?${query}` : ""}`;
147
152
  const processEvent = (event) => {
148
153
  if (event.data) {
149
154
  try {
@@ -153,10 +158,10 @@ class ScaffolderClient {
153
158
  }
154
159
  }
155
160
  };
156
- const ctrl = new AbortController();
157
- void fetchEventSource(url, {
161
+ fetchEventSource(url, {
158
162
  fetch: this.fetchApi.fetch,
159
163
  signal: ctrl.signal,
164
+ openWhenHidden: true,
160
165
  onmessage(e) {
161
166
  if (e.event === "log") {
162
167
  processEvent(e);
@@ -169,15 +174,22 @@ class ScaffolderClient {
169
174
  }
170
175
  processEvent(e);
171
176
  },
177
+ onclose() {
178
+ subscriber.error(new Error("SSE connection closed unexpectedly"));
179
+ },
172
180
  onerror(err) {
181
+ ctrl.abort();
173
182
  subscriber.error(err);
183
+ throw err;
174
184
  }
185
+ }).catch(() => {
175
186
  });
176
187
  },
177
188
  (error) => {
178
189
  subscriber.error(error);
179
190
  }
180
191
  );
192
+ return () => ctrl.abort();
181
193
  });
182
194
  }
183
195
  streamLogsPolling({
@@ -1 +1 @@
1
- {"version":3,"file":"ScaffolderClient.esm.js","sources":["../src/ScaffolderClient.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { parseEntityRef } from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { Observable } from '@backstage/types';\nimport {\n EventSourceMessage,\n fetchEventSource,\n} from '@microsoft/fetch-event-source';\nimport ObservableImpl from 'zen-observable';\n\nimport { type TemplateParameterSchema } from './TemplateEntityV1beta3';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderApi,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderGetIntegrationsListOptions,\n ScaffolderGetIntegrationsListResponse,\n ScaffolderRequestOptions,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderStreamLogsOptions,\n ScaffolderTask,\n} from './api';\nimport { DefaultApiClient, TaskStatus, TypedResponse } from './schema/openapi';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n */\nexport class ScaffolderClient implements ScaffolderApi {\n private readonly apiClient: DefaultApiClient;\n private readonly discoveryApi: {\n getBaseUrl(pluginId: string): Promise<string>;\n };\n private readonly scmIntegrationsApi: ScmIntegrationRegistry;\n private readonly fetchApi: { fetch: typeof fetch };\n private readonly identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n private readonly useLongPollingLogs: boolean;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi: { fetch: typeof fetch };\n identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n scmIntegrationsApi: ScmIntegrationRegistry;\n useLongPollingLogs?: boolean;\n }) {\n this.apiClient = new DefaultApiClient(options);\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi ?? { fetch };\n this.scmIntegrationsApi = options.scmIntegrationsApi;\n this.useLongPollingLogs = options.useLongPollingLogs ?? false;\n this.identityApi = options.identityApi;\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTasks}\n */\n async listTasks(\n request: {\n filterByOwnership: 'owned' | 'all';\n limit?: number;\n offset?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> {\n if (!this.identityApi) {\n throw new Error(\n 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method',\n );\n }\n\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n return await this.requestRequired(\n await this.apiClient.listTasks(\n {\n query: {\n createdBy:\n request.filterByOwnership === 'owned'\n ? [userEntityRef]\n : undefined,\n limit: request.limit,\n offset: request.offset,\n },\n },\n options,\n ),\n );\n }\n\n async getIntegrationsList(\n options: ScaffolderGetIntegrationsListOptions,\n ): Promise<ScaffolderGetIntegrationsListResponse> {\n const integrations = [\n ...this.scmIntegrationsApi.azure.list(),\n ...this.scmIntegrationsApi.bitbucketCloud.list(),\n ...this.scmIntegrationsApi.bitbucketServer.list(),\n ...this.scmIntegrationsApi.gerrit.list(),\n ...this.scmIntegrationsApi.gitea.list(),\n ...this.scmIntegrationsApi.github.list(),\n ...this.scmIntegrationsApi.gitlab.list(),\n ]\n .map(c => ({ type: c.type, title: c.title, host: c.config.host }))\n .filter(c => options.allowedHosts.includes(c.host));\n\n return {\n integrations,\n };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTemplateParameterSchema}\n */\n async getTemplateParameterSchema(\n templateRef: string,\n options?: ScaffolderRequestOptions,\n ): Promise<TemplateParameterSchema> {\n return await this.requestRequired(\n await this.apiClient.getTemplateParameterSchema(\n {\n path: parseEntityRef(templateRef, {\n defaultKind: 'template',\n }),\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.scaffold}\n */\n async scaffold(\n request: ScaffolderScaffoldOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n const response = await this.apiClient.scaffold(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 201) {\n const status = `${response.status} ${response.statusText}`;\n const body = await response.text();\n throw new Error(`Backend request failed, ${status} ${body.trim()}`);\n }\n\n const { id } = await response.json();\n return { taskId: id };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTask}\n */\n async getTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderTask> {\n return await this.requestRequired(\n await this.apiClient.getTask(\n {\n path: { taskId },\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.streamLogs}\n */\n streamLogs(\n request: ScaffolderStreamLogsOptions,\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n if (this.useLongPollingLogs) {\n return this.streamLogsPolling(request, options);\n }\n\n return this.streamLogsEventStream(request);\n }\n\n /**\n * {@inheritdoc ScaffolderApi.dryRun}\n */\n async dryRun(\n request: ScaffolderDryRunOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderDryRunResponse> {\n return await this.requestRequired(\n await this.apiClient.dryRun(\n {\n body: {\n template: request.template,\n values: request.values,\n secrets: request.secrets,\n directoryContents: request.directoryContents,\n },\n },\n options,\n ),\n );\n }\n\n private streamLogsEventStream({\n isTaskRecoverable,\n taskId,\n after,\n }: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n return new ObservableImpl(subscriber => {\n const params = new URLSearchParams();\n if (after !== undefined) {\n params.set('after', String(Number(after)));\n }\n\n this.discoveryApi.getBaseUrl('scaffolder').then(\n baseUrl => {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/eventstream`;\n\n const processEvent = (event: any) => {\n if (event.data) {\n try {\n subscriber.next(JSON.parse(event.data));\n } catch (ex) {\n subscriber.error(ex);\n }\n }\n };\n\n const ctrl = new AbortController();\n void fetchEventSource(url, {\n fetch: this.fetchApi.fetch,\n signal: ctrl.signal,\n onmessage(e: EventSourceMessage) {\n if (e.event === 'log') {\n processEvent(e);\n return;\n } else if (e.event === 'completion' && !isTaskRecoverable) {\n processEvent(e);\n subscriber.complete();\n ctrl.abort();\n return;\n }\n processEvent(e);\n },\n onerror(err) {\n subscriber.error(err);\n },\n });\n },\n error => {\n subscriber.error(error);\n },\n );\n });\n }\n\n private streamLogsPolling(\n {\n taskId,\n after: inputAfter,\n }: {\n taskId: string;\n after?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n let after = inputAfter;\n\n return new ObservableImpl(subscriber => {\n (async () => {\n while (!subscriber.closed) {\n const response = await this.apiClient.streamLogsPolling(\n {\n path: { taskId },\n query: { after },\n },\n options,\n );\n\n if (!response.ok) {\n // wait for one second to not run into an\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n const logs = (await response.json()) as LogEvent[];\n\n for (const event of logs) {\n after = Number(event.id);\n\n subscriber.next(event);\n\n if (event.type === 'completion') {\n subscriber.complete();\n return;\n }\n }\n }\n })();\n });\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listActions}\n */\n async listActions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListActionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listActions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTemplatingExtensions}\n */\n async listTemplatingExtensions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListTemplatingExtensionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listTemplatingExtensions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.cancelTask}\n */\n async cancelTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ status?: TaskStatus }> {\n return await this.requestRequired(\n await this.apiClient.cancelTask({ path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async retry(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ id: string }> {\n return await this.requestRequired(\n await this.apiClient.retry({ body: {}, path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async autocomplete(\n {\n token,\n resource,\n provider,\n context,\n }: {\n token: string;\n provider: string;\n resource: string;\n context: Record<string, string>;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ results: { title?: string; id: string }[] }> {\n return await this.requestRequired(\n await this.apiClient.autocomplete(\n {\n path: { provider, resource },\n body: { token, context },\n },\n options,\n ),\n );\n }\n\n //\n // Private methods\n //\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScaffolderClient.esm.js","sources":["../src/ScaffolderClient.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { parseEntityRef } from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { Observable } from '@backstage/types';\nimport {\n EventSourceMessage,\n fetchEventSource,\n} from '@microsoft/fetch-event-source';\nimport ObservableImpl from 'zen-observable';\n\nimport { type TemplateParameterSchema } from './TemplateEntityV1beta3';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderApi,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderGetIntegrationsListOptions,\n ScaffolderGetIntegrationsListResponse,\n ScaffolderRequestOptions,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderStreamLogsOptions,\n ScaffolderTask,\n} from './api';\nimport { DefaultApiClient, TaskStatus, TypedResponse } from './schema/openapi';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n */\nexport class ScaffolderClient implements ScaffolderApi {\n private readonly apiClient: DefaultApiClient;\n private readonly discoveryApi: {\n getBaseUrl(pluginId: string): Promise<string>;\n };\n private readonly scmIntegrationsApi: ScmIntegrationRegistry;\n private readonly fetchApi: { fetch: typeof fetch };\n private readonly identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n private readonly useLongPollingLogs: boolean;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi: { fetch: typeof fetch };\n identityApi?: {\n getBackstageIdentity(): Promise<{\n type: 'user';\n userEntityRef: string;\n ownershipEntityRefs: string[];\n }>;\n };\n scmIntegrationsApi: ScmIntegrationRegistry;\n useLongPollingLogs?: boolean;\n }) {\n this.apiClient = new DefaultApiClient(options);\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi ?? { fetch };\n this.scmIntegrationsApi = options.scmIntegrationsApi;\n this.useLongPollingLogs = options.useLongPollingLogs ?? false;\n this.identityApi = options.identityApi;\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTasks}\n */\n async listTasks(\n request: {\n filterByOwnership: 'owned' | 'all';\n limit?: number;\n offset?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> {\n if (!this.identityApi) {\n throw new Error(\n 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method',\n );\n }\n\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n return await this.requestRequired(\n await this.apiClient.listTasks(\n {\n query: {\n createdBy:\n request.filterByOwnership === 'owned'\n ? [userEntityRef]\n : undefined,\n limit: request.limit,\n offset: request.offset,\n },\n },\n options,\n ),\n );\n }\n\n async getIntegrationsList(\n options: ScaffolderGetIntegrationsListOptions,\n ): Promise<ScaffolderGetIntegrationsListResponse> {\n const integrations = [\n ...this.scmIntegrationsApi.azure.list(),\n ...this.scmIntegrationsApi.bitbucketCloud.list(),\n ...this.scmIntegrationsApi.bitbucketServer.list(),\n ...this.scmIntegrationsApi.gerrit.list(),\n ...this.scmIntegrationsApi.gitea.list(),\n ...this.scmIntegrationsApi.github.list(),\n ...this.scmIntegrationsApi.gitlab.list(),\n ]\n .map(c => ({ type: c.type, title: c.title, host: c.config.host }))\n .filter(c => options.allowedHosts.includes(c.host));\n\n return {\n integrations,\n };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTemplateParameterSchema}\n */\n async getTemplateParameterSchema(\n templateRef: string,\n options?: ScaffolderRequestOptions,\n ): Promise<TemplateParameterSchema> {\n return await this.requestRequired(\n await this.apiClient.getTemplateParameterSchema(\n {\n path: parseEntityRef(templateRef, {\n defaultKind: 'template',\n }),\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.scaffold}\n */\n async scaffold(\n request: ScaffolderScaffoldOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n const response = await this.apiClient.scaffold(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 201) {\n const status = `${response.status} ${response.statusText}`;\n const body = await response.text();\n throw new Error(`Backend request failed, ${status} ${body.trim()}`);\n }\n\n const { id } = await response.json();\n return { taskId: id };\n }\n\n /**\n * {@inheritdoc ScaffolderApi.getTask}\n */\n async getTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderTask> {\n return await this.requestRequired(\n await this.apiClient.getTask(\n {\n path: { taskId },\n },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.streamLogs}\n */\n streamLogs(\n request: ScaffolderStreamLogsOptions,\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n if (this.useLongPollingLogs) {\n return this.streamLogsPolling(request, options);\n }\n\n return this.streamLogsEventStream(request);\n }\n\n /**\n * {@inheritdoc ScaffolderApi.dryRun}\n */\n async dryRun(\n request: ScaffolderDryRunOptions,\n options?: ScaffolderRequestOptions,\n ): Promise<ScaffolderDryRunResponse> {\n return await this.requestRequired(\n await this.apiClient.dryRun(\n {\n body: {\n template: request.template,\n values: request.values,\n secrets: request.secrets,\n directoryContents: request.directoryContents,\n },\n },\n options,\n ),\n );\n }\n\n private streamLogsEventStream({\n isTaskRecoverable,\n taskId,\n after,\n }: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n return new ObservableImpl(subscriber => {\n const params = new URLSearchParams();\n if (after !== undefined) {\n params.set('after', String(Number(after)));\n }\n\n const ctrl = new AbortController();\n\n this.discoveryApi.getBaseUrl('scaffolder').then(\n baseUrl => {\n if (ctrl.signal.aborted) {\n return;\n }\n\n const query = params.toString();\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/eventstream${query ? `?${query}` : ''}`;\n\n const processEvent = (event: any) => {\n if (event.data) {\n try {\n subscriber.next(JSON.parse(event.data));\n } catch (ex) {\n subscriber.error(ex);\n }\n }\n };\n\n fetchEventSource(url, {\n fetch: this.fetchApi.fetch,\n signal: ctrl.signal,\n openWhenHidden: true,\n onmessage(e: EventSourceMessage) {\n if (e.event === 'log') {\n processEvent(e);\n return;\n } else if (e.event === 'completion' && !isTaskRecoverable) {\n processEvent(e);\n subscriber.complete();\n ctrl.abort();\n return;\n }\n processEvent(e);\n },\n onclose() {\n subscriber.error(new Error('SSE connection closed unexpectedly'));\n },\n onerror(err) {\n ctrl.abort();\n subscriber.error(err);\n throw err;\n },\n }).catch(() => {\n // The throw in onerror is the documented way to stop fetchEventSource\n // from retrying, but it also rejects this promise. The error is already\n // forwarded via subscriber.error above, so we consume the rejection here.\n });\n },\n error => {\n subscriber.error(error);\n },\n );\n\n return () => ctrl.abort();\n });\n }\n\n private streamLogsPolling(\n {\n taskId,\n after: inputAfter,\n }: {\n taskId: string;\n after?: number;\n },\n options?: ScaffolderRequestOptions,\n ): Observable<LogEvent> {\n let after = inputAfter;\n\n return new ObservableImpl(subscriber => {\n (async () => {\n while (!subscriber.closed) {\n const response = await this.apiClient.streamLogsPolling(\n {\n path: { taskId },\n query: { after },\n },\n options,\n );\n\n if (!response.ok) {\n // wait for one second to not run into an\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n const logs = (await response.json()) as LogEvent[];\n\n for (const event of logs) {\n after = Number(event.id);\n\n subscriber.next(event);\n\n if (event.type === 'completion') {\n subscriber.complete();\n return;\n }\n }\n }\n })();\n });\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listActions}\n */\n async listActions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListActionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listActions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.listTemplatingExtensions}\n */\n async listTemplatingExtensions(\n options?: ScaffolderRequestOptions,\n ): Promise<ListTemplatingExtensionsResponse> {\n return await this.requestRequired(\n await this.apiClient.listTemplatingExtensions(null as any, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.cancelTask}\n */\n async cancelTask(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ status?: TaskStatus }> {\n return await this.requestRequired(\n await this.apiClient.cancelTask({ path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async retry(\n taskId: string,\n options?: ScaffolderRequestOptions,\n ): Promise<{ id: string }> {\n return await this.requestRequired(\n await this.apiClient.retry({ body: {}, path: { taskId } }, options),\n );\n }\n\n /**\n * {@inheritdoc ScaffolderApi.retry}\n */\n async autocomplete(\n {\n token,\n resource,\n provider,\n context,\n }: {\n token: string;\n provider: string;\n resource: string;\n context: Record<string, string>;\n },\n options?: ScaffolderRequestOptions,\n ): Promise<{ results: { title?: string; id: string }[] }> {\n return await this.requestRequired(\n await this.apiClient.autocomplete(\n {\n path: { provider, resource },\n body: { token, context },\n },\n options,\n ),\n );\n }\n\n //\n // Private methods\n //\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n"],"names":[],"mappings":";;;;;;AAiDO,MAAM,gBAAA,CAA0C;AAAA,EACpC,SAAA;AAAA,EACA,YAAA;AAAA,EAGA,kBAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EAOA,kBAAA;AAAA,EAEjB,YAAY,OAAA,EAYT;AACD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,gBAAA,CAAiB,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,eAAe,OAAA,CAAQ,YAAA;AAC5B,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,QAAA,IAAY,EAAE,KAAA,EAAM;AAC5C,IAAA,IAAA,CAAK,qBAAqB,OAAA,CAAQ,kBAAA;AAClC,IAAA,IAAA,CAAK,kBAAA,GAAqB,QAAQ,kBAAA,IAAsB,KAAA;AACxD,IAAA,IAAA,CAAK,cAAc,OAAA,CAAQ,WAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,CACJ,OAAA,EAKA,OAAA,EAC2D;AAC3D,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AACrB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,IAAA,CAAK,YAAY,oBAAA,EAAqB;AAEtE,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,SAAA;AAAA,QACnB;AAAA,UACE,KAAA,EAAO;AAAA,YACL,WACE,OAAA,CAAQ,iBAAA,KAAsB,OAAA,GAC1B,CAAC,aAAa,CAAA,GACd,MAAA;AAAA,YACN,OAAO,OAAA,CAAQ,KAAA;AAAA,YACf,QAAQ,OAAA,CAAQ;AAAA;AAClB,SACF;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAAA,EAEA,MAAM,oBACJ,OAAA,EACgD;AAChD,IAAA,MAAM,YAAA,GAAe;AAAA,MACnB,GAAG,IAAA,CAAK,kBAAA,CAAmB,KAAA,CAAM,IAAA,EAAK;AAAA,MACtC,GAAG,IAAA,CAAK,kBAAA,CAAmB,cAAA,CAAe,IAAA,EAAK;AAAA,MAC/C,GAAG,IAAA,CAAK,kBAAA,CAAmB,eAAA,CAAgB,IAAA,EAAK;AAAA,MAChD,GAAG,IAAA,CAAK,kBAAA,CAAmB,MAAA,CAAO,IAAA,EAAK;AAAA,MACvC,GAAG,IAAA,CAAK,kBAAA,CAAmB,KAAA,CAAM,IAAA,EAAK;AAAA,MACtC,GAAG,IAAA,CAAK,kBAAA,CAAmB,MAAA,CAAO,IAAA,EAAK;AAAA,MACvC,GAAG,IAAA,CAAK,kBAAA,CAAmB,MAAA,CAAO,IAAA;AAAK,KACzC,CACG,IAAI,CAAA,CAAA,MAAM,EAAE,MAAM,CAAA,CAAE,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,IAAA,EAAM,EAAE,MAAA,CAAO,IAAA,EAAK,CAAE,CAAA,CAChE,MAAA,CAAO,CAAA,CAAA,KAAK,QAAQ,YAAA,CAAa,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAEpD,IAAA,OAAO;AAAA,MACL;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,0BAAA,CACJ,WAAA,EACA,OAAA,EACkC;AAClC,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,0BAAA;AAAA,QACnB;AAAA,UACE,IAAA,EAAM,eAAe,WAAA,EAAa;AAAA,YAChC,WAAA,EAAa;AAAA,WACd;AAAA,SACH;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CACJ,OAAA,EACA,OAAA,EACqC;AACrC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,QAAA;AAAA,MACpC;AAAA,QACE,IAAA,EAAM;AAAA,OACR;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,MAAM,SAAS,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA,CAAA;AACxD,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,MAAA,MAAM,IAAI,MAAM,CAAA,wBAAA,EAA2B,MAAM,IAAI,IAAA,CAAK,IAAA,EAAM,CAAA,CAAE,CAAA;AAAA,IACpE;AAEA,IAAA,MAAM,EAAE,EAAA,EAAG,GAAI,MAAM,SAAS,IAAA,EAAK;AACnC,IAAA,OAAO,EAAE,QAAQ,EAAA,EAAG;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,CACJ,MAAA,EACA,OAAA,EACyB;AACzB,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,OAAA;AAAA,QACnB;AAAA,UACE,IAAA,EAAM,EAAE,MAAA;AAAO,SACjB;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,CACE,SACA,OAAA,EACsB;AACtB,IAAA,IAAI,KAAK,kBAAA,EAAoB;AAC3B,MAAA,OAAO,IAAA,CAAK,iBAAA,CAAkB,OAAA,EAAS,OAAO,CAAA;AAAA,IAChD;AAEA,IAAA,OAAO,IAAA,CAAK,sBAAsB,OAAO,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,OAAA,EACmC;AACnC,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,MAAA;AAAA,QACnB;AAAA,UACE,IAAA,EAAM;AAAA,YACJ,UAAU,OAAA,CAAQ,QAAA;AAAA,YAClB,QAAQ,OAAA,CAAQ,MAAA;AAAA,YAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,YACjB,mBAAmB,OAAA,CAAQ;AAAA;AAC7B,SACF;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAAA,EAEQ,qBAAA,CAAsB;AAAA,IAC5B,iBAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF,EAAsD;AACpD,IAAA,OAAO,IAAI,eAAe,CAAA,UAAA,KAAc;AACtC,MAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,MAAA,IAAI,UAAU,MAAA,EAAW;AACvB,QAAA,MAAA,CAAO,IAAI,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAAA,MAC3C;AAEA,MAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AAEjC,MAAA,IAAA,CAAK,YAAA,CAAa,UAAA,CAAW,YAAY,CAAA,CAAE,IAAA;AAAA,QACzC,CAAA,OAAA,KAAW;AACT,UAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AACvB,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,EAAS;AAC9B,UAAA,MAAM,GAAA,GAAM,CAAA,EAAG,OAAO,CAAA,UAAA,EAAa,kBAAA;AAAA,YACjC;AAAA,WACD,CAAA,YAAA,EAAe,KAAA,GAAQ,CAAA,CAAA,EAAI,KAAK,KAAK,EAAE,CAAA,CAAA;AAExC,UAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KAAe;AACnC,YAAA,IAAI,MAAM,IAAA,EAAM;AACd,cAAA,IAAI;AACF,gBAAA,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,cACxC,SAAS,EAAA,EAAI;AACX,gBAAA,UAAA,CAAW,MAAM,EAAE,CAAA;AAAA,cACrB;AAAA,YACF;AAAA,UACF,CAAA;AAEA,UAAA,gBAAA,CAAiB,GAAA,EAAK;AAAA,YACpB,KAAA,EAAO,KAAK,QAAA,CAAS,KAAA;AAAA,YACrB,QAAQ,IAAA,CAAK,MAAA;AAAA,YACb,cAAA,EAAgB,IAAA;AAAA,YAChB,UAAU,CAAA,EAAuB;AAC/B,cAAA,IAAI,CAAA,CAAE,UAAU,KAAA,EAAO;AACrB,gBAAA,YAAA,CAAa,CAAC,CAAA;AACd,gBAAA;AAAA,cACF,CAAA,MAAA,IAAW,CAAA,CAAE,KAAA,KAAU,YAAA,IAAgB,CAAC,iBAAA,EAAmB;AACzD,gBAAA,YAAA,CAAa,CAAC,CAAA;AACd,gBAAA,UAAA,CAAW,QAAA,EAAS;AACpB,gBAAA,IAAA,CAAK,KAAA,EAAM;AACX,gBAAA;AAAA,cACF;AACA,cAAA,YAAA,CAAa,CAAC,CAAA;AAAA,YAChB,CAAA;AAAA,YACA,OAAA,GAAU;AACR,cAAA,UAAA,CAAW,KAAA,CAAM,IAAI,KAAA,CAAM,oCAAoC,CAAC,CAAA;AAAA,YAClE,CAAA;AAAA,YACA,QAAQ,GAAA,EAAK;AACX,cAAA,IAAA,CAAK,KAAA,EAAM;AACX,cAAA,UAAA,CAAW,MAAM,GAAG,CAAA;AACpB,cAAA,MAAM,GAAA;AAAA,YACR;AAAA,WACD,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,UAIf,CAAC,CAAA;AAAA,QACH,CAAA;AAAA,QACA,CAAA,KAAA,KAAS;AACP,UAAA,UAAA,CAAW,MAAM,KAAK,CAAA;AAAA,QACxB;AAAA,OACF;AAEA,MAAA,OAAO,MAAM,KAAK,KAAA,EAAM;AAAA,IAC1B,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,iBAAA,CACN;AAAA,IACE,MAAA;AAAA,IACA,KAAA,EAAO;AAAA,KAKT,OAAA,EACsB;AACtB,IAAA,IAAI,KAAA,GAAQ,UAAA;AAEZ,IAAA,OAAO,IAAI,eAAe,CAAA,UAAA,KAAc;AACtC,MAAA,CAAC,YAAY;AACX,QAAA,OAAO,CAAC,WAAW,MAAA,EAAQ;AACzB,UAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,iBAAA;AAAA,YACpC;AAAA,cACE,IAAA,EAAM,EAAE,MAAA,EAAO;AAAA,cACf,KAAA,EAAO,EAAE,KAAA;AAAM,aACjB;AAAA,YACA;AAAA,WACF;AAEA,UAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAEhB,YAAA,MAAM,IAAI,OAAA,CAAQ,CAAA,OAAA,KAAW,UAAA,CAAW,OAAA,EAAS,GAAI,CAAC,CAAA;AACtD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,UAAA,KAAA,MAAW,SAAS,IAAA,EAAM;AACxB,YAAA,KAAA,GAAQ,MAAA,CAAO,MAAM,EAAE,CAAA;AAEvB,YAAA,UAAA,CAAW,KAAK,KAAK,CAAA;AAErB,YAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,cAAA,UAAA,CAAW,QAAA,EAAS;AACpB,cAAA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAA,GAAG;AAAA,IACL,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YACJ,OAAA,EAC8B;AAC9B,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,MAAa,OAAO;AAAA,KACvD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,yBACJ,OAAA,EAC2C;AAC3C,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,IAAA,CAAK,SAAA,CAAU,wBAAA,CAAyB,MAAa,OAAO;AAAA,KACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,CACJ,MAAA,EACA,OAAA,EACkC;AAClC,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA,CAAW,EAAE,MAAM,EAAE,MAAA,EAAO,EAAE,EAAG,OAAO;AAAA,KAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,CACJ,MAAA,EACA,OAAA,EACyB;AACzB,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,EAAE,IAAA,EAAM,EAAC,EAAG,IAAA,EAAM,EAAE,MAAA,EAAO,IAAK,OAAO;AAAA,KACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAA,CACJ;AAAA,IACE,KAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,KAOF,OAAA,EACwD;AACxD,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,YAAA;AAAA,QACnB;AAAA,UACE,IAAA,EAAM,EAAE,QAAA,EAAU,QAAA,EAAS;AAAA,UAC3B,IAAA,EAAM,EAAE,KAAA,EAAO,OAAA;AAAQ,SACzB;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,gBAAmB,QAAA,EAAwC;AACvE,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AACF;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-common",
3
- "version": "2.3.0-next.2",
3
+ "version": "2.3.0",
4
4
  "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin",
5
5
  "backstage": {
6
6
  "role": "common-library",
@@ -70,11 +70,11 @@
70
70
  "test": "backstage-cli package test"
71
71
  },
72
72
  "dependencies": {
73
- "@backstage/catalog-model": "1.10.0",
74
- "@backstage/errors": "1.3.1",
75
- "@backstage/integration": "2.1.2-next.1",
76
- "@backstage/plugin-permission-common": "0.9.11-next.0",
77
- "@backstage/types": "1.2.2",
73
+ "@backstage/catalog-model": "^1.10.1",
74
+ "@backstage/errors": "^1.3.1",
75
+ "@backstage/integration": "^2.1.2",
76
+ "@backstage/plugin-permission-common": "^0.9.11",
77
+ "@backstage/types": "^1.2.2",
78
78
  "@microsoft/fetch-event-source": "^2.0.1",
79
79
  "@types/json-schema": "^7.0.9",
80
80
  "cross-fetch": "^4.0.0",
@@ -82,8 +82,8 @@
82
82
  "zen-observable": "^0.10.0"
83
83
  },
84
84
  "devDependencies": {
85
- "@backstage/cli": "0.36.6-next.1",
86
- "@backstage/test-utils": "1.7.22-next.2",
85
+ "@backstage/cli": "^0.36.6",
86
+ "@backstage/test-utils": "^1.7.22",
87
87
  "msw": "^2.0.0"
88
88
  },
89
89
  "module": "./dist/index.esm.js"