Merge branch 'master' of github.com:backstage/backstage

This commit is contained in:
Martin Morales
2023-03-24 11:43:57 -05:00
18 changed files with 1065 additions and 125 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Minor visual tweaks to adapt to changes in mkdocs-material v9
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': minor
---
Created `confluence:transform:markdown` action for converting confluence docs to Markdown.
+14 -14
View File
@@ -8,14 +8,14 @@
yarn.lock @backstage/maintainers @backstage-service
*/yarn.lock @backstage/maintainers @backstage-service
/.changeset/*.md
/cypress/src/integration/plugins/techdocs.spec.ts @backstage/techdocs-core
/docs/assets/search @backstage/techdocs-core
/docs/features/search @backstage/techdocs-core
/docs/features/techdocs @backstage/techdocs-core
/docs/plugins/integrating-search-into-plugins.md @backstage/techdocs-core
/cypress/src/integration/plugins/techdocs.spec.ts @backstage/techdocs-maintainers
/docs/assets/search @backstage/discoverability-maintainers
/docs/features/search @backstage/discoverability-maintainers
/docs/features/techdocs @backstage/techdocs-maintainers
/docs/plugins/integrating-search-into-plugins.md @backstage/discoverability-maintainers
/packages/cli/src/commands/onboard @backstage/sharks
/packages/techdocs-cli @backstage/techdocs-core
/packages/techdocs-cli-embedded-app @backstage/techdocs-core
/packages/techdocs-cli @backstage/techdocs-maintainers
/packages/techdocs-cli-embedded-app @backstage/techdocs-maintainers
/plugins/adr @backstage/maintainers @kuangp
/plugins/adr-* @backstage/maintainers @kuangp
/plugins/allure @backstage/maintainers @deepak-bhardwaj-ps
@@ -55,7 +55,7 @@ yarn.lock @backstage/maintainers @back
/plugins/fossa @backstage/maintainers @backstage/sda-se-reviewers
/plugins/gcalendar @backstage/maintainers @szubster @ptychu @kielosz @alexrybch
/plugins/git-release-manager @backstage/maintainers @erikengervall
/plugins/home @backstage/techdocs-core
/plugins/home @backstage/discoverability-maintainers
/plugins/ilert @backstage/maintainers @yacut
/plugins/jenkins @backstage/maintainers @timja
/plugins/jenkins-backend @backstage/maintainers @timja
@@ -71,13 +71,13 @@ yarn.lock @backstage/maintainers @back
/plugins/rollbar-backend @backstage/maintainers @andrewthauer
/plugins/scaffolder-backend-module-rails @backstage/maintainers @angeliski
/plugins/scaffolder-backend-module-yeoman @backstage/maintainers @pawelmitka
/plugins/search @backstage/techdocs-core
/plugins/search-* @backstage/techdocs-core
/plugins/search @backstage/discoverability-maintainers
/plugins/search-* @backstage/discoverability-maintainers
/plugins/sonarqube @backstage/maintainers @backstage/sda-se-reviewers
/plugins/stack-overflow @backstage/techdocs-core
/plugins/stack-overflow-backend @backstage/techdocs-core
/plugins/techdocs @backstage/techdocs-core
/plugins/techdocs-* @backstage/techdocs-core
/plugins/stack-overflow @backstage/discoverability-maintainers
/plugins/stack-overflow-backend @backstage/discoverability-maintainers
/plugins/techdocs @backstage/techdocs-maintainers
/plugins/techdocs-* @backstage/techdocs-maintainers
/plugins/user-settings-backend @backstage/maintainers @backstage/sda-se-reviewers
/tech-insights-backend @backstage/maintainers @xantier @iain-b
/tech-insights-backend-module-jsonfc @backstage/maintainers @xantier @iain-b
+33 -21
View File
@@ -24,6 +24,20 @@ Team: @backstage/catalog-maintainers
| ---- | ------------ | --------- | ---------------------------- | ------- |
| TBD | Spotify | Chipmunks | [TBD](http://github.com/TBD) | - |
### Discoverability
Team: @backstage/discoverability-maintainers
Scope: Discoverability within Backstage, including the home page, information architecture, and search
| Name | Organization | Team | GitHub | Discord |
| ------------------------ | ------------ | ---- | ---------------------------------------- | ------------------ |
| Avantika Iyer | Spotify | BUX | [tikabom](http://github.com/tikabom) | - |
| Camila Belo | Spotify | BUX | [camilaibs](http://github.com/camilaibs) | Camila Loiola#0226 |
| Emma Indal | Spotify | BUX | [emmaindal](http://github.com/emmaindal) | emmaindal#7503 |
| Raghunandan Balachandran | Spotify | BUX | [soapraj](http://github.com/soapraj) | raghunandanb#1114 |
| Renan Mendes Carvalho | Spotify | BUX | [aitherios](http://github.com/aitherios) | aitherios#0593 |
### Kubernetes
Team: @backstage/kubernetes-maintainers
@@ -38,17 +52,12 @@ Scope: The Kubernetes plugin and the base it provides for other plugins to build
Team: @backstage/techdocs-maintainers
| Name | Organization | Team | GitHub | Discord |
| ---- | ------------ | ------------ | ---------------------------- | ------- |
| TBD | Spotify | Pulp Fiction | [TBD](http://github.com/TBD) | - |
Scope: The TechDocs plugin and related tooling
### Search
Team: @backstage/search-maintainers
| Name | Organization | Team | GitHub | Discord |
| ---- | ------------ | ---- | ---------------------------- | ------- |
| TBD | Spotify | BUX | [TBD](http://github.com/TBD) | - |
| Name | Organization | Team | GitHub | Discord |
| ------------------------ | ------------ | ------------ | ------------------------------------------------ | ------------------ |
| Morgan Bentell | Spotify | Pulp Fiction | [agentbellnorm](http://github.com/agentbellnorm) | morganbentell#9030 |
| Raghunandan Balachandran | Spotify | Pulp Fiction | [soapraj](http://github.com/soapraj) | raghunandanb#1114 |
## Sponsors
@@ -60,17 +69,20 @@ Team: @backstage/search-maintainers
## Organization Members
| Name | Organization | GitHub | Discord |
| --------------- | ------------------------ | ----------------------------------------------- | ------------------------------ |
| Adam Harvey | Cisco | [adamdmharvey](https://github.com/adamdmharvey) | `adamharvey#3739` |
| Andre Wanlin | Keyloop | [awanlin](https://github.com/awanlin) | `Ahhhndre#3095` |
| Andrew Thauer | Wealthsimple | [andrewthauer](https://github.com/andrewthauer) | `andrewthauer#3060` |
| Brian Fletcher | RoadieHQ | [punkle](https://github.com/punkle) | `Brian Fletcher#7051` |
| David Tuite | Roadie | [dtuite](https://github.com/dtuite) | `David Tuite (roadie.io)#1010` |
| Jussi Hallila | Roadie | [Xantier](https://github.com/Xantier) | `Xantier#0086` |
| Mark Avery | Cvent | [webark](https://github.com/webark) | `webark#8471` |
| Phil Kuang | FactSet Research Systems | [kuangp](https://github.com/kuangp) | `pkuang#3202` |
| Taras Mankovski | Frontside | [taras](https://github.com/taras) | `tarasm#1256` |
| Name | Organization | GitHub | Discord |
| ------------------ | ------------------------- | ----------------------------------------------- | ------------------------------ |
| Adam Harvey | Cisco | [adamdmharvey](https://github.com/adamdmharvey) | `adamharvey#3739` |
| Andre Wanlin | Keyloop | [awanlin](https://github.com/awanlin) | `Ahhhndre#3095` |
| Andrew Thauer | Wealthsimple | [andrewthauer](https://github.com/andrewthauer) | `andrewthauer#3060` |
| Brian Fletcher | RoadieHQ | [punkle](https://github.com/punkle) | `Brian Fletcher#7051` |
| David Tuite | Roadie | [dtuite](https://github.com/dtuite) | `David Tuite (roadie.io)#1010` |
| Himanshu Mishra | Harness.io | [OrkoHunter](https://github.com/OrkoHunter) | `OrkoHunter#1520` |
| Jamie Klassen | VMware | [jamieklassen](https://github.com/jamieklassen) | `jamieklassen#3047` |
| Jussi Hallila | Roadie | [Xantier](https://github.com/Xantier) | `Xantier#0086` |
| Mark Avery | Cvent | [webark](https://github.com/webark) | `webark#8471` |
| Patrick Jungermann | Bonial International GmbH | [pjungermann](https://github.com/pjungermann) | `pjungermann#6933` |
| Phil Kuang | FactSet Research Systems | [kuangp](https://github.com/kuangp) | `pkuang#3202` |
| Taras Mankovski | Frontside | [taras](https://github.com/taras) | `tarasm#1256` |
## Emeritus Core Maintainers
+3 -3
View File
@@ -9438,15 +9438,15 @@ __metadata:
linkType: hard
"sass@npm:^1.57.1":
version: 1.59.3
resolution: "sass@npm:1.59.3"
version: 1.60.0
resolution: "sass@npm:1.60.0"
dependencies:
chokidar: ">=3.0.0 <4.0.0"
immutable: ^4.0.0
source-map-js: ">=0.6.2 <2.0.0"
bin:
sass: sass.js
checksum: 839b5282cdf7d0ba3fdbfb605277dd584a8c40fa3e3e58ad905d64cd812acfb82ff0a4072d4981673db884ee61505472ff07c5c5a8a497f16ba013b183ba6473
checksum: 06e163c37af466ec194cf2ed8dab616372afeb19322d356947d48ea664fc38398ae77c4d91bea9cb0ace954ce289d5518d0f8555ecc49f6bf2539a8ef52fc580
languageName: node
linkType: hard
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
@@ -0,0 +1,118 @@
# @backstage/plugin-scaffolder-backend-module-confluence-to-markdown
Welcome to the `confluence:transform:markdown` action for the `scaffolder-backend`.
## Getting started
You need to configure the action in your backend:
## From your Backstage root directory
```bash
# From your Backstage root directory
yarn add --cwd packages/backend @backstage/plugin-scaffolder-backend-module-confluence-to-markdown
```
Configure the action:
(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options):
```typescript
// packages/backend/src/plugins/scaffolder.ts
import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend';
import { ScmIntegrations } from '@backstage/integration';
import { createConfluenceToMarkdownAction } from '@backstage/plugin-scaffolder-backend-module-confluence-to-markdown';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const catalogClient = new CatalogClient({ discoveryApi: env.discovery });
const integrations = ScmIntegrations.fromConfig(env.config);
const builtInActions = createBuiltinActions({
integrations,
catalogClient,
config: env.config,
reader: env.reader,
});
const actions = [
...builtInActions,
createConfluenceToMarkdownAction({
integrations,
config: env.config,
reader: env.reader,
}),
];
return createRouter({
actions,
catalogClient: catalogClient,
logger: env.logger,
config: env.config,
database: env.database,
reader: env.reader,
});
}
```
You will also need an access token for authorization with `Read` permissions. You can create a Personal Access Token (PAT) in confluence and add the PAT to your `app-config.yaml`
```yaml
confluence:
baseUrl: ${CONFLUENCE_BASE_URL}
token: ${CONFLUENCE_TOKEN}
```
After that you can use the action in your template:
```yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: confluence-to-markdown
title: Confluence to Markdown
description: This template converts a single confluence document to Markdown for Techdocs and adds it to a given GitHub repo.
tags:
- do-not-use
- poc
spec:
owner: <YOUR_EMAIL>
type: service
parameters:
- title: Confluence and Github Repo Information
properties:
confluenceUrls:
type: array
description: Urls for confluence doc to be converted to markdown. In format <CONFLUENCE_BASE_URL>/display/<SPACEKEY>/<PAGE+TITLE>
items:
type: string
default: confluence url
ui:options:
addable: true
minItems: 1
maxItems: 5
repoUrl:
type: string
title: GitHub URL mkdocs.yaml link
description: The GitHub repo URL to your mkdocs.yaml file. Example <https://github.com/blob/master/mkdocs.yml>
steps:
- id: create-docs
name: Get markdown file created and update markdown.yaml file
action: confluence:transform:markdown
input:
confluenceUrls: ${{ parameters.confluenceUrls }}
repoUrl: ${{ parameters.repoUrl }}
- id: publish
name: Publish PR to GitHub
action: publish:github:pull-request
input:
repoUrl: <GITHUB_BASE_URL>?repo=${{ steps['create-docs'].output.repo }}&owner=${{ steps['create-docs'].output.owner }}
branchName: confluence-to-markdown
title: Confluence to Markdown
description: PR for converting confluence page to mkdocs
```
Replace `<GITHUB_BASE_URL>` with your GitHub URL without `https://`.
You can find a list of all registered actions including their parameters at the /create/actions route in your Backstage application.
@@ -0,0 +1,20 @@
## API Report File for "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { Config } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { UrlReader } from '@backstage/backend-common';
// @public (undocumented)
export const createConfluenceToMarkdownAction: (options: {
reader: UrlReader;
integrations: ScmIntegrations;
config: Config;
}) => TemplateAction<{
confluenceUrls: string[];
repoUrl: string;
}>;
```
@@ -0,0 +1,49 @@
{
"name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown",
"description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend",
"version": "0.0.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin-module"
},
"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",
"help": "backstage-cli help"
},
"dependencies": {
"@backstage/backend-common": "workspace:^",
"@backstage/config": "workspace:^",
"@backstage/errors": "workspace:^",
"@backstage/integration": "workspace:^",
"@backstage/plugin-scaffolder-backend": "workspace:^",
"@backstage/plugin-scaffolder-node": "workspace:^",
"@backstage/types": "workspace:^",
"fs-extra": "10.1.0",
"git-url-parse": "^13.1.0",
"node-fetch": "^2.6.7",
"node-html-markdown": "^1.3.0",
"yaml": "^2.0.0"
},
"devDependencies": {
"@backstage/cli": "workspace:^",
"@backstage/test-utils": "workspace:^",
"mock-fs": "^5.2.0",
"msw": "^1.0.0"
},
"files": [
"dist"
]
}
@@ -0,0 +1,294 @@
/*
* Copyright 2023 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 { PassThrough } from 'stream';
import { createConfluenceToMarkdownAction } from './confluenceToMarkdown';
import { getVoidLogger } from '@backstage/backend-common';
import { UrlReader } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import mockFs from 'mock-fs';
import os from 'os';
import type { ActionContext } from '@backstage/plugin-scaffolder-node';
import { readFile, writeFile, createWriteStream } from 'fs-extra';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
jest.mock('fs-extra', () => ({
mkdirSync: jest.fn(),
readFile: jest.fn().mockResolvedValue('File contents'),
writeFile: jest.fn().mockImplementation(() => {
return Promise.resolve();
}),
outputFile: jest.fn(),
openSync: jest.fn(),
createWriteStream: jest.fn().mockReturnValue(new PassThrough()),
ensureDir: jest.fn(),
}));
describe('confluence:transform:markdown', () => {
const baseUrl = `https://nodomain.confluence.com`;
const worker = setupServer();
setupRequestMockHandlers(worker);
const config = new ConfigReader({
confluence: {
baseUrl: baseUrl,
token: 'fake_token',
},
});
const integrations = ScmIntegrations.fromConfig(
new ConfigReader({
integrations: {
github: [{ host: 'github.com', token: 'token' }],
},
}),
);
let reader: UrlReader;
let mockContext: ActionContext<{
confluenceUrls: string[];
repoUrl: string;
}>;
const logger = getVoidLogger();
jest.spyOn(logger, 'info');
const mockTmpDir = os.tmpdir();
beforeEach(() => {
reader = {
readUrl: jest.fn(),
readTree: jest.fn().mockResolvedValue({
dir: jest.fn(),
}),
search: jest.fn(),
};
mockContext = {
input: {
confluenceUrls: [
'https://nodomain.confluence.com/display/testing/mkdocs',
],
repoUrl: 'https://notreal.github.com/space/backstage/mkdocs.yml',
},
workspacePath: '/tmp',
logger,
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir),
};
mockFs({ [`${mockTmpDir}/src/docs`]: {} });
});
afterEach(() => {
jest.clearAllMocks();
mockFs.restore();
});
it('should call confluence to markdown action successfully with results array', async () => {
const options = {
reader,
integrations,
config,
};
const responseBody = {
results: [
{
id: '4444444',
type: 'page',
title: 'Testing',
body: {
export_view: {
value: '<p>hello world</p>',
},
},
},
],
};
const responseBodyTwo = {
results: [
{
id: '4444444',
type: 'attachment',
title: 'testing.pdf',
metadata: {
mediaType: 'application/pdf',
},
_links: {
download: '/download/attachments/4444444/testing.pdf',
},
},
],
};
worker.use(
rest.get(`${baseUrl}/rest/api/content`, (_, res, ctx) =>
res(ctx.status(200, 'OK'), ctx.json(responseBody)),
),
rest.get(
`${baseUrl}/rest/api/content/4444444/child/attachment`,
(_, res, ctx) => res(ctx.status(200, 'OK'), ctx.json(responseBodyTwo)),
),
rest.get(
`${baseUrl}/download/attachments/4444444/testing.pdf`,
(_, res, ctx) => res(ctx.status(200, 'OK'), ctx.body('hello')),
),
);
const action = createConfluenceToMarkdownAction(options);
await action.handler(mockContext);
expect(logger.info).toHaveBeenCalledWith(
`Fetching the mkdocs.yml catalog from https://notreal.github.com/space/backstage/mkdocs.yml`,
);
expect(logger.info).toHaveBeenCalledTimes(5);
expect(createWriteStream).toHaveBeenCalledTimes(1);
expect(readFile).toHaveBeenCalledTimes(1);
expect(writeFile).toHaveBeenCalledTimes(1);
});
it('should call confluence to markdown action successfully with empty results array', async () => {
const options = {
reader,
integrations,
config,
};
const responseBody = {
results: [
{
id: '4444444',
type: 'page',
title: 'Testing',
body: {
export_view: {
value: '<p>hello world</p>',
},
},
},
],
};
const responseBodyTwo = {
results: [],
};
worker.use(
rest.get(`${baseUrl}/rest/api/content`, (_, res, ctx) =>
res(ctx.status(200, 'OK'), ctx.json(responseBody)),
),
rest.get(
`${baseUrl}/rest/api/content/4444444/child/attachment`,
(_, res, ctx) => res(ctx.status(200, 'OK'), ctx.json(responseBodyTwo)),
),
);
const action = createConfluenceToMarkdownAction(options);
await action.handler(mockContext);
expect(logger.info).toHaveBeenCalledWith(
`Fetching the mkdocs.yml catalog from https://notreal.github.com/space/backstage/mkdocs.yml`,
);
expect(logger.info).toHaveBeenCalledTimes(5);
expect(createWriteStream).not.toHaveBeenCalled();
expect(readFile).toHaveBeenCalledTimes(1);
expect(writeFile).toHaveBeenCalledTimes(1);
});
it('shoud fail on the first fetch call with response.ok set to false', async () => {
const options = {
reader,
integrations,
config,
};
const responseBody = {};
worker.use(
rest.get(`${baseUrl}/rest/api/content`, (_, res, ctx) =>
res(ctx.status(401, 'nope'), ctx.json(responseBody)),
),
);
const action = createConfluenceToMarkdownAction(options);
await expect(async () => {
await action.handler(mockContext);
}).rejects.toThrow('Request failed with 401 Error');
});
it('should return nothing in results from the first api call and fail', async () => {
const options = {
reader,
integrations,
config,
};
const responseBody = {
results: [],
};
worker.use(
rest.get(`${baseUrl}/rest/api/content`, (_, res, ctx) =>
res(ctx.status(200, 'OK'), ctx.json(responseBody)),
),
);
const action = createConfluenceToMarkdownAction(options);
await expect(async () => {
await action.handler(mockContext);
}).rejects.toThrow(
'Could not find document https://nodomain.confluence.com/display/testing/mkdocs. Please check your input.',
);
});
it('should fail on the second fetch call to confluence', async () => {
const options = {
reader,
integrations,
config,
};
const responseBody = {
results: [
{
id: '4444444',
type: 'page',
title: 'Testing',
body: {
export_view: {
value: '<p>hello world</p>',
},
},
},
],
};
const responseBodyTwo = {};
worker.use(
rest.get(`${baseUrl}/rest/api/content`, (_, res, ctx) =>
res(ctx.status(200, 'OK'), ctx.json(responseBody)),
),
rest.get(
`${baseUrl}/rest/api/content/4444444/child/attachment`,
(_, res, ctx) =>
res(ctx.status(404, 'nope'), ctx.json(responseBodyTwo)),
),
);
const action = createConfluenceToMarkdownAction(options);
await expect(async () => {
await action.handler(mockContext);
}).rejects.toThrow('Request failed with 404 Error');
});
});
@@ -0,0 +1,182 @@
/*
* Copyright 2023 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 { Config } from '@backstage/config';
import { UrlReader } from '@backstage/backend-common';
import { ScmIntegrations } from '@backstage/integration';
import { createFetchPlainAction } from '@backstage/plugin-scaffolder-backend';
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
import { InputError, ConflictError } from '@backstage/errors';
import { NodeHtmlMarkdown } from 'node-html-markdown';
import fs from 'fs-extra';
import parseGitUrl from 'git-url-parse';
import YAML from 'yaml';
import {
readFileAsString,
fetchConfluence,
getAndWriteAttachments,
createConfluenceVariables,
} from './helpers';
/**
* @public
*/
export const createConfluenceToMarkdownAction = (options: {
reader: UrlReader;
integrations: ScmIntegrations;
config: Config;
}) => {
const { config, reader, integrations } = options;
const fetchPlainAction = createFetchPlainAction({ reader, integrations });
type Obj = {
[key: string]: string;
};
return createTemplateAction<{
confluenceUrls: string[];
repoUrl: string;
}>({
id: 'confluence:transform:markdown',
schema: {
input: {
properties: {
confluenceUrls: {
type: 'array',
title: 'Confluence URL',
description:
'Paste your confluence url. Ensure it follows this format: https://{confluence+base+url}/display/{spacekey}/{page+title}',
items: {
type: 'string',
default: 'Confluence URL',
},
},
repoUrl: {
type: 'string',
title: 'GitHub Repo Url',
description:
'mkdocs.yml file location inside the github repo you want to store the document',
},
},
},
},
async handler(ctx) {
const { confluenceUrls, repoUrl } = ctx.input;
const parsedRepoUrl = parseGitUrl(repoUrl);
const filePathToMkdocs = parsedRepoUrl.filepath.substring(
0,
parsedRepoUrl.filepath.lastIndexOf('/') + 1,
);
const dirPath = ctx.workspacePath;
let productArray: string[][] = [];
ctx.logger.info(`Fetching the mkdocs.yml catalog from ${repoUrl}`);
// This grabs the files from Github
const repoFileDir = `${dirPath}/${parsedRepoUrl.filepath}`;
await fetchPlainAction.handler({
...ctx,
input: {
url: `https://${parsedRepoUrl.resource}/${parsedRepoUrl.owner}/${parsedRepoUrl.name}`,
targetPath: dirPath,
},
});
for (const url of confluenceUrls) {
const { spacekey, title, titleWithSpaces } =
await createConfluenceVariables(url);
// This calls confluence to get the page html and page id
const getConfluenceDoc = await fetchConfluence(
`/rest/api/content?title=${title}&spaceKey=${spacekey}&expand=body.export_view`,
config,
);
if (getConfluenceDoc.results.length === 0) {
throw new InputError(
`Could not find document ${url}. Please check your input.`,
);
}
// This gets attachements for the confluence page if they exist
const getDocAttachments = await fetchConfluence(
`/rest/api/content/${getConfluenceDoc.results[0].id}/child/attachment`,
config,
);
if (getDocAttachments.results.length) {
fs.mkdirSync(`${dirPath}/${filePathToMkdocs}docs/img`, {
recursive: true,
});
productArray = await getAndWriteAttachments(
getDocAttachments,
dirPath,
config,
filePathToMkdocs,
);
}
ctx.logger.info(
`starting action for converting ${titleWithSpaces} from Confluence To Markdown`,
);
// This reads mkdocs.yml file
const mkdocsFileContent = await readFileAsString(repoFileDir);
const mkdocsFile = await YAML.parse(mkdocsFileContent);
ctx.logger.info(
`Adding new file - ${titleWithSpaces} to the current mkdocs.yml file`,
);
// This modifies the mkdocs.yml file
if (mkdocsFile !== undefined && mkdocsFile.hasOwnProperty('nav')) {
const { nav } = mkdocsFile;
if (!nav.some((i: Obj) => i.hasOwnProperty(titleWithSpaces))) {
nav.push({
[titleWithSpaces]: `${titleWithSpaces.replace(/\s+/g, '-')}.md`,
});
mkdocsFile.nav = nav;
} else {
throw new ConflictError(
'This document looks to exist inside the GitHub repo. Will end the action.',
);
}
}
await fs.writeFile(repoFileDir, YAML.stringify(mkdocsFile));
// This grabs the confluence html and converts it to markdown and adds attachments
const html = getConfluenceDoc.results[0].body.export_view.value;
const markdownToPublish = NodeHtmlMarkdown.translate(html);
let newString: string = markdownToPublish;
productArray.forEach((product: string[]) => {
// This regex is looking for either [](link to confluence) or ![](link to confluence) in the newly created markdown doc and updating it to point to the versions saved(in ./docs/img) in the local version of GitHub Repo during getAndWriteAttachments
const regex = product[0].includes('.pdf')
? new RegExp(`(\\[.*?\\]\\()(.*?${product[0]}.*?)(\\))`, 'gi')
: new RegExp(`(\\!\\[.*?\\]\\()(.*?${product[0]}.*?)(\\))`, 'gi');
newString = newString.replace(regex, `$1./img/${product[1]}$3`);
});
ctx.logger.info(`Adding new file to repo.`);
await fs.outputFile(
`${dirPath}/${filePathToMkdocs}docs/${titleWithSpaces.replace(
/\s+/g,
'-',
)}.md`,
newString,
);
}
ctx.output('repo', parsedRepoUrl.name);
ctx.output('owner', parsedRepoUrl.owner);
},
});
};
@@ -0,0 +1,128 @@
/*
* Copyright 2023 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 { Config } from '@backstage/config';
import { ResponseError, ConflictError, InputError } from '@backstage/errors';
import fs from 'fs-extra';
import fetch, { Response } from 'node-fetch';
interface Links {
webui: string;
download: string;
thumbnail: string;
self: string;
}
interface Metadata {
mediaType: string;
}
export interface Result {
id: string;
type: string;
status: string;
title: string;
metadata: Metadata;
_links: Links;
}
export interface Results {
results: Result[];
}
export const readFileAsString = async (fileDir: string) => {
const content = await fs.readFile(fileDir, 'utf-8');
return content.toString();
};
export const fetchConfluence = async (relativeUrl: string, config: Config) => {
const baseUrl = config.getString('confluence.baseUrl');
const token = config.getString('confluence.token');
const response: Response = await fetch(`${baseUrl}${relativeUrl}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
throw await ResponseError.fromResponse(response);
}
return response.json();
};
export const getAndWriteAttachments = async (
arr: Results,
workspace: string,
config: Config,
mkdocsDir: string,
) => {
const productArr: string[][] = [];
const baseUrl = config.getString('confluence.baseUrl');
const token = config.getString('confluence.token');
await Promise.all(
await arr.results.map(async (result: Result) => {
const downloadLink = result._links.download;
const downloadTitle = result.title.replace(/ /g, '-');
if (result.metadata.mediaType !== 'application/gliffy+json') {
productArr.push([result.title.replace(/ /g, '%20'), downloadTitle]);
}
const res = await fetch(`${baseUrl}${downloadLink}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) {
throw ResponseError.fromResponse(res);
} else if (res.body !== null) {
fs.openSync(`${workspace}/${mkdocsDir}docs/img/${downloadTitle}`, 'w');
const writeStream = fs.createWriteStream(
`${workspace}/${mkdocsDir}docs/img/${downloadTitle}`,
);
res.body.pipe(writeStream);
await new Promise((resolve, reject) => {
writeStream.on('finish', () => {
resolve(`${workspace}/${mkdocsDir}docs/img/${downloadTitle}`);
});
writeStream.on('error', reject);
});
} else {
throw new ConflictError(
'No Body on the response. Can not save images from Confluence Doc',
);
}
}),
);
return productArr;
};
export const createConfluenceVariables = async (url: string) => {
let spacekey: string | undefined = undefined;
let title: string | undefined = undefined;
let titleWithSpaces: string | undefined = '';
const params = new URL(url);
if (params.pathname.split('/')[1] === 'display') {
spacekey = params.pathname.split('/')[2];
title = params.pathname.split('/')[3];
titleWithSpaces = title?.replace(/\+/g, ' ');
return { spacekey, title, titleWithSpaces };
}
throw new InputError(
'The Url format for Confluence is incorrect. Acceptable format is `<CONFLUENCE_BASE_URL>/display/<SPACEKEY>/<PAGE+TITLE>`',
);
};
@@ -0,0 +1,16 @@
/*
* Copyright 2023 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.
*/
export { createConfluenceToMarkdownAction } from './confluenceToMarkdown';
@@ -0,0 +1,16 @@
/*
* Copyright 2023 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.
*/
export * from './confluence';
@@ -0,0 +1,23 @@
/*
* Copyright 2023 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 confluence-to-markdown module for \@backstage/plugin-scaffolder-backend.
*
* @packageDocumentation
*/
export * from './actions';
@@ -23,7 +23,7 @@ import {
SvgIcon,
Tooltip,
} from '@material-ui/core';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import type { Transformer } from './transformer';
import useCopyToClipboard from 'react-use/lib/useCopyToClipboard';
@@ -69,9 +69,13 @@ const CopyToClipboardButton = ({ text }: CopyToClipboardButtonProps) => {
onClose={handleClose}
leaveDelay={1000}
>
<Button className="md-clipboard md-icon" onClick={handleClick}>
<IconButton
style={{ color: 'inherit' }}
className="md-clipboard md-icon"
onClick={handleClick}
>
<CopyToClipboardIcon />
</Button>
</IconButton>
</CopyToClipboardTooltip>
);
};
@@ -21,6 +21,11 @@ const SIDEBAR_WIDTH = '224px';
export default ({ theme, sidebar }: RuleOptions) => `
/*================== Layout ==================*/
/* mkdocs material v9 compat */
.md-nav__title {
color: var(--md-default-fg-color);
}
.md-grid {
max-width: 100%;
margin: 0;
+146 -84
View File
@@ -518,15 +518,15 @@ __metadata:
languageName: node
linkType: hard
"@aws-sdk/client-cognito-identity@npm:3.296.0":
version: 3.296.0
resolution: "@aws-sdk/client-cognito-identity@npm:3.296.0"
"@aws-sdk/client-cognito-identity@npm:3.298.0":
version: 3.298.0
resolution: "@aws-sdk/client-cognito-identity@npm:3.298.0"
dependencies:
"@aws-crypto/sha256-browser": 3.0.0
"@aws-crypto/sha256-js": 3.0.0
"@aws-sdk/client-sts": 3.296.0
"@aws-sdk/client-sts": 3.298.0
"@aws-sdk/config-resolver": 3.296.0
"@aws-sdk/credential-provider-node": 3.296.0
"@aws-sdk/credential-provider-node": 3.298.0
"@aws-sdk/fetch-http-handler": 3.296.0
"@aws-sdk/hash-node": 3.296.0
"@aws-sdk/invalid-dependency": 3.296.0
@@ -557,20 +557,20 @@ __metadata:
"@aws-sdk/util-user-agent-node": 3.296.0
"@aws-sdk/util-utf8": 3.295.0
tslib: ^2.5.0
checksum: 72c8aac879cc31f156178ecef5895b1c5c802fe1433a3ba0c0010364259815b7e96f7ca7872781e0a512f15ecacb82f62d67902d15f3960a4c0ebf20a1dfd3bd
checksum: 92ec17e7bfa2f71e06a916311ae624e3973b67d0ab1bd0ba7f27481df5cf34f0ee48d26b34bb0c328c7cc0adfd75e4822da0d186fd95cc99a7ac50b165751721
languageName: node
linkType: hard
"@aws-sdk/client-s3@npm:^3.208.0":
version: 3.296.0
resolution: "@aws-sdk/client-s3@npm:3.296.0"
version: 3.298.0
resolution: "@aws-sdk/client-s3@npm:3.298.0"
dependencies:
"@aws-crypto/sha1-browser": 3.0.0
"@aws-crypto/sha256-browser": 3.0.0
"@aws-crypto/sha256-js": 3.0.0
"@aws-sdk/client-sts": 3.296.0
"@aws-sdk/client-sts": 3.298.0
"@aws-sdk/config-resolver": 3.296.0
"@aws-sdk/credential-provider-node": 3.296.0
"@aws-sdk/credential-provider-node": 3.298.0
"@aws-sdk/eventstream-serde-browser": 3.296.0
"@aws-sdk/eventstream-serde-config-resolver": 3.296.0
"@aws-sdk/eventstream-serde-node": 3.296.0
@@ -619,19 +619,19 @@ __metadata:
"@aws-sdk/xml-builder": 3.295.0
fast-xml-parser: 4.1.2
tslib: ^2.5.0
checksum: e7c73260ec654780be882eddad68f39873010a436477c1536ae04abc249ba08280f240a8dea51db0e222fd623db12a5e555514b2dde9f042299643c483b446cd
checksum: 83d5876eb92493f64fc64dc49229b33f44f7f8def6fa9b32f42e341d0cbe50a340daaa9cbf4e7132e8271fd2f0c07a0a9a790249da3b34e54856d5003d3134bb
languageName: node
linkType: hard
"@aws-sdk/client-sqs@npm:^3.208.0":
version: 3.296.0
resolution: "@aws-sdk/client-sqs@npm:3.296.0"
version: 3.298.0
resolution: "@aws-sdk/client-sqs@npm:3.298.0"
dependencies:
"@aws-crypto/sha256-browser": 3.0.0
"@aws-crypto/sha256-js": 3.0.0
"@aws-sdk/client-sts": 3.296.0
"@aws-sdk/client-sts": 3.298.0
"@aws-sdk/config-resolver": 3.296.0
"@aws-sdk/credential-provider-node": 3.296.0
"@aws-sdk/credential-provider-node": 3.298.0
"@aws-sdk/fetch-http-handler": 3.296.0
"@aws-sdk/hash-node": 3.296.0
"@aws-sdk/invalid-dependency": 3.296.0
@@ -665,13 +665,13 @@ __metadata:
"@aws-sdk/util-utf8": 3.295.0
fast-xml-parser: 4.1.2
tslib: ^2.5.0
checksum: ec3c7844ef114e8784efad036f0442bbc1a17bec5878fc22a4641bde3847a57c16e8d5ec92917df9f8a3601b63277852788b16727e9039d389cb8fcf06131e25
checksum: 262b174e0c7df07dcc3eaf2741596caa7b2f9e964421e6e16102b55d11292c8c626061bf6e39175b80b19083f0e593302e7bb5328dbff80ea92b3aa50cb619c8
languageName: node
linkType: hard
"@aws-sdk/client-sso-oidc@npm:3.296.0":
version: 3.296.0
resolution: "@aws-sdk/client-sso-oidc@npm:3.296.0"
"@aws-sdk/client-sso-oidc@npm:3.298.0":
version: 3.298.0
resolution: "@aws-sdk/client-sso-oidc@npm:3.298.0"
dependencies:
"@aws-crypto/sha256-browser": 3.0.0
"@aws-crypto/sha256-js": 3.0.0
@@ -705,13 +705,13 @@ __metadata:
"@aws-sdk/util-user-agent-node": 3.296.0
"@aws-sdk/util-utf8": 3.295.0
tslib: ^2.5.0
checksum: e2cae6747b8300a143e67354913964e2aa7d96fcb7d68e1020cbb40e2e9079a3aea10f427a3cddd98cf8e8463b189d1a15639d713e92d3dff2f8aada7527db9d
checksum: 48786eb7287a7430bd0460d6faf76903aa8979248d626da53727a20b2e4499d5b01e9ebc0206a7f4061673796c07d597d3fc52bd157d765483a59a5e7a484292
languageName: node
linkType: hard
"@aws-sdk/client-sso@npm:3.296.0":
version: 3.296.0
resolution: "@aws-sdk/client-sso@npm:3.296.0"
"@aws-sdk/client-sso@npm:3.298.0":
version: 3.298.0
resolution: "@aws-sdk/client-sso@npm:3.298.0"
dependencies:
"@aws-crypto/sha256-browser": 3.0.0
"@aws-crypto/sha256-js": 3.0.0
@@ -745,18 +745,18 @@ __metadata:
"@aws-sdk/util-user-agent-node": 3.296.0
"@aws-sdk/util-utf8": 3.295.0
tslib: ^2.5.0
checksum: def371cedc2add3127d648c24ea1356517cba510f06679134add036f22c9d139205071fc30e0c753081507881068987efcef2a3a61ca283c4696614236febc08
checksum: 226b8c211e78a384db7106c6c5ed4d8ae7cfb672ed31c595c6f8531d17b5704315b06cba07aabbc35d8dbccc3fe0ed4f1c290e33d9e599e2f75af9d51afdb1fe
languageName: node
linkType: hard
"@aws-sdk/client-sts@npm:3.296.0, @aws-sdk/client-sts@npm:^3.208.0":
version: 3.296.0
resolution: "@aws-sdk/client-sts@npm:3.296.0"
"@aws-sdk/client-sts@npm:3.298.0, @aws-sdk/client-sts@npm:^3.208.0":
version: 3.298.0
resolution: "@aws-sdk/client-sts@npm:3.298.0"
dependencies:
"@aws-crypto/sha256-browser": 3.0.0
"@aws-crypto/sha256-js": 3.0.0
"@aws-sdk/config-resolver": 3.296.0
"@aws-sdk/credential-provider-node": 3.296.0
"@aws-sdk/credential-provider-node": 3.298.0
"@aws-sdk/fetch-http-handler": 3.296.0
"@aws-sdk/hash-node": 3.296.0
"@aws-sdk/invalid-dependency": 3.296.0
@@ -789,7 +789,7 @@ __metadata:
"@aws-sdk/util-utf8": 3.295.0
fast-xml-parser: 4.1.2
tslib: ^2.5.0
checksum: c7a7837601d3bf2cf80e00a498e4f3412d88cccb605a251e65b949e8495874cb7738f0979dc51857f7606e76a568c9c15ecc77800191f54fef181c5cb2bca97b
checksum: a46024185263e548101746cc6c1841d904b02a5bc44e580384bd616ab5325ecb2d27bd0231bce7fab9796e10ce60387c98853e5915b4718f9b2715482c5eca46
languageName: node
linkType: hard
@@ -806,15 +806,15 @@ __metadata:
languageName: node
linkType: hard
"@aws-sdk/credential-provider-cognito-identity@npm:3.296.0":
version: 3.296.0
resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.296.0"
"@aws-sdk/credential-provider-cognito-identity@npm:3.298.0":
version: 3.298.0
resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.298.0"
dependencies:
"@aws-sdk/client-cognito-identity": 3.296.0
"@aws-sdk/client-cognito-identity": 3.298.0
"@aws-sdk/property-provider": 3.296.0
"@aws-sdk/types": 3.296.0
tslib: ^2.5.0
checksum: ef2046e91aa3235e894ac762da7a4d6146fb383f094e504e6a0c6a6950f827c3c81e6826dd622483db5b13df234aa8e73cc4bad089753ef9ac3a1ffb390f75fa
checksum: d6bf9bf5c3d5ef916b931a4a69ae3e54cd90ff86da508a22e24b1b401f771461be73ccacf3aaed844b27019355f3c0c2a64af5815140fdcd7438c7190dc7a207
languageName: node
linkType: hard
@@ -842,38 +842,38 @@ __metadata:
languageName: node
linkType: hard
"@aws-sdk/credential-provider-ini@npm:3.296.0":
version: 3.296.0
resolution: "@aws-sdk/credential-provider-ini@npm:3.296.0"
"@aws-sdk/credential-provider-ini@npm:3.298.0":
version: 3.298.0
resolution: "@aws-sdk/credential-provider-ini@npm:3.298.0"
dependencies:
"@aws-sdk/credential-provider-env": 3.296.0
"@aws-sdk/credential-provider-imds": 3.296.0
"@aws-sdk/credential-provider-process": 3.296.0
"@aws-sdk/credential-provider-sso": 3.296.0
"@aws-sdk/credential-provider-sso": 3.298.0
"@aws-sdk/credential-provider-web-identity": 3.296.0
"@aws-sdk/property-provider": 3.296.0
"@aws-sdk/shared-ini-file-loader": 3.296.0
"@aws-sdk/types": 3.296.0
tslib: ^2.5.0
checksum: 8c3a518ab5eb1b2153f722548e50c11af1cc2d8d2b3eafe5ddb1022bb677eb6fb6cc41bd60a508d45c322c6a653511d9445ca335ea103890f7b534ed0fdfab78
checksum: b729aa62ea23377185c031d5738f4d97e263b2e24eae8643a12ce493ba63729a19c4590f861ead268c6264f5b1bb06dd4cff8e52b4cc0b906c3dae254ab1d11c
languageName: node
linkType: hard
"@aws-sdk/credential-provider-node@npm:3.296.0, @aws-sdk/credential-provider-node@npm:^3.208.0":
version: 3.296.0
resolution: "@aws-sdk/credential-provider-node@npm:3.296.0"
"@aws-sdk/credential-provider-node@npm:3.298.0, @aws-sdk/credential-provider-node@npm:^3.208.0":
version: 3.298.0
resolution: "@aws-sdk/credential-provider-node@npm:3.298.0"
dependencies:
"@aws-sdk/credential-provider-env": 3.296.0
"@aws-sdk/credential-provider-imds": 3.296.0
"@aws-sdk/credential-provider-ini": 3.296.0
"@aws-sdk/credential-provider-ini": 3.298.0
"@aws-sdk/credential-provider-process": 3.296.0
"@aws-sdk/credential-provider-sso": 3.296.0
"@aws-sdk/credential-provider-sso": 3.298.0
"@aws-sdk/credential-provider-web-identity": 3.296.0
"@aws-sdk/property-provider": 3.296.0
"@aws-sdk/shared-ini-file-loader": 3.296.0
"@aws-sdk/types": 3.296.0
tslib: ^2.5.0
checksum: ccc0616dc331764a7378bad898982c2dfb56c8c2d52d4eed003a5265105dfab2598bf40761ef231df28bf9bce17671e86af88415784ae779979ab9c55d75aeb8
checksum: 7ac85fff40f4c266f5890ae02998f166c10cda43c6ce50b59c475e776be3356cadca8bf00f0f687c62a38ce6030597e850f98068c862a1103fee62198c206f3a
languageName: node
linkType: hard
@@ -889,17 +889,17 @@ __metadata:
languageName: node
linkType: hard
"@aws-sdk/credential-provider-sso@npm:3.296.0":
version: 3.296.0
resolution: "@aws-sdk/credential-provider-sso@npm:3.296.0"
"@aws-sdk/credential-provider-sso@npm:3.298.0":
version: 3.298.0
resolution: "@aws-sdk/credential-provider-sso@npm:3.298.0"
dependencies:
"@aws-sdk/client-sso": 3.296.0
"@aws-sdk/client-sso": 3.298.0
"@aws-sdk/property-provider": 3.296.0
"@aws-sdk/shared-ini-file-loader": 3.296.0
"@aws-sdk/token-providers": 3.296.0
"@aws-sdk/token-providers": 3.298.0
"@aws-sdk/types": 3.296.0
tslib: ^2.5.0
checksum: c4916c1d923831240b65bd51c1db3e0f80ce65f2caedf5e45c4799cf0db71ef79b27cd0394a1bd2c94a90bd65ae08b6cbc36416f3c91f7e6c41339c5ef00f919
checksum: cabb308ec19016f7ab416e2f77b9ec4293c1b8a7e129c60133f19532cd9fedb2dbef6471e48119b8e084539cd095b08ad810680d82d2059288ac43d69cea2163
languageName: node
linkType: hard
@@ -915,25 +915,25 @@ __metadata:
linkType: hard
"@aws-sdk/credential-providers@npm:^3.208.0":
version: 3.296.0
resolution: "@aws-sdk/credential-providers@npm:3.296.0"
version: 3.298.0
resolution: "@aws-sdk/credential-providers@npm:3.298.0"
dependencies:
"@aws-sdk/client-cognito-identity": 3.296.0
"@aws-sdk/client-sso": 3.296.0
"@aws-sdk/client-sts": 3.296.0
"@aws-sdk/credential-provider-cognito-identity": 3.296.0
"@aws-sdk/client-cognito-identity": 3.298.0
"@aws-sdk/client-sso": 3.298.0
"@aws-sdk/client-sts": 3.298.0
"@aws-sdk/credential-provider-cognito-identity": 3.298.0
"@aws-sdk/credential-provider-env": 3.296.0
"@aws-sdk/credential-provider-imds": 3.296.0
"@aws-sdk/credential-provider-ini": 3.296.0
"@aws-sdk/credential-provider-node": 3.296.0
"@aws-sdk/credential-provider-ini": 3.298.0
"@aws-sdk/credential-provider-node": 3.298.0
"@aws-sdk/credential-provider-process": 3.296.0
"@aws-sdk/credential-provider-sso": 3.296.0
"@aws-sdk/credential-provider-sso": 3.298.0
"@aws-sdk/credential-provider-web-identity": 3.296.0
"@aws-sdk/property-provider": 3.296.0
"@aws-sdk/shared-ini-file-loader": 3.296.0
"@aws-sdk/types": 3.296.0
tslib: ^2.5.0
checksum: 5daa3d2e69c346f37f9c752c8e25953678d2571c911bb3da4d6b71b7f2ab5af3066890b3116b176a5d1aa9d7163e80c32db70d61bcd901dc0091711fa313a763
checksum: 133c41843a4d5913ab7ec8a833a7868cb243ed56a574e3ab8f557bcc0366933ce09f06d48e17e461eeaf0eb7f86991e527f76b9b22fbb082d5c9af804fe4fc5d
languageName: node
linkType: hard
@@ -1060,8 +1060,8 @@ __metadata:
linkType: hard
"@aws-sdk/lib-storage@npm:^3.208.0":
version: 3.296.0
resolution: "@aws-sdk/lib-storage@npm:3.296.0"
version: 3.298.0
resolution: "@aws-sdk/lib-storage@npm:3.298.0"
dependencies:
"@aws-sdk/middleware-endpoint": 3.296.0
"@aws-sdk/smithy-client": 3.296.0
@@ -1072,7 +1072,7 @@ __metadata:
peerDependencies:
"@aws-sdk/abort-controller": ^3.0.0
"@aws-sdk/client-s3": ^3.0.0
checksum: 2d609ea842dbef07ed6b4ed5d5593d562332dd81141398e9e41e2f8282e37e8293021fa416c28d3c2430b5ffc16e301d09073fd2d20e85983f2ec2352b19eba2
checksum: 5148a92123a4bbf596ead6901cdbfb4985cc59a50437593dfc483ddf29c66a9d9fbf3040b4b6675a2b92517a01bb9fbf0cffc31c3391ad212787cc77d5867d51
languageName: node
linkType: hard
@@ -1430,16 +1430,16 @@ __metadata:
languageName: node
linkType: hard
"@aws-sdk/token-providers@npm:3.296.0":
version: 3.296.0
resolution: "@aws-sdk/token-providers@npm:3.296.0"
"@aws-sdk/token-providers@npm:3.298.0":
version: 3.298.0
resolution: "@aws-sdk/token-providers@npm:3.298.0"
dependencies:
"@aws-sdk/client-sso-oidc": 3.296.0
"@aws-sdk/client-sso-oidc": 3.298.0
"@aws-sdk/property-provider": 3.296.0
"@aws-sdk/shared-ini-file-loader": 3.296.0
"@aws-sdk/types": 3.296.0
tslib: ^2.5.0
checksum: 02d5294fcec153977a7edff3b1843a9c935b11b59adbde26dc84cc5e793d2850b9d4736b29425f384a5c01ca0d747f5b3686d42e1370dae8ed9bc298eda1d888
checksum: aed172e630a4d5de12f77564782486989cf12fe90b837bf0b82347cf1ed6c73c086aacad284d753a9e47676d4bdf251232b845d57f2f9943e5c815bb9321b465
languageName: node
linkType: hard
@@ -7608,6 +7608,29 @@ __metadata:
languageName: unknown
linkType: soft
"@backstage/plugin-scaffolder-backend-module-confluence-to-markdown@workspace:plugins/scaffolder-backend-module-confluence-to-markdown":
version: 0.0.0-use.local
resolution: "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown@workspace:plugins/scaffolder-backend-module-confluence-to-markdown"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/cli": "workspace:^"
"@backstage/config": "workspace:^"
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-backend": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/test-utils": "workspace:^"
"@backstage/types": "workspace:^"
fs-extra: 10.1.0
git-url-parse: ^13.1.0
mock-fs: ^5.2.0
msw: ^1.0.0
node-fetch: ^2.6.7
node-html-markdown: ^1.3.0
yaml: ^2.0.0
languageName: unknown
linkType: soft
"@backstage/plugin-scaffolder-backend-module-cookiecutter@workspace:plugins/scaffolder-backend-module-cookiecutter":
version: 0.0.0-use.local
resolution: "@backstage/plugin-scaffolder-backend-module-cookiecutter@workspace:plugins/scaffolder-backend-module-cookiecutter"
@@ -20245,11 +20268,11 @@ __metadata:
linkType: hard
"cronstrue@npm:^2.2.0":
version: 2.23.0
resolution: "cronstrue@npm:2.23.0"
version: 2.24.0
resolution: "cronstrue@npm:2.24.0"
bin:
cronstrue: bin/cli.js
checksum: 050140ac6452468d6f9032f18038f41b16968502d411a996efd5d42243cfd882271ff20ed4a3cdb25c45bf8f88beeb0579e45e974a11987401e9d383af2641a8
checksum: 2c7d4cfe43bec7b57b1824772641271bb5f5ed0209336ea53796f97b17966dd95cf15ae890f7c2494f639ba489d225bfb882950cda0ec7e5453fa7bf236842dd
languageName: node
linkType: hard
@@ -20407,6 +20430,19 @@ __metadata:
languageName: node
linkType: hard
"css-select@npm:^5.1.0":
version: 5.1.0
resolution: "css-select@npm:5.1.0"
dependencies:
boolbase: ^1.0.0
css-what: ^6.1.0
domhandler: ^5.0.2
domutils: ^3.0.1
nth-check: ^2.0.1
checksum: 2772c049b188d3b8a8159907192e926e11824aea525b8282981f72ba3f349cf9ecd523fdf7734875ee2cb772246c22117fc062da105b6d59afe8dcd5c99c9bda
languageName: node
linkType: hard
"css-to-react-native@npm:^3.0.0":
version: 3.0.0
resolution: "css-to-react-native@npm:3.0.0"
@@ -20461,6 +20497,13 @@ __metadata:
languageName: node
linkType: hard
"css-what@npm:^6.1.0":
version: 6.1.0
resolution: "css-what@npm:6.1.0"
checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe
languageName: node
linkType: hard
"css.escape@npm:1.5.1, css.escape@npm:^1.5.1":
version: 1.5.1
resolution: "css.escape@npm:1.5.1"
@@ -24459,7 +24502,7 @@ __metadata:
languageName: node
linkType: hard
"git-url-parse@npm:^13.0.0":
"git-url-parse@npm:^13.0.0, git-url-parse@npm:^13.1.0":
version: 13.1.0
resolution: "git-url-parse@npm:13.1.0"
dependencies:
@@ -25143,7 +25186,7 @@ __metadata:
languageName: node
linkType: hard
"he@npm:^1.2.0":
"he@npm:1.2.0, he@npm:^1.2.0":
version: 1.2.0
resolution: "he@npm:1.2.0"
bin:
@@ -25666,9 +25709,9 @@ __metadata:
linkType: hard
"immer@npm:^9.0.1, immer@npm:^9.0.7":
version: 9.0.19
resolution: "immer@npm:9.0.19"
checksum: f02ee53989989c287cd548a3d817fccf0bfe56db919755ee94a72ea3ae78a00363fba93ee6c010fe54a664380c29c53d44ed4091c6a86cae60957ad2cfabc010
version: 9.0.21
resolution: "immer@npm:9.0.21"
checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432
languageName: node
linkType: hard
@@ -29354,11 +29397,11 @@ __metadata:
linkType: hard
"marked@npm:^4.0.10, marked@npm:^4.0.14":
version: 4.2.12
resolution: "marked@npm:4.2.12"
version: 4.3.0
resolution: "marked@npm:4.3.0"
bin:
marked: bin/marked.js
checksum: bd551cd61028ee639d4ca2ccdfcc5a6ba4227c1b143c4538f3cde27f569dcb57df8e6313560394645b418b84a7336c07ab1e438b89b6324c29d7d8cdd3102d63
checksum: 0db6817893952c3ec710eb9ceafb8468bf5ae38cb0f92b7b083baa13d70b19774674be04db5b817681fa7c5c6a088f61300815e4dd75a59696f4716ad69f6260
languageName: node
linkType: hard
@@ -30905,6 +30948,25 @@ __metadata:
languageName: node
linkType: hard
"node-html-markdown@npm:^1.3.0":
version: 1.3.0
resolution: "node-html-markdown@npm:1.3.0"
dependencies:
node-html-parser: ^6.1.1
checksum: 303affd75bf11e92f004047e283aa05da5c8ae8696c1f28f811e9f61762c55b4480e0e5986a9a4b399791485b835380af8ab0554ebf867d6cf9be362abedcf5d
languageName: node
linkType: hard
"node-html-parser@npm:^6.1.1":
version: 6.1.5
resolution: "node-html-parser@npm:6.1.5"
dependencies:
css-select: ^5.1.0
he: 1.2.0
checksum: b54257b31954be17d473c86a2fede53d5e238708f3d88577c98881c28ab66013fd37044903f6f3cd662b56d882681fb511bca75a80a80b62f7111b32b39eebae
languageName: node
linkType: hard
"node-int64@npm:^0.4.0":
version: 0.4.0
resolution: "node-int64@npm:0.4.0"
@@ -31205,12 +31267,12 @@ __metadata:
languageName: node
linkType: hard
"nth-check@npm:^2.0.0":
version: 2.0.1
resolution: "nth-check@npm:2.0.1"
"nth-check@npm:^2.0.0, nth-check@npm:^2.0.1":
version: 2.1.1
resolution: "nth-check@npm:2.1.1"
dependencies:
boolbase: ^1.0.0
checksum: 5386d035c48438ff304fe687704d93886397349d1bed136de97aeae464caba10e8ffac55a04b215b86b3bc8897f33e0a5aa1045a9d8b2f251ae61b2a3ad3e450
checksum: 5afc3dafcd1573b08877ca8e6148c52abd565f1d06b1eb08caf982e3fa289a82f2cae697ffb55b5021e146d60443f1590a5d6b944844e944714a5b549675bcd3
languageName: node
linkType: hard