From c3fd72b8a5a8035330b3f03df67ffdb556cf2d0f Mon Sep 17 00:00:00 2001 From: hoangndst Date: Fri, 6 Dec 2024 04:46:21 +0700 Subject: [PATCH 1/3] chore: init scaffolder --- packages/backend/package.json | 1 + packages/backend/src/index.ts | 3 + .../.eslintrc.js | 1 + .../README.md | 61 ++++ .../package.json | 41 +++ .../actions/backend/createBackend.example.ts | 48 +++ .../src/actions/backend/createBackend.test.ts | 124 +++++++ .../src/actions/backend/createBackend.ts | 105 ++++++ .../src/actions/backend/index.ts | 1 + .../workspace/createWorkspace.example.ts | 40 +++ .../actions/workspace/createWorkspace.test.ts | 108 ++++++ .../src/actions/workspace/createWorkspace.ts | 121 +++++++ .../src/actions/workspace/index.ts | 1 + .../src/api/index.ts | 122 +++++++ .../src/api/types.ts | 27 ++ .../src/index.ts | 23 ++ .../src/module.ts | 52 +++ yarn.lock | 316 +++++++++++++++++- 18 files changed, 1184 insertions(+), 11 deletions(-) create mode 100644 plugins/scaffolder-backend-module-kusion/.eslintrc.js create mode 100644 plugins/scaffolder-backend-module-kusion/README.md create mode 100644 plugins/scaffolder-backend-module-kusion/package.json create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/api/index.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/api/types.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/index.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/module.ts diff --git a/packages/backend/package.json b/packages/backend/package.json index 8a0ef94..6ef1f7a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -39,6 +39,7 @@ "@backstage/plugin-search-backend-module-techdocs": "^0.3.2", "@backstage/plugin-search-backend-node": "^1.3.5", "@backstage/plugin-techdocs-backend": "^1.11.2", + "@kusion/backstage-plugin-scaffolder-backend-module-kusion": "^0.1.0", "app": "link:../app", "better-sqlite3": "^9.0.0", "node-gyp": "^10.0.0", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 69a7351..71b837c 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -51,4 +51,7 @@ backend.add(import('@backstage/plugin-search-backend-module-techdocs')); // kubernetes backend.add(import('@backstage/plugin-kubernetes-backend')); +// kusion +backend.add(import('@kusion/backstage-plugin-scaffolder-backend-module-kusion')); + backend.start(); diff --git a/plugins/scaffolder-backend-module-kusion/.eslintrc.js b/plugins/scaffolder-backend-module-kusion/.eslintrc.js new file mode 100644 index 0000000..e2a53a6 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/scaffolder-backend-module-kusion/README.md b/plugins/scaffolder-backend-module-kusion/README.md new file mode 100644 index 0000000..4ce3061 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/README.md @@ -0,0 +1,61 @@ +## Backstage Plugin Scaffolder Backend Module Kusion + +### Getting Started + +You need a `Kusion Server` running. You can find the server [here](https://github.com/KusionStack/kusion). + +You need to add the following to your `app-config.yaml`. For example: + +```yaml +backend: +kusion: + baseUrl: 'http://localhost:3000' + proxyPath: '/api/v1' # Optional - Default is '/api/v1' + token: 'your-token' +``` + +### From your Backstage root directory + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @kusion/backstage-plugin-scaffolder-backend-module-kusion +``` + +### Workspace + +#### Kusion Create Workspace + +The Kusion Workspace Create action that allows you to create a new Kusion Workspace from a template. + +`kusion:workspace:create` + +```yaml +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: create-workspace + title: Create Workspace Template + description: A template to create a workspace +tags: + - kusion + - workspace +spec: + steps: + - id: create-workspace + name: Create Workspace + action: kusion:workspace:create + input: + name: ${{ parameters.name }} + description: ${{ parameters.description }} + labels: ${{ parameters.labels }} + owners: ${{ parameters.owners }} + backendID: ${{ parameters.backend_id }} + output: + text: + - title: Workspace create status + description: The status of workspace creation + content: | + Success: `${{ steps['create-workspace'].output.success }}` + Message: `${{ steps['create-workspace'].output.message }}` + Data: `${{ steps['create-workspace'].output.data }}` +``` diff --git a/plugins/scaffolder-backend-module-kusion/package.json b/plugins/scaffolder-backend-module-kusion/package.json new file mode 100644 index 0000000..7ef0436 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/package.json @@ -0,0 +1,41 @@ +{ + "name": "@kusion/backstage-plugin-scaffolder-backend-module-kusion", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": true, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "scaffolder", + "pluginPackage": "@backstage/plugin-scaffolder-backend" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "^1.0.2", + "@backstage/config": "^1.3.0", + "@backstage/plugin-scaffolder-node": "^0.6.0", + "node-fetch": "^2.7.0", + "yaml": "^2.6.1" + }, + "devDependencies": { + "@backstage/cli": "^0.29.0", + "@backstage/plugin-scaffolder-node-test-utils": "^0.1.15" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts new file mode 100644 index 0000000..9623977 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Create a backend in Kusion', + example: yaml.stringify({ + steps: [ + { + id: 'create-backend', + action: 'kusion:backend:create', + name: 'Create backend', + input: { + name: 'my-backend', + description: 'This is my backend', + backendConfig: { + "configs": { + "region": "string", + "endpoint": "string", + "accessKeyID": "string", + "accessKeySecret": "string", + "bucket": "string", + "prefix": "string", + }, + "type": "s3" + }, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts new file mode 100644 index 0000000..119d62a --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts @@ -0,0 +1,124 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createCreateBackendAction } from './createBackend'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ConfigReader } from '@backstage/config'; + +jest.mock('../../api', () => ({ + createKusionApi: jest.fn(), +})); + +describe('createCreateBackendAction', () => { + const config = new ConfigReader({}); + const action = createCreateBackendAction({ config }); + + it('should create a backend successfully', async () => { + const mockContext = createMockActionContext({ + input: { + name: 'test-backend', + description: 'A test backend', + backendConfig: { + type: 'exampleType', + configs: { + key1: 'value1', + key2: 'value2', + }, + }, + }, + }); + + const mockKusionApi = { + post: jest.fn().mockResolvedValue({ + success: true, + message: 'Backend created successfully', + data: { id: 'backend-id' }, + }), + }; + + require('../../api').createKusionApi.mockReturnValue(mockKusionApi); + + await action.handler(mockContext); + + expect(mockKusionApi.post).toHaveBeenCalledWith('backends', { + name: 'test-backend', + description: 'A test backend', + backendConfig: { + type: 'exampleType', + configs: { + key1: 'value1', + key2: 'value2', + }, + }, + }); + expect(mockContext.output).toHaveBeenCalledWith('success', true); + expect(mockContext.output).toHaveBeenCalledWith( + 'message', + 'Backend created successfully', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'data', + JSON.stringify({ id: 'backend-id' }), + ); + }); + + it('should handle failure to create a backend', async () => { + const mockContext = createMockActionContext({ + input: { + name: 'test-backend', + description: 'A test backend', + backendConfig: { + type: 'exampleType', + configs: { + key1: 'value1', + key2: 'value2', + }, + }, + }, + }); + + const mockKusionApi = { + post: jest.fn().mockResolvedValue({ + success: false, + message: 'Failed to create backend', + }), + }; + + require('../../api').createKusionApi.mockReturnValue(mockKusionApi); + + await expect(action.handler(mockContext)).rejects.toThrow( + 'Unable to create backend, Failed to create backend', + ); + + expect(mockKusionApi.post).toHaveBeenCalledWith('backends', { + name: 'test-backend', + description: 'A test backend', + backendConfig: { + type: 'exampleType', + configs: { + key1: 'value1', + key2: 'value2', + }, + }, + }); + expect(mockContext.output).toHaveBeenCalledWith('success', false); + expect(mockContext.output).toHaveBeenCalledWith( + 'message', + 'Failed to create backend', + ); + expect(mockContext.output).toHaveBeenCalledWith('data', '{}'); + }); +}); diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts new file mode 100644 index 0000000..d69e2a1 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts @@ -0,0 +1,105 @@ +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { Config } from '@backstage/config'; +import { createKusionApi } from '../../api'; +import { examples } from './createBackend.example'; + +/** + * Creates a `kusion:backend:create` Scaffolder action. + * + * @public + */ +export function createCreateBackendAction(options: { config: Config }) { + const { config } = options; + return createTemplateAction<{ + name: string; + description: string; + backendConfig: { + type: string; + configs: Record; + }; + }>({ + id: 'kusion:backend:create', + examples, + schema: { + input: { + type: 'object', + required: ['name', 'backendConfig'], + properties: { + name: { + title: 'Backend Name', + type: 'string', + }, + description: { + title: 'Backend Description', + type: 'string', + }, + backendConfig: { + title: 'Backend Configuration', + type: 'object', + required: ['type', 'configs'], + properties: { + type: { + title: 'Backend Type', + type: 'string', + }, + configs: { + title: 'Backend Configs', + type: 'object', + additionalProperties: { + type: 'string', + }, + }, + }, + }, + }, + }, + output: { + type: 'object', + properties: { + success: { + title: 'Success', + type: 'boolean', + }, + message: { + title: 'Message', + type: 'string', + }, + data: { + title: 'Data', + type: 'object', + }, + }, + }, + }, + async handler(ctx) { + const { name, description, backendConfig } = ctx.input; + const kusionApi = createKusionApi({ configApi: config }); + const requestBody = { + name, + description, + backendConfig, + }; + + ctx.logger.info( + 'Creating backend with the following request body: ', + requestBody, + ); + + const response = await kusionApi.post('backends', requestBody); + + if (!response.success || response.data === undefined) { + ctx.logger.error(` + Unable to create backend, ${response.message}`); + ctx.output('success', response.success); + ctx.output('message', response.message); + ctx.output('data', '{}'); + throw new Error(`Unable to create backend, ${response.message}`); + } + + ctx.logger.info('Backend created successfully'); + ctx.output('success', response.success); + ctx.output('message', response.message); + ctx.output('data', JSON.stringify(response.data)); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts new file mode 100644 index 0000000..ef26512 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts @@ -0,0 +1 @@ +export * from "../backend" diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts new file mode 100644 index 0000000..917da6f --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Create a workspace in Kusion', + example: yaml.stringify({ + steps: [ + { + id: 'create-workspace', + action: 'kusion:workspace:create', + name: 'Create Workspace', + input: { + name: 'my-workspace', + description: 'This is my workspace', + labels: ['label1', 'label2'], + owners: ['owner1', 'owner2'], + backendID: 1, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts new file mode 100644 index 0000000..ca94819 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts @@ -0,0 +1,108 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createCreateWorkspaceAction } from './createWorkspace'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ConfigReader } from '@backstage/config'; + +jest.mock('../../api', () => ({ + createKusionApi: jest.fn(), +})); + +describe('createCreateWorkspaceAction', () => { + const config = new ConfigReader({}); + const action = createCreateWorkspaceAction({ config }); + + it('should create a workspace successfully', async () => { + const mockContext = createMockActionContext({ + input: { + name: 'test-workspace', + description: 'A test workspace', + labels: ['test', 'workspace'], + owners: ['owner1'], + backendID: 1, + }, + }); + + const mockKusionApi = { + post: jest.fn().mockResolvedValue({ + success: true, + message: 'Workspace created successfully', + data: { id: 'workspace-id' }, + }), + }; + + require('../../api').createKusionApi.mockReturnValue(mockKusionApi); + + await action.handler(mockContext); + + expect(mockKusionApi.post).toHaveBeenCalledWith('workspaces', { + name: 'test-workspace', + description: 'A test workspace', + labels: ['test', 'workspace'], + owners: ['owner1'], + backendID: 1, + }); + expect(mockContext.output).toHaveBeenCalledWith('success', true); + expect(mockContext.output).toHaveBeenCalledWith( + 'message', + 'Workspace created successfully', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'data', + JSON.stringify({ id: 'workspace-id' }), + ); + }); + + it('should handle failure to create a workspace', async () => { + const mockContext = createMockActionContext({ + input: { + name: 'test-workspace', + description: 'A test workspace', + labels: ['test', 'workspace'], + owners: ['owner1'], + backendID: 1, + }, + }); + + const mockKusionApi = { + post: jest.fn().mockResolvedValue({ + success: false, + message: 'Failed to create workspace', + }), + }; + + require('../../api').createKusionApi.mockReturnValue(mockKusionApi); + + await expect(action.handler(mockContext)).rejects.toThrow( + 'Unable to create workspace, Failed to create workspace', + ); + + expect(mockKusionApi.post).toHaveBeenCalledWith('workspaces', { + name: 'test-workspace', + description: 'A test workspace', + labels: ['test', 'workspace'], + owners: ['owner1'], + backendID: 1, + }); + expect(mockContext.output).toHaveBeenCalledWith('success', false); + expect(mockContext.output).toHaveBeenCalledWith( + 'message', + 'Failed to create workspace', + ); + expect(mockContext.output).toHaveBeenCalledWith('data', '{}'); + }); +}); diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts new file mode 100644 index 0000000..e21bcc3 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts @@ -0,0 +1,121 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { Config } from '@backstage/config'; +import { createKusionApi } from '../../api'; +import { examples } from './createWorkspace.example'; + +/** + * Creates an `kusion:workspace:create` Scaffolder action. + + * @public + */ +export function createCreateWorkspaceAction(options: { config: Config }) { + const { config } = options; + return createTemplateAction<{ + name: string; + description: string; + labels: string[]; + owners: string[]; + backendID: number; + }>({ + id: 'kusion:workspace:create', + examples, + schema: { + input: { + type: 'object', + required: ['name', 'owners', 'backendID'], + properties: { + name: { + title: 'Workspace Name', + type: 'string', + }, + description: { + title: 'Workspace Description', + type: 'string', + }, + labels: { + title: 'Workspace Labels', + type: 'array', + items: { + type: 'string', + }, + }, + owners: { + title: 'Workspace Owners', + type: 'array', + items: { + type: 'string', + }, + }, + backendID: { + title: 'Backend ID', + type: 'number', + }, + }, + }, + output: { + type: 'object', + properties: { + success: { + title: 'Success', + type: 'boolean', + }, + message: { + title: 'Message', + type: 'string', + }, + data: { + title: 'Data', + type: 'object', + }, + }, + }, + }, + async handler(ctx) { + const { name, description, labels, owners, backendID } = ctx.input; + const kusionApi = createKusionApi({ configApi: config }); + const requestBody = { + name, + description, + labels, + owners, + backendID, + }; + + ctx.logger.info( + 'Creating workspace with the following request body: ', + requestBody, + ); + + const response = await kusionApi.post('workspaces', requestBody); + + if (!response.success || response.data === undefined) { + ctx.logger.error(` + Unable to create workspace, ${response.message}`); + ctx.output('success', response.success); + ctx.output('message', response.message); + ctx.output('data', '{}'); + throw new Error(`Unable to create workspace, ${response.message}`); + } + ctx.logger.info('Workspace created successfully'); + ctx.output('success', response.success); + ctx.output('message', response.message); + ctx.output('data', JSON.stringify(response.data)); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts new file mode 100644 index 0000000..517561a --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts @@ -0,0 +1 @@ +export * from "../workspace" diff --git a/plugins/scaffolder-backend-module-kusion/src/api/index.ts b/plugins/scaffolder-backend-module-kusion/src/api/index.ts new file mode 100644 index 0000000..fad7c3d --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/api/index.ts @@ -0,0 +1,122 @@ +/* + * Copyright 2024 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; +import fetch, { RequestInit } from 'node-fetch'; + +type Options = { + configApi: Config; +}; + +export const createKusionApi = (option: Options) => { + const { configApi } = option; + const getApiUrl = async ( + { serviceName }: { serviceName?: string }, + { params }: { params?: string } = {}, + ): Promise => { + const kusionBaseUrl = configApi.getOptionalString('kusion.baseUrl'); + if (!kusionBaseUrl) { + throw new Error('backstage config kusion.baseUrl is required'); + } + + const proxyPath = + configApi.getOptionalString('kusion.proxyPath') || DEFAULT_PROXY_PATH; + + let url = `${kusionBaseUrl}${proxyPath}`; + + if (serviceName) { + url += `/${serviceName}`; + } + if (params) { + url += `/${params}`; + } + + return url.replace(/\/$/, ''); + }; + + const getKusionToken = async () => { + const token = configApi.getOptionalString('kusion.token'); + if (!Boolean(token) || token?.length === 0) { + throw new Error('backstage config kusion.token is required'); + } + return token; + }; + + const post = async ( + serviceName: string, + body: any, + params?: string, + ): Promise => { + try { + const url = await getApiUrl({ serviceName }, { params }); + const requestOption: RequestInit = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${await getKusionToken()}`, + }, + body: JSON.stringify(body), + }; + + const response = await fetch(url, requestOption); + + if (!response.ok) { + throw new Error( + `Failed to create ${serviceName}: ${response.statusText}`, + ); + } + + return (await response.json()) as KusionResponse; + } catch (error) { + throw new Error(`Error in post request to ${serviceName}: ${error}`); + } + }; + + const put = async ( + serviceName: string, + body: any, + params?: string, + ): Promise => { + try { + const url = await getApiUrl({ serviceName }, { params }); + const requestOption: RequestInit = { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${await getKusionToken()}`, + }, + body: JSON.stringify(body), + }; + + const response = await fetch(url, requestOption); + + if (!response.ok) { + throw new Error( + `Failed to update ${serviceName}: ${response.statusText}`, + ); + } + + return (await response.json()) as KusionResponse; + } catch (error) { + throw new Error(`Error in put request to ${serviceName}: ${error}`); + } + }; + + return { + post, + put, + }; +}; diff --git a/plugins/scaffolder-backend-module-kusion/src/api/types.ts b/plugins/scaffolder-backend-module-kusion/src/api/types.ts new file mode 100644 index 0000000..ee0812f --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/api/types.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const DEFAULT_PROXY_PATH = '/api/v1'; + +type KusionResponse = { + success: boolean; + message: string; + data?: any; + traceID?: string; + startTime?: Date; + endTime?: Date; + costTime?: number; +}; diff --git a/plugins/scaffolder-backend-module-kusion/src/index.ts b/plugins/scaffolder-backend-module-kusion/src/index.ts new file mode 100644 index 0000000..737daac --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The kusion module for scaffolder backend that lets you interact with Kusion Server. + * + * @packageDocumentation + */ + +export { kusionModule as default } from './module'; diff --git a/plugins/scaffolder-backend-module-kusion/src/module.ts b/plugins/scaffolder-backend-module-kusion/src/module.ts new file mode 100644 index 0000000..79ed6b0 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/module.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; +import { createCreateWorkspaceAction } from './actions/workspace/createWorkspace'; +import { createCreateBackendAction } from './actions/backend/createBackend'; + +/** + * The Kusion Module for the Scaffolder Backend + * @public + */ +export const kusionModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'kusion', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + config: coreServices.rootConfig, + }, + async init({ scaffolder, config }) { + scaffolder.addActions( + createCreateWorkspaceAction({ + config, + }), + ); + scaffolder.addActions( + createCreateBackendAction({ + config, + }), + ); + }, + }); + }, +}); diff --git a/yarn.lock b/yarn.lock index 2c17b3d..ec6b4fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3037,6 +3037,43 @@ __metadata: languageName: node linkType: hard +"@backstage/backend-test-utils@npm:^1.1.0": + version: 1.1.0 + resolution: "@backstage/backend-test-utils@npm:1.1.0" + dependencies: + "@backstage/backend-app-api": "npm:^1.0.2" + "@backstage/backend-defaults": "npm:^0.5.3" + "@backstage/backend-plugin-api": "npm:^1.0.2" + "@backstage/config": "npm:^1.3.0" + "@backstage/errors": "npm:^1.2.5" + "@backstage/plugin-auth-node": "npm:^0.5.4" + "@backstage/plugin-events-node": "npm:^0.4.5" + "@backstage/types": "npm:^1.2.0" + "@keyv/memcache": "npm:^1.3.5" + "@keyv/redis": "npm:^2.5.3" + "@types/express": "npm:^4.17.6" + "@types/express-serve-static-core": "npm:^4.17.5" + "@types/keyv": "npm:^4.2.0" + "@types/qs": "npm:^6.9.6" + better-sqlite3: "npm:^11.0.0" + cookie: "npm:^0.7.0" + express: "npm:^4.17.1" + fs-extra: "npm:^11.0.0" + keyv: "npm:^4.5.2" + knex: "npm:^3.0.0" + mysql2: "npm:^3.0.0" + pg: "npm:^8.11.3" + pg-connection-string: "npm:^2.3.0" + testcontainers: "npm:^10.0.0" + textextensions: "npm:^5.16.0" + uuid: "npm:^11.0.0" + yn: "npm:^4.0.0" + peerDependencies: + "@types/jest": "*" + checksum: 10c0/e7046ef659a4d8301ddb8c2b4b39eff07cdd5cb0c4b89af0d6ab5f6987d6d072b8d851eaff0b962d97111a23c1a09da30083616242fe0c5fdfabae7c61064be5 + languageName: node + linkType: hard + "@backstage/catalog-client@npm:^1.8.0": version: 1.8.0 resolution: "@backstage/catalog-client@npm:1.8.0" @@ -4798,7 +4835,27 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-scaffolder-node@npm:^0.6.1": +"@backstage/plugin-scaffolder-node-test-utils@npm:^0.1.15": + version: 0.1.16 + resolution: "@backstage/plugin-scaffolder-node-test-utils@npm:0.1.16" + dependencies: + "@backstage/backend-common": "npm:^0.25.0" + "@backstage/backend-test-utils": "npm:^1.1.0" + "@backstage/plugin-scaffolder-node": "npm:^0.6.1" + "@backstage/types": "npm:^1.2.0" + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/00e51b91b2cc877186fdfddc44a2e5ce6dac0b90bf29e2df9c833dde39de60d067bc43b73a0379d3ac7f9bab5df668e62c40740ac06bdd86c82af76506a20a4d + languageName: node + linkType: hard + +"@backstage/plugin-scaffolder-node@npm:^0.6.0, @backstage/plugin-scaffolder-node@npm:^0.6.1": version: 0.6.1 resolution: "@backstage/plugin-scaffolder-node@npm:0.6.1" dependencies: @@ -6373,6 +6430,13 @@ __metadata: languageName: node linkType: hard +"@fastify/busboy@npm:^2.0.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 10c0/6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.6.0": version: 1.6.8 resolution: "@floating-ui/core@npm:1.6.8" @@ -7473,6 +7537,15 @@ __metadata: languageName: node linkType: hard +"@keyv/serialize@npm:*": + version: 1.0.1 + resolution: "@keyv/serialize@npm:1.0.1" + dependencies: + buffer: "npm:^6.0.3" + checksum: 10c0/948fadc632f6050b67cb8ea664192a98d7743015e1b449d383addacbce371414b9cd7129b33ab36d5d81b558744ab0a56c2753b287e7c4f5b2c46401c486cbd0 + languageName: node + linkType: hard + "@kubernetes-models/apimachinery@npm:^2.0.0, @kubernetes-models/apimachinery@npm:^2.0.1": version: 2.0.1 resolution: "@kubernetes-models/apimachinery@npm:2.0.1" @@ -7566,6 +7639,20 @@ __metadata: languageName: node linkType: hard +"@kusion/backstage-plugin-scaffolder-backend-module-kusion@npm:^0.1.0, @kusion/backstage-plugin-scaffolder-backend-module-kusion@workspace:plugins/scaffolder-backend-module-kusion": + version: 0.0.0-use.local + resolution: "@kusion/backstage-plugin-scaffolder-backend-module-kusion@workspace:plugins/scaffolder-backend-module-kusion" + dependencies: + "@backstage/backend-plugin-api": "npm:^1.0.2" + "@backstage/cli": "npm:^0.29.0" + "@backstage/config": "npm:^1.3.0" + "@backstage/plugin-scaffolder-node": "npm:^0.6.0" + "@backstage/plugin-scaffolder-node-test-utils": "npm:^0.1.15" + node-fetch: "npm:^2.7.0" + yaml: "npm:^2.6.1" + languageName: unknown + linkType: soft + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.5 resolution: "@leichtgewicht/ip-codec@npm:2.0.5" @@ -12196,7 +12283,7 @@ __metadata: languageName: node linkType: hard -"@types/dockerode@npm:^3.3.0": +"@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.29": version: 3.3.32 resolution: "@types/dockerode@npm:3.3.32" dependencies: @@ -12460,6 +12547,15 @@ __metadata: languageName: node linkType: hard +"@types/keyv@npm:^4.2.0": + version: 4.2.0 + resolution: "@types/keyv@npm:4.2.0" + dependencies: + keyv: "npm:*" + checksum: 10c0/ad626918f1843035b732b582263890a67d73dc3ff80da97e51fbe0ae3f2fe7a1ada2eef1bd89605c5fb739444110e696c0e0703d9b49a842a2f924c6e9164faa + languageName: node + linkType: hard + "@types/long@npm:^4.0.0": version: 4.0.2 resolution: "@types/long@npm:4.0.2" @@ -12628,7 +12724,7 @@ __metadata: languageName: node linkType: hard -"@types/qs@npm:*, @types/qs@npm:^6.9.11": +"@types/qs@npm:*, @types/qs@npm:^6.9.11, @types/qs@npm:^6.9.6": version: 6.9.17 resolution: "@types/qs@npm:6.9.17" checksum: 10c0/a183fa0b3464267f8f421e2d66d960815080e8aab12b9aadab60479ba84183b1cdba8f4eff3c06f76675a8e42fe6a3b1313ea76c74f2885c3e25d32499c17d1b @@ -12781,6 +12877,15 @@ __metadata: languageName: node linkType: hard +"@types/ssh2-streams@npm:*": + version: 0.1.12 + resolution: "@types/ssh2-streams@npm:0.1.12" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/6c860066e76391c937723b9f8c3953208737be5adf33b5584d7817ec90913094f2ca578e1d47717182f1d62cb5ca8e83fdec0241d73bf064221e3a2b2d132f0e + languageName: node + linkType: hard + "@types/ssh2@npm:*": version: 1.15.1 resolution: "@types/ssh2@npm:1.15.1" @@ -12790,6 +12895,16 @@ __metadata: languageName: node linkType: hard +"@types/ssh2@npm:^0.5.48": + version: 0.5.52 + resolution: "@types/ssh2@npm:0.5.52" + dependencies: + "@types/node": "npm:*" + "@types/ssh2-streams": "npm:*" + checksum: 10c0/95c52fd3438dedae6a59ca87b6558cb36568db6b9144c6c8a28c168739e04c51e27c02908aae14950b7b5020e1c40fea039b1203ae2734c356a40a050fd51c84 + languageName: node + linkType: hard + "@types/stack-utils@npm:^2.0.0": version: 2.0.3 resolution: "@types/stack-utils@npm:2.0.3" @@ -13820,7 +13935,7 @@ __metadata: languageName: node linkType: hard -"archiver@npm:^7.0.0": +"archiver@npm:^7.0.0, archiver@npm:^7.0.1": version: 7.0.1 resolution: "archiver@npm:7.0.1" dependencies: @@ -14439,6 +14554,7 @@ __metadata: "@backstage/plugin-search-backend-module-techdocs": "npm:^0.3.2" "@backstage/plugin-search-backend-node": "npm:^1.3.5" "@backstage/plugin-techdocs-backend": "npm:^1.11.2" + "@kusion/backstage-plugin-scaffolder-backend-module-kusion": "npm:^0.1.0" app: "link:../app" better-sqlite3: "npm:^9.0.0" node-gyp: "npm:^10.0.0" @@ -14467,13 +14583,49 @@ __metadata: languageName: node linkType: hard -"bare-events@npm:^2.2.0": +"bare-events@npm:^2.0.0, bare-events@npm:^2.2.0": version: 2.5.0 resolution: "bare-events@npm:2.5.0" checksum: 10c0/afbeec4e8be4d93fb4a3be65c3b4a891a2205aae30b5a38fafd42976cc76cf30dad348963fe330a0d70186e15dc507c11af42c89af5dddab2a54e5aff02e2896 languageName: node linkType: hard +"bare-fs@npm:^2.1.1": + version: 2.3.5 + resolution: "bare-fs@npm:2.3.5" + dependencies: + bare-events: "npm:^2.0.0" + bare-path: "npm:^2.0.0" + bare-stream: "npm:^2.0.0" + checksum: 10c0/ff18cc9be7c557c38e0342681ba3672ae4b01e5696b567d4035e5995255dc6bc7d4df88ed210fa4d3eb940eb29512e924ebb42814c87fc59a2bee8cf83b7c2f9 + languageName: node + linkType: hard + +"bare-os@npm:^2.1.0": + version: 2.4.4 + resolution: "bare-os@npm:2.4.4" + checksum: 10c0/e7d1a7b2100c05da8d25b60d0d48cf850c6f57064577a3f2f51cf18d417fbcfd6967ed2d8314320914ed69e0f2ebcf54eb1b36092dd172d8e8f969cf8cccf041 + languageName: node + linkType: hard + +"bare-path@npm:^2.0.0, bare-path@npm:^2.1.0": + version: 2.1.3 + resolution: "bare-path@npm:2.1.3" + dependencies: + bare-os: "npm:^2.1.0" + checksum: 10c0/35587e177fc8fa5b13fb90bac8779b5ce49c99016d221ddaefe2232d02bd4295d79b941e14ae19fda75ec42a6fe5fb66c07d83ae7ec11462178e66b7be65ca74 + languageName: node + linkType: hard + +"bare-stream@npm:^2.0.0": + version: 2.4.2 + resolution: "bare-stream@npm:2.4.2" + dependencies: + streamx: "npm:^2.20.0" + checksum: 10c0/5e64d96dc32d901c317399f14fd1057882b2bd68d1f8ab54710f0e640b0d1f3a4bf4f9c238bb4c81051ef4b687cf2223e5e05dda9f6ce08bc0cc2ac98f3b52e0 + languageName: node + linkType: hard + "base64-arraybuffer@npm:^0.1.5": version: 0.1.5 resolution: "base64-arraybuffer@npm:0.1.5" @@ -16669,7 +16821,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6": version: 4.3.7 resolution: "debug@npm:4.3.7" dependencies: @@ -17081,6 +17233,27 @@ __metadata: languageName: node linkType: hard +"docker-compose@npm:^0.24.8": + version: 0.24.8 + resolution: "docker-compose@npm:0.24.8" + dependencies: + yaml: "npm:^2.2.2" + checksum: 10c0/1494389e554fed8aabf9fef24210a641cd2442028b1462d7f68186919f5e75045f7bfb4ccaf47c94ed879dcb63e4d82885c389399f531550c4b244920740b2b3 + languageName: node + linkType: hard + +"docker-modem@npm:^3.0.0": + version: 3.0.8 + resolution: "docker-modem@npm:3.0.8" + dependencies: + debug: "npm:^4.1.1" + readable-stream: "npm:^3.5.0" + split-ca: "npm:^1.0.1" + ssh2: "npm:^1.11.0" + checksum: 10c0/5c00592297fabd78454621fe765a5ef0daea4bbb6692e239ad65b111f4da9d750178f448f8efcaf84f9f999598eb735bc14ad6bf5f0a2dcf9c2d453d5b683540 + languageName: node + linkType: hard + "docker-modem@npm:^5.0.3": version: 5.0.3 resolution: "docker-modem@npm:5.0.3" @@ -17093,6 +17266,17 @@ __metadata: languageName: node linkType: hard +"dockerode@npm:^3.3.5": + version: 3.3.5 + resolution: "dockerode@npm:3.3.5" + dependencies: + "@balena/dockerignore": "npm:^1.0.2" + docker-modem: "npm:^3.0.0" + tar-fs: "npm:~2.0.1" + checksum: 10c0/c45fa8ed3ad76f13fe7799d539a60fe466f8e34bea06b30d75be9e08bc00536cc9ff2d54e38fbb3b2a8a382bf9d4459a27741e6454ce7d0cda5cd35c51224c73 + languageName: node + linkType: hard + "dockerode@npm:^4.0.0": version: 4.0.2 resolution: "dockerode@npm:4.0.2" @@ -22601,6 +22785,15 @@ __metadata: languageName: node linkType: hard +"keyv@npm:*": + version: 5.2.1 + resolution: "keyv@npm:5.2.1" + dependencies: + "@keyv/serialize": "npm:*" + checksum: 10c0/95c986a4785bd169c1545c8263662c3e898dc446c4acd9640598ca454075b9dea73559909dded6b23df0a247031d101df84a757bb6db08bbfe06499896e494fc + languageName: node + linkType: hard + "keyv@npm:^4.0.0, keyv@npm:^4.5.2, keyv@npm:^4.5.3": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -24339,7 +24532,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^1.0.3": +"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -26829,6 +27022,26 @@ __metadata: languageName: node linkType: hard +"proper-lockfile@npm:^4.1.2": + version: 4.1.2 + resolution: "proper-lockfile@npm:4.1.2" + dependencies: + graceful-fs: "npm:^4.2.4" + retry: "npm:^0.12.0" + signal-exit: "npm:^3.0.2" + checksum: 10c0/2f265dbad15897a43110a02dae55105c04d356ec4ed560723dcb9f0d34bc4fb2f13f79bb930e7561be10278e2314db5aca2527d5d3dcbbdee5e6b331d1571f6d + languageName: node + linkType: hard + +"properties-reader@npm:^2.3.0": + version: 2.3.0 + resolution: "properties-reader@npm:2.3.0" + dependencies: + mkdirp: "npm:^1.0.4" + checksum: 10c0/f665057e3a9076c643ba1198afcc71703eda227a59913252f7ff9467ece8d29c0cf8bf14bf1abcaef71570840c32a4e257e6c39b7550451bbff1a777efcf5667 + languageName: node + linkType: hard + "property-expr@npm:^2.0.5": version: 2.0.6 resolution: "property-expr@npm:2.0.6" @@ -29300,7 +29513,17 @@ __metadata: languageName: node linkType: hard -"ssh2@npm:^1.15.0": +"ssh-remote-port-forward@npm:^1.0.4": + version: 1.0.4 + resolution: "ssh-remote-port-forward@npm:1.0.4" + dependencies: + "@types/ssh2": "npm:^0.5.48" + ssh2: "npm:^1.4.0" + checksum: 10c0/33a441af12817577ea30d089b03c19f980d2fb2370933123a35026dc6be40f2dfce067e4dfc173e23d745464537ff647aa1bb7469be5571cc21f7cdb25181c09 + languageName: node + linkType: hard + +"ssh2@npm:^1.11.0, ssh2@npm:^1.15.0, ssh2@npm:^1.4.0": version: 1.16.0 resolution: "ssh2@npm:1.16.0" dependencies: @@ -29542,6 +29765,21 @@ __metadata: languageName: node linkType: hard +"streamx@npm:^2.20.0": + version: 2.21.0 + resolution: "streamx@npm:2.21.0" + dependencies: + bare-events: "npm:^2.2.0" + fast-fifo: "npm:^1.3.2" + queue-tick: "npm:^1.0.1" + text-decoder: "npm:^1.1.0" + dependenciesMeta: + bare-events: + optional: true + checksum: 10c0/4583d1585c0b5876bc623e4c31c00358d914277b649928573002577019cb41cb8e62a7b39559aa118ff8424c1d98b03eb163536f838fa21d006f274042498180 + languageName: node + linkType: hard + "strict-uri-encode@npm:^2.0.0": version: 2.0.0 resolution: "strict-uri-encode@npm:2.0.0" @@ -30062,6 +30300,23 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:^3.0.6": + version: 3.0.6 + resolution: "tar-fs@npm:3.0.6" + dependencies: + bare-fs: "npm:^2.1.1" + bare-path: "npm:^2.1.0" + pump: "npm:^3.0.0" + tar-stream: "npm:^3.1.5" + dependenciesMeta: + bare-fs: + optional: true + bare-path: + optional: true + checksum: 10c0/207b7c0f193495668bd9dbad09a0108ce4ffcfec5bce2133f90988cdda5c81fad83c99f963d01e47b565196594f7a17dbd063ae55b97b36268fcc843975278ee + languageName: node + linkType: hard + "tar-fs@npm:~2.0.1": version: 2.0.1 resolution: "tar-fs@npm:2.0.1" @@ -30087,7 +30342,7 @@ __metadata: languageName: node linkType: hard -"tar-stream@npm:^3.0.0": +"tar-stream@npm:^3.0.0, tar-stream@npm:^3.1.5": version: 3.1.7 resolution: "tar-stream@npm:3.1.7" dependencies: @@ -30209,6 +30464,29 @@ __metadata: languageName: node linkType: hard +"testcontainers@npm:^10.0.0": + version: 10.16.0 + resolution: "testcontainers@npm:10.16.0" + dependencies: + "@balena/dockerignore": "npm:^1.0.2" + "@types/dockerode": "npm:^3.3.29" + archiver: "npm:^7.0.1" + async-lock: "npm:^1.4.1" + byline: "npm:^5.0.0" + debug: "npm:^4.3.5" + docker-compose: "npm:^0.24.8" + dockerode: "npm:^3.3.5" + get-port: "npm:^5.1.1" + proper-lockfile: "npm:^4.1.2" + properties-reader: "npm:^2.3.0" + ssh-remote-port-forward: "npm:^1.0.4" + tar-fs: "npm:^3.0.6" + tmp: "npm:^0.2.3" + undici: "npm:^5.28.4" + checksum: 10c0/17f748927d484e63718e2a745c776d54a893eba08c4fa20b84e5056f2ef45f585e39c7a1ffebea37ec63ae96e71dd50de5a611d4d313f63380bacca52b12737a + languageName: node + linkType: hard + "text-decoder@npm:^1.1.0": version: 1.2.1 resolution: "text-decoder@npm:1.2.1" @@ -30230,6 +30508,13 @@ __metadata: languageName: node linkType: hard +"textextensions@npm:^5.16.0": + version: 5.16.0 + resolution: "textextensions@npm:5.16.0" + checksum: 10c0/bc90dc60272c3ffb76eeff86dc1decab9535ba8da6a00efe2a005763d0305cb445db9ac35970538c59b89bf41820c3d19394f46c6b7346d520b9ae16fe47be80 + languageName: node + linkType: hard + "thenify-all@npm:^1.0.0": version: 1.6.0 resolution: "thenify-all@npm:1.6.0" @@ -30370,7 +30655,7 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.0": +"tmp@npm:^0.2.0, tmp@npm:^0.2.3": version: 0.2.3 resolution: "tmp@npm:0.2.3" checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125 @@ -31041,6 +31326,15 @@ __metadata: languageName: node linkType: hard +"undici@npm:^5.28.4": + version: 5.28.4 + resolution: "undici@npm:5.28.4" + dependencies: + "@fastify/busboy": "npm:^2.0.0" + checksum: 10c0/08d0f2596553aa0a54ca6e8e9c7f45aef7d042c60918564e3a142d449eda165a80196f6ef19ea2ef2e6446959e293095d8e40af1236f0d67223b06afac5ecad7 + languageName: node + linkType: hard + "unicode-canonical-property-names-ecmascript@npm:^2.0.0": version: 2.0.1 resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" @@ -32287,7 +32581,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.0.0, yaml@npm:^2.2.1": +"yaml@npm:^2.0.0, yaml@npm:^2.2.1, yaml@npm:^2.2.2, yaml@npm:^2.6.1": version: 2.6.1 resolution: "yaml@npm:2.6.1" bin: From 1fbeb2e04e669acd4a8a03b0a95e9a39b705ddf9 Mon Sep 17 00:00:00 2001 From: hoangndst Date: Wed, 15 Jan 2025 05:40:16 +0700 Subject: [PATCH 2/3] feat: add some action --- app-config.yaml | 4 + .../README.md | 2 - .../package.json | 11 +- .../src/actions/backend/createBackend.test.ts | 124 ---------------- .../src/actions/backend/createBackend.ts | 38 ++--- .../backend/deleteBackend.example.ts} | 29 ++-- .../src/actions/backend/deleteBackend.ts | 96 +++++++++++++ .../src/actions/backend/index.ts | 3 +- .../createOrganization.example.ts | 39 +++++ .../organization/createOrganization.ts | 123 ++++++++++++++++ .../src/actions/organization/index.ts | 1 + .../actions/project/createProject.example.ts | 27 ++++ .../src/actions/project/createProject.ts | 136 ++++++++++++++++++ .../src/actions/project/index.ts | 1 + .../actions/workspace/createWorkspace.test.ts | 108 -------------- .../src/actions/workspace/createWorkspace.ts | 44 +++--- .../workspace/deleteWorkspace.example.ts | 36 +++++ .../src/actions/workspace/deleteWorkspace.ts | 98 +++++++++++++ .../src/actions/workspace/index.ts | 3 +- .../src/api/index.ts | 93 ++---------- .../src/module.ts | 28 +++- yarn.lock | 17 +++ 22 files changed, 694 insertions(+), 367 deletions(-) delete mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts rename plugins/scaffolder-backend-module-kusion/src/{api/types.ts => actions/backend/deleteBackend.example.ts} (57%) create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts delete mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts diff --git a/app-config.yaml b/app-config.yaml index ca52ec5..f6c0919 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -111,3 +111,7 @@ kubernetes: permission: # setting this to `false` will disable permissions enabled: true + +# kusion +kusion: + baseUrl: ${KUSION_BASE_URL} diff --git a/plugins/scaffolder-backend-module-kusion/README.md b/plugins/scaffolder-backend-module-kusion/README.md index 4ce3061..01c0c3b 100644 --- a/plugins/scaffolder-backend-module-kusion/README.md +++ b/plugins/scaffolder-backend-module-kusion/README.md @@ -10,8 +10,6 @@ You need to add the following to your `app-config.yaml`. For example: backend: kusion: baseUrl: 'http://localhost:3000' - proxyPath: '/api/v1' # Optional - Default is '/api/v1' - token: 'your-token' ``` ### From your Backstage root directory diff --git a/plugins/scaffolder-backend-module-kusion/package.json b/plugins/scaffolder-backend-module-kusion/package.json index 7ef0436..5db4fbc 100644 --- a/plugins/scaffolder-backend-module-kusion/package.json +++ b/plugins/scaffolder-backend-module-kusion/package.json @@ -4,6 +4,10 @@ "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", + "author": { + "email": "hoangndst@gmail.com", + "name": "hoangndst" + }, "private": true, "publishConfig": { "access": "public", @@ -24,11 +28,16 @@ "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack" }, + "repository": { + "type": "git", + "url": "https://github.com/KusionStack/kusion-backstage-plugin", + "directory": "plugins/scaffolder-backend-module-kusion" + }, "dependencies": { "@backstage/backend-plugin-api": "^1.0.2", "@backstage/config": "^1.3.0", "@backstage/plugin-scaffolder-node": "^0.6.0", - "node-fetch": "^2.7.0", + "@kusionstack/kusion-api-client-sdk": "^1.1.3", "yaml": "^2.6.1" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts deleted file mode 100644 index 119d62a..0000000 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createCreateBackendAction } from './createBackend'; -import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; -import { ConfigReader } from '@backstage/config'; - -jest.mock('../../api', () => ({ - createKusionApi: jest.fn(), -})); - -describe('createCreateBackendAction', () => { - const config = new ConfigReader({}); - const action = createCreateBackendAction({ config }); - - it('should create a backend successfully', async () => { - const mockContext = createMockActionContext({ - input: { - name: 'test-backend', - description: 'A test backend', - backendConfig: { - type: 'exampleType', - configs: { - key1: 'value1', - key2: 'value2', - }, - }, - }, - }); - - const mockKusionApi = { - post: jest.fn().mockResolvedValue({ - success: true, - message: 'Backend created successfully', - data: { id: 'backend-id' }, - }), - }; - - require('../../api').createKusionApi.mockReturnValue(mockKusionApi); - - await action.handler(mockContext); - - expect(mockKusionApi.post).toHaveBeenCalledWith('backends', { - name: 'test-backend', - description: 'A test backend', - backendConfig: { - type: 'exampleType', - configs: { - key1: 'value1', - key2: 'value2', - }, - }, - }); - expect(mockContext.output).toHaveBeenCalledWith('success', true); - expect(mockContext.output).toHaveBeenCalledWith( - 'message', - 'Backend created successfully', - ); - expect(mockContext.output).toHaveBeenCalledWith( - 'data', - JSON.stringify({ id: 'backend-id' }), - ); - }); - - it('should handle failure to create a backend', async () => { - const mockContext = createMockActionContext({ - input: { - name: 'test-backend', - description: 'A test backend', - backendConfig: { - type: 'exampleType', - configs: { - key1: 'value1', - key2: 'value2', - }, - }, - }, - }); - - const mockKusionApi = { - post: jest.fn().mockResolvedValue({ - success: false, - message: 'Failed to create backend', - }), - }; - - require('../../api').createKusionApi.mockReturnValue(mockKusionApi); - - await expect(action.handler(mockContext)).rejects.toThrow( - 'Unable to create backend, Failed to create backend', - ); - - expect(mockKusionApi.post).toHaveBeenCalledWith('backends', { - name: 'test-backend', - description: 'A test backend', - backendConfig: { - type: 'exampleType', - configs: { - key1: 'value1', - key2: 'value2', - }, - }, - }); - expect(mockContext.output).toHaveBeenCalledWith('success', false); - expect(mockContext.output).toHaveBeenCalledWith( - 'message', - 'Failed to create backend', - ); - expect(mockContext.output).toHaveBeenCalledWith('data', '{}'); - }); -}); diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts index d69e2a1..7fb8b3c 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts @@ -1,6 +1,10 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; -import { createKusionApi } from '../../api'; +import { configKusionApi } from '../../api'; +import { + BackendService, + CreateBackendData, +} from '@kusionstack/kusion-api-client-sdk'; import { examples } from './createBackend.example'; /** @@ -73,11 +77,13 @@ export function createCreateBackendAction(options: { config: Config }) { }, async handler(ctx) { const { name, description, backendConfig } = ctx.input; - const kusionApi = createKusionApi({ configApi: config }); - const requestBody = { - name, - description, - backendConfig, + configKusionApi({ configApi: config }); + const requestBody: CreateBackendData = { + body: { + name: name, + description: description, + backendConfig: backendConfig, + }, }; ctx.logger.info( @@ -85,21 +91,21 @@ export function createCreateBackendAction(options: { config: Config }) { requestBody, ); - const response = await kusionApi.post('backends', requestBody); + const response = await BackendService.createBackend(requestBody); - if (!response.success || response.data === undefined) { + if (!response.data?.success) { ctx.logger.error(` - Unable to create backend, ${response.message}`); - ctx.output('success', response.success); - ctx.output('message', response.message); - ctx.output('data', '{}'); - throw new Error(`Unable to create backend, ${response.message}`); + Unable to create backend, ${response.data?.message}`); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); + throw new Error(`Unable to create backend, ${response.data?.message}`); } ctx.logger.info('Backend created successfully'); - ctx.output('success', response.success); - ctx.output('message', response.message); - ctx.output('data', JSON.stringify(response.data)); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); }, }); } diff --git a/plugins/scaffolder-backend-module-kusion/src/api/types.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.example.ts similarity index 57% rename from plugins/scaffolder-backend-module-kusion/src/api/types.ts rename to plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.example.ts index ee0812f..586bcd8 100644 --- a/plugins/scaffolder-backend-module-kusion/src/api/types.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.example.ts @@ -14,14 +14,23 @@ * limitations under the License. */ -const DEFAULT_PROXY_PATH = '/api/v1'; +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; -type KusionResponse = { - success: boolean; - message: string; - data?: any; - traceID?: string; - startTime?: Date; - endTime?: Date; - costTime?: number; -}; +export const examples: TemplateExample[] = [ + { + description: 'Delete a backend in Kusion', + example: yaml.stringify({ + steps: [ + { + id: 'delete-backend', + action: 'kusion:backend:delete', + name: 'Delete backend', + input: { + id: '1', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts new file mode 100644 index 0000000..a3e12aa --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts @@ -0,0 +1,96 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { Config } from '@backstage/config'; +import { configKusionApi } from '../../api'; +import { + BackendService, + DeleteBackendData, +} from '@kusionstack/kusion-api-client-sdk'; +import { examples } from './deleteBackend.example'; + +/** + * Creates a `kusion:backend:delete` Scaffolder action. + * + * @public + */ +export function createDeleteBackendAction(options: { config: Config }) { + const { config } = options; + return createTemplateAction<{ + id: string; + }>({ + id: 'kusion:backend:delete', + examples, + schema: { + input: { + type: 'object', + required: ['id'], + properties: { + id: { + title: 'Backend ID', + type: 'string', + }, + }, + }, + output: { + type: 'object', + properties: { + success: { + title: 'Success', + type: 'boolean', + }, + message: { + title: 'Message', + type: 'string', + }, + data: { + title: 'Data', + type: 'object', + }, + }, + }, + }, + async handler(ctx) { + const { id } = ctx.input; + configKusionApi({ configApi: config }); + + ctx.logger.info('Deleting backend with ID: %s', id); + + const request: DeleteBackendData = { + path: { + backendID: Number(id), + }, + }; + + const response = await BackendService.deleteBackend(request); + + if (!response.data?.success) { + ctx.logger.error(` + Unable to delete backend, ${response.data?.message}`); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); + throw new Error(`Unable to delete backend, ${response.data?.message}`); + } + + ctx.logger.info('Backend deleted successfully'); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', response.data?.data); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts index ef26512..6237dba 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts @@ -1 +1,2 @@ -export * from "../backend" +export * from "./createBackend"; +export * from "./deleteBackend"; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts new file mode 100644 index 0000000..3f70484 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Create an organization in Kusion', + example: yaml.stringify({ + steps: [ + { + id: 'create-organization', + action: 'kusion:organization:create', + name: 'Create Organization', + input: { + name: 'my-workspace', + description: 'This is my organization', + labels: ['label1', 'label2'], + owners: ['owner1', 'owner2'], + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts new file mode 100644 index 0000000..37d6cb0 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts @@ -0,0 +1,123 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { Config } from '@backstage/config'; +import { configKusionApi } from '../../api'; +import { + OrganizationService, + CreateOrganizationData, +} from '@kusionstack/kusion-api-client-sdk'; +import { examples } from './createOrganization.example'; + +/** + * Creates an `kusion:organization:create` Scaffolder action. + + * @public + */ +export function createCreateOrganizationAction(options: { config: Config }) { + const { config } = options; + return createTemplateAction<{ + name: string; + description: string; + labels: string[]; + owners: string[]; + }>({ + id: 'kusion:organization:create', + examples, + schema: { + input: { + type: 'object', + required: ['owners'], + properties: { + name: { + title: 'Organization Name', + type: 'string', + }, + description: { + title: 'Organization Description', + type: 'string', + }, + labels: { + title: 'Organization Labels', + type: 'array', + items: { + type: 'string', + }, + }, + owners: { + title: 'Organization Owners', + type: 'array', + items: { + type: 'string', + }, + }, + }, + }, + output: { + type: 'object', + properties: { + success: { + title: 'Success', + type: 'boolean', + }, + message: { + title: 'Message', + type: 'string', + }, + data: { + title: 'Data', + type: 'object', + }, + }, + }, + }, + async handler(ctx) { + const { name, description, labels, owners } = ctx.input; + configKusionApi({ configApi: config }); + const requestBody: CreateOrganizationData = { + body: { + name: name, + description: description, + labels: labels, + owners: owners, + }, + }; + ctx.logger.info( + 'Creating organization with the following request body: ', + requestBody, + ); + const response = await OrganizationService.createOrganization( + requestBody, + ); + + if (!response.data?.success) { + ctx.logger.error(` + Unable to create backend, ${response.data?.message}`); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); + throw new Error( + `Unable to create organization, ${response.data?.message}`, + ); + } + ctx.logger.info('Organization created successfully'); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts new file mode 100644 index 0000000..29bb8f0 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts @@ -0,0 +1 @@ +export * from "./createOrganization" diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts new file mode 100644 index 0000000..0c7ea99 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts @@ -0,0 +1,27 @@ +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Create a project in Kusion', + example: yaml.stringify({ + steps: [ + { + id: 'create-project', + action: 'kusion:project:create', + name: 'Create Project', + input: { + domain: 'http://localhost:3000', + name: 'my-workspace', + description: 'This is my project', + labels: ['label1', 'label2'], + owners: ['owner1', 'owner2'], + organizationID: 1, + path: '/project/tdt', + sourceID: 1, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts new file mode 100644 index 0000000..edef35b --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts @@ -0,0 +1,136 @@ +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { Config } from '@backstage/config'; +import { configKusionApi } from '../../api'; +import { + ProjectService, + CreateProjectData, +} from '@kusionstack/kusion-api-client-sdk'; +import { examples } from './createProject.example'; + +/** + * Creates an `kusion:project:create` Scaffolder action. + + * @public + */ +export function createCreateProjectAction(options: { config: Config }) { + const { config } = options; + return createTemplateAction<{ + domain: string; + name: string; + description: string; + labels: string[]; + owners: string[]; + organizationID: number; + path: string; + sourceID: number; + }>({ + id: 'kusion:project:create', + examples, + schema: { + input: { + type: 'object', + required: ['domain'], + properties: { + domain: { + title: 'Project Domain', + type: 'string', + }, + name: { + title: 'Project Name', + type: 'string', + }, + description: { + title: 'Project Description', + type: 'string', + }, + labels: { + title: 'Project Labels', + type: 'array', + items: { + type: 'string', + }, + }, + owners: { + title: 'Project Owners', + type: 'array', + items: { + type: 'string', + }, + }, + organizationID: { + title: 'Organization ID', + type: 'number', + }, + path: { + title: 'Project Path', + type: 'string', + }, + sourceID: { + title: 'Source ID', + type: 'number', + }, + }, + }, + output: { + type: 'object', + properties: { + success: { + title: 'Success', + type: 'boolean', + }, + message: { + title: 'Message', + type: 'string', + }, + data: { + title: 'Data', + type: 'object', + }, + }, + }, + }, + async handler(ctx) { + const { + domain, + name, + description, + labels, + owners, + organizationID, + path, + sourceID, + } = ctx.input; + configKusionApi({ configApi: config }); + const requestBody: CreateProjectData = { + body: { + domain, + name, + description, + labels, + owners, + organizationID, + path, + sourceID, + }, + }; + ctx.logger.info( + 'Creating project with the following request body: ', + requestBody, + ); + const response = await ProjectService.createProject(requestBody); + + if (!response.data?.success) { + ctx.logger.error(` + Unable to create project, ${response.data?.message}`); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', '{}'); + throw new Error(`Unable to create project, ${response.data?.message}`); + } + ctx.logger.info('Project created successfully'); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts new file mode 100644 index 0000000..174c6d2 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts @@ -0,0 +1 @@ +export * from './createProject'; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts deleted file mode 100644 index ca94819..0000000 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createCreateWorkspaceAction } from './createWorkspace'; -import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; -import { ConfigReader } from '@backstage/config'; - -jest.mock('../../api', () => ({ - createKusionApi: jest.fn(), -})); - -describe('createCreateWorkspaceAction', () => { - const config = new ConfigReader({}); - const action = createCreateWorkspaceAction({ config }); - - it('should create a workspace successfully', async () => { - const mockContext = createMockActionContext({ - input: { - name: 'test-workspace', - description: 'A test workspace', - labels: ['test', 'workspace'], - owners: ['owner1'], - backendID: 1, - }, - }); - - const mockKusionApi = { - post: jest.fn().mockResolvedValue({ - success: true, - message: 'Workspace created successfully', - data: { id: 'workspace-id' }, - }), - }; - - require('../../api').createKusionApi.mockReturnValue(mockKusionApi); - - await action.handler(mockContext); - - expect(mockKusionApi.post).toHaveBeenCalledWith('workspaces', { - name: 'test-workspace', - description: 'A test workspace', - labels: ['test', 'workspace'], - owners: ['owner1'], - backendID: 1, - }); - expect(mockContext.output).toHaveBeenCalledWith('success', true); - expect(mockContext.output).toHaveBeenCalledWith( - 'message', - 'Workspace created successfully', - ); - expect(mockContext.output).toHaveBeenCalledWith( - 'data', - JSON.stringify({ id: 'workspace-id' }), - ); - }); - - it('should handle failure to create a workspace', async () => { - const mockContext = createMockActionContext({ - input: { - name: 'test-workspace', - description: 'A test workspace', - labels: ['test', 'workspace'], - owners: ['owner1'], - backendID: 1, - }, - }); - - const mockKusionApi = { - post: jest.fn().mockResolvedValue({ - success: false, - message: 'Failed to create workspace', - }), - }; - - require('../../api').createKusionApi.mockReturnValue(mockKusionApi); - - await expect(action.handler(mockContext)).rejects.toThrow( - 'Unable to create workspace, Failed to create workspace', - ); - - expect(mockKusionApi.post).toHaveBeenCalledWith('workspaces', { - name: 'test-workspace', - description: 'A test workspace', - labels: ['test', 'workspace'], - owners: ['owner1'], - backendID: 1, - }); - expect(mockContext.output).toHaveBeenCalledWith('success', false); - expect(mockContext.output).toHaveBeenCalledWith( - 'message', - 'Failed to create workspace', - ); - expect(mockContext.output).toHaveBeenCalledWith('data', '{}'); - }); -}); diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts index e21bcc3..24793c0 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts @@ -16,7 +16,11 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; -import { createKusionApi } from '../../api'; +import { configKusionApi } from '../../api'; +import { + WorkspaceService, + CreateWorkspaceData, +} from '@kusionstack/kusion-api-client-sdk'; import { examples } from './createWorkspace.example'; /** @@ -88,13 +92,15 @@ export function createCreateWorkspaceAction(options: { config: Config }) { }, async handler(ctx) { const { name, description, labels, owners, backendID } = ctx.input; - const kusionApi = createKusionApi({ configApi: config }); - const requestBody = { - name, - description, - labels, - owners, - backendID, + configKusionApi({ configApi: config }); + const requestBody: CreateWorkspaceData = { + body: { + name: name, + description: description, + labels: labels, + owners: owners, + backendID: backendID, + }, }; ctx.logger.info( @@ -102,20 +108,22 @@ export function createCreateWorkspaceAction(options: { config: Config }) { requestBody, ); - const response = await kusionApi.post('workspaces', requestBody); + const response = await WorkspaceService.createWorkspace(requestBody); - if (!response.success || response.data === undefined) { + if (!response.data?.success) { ctx.logger.error(` - Unable to create workspace, ${response.message}`); - ctx.output('success', response.success); - ctx.output('message', response.message); - ctx.output('data', '{}'); - throw new Error(`Unable to create workspace, ${response.message}`); + Unable to create backend, ${response.data?.message}`); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); + throw new Error( + `Unable to create workspace, ${response.data?.message}`, + ); } ctx.logger.info('Workspace created successfully'); - ctx.output('success', response.success); - ctx.output('message', response.message); - ctx.output('data', JSON.stringify(response.data)); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); }, }); } diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts new file mode 100644 index 0000000..3a399ef --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Delete a workspace in Kusion', + example: yaml.stringify({ + steps: [ + { + id: 'delete-workspace', + action: 'kusion:workspace:delete', + name: 'Delete workspace', + input: { + id: '1', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts new file mode 100644 index 0000000..2b84a19 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts @@ -0,0 +1,98 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { Config } from '@backstage/config'; +import { configKusionApi } from '../../api'; +import { + WorkspaceService, + DeleteWorkspaceData, +} from '@kusionstack/kusion-api-client-sdk'; +import { examples } from './deleteWorkspace.example'; + +/** + * Creates a `kusion:workspace:delete` Scaffolder action. + * + * @public + */ +export function createDeleteWorkspaceAction(options: { config: Config }) { + const { config } = options; + return createTemplateAction<{ + id: string; + }>({ + id: 'kusion:workspace:delete', + examples, + schema: { + input: { + type: 'object', + required: ['id'], + properties: { + id: { + title: 'Workspace ID', + type: 'string', + }, + }, + }, + output: { + type: 'object', + properties: { + success: { + title: 'Success', + type: 'boolean', + }, + message: { + title: 'Message', + type: 'string', + }, + data: { + title: 'Data', + type: 'object', + }, + }, + }, + }, + async handler(ctx) { + const { id } = ctx.input; + configKusionApi({ configApi: config }); + + ctx.logger.info('Deleting workspace with ID: %s', id); + + const request: DeleteWorkspaceData = { + path: { + workspaceID: Number(id), + }, + }; + + const response = await WorkspaceService.deleteWorkspace(request); + + if (!response.data?.success) { + ctx.logger.error(` + Unable to delete workspace, ${response.data?.message}`); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', JSON.stringify(response.data?.data)); + throw new Error( + `Unable to delete workspace, ${response.data?.message}`, + ); + } + + ctx.logger.info('Workspace deleted successfully'); + ctx.output('success', response.data?.success); + ctx.output('message', response.data?.message); + ctx.output('data', response.data?.data); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts index 517561a..f313bf6 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts @@ -1 +1,2 @@ -export * from "../workspace" +export * from "./createWorkspace"; +export * from "./deleteWorkspace"; diff --git a/plugins/scaffolder-backend-module-kusion/src/api/index.ts b/plugins/scaffolder-backend-module-kusion/src/api/index.ts index fad7c3d..79be9b7 100644 --- a/plugins/scaffolder-backend-module-kusion/src/api/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/api/index.ts @@ -15,39 +15,25 @@ */ import { Config } from '@backstage/config'; -import fetch, { RequestInit } from 'node-fetch'; +import { client } from '@kusionstack/kusion-api-client-sdk'; type Options = { configApi: Config; }; -export const createKusionApi = (option: Options) => { +export const configKusionApi = (option: Options) => { const { configApi } = option; - const getApiUrl = async ( - { serviceName }: { serviceName?: string }, - { params }: { params?: string } = {}, - ): Promise => { + const getApiUrl = () => { const kusionBaseUrl = configApi.getOptionalString('kusion.baseUrl'); if (!kusionBaseUrl) { throw new Error('backstage config kusion.baseUrl is required'); } - const proxyPath = - configApi.getOptionalString('kusion.proxyPath') || DEFAULT_PROXY_PATH; - - let url = `${kusionBaseUrl}${proxyPath}`; - - if (serviceName) { - url += `/${serviceName}`; - } - if (params) { - url += `/${params}`; - } - - return url.replace(/\/$/, ''); + return kusionBaseUrl; }; - const getKusionToken = async () => { + // TODO: Wait for the Kusion Server to support authentication. + const getKusionToken = () => { const token = configApi.getOptionalString('kusion.token'); if (!Boolean(token) || token?.length === 0) { throw new Error('backstage config kusion.token is required'); @@ -55,68 +41,7 @@ export const createKusionApi = (option: Options) => { return token; }; - const post = async ( - serviceName: string, - body: any, - params?: string, - ): Promise => { - try { - const url = await getApiUrl({ serviceName }, { params }); - const requestOption: RequestInit = { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${await getKusionToken()}`, - }, - body: JSON.stringify(body), - }; - - const response = await fetch(url, requestOption); - - if (!response.ok) { - throw new Error( - `Failed to create ${serviceName}: ${response.statusText}`, - ); - } - - return (await response.json()) as KusionResponse; - } catch (error) { - throw new Error(`Error in post request to ${serviceName}: ${error}`); - } - }; - - const put = async ( - serviceName: string, - body: any, - params?: string, - ): Promise => { - try { - const url = await getApiUrl({ serviceName }, { params }); - const requestOption: RequestInit = { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${await getKusionToken()}`, - }, - body: JSON.stringify(body), - }; - - const response = await fetch(url, requestOption); - - if (!response.ok) { - throw new Error( - `Failed to update ${serviceName}: ${response.statusText}`, - ); - } - - return (await response.json()) as KusionResponse; - } catch (error) { - throw new Error(`Error in put request to ${serviceName}: ${error}`); - } - }; - - return { - post, - put, - }; + client.setConfig({ + baseUrl: getApiUrl(), + }); }; diff --git a/plugins/scaffolder-backend-module-kusion/src/module.ts b/plugins/scaffolder-backend-module-kusion/src/module.ts index 79ed6b0..f4a1ddd 100644 --- a/plugins/scaffolder-backend-module-kusion/src/module.ts +++ b/plugins/scaffolder-backend-module-kusion/src/module.ts @@ -19,8 +19,16 @@ import { coreServices, } from '@backstage/backend-plugin-api'; import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; -import { createCreateWorkspaceAction } from './actions/workspace/createWorkspace'; -import { createCreateBackendAction } from './actions/backend/createBackend'; +import { createCreateOrganizationAction } from './actions/organization'; +import { createCreateProjectAction } from './actions/project'; +import { + createCreateWorkspaceAction, + createDeleteWorkspaceAction, +} from './actions/workspace'; +import { + createCreateBackendAction, + createDeleteBackendAction, +} from './actions/backend'; /** * The Kusion Module for the Scaffolder Backend @@ -40,11 +48,27 @@ export const kusionModule = createBackendModule({ createCreateWorkspaceAction({ config, }), + createDeleteWorkspaceAction({ + config, + }), ); scaffolder.addActions( createCreateBackendAction({ config, }), + createDeleteBackendAction({ + config, + }), + ); + scaffolder.addActions( + createCreateOrganizationAction({ + config, + }), + ); + scaffolder.addActions( + createCreateProjectAction({ + config, + }), ); }, }); diff --git a/yarn.lock b/yarn.lock index ec6b4fa..fd06410 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7006,6 +7006,13 @@ __metadata: languageName: node linkType: hard +"@hey-api/client-fetch@npm:^0.5.2": + version: 0.5.3 + resolution: "@hey-api/client-fetch@npm:0.5.3" + checksum: 10c0/04e8271d09197d78890d0cfb124eefed7d38156a7dd4e578f2d083083569845cea7803744e0abf3f54cb518cb0ad3d4cbc5f082ac5aa66ec5057d96d4a5e0fac + languageName: node + linkType: hard + "@httptoolkit/httpolyglot@npm:^2.2.1": version: 2.2.2 resolution: "@httptoolkit/httpolyglot@npm:2.2.2" @@ -7648,11 +7655,21 @@ __metadata: "@backstage/config": "npm:^1.3.0" "@backstage/plugin-scaffolder-node": "npm:^0.6.0" "@backstage/plugin-scaffolder-node-test-utils": "npm:^0.1.15" + "@kusionstack/kusion-api-client-sdk": "npm:^1.1.3" node-fetch: "npm:^2.7.0" yaml: "npm:^2.6.1" languageName: unknown linkType: soft +"@kusionstack/kusion-api-client-sdk@npm:^1.1.3": + version: 1.1.3 + resolution: "@kusionstack/kusion-api-client-sdk@npm:1.1.3" + dependencies: + "@hey-api/client-fetch": "npm:^0.5.2" + checksum: 10c0/c6e641f5c37ff230d45fd4dfd98015f8f2d77fbb176fe9739cf5858363663f7f71ff4c938edf8a28b66e7f6b5febc7f8306098380fbd90b5d4fe4c32f777f607 + languageName: node + linkType: hard + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.5 resolution: "@leichtgewicht/ip-codec@npm:2.0.5" From 7181f0338c944156fbfe7bc1aaaf0c589562ade1 Mon Sep 17 00:00:00 2001 From: hoangndst Date: Fri, 16 May 2025 03:11:56 +0700 Subject: [PATCH 3/3] feat: add create action for backend, organization, project, and workspace --- .changeset/slick-ghosts-retire.md | 5 + .changeset/tricky-files-smash.md | 5 + app-config.yaml | 5 + examples/template/scaffolder.yaml | 65 + package.json | 3 + packages/backend/package.json | 2 +- packages/backend/src/index.ts | 2 +- .../README.md | 90 +- .../catalog-info.yaml | 10 + .../package.json | 19 +- .../report.api.md | 11 + .../backend/createBackend.example.test.ts | 36 + .../actions/backend/createBackend.example.ts | 18 +- .../src/actions/backend/createBackend.test.ts | 78 + .../src/actions/backend/createBackend.ts | 16 + .../actions/backend/deleteBackend.example.ts | 36 - .../src/actions/backend/deleteBackend.ts | 96 - .../src/actions/backend/index.ts | 19 +- .../createOrganization.example.ts | 2 +- .../organization/createOrganization.ts | 2 +- .../src/actions/organization/index.ts | 18 +- .../actions/project/createProject.example.ts | 16 + .../src/actions/project/createProject.ts | 16 + .../src/actions/project/index.ts | 16 + .../workspace/createWorkspace.example.ts | 2 +- .../src/actions/workspace/createWorkspace.ts | 2 +- .../workspace/deleteWorkspace.example.ts | 36 - .../src/actions/workspace/deleteWorkspace.ts | 98 - .../src/actions/workspace/index.ts | 17 +- .../src/api/index.ts | 11 +- .../src/index.ts | 2 +- .../src/module.ts | 18 +- yarn.lock | 1773 ++++++++++++++++- 33 files changed, 2139 insertions(+), 406 deletions(-) create mode 100644 .changeset/slick-ghosts-retire.md create mode 100644 .changeset/tricky-files-smash.md create mode 100644 examples/template/scaffolder.yaml create mode 100644 plugins/scaffolder-backend-module-kusion/catalog-info.yaml create mode 100644 plugins/scaffolder-backend-module-kusion/report.api.md create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.test.ts create mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts delete mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.example.ts delete mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts delete mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts delete mode 100644 plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts diff --git a/.changeset/slick-ghosts-retire.md b/.changeset/slick-ghosts-retire.md new file mode 100644 index 0000000..3e91d36 --- /dev/null +++ b/.changeset/slick-ghosts-retire.md @@ -0,0 +1,5 @@ +--- +'backend': patch +--- + +add package @kusionstack/plugin-scaffolder-backend-module-kusion. diff --git a/.changeset/tricky-files-smash.md b/.changeset/tricky-files-smash.md new file mode 100644 index 0000000..a87235e --- /dev/null +++ b/.changeset/tricky-files-smash.md @@ -0,0 +1,5 @@ +--- +'@kusionstack/plugin-scaffolder-backend-module-kusion': minor +--- + +add create action for backend, organization, project, and workspace. diff --git a/app-config.yaml b/app-config.yaml index f6c0919..2a04598 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -94,6 +94,11 @@ catalog: rules: - allow: [User, Group] + - type: file + target: ../../examples/template/scaffolder.yaml + rules: + - allow: [Template] + ## Uncomment these lines to add more example data # - type: url # target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all.yaml diff --git a/examples/template/scaffolder.yaml b/examples/template/scaffolder.yaml new file mode 100644 index 0000000..9bf30da --- /dev/null +++ b/examples/template/scaffolder.yaml @@ -0,0 +1,65 @@ +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: create-kusion-backend + title: Create Kusion Backend + description: Template to create a new Kusion Backend. +spec: + owner: KusionStack + type: service + + parameters: + - title: Backend Information + required: + - name + - backendType + properties: + name: + title: Backend Name + type: string + description: The name of the backend to create. + pattern: ^[a-zA-Z0-9_-]+$ + + description: + title: Backend Description + type: string + description: A description for the backend. + backendType: + title: Backend Type + type: string + description: The type of backend (e.g., local, s3, etc). + enum: + - local + - oss + - s3 + - google + markdown: + type: 'null' # Needs to be quoted + description: | + ### ❗ **Important**: Please fill in the backend configs according to the backend type. + * [Kusion Backend concepts](https://www.kusionstack.io/docs/concepts/backend/overview) + backendConfigs: + title: Backend Configs + type: object + additionalProperties: + type: string + description: Key-value pairs for backend configuration. + + steps: + - id: createBackend + name: Create Backend + action: kusion:backend:create + input: + name: ${{ parameters.name }} + description: ${{ parameters.description }} + backendConfig: + type: ${{ parameters.backendType }} + configs: ${{ parameters.backendConfigs }} + + output: + text: + - title: Information + content: | + * success: ${{ steps.createBackend.output.success }} + * message: ${{ steps.createBackend.output.message }} + * data: ${{ steps.createBackend.output.data }} \ No newline at end of file diff --git a/package.json b/package.json index 973268e..3294344 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "dev": "yarn workspaces foreach -A --include backend --include app --parallel -v -i run start", "start": "yarn workspace app start", "start-backend": "yarn workspace backend start", + "build:api-reports": "yarn build:api-reports:only --tsc", + "build:api-reports:only": "LANG=en_US.UTF-8 NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --sql-reports --allow-warnings 'plugins/*' -o ae-undocumented,ae-wrong-input-file-type --validate-release-tags", "build:backend": "yarn workspace backend build", "build:all": "backstage-cli repo build --all", "build-image": "yarn workspace backend build-image", @@ -33,6 +35,7 @@ "devDependencies": { "@backstage/cli": "^0.29.0", "@backstage/e2e-test-utils": "^0.1.1", + "@backstage/repo-tools": "^0.13.2", "@changesets/cli": "^2.29.4", "@octokit/rest": "^21.1.1", "@playwright/test": "^1.32.3", diff --git a/packages/backend/package.json b/packages/backend/package.json index 6ef1f7a..382247c 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -39,7 +39,7 @@ "@backstage/plugin-search-backend-module-techdocs": "^0.3.2", "@backstage/plugin-search-backend-node": "^1.3.5", "@backstage/plugin-techdocs-backend": "^1.11.2", - "@kusion/backstage-plugin-scaffolder-backend-module-kusion": "^0.1.0", + "@kusionstack/plugin-scaffolder-backend-module-kusion": "^0.0.0", "app": "link:../app", "better-sqlite3": "^9.0.0", "node-gyp": "^10.0.0", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 71b837c..9ab132f 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -52,6 +52,6 @@ backend.add(import('@backstage/plugin-search-backend-module-techdocs')); backend.add(import('@backstage/plugin-kubernetes-backend')); // kusion -backend.add(import('@kusion/backstage-plugin-scaffolder-backend-module-kusion')); +backend.add(import('@kusionstack/plugin-scaffolder-backend-module-kusion')); backend.start(); diff --git a/plugins/scaffolder-backend-module-kusion/README.md b/plugins/scaffolder-backend-module-kusion/README.md index 01c0c3b..f711ae5 100644 --- a/plugins/scaffolder-backend-module-kusion/README.md +++ b/plugins/scaffolder-backend-module-kusion/README.md @@ -1,59 +1,85 @@ -## Backstage Plugin Scaffolder Backend Module Kusion +# Backstage Scaffolder Backend Module for Kusion -### Getting Started +## Overview -You need a `Kusion Server` running. You can find the server [here](https://github.com/KusionStack/kusion). +This plugin integrates [KusionStack](https://github.com/KusionStack/kusion) with Backstage's scaffolder backend, enabling you to create and manage Kusion backends directly from Backstage templates. -You need to add the following to your `app-config.yaml`. For example: +--- + +## Prerequisites + +- A running [Kusion Server](https://github.com/KusionStack/kusion) +- A Backstage instance (see [Backstage documentation](https://backstage.io/docs/getting-started/)) + +--- + +## Installation + +From your Backstage root directory, install the plugin: + +```bash +yarn add --cwd packages/backend @kusionstack/plugin-scaffolder-backend-module-kusion +``` + +--- + +## Configuration + +Add the following configuration to your `app-config.yaml` to specify the Kusion server endpoint: ```yaml backend: -kusion: - baseUrl: 'http://localhost:3000' + kusion: + baseUrl: 'http://localhost:3000' # Replace with your Kusion server URL ``` -### From your Backstage root directory +--- -```bash -# From your Backstage root directory -yarn add --cwd packages/backend @kusion/backstage-plugin-scaffolder-backend-module-kusion +## Backend Integration + +Import and register the plugin in your Backstage backend: + +Edit `packages/backend/src/index.ts`: + +```typescript +// Import and register the Kusion scaffolder backend module +backend.add(import('@kusionstack/plugin-scaffolder-backend-module-kusion')); ``` -### Workspace +--- -#### Kusion Create Workspace +## Usage Example -The Kusion Workspace Create action that allows you to create a new Kusion Workspace from a template. +### Kusion Backend Creation Template. -`kusion:workspace:create` +`kusion:backend:create` ```yaml apiVersion: scaffolder.backstage.io/v1beta3 kind: Template metadata: - name: create-workspace - title: Create Workspace Template - description: A template to create a workspace -tags: - - kusion - - workspace + name: create-kusion-backend + title: Create Kusion Backend + description: Template to create a new Kusion Backend. spec: + owner: KusionStack + type: service steps: - - id: create-workspace - name: Create Workspace - action: kusion:workspace:create + - id: createBackend + name: Create Backend + action: kusion:backend:create input: name: ${{ parameters.name }} description: ${{ parameters.description }} - labels: ${{ parameters.labels }} - owners: ${{ parameters.owners }} - backendID: ${{ parameters.backend_id }} + backendConfig: + type: ${{ parameters.backendType }} + configs: ${{ parameters.backendConfigs }} + output: text: - - title: Workspace create status - description: The status of workspace creation - content: | - Success: `${{ steps['create-workspace'].output.success }}` - Message: `${{ steps['create-workspace'].output.message }}` - Data: `${{ steps['create-workspace'].output.data }}` + - title: Information + content: | + * success: ${{ steps.createBackend.output.success }} + * message: ${{ steps.createBackend.output.message }} + * data: ${{ steps.createBackend.output.data }} ``` diff --git a/plugins/scaffolder-backend-module-kusion/catalog-info.yaml b/plugins/scaffolder-backend-module-kusion/catalog-info.yaml new file mode 100644 index 0000000..e0c6349 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-backend-module-kusion + title: '@kusionstack/plugin-scaffolder-backend-module-kusion' + description: The kusion backend module for the scaffolder plugin provide by KusionStack team +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/scaffolder-backend-module-kusion/package.json b/plugins/scaffolder-backend-module-kusion/package.json index 5db4fbc..350a29b 100644 --- a/plugins/scaffolder-backend-module-kusion/package.json +++ b/plugins/scaffolder-backend-module-kusion/package.json @@ -1,14 +1,14 @@ { - "name": "@kusion/backstage-plugin-scaffolder-backend-module-kusion", - "version": "0.1.0", + "name": "@kusionstack/plugin-scaffolder-backend-module-kusion", + "version": "0.0.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", + "homepage": "https://kusionstack.io", "author": { "email": "hoangndst@gmail.com", "name": "hoangndst" }, - "private": true, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -19,6 +19,17 @@ "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "package.json": [ + "package.json" + ] + } + }, "scripts": { "start": "backstage-cli package start", "build": "backstage-cli package build", @@ -37,7 +48,7 @@ "@backstage/backend-plugin-api": "^1.0.2", "@backstage/config": "^1.3.0", "@backstage/plugin-scaffolder-node": "^0.6.0", - "@kusionstack/kusion-api-client-sdk": "^1.1.3", + "@kusionstack/kusion-api-client-sdk": "^1.1.5", "yaml": "^2.6.1" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-kusion/report.api.md b/plugins/scaffolder-backend-module-kusion/report.api.md new file mode 100644 index 0000000..3647c22 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/report.api.md @@ -0,0 +1,11 @@ +## API Report File for "@kusionstack/plugin-scaffolder-backend-module-kusion" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @public +const kusionModule: BackendFeature; +export default kusionModule; +``` diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.test.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.test.ts new file mode 100644 index 0000000..6d2aeee --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.test.ts @@ -0,0 +1,36 @@ +import { examples } from './createBackend.example'; +import yaml from 'yaml'; + +describe('createBackend.example', () => { + it('should export the correct example', () => { + expect(Array.isArray(examples)).toBe(true); + expect(examples.length).toBe(1); + const example = examples[0]; + expect(example.description).toBe('Create a backend in Kusion'); + + // Parse the YAML to verify its structure + const parsed = yaml.parse(example.example); + expect(parsed).toHaveProperty('steps'); + expect(Array.isArray(parsed.steps)).toBe(true); + expect(parsed.steps[0]).toMatchObject({ + id: 'create-backend', + action: 'kusion:backend:create', + name: 'Create backend', + input: { + name: 'my-backend', + description: 'This is my backend', + backendConfig: { + type: 's3', + configs: { + region: 'string', + endpoint: 'string', + accessKeyID: 'string', + accessKeySecret: 'string', + bucket: 'string', + prefix: 'string', + }, + }, + }, + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts index 9623977..f6dd9ba 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.example.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,15 +30,15 @@ export const examples: TemplateExample[] = [ name: 'my-backend', description: 'This is my backend', backendConfig: { - "configs": { - "region": "string", - "endpoint": "string", - "accessKeyID": "string", - "accessKeySecret": "string", - "bucket": "string", - "prefix": "string", + configs: { + region: 'string', + endpoint: 'string', + accessKeyID: 'string', + accessKeySecret: 'string', + bucket: 'string', + prefix: 'string', }, - "type": "s3" + type: 's3', }, }, }, diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts new file mode 100644 index 0000000..0a348b3 --- /dev/null +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.test.ts @@ -0,0 +1,78 @@ +import { createCreateBackendAction } from './createBackend'; +import { Config } from '@backstage/config'; +import { BackendService } from '@kusionstack/kusion-api-client-sdk'; + +jest.mock('../../api', () => ({ + configKusionApi: jest.fn(), +})); +jest.mock('@kusionstack/kusion-api-client-sdk', () => ({ + BackendService: { + createBackend: jest.fn(), + }, +})); + +describe('createCreateBackendAction', () => { + const mockConfig = { get: jest.fn() } as unknown as Config; + const action = createCreateBackendAction({ config: mockConfig }); + const input = { + name: 'my-backend', + description: 'This is my backend', + backendConfig: { + type: 's3', + configs: { + region: 'string', + endpoint: 'string', + accessKeyID: 'string', + accessKeySecret: 'string', + bucket: 'string', + prefix: 'string', + }, + }, + }; + + let ctx: any; + + beforeEach(() => { + ctx = { + input, + logger: { info: jest.fn(), error: jest.fn() }, + output: jest.fn(), + }; + jest.clearAllMocks(); + }); + + it('should create backend successfully', async () => { + (BackendService.createBackend as jest.Mock).mockResolvedValue({ + data: { success: true, message: 'Created', data: { id: 1 } }, + }); + + await action.handler(ctx); + + expect(BackendService.createBackend).toHaveBeenCalledWith({ + body: { + name: input.name, + description: input.description, + backendConfig: input.backendConfig, + }, + }); + expect(ctx.output).toHaveBeenCalledWith('success', true); + expect(ctx.output).toHaveBeenCalledWith('message', 'Created'); + expect(ctx.output).toHaveBeenCalledWith('data', JSON.stringify({ id: 1 })); + }); + + it('should handle backend creation failure', async () => { + (BackendService.createBackend as jest.Mock).mockResolvedValue({ + data: { success: false, message: 'Failed', data: { error: 'reason' } }, + }); + + await expect(action.handler(ctx)).rejects.toThrow( + 'Unable to create backend, Failed', + ); + expect(ctx.output).toHaveBeenCalledWith('success', false); + expect(ctx.output).toHaveBeenCalledWith('message', 'Failed'); + expect(ctx.output).toHaveBeenCalledWith( + 'data', + JSON.stringify({ error: 'reason' }), + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts index 7fb8b3c..fd888d7 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/createBackend.ts @@ -1,3 +1,19 @@ +/* + * Copyright 2025 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; import { configKusionApi } from '../../api'; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.example.ts deleted file mode 100644 index 586bcd8..0000000 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.example.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TemplateExample } from '@backstage/plugin-scaffolder-node'; -import yaml from 'yaml'; - -export const examples: TemplateExample[] = [ - { - description: 'Delete a backend in Kusion', - example: yaml.stringify({ - steps: [ - { - id: 'delete-backend', - action: 'kusion:backend:delete', - name: 'Delete backend', - input: { - id: '1', - }, - }, - ], - }), - }, -]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts deleted file mode 100644 index a3e12aa..0000000 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/deleteBackend.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { Config } from '@backstage/config'; -import { configKusionApi } from '../../api'; -import { - BackendService, - DeleteBackendData, -} from '@kusionstack/kusion-api-client-sdk'; -import { examples } from './deleteBackend.example'; - -/** - * Creates a `kusion:backend:delete` Scaffolder action. - * - * @public - */ -export function createDeleteBackendAction(options: { config: Config }) { - const { config } = options; - return createTemplateAction<{ - id: string; - }>({ - id: 'kusion:backend:delete', - examples, - schema: { - input: { - type: 'object', - required: ['id'], - properties: { - id: { - title: 'Backend ID', - type: 'string', - }, - }, - }, - output: { - type: 'object', - properties: { - success: { - title: 'Success', - type: 'boolean', - }, - message: { - title: 'Message', - type: 'string', - }, - data: { - title: 'Data', - type: 'object', - }, - }, - }, - }, - async handler(ctx) { - const { id } = ctx.input; - configKusionApi({ configApi: config }); - - ctx.logger.info('Deleting backend with ID: %s', id); - - const request: DeleteBackendData = { - path: { - backendID: Number(id), - }, - }; - - const response = await BackendService.deleteBackend(request); - - if (!response.data?.success) { - ctx.logger.error(` - Unable to delete backend, ${response.data?.message}`); - ctx.output('success', response.data?.success); - ctx.output('message', response.data?.message); - ctx.output('data', JSON.stringify(response.data?.data)); - throw new Error(`Unable to delete backend, ${response.data?.message}`); - } - - ctx.logger.info('Backend deleted successfully'); - ctx.output('success', response.data?.success); - ctx.output('message', response.data?.message); - ctx.output('data', response.data?.data); - }, - }); -} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts index 6237dba..28ef62f 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/backend/index.ts @@ -1,2 +1,17 @@ -export * from "./createBackend"; -export * from "./deleteBackend"; +/* + * Copyright 2025 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './createBackend'; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts index 3f70484..a74dd5b 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.example.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts index 37d6cb0..147c53f 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/organization/createOrganization.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts index 29bb8f0..350cf8d 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/organization/index.ts @@ -1 +1,17 @@ -export * from "./createOrganization" +/* + * Copyright 2025 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './createOrganization'; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts index 0c7ea99..5a8de6f 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.example.ts @@ -1,3 +1,19 @@ +/* + * Copyright 2025 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { TemplateExample } from '@backstage/plugin-scaffolder-node'; import yaml from 'yaml'; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts index edef35b..6f7e9e7 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/project/createProject.ts @@ -1,3 +1,19 @@ +/* + * Copyright 2025 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; import { configKusionApi } from '../../api'; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts index 174c6d2..42cd51a 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/project/index.ts @@ -1 +1,17 @@ +/* + * Copyright 2025 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + export * from './createProject'; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts index 917da6f..85c9977 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.example.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts index 24793c0..bc0a7f9 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/createWorkspace.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts deleted file mode 100644 index 3a399ef..0000000 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.example.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TemplateExample } from '@backstage/plugin-scaffolder-node'; -import yaml from 'yaml'; - -export const examples: TemplateExample[] = [ - { - description: 'Delete a workspace in Kusion', - example: yaml.stringify({ - steps: [ - { - id: 'delete-workspace', - action: 'kusion:workspace:delete', - name: 'Delete workspace', - input: { - id: '1', - }, - }, - ], - }), - }, -]; diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts deleted file mode 100644 index 2b84a19..0000000 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/deleteWorkspace.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { Config } from '@backstage/config'; -import { configKusionApi } from '../../api'; -import { - WorkspaceService, - DeleteWorkspaceData, -} from '@kusionstack/kusion-api-client-sdk'; -import { examples } from './deleteWorkspace.example'; - -/** - * Creates a `kusion:workspace:delete` Scaffolder action. - * - * @public - */ -export function createDeleteWorkspaceAction(options: { config: Config }) { - const { config } = options; - return createTemplateAction<{ - id: string; - }>({ - id: 'kusion:workspace:delete', - examples, - schema: { - input: { - type: 'object', - required: ['id'], - properties: { - id: { - title: 'Workspace ID', - type: 'string', - }, - }, - }, - output: { - type: 'object', - properties: { - success: { - title: 'Success', - type: 'boolean', - }, - message: { - title: 'Message', - type: 'string', - }, - data: { - title: 'Data', - type: 'object', - }, - }, - }, - }, - async handler(ctx) { - const { id } = ctx.input; - configKusionApi({ configApi: config }); - - ctx.logger.info('Deleting workspace with ID: %s', id); - - const request: DeleteWorkspaceData = { - path: { - workspaceID: Number(id), - }, - }; - - const response = await WorkspaceService.deleteWorkspace(request); - - if (!response.data?.success) { - ctx.logger.error(` - Unable to delete workspace, ${response.data?.message}`); - ctx.output('success', response.data?.success); - ctx.output('message', response.data?.message); - ctx.output('data', JSON.stringify(response.data?.data)); - throw new Error( - `Unable to delete workspace, ${response.data?.message}`, - ); - } - - ctx.logger.info('Workspace deleted successfully'); - ctx.output('success', response.data?.success); - ctx.output('message', response.data?.message); - ctx.output('data', response.data?.data); - }, - }); -} diff --git a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts index f313bf6..c6ac9f6 100644 --- a/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/actions/workspace/index.ts @@ -1,2 +1,17 @@ +/* + * Copyright 2025 KusionStack + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + export * from "./createWorkspace"; -export * from "./deleteWorkspace"; diff --git a/plugins/scaffolder-backend-module-kusion/src/api/index.ts b/plugins/scaffolder-backend-module-kusion/src/api/index.ts index 79be9b7..1d6d9d0 100644 --- a/plugins/scaffolder-backend-module-kusion/src/api/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/api/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 KusionStack + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,15 +32,6 @@ export const configKusionApi = (option: Options) => { return kusionBaseUrl; }; - // TODO: Wait for the Kusion Server to support authentication. - const getKusionToken = () => { - const token = configApi.getOptionalString('kusion.token'); - if (!Boolean(token) || token?.length === 0) { - throw new Error('backstage config kusion.token is required'); - } - return token; - }; - client.setConfig({ baseUrl: getApiUrl(), }); diff --git a/plugins/scaffolder-backend-module-kusion/src/index.ts b/plugins/scaffolder-backend-module-kusion/src/index.ts index 737daac..8482d14 100644 --- a/plugins/scaffolder-backend-module-kusion/src/index.ts +++ b/plugins/scaffolder-backend-module-kusion/src/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/scaffolder-backend-module-kusion/src/module.ts b/plugins/scaffolder-backend-module-kusion/src/module.ts index f4a1ddd..8684f69 100644 --- a/plugins/scaffolder-backend-module-kusion/src/module.ts +++ b/plugins/scaffolder-backend-module-kusion/src/module.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 KusionStack * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,14 +21,8 @@ import { import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; import { createCreateOrganizationAction } from './actions/organization'; import { createCreateProjectAction } from './actions/project'; -import { - createCreateWorkspaceAction, - createDeleteWorkspaceAction, -} from './actions/workspace'; -import { - createCreateBackendAction, - createDeleteBackendAction, -} from './actions/backend'; +import { createCreateWorkspaceAction } from './actions/workspace'; +import { createCreateBackendAction } from './actions/backend'; /** * The Kusion Module for the Scaffolder Backend @@ -48,17 +42,11 @@ export const kusionModule = createBackendModule({ createCreateWorkspaceAction({ config, }), - createDeleteWorkspaceAction({ - config, - }), ); scaffolder.addActions( createCreateBackendAction({ config, }), - createDeleteBackendAction({ - config, - }), ); scaffolder.addActions( createCreateOrganizationAction({ diff --git a/yarn.lock b/yarn.lock index fd06410..bf45358 100644 --- a/yarn.lock +++ b/yarn.lock @@ -75,6 +75,16 @@ __metadata: languageName: node linkType: hard +"@apisyouwonthate/style-guide@npm:^1.4.0": + version: 1.5.0 + resolution: "@apisyouwonthate/style-guide@npm:1.5.0" + dependencies: + "@stoplight/spectral-formats": "npm:^1.2.0" + "@stoplight/spectral-functions": "npm:^1.6.1" + checksum: 10c0/d2c209f14ac5301ab97895ecd27b6072f9e7eb45cce650752feb323e0a06836c0765a0f820dcfbc36c71e34df70e0059e6109ba93571c20f21f1c957274ef2e4 + languageName: node + linkType: hard + "@ardatan/sync-fetch@npm:^0.0.1": version: 0.0.1 resolution: "@ardatan/sync-fetch@npm:0.0.1" @@ -3037,6 +3047,25 @@ __metadata: languageName: node linkType: hard +"@backstage/backend-plugin-api@npm:^1.3.0": + version: 1.3.0 + resolution: "@backstage/backend-plugin-api@npm:1.3.0" + dependencies: + "@backstage/cli-common": "npm:^0.1.15" + "@backstage/config": "npm:^1.3.2" + "@backstage/errors": "npm:^1.2.7" + "@backstage/plugin-auth-node": "npm:^0.6.2" + "@backstage/plugin-permission-common": "npm:^0.8.4" + "@backstage/plugin-permission-node": "npm:^0.9.1" + "@backstage/types": "npm:^1.2.1" + "@types/express": "npm:^4.17.6" + "@types/luxon": "npm:^3.0.0" + knex: "npm:^3.0.0" + luxon: "npm:^3.0.0" + checksum: 10c0/9e31dd759e0e6f34ec5fd677981ebc4a74a1c8ca9e6091da07bace84e5054daae80d903f399bea09c9dc4b52fb3739b7913ed5a9b357c626b048537cbce96fd0 + languageName: node + linkType: hard + "@backstage/backend-test-utils@npm:^1.1.0": version: 1.1.0 resolution: "@backstage/backend-test-utils@npm:1.1.0" @@ -3086,6 +3115,18 @@ __metadata: languageName: node linkType: hard +"@backstage/catalog-client@npm:^1.9.1": + version: 1.9.1 + resolution: "@backstage/catalog-client@npm:1.9.1" + dependencies: + "@backstage/catalog-model": "npm:^1.7.3" + "@backstage/errors": "npm:^1.2.7" + cross-fetch: "npm:^4.0.0" + uri-template: "npm:^2.0.0" + checksum: 10c0/8b9a9e61026418e4ba85d5e8129e2ba0b0e39f526b94a5f0e6d0b862770c5304f1677e028c444e52fd8fd1d14193c5effce022996264fd3d3365c5d8b8e45551 + languageName: node + linkType: hard + "@backstage/catalog-model@npm:^1.7.1": version: 1.7.1 resolution: "@backstage/catalog-model@npm:1.7.1" @@ -3098,6 +3139,18 @@ __metadata: languageName: node linkType: hard +"@backstage/catalog-model@npm:^1.7.3": + version: 1.7.3 + resolution: "@backstage/catalog-model@npm:1.7.3" + dependencies: + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.1" + ajv: "npm:^8.10.0" + lodash: "npm:^4.17.21" + checksum: 10c0/6bd3644be089ea5bb980a40426663b609d5a224d1b27a6967a335d497d3591a6463cfd0c5ab27151bb4a8727cd0f881c25423dcb993352b0eb60fe1c7e55f1be + languageName: node + linkType: hard + "@backstage/cli-common@npm:^0.1.14, @backstage/cli-common@npm:^0.1.15": version: 0.1.15 resolution: "@backstage/cli-common@npm:0.1.15" @@ -3121,6 +3174,22 @@ __metadata: languageName: node linkType: hard +"@backstage/cli-node@npm:^0.2.13": + version: 0.2.13 + resolution: "@backstage/cli-node@npm:0.2.13" + dependencies: + "@backstage/cli-common": "npm:^0.1.15" + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.1" + "@manypkg/get-packages": "npm:^1.1.3" + "@yarnpkg/parsers": "npm:^3.0.0" + fs-extra: "npm:^11.2.0" + semver: "npm:^7.5.3" + zod: "npm:^3.22.4" + checksum: 10c0/32549303f1d243dd7ea4a36021391e4c80bb764552157669a50b009a168a991e28c7b6de3abc75efa7c1f153372e66f4561e4a93a4a4e10f957b3a0ad8a48ab2 + languageName: node + linkType: hard + "@backstage/cli@npm:^0.29.0": version: 0.29.2 resolution: "@backstage/cli@npm:0.29.2" @@ -3271,6 +3340,29 @@ __metadata: languageName: node linkType: hard +"@backstage/config-loader@npm:^1.10.0": + version: 1.10.0 + resolution: "@backstage/config-loader@npm:1.10.0" + dependencies: + "@backstage/cli-common": "npm:^0.1.15" + "@backstage/config": "npm:^1.3.2" + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.1" + "@types/json-schema": "npm:^7.0.6" + ajv: "npm:^8.10.0" + chokidar: "npm:^3.5.2" + fs-extra: "npm:^11.2.0" + json-schema: "npm:^0.4.0" + json-schema-merge-allof: "npm:^0.8.1" + json-schema-traverse: "npm:^1.0.0" + lodash: "npm:^4.17.21" + minimist: "npm:^1.2.5" + typescript-json-schema: "npm:^0.65.0" + yaml: "npm:^2.0.0" + checksum: 10c0/4cd9c92a45eb1f71c9dcf91856b83b64495a5d72a4629e61f1ca2d8117a851186b9062899805007a1b2c51c2690cb14f67014bd783ee6c2ad2ac5e6e182b8686 + languageName: node + linkType: hard + "@backstage/config-loader@npm:^1.9.1, @backstage/config-loader@npm:^1.9.2": version: 1.9.2 resolution: "@backstage/config-loader@npm:1.9.2" @@ -3306,6 +3398,17 @@ __metadata: languageName: node linkType: hard +"@backstage/config@npm:^1.3.2": + version: 1.3.2 + resolution: "@backstage/config@npm:1.3.2" + dependencies: + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.1" + ms: "npm:^2.1.3" + checksum: 10c0/9d3dfac9b359727b727567834c2576cc2af96e149b3a0b45565251b02f2dfda9559ee3719d1eed240f5cae4f6b8bb9babfbffc3a35d2d2d8fbe5c408c41c42e3 + languageName: node + linkType: hard + "@backstage/core-app-api@npm:^1.15.2": version: 1.15.2 resolution: "@backstage/core-app-api@npm:1.15.2" @@ -3453,6 +3556,16 @@ __metadata: languageName: node linkType: hard +"@backstage/errors@npm:^1.2.7": + version: 1.2.7 + resolution: "@backstage/errors@npm:1.2.7" + dependencies: + "@backstage/types": "npm:^1.2.1" + serialize-error: "npm:^8.0.1" + checksum: 10c0/ce04dccc96c49bf121f1de86a589bbe3a613a32f63546b100a9d074bf2cb79c8ba889e1e7ba39c44c717b1bc7dea7654de85b1229fb7e4106e31dd60327c10c1 + languageName: node + linkType: hard + "@backstage/eslint-plugin@npm:^0.1.10": version: 0.1.10 resolution: "@backstage/eslint-plugin@npm:0.1.10" @@ -4044,6 +4157,29 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-auth-node@npm:^0.6.2": + version: 0.6.2 + resolution: "@backstage/plugin-auth-node@npm:0.6.2" + dependencies: + "@backstage/backend-plugin-api": "npm:^1.3.0" + "@backstage/catalog-client": "npm:^1.9.1" + "@backstage/catalog-model": "npm:^1.7.3" + "@backstage/config": "npm:^1.3.2" + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.1" + "@types/express": "npm:^4.17.6" + "@types/passport": "npm:^1.0.3" + express: "npm:^4.17.1" + jose: "npm:^5.0.0" + lodash: "npm:^4.17.21" + passport: "npm:^0.7.0" + zod: "npm:^3.22.4" + zod-to-json-schema: "npm:^3.21.4" + zod-validation-error: "npm:^3.4.0" + checksum: 10c0/cb49d6f2160cbfc85aa48ef54c9b4b6eeedee320aa7aaf3d41375443be259e9eb28298a18dc62dbc62d59e4a9397fb2827ea7191d2e902d697780dc3d0db6363 + languageName: node + linkType: hard + "@backstage/plugin-auth-react@npm:^0.1.9": version: 0.1.9 resolution: "@backstage/plugin-auth-react@npm:0.1.9" @@ -4565,6 +4701,21 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-permission-common@npm:^0.8.4": + version: 0.8.4 + resolution: "@backstage/plugin-permission-common@npm:0.8.4" + dependencies: + "@backstage/config": "npm:^1.3.2" + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.1" + cross-fetch: "npm:^4.0.0" + uuid: "npm:^11.0.0" + zod: "npm:^3.22.4" + zod-to-json-schema: "npm:^3.20.4" + checksum: 10c0/35d52365c1abb23c6ad167149ab78aad0396b97d5c9e591f5a5e397ea029855a6b88f05060e2215e2480244bec797d92871ad92fa613255eeddd54228c01b7f1 + languageName: node + linkType: hard + "@backstage/plugin-permission-node@npm:^0.8.5": version: 0.8.5 resolution: "@backstage/plugin-permission-node@npm:0.8.5" @@ -4584,6 +4735,24 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-permission-node@npm:^0.9.1": + version: 0.9.1 + resolution: "@backstage/plugin-permission-node@npm:0.9.1" + dependencies: + "@backstage/backend-plugin-api": "npm:^1.3.0" + "@backstage/config": "npm:^1.3.2" + "@backstage/errors": "npm:^1.2.7" + "@backstage/plugin-auth-node": "npm:^0.6.2" + "@backstage/plugin-permission-common": "npm:^0.8.4" + "@types/express": "npm:^4.17.6" + express: "npm:^4.17.1" + express-promise-router: "npm:^4.1.0" + zod: "npm:^3.22.4" + zod-to-json-schema: "npm:^3.20.4" + checksum: 10c0/29fcbffc61f5466e5b2babe0a7aca0bea1dd920009518ceab76ada99fa953a44e2ce4cd820411e990df9da402c3b5b725173b92643f0dcac306d050deef8a648 + languageName: node + linkType: hard + "@backstage/plugin-permission-react@npm:^0.4.28": version: 0.4.28 resolution: "@backstage/plugin-permission-react@npm:0.4.28" @@ -5400,6 +5569,70 @@ __metadata: languageName: node linkType: hard +"@backstage/repo-tools@npm:^0.13.2": + version: 0.13.2 + resolution: "@backstage/repo-tools@npm:0.13.2" + dependencies: + "@apidevtools/swagger-parser": "npm:^10.1.0" + "@apisyouwonthate/style-guide": "npm:^1.4.0" + "@backstage/backend-plugin-api": "npm:^1.3.0" + "@backstage/catalog-model": "npm:^1.7.3" + "@backstage/cli-common": "npm:^0.1.15" + "@backstage/cli-node": "npm:^0.2.13" + "@backstage/config-loader": "npm:^1.10.0" + "@backstage/errors": "npm:^1.2.7" + "@electric-sql/pglite": "npm:^0.2.15" + "@manypkg/get-packages": "npm:^1.1.3" + "@microsoft/api-documenter": "npm:^7.25.7" + "@microsoft/api-extractor": "npm:^7.47.2" + "@openapitools/openapi-generator-cli": "npm:^2.7.0" + "@stoplight/spectral-core": "npm:^1.18.0" + "@stoplight/spectral-formatters": "npm:^1.1.0" + "@stoplight/spectral-functions": "npm:^1.7.2" + "@stoplight/spectral-parsers": "npm:^1.0.2" + "@stoplight/spectral-rulesets": "npm:^1.18.0" + "@stoplight/spectral-runtime": "npm:^1.1.2" + "@stoplight/types": "npm:^14.0.0" + "@useoptic/openapi-utilities": "npm:^0.55.0" + chalk: "npm:^4.0.0" + chokidar: "npm:^3.5.3" + codeowners-utils: "npm:^1.0.2" + command-exists: "npm:^1.2.9" + commander: "npm:^12.0.0" + fs-extra: "npm:^11.2.0" + glob: "npm:^8.0.3" + is-glob: "npm:^4.0.3" + js-yaml: "npm:^4.1.0" + just-diff: "npm:^6.0.2" + knex: "npm:^3.0.0" + knex-pglite: "npm:^0.11.0" + knip: "npm:^5.42.0" + lodash: "npm:^4.17.21" + minimatch: "npm:^9.0.0" + p-limit: "npm:^3.0.2" + portfinder: "npm:^1.0.32" + tar: "npm:^6.1.12" + ts-morph: "npm:^24.0.0" + yaml-diff-patch: "npm:^2.0.0" + peerDependencies: + "@microsoft/api-extractor-model": "*" + "@microsoft/tsdoc": "*" + "@microsoft/tsdoc-config": "*" + "@useoptic/optic": ^1.0.0 + prettier: ^2.8.1 + typedoc: ^0.27.0 + typescript: "> 3.0.0" + peerDependenciesMeta: + prettier: + optional: true + typedoc: + optional: true + bin: + backstage-repo-tools: bin/backstage-repo-tools + checksum: 10c0/d844b123bc1c8a4523230cf29a7bf64300b2e1bc3784ce16406065c0685e703c734011ee0f297c6bcbfa689f4ca5a58a80ce5083f5b0697c5402ca4548249904 + languageName: node + linkType: hard + "@backstage/test-utils@npm:^1.7.1, @backstage/test-utils@npm:^1.7.2": version: 1.7.2 resolution: "@backstage/test-utils@npm:1.7.2" @@ -5459,6 +5692,13 @@ __metadata: languageName: node linkType: hard +"@backstage/types@npm:^1.2.1": + version: 1.2.1 + resolution: "@backstage/types@npm:1.2.1" + checksum: 10c0/e7ed5ee0c4e6afa997a3885b7851ce51fc8c1c99cec98a2724da79dbc626f3f9055c5c72f097a2e2f762293e74ecd6b5d30617c27c3b27aa9a63a436f07b576d + languageName: node + linkType: hard + "@backstage/version-bridge@npm:^1.0.10": version: 1.0.10 resolution: "@backstage/version-bridge@npm:1.0.10" @@ -5890,6 +6130,41 @@ __metadata: languageName: node linkType: hard +"@electric-sql/pglite@npm:^0.2.14, @electric-sql/pglite@npm:^0.2.15": + version: 0.2.17 + resolution: "@electric-sql/pglite@npm:0.2.17" + checksum: 10c0/4358eccb2a3de5148b8995c7dbf3cad2d80a2a193885838ec19e0381ca204c0e37f721d006ad23fcad0b694ec6089a6786b82f2ad87f18344c82e059ff37017f + languageName: node + linkType: hard + +"@emnapi/core@npm:^1.4.0": + version: 1.4.3 + resolution: "@emnapi/core@npm:1.4.3" + dependencies: + "@emnapi/wasi-threads": "npm:1.0.2" + tslib: "npm:^2.4.0" + checksum: 10c0/e30101d16d37ef3283538a35cad60e22095aff2403fb9226a35330b932eb6740b81364d525537a94eb4fb51355e48ae9b10d779c0dd1cdcd55d71461fe4b45c7 + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.4.0": + version: 1.4.3 + resolution: "@emnapi/runtime@npm:1.4.3" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/3b7ab72d21cb4e034f07df80165265f85f445ef3f581d1bc87b67e5239428baa00200b68a7d5e37a0425c3a78320b541b07f76c5530f6f6f95336a6294ebf30b + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.0.2": + version: 1.0.2 + resolution: "@emnapi/wasi-threads@npm:1.0.2" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/f0621b1fc715221bd2d8332c0ca922617bcd77cdb3050eae50a124eb8923c54fa425d23982dc8f29d505c8798a62d1049bace8b0686098ff9dd82270e06d772e + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.13.5": version: 11.13.5 resolution: "@emotion/babel-plugin@npm:11.13.5" @@ -7646,30 +7921,29 @@ __metadata: languageName: node linkType: hard -"@kusion/backstage-plugin-scaffolder-backend-module-kusion@npm:^0.1.0, @kusion/backstage-plugin-scaffolder-backend-module-kusion@workspace:plugins/scaffolder-backend-module-kusion": +"@kusionstack/kusion-api-client-sdk@npm:^1.1.5": + version: 1.1.5 + resolution: "@kusionstack/kusion-api-client-sdk@npm:1.1.5" + dependencies: + "@hey-api/client-fetch": "npm:^0.5.2" + checksum: 10c0/f1c8d734f0b753a746462cddbaa47bbe4c6cfc10636816f8ab6753b2221eb34705890ce801a53b3d7ff8ce41c0c13c9666650ff2e9c35a425b603853f1936b0c + languageName: node + linkType: hard + +"@kusionstack/plugin-scaffolder-backend-module-kusion@npm:^0.0.0, @kusionstack/plugin-scaffolder-backend-module-kusion@workspace:plugins/scaffolder-backend-module-kusion": version: 0.0.0-use.local - resolution: "@kusion/backstage-plugin-scaffolder-backend-module-kusion@workspace:plugins/scaffolder-backend-module-kusion" + resolution: "@kusionstack/plugin-scaffolder-backend-module-kusion@workspace:plugins/scaffolder-backend-module-kusion" dependencies: "@backstage/backend-plugin-api": "npm:^1.0.2" "@backstage/cli": "npm:^0.29.0" "@backstage/config": "npm:^1.3.0" "@backstage/plugin-scaffolder-node": "npm:^0.6.0" "@backstage/plugin-scaffolder-node-test-utils": "npm:^0.1.15" - "@kusionstack/kusion-api-client-sdk": "npm:^1.1.3" - node-fetch: "npm:^2.7.0" + "@kusionstack/kusion-api-client-sdk": "npm:^1.1.5" yaml: "npm:^2.6.1" languageName: unknown linkType: soft -"@kusionstack/kusion-api-client-sdk@npm:^1.1.3": - version: 1.1.3 - resolution: "@kusionstack/kusion-api-client-sdk@npm:1.1.3" - dependencies: - "@hey-api/client-fetch": "npm:^0.5.2" - checksum: 10c0/c6e641f5c37ff230d45fd4dfd98015f8f2d77fbb176fe9739cf5858363663f7f71ff4c938edf8a28b66e7f6b5febc7f8306098380fbd90b5d4fe4c32f777f607 - languageName: node - linkType: hard - "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.5 resolution: "@leichtgewicht/ip-codec@npm:2.0.5" @@ -7702,6 +7976,13 @@ __metadata: languageName: node linkType: hard +"@lukeed/csprng@npm:^1.0.0": + version: 1.1.0 + resolution: "@lukeed/csprng@npm:1.1.0" + checksum: 10c0/5d6dcf478af732972083ab2889c294b57f1028fa13c2c240d7a4aaa079c2c75df7ef0dcbdda5419147fc6704b4adf96b2de92f1a9a72ac21c6350c4014fffe6c + languageName: node + linkType: hard + "@manypkg/find-root@npm:^1.1.0": version: 1.1.0 resolution: "@manypkg/find-root@npm:1.1.0" @@ -7926,6 +8207,57 @@ __metadata: languageName: node linkType: hard +"@microsoft/api-documenter@npm:^7.25.7": + version: 7.26.27 + resolution: "@microsoft/api-documenter@npm:7.26.27" + dependencies: + "@microsoft/api-extractor-model": "npm:7.30.6" + "@microsoft/tsdoc": "npm:~0.15.1" + "@rushstack/node-core-library": "npm:5.13.1" + "@rushstack/terminal": "npm:0.15.3" + "@rushstack/ts-command-line": "npm:5.0.1" + js-yaml: "npm:~3.13.1" + resolve: "npm:~1.22.1" + bin: + api-documenter: bin/api-documenter + checksum: 10c0/21a5193be73890e3c8515e1c0736aad50d33fe9ec038505bc81658edaee44120cdd1fd08110717c54ec0426941726602189c39b56f9e9899c020587efef56617 + languageName: node + linkType: hard + +"@microsoft/api-extractor-model@npm:7.30.6": + version: 7.30.6 + resolution: "@microsoft/api-extractor-model@npm:7.30.6" + dependencies: + "@microsoft/tsdoc": "npm:~0.15.1" + "@microsoft/tsdoc-config": "npm:~0.17.1" + "@rushstack/node-core-library": "npm:5.13.1" + checksum: 10c0/a2f6d01302f9e97e3100eb338e66ea2efd63742f81863cf69b616dbd2804ac47a1f988b6e5b8e2a836fb9f0be39eba3972d68c3654bfadd54339efb56d1c0643 + languageName: node + linkType: hard + +"@microsoft/api-extractor@npm:^7.47.2": + version: 7.52.8 + resolution: "@microsoft/api-extractor@npm:7.52.8" + dependencies: + "@microsoft/api-extractor-model": "npm:7.30.6" + "@microsoft/tsdoc": "npm:~0.15.1" + "@microsoft/tsdoc-config": "npm:~0.17.1" + "@rushstack/node-core-library": "npm:5.13.1" + "@rushstack/rig-package": "npm:0.5.3" + "@rushstack/terminal": "npm:0.15.3" + "@rushstack/ts-command-line": "npm:5.0.1" + lodash: "npm:~4.17.15" + minimatch: "npm:~3.0.3" + resolve: "npm:~1.22.1" + semver: "npm:~7.5.4" + source-map: "npm:~0.6.1" + typescript: "npm:5.8.2" + bin: + api-extractor: bin/api-extractor + checksum: 10c0/42f4335ebf27c7fa819a858378062d774e130dda109f001825d49fd284430c62ea9eb703a8c49a9dd8e3a607bbf19ba4457548353282673e7429e0e6d01b325b + languageName: node + linkType: hard + "@microsoft/fetch-event-source@npm:^2.0.1": version: 2.0.1 resolution: "@microsoft/fetch-event-source@npm:2.0.1" @@ -7933,6 +8265,25 @@ __metadata: languageName: node linkType: hard +"@microsoft/tsdoc-config@npm:~0.17.1": + version: 0.17.1 + resolution: "@microsoft/tsdoc-config@npm:0.17.1" + dependencies: + "@microsoft/tsdoc": "npm:0.15.1" + ajv: "npm:~8.12.0" + jju: "npm:~1.4.0" + resolve: "npm:~1.22.2" + checksum: 10c0/a686355796f492f27af17e2a17d615221309caf4d9f9047a5a8f17f8625c467c4c81e2a7923ddafd71b892631d5e5013c4b8cc49c5867d3cc1d260fd90c1413d + languageName: node + linkType: hard + +"@microsoft/tsdoc@npm:0.15.1, @microsoft/tsdoc@npm:~0.15.1": + version: 0.15.1 + resolution: "@microsoft/tsdoc@npm:0.15.1" + checksum: 10c0/09948691fac56c45a0d1920de478d66a30371a325bd81addc92eea5654d95106ce173c440fea1a1bd5bb95b3a544b6d4def7bb0b5a846c05d043575d8369a20c + languageName: node + linkType: hard + "@module-federation/bridge-react-webpack-plugin@npm:0.7.7": version: 0.7.7 resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.7.7" @@ -8330,6 +8681,79 @@ __metadata: languageName: node linkType: hard +"@napi-rs/wasm-runtime@npm:^0.2.9": + version: 0.2.9 + resolution: "@napi-rs/wasm-runtime@npm:0.2.9" + dependencies: + "@emnapi/core": "npm:^1.4.0" + "@emnapi/runtime": "npm:^1.4.0" + "@tybys/wasm-util": "npm:^0.9.0" + checksum: 10c0/1cc40b854b255f84e12ade634456ba489f6bf90659ef8164a16823c515c294024c96ee2bb81ab51f35493ba9496f62842b960f915dbdcdc1791f221f989e9e59 + languageName: node + linkType: hard + +"@nestjs/axios@npm:4.0.0": + version: 4.0.0 + resolution: "@nestjs/axios@npm:4.0.0" + peerDependencies: + "@nestjs/common": ^10.0.0 || ^11.0.0 + axios: ^1.3.1 + rxjs: ^7.0.0 + checksum: 10c0/2def06621bd26ab422f2279c7470c5f6369c6abe5d6e5b9ab89614fb2b4ff1d0a725319cc2a46655a476e1ea411bf436db275c66f4c225de32345344afe410ba + languageName: node + linkType: hard + +"@nestjs/common@npm:11.0.20": + version: 11.0.20 + resolution: "@nestjs/common@npm:11.0.20" + dependencies: + file-type: "npm:20.4.1" + iterare: "npm:1.2.1" + load-esm: "npm:1.0.2" + tslib: "npm:2.8.1" + uid: "npm:2.0.2" + peerDependencies: + class-transformer: "*" + class-validator: "*" + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + checksum: 10c0/f60b7f5a15b8371e4a167e1393129f02111f5b7ee248280be9d7851fb294bbe958d998f14c6ba4d18152f671ac9172be72d64f6168edb5967c8ea12bf0310aeb + languageName: node + linkType: hard + +"@nestjs/core@npm:11.0.20": + version: 11.0.20 + resolution: "@nestjs/core@npm:11.0.20" + dependencies: + "@nuxt/opencollective": "npm:0.4.1" + fast-safe-stringify: "npm:2.1.1" + iterare: "npm:1.2.1" + path-to-regexp: "npm:8.2.0" + tslib: "npm:2.8.1" + uid: "npm:2.0.2" + peerDependencies: + "@nestjs/common": ^11.0.0 + "@nestjs/microservices": ^11.0.0 + "@nestjs/platform-express": ^11.0.0 + "@nestjs/websockets": ^11.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + "@nestjs/microservices": + optional: true + "@nestjs/platform-express": + optional: true + "@nestjs/websockets": + optional: true + checksum: 10c0/6d823fe897c23db43e1a77c85ca98863d8e52d072516830bef9f46e78575c6646b538af87ad651e03fe79ee80d37e1f1883c20cdb504176a73bb8eec0d48da7f + languageName: node + linkType: hard + "@node-saml/node-saml@npm:^5.0.0": version: 5.0.0 resolution: "@node-saml/node-saml@npm:5.0.0" @@ -8413,6 +8837,30 @@ __metadata: languageName: node linkType: hard +"@nuxt/opencollective@npm:0.4.1": + version: 0.4.1 + resolution: "@nuxt/opencollective@npm:0.4.1" + dependencies: + consola: "npm:^3.2.3" + bin: + opencollective: bin/opencollective.js + checksum: 10c0/ef2835d8635d2928152eff8b5a1ec42c145e2ab00cb02ff4bb61f0a6f5528afc9b169c06c32308c783779fe26855ebc67419743046caa80e582e814cff73187d + languageName: node + linkType: hard + +"@nuxtjs/opencollective@npm:0.3.2": + version: 0.3.2 + resolution: "@nuxtjs/opencollective@npm:0.3.2" + dependencies: + chalk: "npm:^4.1.0" + consola: "npm:^2.15.0" + node-fetch: "npm:^2.6.1" + bin: + opencollective: bin/opencollective.js + checksum: 10c0/540268687af3289ff107585484d42201b404cdbb98b3a512487c12a6b180a8f0e1df0d701df47d3d9e0d5c0f6eb3252d80535562aedca9edf52cf7fd17ae4601 + languageName: node + linkType: hard + "@octokit/app@npm:^14.0.2": version: 14.1.0 resolution: "@octokit/app@npm:14.1.0" @@ -9174,6 +9622,34 @@ __metadata: languageName: node linkType: hard +"@openapitools/openapi-generator-cli@npm:^2.7.0": + version: 2.20.0 + resolution: "@openapitools/openapi-generator-cli@npm:2.20.0" + dependencies: + "@nestjs/axios": "npm:4.0.0" + "@nestjs/common": "npm:11.0.20" + "@nestjs/core": "npm:11.0.20" + "@nuxtjs/opencollective": "npm:0.3.2" + axios: "npm:1.8.4" + chalk: "npm:4.1.2" + commander: "npm:8.3.0" + compare-versions: "npm:4.1.4" + concurrently: "npm:6.5.1" + console.table: "npm:0.10.0" + fs-extra: "npm:11.3.0" + glob: "npm:9.3.5" + inquirer: "npm:8.2.6" + lodash: "npm:4.17.21" + proxy-agent: "npm:6.5.0" + reflect-metadata: "npm:0.2.2" + rxjs: "npm:7.8.2" + tslib: "npm:2.8.1" + bin: + openapi-generator-cli: main.js + checksum: 10c0/919cba99b76e3a67f5fc0ff23e2d5104c5ac77180b1119727beefe7130717fe6cd54664c874762f3ebabdc6289b9d3ef77030330c93f7098199e3d4c8735242a + languageName: node + linkType: hard + "@opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0": version: 1.9.0 resolution: "@opentelemetry/api@npm:1.9.0" @@ -9181,6 +9657,99 @@ __metadata: languageName: node linkType: hard +"@oxc-resolver/binding-darwin-arm64@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-darwin-arm64@npm:9.0.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@oxc-resolver/binding-darwin-x64@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-darwin-x64@npm:9.0.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@oxc-resolver/binding-freebsd-x64@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-freebsd-x64@npm:9.0.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-arm-gnueabihf@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-arm-gnueabihf@npm:9.0.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-arm64-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-arm64-gnu@npm:9.0.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-arm64-musl@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-arm64-musl@npm:9.0.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-riscv64-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-riscv64-gnu@npm:9.0.2" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-s390x-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-s390x-gnu@npm:9.0.2" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-x64-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-x64-gnu@npm:9.0.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-x64-musl@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-x64-musl@npm:9.0.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@oxc-resolver/binding-wasm32-wasi@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-wasm32-wasi@npm:9.0.2" + dependencies: + "@napi-rs/wasm-runtime": "npm:^0.2.9" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@oxc-resolver/binding-win32-arm64-msvc@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-win32-arm64-msvc@npm:9.0.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@oxc-resolver/binding-win32-x64-msvc@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-win32-x64-msvc@npm:9.0.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -10173,6 +10742,64 @@ __metadata: languageName: node linkType: hard +"@rushstack/node-core-library@npm:5.13.1": + version: 5.13.1 + resolution: "@rushstack/node-core-library@npm:5.13.1" + dependencies: + ajv: "npm:~8.13.0" + ajv-draft-04: "npm:~1.0.0" + ajv-formats: "npm:~3.0.1" + fs-extra: "npm:~11.3.0" + import-lazy: "npm:~4.0.0" + jju: "npm:~1.4.0" + resolve: "npm:~1.22.1" + semver: "npm:~7.5.4" + peerDependencies: + "@types/node": "*" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/e3d31c876390040235e0aae9e458a6b7214cb4385fd743adb49b8408911e7d662761d745276d4ff10c09a9b47b55a3a01690c4800f4b775d82b7c991b3de25d2 + languageName: node + linkType: hard + +"@rushstack/rig-package@npm:0.5.3": + version: 0.5.3 + resolution: "@rushstack/rig-package@npm:0.5.3" + dependencies: + resolve: "npm:~1.22.1" + strip-json-comments: "npm:~3.1.1" + checksum: 10c0/ef0b0115b60007f965b875f671019ac7fc26592f6bf7d7b40fa8c68e8dc37e9f7dcda3b5533b489ebf04d28a182dc60987bfd365a8d4173c73d482b270647741 + languageName: node + linkType: hard + +"@rushstack/terminal@npm:0.15.3": + version: 0.15.3 + resolution: "@rushstack/terminal@npm:0.15.3" + dependencies: + "@rushstack/node-core-library": "npm:5.13.1" + supports-color: "npm:~8.1.1" + peerDependencies: + "@types/node": "*" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/3e8be5168aea2224261fce071808948d63790fa9d9fb2dfb2a659e616b4b9ce513ebc4cf211d528322987b75fc83482e8e0a7c1e262077e271ef887a5b56f5aa + languageName: node + linkType: hard + +"@rushstack/ts-command-line@npm:5.0.1": + version: 5.0.1 + resolution: "@rushstack/ts-command-line@npm:5.0.1" + dependencies: + "@rushstack/terminal": "npm:0.15.3" + "@types/argparse": "npm:1.0.38" + argparse: "npm:~1.0.9" + string-argv: "npm:~0.3.1" + checksum: 10c0/9f4ffe63d5eaa9bda2b026c68e62a99f6c1d6d8ad3cc7a4247d6cd90f2fdf038ca9e950911f8035f9cb408a54abcd049ba5435206f63f98fb8df484488debd83 + languageName: node + linkType: hard + "@sagold/json-pointer@npm:^5.1.2": version: 5.1.2 resolution: "@sagold/json-pointer@npm:5.1.2" @@ -10957,6 +11584,35 @@ __metadata: languageName: node linkType: hard +"@stoplight/spectral-core@npm:^1.18.0": + version: 1.20.0 + resolution: "@stoplight/spectral-core@npm:1.20.0" + dependencies: + "@stoplight/better-ajv-errors": "npm:1.0.3" + "@stoplight/json": "npm:~3.21.0" + "@stoplight/path": "npm:1.3.2" + "@stoplight/spectral-parsers": "npm:^1.0.0" + "@stoplight/spectral-ref-resolver": "npm:^1.0.4" + "@stoplight/spectral-runtime": "npm:^1.1.2" + "@stoplight/types": "npm:~13.6.0" + "@types/es-aggregate-error": "npm:^1.0.2" + "@types/json-schema": "npm:^7.0.11" + ajv: "npm:^8.17.1" + ajv-errors: "npm:~3.0.0" + ajv-formats: "npm:~2.1.1" + es-aggregate-error: "npm:^1.0.7" + jsonpath-plus: "npm:^10.3.0" + lodash: "npm:~4.17.21" + lodash.topath: "npm:^4.5.2" + minimatch: "npm:3.1.2" + nimma: "npm:0.2.3" + pony-cause: "npm:^1.1.1" + simple-eval: "npm:1.0.1" + tslib: "npm:^2.8.1" + checksum: 10c0/ebf6adeefded181b7c220a6cae70ebed37aa9e2ca73d9bd386d7e4c2bef965aea154fd6bb7613c822d37ae3440745fe1408c1369a11475e1050fcb986e64b63a + languageName: node + linkType: hard + "@stoplight/spectral-core@npm:^1.18.3, @stoplight/spectral-core@npm:^1.19.2, @stoplight/spectral-core@npm:^1.19.4": version: 1.19.4 resolution: "@stoplight/spectral-core@npm:1.19.4" @@ -10986,7 +11642,7 @@ __metadata: languageName: node linkType: hard -"@stoplight/spectral-formats@npm:^1.8.1": +"@stoplight/spectral-formats@npm:^1.2.0, @stoplight/spectral-formats@npm:^1.8.1": version: 1.8.2 resolution: "@stoplight/spectral-formats@npm:1.8.2" dependencies: @@ -10998,6 +11654,46 @@ __metadata: languageName: node linkType: hard +"@stoplight/spectral-formatters@npm:^1.1.0": + version: 1.5.0 + resolution: "@stoplight/spectral-formatters@npm:1.5.0" + dependencies: + "@stoplight/path": "npm:^1.3.2" + "@stoplight/spectral-core": "npm:^1.19.4" + "@stoplight/spectral-runtime": "npm:^1.1.2" + "@stoplight/types": "npm:^13.15.0" + "@types/markdown-escape": "npm:^1.1.3" + chalk: "npm:4.1.2" + cliui: "npm:7.0.4" + lodash: "npm:^4.17.21" + markdown-escape: "npm:^2.0.0" + node-sarif-builder: "npm:^2.0.3" + strip-ansi: "npm:6.0" + text-table: "npm:^0.2.0" + tslib: "npm:^2.8.1" + checksum: 10c0/dee8e0a2f4a47c2e318e8af09e3b64ed86e5ecb5c652f8117db25857ba6b32b5cd34ae0db1ae7e2eb098ee79a73e5aff0fa184a4eba7dcc887ae6ff8cf285543 + languageName: node + linkType: hard + +"@stoplight/spectral-functions@npm:^1.6.1, @stoplight/spectral-functions@npm:^1.9.1": + version: 1.10.1 + resolution: "@stoplight/spectral-functions@npm:1.10.1" + dependencies: + "@stoplight/better-ajv-errors": "npm:1.0.3" + "@stoplight/json": "npm:^3.17.1" + "@stoplight/spectral-core": "npm:^1.19.4" + "@stoplight/spectral-formats": "npm:^1.8.1" + "@stoplight/spectral-runtime": "npm:^1.1.2" + ajv: "npm:^8.17.1" + ajv-draft-04: "npm:~1.0.0" + ajv-errors: "npm:~3.0.0" + ajv-formats: "npm:~2.1.1" + lodash: "npm:~4.17.21" + tslib: "npm:^2.8.1" + checksum: 10c0/f26af18a8ff107f5d49a86e4134f10d244fc9bc64833b92c487d1372740b2b3839a72bb76d2061320f33498e65c2704aba5062635ec4c24c16139a4cf83497ca + languageName: node + linkType: hard + "@stoplight/spectral-functions@npm:^1.7.2": version: 1.9.3 resolution: "@stoplight/spectral-functions@npm:1.9.3" @@ -11042,6 +11738,29 @@ __metadata: languageName: node linkType: hard +"@stoplight/spectral-rulesets@npm:^1.18.0": + version: 1.22.0 + resolution: "@stoplight/spectral-rulesets@npm:1.22.0" + dependencies: + "@asyncapi/specs": "npm:^6.8.0" + "@stoplight/better-ajv-errors": "npm:1.0.3" + "@stoplight/json": "npm:^3.17.0" + "@stoplight/spectral-core": "npm:^1.19.4" + "@stoplight/spectral-formats": "npm:^1.8.1" + "@stoplight/spectral-functions": "npm:^1.9.1" + "@stoplight/spectral-runtime": "npm:^1.1.2" + "@stoplight/types": "npm:^13.6.0" + "@types/json-schema": "npm:^7.0.7" + ajv: "npm:^8.17.1" + ajv-formats: "npm:~2.1.1" + json-schema-traverse: "npm:^1.0.0" + leven: "npm:3.1.0" + lodash: "npm:~4.17.21" + tslib: "npm:^2.8.1" + checksum: 10c0/9a19bc55ee4f800089f943ff0cb5f8c3902b689060c2b2b9de0c298cc5e8e9baa74767c218c3fa037483470fb10268c4d70d48ba7513b293ad184126459ebc71 + languageName: node + linkType: hard + "@stoplight/spectral-runtime@npm:^1.1.2": version: 1.1.3 resolution: "@stoplight/spectral-runtime@npm:1.1.3" @@ -11057,7 +11776,7 @@ __metadata: languageName: node linkType: hard -"@stoplight/types@npm:^12.3.0 || ^13.0.0, @stoplight/types@npm:^13.12.0, @stoplight/types@npm:^13.6.0": +"@stoplight/types@npm:^12.3.0 || ^13.0.0, @stoplight/types@npm:^13.12.0, @stoplight/types@npm:^13.15.0, @stoplight/types@npm:^13.6.0": version: 13.20.0 resolution: "@stoplight/types@npm:13.20.0" dependencies: @@ -11067,7 +11786,7 @@ __metadata: languageName: node linkType: hard -"@stoplight/types@npm:^14.1.1": +"@stoplight/types@npm:^14.0.0, @stoplight/types@npm:^14.1.1": version: 14.1.1 resolution: "@stoplight/types@npm:14.1.1" dependencies: @@ -12040,6 +12759,17 @@ __metadata: languageName: node linkType: hard +"@tokenizer/inflate@npm:^0.2.6": + version: 0.2.7 + resolution: "@tokenizer/inflate@npm:0.2.7" + dependencies: + debug: "npm:^4.4.0" + fflate: "npm:^0.8.2" + token-types: "npm:^6.0.0" + checksum: 10c0/75bd0c510810dfd62be9d963216b5852cde021e1f8aab43b37662bc6aa75e65fd7277fcab7d463186b55cee36a5b61129916161bdb2a7d18064016156c7daf4f + languageName: node + linkType: hard + "@tokenizer/token@npm:^0.3.0": version: 0.3.0 resolution: "@tokenizer/token@npm:0.3.0" @@ -12135,6 +12865,22 @@ __metadata: languageName: node linkType: hard +"@tybys/wasm-util@npm:^0.9.0": + version: 0.9.0 + resolution: "@tybys/wasm-util@npm:0.9.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/f9fde5c554455019f33af6c8215f1a1435028803dc2a2825b077d812bed4209a1a64444a4ca0ce2ea7e1175c8d88e2f9173a36a33c199e8a5c671aa31de8242d + languageName: node + linkType: hard + +"@types/argparse@npm:1.0.38": + version: 1.0.38 + resolution: "@types/argparse@npm:1.0.38" + checksum: 10c0/4fc892da5df16923f48180da2d1f4562fa8b0507cf636b24780444fa0a1d7321d4dc0c0ecbee6152968823f5a2ae0d321b4f8c705a489bf1ae1245bdeb0868fd + languageName: node + linkType: hard + "@types/aria-query@npm:^5.0.1": version: 5.0.4 resolution: "@types/aria-query@npm:5.0.4" @@ -12594,6 +13340,13 @@ __metadata: languageName: node linkType: hard +"@types/markdown-escape@npm:^1.1.3": + version: 1.1.3 + resolution: "@types/markdown-escape@npm:1.1.3" + checksum: 10c0/fff3f902327bb0a36b06f6dbc5fafe478d917964084f87f109f2a90cd06722fa9ecf556f56efa4a78d64764b7b6590a2864a5fc0165091cf9ffceed222721162 + languageName: node + linkType: hard + "@types/mdast@npm:^3.0.0": version: 3.0.15 resolution: "@types/mdast@npm:3.0.15" @@ -12848,6 +13601,13 @@ __metadata: languageName: node linkType: hard +"@types/sarif@npm:^2.1.4": + version: 2.1.7 + resolution: "@types/sarif@npm:2.1.7" + checksum: 10c0/983d593735c42b288c3d95bb1655b036652438d267eecb2cd5d0f8c613ac98ae198eb7828dc171776e64a6ebe93e88c920ec9b80cf3c780e015e081ac5d26c01 + languageName: node + linkType: hard + "@types/semver@npm:7.5.8, @types/semver@npm:^7.5.0": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" @@ -13303,6 +14063,41 @@ __metadata: languageName: node linkType: hard +"@useoptic/json-pointer-helpers@npm:0.55.1": + version: 0.55.1 + resolution: "@useoptic/json-pointer-helpers@npm:0.55.1" + dependencies: + jsonpointer: "npm:^5.0.1" + minimatch: "npm:9.0.3" + checksum: 10c0/6d1d20b2f34e2225fbeba2a8c86918abdf7fde66e1157094de59713084db6dc10822f8fbb3938182b3ee89a5a2f6a677045d797030ca331b459b9f04dac49c0e + languageName: node + linkType: hard + +"@useoptic/openapi-utilities@npm:^0.55.0": + version: 0.55.1 + resolution: "@useoptic/openapi-utilities@npm:0.55.1" + dependencies: + "@useoptic/json-pointer-helpers": "npm:0.55.1" + ajv: "npm:^8.6.0" + ajv-errors: "npm:~3.0.0" + ajv-formats: "npm:~2.1.0" + chalk: "npm:^4.1.2" + fast-deep-equal: "npm:^3.1.3" + is-url: "npm:^1.2.4" + js-yaml: "npm:^4.1.0" + json-stable-stringify: "npm:^1.0.1" + lodash.groupby: "npm:^4.6.0" + lodash.isequal: "npm:^4.5.0" + lodash.omit: "npm:^4.5.0" + node-machine-id: "npm:^1.1.12" + openapi-types: "npm:^12.0.2" + ts-invariant: "npm:^0.9.3" + url-join: "npm:^4.0.1" + yaml-ast-parser: "npm:^0.0.43" + checksum: 10c0/e23239b0520827058724455a00bb5c053f8c56ce1206af64a43c70346a0f7278a1d2529c74722985e8172f368d69611dd1bf5c930dd52229d7fe3a57cd612212 + languageName: node + linkType: hard + "@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.12.1": version: 1.14.1 resolution: "@webassemblyjs/ast@npm:1.14.1" @@ -13647,6 +14442,13 @@ __metadata: languageName: node linkType: hard +"agent-base@npm:^7.1.2": + version: 7.1.3 + resolution: "agent-base@npm:7.1.3" + checksum: 10c0/6192b580c5b1d8fb399b9c62bf8343d76654c2dd62afcb9a52b2cf44a8b6ace1e3b704d3fe3547d91555c857d3df02603341ff2cb961b9cfe2b12f9f3c38ee11 + languageName: node + linkType: hard + "agentkeepalive@npm:^4.1.4": version: 4.5.0 resolution: "agentkeepalive@npm:4.5.0" @@ -13701,7 +14503,7 @@ __metadata: languageName: node linkType: hard -"ajv-formats@npm:^2.1.1, ajv-formats@npm:~2.1.0": +"ajv-formats@npm:^2.1.1, ajv-formats@npm:~2.1.0, ajv-formats@npm:~2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" dependencies: @@ -13715,6 +14517,20 @@ __metadata: languageName: node linkType: hard +"ajv-formats@npm:~3.0.1": + version: 3.0.1 + resolution: "ajv-formats@npm:3.0.1" + dependencies: + ajv: "npm:^8.0.0" + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 10c0/168d6bca1ea9f163b41c8147bae537e67bd963357a5488a1eaf3abe8baa8eec806d4e45f15b10767e6020679315c7e1e5e6803088dfb84efa2b4e9353b83dd0a + languageName: node + linkType: hard + "ajv-i18n@npm:^4.2.0": version: 4.2.0 resolution: "ajv-i18n@npm:4.2.0" @@ -13756,7 +14572,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.12.0, ajv@npm:^8.16.0, ajv@npm:^8.17.1, ajv@npm:^8.6.3, ajv@npm:^8.9.0": +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.12.0, ajv@npm:^8.16.0, ajv@npm:^8.17.1, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.9.0": version: 8.17.1 resolution: "ajv@npm:8.17.1" dependencies: @@ -13768,6 +14584,30 @@ __metadata: languageName: node linkType: hard +"ajv@npm:~8.12.0": + version: 8.12.0 + resolution: "ajv@npm:8.12.0" + dependencies: + fast-deep-equal: "npm:^3.1.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + uri-js: "npm:^4.2.2" + checksum: 10c0/ac4f72adf727ee425e049bc9d8b31d4a57e1c90da8d28bcd23d60781b12fcd6fc3d68db5df16994c57b78b94eed7988f5a6b482fd376dc5b084125e20a0a622e + languageName: node + linkType: hard + +"ajv@npm:~8.13.0": + version: 8.13.0 + resolution: "ajv@npm:8.13.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + uri-js: "npm:^4.4.1" + checksum: 10c0/14c6497b6f72843986d7344175a1aa0e2c35b1e7f7475e55bc582cddb765fca7e6bf950f465dc7846f817776d9541b706f4b5b3fbedd8dfdeb5fce6f22864264 + languageName: node + linkType: hard + "ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" @@ -13974,7 +14814,7 @@ __metadata: languageName: node linkType: hard -"argparse@npm:^1.0.10, argparse@npm:^1.0.7": +"argparse@npm:^1.0.10, argparse@npm:^1.0.7, argparse@npm:~1.0.9": version: 1.0.10 resolution: "argparse@npm:1.0.10" dependencies: @@ -14361,6 +15201,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:1.8.4": + version: 1.8.4 + resolution: "axios@npm:1.8.4" + dependencies: + follow-redirects: "npm:^1.15.6" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 10c0/450993c2ba975ffccaf0d480b68839a3b2435a5469a71fa2fb0b8a55cdb2c2ae47e609360b9c1e2b2534b73dfd69e2733a1cf9f8215bee0bcd729b72f801b0ce + languageName: node + linkType: hard + "axios@npm:^1.0.0, axios@npm:^1.6.0, axios@npm:^1.7.4": version: 1.7.8 resolution: "axios@npm:1.7.8" @@ -14571,7 +15422,7 @@ __metadata: "@backstage/plugin-search-backend-module-techdocs": "npm:^0.3.2" "@backstage/plugin-search-backend-node": "npm:^1.3.5" "@backstage/plugin-techdocs-backend": "npm:^1.11.2" - "@kusion/backstage-plugin-scaffolder-backend-module-kusion": "npm:^0.1.0" + "@kusionstack/plugin-scaffolder-backend-module-kusion": "npm:^0.0.0" app: "link:../app" better-sqlite3: "npm:^9.0.0" node-gyp: "npm:^10.0.0" @@ -15225,6 +16076,16 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938 + languageName: node + linkType: hard + "call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": version: 1.0.7 resolution: "call-bind@npm:1.0.7" @@ -15238,6 +16099,28 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" + dependencies: + call-bind-apply-helpers: "npm:^1.0.0" + es-define-property: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.2" + checksum: 10c0/a13819be0681d915144467741b69875ae5f4eba8961eb0bf322aab63ec87f8250eb6d6b0dcbb2e1349876412a56129ca338592b3829ef4343527f5f18a0752d4 + languageName: node + linkType: hard + +"call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644 + languageName: node + linkType: hard + "call-me-maybe@npm:^1.0.1": version: 1.0.2 resolution: "call-me-maybe@npm:1.0.2" @@ -15296,9 +16179,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001669": - version: 1.0.30001686 - resolution: "caniuse-lite@npm:1.0.30001686" - checksum: 10c0/41748e81c17c1a6a0fd6e515c93c8620004171fe6706027e45f837fde71e97173e85141b0dc11e07d53b4782f3741a6651cb0f7d395cc1c1860892355eabdfa2 + version: 1.0.30001718 + resolution: "caniuse-lite@npm:1.0.30001718" + checksum: 10c0/67f9ad09bc16443e28d14f265d6e468480cd8dc1900d0d8b982222de80c699c4f2306599c3da8a3fa7139f110d4b30d49dbac78f215470f479abb6ffe141d5d3 languageName: node linkType: hard @@ -15337,7 +16220,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": +"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -15536,7 +16419,7 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^7.0.2": +"cliui@npm:7.0.4, cliui@npm:^7.0.2": version: 7.0.4 resolution: "cliui@npm:7.0.4" dependencies: @@ -15777,6 +16660,20 @@ __metadata: languageName: node linkType: hard +"command-exists@npm:^1.2.9": + version: 1.2.9 + resolution: "command-exists@npm:1.2.9" + checksum: 10c0/75040240062de46cd6cd43e6b3032a8b0494525c89d3962e280dde665103f8cc304a8b313a5aa541b91da2f5a9af75c5959dc3a77893a2726407a5e9a0234c16 + languageName: node + linkType: hard + +"commander@npm:8.3.0, commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 + languageName: node + linkType: hard + "commander@npm:^10.0.0": version: 10.0.1 resolution: "commander@npm:10.0.1" @@ -15819,13 +16716,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^8.3.0": - version: 8.3.0 - resolution: "commander@npm:8.3.0" - checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 - languageName: node - linkType: hard - "common-tags@npm:^1.8.0": version: 1.8.2 resolution: "common-tags@npm:1.8.2" @@ -15840,6 +16730,13 @@ __metadata: languageName: node linkType: hard +"compare-versions@npm:4.1.4": + version: 4.1.4 + resolution: "compare-versions@npm:4.1.4" + checksum: 10c0/cd3b35190bf2173fa6b43e89ba00606267442d0b4baa39bdb4f969839c266877ffc657f56e484d664cd06b7007a224e344c254545bb6e0184257df8272c5a123 + languageName: node + linkType: hard + "compress-commons@npm:^6.0.2": version: 6.0.2 resolution: "compress-commons@npm:6.0.2" @@ -15940,6 +16837,24 @@ __metadata: languageName: node linkType: hard +"concurrently@npm:6.5.1": + version: 6.5.1 + resolution: "concurrently@npm:6.5.1" + dependencies: + chalk: "npm:^4.1.0" + date-fns: "npm:^2.16.1" + lodash: "npm:^4.17.21" + rxjs: "npm:^6.6.3" + spawn-command: "npm:^0.0.2-1" + supports-color: "npm:^8.1.0" + tree-kill: "npm:^1.2.2" + yargs: "npm:^16.2.0" + bin: + concurrently: bin/concurrently.js + checksum: 10c0/4bc2eb5d8fa9a87d2241bc1f7830f5432fd52593944eed162567188f36d1f4219f336f72b5e6afee265547e8be1e54c8c893e5693d3874666a9ce5a7ffe4cc81 + languageName: node + linkType: hard + "connect-history-api-fallback@npm:^2.0.0": version: 2.0.0 resolution: "connect-history-api-fallback@npm:2.0.0" @@ -15969,6 +16884,20 @@ __metadata: languageName: node linkType: hard +"consola@npm:^2.15.0": + version: 2.15.3 + resolution: "consola@npm:2.15.3" + checksum: 10c0/34a337e6b4a1349ee4d7b4c568484344418da8fdb829d7d71bfefcd724f608f273987633b6eef465e8de510929907a092e13cb7a28a5d3acb3be446fcc79fd5e + languageName: node + linkType: hard + +"consola@npm:^3.2.3": + version: 3.4.2 + resolution: "consola@npm:3.4.2" + checksum: 10c0/7cebe57ecf646ba74b300bcce23bff43034ed6fbec9f7e39c27cee1dc00df8a21cd336b466ad32e304ea70fba04ec9e890c200270de9a526ce021ba8a7e4c11a + languageName: node + linkType: hard + "console-browserify@npm:^1.1.0": version: 1.2.0 resolution: "console-browserify@npm:1.2.0" @@ -15976,6 +16905,15 @@ __metadata: languageName: node linkType: hard +"console.table@npm:0.10.0": + version: 0.10.0 + resolution: "console.table@npm:0.10.0" + dependencies: + easy-table: "npm:1.1.0" + checksum: 10c0/b1893a06b422c7e82dca03dec000beabebc26415df558a05e1b9778407a76e4caa1db286df40f72e3780ac5c5b5ef5f4b8a3bef2d22020abb86f6408dc357875 + languageName: node + linkType: hard + "constants-browserify@npm:^1.0.0": version: 1.0.0 resolution: "constants-browserify@npm:1.0.0" @@ -16871,6 +17809,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4.4.0": + version: 4.4.1 + resolution: "debug@npm:4.4.1" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/d2b44bc1afd912b49bb7ebb0d50a860dc93a4dd7d946e8de94abc957bb63726b7dd5aa48c18c2386c379ec024c46692e15ed3ed97d481729f929201e671fcd55 + languageName: node + linkType: hard + "decimal.js@npm:^10.4.2, decimal.js@npm:^10.4.3": version: 10.4.3 resolution: "decimal.js@npm:10.4.3" @@ -17453,6 +18403,17 @@ __metadata: languageName: node linkType: hard +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.2.0" + checksum: 10c0/199f2a0c1c16593ca0a145dbf76a962f8033ce3129f01284d48c45ed4e14fea9bbacd7b3610b6cdc33486cef20385ac054948fefc6272fcce645c09468f93031 + languageName: node + linkType: hard + "duplexer@npm:^0.1.2": version: 0.1.2 resolution: "duplexer@npm:0.1.2" @@ -17491,6 +18452,18 @@ __metadata: languageName: node linkType: hard +"easy-table@npm:1.1.0": + version: 1.1.0 + resolution: "easy-table@npm:1.1.0" + dependencies: + wcwidth: "npm:>=1.0.1" + dependenciesMeta: + wcwidth: + optional: true + checksum: 10c0/0b7b03723e450c8286bd375bbe7d23247456dbb8f79df055adcfd745bfb91f7604c4e78204ff75d65d5229bec8867cbefca51c57938004f487ff800b587540bb + languageName: node + linkType: hard + "ebnf@npm:^1.9.1": version: 1.9.1 resolution: "ebnf@npm:1.9.1" @@ -17767,6 +18740,13 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c + languageName: node + linkType: hard + "es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": version: 1.3.0 resolution: "es-errors@npm:1.3.0" @@ -17830,6 +18810,15 @@ __metadata: languageName: node linkType: hard +"es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.3": version: 2.0.3 resolution: "es-set-tostringtag@npm:2.0.3" @@ -18809,6 +19798,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:^3.3.3": + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.8" + checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe + languageName: node + linkType: hard + "fast-json-parse@npm:^1.0.3": version: 1.0.3 resolution: "fast-json-parse@npm:1.0.3" @@ -18816,7 +19818,7 @@ __metadata: languageName: node linkType: hard -"fast-json-patch@npm:^3.0.0-1, fast-json-patch@npm:^3.1.1": +"fast-json-patch@npm:^3.0.0-1, fast-json-patch@npm:^3.1.0, fast-json-patch@npm:^3.1.1": version: 3.1.1 resolution: "fast-json-patch@npm:3.1.1" checksum: 10c0/8a0438b4818bb53153275fe5b38033610e8c9d9eb11869e6a7dc05eb92fa70f3caa57015e344eb3ae1e71c7a75ad4cc6bc2dc9e0ff281d6ed8ecd44505210ca8 @@ -18860,7 +19862,7 @@ __metadata: languageName: node linkType: hard -"fast-safe-stringify@npm:^2.0.6, fast-safe-stringify@npm:^2.0.7": +"fast-safe-stringify@npm:2.1.1, fast-safe-stringify@npm:^2.0.6, fast-safe-stringify@npm:^2.0.7": version: 2.1.1 resolution: "fast-safe-stringify@npm:2.1.1" checksum: 10c0/d90ec1c963394919828872f21edaa3ad6f1dddd288d2bd4e977027afff09f5db40f94e39536d4646f7e01761d704d72d51dce5af1b93717f3489ef808f5f4e4d @@ -18946,6 +19948,15 @@ __metadata: languageName: node linkType: hard +"fd-package-json@npm:^1.2.0": + version: 1.2.0 + resolution: "fd-package-json@npm:1.2.0" + dependencies: + walk-up-path: "npm:^3.0.1" + checksum: 10c0/712a78a12bd8ec8482867b26bbcb2ff1dca9b096a416150c138e1512f1879c6d23dfb41b03b8e9226afc1e58a35df4738e9f9ae57032ff1dbbae75acfb70343b + languageName: node + linkType: hard + "fdir@npm:^6.4.2": version: 6.4.2 resolution: "fdir@npm:6.4.2" @@ -18965,6 +19976,13 @@ __metadata: languageName: node linkType: hard +"fflate@npm:^0.8.2": + version: 0.8.2 + resolution: "fflate@npm:0.8.2" + checksum: 10c0/03448d630c0a583abea594835a9fdb2aaf7d67787055a761515bf4ed862913cfd693b4c4ffd5c3f3b355a70cf1e19033e9ae5aedcca103188aaff91b8bd6e293 + languageName: node + linkType: hard + "figures@npm:^3.0.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -18983,6 +20001,18 @@ __metadata: languageName: node linkType: hard +"file-type@npm:20.4.1": + version: 20.4.1 + resolution: "file-type@npm:20.4.1" + dependencies: + "@tokenizer/inflate": "npm:^0.2.6" + strtok3: "npm:^10.2.0" + token-types: "npm:^6.0.0" + uint8array-extras: "npm:^1.4.0" + checksum: 10c0/ae6f65e537205a9a3e07ae574de74ed5210aa78899d6478351a466f97e3f17096b93d74cb97f3fce7488bc8486a21e449ab076ec358ed06984f4a9a8f48a9f55 + languageName: node + linkType: hard + "file-type@npm:^16.5.4": version: 16.5.4 resolution: "file-type@npm:16.5.4" @@ -19285,6 +20315,17 @@ __metadata: languageName: node linkType: hard +"formatly@npm:^0.2.3": + version: 0.2.3 + resolution: "formatly@npm:0.2.3" + dependencies: + fd-package-json: "npm:^1.2.0" + bin: + formatly: bin/index.mjs + checksum: 10c0/d63e492b9f281ce68a40baab609536acc6e7e09343e53f261b2203726cebd8db145d329c6bca2f8a494f4e16db3ade6c9d1a62c32c66df170d04fbc82893ceda + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -19343,6 +20384,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:11.3.0, fs-extra@npm:~11.3.0": + version: 11.3.0 + resolution: "fs-extra@npm:11.3.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f95e996186ff45463059feb115a22fb048bdaf7e487ecee8a8646c78ed8fdca63630e3077d4c16ce677051f5e60d3355a06f3cd61f3ca43f48cc58822a44d0a + languageName: node + linkType: hard + "fs-extra@npm:9.1.0, fs-extra@npm:^9.0.0": version: 9.1.0 resolution: "fs-extra@npm:9.1.0" @@ -19570,6 +20622,24 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.3.0": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a + languageName: node + linkType: hard + "get-nonce@npm:^1.0.0": version: 1.0.1 resolution: "get-nonce@npm:1.0.1" @@ -19591,6 +20661,16 @@ __metadata: languageName: node linkType: hard +"get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: "npm:^1.0.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/9224acb44603c5526955e83510b9da41baf6ae73f7398875fba50edc5e944223a89c4a72b070fcd78beb5f7bdda58ecb6294adc28f7acfc0da05f76a2399643c + languageName: node + linkType: hard + "get-stream@npm:^5.1.0": version: 5.2.0 resolution: "get-stream@npm:5.2.0" @@ -19715,6 +20795,18 @@ __metadata: languageName: node linkType: hard +"glob@npm:9.3.5": + version: 9.3.5 + resolution: "glob@npm:9.3.5" + dependencies: + fs.realpath: "npm:^1.0.0" + minimatch: "npm:^8.0.2" + minipass: "npm:^4.2.4" + path-scurry: "npm:^1.6.1" + checksum: 10c0/2f6c2b9ee019ee21dc258ae97a88719614591e4c979cb4580b1b9df6f0f778a3cb38b4bdaf18dfa584637ea10f89a3c5f2533a5e449cf8741514ad18b0951f2e + languageName: node + linkType: hard + "glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1": version: 10.4.5 resolution: "glob@npm:10.4.5" @@ -19745,7 +20837,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.1, glob@npm:^8.1.0": +"glob@npm:^8.0.1, glob@npm:^8.0.3, glob@npm:^8.1.0": version: 8.1.0 resolution: "glob@npm:8.1.0" dependencies: @@ -19899,6 +20991,13 @@ __metadata: languageName: node linkType: hard +"gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead + languageName: node + linkType: hard + "got@npm:^11.8.3": version: 11.8.6 resolution: "got@npm:11.8.6" @@ -20158,7 +21257,7 @@ __metadata: languageName: node linkType: hard -"has-symbols@npm:^1.0.3": +"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": version: 1.1.0 resolution: "has-symbols@npm:1.1.0" checksum: 10c0/dde0a734b17ae51e84b10986e651c664379018d10b91b6b0e9b293eddb32f0f069688c841fb40f19e9611546130153e0a2a48fd7f512891fb000ddfa36f5a20e @@ -20515,7 +21614,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.2": +"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.1, http-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" dependencies: @@ -20626,6 +21725,16 @@ __metadata: languageName: node linkType: hard +"https-proxy-agent@npm:^7.0.6": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:4" + checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac + languageName: node + linkType: hard + "human-id@npm:^4.1.1": version: 4.1.1 resolution: "human-id@npm:4.1.1" @@ -20805,6 +21914,13 @@ __metadata: languageName: node linkType: hard +"import-lazy@npm:~4.0.0": + version: 4.0.0 + resolution: "import-lazy@npm:4.0.0" + checksum: 10c0/a3520313e2c31f25c0b06aa66d167f329832b68a4f957d7c9daf6e0fa41822b6e84948191648b9b9d8ca82f94740cdf15eecf2401a5b42cd1c33fd84f2225cca + languageName: node + linkType: hard + "import-local@npm:^3.0.2": version: 3.2.0 resolution: "import-local@npm:3.2.0" @@ -20878,7 +21994,7 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:^8.2.0": +"inquirer@npm:8.2.6, inquirer@npm:^8.2.0": version: 8.2.6 resolution: "inquirer@npm:8.2.6" dependencies: @@ -21096,6 +22212,15 @@ __metadata: languageName: node linkType: hard +"is-core-module@npm:^2.16.0": + version: 2.16.1 + resolution: "is-core-module@npm:2.16.1" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10c0/898443c14780a577e807618aaae2b6f745c8538eca5c7bc11388a3f2dc6de82b9902bcc7eb74f07be672b11bbe82dd6a6edded44a00cb3d8f933d0459905eedd + languageName: node + linkType: hard + "is-data-view@npm:^1.0.1": version: 1.0.1 resolution: "is-data-view@npm:1.0.1" @@ -21449,6 +22574,13 @@ __metadata: languageName: node linkType: hard +"is-url@npm:^1.2.4": + version: 1.2.4 + resolution: "is-url@npm:1.2.4" + checksum: 10c0/0157a79874f8f95fdd63540e3f38c8583c2ef572661cd0693cda80ae3e42dfe8e9a4a972ec1b827f861d9a9acf75b37f7d58a37f94a8a053259642912c252bc3 + languageName: node + linkType: hard + "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -21697,6 +22829,13 @@ __metadata: languageName: node linkType: hard +"iterare@npm:1.2.1": + version: 1.2.1 + resolution: "iterare@npm:1.2.1" + checksum: 10c0/02667d486e3e83ead028ba8484d927498c2ceab7e8c6a69dd881fd02abc4114f00b13abb36b592252fbb578b6e6f99ca1dfc2835408b9158c9a112a9964f453f + languageName: node + linkType: hard + "iterator.prototype@npm:^1.1.3": version: 1.1.3 resolution: "iterator.prototype@npm:1.1.3" @@ -22212,6 +23351,22 @@ __metadata: languageName: node linkType: hard +"jiti@npm:^2.4.2": + version: 2.4.2 + resolution: "jiti@npm:2.4.2" + bin: + jiti: lib/jiti-cli.mjs + checksum: 10c0/4ceac133a08c8faff7eac84aabb917e85e8257f5ad659e843004ce76e981c457c390a220881748ac67ba1b940b9b729b30fb85cbaf6e7989f04b6002c94da331 + languageName: node + linkType: hard + +"jju@npm:~1.4.0": + version: 1.4.0 + resolution: "jju@npm:1.4.0" + checksum: 10c0/f3f444557e4364cfc06b1abf8331bf3778b26c0c8552ca54429bc0092652172fdea26cbffe33e1017b303d5aa506f7ede8571857400efe459cb7439180e2acad + languageName: node + linkType: hard + "jmespath@npm:^0.15.0": version: 0.15.0 resolution: "jmespath@npm:0.15.0" @@ -22291,6 +23446,18 @@ __metadata: languageName: node linkType: hard +"js-yaml@npm:~3.13.1": + version: 3.13.1 + resolution: "js-yaml@npm:3.13.1" + dependencies: + argparse: "npm:^1.0.7" + esprima: "npm:^4.0.0" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/6a4f78b998d2eb58964cc5e051c031865bf292dc3c156a8057cf468d9e60a8739f4e8f607a267e97f09eb8d08263b8262df57eddb16b920ec5a04a259c3b4960 + languageName: node + linkType: hard + "jsbn@npm:1.1.0": version: 1.1.0 resolution: "jsbn@npm:1.1.0" @@ -22499,6 +23666,19 @@ __metadata: languageName: node linkType: hard +"json-stable-stringify@npm:^1.0.1": + version: 1.3.0 + resolution: "json-stable-stringify@npm:1.3.0" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + isarray: "npm:^2.0.5" + jsonify: "npm:^0.0.1" + object-keys: "npm:^1.1.1" + checksum: 10c0/8b3ff19e4c23c0ad591a49bc3a015d89a538db787d12fe9c4072e1d64d8cfa481f8c37719c629c3d84e848847617bf49f5fee894cf1d25959ab5b67e1c517f31 + languageName: node + linkType: hard + "json-stringify-safe@npm:^5.0.1, json-stringify-safe@npm:~5.0.1": version: 5.0.1 resolution: "json-stringify-safe@npm:5.0.1" @@ -22565,6 +23745,13 @@ __metadata: languageName: node linkType: hard +"jsonify@npm:^0.0.1": + version: 0.0.1 + resolution: "jsonify@npm:0.0.1" + checksum: 10c0/7f5499cdd59a0967ed35bda48b7cec43d850bbc8fb955cdd3a1717bb0efadbe300724d5646de765bb7a99fc1c3ab06eb80d93503c6faaf99b4ff50a3326692f6 + languageName: node + linkType: hard + "jsonpath-plus@npm:10.2.0, jsonpath-plus@npm:^10.0.0, jsonpath-plus@npm:^6.0.1 || ^10.1.0": version: 10.2.0 resolution: "jsonpath-plus@npm:10.2.0" @@ -22579,6 +23766,20 @@ __metadata: languageName: node linkType: hard +"jsonpath-plus@npm:^10.3.0": + version: 10.3.0 + resolution: "jsonpath-plus@npm:10.3.0" + dependencies: + "@jsep-plugin/assignment": "npm:^1.3.0" + "@jsep-plugin/regex": "npm:^1.0.4" + jsep: "npm:^1.4.0" + bin: + jsonpath: bin/jsonpath-cli.js + jsonpath-plus: bin/jsonpath-cli.js + checksum: 10c0/f5ff53078ecab98e8afd1dcdb4488e528653fa5a03a32d671f52db1ae9c3236e6e072d75e1949a80929fd21b07603924a586f829b40ad35993fa0247fa4f7506 + languageName: node + linkType: hard + "jsonpath-plus@npm:^7.2.0": version: 7.2.0 resolution: "jsonpath-plus@npm:7.2.0" @@ -22751,6 +23952,13 @@ __metadata: languageName: node linkType: hard +"just-diff@npm:^6.0.2": + version: 6.0.2 + resolution: "just-diff@npm:6.0.2" + checksum: 10c0/1931ca1f0cea4cc480172165c189a84889033ad7a60bee302268ba8ca9f222b43773fd5f272a23ee618d43d85d3048411f06b635571a198159e9a85bb2495f5c + languageName: node + linkType: hard + "jwa@npm:^1.4.1": version: 1.4.1 resolution: "jwa@npm:1.4.1" @@ -22841,7 +24049,17 @@ __metadata: languageName: node linkType: hard -"knex@npm:3, knex@npm:^3.0.0": +"knex-pglite@npm:^0.11.0": + version: 0.11.0 + resolution: "knex-pglite@npm:0.11.0" + dependencies: + "@electric-sql/pglite": "npm:^0.2.14" + knex: "npm:3.1.0" + checksum: 10c0/3920dad59f44042bfa8b661be946ae5359ba88f3e96ed8270563614e9a58a174ae4f5aa2a060b5a2f8d3ca9ce3f20ea08597b4c908f204f41996a78c9c3b755c + languageName: node + linkType: hard + +"knex@npm:3, knex@npm:3.1.0, knex@npm:^3.0.0": version: 3.1.0 resolution: "knex@npm:3.1.0" dependencies: @@ -22880,6 +24098,33 @@ __metadata: languageName: node linkType: hard +"knip@npm:^5.42.0": + version: 5.56.0 + resolution: "knip@npm:5.56.0" + dependencies: + "@nodelib/fs.walk": "npm:^1.2.3" + fast-glob: "npm:^3.3.3" + formatly: "npm:^0.2.3" + jiti: "npm:^2.4.2" + js-yaml: "npm:^4.1.0" + minimist: "npm:^1.2.8" + oxc-resolver: "npm:^9.0.2" + picocolors: "npm:^1.1.0" + picomatch: "npm:^4.0.1" + smol-toml: "npm:^1.3.1" + strip-json-comments: "npm:5.0.1" + zod: "npm:^3.22.4" + zod-validation-error: "npm:^3.0.3" + peerDependencies: + "@types/node": ">=18" + typescript: ">=5.0.4" + bin: + knip: bin/knip.js + knip-bun: bin/knip-bun.js + checksum: 10c0/434fc8962f0d42faaa001ccda0fd2f78503a453acc69254de49103fe02224f4e74950766c6c441af8217b6f9fa0d7e7907c2eb8c0c2fcc7ef9b663293e9639b0 + languageName: node + linkType: hard + "koa-compose@npm:^4.1.0": version: 4.1.0 resolution: "koa-compose@npm:4.1.0" @@ -22989,7 +24234,7 @@ __metadata: languageName: node linkType: hard -"leven@npm:^3.1.0": +"leven@npm:3.1.0, leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" checksum: 10c0/cd778ba3fbab0f4d0500b7e87d1f6e1f041507c56fdcd47e8256a3012c98aaee371d4c15e0a76e0386107af2d42e2b7466160a2d80688aaa03e66e49949f42df @@ -23097,6 +24342,13 @@ __metadata: languageName: node linkType: hard +"load-esm@npm:1.0.2": + version: 1.0.2 + resolution: "load-esm@npm:1.0.2" + checksum: 10c0/1d66736d97f8005102dfdd03a77f5b99aa34aa934c7a5de345d0a455b4bfe9cb07bb32802b82777b4c48c217a92f4484681cc3971e6c7d73b39ba967f955f501 + languageName: node + linkType: hard + "loader-runner@npm:^4.2.0": version: 4.3.0 resolution: "loader-runner@npm:4.3.0" @@ -23217,6 +24469,13 @@ __metadata: languageName: node linkType: hard +"lodash.groupby@npm:^4.6.0": + version: 4.6.0 + resolution: "lodash.groupby@npm:4.6.0" + checksum: 10c0/3d136cad438ad6c3a078984ef60e057a3498b1312aa3621b00246ecb99e8f2c4d447e2815460db7a0b661a4fe4e2eeee96c84cb661a824bad04b6cf1f7bc6e9b + languageName: node + linkType: hard + "lodash.includes@npm:^4.3.0": version: 4.3.0 resolution: "lodash.includes@npm:4.3.0" @@ -23238,6 +24497,13 @@ __metadata: languageName: node linkType: hard +"lodash.isequal@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.isequal@npm:4.5.0" + checksum: 10c0/dfdb2356db19631a4b445d5f37868a095e2402292d59539a987f134a8778c62a2810c2452d11ae9e6dcac71fc9de40a6fedcb20e2952a15b431ad8b29e50e28f + languageName: node + linkType: hard + "lodash.isinteger@npm:^4.0.4": version: 4.0.4 resolution: "lodash.isinteger@npm:4.0.4" @@ -23280,6 +24546,13 @@ __metadata: languageName: node linkType: hard +"lodash.omit@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.omit@npm:4.5.0" + checksum: 10c0/3808b9b6faae35177174b6ab327f1177e29c91f1e98dcbccf13a72a6767bba337306449d537a4e0d8a33d2673f10d39bc732e30c4b803274ea0c1168ea60e549 + languageName: node + linkType: hard + "lodash.once@npm:^4.0.0": version: 4.1.1 resolution: "lodash.once@npm:4.1.1" @@ -23308,7 +24581,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.15.0, lodash@npm:^4.16.4, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.21": +"lodash@npm:4.17.21, lodash@npm:^4.15.0, lodash@npm:^4.16.4, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.15, lodash@npm:~4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -23549,6 +24822,13 @@ __metadata: languageName: node linkType: hard +"markdown-escape@npm:^2.0.0": + version: 2.0.0 + resolution: "markdown-escape@npm:2.0.0" + checksum: 10c0/8dce0424e6009372938fd813e9d4e545f20b2496815d0536f68ff7dfb8c9cb0e8e0b4b99fa6a3a0469b792207cb48a9acc2ac28ce437092de6a6f27855c32167 + languageName: node + linkType: hard + "markdown-it@npm:^12.2.0": version: 12.3.2 resolution: "markdown-it@npm:12.3.2" @@ -23629,6 +24909,13 @@ __metadata: languageName: node linkType: hard +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 10c0/7579ff94e899e2f76ab64491d76cf606274c874d8f2af4a442c016bd85688927fcfca157ba6bf74b08e9439dc010b248ce05b96cc7c126a354c3bae7fcb48b7f + languageName: node + linkType: hard + "md5.js@npm:^1.3.4": version: 1.3.5 resolution: "md5.js@npm:1.3.5" @@ -24405,6 +25692,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^8.0.2": + version: 8.0.4 + resolution: "minimatch@npm:8.0.4" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10c0/a0a394c356dd5b4cb7f821720841a82fa6f07c9c562c5b716909d1b6ec5e56a7e4c4b5029da26dd256b7d2b3a3f38cbf9ddd8680e887b9b5282b09c05501c1ca + languageName: node + linkType: hard + "minimatch@npm:^9.0.0, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" @@ -24414,7 +25710,16 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6": +"minimatch@npm:~3.0.3": + version: 3.0.8 + resolution: "minimatch@npm:3.0.8" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/72b226f452dcfb5075255f53534cb83fc25565b909e79b9be4fad463d735cb1084827f7013ff41d050e77ee6e474408c6073473edd2fb72c2fd630cfb0acc6ad + languageName: node + linkType: hard + +"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -24490,7 +25795,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^4.0.0": +"minipass@npm:^4.0.0, minipass@npm:^4.2.4": version: 4.2.8 resolution: "minipass@npm:4.2.8" checksum: 10c0/4ea76b030d97079f4429d6e8a8affd90baf1b6a1898977c8ccce4701c5a2ba2792e033abc6709373f25c2c4d4d95440d9d5e9464b46b7b76ca44d2ce26d939ce @@ -25054,6 +26359,13 @@ __metadata: languageName: node linkType: hard +"node-machine-id@npm:^1.1.12": + version: 1.1.12 + resolution: "node-machine-id@npm:1.1.12" + checksum: 10c0/ab2fea5f75a6f1ce3c76c5e0ae3903b631230e0a99b003d176568fff8ddbdf7b2943be96cd8d220c497ca0f6149411831f8a450601929f326781cb1b59bab7f8 + languageName: node + linkType: hard + "node-releases@npm:^2.0.18": version: 2.0.18 resolution: "node-releases@npm:2.0.18" @@ -25061,6 +26373,16 @@ __metadata: languageName: node linkType: hard +"node-sarif-builder@npm:^2.0.3": + version: 2.0.3 + resolution: "node-sarif-builder@npm:2.0.3" + dependencies: + "@types/sarif": "npm:^2.1.4" + fs-extra: "npm:^10.0.0" + checksum: 10c0/328821b645d46a256197c6f8a17f3eb9c53f1af3416184a3d2b354e28d595d2f216380b573ccbd2dd769eaac70e5d020b731f32dc66b8782af0e403723e5ed5f + languageName: node + linkType: hard + "node-schedule@npm:2.1.1": version: 2.1.1 resolution: "node-schedule@npm:2.1.1" @@ -25481,6 +26803,13 @@ __metadata: languageName: node linkType: hard +"openapi-types@npm:^12.0.2": + version: 12.1.3 + resolution: "openapi-types@npm:12.1.3" + checksum: 10c0/4ad4eb91ea834c237edfa6ab31394e87e00c888fc2918009763389c00d02342345195d6f302d61c3fd807f17723cd48df29b47b538b68375b3827b3758cd520f + languageName: node + linkType: hard + "openapi3-ts@npm:^3.1.2": version: 3.2.0 resolution: "openapi3-ts@npm:3.2.0" @@ -25502,6 +26831,15 @@ __metadata: languageName: node linkType: hard +"oppa@npm:^0.4.0": + version: 0.4.0 + resolution: "oppa@npm:0.4.0" + dependencies: + chalk: "npm:^4.1.1" + checksum: 10c0/3c4705b0adce90c7034f92692071f7d27f51e637501bb0b485c2701da70d9c831a52d7e87ea9c53f9bc823e3e913f3fcb58b364f46d57f7de9721cf9ae70d569 + languageName: node + linkType: hard + "optionator@npm:^0.8.1": version: 0.8.3 resolution: "optionator@npm:0.8.3" @@ -25568,6 +26906,54 @@ __metadata: languageName: node linkType: hard +"oxc-resolver@npm:^9.0.2": + version: 9.0.2 + resolution: "oxc-resolver@npm:9.0.2" + dependencies: + "@oxc-resolver/binding-darwin-arm64": "npm:9.0.2" + "@oxc-resolver/binding-darwin-x64": "npm:9.0.2" + "@oxc-resolver/binding-freebsd-x64": "npm:9.0.2" + "@oxc-resolver/binding-linux-arm-gnueabihf": "npm:9.0.2" + "@oxc-resolver/binding-linux-arm64-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-arm64-musl": "npm:9.0.2" + "@oxc-resolver/binding-linux-riscv64-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-s390x-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-x64-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-x64-musl": "npm:9.0.2" + "@oxc-resolver/binding-wasm32-wasi": "npm:9.0.2" + "@oxc-resolver/binding-win32-arm64-msvc": "npm:9.0.2" + "@oxc-resolver/binding-win32-x64-msvc": "npm:9.0.2" + dependenciesMeta: + "@oxc-resolver/binding-darwin-arm64": + optional: true + "@oxc-resolver/binding-darwin-x64": + optional: true + "@oxc-resolver/binding-freebsd-x64": + optional: true + "@oxc-resolver/binding-linux-arm-gnueabihf": + optional: true + "@oxc-resolver/binding-linux-arm64-gnu": + optional: true + "@oxc-resolver/binding-linux-arm64-musl": + optional: true + "@oxc-resolver/binding-linux-riscv64-gnu": + optional: true + "@oxc-resolver/binding-linux-s390x-gnu": + optional: true + "@oxc-resolver/binding-linux-x64-gnu": + optional: true + "@oxc-resolver/binding-linux-x64-musl": + optional: true + "@oxc-resolver/binding-wasm32-wasi": + optional: true + "@oxc-resolver/binding-win32-arm64-msvc": + optional: true + "@oxc-resolver/binding-win32-x64-msvc": + optional: true + checksum: 10c0/54c9791d19a44930448d21ea79fca5b6649d69b41a8e8b0ca2d57345e871608a775b54ff92827f65177b5d856c6ce490e0ce99209d899d74de7db6be49c56a6d + languageName: node + linkType: hard + "p-cancelable@npm:^2.0.0": version: 2.1.1 resolution: "p-cancelable@npm:2.1.1" @@ -25712,6 +27098,22 @@ __metadata: languageName: node linkType: hard +"pac-proxy-agent@npm:^7.1.0": + version: 7.2.0 + resolution: "pac-proxy-agent@npm:7.2.0" + dependencies: + "@tootallnate/quickjs-emscripten": "npm:^0.23.0" + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + get-uri: "npm:^6.0.1" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.6" + pac-resolver: "npm:^7.0.1" + socks-proxy-agent: "npm:^8.0.5" + checksum: 10c0/0265c17c9401c2ea735697931a6553a0c6d8b20c4d7d4e3b3a0506080ba69a8d5ad656e2a6be875411212e2b6ed7a4d9526dd3997e08581fdfb1cbcad454c296 + languageName: node + linkType: hard + "pac-resolver@npm:^7.0.1": version: 7.0.1 resolution: "pac-resolver@npm:7.0.1" @@ -26047,7 +27449,7 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.11.1": +"path-scurry@npm:^1.11.1, path-scurry@npm:^1.6.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" dependencies: @@ -26064,7 +27466,7 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^8.0.0, path-to-regexp@npm:^8.1.0": +"path-to-regexp@npm:8.2.0, path-to-regexp@npm:^8.0.0, path-to-regexp@npm:^8.1.0": version: 8.2.0 resolution: "path-to-regexp@npm:8.2.0" checksum: 10c0/ef7d0a887b603c0a142fad16ccebdcdc42910f0b14830517c724466ad676107476bba2fe9fffd28fd4c141391ccd42ea426f32bb44c2c82ecaefe10c37b90f5a @@ -26112,6 +27514,13 @@ __metadata: languageName: node linkType: hard +"peek-readable@npm:^7.0.0": + version: 7.0.0 + resolution: "peek-readable@npm:7.0.0" + checksum: 10c0/a979b0678a5c2b58c2a755eadc5bb990814e479ff17b9fbcec39a6c88f278eb9a788b6ae13371ee84f7a2c6672505dac961f99ccc0c0300354d9b4dc5a207604 + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -26249,7 +27658,7 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^4.0.2": +"picomatch@npm:^4.0.1, picomatch@npm:^4.0.2": version: 4.0.2 resolution: "picomatch@npm:4.0.2" checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc @@ -27128,6 +28537,22 @@ __metadata: languageName: node linkType: hard +"proxy-agent@npm:6.5.0": + version: 6.5.0 + resolution: "proxy-agent@npm:6.5.0" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + http-proxy-agent: "npm:^7.0.1" + https-proxy-agent: "npm:^7.0.6" + lru-cache: "npm:^7.14.1" + pac-proxy-agent: "npm:^7.1.0" + proxy-from-env: "npm:^1.1.0" + socks-proxy-agent: "npm:^8.0.5" + checksum: 10c0/7fd4e6f36bf17098a686d4aee3b8394abfc0b0537c2174ce96b0a4223198b9fafb16576c90108a3fcfc2af0168bd7747152bfa1f58e8fee91d3780e79aab7fd8 + languageName: node + linkType: hard + "proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -28105,6 +29530,13 @@ __metadata: languageName: node linkType: hard +"reflect-metadata@npm:0.2.2": + version: 0.2.2 + resolution: "reflect-metadata@npm:0.2.2" + checksum: 10c0/1cd93a15ea291e420204955544637c264c216e7aac527470e393d54b4bb075f10a17e60d8168ec96600c7e0b9fcc0cb0bb6e91c3fbf5b0d8c9056f04e6ac1ec2 + languageName: node + linkType: hard + "reflect.getprototypeof@npm:^1.0.4, reflect.getprototypeof@npm:^1.0.6": version: 1.0.7 resolution: "reflect.getprototypeof@npm:1.0.7" @@ -28458,6 +29890,19 @@ __metadata: languageName: node linkType: hard +"resolve@npm:~1.22.1, resolve@npm:~1.22.2": + version: 1.22.10 + resolution: "resolve@npm:1.22.10" + dependencies: + is-core-module: "npm:^2.16.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/8967e1f4e2cc40f79b7e080b4582b9a8c5ee36ffb46041dccb20e6461161adf69f843b43067b4a375de926a2cd669157e29a29578191def399dd5ef89a1b5203 + languageName: node + linkType: hard + "resolve@patch:resolve@npm%3A1.22.8#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" @@ -28484,6 +29929,19 @@ __metadata: languageName: node linkType: hard +"resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin": + version: 1.22.10 + resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.16.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/52a4e505bbfc7925ac8f4cd91fd8c4e096b6a89728b9f46861d3b405ac9a1ccf4dcbf8befb4e89a2e11370dacd0160918163885cbc669369590f2f31f4c58939 + languageName: node + linkType: hard + "responselike@npm:^2.0.0": version: 2.0.1 resolution: "responselike@npm:2.0.1" @@ -28758,6 +30216,7 @@ __metadata: dependencies: "@backstage/cli": "npm:^0.29.0" "@backstage/e2e-test-utils": "npm:^0.1.1" + "@backstage/repo-tools": "npm:^0.13.2" "@changesets/cli": "npm:^2.29.4" "@octokit/rest": "npm:^21.1.1" "@playwright/test": "npm:^1.32.3" @@ -28807,6 +30266,24 @@ __metadata: languageName: node linkType: hard +"rxjs@npm:7.8.2": + version: 7.8.2 + resolution: "rxjs@npm:7.8.2" + dependencies: + tslib: "npm:^2.1.0" + checksum: 10c0/1fcd33d2066ada98ba8f21fcbbcaee9f0b271de1d38dc7f4e256bfbc6ffcdde68c8bfb69093de7eeb46f24b1fb820620bf0223706cff26b4ab99a7ff7b2e2c45 + languageName: node + linkType: hard + +"rxjs@npm:^6.6.3": + version: 6.6.7 + resolution: "rxjs@npm:6.6.7" + dependencies: + tslib: "npm:^1.9.0" + checksum: 10c0/e556a13a9aa89395e5c9d825eabcfa325568d9c9990af720f3f29f04a888a3b854f25845c2b55875d875381abcae2d8100af9cacdc57576e7ed6be030a01d2fe + languageName: node + linkType: hard + "rxjs@npm:^7.5.5": version: 7.8.1 resolution: "rxjs@npm:7.8.1" @@ -29014,6 +30491,17 @@ __metadata: languageName: node linkType: hard +"semver@npm:~7.5.4": + version: 7.5.4 + resolution: "semver@npm:7.5.4" + dependencies: + lru-cache: "npm:^6.0.0" + bin: + semver: bin/semver.js + checksum: 10c0/5160b06975a38b11c1ab55950cb5b8a23db78df88275d3d8a42ccf1f29e55112ac995b3a26a522c36e3b5f76b0445f1eef70d696b8c7862a2b4303d7b0e7609e + languageName: node + linkType: hard + "send@npm:0.19.0": version: 0.19.0 resolution: "send@npm:0.19.0" @@ -29096,7 +30584,7 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.1": +"set-function-length@npm:^1.2.1, set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" dependencies: @@ -29288,6 +30776,13 @@ __metadata: languageName: node linkType: hard +"smol-toml@npm:^1.3.1": + version: 1.3.4 + resolution: "smol-toml@npm:1.3.4" + checksum: 10c0/801435476f52d6b05dfcb2bd2ed1956c6fc2b4c20e84b5e609eb27fa0c27b51a47528d91cabd1a93e8659bd2b8edb685e73ce2b686678739e67d7939fa25a92b + languageName: node + linkType: hard + "smtp-address-parser@npm:1.0.10": version: 1.0.10 resolution: "smtp-address-parser@npm:1.0.10" @@ -29339,6 +30834,17 @@ __metadata: languageName: node linkType: hard +"socks-proxy-agent@npm:^8.0.5": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + socks: "npm:^2.8.3" + checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6 + languageName: node + linkType: hard + "socks@npm:^2.6.2, socks@npm:^2.8.3": version: 2.8.3 resolution: "socks@npm:2.8.3" @@ -29442,6 +30948,13 @@ __metadata: languageName: node linkType: hard +"spawn-command@npm:^0.0.2-1": + version: 0.0.2 + resolution: "spawn-command@npm:0.0.2" + checksum: 10c0/b22f2d71239e6e628a400831861ba747750bbb40c0a53323754cf7b84330b73d81e40ff1f9055e6d1971818679510208a9302e13d9ff3b32feb67e74d7a1b3ef + languageName: node + linkType: hard + "spawndamnit@npm:^3.0.1": version: 3.0.1 resolution: "spawndamnit@npm:3.0.1" @@ -29804,6 +31317,13 @@ __metadata: languageName: node linkType: hard +"string-argv@npm:~0.3.1": + version: 0.3.2 + resolution: "string-argv@npm:0.3.2" + checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82 + languageName: node + linkType: hard + "string-env-interpolation@npm:^1.0.1": version: 1.0.1 resolution: "string-env-interpolation@npm:1.0.1" @@ -29943,7 +31463,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:6.0, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" dependencies: @@ -30000,7 +31520,14 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:^3.1.1": +"strip-json-comments@npm:5.0.1": + version: 5.0.1 + resolution: "strip-json-comments@npm:5.0.1" + checksum: 10c0/c9d9d55a0167c57aa688df3aa20628cf6f46f0344038f189eaa9d159978e80b2bfa6da541a40d83f7bde8a3554596259bf6b70578b2172356536a0e3fa5a0982 + languageName: node + linkType: hard + +"strip-json-comments@npm:^3.1.1, strip-json-comments@npm:~3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd @@ -30021,6 +31548,16 @@ __metadata: languageName: node linkType: hard +"strtok3@npm:^10.2.0": + version: 10.2.2 + resolution: "strtok3@npm:10.2.2" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + peek-readable: "npm:^7.0.0" + checksum: 10c0/0d13a7fee7d773693b9e23c53429a032beb1d0ba9ab1cef3b5f3968c2c65f5c292a54af2b54c8e55abd210544e786a2369c8c241c68bb7d80b0ae5b207e4afd9 + languageName: node + linkType: hard + "strtok3@npm:^6.2.4": version: 6.3.0 resolution: "strtok3@npm:6.3.0" @@ -30142,7 +31679,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0": +"supports-color@npm:^8.0.0, supports-color@npm:^8.1.0, supports-color@npm:~8.1.1": version: 8.1.1 resolution: "supports-color@npm:8.1.1" dependencies: @@ -30726,6 +32263,16 @@ __metadata: languageName: node linkType: hard +"token-types@npm:^6.0.0": + version: 6.0.0 + resolution: "token-types@npm:6.0.0" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + ieee754: "npm:^1.2.1" + checksum: 10c0/5bf5eba51d63f71f301659ff70ce10ca43e7038364883437d8b4541cc98377e3e56109b11720e25fe51047014efaccdff90eaf6de9a78270483578814b838ab9 + languageName: node + linkType: hard + "toposort@npm:^2.0.2": version: 2.0.2 resolution: "toposort@npm:2.0.2" @@ -30805,6 +32352,15 @@ __metadata: languageName: node linkType: hard +"tree-kill@npm:^1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2 + languageName: node + linkType: hard + "tree-sitter-json@npm:=0.24.8": version: 0.24.8 resolution: "tree-sitter-json@npm:0.24.8" @@ -30890,6 +32446,15 @@ __metadata: languageName: node linkType: hard +"ts-invariant@npm:^0.9.3": + version: 0.9.4 + resolution: "ts-invariant@npm:0.9.4" + dependencies: + tslib: "npm:^2.1.0" + checksum: 10c0/67cb364f535f40312e72d317bdc24c34fc09a43b63ecb1eab7285d6dc909f1f9b2dd73906104e510031cf3b1493636c7f0120f211c8f92783ada3be4c57f0f58 + languageName: node + linkType: hard + "ts-is-present@npm:^1.1.1": version: 1.2.2 resolution: "ts-is-present@npm:1.2.2" @@ -30971,20 +32536,20 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.11.1, tslib@npm:^1.14.1, tslib@npm:^1.8.1": - version: 1.14.1 - resolution: "tslib@npm:1.14.1" - checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 - languageName: node - linkType: hard - -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2, tslib@npm:^2.6.3, tslib@npm:^2.8.0, tslib@npm:^2.8.1": +"tslib@npm:2.8.1, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2, tslib@npm:^2.6.3, tslib@npm:^2.8.0, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 languageName: node linkType: hard +"tslib@npm:^1.11.1, tslib@npm:^1.14.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": + version: 1.14.1 + resolution: "tslib@npm:1.14.1" + checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 + languageName: node + linkType: hard + "tsscmp@npm:1.0.6": version: 1.0.6 resolution: "tsscmp@npm:1.0.6" @@ -31203,6 +32768,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:5.8.2": + version: 5.8.2 + resolution: "typescript@npm:5.8.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/5c4f6fbf1c6389b6928fe7b8fcd5dc73bb2d58cd4e3883f1d774ed5bd83b151cbac6b7ecf11723de56d4676daeba8713894b1e9af56174f2f9780ae7848ec3c6 + languageName: node + linkType: hard + "typescript@npm:~5.4.0": version: 5.4.5 resolution: "typescript@npm:5.4.5" @@ -31223,6 +32798,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@npm%3A5.8.2#optional!builtin": + version: 5.8.2 + resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin::version=5.8.2&hash=8c6c40" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/8a6cd29dfb59bd5a978407b93ae0edb530ee9376a5b95a42ad057a6f80ffb0c410489ccd6fe48d1d0dfad6e8adf5d62d3874bbd251f488ae30e11a1ce6dabd28 + languageName: node + linkType: hard + "typescript@patch:typescript@npm%3A~5.4.0#optional!builtin": version: 5.4.5 resolution: "typescript@patch:typescript@npm%3A5.4.5#optional!builtin::version=5.4.5&hash=5adc0c" @@ -31296,6 +32881,22 @@ __metadata: languageName: node linkType: hard +"uid@npm:2.0.2": + version: 2.0.2 + resolution: "uid@npm:2.0.2" + dependencies: + "@lukeed/csprng": "npm:^1.0.0" + checksum: 10c0/e9d02d0562c74e74b5a2519e586db9d7f8204978e476cddd191ee1a9efb85efafdbab2dbf3fc3dde0f5da01fd9da161f37d604dabf513447fd2c03d008f1324c + languageName: node + linkType: hard + +"uint8array-extras@npm:^1.4.0": + version: 1.4.0 + resolution: "uint8array-extras@npm:1.4.0" + checksum: 10c0/eaffd3388634b7e5e1496073b878dd19136043137d3e7e0d2a453e37f566a5a551e640819e1a6596c6df9b9d1f7b70884cc29db6a357bdd424811f3598d504dd + languageName: node + linkType: hard + "unbox-primitive@npm:^1.0.2": version: 1.0.2 resolution: "unbox-primitive@npm:1.0.2" @@ -31585,6 +33186,13 @@ __metadata: languageName: node linkType: hard +"url-join@npm:^4.0.1": + version: 4.0.1 + resolution: "url-join@npm:4.0.1" + checksum: 10c0/ac65e2c7c562d7b49b68edddcf55385d3e922bc1dd5d90419ea40b53b6de1607d1e45ceb71efb9d60da02c681d13c6cb3a1aa8b13fc0c989dfc219df97ee992d + languageName: node + linkType: hard + "url-parse@npm:^1.4.3, url-parse@npm:^1.5.10, url-parse@npm:^1.5.3": version: 1.5.10 resolution: "url-parse@npm:1.5.10" @@ -31957,6 +33565,13 @@ __metadata: languageName: node linkType: hard +"walk-up-path@npm:^3.0.1": + version: 3.0.1 + resolution: "walk-up-path@npm:3.0.1" + checksum: 10c0/3184738e0cf33698dd58b0ee4418285b9c811e58698f52c1f025435a85c25cbc5a63fee599f1a79cb29ca7ef09a44ec9417b16bfd906b1a37c305f7aa20ee5bc + languageName: node + linkType: hard + "walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" @@ -31985,7 +33600,7 @@ __metadata: languageName: node linkType: hard -"wcwidth@npm:^1.0.1": +"wcwidth@npm:>=1.0.1, wcwidth@npm:^1.0.1": version: 1.0.1 resolution: "wcwidth@npm:1.0.1" dependencies: @@ -32591,6 +34206,28 @@ __metadata: languageName: node linkType: hard +"yaml-ast-parser@npm:^0.0.43": + version: 0.0.43 + resolution: "yaml-ast-parser@npm:0.0.43" + checksum: 10c0/4d2f1e761067b2c6abdd882279a406f879258787af470a6d4a659cb79cb2ab056b870b25f1f80f46ed556e8b499d611d247806376f53edf3412f72c0a8ea2e98 + languageName: node + linkType: hard + +"yaml-diff-patch@npm:^2.0.0": + version: 2.0.0 + resolution: "yaml-diff-patch@npm:2.0.0" + dependencies: + fast-json-patch: "npm:^3.1.0" + oppa: "npm:^0.4.0" + yaml: "npm:^2.0.0-10" + bin: + yaml-diff-patch: dist/bin/yaml-patch.js + yaml-overwrite: dist/bin/yaml-patch.js + yaml-patch: dist/bin/yaml-patch.js + checksum: 10c0/2b33ecad3be1519af476cf204bb2b194f0e6b2b4abae1f9fff9300d0b71a6fcadd8789d1a8f1e4fa02fef7c1e2f64da43b9f29abc16bac9b80783455089a4564 + languageName: node + linkType: hard + "yaml@npm:^1.10.0, yaml@npm:^1.10.2, yaml@npm:^1.7.2": version: 1.10.2 resolution: "yaml@npm:1.10.2" @@ -32607,6 +34244,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.0.0-10": + version: 2.8.0 + resolution: "yaml@npm:2.8.0" + bin: + yaml: bin.mjs + checksum: 10c0/f6f7310cf7264a8107e72c1376f4de37389945d2fb4656f8060eca83f01d2d703f9d1b925dd8f39852a57034fafefde6225409ddd9f22aebfda16c6141b71858 + languageName: node + linkType: hard + "yargs-parser@npm:^20.2.2": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" @@ -32745,6 +34391,15 @@ __metadata: languageName: node linkType: hard +"zod-validation-error@npm:^3.0.3": + version: 3.4.1 + resolution: "zod-validation-error@npm:3.4.1" + peerDependencies: + zod: ^3.24.4 + checksum: 10c0/cf16f12fccb3e515d18c876c8a75ae4a87219b28e8e7f6334b8d423bebfa2c08b3382d7c53842ba05af8c5caabf66ee8df1ce2862b3b41c2e96eba26e70a995f + languageName: node + linkType: hard + "zod-validation-error@npm:^3.4.0": version: 3.4.0 resolution: "zod-validation-error@npm:3.4.0"