From b708db5a94364d349de2ac2acebfaa08abf87a9c Mon Sep 17 00:00:00 2001 From: Kurt King Date: Wed, 25 Dec 2024 11:43:52 -0700 Subject: [PATCH] Migrate announcements-backend from procore-oss (#2399) * migrate announcements-backend Signed-off-by: Kurt King * update workspace deps Signed-off-by: Kurt King * fix: backstage pluginPackages Signed-off-by: Kurt King * remove local.sqlite from git tracking Signed-off-by: Kurt King --------- Signed-off-by: Kurt King --- .../announcements-backend/.eslintrc.js | 1 + .../plugins/announcements-backend/.gitignore | 2 + .../plugins/announcements-backend/README.md | 100 + .../202210311212_announcements_schemas.js | 47 + .../202304071343_announcements_categories.js | 48 + ...20240929155025_announcements_add_active.js | 31 + .../20240930025128_backfill_active_column.js | 25 + .../db/seeds/01_categories.js | 38 + .../db/seeds/02_announcements.js | 543 +++++ .../announcements-backend/dev/index.ts | 45 + .../plugins/announcements-backend/knexfile.js | 31 + .../announcements-backend/package.json | 89 + .../announcements-backend/report.api.md | 17 + .../announcements-backend/src/index.ts | 24 + .../announcements-backend/src/plugin.ts | 67 + .../announcements-backend/src/router.test.ts | 111 + .../announcements-backend/src/router.ts | 342 +++ .../announcementsContextBuilder.test.ts | 61 + .../service/announcementsContextBuilder.ts | 73 + .../src/service/index.ts | 21 + .../src/service/model.ts | 26 + .../persistence/AnnouncementsDatabase.test.ts | 442 ++++ .../persistence/AnnouncementsDatabase.ts | 245 ++ .../persistence/CategoriesDatabase.test.ts | 80 + .../service/persistence/CategoriesDatabase.ts | 51 + .../src/service/persistence/index.ts | 19 + .../persistence/persistenceContext.test.ts | 47 + .../service/persistence/persistenceContext.ts | 58 + .../src/service/signal.ts | 53 + .../announcements-backend/src/setupTests.ts | 16 + .../plugins/announcements-common/package.json | 1 + .../plugins/announcements-node/package.json | 1 + .../plugins/announcements/package.json | 1 + .../package.json | 4 +- .../report.api.md | 33 + .../collators/AnnouncementCollatorFactory.ts | 8 +- .../src/index.ts | 6 + workspaces/announcements/yarn.lock | 2061 ++++++++++++++++- 38 files changed, 4754 insertions(+), 114 deletions(-) create mode 100644 workspaces/announcements/plugins/announcements-backend/.eslintrc.js create mode 100644 workspaces/announcements/plugins/announcements-backend/.gitignore create mode 100644 workspaces/announcements/plugins/announcements-backend/README.md create mode 100644 workspaces/announcements/plugins/announcements-backend/db/migrations/202210311212_announcements_schemas.js create mode 100644 workspaces/announcements/plugins/announcements-backend/db/migrations/202304071343_announcements_categories.js create mode 100644 workspaces/announcements/plugins/announcements-backend/db/migrations/20240929155025_announcements_add_active.js create mode 100644 workspaces/announcements/plugins/announcements-backend/db/migrations/20240930025128_backfill_active_column.js create mode 100644 workspaces/announcements/plugins/announcements-backend/db/seeds/01_categories.js create mode 100644 workspaces/announcements/plugins/announcements-backend/db/seeds/02_announcements.js create mode 100644 workspaces/announcements/plugins/announcements-backend/dev/index.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/knexfile.js create mode 100644 workspaces/announcements/plugins/announcements-backend/package.json create mode 100644 workspaces/announcements/plugins/announcements-backend/report.api.md create mode 100644 workspaces/announcements/plugins/announcements-backend/src/index.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/plugin.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/router.test.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/router.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.test.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/index.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/model.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.test.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.test.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/persistence/index.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.test.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/service/signal.ts create mode 100644 workspaces/announcements/plugins/announcements-backend/src/setupTests.ts diff --git a/workspaces/announcements/plugins/announcements-backend/.eslintrc.js b/workspaces/announcements/plugins/announcements-backend/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/announcements/plugins/announcements-backend/.gitignore b/workspaces/announcements/plugins/announcements-backend/.gitignore new file mode 100644 index 0000000000..1706de62ed --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/.gitignore @@ -0,0 +1,2 @@ +# local sqlite database +db/local.sqlite diff --git a/workspaces/announcements/plugins/announcements-backend/README.md b/workspaces/announcements/plugins/announcements-backend/README.md new file mode 100644 index 0000000000..3f88f773f9 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/README.md @@ -0,0 +1,100 @@ +# announcements + +This is the backend for the Announcements plugin. This plugin provides: + +- REST APIs for managing announcements and categories +- Integration with the [`@backstage/plugin-search`](https://github.com/backstage/backstage/tree/master/plugins/search) plugin +- Integration with the [`@backstage/plugin-permission-backend`](https://github.com/backstage/backstage/tree/master/plugins/permission-backend) plugin + +## Installation + +This plugin is installed via the `@backstage-community/plugin-announcements-backend` package. To install it to your backend package, run the following command: + +```bash +# From your root directory +yarn --cwd packages/backend add @backstage-community/plugin-announcements-backend +``` + +Then add the plugin to your backend in `packages/backend/src/index.ts`: + +```ts +const backend = createBackend(); +// ... +backend.add(import('@backstage-community/plugin-announcements-backend')); +``` + +## Development + +This plugin backend can be started in a standalone mode from directly in this +package with `yarn start`. It is a limited setup that is most convenient when +developing the plugin backend itself. + +If you want to run the entire project, including the frontend, run `yarn dev` from the root directory. + +### Setup + +```sh +# install dependencies +yarn install + +# set .env +cp env.sample .env +source .env + +# start the backend +yarn start +``` + +### Database + +The plugin includes support for postgres and better-sqlite3 databases. By default, the plugin uses a postgres database via docker-compose. Update the `app-config.yaml` to use the `better-sqlite3` database. + +#### Postgres + +The postgres database can be started with docker-compose. Don't forget to copy the `env.sample`. + +```sh +# start the postgres database +docker-compose up -d + +# stop the postgres database +docker-compose down -v +``` + +#### better-sqlite3 + +The better-sqlite3 database can be seeded with categories and announcements. + +With the backend running, + +```sh +# runs migrations and seeds the database +yarn db:setup + +# or run them separately +yarn db:migrations +yarn db:seed +``` + +This will create a `local.sqlite` file under the `db/` directory. + +Visit [knexjs](https://knexjs.org/guide/migrations.html) to learn more about the database migrations and seeding. + +### API Examples + +```sh +# get all announcements +curl http://localhost:7007/api/announcements/announcements + +# get all categories +curl http://localhost:7007/api/categories +``` + +```ts +// get all announcements +const response = await fetch( + 'http://localhost:7007/api/announcements/announcements', +); +const data = await response.json(); +return data; +``` diff --git a/workspaces/announcements/plugins/announcements-backend/db/migrations/202210311212_announcements_schemas.js b/workspaces/announcements/plugins/announcements-backend/db/migrations/202210311212_announcements_schemas.js new file mode 100644 index 0000000000..d33b3e70de --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/db/migrations/202210311212_announcements_schemas.js @@ -0,0 +1,47 @@ +/* + * 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. + */ + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.createTable('announcements', table => { + table.comment('The table for announcements.'); + table.text('id').notNullable().primary().comment('Announcement ID'); + table + .string('publisher') + .notNullable() + .comment('A catalog reference to the team publishing the announcement.'); + table.text('title').notNullable().comment('Title of the announcement.'); + table.text('excerpt').notNullable().comment('Short summary (one-liner).'); + table.text('body').notNullable(); + table + .timestamp('created_at') + .notNullable() + .index('announcements_created_at_idx'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('announcements', table => { + table.dropIndex([], 'announcements_created_at_idx'); + }); + + await knex.schema.dropTable('announcements'); +}; diff --git a/workspaces/announcements/plugins/announcements-backend/db/migrations/202304071343_announcements_categories.js b/workspaces/announcements/plugins/announcements-backend/db/migrations/202304071343_announcements_categories.js new file mode 100644 index 0000000000..0ca634a058 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/db/migrations/202304071343_announcements_categories.js @@ -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. + */ + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.createTable('categories', table => { + table.comment('The table for announcement categories.'); + table.string('slug').notNullable().primary().comment('Category slug'); + table.string('title').notNullable().comment('Title of the category.'); + }); + + await knex.schema.alterTable('announcements', table => { + table.string('category').comment('Announcement category'); + + table + .foreign('category', 'category_fk') + .references('slug') + .inTable('categories') + .onDelete('SET NULL'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('announcements', table => { + table.dropForeign('category', 'category_fk'); + table.dropColumn('category'); + }); + + await knex.schema.dropTable('categories'); +}; diff --git a/workspaces/announcements/plugins/announcements-backend/db/migrations/20240929155025_announcements_add_active.js b/workspaces/announcements/plugins/announcements-backend/db/migrations/20240929155025_announcements_add_active.js new file mode 100644 index 0000000000..a65f9c9665 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/db/migrations/20240929155025_announcements_add_active.js @@ -0,0 +1,31 @@ +/* + * 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. + */ + +exports.up = async function up(knex) { + await knex.schema.alterTable('announcements', table => { + table.boolean('active'); + }); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('announcements', table => { + table.dropColumn('active'); + }); +}; diff --git a/workspaces/announcements/plugins/announcements-backend/db/migrations/20240930025128_backfill_active_column.js b/workspaces/announcements/plugins/announcements-backend/db/migrations/20240930025128_backfill_active_column.js new file mode 100644 index 0000000000..583f9b8717 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/db/migrations/20240930025128_backfill_active_column.js @@ -0,0 +1,25 @@ +/* + * 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. + */ + +exports.up = async function up(knex) { + await knex.table('announcements').update('active', true).whereNull('active'); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async function down(_knex) {}; diff --git a/workspaces/announcements/plugins/announcements-backend/db/seeds/01_categories.js b/workspaces/announcements/plugins/announcements-backend/db/seeds/01_categories.js new file mode 100644 index 0000000000..e4c9b9f269 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/db/seeds/01_categories.js @@ -0,0 +1,38 @@ +/* + * 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. + */ + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.seed = async function (knex) { + // Deletes ALL existing entries + await knex('categories').del(); + await knex('categories').insert([ + { slug: 'infrastructure', title: 'Infrastructure' }, + { slug: 'internal-developer-portal', title: 'IDP' }, + { slug: 'cost-savings', title: 'Cost Savings' }, + { slug: 'javascript', title: 'Javascript' }, + { slug: 'ruby-on-rails', title: 'Ruby on Rails' }, + { slug: 'monolith', title: 'Monolith' }, + { slug: 'micro-service', title: 'Micro Service' }, + { slug: 'engineering-community', title: 'Engineering Community' }, + { slug: 'product-updates', title: 'Product Updates' }, + { slug: 'security', title: 'Security' }, + { slug: 'documentation', title: 'Documenation' }, + { slug: 'events', title: 'Events' }, + ]); +}; diff --git a/workspaces/announcements/plugins/announcements-backend/db/seeds/02_announcements.js b/workspaces/announcements/plugins/announcements-backend/db/seeds/02_announcements.js new file mode 100644 index 0000000000..b1b97576cb --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/db/seeds/02_announcements.js @@ -0,0 +1,543 @@ +/* + * 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. + */ + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.seed = async function (knex) { + // Deletes ALL existing entries + await knex('announcements').del(); + await knex('announcements').insert([ + { + id: '0', + publisher: 'default:group/developer-enablement', + title: 'Introducing Backstage', + excerpt: 'The developer enablement team is exited to announce Backstage!', + body: `Backstage is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly — without compromising autonomy. Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end.`, + created_at: '2020-01-02T15:28:08.539+00:00', + category: 'internal-developer-portal', + active: 1, + }, + { + id: '1', + publisher: 'default:group/sre', + title: 'New DORA Metrics', + excerpt: 'Q1 DORA metrics are here', + body: 'The DevOps Research and Assessment (DORA) team was founded in 2014 as an independent research group focused on investigating the practices and capabilities that drive high performance in software delivery and financial results. The DORA team is known for the annual State of DevOps report that has been published for seven consecutive years, from 2014 to 2021. In 2019, DORA was acquired by Google.', + created_at: '2021-03-02T04:30:08.539+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '2', + publisher: 'default:user/guest', + title: 'Community blog post', + excerpt: 'How to scale your infrastructure', + body: `Today we will dive into some strategies you can use to scale Ruby on Rails applications to a huge user base. + + One obvious way of scaling applications is to throw more money at them. And it works amazingly well — add a few more servers, upgrade your database server, and voila, a lot of the performance issues just go poof! + + But it is often also possible to scale applications without adding more servers. That's what we will discuss today. + + Let's get going! + + Randomly taken from [this](https://blog.appsignal.com/2022/11/09/how-to-scale-ruby-on-rails-applications.html) blog post. + `, + category: 'infrastructure', + created_at: '2021-03-17T18:28:08.539+00:00', + active: 1, + }, + { + id: '3', + publisher: 'default:group/incident-management', + title: 'Incident Response Metrics', + excerpt: 'Quarterly respone metrics', + body: 'You will find the incident response metrics for the last quarter here. Our average time to resolve an incident is 2 hours. We are aiming to reduce this to 1 hour by the end of the year.', + created_at: '2022-01-02T15:28:08.539+00:00', + active: 1, + }, + { + id: '4', + publisher: 'default:user/kurtaking', + title: 'What a wonderful announcement', + excerpt: 'Happy to announce this announcement', + body: 'We are happy to announce the new Announcements feature!', + created_at: '2022-02-04T14:47:08.539+00:00', + active: 1, + }, + { + id: '5', + publisher: 'default:group/developer-enablement', + title: 'Introducing Software Catalog', + excerpt: 'Thank you Spotify. The Software Catalog is here!', + body: 'The Backstage Software Catalog is a centralized system that keeps track of ownership and metadata for all the software in your ecosystem (services, websites, libraries, data pipelines, etc). The catalog is built around the concept of metadata YAML files stored together with the code, which are then harvested and visualized in Backstage.', + created_at: '2022-03-26T01:28:08.539+00:00', + category: 'internal-developer-portal', + active: 1, + }, + { + id: '6', + publisher: 'default:group/sre', + title: 'New feature: Announcements', + excerpt: 'We are happy to announce the new Announcements feature!', + body: 'We are happy to announce the new Announcements feature!', + created_at: '2022-04-04T01:28:08.539+00:00', + active: 1, + }, + { + id: '7', + publisher: 'default:user/guest', + title: 'Required upgrade to Node 18', + excerpt: 'All services are required to upgrade to Node 18', + body: 'Service leveraging node are required to upgrade to Node 18 by the end of the month. Please contact the platform team if you have any questions.', + category: 'javascript', + created_at: '2023-02-26T01:52:01.539+00:00', + active: 1, + }, + { + id: '8', + publisher: 'default:user/guest', + title: 'Lorem Ipsum: A really long announcement example', + excerpt: 'A long announcement!', + body: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', + created_at: '2023-03-01T03:28:08.539+00:00', + category: 'product-updates', + active: 1, + }, + { + id: '9', + publisher: 'default:group/documentation', + title: 'Documentation, upgrading to TechDocs', + excerpt: + 'TechDocs is Spotify’s homegrown docs-like-code solution built directly into Backstage.', + body: 'TechDocs is Spotify’s homegrown docs-like-code solution built directly into Backstage. Engineers write their documentation in Markdown files which live together with their code - and with little configuration get a nice-looking doc site in Backstage. Today, it is one of the core products in Spotify’s developer experience offering with 5000+ documentation sites and around 10000 average daily hits. Read more about TechDocs in its announcement blog post. 🎉 More info [here](https://backstage.io/docs/features/techdocs/)', + created_at: '2023-04-15T01:28:08.539+00:00', + category: 'product-updates', + active: 1, + }, + { + id: '10', + publisher: 'default:group/cloud-provisioning', + title: 'Brownout: Service A', + excerpt: 'Service A will be browned out for 2 hours', + body: 'Service A will be browned out for 2 hours. Please contact the environments team if you have any questions.', + created_at: '2023-06-04T01:28:08.539+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '11', + publisher: 'default:group/team-environments', + title: 'Scheduled Maintenance: Database Upgrade', + excerpt: + 'We will be performing a scheduled maintenance to upgrade the database', + body: 'We will be performing a scheduled maintenance to upgrade the database. During this time, there may be temporary service disruptions. We apologize for any inconvenience caused.', + created_at: '2023-06-10T08:00:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '12', + publisher: 'default:group/developer-enablement', + title: 'New Feature: Code Review Checklist', + excerpt: 'Introducing the Code Review Checklist feature', + body: 'We are excited to introduce the Code Review Checklist feature. This feature provides a standardized checklist for code reviews, helping to improve code quality and maintain consistency across the organization.', + created_at: '2023-06-15T14:30:00.000+00:00', + category: 'internal-developer-portal', + active: 1, + }, + { + id: '13', + publisher: 'default:user/guest', + title: 'Upcoming Webinar: Introduction to Backstage', + excerpt: 'Join us for a webinar on the basics of Backstage', + body: "We invite you to join us for an upcoming webinar on the basics of Backstage. This webinar is designed for both new and existing users who want to learn more about the features and capabilities of Backstage. Don't miss out!", + created_at: '2023-06-20T10:00:00.000+00:00', + active: 1, + }, + { + id: '14', + publisher: 'default:group/sre', + title: 'New Monitoring Dashboard', + excerpt: 'Introducing the new Monitoring Dashboard', + body: 'We are pleased to announce the release of the new Monitoring Dashboard. This dashboard provides real-time visibility into the health and performance of our systems, allowing us to proactively identify and resolve issues. Check it out!', + created_at: '2023-06-25T16:45:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '15', + publisher: 'default:user/guest', + title: 'Security Alert: Vulnerability Patch', + excerpt: 'Action required: Apply the latest security patch', + body: 'A critical security vulnerability has been discovered in our system. It is important that all users apply the latest security patch immediately to protect against potential exploits. Please follow the provided instructions to apply the patch.', + created_at: '2023-06-30T09:15:00.000+00:00', + category: 'security', + active: 1, + }, + { + id: '16', + publisher: 'default:group/documentation', + title: 'New Tutorial: Getting Started with Backstage', + excerpt: 'Learn how to get started with Backstage', + body: 'We have published a new tutorial that provides a step-by-step guide on getting started with Backstage. Whether you are a beginner or an experienced user, this tutorial will help you quickly set up and navigate the Backstage platform. Happy learning!', + created_at: '2023-07-05T13:30:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '17', + publisher: 'default:group/team-environments', + title: 'Planned Outage: Service B', + excerpt: 'Service B will be temporarily unavailable due to maintenance', + body: 'We will be performing maintenance on Service B, which will result in a temporary outage. We apologize for any inconvenience caused and assure you that we are working diligently to minimize the impact and restore service as quickly as possible.', + created_at: '2023-07-10T07:45:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '18', + publisher: 'default:group/sre', + title: 'New Feature: Automated Incident Response', + excerpt: 'Introducing the Automated Incident Response feature', + body: 'We are excited to announce the release of the Automated Incident Response feature. This feature leverages machine learning algorithms to automatically detect and respond to incidents, reducing response times and improving overall system reliability. Try it out!', + created_at: '2023-07-15T15:00:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '19', + publisher: 'default:user/guest', + title: 'Upcoming Conference: Backstage Connect', + excerpt: 'Join us for the annual Backstage Connect conference', + body: "We are thrilled to invite you to the annual Backstage Connect conference. This conference brings together industry experts, thought leaders, and Backstage users from around the world to share insights, best practices, and success stories. Don't miss this opportunity to connect and learn!", + created_at: '2023-07-20T11:30:00.000+00:00', + category: 'events', + active: 1, + }, + { + id: '20', + publisher: 'default:group/developer-enablement', + title: 'New Feature: API Documentation Generator', + excerpt: 'Introducing the API Documentation Generator', + body: 'We are pleased to introduce the API Documentation Generator, a powerful tool that automatically generates comprehensive documentation for your APIs. With this feature, you can easily keep your API documentation up to date and ensure that developers have the information they need to integrate with your services.', + created_at: '2023-07-25T17:15:00.000+00:00', + category: 'internal-developer-portal', + active: 1, + }, + { + id: '21', + publisher: 'default:user/guest', + title: 'Important Announcement: System Upgrade', + excerpt: 'We will be performing a system upgrade', + body: 'We will be performing a system upgrade to enhance performance and introduce new features. During this time, there may be temporary service disruptions. We apologize for any inconvenience caused and appreciate your patience.', + created_at: '2023-07-30T10:45:00.000+00:00', + active: 1, + }, + { + id: '22', + publisher: 'default:group/sre', + title: 'New Feature: Incident Analysis Dashboard', + excerpt: 'Introducing the Incident Analysis Dashboard', + body: 'We are excited to announce the release of the Incident Analysis Dashboard. This dashboard provides detailed insights into past incidents, allowing us to analyze root causes, identify trends, and implement preventive measures. Explore the dashboard and gain valuable insights!', + created_at: '2023-08-04T16:30:00.000+00:00', + active: 1, + }, + { + id: '23', + publisher: 'default:user/guest', + title: 'Webinar Recap: Backstage Best Practices', + excerpt: 'Missed the webinar? Read the recap of Backstage best practices', + body: 'In case you missed our recent webinar on Backstage best practices, we have prepared a recap for you. This recap highlights key takeaways, tips, and tricks shared during the webinar. Catch up on the latest best practices and make the most out of Backstage!', + created_at: '2023-08-09T12:00:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '24', + publisher: 'default:group/team-environments', + title: 'Planned Maintenance: Network Upgrade', + excerpt: 'We will be upgrading the network infrastructure', + body: 'We will be performing a planned maintenance to upgrade our network infrastructure. This upgrade will enhance network performance and reliability. During the maintenance window, there may be intermittent connectivity issues. We apologize for any inconvenience caused.', + created_at: '2023-08-14T08:30:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '25', + publisher: 'default:group/developer-enablement', + title: 'New Feature: Test Coverage Analyzer', + excerpt: 'Introducing the Test Coverage Analyzer', + body: 'We are thrilled to introduce the Test Coverage Analyzer, a powerful tool that helps you measure and improve test coverage in your codebase. With this feature, you can identify areas of your code that lack proper test coverage and take necessary actions to ensure code quality.', + created_at: '2023-08-19T14:45:00.000+00:00', + category: 'internal-developer-portal', + active: 1, + }, + { + id: '26', + publisher: 'default:user/guest', + title: 'Upcoming Workshop: Backstage Deep Dive', + excerpt: 'Join us for an in-depth workshop on Backstage', + body: "We are excited to invite you to an upcoming workshop on Backstage. This workshop is designed for intermediate and advanced users who want to dive deeper into the advanced features and customization options of Backstage. Don't miss this opportunity to expand your Backstage knowledge!", + created_at: '2023-08-24T10:15:00.000+00:00', + category: 'events', + active: 1, + }, + { + id: '27', + publisher: 'default:group/sre', + title: 'New Feature: Anomaly Detection', + excerpt: 'Introducing the Anomaly Detection feature', + body: 'We are pleased to announce the release of the Anomaly Detection feature. This feature leverages machine learning algorithms to automatically detect anomalies in system metrics, helping us identify potential issues before they impact the user experience. Try it out and stay ahead of potential problems!', + created_at: '2023-08-29T16:00:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '28', + publisher: 'default:user/guest', + title: 'Important Update: Service Deprecation', + excerpt: 'Service X will be deprecated in the upcoming release', + body: 'In the upcoming release, we will be deprecating Service X. This means that Service X will no longer receive updates or support. We recommend migrating to alternative solutions as soon as possible to avoid any disruptions. Please reach out to the support team if you have any questions.', + created_at: '2023-09-03T09:30:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '29', + publisher: 'default:group/documentation', + title: 'New Tutorial: Advanced Backstage Customization', + excerpt: 'Learn advanced customization techniques for Backstage', + body: "We have published a new tutorial that explores advanced customization techniques for Backstage. This tutorial covers topics such as theming, plugin development, and extending Backstage's core functionality. Take your Backstage customization skills to the next level!", + created_at: '2023-09-08T15:45:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '30', + publisher: 'default:group/team-environments', + title: 'Planned Outage: Service C', + excerpt: 'Service C will be temporarily unavailable due to maintenance', + body: 'We will be performing maintenance on Service C, which will result in a temporary outage. We apologize for any inconvenience caused and assure you that we are working diligently to minimize the impact and restore service as quickly as possible.', + created_at: '2023-09-13T11:00:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '31', + publisher: 'default:group/sre', + title: 'New Feature: Auto Scaling', + excerpt: 'Introducing the Auto Scaling feature', + body: 'We are excited to announce the release of the Auto Scaling feature. This feature automatically adjusts the number of resources allocated to a service based on demand, ensuring optimal performance and cost efficiency. Experience the benefits of automatic scaling!', + created_at: '2023-09-18T17:15:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '32', + publisher: 'default:user/guest', + title: 'Webinar Recap: Backstage Plugin Development', + excerpt: + 'Missed the webinar? Read the recap of Backstage plugin development', + body: 'In case you missed our recent webinar on Backstage plugin development, we have prepared a recap for you. This recap highlights key takeaways, best practices, and examples shared during the webinar. Catch up on the latest plugin development techniques and enhance your Backstage experience!', + created_at: '2023-09-23T12:30:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '33', + publisher: 'default:group/developer-enablement', + title: 'New Feature: Performance Profiler', + excerpt: 'Introducing the Performance Profiler', + body: 'We are thrilled to introduce the Performance Profiler, a powerful tool that helps you analyze and optimize the performance of your applications. With this feature, you can identify performance bottlenecks, optimize resource usage, and deliver faster and more efficient applications.', + created_at: '2023-09-28T08:45:00.000+00:00', + category: 'internal-developer-portal', + active: 1, + }, + { + id: '34', + publisher: 'default:user/guest', + title: 'Upcoming Conference: Backstage Innovate', + excerpt: 'Join us for the annual Backstage Innovate conference', + body: "We are thrilled to invite you to the annual Backstage Innovate conference. This conference brings together industry leaders, innovators, and Backstage enthusiasts to explore the latest trends, technologies, and use cases of Backstage. Don't miss this opportunity to connect and innovate!", + created_at: '2023-10-03T15:00:00.000+00:00', + category: 'events', + active: 1, + }, + { + id: '35', + publisher: 'default:group/observability', + title: 'New Feature: Log Analysis', + excerpt: 'Introducing the Log Analysis feature', + body: 'We are pleased to announce the release of the Log Analysis feature. This feature provides powerful log search and analysis capabilities, allowing us to quickly identify and troubleshoot issues. Dive into your logs and gain valuable insights!', + created_at: '2023-10-08T11:15:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '36', + publisher: 'default:user/guest', + title: 'Important Announcement: Service Migration', + excerpt: 'Service Y will be migrated to a new infrastructure', + body: 'We will be migrating Service Y to a new infrastructure to improve performance and reliability. During the migration, there may be temporary service disruptions. We apologize for any inconvenience caused and appreciate your understanding.', + created_at: '2023-10-13T17:30:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '37', + publisher: 'default:group/documentation', + title: 'New Tutorial: Backstage Custom Plugin Development', + excerpt: 'Learn how to develop custom plugins for Backstage', + body: 'We have published a new tutorial that guides you through the process of developing custom plugins for Backstage. This tutorial covers plugin architecture, API integration, and best practices for plugin development. Start building your own custom plugins today!', + created_at: '2023-10-18T13:45:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '38', + publisher: 'default:group/team-environments', + title: 'Planned Outage: Service D', + excerpt: 'Service D will be temporarily unavailable due to maintenance', + body: 'We will be performing maintenance on Service D, which will result in a temporary outage. We apologize for any inconvenience caused and assure you that we are working diligently to minimize the impact and restore service as quickly as possible.', + created_at: '2023-10-23T10:00:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '39', + publisher: 'default:group/platform-engineering', + title: 'New Feature: Distributed Tracing', + excerpt: 'Introducing the Distributed Tracing feature', + body: 'We are excited to announce the release of the Distributed Tracing feature. This feature provides end-to-end visibility into the flow of requests across distributed systems, helping us identify performance bottlenecks and optimize system performance. Trace your requests and gain valuable insights!', + created_at: '2023-10-28T16:15:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '40', + publisher: 'default:user/security', + title: 'Webinar Recap: Backstage Security Best Practices', + excerpt: + 'Missed the webinar? Read the recap of Backstage security best practices', + body: 'In case you missed our recent webinar on Backstage security best practices, we have prepared a recap for you. This recap highlights key takeaways, security measures, and recommendations shared during the webinar. Stay informed and protect your Backstage instance!', + created_at: '2023-11-02T12:30:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '41', + publisher: 'default:group/team-environments', + title: 'New Feature: Environment Variables', + excerpt: 'Introducing the Environment Variables feature', + body: 'We are excited to introduce the Environment Variables feature. This feature allows you to manage and configure environment-specific variables for your services, making it easier to handle different environments and deployments. Simplify your configuration management with environment variables!', + created_at: '2023-11-07T09:15:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '42', + publisher: 'default:group/sre', + title: 'Planned Outage: Service E', + excerpt: 'Service E will be temporarily unavailable due to maintenance', + body: 'We will be performing maintenance on Service E, which will result in a temporary outage. We apologize for any inconvenience caused and assure you that we are working diligently to minimize the impact and restore service as quickly as possible.', + created_at: '2023-11-12T14:30:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '43', + publisher: 'default:user/guest', + title: 'New Tutorial: Backstage Plugin Testing', + excerpt: 'Learn how to test your Backstage plugins', + body: 'We have published a new tutorial that guides you through the process of testing your Backstage plugins. This tutorial covers unit testing, integration testing, and best practices for plugin testing. Ensure the quality and reliability of your plugins with comprehensive testing!', + created_at: '2023-11-17T11:45:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '44', + publisher: 'default:group/developer-enablement', + title: 'New Feature: API Documentation', + excerpt: 'Introducing the API Documentation feature', + body: 'We are pleased to announce the release of the API Documentation feature. This feature provides a centralized location to document and explore APIs used in your services. Easily access API specifications, examples, and usage guidelines. Streamline your API documentation process!', + created_at: '2023-11-22T17:00:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '45', + publisher: 'default:user/guest', + title: 'Upcoming Conference: Backstage Connect', + excerpt: 'Join us for the annual Backstage Connect conference', + body: "We are thrilled to invite you to the annual Backstage Connect conference. This conference brings together Backstage users, contributors, and experts to share knowledge, network, and collaborate. Don't miss this opportunity to connect with the Backstage community!", + created_at: '2023-11-27T13:15:00.000+00:00', + category: 'events', + active: 1, + }, + { + id: '46', + publisher: 'default:group/observability', + title: 'New Feature: Error Monitoring', + excerpt: 'Introducing the Error Monitoring feature', + body: 'We are excited to announce the release of the Error Monitoring feature. This feature provides real-time error tracking and monitoring capabilities, allowing you to proactively identify and resolve issues in your applications. Stay on top of errors and deliver reliable software!', + created_at: '2023-12-02T09:30:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '47', + publisher: 'default:user/guest', + title: 'Important Announcement: Service Migration', + excerpt: 'Service Z will be migrated to a new infrastructure', + body: 'We will be migrating Service Z to a new infrastructure to improve performance and reliability. During the migration, there may be temporary service disruptions. We apologize for any inconvenience caused and appreciate your understanding.', + created_at: '2023-12-07T15:45:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '48', + publisher: 'default:group/documentation', + title: 'New Tutorial: Backstage Plugin Deployment', + excerpt: 'Learn how to deploy your Backstage plugins', + body: 'We have published a new tutorial that guides you through the process of deploying your Backstage plugins. This tutorial covers different deployment strategies, CI/CD integration, and best practices for plugin deployment. Deploy your plugins with confidence!', + created_at: '2023-12-12T12:00:00.000+00:00', + category: 'documentation', + active: 1, + }, + { + id: '49', + publisher: 'default:group/team-environments', + title: 'Planned Outage: Service F', + excerpt: 'Service F will be temporarily unavailable due to maintenance', + body: 'We will be performing maintenance on Service F, which will result in a temporary outage. We apologize for any inconvenience caused and assure you that we are working diligently to minimize the impact and restore service as quickly as possible.', + created_at: '2023-12-17T08:15:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + { + id: '50', + publisher: 'default:group/platform-engineering', + title: 'New Feature: Service Mesh Integration', + excerpt: 'Introducing the Service Mesh Integration feature', + body: 'We are excited to announce the release of the Service Mesh Integration feature. This feature enables seamless integration with popular service mesh solutions, providing advanced traffic management, security, and observability capabilities. Enhance your microservices architecture with service mesh integration!', + created_at: '2023-12-22T14:30:00.000+00:00', + category: 'infrastructure', + active: 1, + }, + ]); +}; diff --git a/workspaces/announcements/plugins/announcements-backend/dev/index.ts b/workspaces/announcements/plugins/announcements-backend/dev/index.ts new file mode 100644 index 0000000000..4a6015325f --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/dev/index.ts @@ -0,0 +1,45 @@ +/* + * 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 { createBackend } from '@backstage/backend-defaults'; +import { mockServices } from '@backstage/backend-test-utils'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; + +const backend = createBackend(); + +backend.add(mockServices.auth.factory()); +backend.add(mockServices.httpAuth.factory()); + +backend.add( + catalogServiceMock.factory({ + entities: [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'sample', + title: 'Sample Component', + }, + spec: { + type: 'service', + }, + }, + ], + }), +); + +backend.add(import('../src')); + +backend.start(); diff --git a/workspaces/announcements/plugins/announcements-backend/knexfile.js b/workspaces/announcements/plugins/announcements-backend/knexfile.js new file mode 100644 index 0000000000..f023598d0a --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/knexfile.js @@ -0,0 +1,31 @@ +/* + * 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. + */ + +module.exports = { + development: { + client: 'better-sqlite3', + connection: { + filename: './db/local.sqlite', + }, + useNullAsDefault: true, + seeds: { + directory: './db/seeds', + }, + migrations: { + directory: './db/migrations', + }, + }, +}; diff --git a/workspaces/announcements/plugins/announcements-backend/package.json b/workspaces/announcements/plugins/announcements-backend/package.json new file mode 100644 index 0000000000..cd2c982d89 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/package.json @@ -0,0 +1,89 @@ +{ + "name": "@backstage-community/plugin-announcements-backend", + "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" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/announcements/plugins/announcements-backend" + }, + "backstage": { + "role": "backend-plugin", + "pluginId": "announcements", + "pluginPackages": [ + "@backstage-community/plugin-announcements", + "@backstage-community/plugin-announcements-backend", + "@backstage-community/plugin-announcements-common", + "@backstage-community/plugin-announcements-node" + ] + }, + "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", + "db:migrations": "knex migrate:latest", + "db:seed": "knex seed:run", + "db:setup": "knex migrate:latest && knex seed:run" + }, + "dependencies": { + "@backstage-community/plugin-announcements-common": "workspace:^", + "@backstage-community/plugin-search-backend-module-announcements": "workspace:^", + "@backstage/backend-common": "^0.25.0", + "@backstage/backend-defaults": "^0.5.3", + "@backstage/backend-plugin-api": "^1.0.2", + "@backstage/backend-test-utils": "^1.1.0", + "@backstage/catalog-client": "^1.8.0", + "@backstage/config": "^1.3.0", + "@backstage/core-plugin-api": "^1.10.1", + "@backstage/errors": "^1.2.5", + "@backstage/plugin-auth-node": "^0.5.4", + "@backstage/plugin-events-backend": "^0.3.16", + "@backstage/plugin-events-node": "^0.4.5", + "@backstage/plugin-permission-common": "^0.8.2", + "@backstage/plugin-permission-node": "^0.8.5", + "@backstage/plugin-search-backend-node": "^1.3.5", + "@backstage/plugin-search-common": "^1.2.15", + "@backstage/plugin-signals-node": "^0.1.14", + "cross-fetch": "^3.1.5", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", + "knex": "^3.0.1", + "luxon": "^3.2.0", + "node-fetch": "^2.6.7", + "slugify": "^1.6.6", + "uuid": "^9.0.0", + "winston": "^3.2.1", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.29.2", + "@backstage/plugin-auth-backend": "^0.24.0", + "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.2", + "@backstage/plugin-catalog-node": "^1.15.0", + "@backstage/plugin-permission-backend": "^0.5.51", + "@backstage/plugin-permission-backend-module-allow-all-policy": "^0.2.2", + "@backstage/plugin-signals-backend": "^0.2.3", + "@backstage/test-utils": "^1.7.2", + "@types/supertest": "^2.0.15", + "@types/uuid": "^8.3.4", + "better-sqlite3": "^11.3.0", + "msw": "^1.3.2", + "supertest": "^6.3.3" + }, + "files": [ + "dist", + "db/migrations/**/*.{js,d.ts}" + ] +} diff --git a/workspaces/announcements/plugins/announcements-backend/report.api.md b/workspaces/announcements/plugins/announcements-backend/report.api.md new file mode 100644 index 0000000000..7dc302d0bc --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/report.api.md @@ -0,0 +1,17 @@ +## API Report File for "@backstage-community/plugin-announcements-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { AnnouncementCollatorFactory as AnnouncementCollatorFactory_2 } from '@backstage-community/plugin-search-backend-module-announcements'; +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @public @deprecated (undocumented) +export type AnnouncementCollatorFactory = AnnouncementCollatorFactory_2; + +// @public +const announcementsPlugin: BackendFeature; +export default announcementsPlugin; + +// (No @packageDocumentation comment for this package) +``` diff --git a/workspaces/announcements/plugins/announcements-backend/src/index.ts b/workspaces/announcements/plugins/announcements-backend/src/index.ts new file mode 100644 index 0000000000..517ed34068 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/index.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ +export { announcementsPlugin as default } from './plugin'; + +import { AnnouncementCollatorFactory as AnnouncementCollatorFactory_ } from '@backstage-community/plugin-search-backend-module-announcements'; + +/** + * @public + * @deprecated Use `AnnouncementCollatorFactory` from `@backstage-community/plugin-search-backend-module-announcements` instead + */ +export type AnnouncementCollatorFactory = AnnouncementCollatorFactory_; diff --git a/workspaces/announcements/plugins/announcements-backend/src/plugin.ts b/workspaces/announcements/plugins/announcements-backend/src/plugin.ts new file mode 100644 index 0000000000..71ac729101 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/plugin.ts @@ -0,0 +1,67 @@ +/* + * 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 { + createBackendPlugin, + coreServices, +} from '@backstage/backend-plugin-api'; +import { createRouter } from './router'; +import { initializePersistenceContext } from './service/persistence/persistenceContext'; +import { signalsServiceRef } from '@backstage/plugin-signals-node'; +import { eventsServiceRef } from '@backstage/plugin-events-node'; + +/** + * A backend for the announcements plugin. + * @public + */ +export const announcementsPlugin = createBackendPlugin({ + pluginId: 'announcements', + register(env) { + env.registerInit({ + deps: { + logger: coreServices.logger, + http: coreServices.httpRouter, + permissions: coreServices.permissions, + database: coreServices.database, + httpAuth: coreServices.httpAuth, + config: coreServices.rootConfig, + events: eventsServiceRef, + signals: signalsServiceRef, + }, + async init({ + http, + logger, + permissions, + database, + httpAuth, + config, + events, + signals, + }) { + http.use( + await createRouter({ + permissions, + logger, + config, + persistenceContext: await initializePersistenceContext(database), + httpAuth, + events, + signals, + }), + ); + }, + }); + }, +}); diff --git a/workspaces/announcements/plugins/announcements-backend/src/router.test.ts b/workspaces/announcements/plugins/announcements-backend/src/router.test.ts new file mode 100644 index 0000000000..210ebe23ca --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/router.test.ts @@ -0,0 +1,111 @@ +/* + * 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 express from 'express'; +import { DateTime } from 'luxon'; +import request from 'supertest'; +import { AnnouncementsContext } from './service/announcementsContextBuilder'; +import { AnnouncementModel } from './service/model'; +import { AnnouncementsDatabase } from './service/persistence/AnnouncementsDatabase'; +import { PersistenceContext } from './service/persistence/persistenceContext'; +import { createRouter } from './router'; +import { CategoriesDatabase } from './service/persistence/CategoriesDatabase'; +import { + HttpAuthService, + PermissionsService, +} from '@backstage/backend-plugin-api'; +import { mockServices } from '@backstage/backend-test-utils'; + +describe('createRouter', () => { + let app: express.Express; + + const announcementsMock = jest.fn(); + const announcementByIDMock = jest.fn(); + const deleteAnnouncementByIDMock = jest.fn(); + const insertAnnouncementMock = jest.fn(); + const updateAnnouncementMock = jest.fn(); + + const mockPersistenceContext: PersistenceContext = { + announcementsStore: { + announcements: announcementsMock, + announcementByID: announcementByIDMock, + deleteAnnouncementByID: deleteAnnouncementByIDMock, + insertAnnouncement: insertAnnouncementMock, + updateAnnouncement: updateAnnouncementMock, + } as unknown as AnnouncementsDatabase, + categoriesStore: {} as unknown as CategoriesDatabase, + }; + + const mockPermissions: PermissionsService = { + authorize: jest.fn(), + authorizeConditional: jest.fn(), + }; + + const mockHttpAuth: HttpAuthService = { + credentials: jest.fn(), + issueUserCookie: jest.fn(), + }; + + afterEach(() => { + jest.resetAllMocks(); + }); + + beforeAll(async () => { + const announcementsContext: AnnouncementsContext = { + logger: mockServices.logger.mock(), + config: mockServices.rootConfig.mock(), + persistenceContext: mockPersistenceContext, + permissions: mockPermissions, + httpAuth: mockHttpAuth, + }; + + const router = await createRouter(announcementsContext); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /announcements', () => { + it('returns ok', async () => { + announcementsMock.mockReturnValueOnce([ + { + id: 'uuid', + title: 'title', + excerpt: 'excerpt', + body: 'body', + publisher: 'user:default/name', + created_at: DateTime.fromISO('2022-11-02T15:28:08.539Z'), + }, + ] as AnnouncementModel[]); + + const response = await request(app).get('/announcements'); + + expect(response.status).toEqual(200); + expect(announcementsMock).toHaveBeenCalledWith({}); + expect(response.body).toEqual([ + { + id: 'uuid', + title: 'title', + excerpt: 'excerpt', + body: 'body', + publisher: 'user:default/name', + created_at: '2022-11-02T15:28:08.539+00:00', + }, + ]); + }); + }); +}); diff --git a/workspaces/announcements/plugins/announcements-backend/src/router.ts b/workspaces/announcements/plugins/announcements-backend/src/router.ts new file mode 100644 index 0000000000..1faf52942f --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/router.ts @@ -0,0 +1,342 @@ +/* + * 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 express, { Request } from 'express'; +import Router from 'express-promise-router'; +import { DateTime } from 'luxon'; +import slugify from 'slugify'; +import { v4 as uuid } from 'uuid'; +import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; +import { NotAllowedError } from '@backstage/errors'; +import { + AuthorizeResult, + BasicPermission, +} from '@backstage/plugin-permission-common'; +import { + announcementCreatePermission, + announcementDeletePermission, + announcementUpdatePermission, + announcementEntityPermissions, + EVENTS_TOPIC_ANNOUNCEMENTS, + EVENTS_ACTION_CREATE_ANNOUNCEMENT, + EVENTS_ACTION_DELETE_ANNOUNCEMENT, + EVENTS_ACTION_UPDATE_ANNOUNCEMENT, + EVENTS_ACTION_CREATE_CATEGORY, + EVENTS_ACTION_DELETE_CATEGORY, +} from '@backstage-community/plugin-announcements-common'; +import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; +import { + HttpAuthService, + LoggerService, + PermissionsService, + RootConfigService, +} from '@backstage/backend-plugin-api'; +import { PersistenceContext } from './service/persistence/persistenceContext'; +import { EventsService } from '@backstage/plugin-events-node'; +import { signalAnnouncement } from './service/signal'; +import { SignalsService } from '@backstage/plugin-signals-node'; + +interface AnnouncementRequest { + publisher: string; + category?: string; + title: string; + excerpt: string; + body: string; + active: boolean; +} + +interface CategoryRequest { + title: string; +} + +type RouterOptions = { + httpAuth: HttpAuthService; + config: RootConfigService; + logger: LoggerService; + permissions: PermissionsService; + persistenceContext: PersistenceContext; + events?: EventsService; + signals?: SignalsService; +}; + +type GetAnnouncementsQueryParams = { + category?: string; + page?: number; + max?: number; + active?: boolean; +}; + +export async function createRouter( + options: RouterOptions, +): Promise { + const { + persistenceContext, + permissions, + httpAuth, + config, + logger, + events, + signals, + } = options; + + const permissionIntegrationRouter = createPermissionIntegrationRouter({ + permissions: Object.values(announcementEntityPermissions), + }); + + const isRequestAuthorized = async ( + req: Request, + permission: BasicPermission, + ): Promise => { + const credentials = await httpAuth.credentials(req); + + const decision = ( + await permissions.authorize([{ permission: permission }], { + credentials, + }) + )[0]; + + return decision.result !== AuthorizeResult.DENY; + }; + + const router = Router(); + router.use(express.json()); + router.use(permissionIntegrationRouter); + + // eslint-disable-next-line spaced-comment + /***************** + * Announcements * + ****************/ + router.get( + '/announcements', + async (req: Request<{}, {}, {}, GetAnnouncementsQueryParams>, res) => { + const { + query: { category, max, page, active }, + } = req; + + const results = await persistenceContext.announcementsStore.announcements( + { + category, + max, + offset: page ? (page - 1) * (max ?? 10) : undefined, + active, + }, + ); + + return res.json(results); + }, + ); + + router.get( + '/announcements/:id', + async (req: Request<{ id: string }, {}, {}, {}>, res) => { + const result = + await persistenceContext.announcementsStore.announcementByID( + req.params.id, + ); + + return res.json(result); + }, + ); + + router.delete( + '/announcements/:id', + async (req: Request<{ id: string }, {}, {}, {}>, res) => { + if (!(await isRequestAuthorized(req, announcementDeletePermission))) { + throw new NotAllowedError('Unauthorized'); + } + + const announcement = + await persistenceContext.announcementsStore.announcementByID( + req.params.id, + ); + + if (!announcement) { + logger.warn('Announcement not found', { id: req.params.id }); + return res.status(404).end(); + } + + await persistenceContext.announcementsStore.deleteAnnouncementByID( + req.params.id, + ); + + if (events) { + events.publish({ + topic: EVENTS_TOPIC_ANNOUNCEMENTS, + eventPayload: { + announcement, + }, + metadata: { action: EVENTS_ACTION_DELETE_ANNOUNCEMENT }, + }); + } + + return res.status(204).end(); + }, + ); + + router.post( + '/announcements', + async (req: Request<{}, {}, AnnouncementRequest, {}>, res) => { + if (!(await isRequestAuthorized(req, announcementCreatePermission))) { + throw new NotAllowedError('Unauthorized'); + } + + const announcement = + await persistenceContext.announcementsStore.insertAnnouncement({ + ...req.body, + ...{ + id: uuid(), + created_at: DateTime.now(), + }, + }); + + if (events) { + events.publish({ + topic: EVENTS_TOPIC_ANNOUNCEMENTS, + eventPayload: { + announcement, + }, + metadata: { action: EVENTS_ACTION_CREATE_ANNOUNCEMENT }, + }); + + await signalAnnouncement(announcement, signals); + } + + return res.status(201).json(announcement); + }, + ); + + router.put( + '/announcements/:id', + async (req: Request<{ id: string }, {}, AnnouncementRequest, {}>, res) => { + if (!(await isRequestAuthorized(req, announcementUpdatePermission))) { + throw new NotAllowedError('Unauthorized'); + } + + const { + params: { id }, + body: { title, excerpt, body, publisher, category, active }, + } = req; + + const initialAnnouncement = + await persistenceContext.announcementsStore.announcementByID(id); + if (!initialAnnouncement) { + return res.status(404).end(); + } + + const announcement = + await persistenceContext.announcementsStore.updateAnnouncement({ + ...initialAnnouncement, + ...{ + title, + excerpt, + body, + publisher, + category, + active, + }, + }); + + if (events) { + events.publish({ + topic: EVENTS_TOPIC_ANNOUNCEMENTS, + eventPayload: { + announcement, + }, + metadata: { action: EVENTS_ACTION_UPDATE_ANNOUNCEMENT }, + }); + } + + return res.status(200).json(announcement); + }, + ); + + // eslint-disable-next-line spaced-comment + /************** + * Categories * + **************/ + router.get('/categories', async (_req, res) => { + const results = await persistenceContext.categoriesStore.categories(); + + return res.json(results); + }); + + router.post( + '/categories', + async (req: Request<{}, {}, CategoryRequest, {}>, res) => { + if (!(await isRequestAuthorized(req, announcementCreatePermission))) { + throw new NotAllowedError('Unauthorized'); + } + + const category = { + ...req.body, + ...{ + slug: slugify(req.body.title, { + lower: true, + }), + }, + }; + + await persistenceContext.categoriesStore.insert(category); + + if (events) { + events.publish({ + topic: EVENTS_TOPIC_ANNOUNCEMENTS, + eventPayload: { + category: category.slug, + }, + metadata: { action: EVENTS_ACTION_CREATE_CATEGORY }, + }); + } + + return res.status(201).json(category); + }, + ); + + router.delete( + '/categories/:slug', + async (req: Request<{ slug: string }, {}, {}, {}>, res) => { + if (!(await isRequestAuthorized(req, announcementDeletePermission))) { + throw new NotAllowedError('Unauthorized'); + } + const announcementsByCategory = + await persistenceContext.announcementsStore.announcements({ + category: req.params.slug, + }); + + if (announcementsByCategory.count) { + throw new NotAllowedError( + 'Category to delete is used in some announcements', + ); + } + await persistenceContext.categoriesStore.delete(req.params.slug); + + if (events) { + events.publish({ + topic: EVENTS_TOPIC_ANNOUNCEMENTS, + eventPayload: { + category: req.params.slug, + }, + metadata: { action: EVENTS_ACTION_DELETE_CATEGORY }, + }); + } + + return res.status(204).end(); + }, + ); + + router.use(MiddlewareFactory.create({ config, logger }).error()); + + return router; +} diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.test.ts b/workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.test.ts new file mode 100644 index 0000000000..a3c044245d --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.test.ts @@ -0,0 +1,61 @@ +/* + * 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 { mockServices } from '@backstage/backend-test-utils'; +import { buildAnnouncementsContext } from './announcementsContextBuilder'; +import { initializePersistenceContext } from './persistence/persistenceContext'; +import { + HttpAuthService, + PermissionsService, +} from '@backstage/backend-plugin-api'; + +jest.mock('./persistence/persistenceContext', () => ({ + initializePersistenceContext: jest.fn(), +})); + +describe('buildAnnouncementsContext', () => { + it('returns context with logger, persistenceContext, permissions and httpAuth properties', async () => { + const logger = mockServices.logger.mock(); + const config = mockServices.rootConfig.mock(); + const database = { + getClient: jest.fn(), + url: 'url', + }; + const permissions: PermissionsService = { + authorize: jest.fn(), + authorizeConditional: jest.fn(), + }; + const httpAuth: HttpAuthService = { + credentials: jest.fn(), + issueUserCookie: jest.fn(), + }; + + const context = await buildAnnouncementsContext({ + logger, + config, + database, + permissions, + httpAuth, + }); + + expect(context).toStrictEqual({ + logger, + config, + persistenceContext: await initializePersistenceContext(database), + permissions, + httpAuth, + }); + }); +}); diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.ts b/workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.ts new file mode 100644 index 0000000000..4c156fa212 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/announcementsContextBuilder.ts @@ -0,0 +1,73 @@ +/* + * 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 { + initializePersistenceContext, + PersistenceContext, +} from './persistence/persistenceContext'; +import { + DatabaseService, + HttpAuthService, + LoggerService, + PermissionsService, + RootConfigService, +} from '@backstage/backend-plugin-api'; + +/** + * Options to build the context for the announcements plugin. + * + * @public + */ +export type AnnouncementsContextOptions = { + logger: LoggerService; + config: RootConfigService; + database: DatabaseService; + permissions: PermissionsService; + httpAuth: HttpAuthService; +}; + +/** + * Context for the announcements plugin. + * + * @public + */ +export type AnnouncementsContext = { + logger: LoggerService; + config: RootConfigService; + persistenceContext: PersistenceContext; + permissions: PermissionsService; + httpAuth: HttpAuthService; +}; + +/** + * Builds the context for the announcements plugin. + * + * @public + */ +export const buildAnnouncementsContext = async ({ + logger, + config, + database, + permissions, + httpAuth, +}: AnnouncementsContextOptions): Promise => { + return { + logger, + config, + persistenceContext: await initializePersistenceContext(database), + permissions, + httpAuth, + }; +}; diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/index.ts b/workspaces/announcements/plugins/announcements-backend/src/service/index.ts new file mode 100644 index 0000000000..1d63d00c21 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/index.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ +export { buildAnnouncementsContext } from './announcementsContextBuilder'; + +export type { + AnnouncementsContext, + AnnouncementsContextOptions, +} from './announcementsContextBuilder'; diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/model.ts b/workspaces/announcements/plugins/announcements-backend/src/service/model.ts new file mode 100644 index 0000000000..25daea55a4 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/model.ts @@ -0,0 +1,26 @@ +/* + * 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 { Announcement } from '@backstage-community/plugin-announcements-common'; +import { DateTime } from 'luxon'; + +/** + * A model representing an Announcement on the backend. + * + * @internal + */ +export type AnnouncementModel = Omit & { + created_at: DateTime; +}; diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.test.ts b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.test.ts new file mode 100644 index 0000000000..0f8f1b6424 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.test.ts @@ -0,0 +1,442 @@ +/* + * 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 { TestDatabases } from '@backstage/backend-test-utils'; +import { + AnnouncementsDatabase, + timestampToDateTime, +} from './AnnouncementsDatabase'; +import { Knex } from 'knex'; +import { initializePersistenceContext } from './persistenceContext'; +import { DateTime } from 'luxon'; + +function createDatabaseManager(client: Knex, skipMigrations: boolean = false) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; +} + +describe('AnnouncementsDatabase', () => { + const databases = TestDatabases.create(); + let store: AnnouncementsDatabase; + let testDbClient: Knex; + let database; + + beforeAll(async () => { + testDbClient = await databases.init('SQLITE_3'); + database = createDatabaseManager(testDbClient); + store = (await initializePersistenceContext(database)).announcementsStore; + }); + + afterEach(async () => { + await testDbClient('announcements').delete(); + }); + + it('should return an empty array when there are no announcements', async () => { + const announcements = await store.announcements({}); + expect(announcements).toEqual({ + count: 0, + results: [], + }); + }); + + it('should return an announcement by id', async () => { + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + const announcement = await store.announcementByID('id'); + + expect(announcement).toEqual({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + category: undefined, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }); + }); + + it('should insert a new announcement', async () => { + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + const announcements = await store.announcements({}); + + expect(announcements).toEqual({ + count: 1, + results: [ + { + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + category: undefined, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }, + ], + }); + }); + + it('should update an existing announcement', async () => { + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.updateAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: false, + }); + + const announcements = await store.announcements({}); + + expect(announcements).toEqual({ + count: 1, + results: [ + { + id: 'id', + publisher: 'publisher', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + category: undefined, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 0, + }, + ], + }); + }); + + it('should delete an existing announcement', async () => { + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + expect((await store.announcements({})).count).toBe(1); + + await store.deleteAnnouncementByID('id'); + + const announcements = await store.announcements({}); + + expect(announcements).toEqual({ + count: 0, + results: [], + }); + }); + + it('handles not finding an announcement', async () => { + expect(await store.announcementByID('id')).toBeUndefined(); + }); + + describe('filters', () => { + it('categories', async () => { + database = createDatabaseManager(testDbClient); + const categoryStore = (await initializePersistenceContext(database)) + .categoriesStore; + + await categoryStore.insert({ + slug: 'category', + title: 'Category', + }); + + await categoryStore.insert({ + slug: 'different', + title: 'A different category', + }); + + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + category: 'category', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.insertAnnouncement({ + id: 'id2', + publisher: 'publisher2', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + category: 'category', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.insertAnnouncement({ + id: 'id3', + publisher: 'publisher3', + title: 'title3', + excerpt: 'excerpt3', + body: 'body3', + category: 'different', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + const announcements = await store.announcements({ + category: 'category', + }); + + expect(announcements).toEqual({ + count: 2, + results: [ + { + id: 'id2', + publisher: 'publisher2', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + category: { + slug: 'category', + title: 'Category', + }, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }, + { + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + category: { + slug: 'category', + title: 'Category', + }, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }, + ], + }); + }); + + it('offset', async () => { + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.insertAnnouncement({ + id: 'id2', + publisher: 'publisher2', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + created_at: DateTime.fromISO('2023-10-26T15:28:09.539Z'), + active: true, + }); + + const announcements = await store.announcements({ + offset: 1, + }); + + expect(announcements).toEqual({ + count: 2, + results: [ + { + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + category: undefined, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }, + ], + }); + }); + + it('max', async () => { + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.insertAnnouncement({ + id: 'id2', + publisher: 'publisher2', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.insertAnnouncement({ + id: 'id3', + publisher: 'publisher3', + title: 'title3', + excerpt: 'excerpt3', + body: 'body3', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.insertAnnouncement({ + id: 'id4', + publisher: 'publisher4', + title: 'title4', + excerpt: 'excerpt4', + body: 'body4', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + const announcements = await store.announcements({ + max: 1, + }); + + expect(announcements).toEqual({ + count: 4, + results: [ + { + id: 'id4', + publisher: 'publisher4', + title: 'title4', + excerpt: 'excerpt4', + body: 'body4', + category: undefined, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }, + ], + }); + }); + + it('active', async () => { + await store.insertAnnouncement({ + id: 'id', + publisher: 'publisher', + title: 'title', + excerpt: 'excerpt', + body: 'body', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: false, + }); + + await store.insertAnnouncement({ + id: 'id2', + publisher: 'publisher2', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + await store.insertAnnouncement({ + id: 'id3', + publisher: 'publisher3', + title: 'title3', + excerpt: 'excerpt3', + body: 'body3', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: false, + }); + + await store.insertAnnouncement({ + id: 'id4', + publisher: 'publisher4', + title: 'title4', + excerpt: 'excerpt4', + body: 'body4', + created_at: DateTime.fromISO('2023-10-26T15:28:08.539Z'), + active: true, + }); + + const announcements = await store.announcements({ + active: true, + }); + + expect(announcements).toEqual({ + count: 2, + results: [ + { + id: 'id4', + publisher: 'publisher4', + title: 'title4', + excerpt: 'excerpt4', + body: 'body4', + category: undefined, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }, + { + id: 'id2', + publisher: 'publisher2', + title: 'title2', + excerpt: 'excerpt2', + body: 'body2', + category: undefined, + created_at: timestampToDateTime('2023-10-26T15:28:08.539Z'), + active: 1, + }, + ], + }); + }); + }); +}); diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.ts b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.ts new file mode 100644 index 0000000000..9154db16e7 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/AnnouncementsDatabase.ts @@ -0,0 +1,245 @@ +/* + * 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 { Knex } from 'knex'; +import { DateTime } from 'luxon'; +import { AnnouncementModel } from '../model'; +import { + AnnouncementsFilters, + Announcement, +} from '@backstage-community/plugin-announcements-common'; +import slugify from 'slugify'; + +const announcementsTable = 'announcements'; + +/** + * @internal + */ +type AnnouncementUpsert = Omit & { + category?: string; + created_at: DateTime; +}; + +/** + * @internal + */ +type DbAnnouncement = Omit & { + category?: string; +}; + +/** + * @internal + */ +type DbAnnouncementWithCategory = DbAnnouncement & { + category_slug?: string; + category_title?: string; +}; + +/** + * @internal + */ +type AnnouncementModelsList = { + count: number; + results: AnnouncementModel[]; +}; + +export const timestampToDateTime = (input: Date | string): DateTime => { + if (typeof input === 'object') { + return DateTime.fromJSDate(input).toUTC(); + } + + const result = input.includes(' ') + ? DateTime.fromSQL(input, { zone: 'utc' }) + : DateTime.fromISO(input, { zone: 'utc' }); + if (!result.isValid) { + throw new TypeError('Not valid'); + } + + return result; +}; + +/** + * @internal + */ +const announcementUpsertToDB = ( + announcement: AnnouncementUpsert, +): DbAnnouncement => { + return { + id: announcement.id, + category: announcement.category + ? slugify(announcement.category, { + lower: true, + }) + : announcement.category, + title: announcement.title, + excerpt: announcement.excerpt, + body: announcement.body, + publisher: announcement.publisher, + created_at: announcement.created_at.toSQL()!, + active: announcement.active, + }; +}; + +/** + * @internal + */ +const DBToAnnouncementWithCategory = ( + announcementDb: DbAnnouncementWithCategory, +): AnnouncementModel => { + return { + id: announcementDb.id, + category: + announcementDb.category && announcementDb.category_title + ? { + slug: announcementDb.category, + title: announcementDb.category_title, + } + : undefined, + title: announcementDb.title, + excerpt: announcementDb.excerpt, + body: announcementDb.body, + publisher: announcementDb.publisher, + created_at: timestampToDateTime(announcementDb.created_at), + active: announcementDb.active, + }; +}; + +/** + * Database implementation for announcements + * @internal + */ +export class AnnouncementsDatabase { + constructor(private readonly db: Knex) {} + + async announcements( + request: AnnouncementsFilters, + ): Promise { + const { category, offset, max, active } = request; + + // Filter the query by states + // Used for both the result query and the count query + const filterState = ( + qb: Knex.QueryBuilder, + ) => { + if (category) { + qb.where('category', category); + } + if (active) { + qb.where('active', active); + } + }; + + // Filter the page (offset + max). Used only for the result query + const filterRange = ( + qb: Knex.QueryBuilder, + ) => { + if (offset) { + qb.offset(offset); + } + if (max) { + qb.limit(max); + } + }; + + const queryBuilder = this.db(announcementsTable) + .select( + 'id', + 'publisher', + 'announcements.title', + 'excerpt', + 'body', + 'category', + 'created_at', + 'categories.title as category_title', + 'active', + ) + .orderBy('created_at', 'desc') + .leftJoin('categories', 'announcements.category', 'categories.slug'); + filterState(queryBuilder); + filterRange(queryBuilder); + const results = (await queryBuilder.select()).map( + DBToAnnouncementWithCategory, + ); + + const countQueryBuilder = this.db(announcementsTable).count< + Record + >('id', { as: 'total' }); + filterState(countQueryBuilder); + const countResult = await countQueryBuilder.first(); + const count = + countResult && countResult.total + ? parseInt(countResult.total.toString(), 10) + : 0; + + return { + count, + results, + }; + } + + async announcementByID(id: string): Promise { + const dbAnnouncement: DbAnnouncementWithCategory = + await this.db(announcementsTable) + .select( + 'id', + 'publisher', + 'announcements.title', + 'excerpt', + 'body', + 'category', + 'created_at', + 'categories.title as category_title', + 'active', + ) + .leftJoin('categories', 'announcements.category', 'categories.slug') + .where('id', id) + .first(); + if (!dbAnnouncement) { + return undefined; + } + + return DBToAnnouncementWithCategory(dbAnnouncement); + } + + async deleteAnnouncementByID(id: string): Promise { + return this.db(announcementsTable).where('id', id).delete(); + } + + async insertAnnouncement( + announcement: AnnouncementUpsert, + ): Promise { + await this.db(announcementsTable).insert( + announcementUpsertToDB(announcement), + ); + + const newAnnouncement = await this.announcementByID(announcement.id); + + if (!newAnnouncement) { + throw new Error('Failed to insert announcement'); + } + + return newAnnouncement; + } + + async updateAnnouncement( + announcement: AnnouncementUpsert, + ): Promise { + await this.db(announcementsTable) + .where('id', announcement.id) + .update(announcementUpsertToDB(announcement)); + + return (await this.announcementByID(announcement.id))!; + } +} diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.test.ts b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.test.ts new file mode 100644 index 0000000000..3d1a21b91f --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.test.ts @@ -0,0 +1,80 @@ +/* + * 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 { Knex } from 'knex'; +import { CategoriesDatabase } from './CategoriesDatabase'; +import { TestDatabases } from '@backstage/backend-test-utils'; +import { initializePersistenceContext } from './persistenceContext'; +import { Category } from '@backstage-community/plugin-announcements-common'; + +function createDatabaseManager(client: Knex, skipMigrations: boolean = false) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; +} + +describe('categories', () => { + const databases = TestDatabases.create(); + let store: CategoriesDatabase; + let testDbClient: Knex; + let database; + + beforeAll(async () => { + testDbClient = await databases.init('SQLITE_3'); + database = createDatabaseManager(testDbClient); + store = (await initializePersistenceContext(database)).categoriesStore; + }); + + afterEach(async () => { + await testDbClient('categories').delete(); + }); + + it('should return an empty array when there are no categories', async () => { + const categories = await store.categories(); + expect(categories).toEqual([]); + }); + + it('should return all categories in ascending order by title', async () => { + const category1: Category = { slug: 'category-1', title: 'Category 1' }; + const category2: Category = { slug: 'category-2', title: 'Category 2' }; + store.insert(category2); + store.insert(category1); + + const categories = await store.categories(); + expect(categories).toEqual([category1, category2]); + }); + + it('should delete a category', async () => { + const category: Category = { slug: 'category-1', title: 'Category 1' }; + store.insert(category); + + expect(await store.categories()).toEqual([category]); + await store.delete(category.slug); + expect(await store.categories()).toEqual([]); + }); + + it('should update a category', async () => { + const category: Category = { slug: 'category-1', title: 'Category 1' }; + store.insert(category); + + await store.update({ ...category, title: 'New Title' }); + expect(await store.categories()).toEqual([ + { slug: 'category-1', title: 'New Title' }, + ]); + }); +}); diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.ts b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.ts new file mode 100644 index 0000000000..667f238c29 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/CategoriesDatabase.ts @@ -0,0 +1,51 @@ +/* + * 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 { Category } from '@backstage-community/plugin-announcements-common'; +import { Knex } from 'knex'; + +const categoriesTable = 'categories'; + +/** + * Database implementation for categories + * + * @internal + */ +export class CategoriesDatabase { + constructor(private readonly db: Knex) {} + + async categories(): Promise { + const queryBuilder = this.db(categoriesTable).orderBy( + 'title', + 'asc', + ); + + return queryBuilder.select(); + } + + async delete(slug: string): Promise { + return this.db(categoriesTable).where('slug', slug).delete(); + } + + async insert(category: Category): Promise { + await this.db(categoriesTable).insert(category); + } + + async update(category: Category): Promise { + await this.db(categoriesTable) + .where('slug', category.slug) + .update(category); + } +} diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/persistence/index.ts b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/index.ts new file mode 100644 index 0000000000..24d4b242eb --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/index.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ +export { + type PersistenceContext, + initializePersistenceContext, +} from './persistenceContext'; diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.test.ts b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.test.ts new file mode 100644 index 0000000000..bfcd9f808f --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.test.ts @@ -0,0 +1,47 @@ +/* + * 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 { AnnouncementsDatabase } from './AnnouncementsDatabase'; +import { CategoriesDatabase } from './CategoriesDatabase'; +import { + PersistenceContext, + initializePersistenceContext, +} from './persistenceContext'; +import { TestDatabases } from '@backstage/backend-test-utils'; + +describe('initializePersistenceContext', () => { + const databases = TestDatabases.create(); + const dbClient = databases.init('SQLITE_3'); + const mockedDb = { + getClient: async () => dbClient, + migrations: { + skip: false, + }, + }; + + let context: PersistenceContext; + + beforeEach(async () => { + context = await initializePersistenceContext(mockedDb); + }); + + it('initializes the announcements store', async () => { + expect(context.announcementsStore).toBeInstanceOf(AnnouncementsDatabase); + }); + + it('initializes the categories store', async () => { + expect(context.categoriesStore).toBeInstanceOf(CategoriesDatabase); + }); +}); diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.ts b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.ts new file mode 100644 index 0000000000..93e44ba1f5 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/persistence/persistenceContext.ts @@ -0,0 +1,58 @@ +/* + * 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 { AnnouncementsDatabase } from './AnnouncementsDatabase'; +import { CategoriesDatabase } from './CategoriesDatabase'; +import { + DatabaseService, + resolvePackagePath, +} from '@backstage/backend-plugin-api'; + +const migrationsDir = resolvePackagePath( + '@backstage-community/plugin-announcements-backend', + 'db/migrations', +); + +/** + * A Container for persistence related components in Announcements + * + * @public + */ +export type PersistenceContext = { + announcementsStore: AnnouncementsDatabase; + categoriesStore: CategoriesDatabase; +}; + +/** + * A factory method to construct persistence context. + * + * @public + */ +export const initializePersistenceContext = async ( + database: DatabaseService, +): Promise => { + const client = await database.getClient(); + + if (!database.migrations?.skip) { + await client.migrate.latest({ + directory: migrationsDir, + }); + } + + return { + announcementsStore: new AnnouncementsDatabase(client), + categoriesStore: new CategoriesDatabase(client), + }; +}; diff --git a/workspaces/announcements/plugins/announcements-backend/src/service/signal.ts b/workspaces/announcements/plugins/announcements-backend/src/service/signal.ts new file mode 100644 index 0000000000..0b45390981 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/service/signal.ts @@ -0,0 +1,53 @@ +/* + * 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 { SignalsService } from '@backstage/plugin-signals-node'; +import { AnnouncementModel } from './model'; +import { + AnnouncementSignal, + SIGNALS_CHANNEL_ANNOUNCEMENTS, +} from '@backstage-community/plugin-announcements-common'; + +/** + * Forwards an announcement to the signals service. + * + * @param announcement the announcement to signal + * @param signals an optional signals service to use, if not provided, the announcement will not be signaled + * @returns a promise that resolves when the announcement has been signaled + * + * @public + * @remarks + * + * Signal types are located in `@backstage-community/plugin-announcements-common`. + */ +export const signalAnnouncement = async ( + announcement: AnnouncementModel, + signals?: SignalsService, +) => { + if (!signals) { + return; + } + + await signals.publish({ + recipients: { type: 'broadcast' }, + channel: SIGNALS_CHANNEL_ANNOUNCEMENTS, + message: { + data: { + ...announcement, + created_at: announcement.created_at.toString(), + }, + }, + }); +}; diff --git a/workspaces/announcements/plugins/announcements-backend/src/setupTests.ts b/workspaces/announcements/plugins/announcements-backend/src/setupTests.ts new file mode 100644 index 0000000000..c7ce5c0988 --- /dev/null +++ b/workspaces/announcements/plugins/announcements-backend/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ +export {}; diff --git a/workspaces/announcements/plugins/announcements-common/package.json b/workspaces/announcements/plugins/announcements-common/package.json index f2be3598b4..878a1792c0 100644 --- a/workspaces/announcements/plugins/announcements-common/package.json +++ b/workspaces/announcements/plugins/announcements-common/package.json @@ -22,6 +22,7 @@ "pluginId": "announcements", "pluginPackages": [ "@backstage-community/plugin-announcements", + "@backstage-community/plugin-announcements-backend", "@backstage-community/plugin-announcements-common", "@backstage-community/plugin-announcements-node" ] diff --git a/workspaces/announcements/plugins/announcements-node/package.json b/workspaces/announcements/plugins/announcements-node/package.json index d0eee32d9d..9a7318c0e9 100644 --- a/workspaces/announcements/plugins/announcements-node/package.json +++ b/workspaces/announcements/plugins/announcements-node/package.json @@ -21,6 +21,7 @@ "pluginId": "announcements", "pluginPackages": [ "@backstage-community/plugin-announcements", + "@backstage-community/plugin-announcements-backend", "@backstage-community/plugin-announcements-common", "@backstage-community/plugin-announcements-node" ] diff --git a/workspaces/announcements/plugins/announcements/package.json b/workspaces/announcements/plugins/announcements/package.json index c1508d359f..390ff7c729 100644 --- a/workspaces/announcements/plugins/announcements/package.json +++ b/workspaces/announcements/plugins/announcements/package.json @@ -33,6 +33,7 @@ "pluginId": "announcements", "pluginPackages": [ "@backstage-community/plugin-announcements", + "@backstage-community/plugin-announcements-backend", "@backstage-community/plugin-announcements-common", "@backstage-community/plugin-announcements-node" ] diff --git a/workspaces/announcements/plugins/search-backend-module-announcements/package.json b/workspaces/announcements/plugins/search-backend-module-announcements/package.json index 6b4df2e92a..c25638779e 100644 --- a/workspaces/announcements/plugins/search-backend-module-announcements/package.json +++ b/workspaces/announcements/plugins/search-backend-module-announcements/package.json @@ -32,10 +32,10 @@ }, "dependencies": { "@backstage-community/plugin-announcements-common": "workspace:^", + "@backstage-community/plugin-announcements-node": "workspace:^", "@backstage/backend-plugin-api": "^1.0.2", "@backstage/plugin-search-backend-node": "^1.3.5", - "@backstage/plugin-search-common": "^1.2.15", - "@procore-oss/backstage-plugin-announcements-node": "^0.3.3" + "@backstage/plugin-search-common": "^1.2.15" }, "devDependencies": { "@backstage/backend-test-utils": "^1.1.0", diff --git a/workspaces/announcements/plugins/search-backend-module-announcements/report.api.md b/workspaces/announcements/plugins/search-backend-module-announcements/report.api.md index ed2dde9982..3d9acf1da9 100644 --- a/workspaces/announcements/plugins/search-backend-module-announcements/report.api.md +++ b/workspaces/announcements/plugins/search-backend-module-announcements/report.api.md @@ -3,7 +3,40 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// + +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; +import { IndexableDocument } from '@backstage/plugin-search-common'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { Readable } from 'stream'; + +// @public +export class AnnouncementCollatorFactory implements DocumentCollatorFactory { + // (undocumented) + static fromConfig( + options: AnnouncementCollatorOptions, + ): AnnouncementCollatorFactory; + // (undocumented) + getCollator(): Promise; + // (undocumented) + readonly type: string; +} + +// @public +export type AnnouncementCollatorOptions = { + logger: LoggerService; + discoveryApi: DiscoveryService; + auth: AuthService; +}; + +// @public +export type IndexableAnnouncementDocument = IndexableDocument & { + excerpt: string; + createdAt: string; +}; // @public const searchModuleAnnouncementsCollator: BackendFeature; diff --git a/workspaces/announcements/plugins/search-backend-module-announcements/src/collators/AnnouncementCollatorFactory.ts b/workspaces/announcements/plugins/search-backend-module-announcements/src/collators/AnnouncementCollatorFactory.ts index f78bdb1122..d302e428b2 100644 --- a/workspaces/announcements/plugins/search-backend-module-announcements/src/collators/AnnouncementCollatorFactory.ts +++ b/workspaces/announcements/plugins/search-backend-module-announcements/src/collators/AnnouncementCollatorFactory.ts @@ -18,8 +18,8 @@ import { DocumentCollatorFactory, IndexableDocument, } from '@backstage/plugin-search-common'; -import { DefaultAnnouncementsService } from '@procore-oss/backstage-plugin-announcements-node'; -import { Announcement } from '@procore-oss/backstage-plugin-announcements-common'; +import { DefaultAnnouncementsService } from '@backstage-community/plugin-announcements-node'; +import { Announcement } from '@backstage-community/plugin-announcements-common'; import { AuthService, DiscoveryService, @@ -31,7 +31,7 @@ import { * * @public */ -type IndexableAnnouncementDocument = IndexableDocument & { +export type IndexableAnnouncementDocument = IndexableDocument & { excerpt: string; createdAt: string; }; @@ -41,7 +41,7 @@ type IndexableAnnouncementDocument = IndexableDocument & { * * @public */ -type AnnouncementCollatorOptions = { +export type AnnouncementCollatorOptions = { logger: LoggerService; discoveryApi: DiscoveryService; auth: AuthService; diff --git a/workspaces/announcements/plugins/search-backend-module-announcements/src/index.ts b/workspaces/announcements/plugins/search-backend-module-announcements/src/index.ts index ff9b21d3f2..8c16867b24 100644 --- a/workspaces/announcements/plugins/search-backend-module-announcements/src/index.ts +++ b/workspaces/announcements/plugins/search-backend-module-announcements/src/index.ts @@ -21,3 +21,9 @@ */ export { searchModuleAnnouncementsCollator as default } from './module'; + +export { AnnouncementCollatorFactory } from './collators/AnnouncementCollatorFactory'; +export type { + IndexableAnnouncementDocument, + AnnouncementCollatorOptions, +} from './collators/AnnouncementCollatorFactory'; diff --git a/workspaces/announcements/yarn.lock b/workspaces/announcements/yarn.lock index 518cc47806..4d01dc3584 100644 --- a/workspaces/announcements/yarn.lock +++ b/workspaces/announcements/yarn.lock @@ -33,6 +33,17 @@ __metadata: languageName: node linkType: hard +"@apidevtools/json-schema-ref-parser@npm:^11.7.0": + version: 11.7.3 + resolution: "@apidevtools/json-schema-ref-parser@npm:11.7.3" + dependencies: + "@jsdevtools/ono": ^7.1.3 + "@types/json-schema": ^7.0.15 + js-yaml: ^4.1.0 + checksum: 3496edfb2c3d2f9a5a7a49795b4d560f1e4957015aef473775f4b5f2db55a4ddfb3778783401ddd24e7db2930a67a370fb8c68840d8bae0a2a581e0e57fc2f58 + languageName: node + linkType: hard + "@apidevtools/openapi-schemas@npm:^2.1.0": version: 2.1.0 resolution: "@apidevtools/openapi-schemas@npm:2.1.0" @@ -2513,6 +2524,54 @@ __metadata: languageName: node linkType: hard +"@backstage-community/plugin-announcements-backend@workspace:plugins/announcements-backend": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-announcements-backend@workspace:plugins/announcements-backend" + dependencies: + "@backstage-community/plugin-announcements-common": "workspace:^" + "@backstage-community/plugin-search-backend-module-announcements": "workspace:^" + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-defaults": ^0.5.3 + "@backstage/backend-plugin-api": ^1.0.2 + "@backstage/backend-test-utils": ^1.1.0 + "@backstage/catalog-client": ^1.8.0 + "@backstage/cli": ^0.29.2 + "@backstage/config": ^1.3.0 + "@backstage/core-plugin-api": ^1.10.1 + "@backstage/errors": ^1.2.5 + "@backstage/plugin-auth-backend": ^0.24.0 + "@backstage/plugin-auth-backend-module-guest-provider": ^0.2.2 + "@backstage/plugin-auth-node": ^0.5.4 + "@backstage/plugin-catalog-node": ^1.15.0 + "@backstage/plugin-events-backend": ^0.3.16 + "@backstage/plugin-events-node": ^0.4.5 + "@backstage/plugin-permission-backend": ^0.5.51 + "@backstage/plugin-permission-backend-module-allow-all-policy": ^0.2.2 + "@backstage/plugin-permission-common": ^0.8.2 + "@backstage/plugin-permission-node": ^0.8.5 + "@backstage/plugin-search-backend-node": ^1.3.5 + "@backstage/plugin-search-common": ^1.2.15 + "@backstage/plugin-signals-backend": ^0.2.3 + "@backstage/plugin-signals-node": ^0.1.14 + "@backstage/test-utils": ^1.7.2 + "@types/supertest": ^2.0.15 + "@types/uuid": ^8.3.4 + better-sqlite3: ^11.3.0 + cross-fetch: ^3.1.5 + express: ^4.17.1 + express-promise-router: ^4.1.0 + knex: ^3.0.1 + luxon: ^3.2.0 + msw: ^1.3.2 + node-fetch: ^2.6.7 + slugify: ^1.6.6 + supertest: ^6.3.3 + uuid: ^9.0.0 + winston: ^3.2.1 + yn: ^4.0.0 + languageName: unknown + linkType: soft + "@backstage-community/plugin-announcements-common@workspace:^, @backstage-community/plugin-announcements-common@workspace:plugins/announcements-common": version: 0.0.0-use.local resolution: "@backstage-community/plugin-announcements-common@workspace:plugins/announcements-common" @@ -2522,7 +2581,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage-community/plugin-announcements-node@workspace:plugins/announcements-node": +"@backstage-community/plugin-announcements-node@workspace:^, @backstage-community/plugin-announcements-node@workspace:plugins/announcements-node": version: 0.0.0-use.local resolution: "@backstage-community/plugin-announcements-node@workspace:plugins/announcements-node" dependencies: @@ -2587,18 +2646,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage-community/plugin-search-backend-module-announcements@workspace:plugins/search-backend-module-announcements": +"@backstage-community/plugin-search-backend-module-announcements@workspace:^, @backstage-community/plugin-search-backend-module-announcements@workspace:plugins/search-backend-module-announcements": version: 0.0.0-use.local resolution: "@backstage-community/plugin-search-backend-module-announcements@workspace:plugins/search-backend-module-announcements" dependencies: "@backstage-community/plugin-announcements-common": "workspace:^" + "@backstage-community/plugin-announcements-node": "workspace:^" "@backstage/backend-plugin-api": ^1.0.2 "@backstage/backend-test-utils": ^1.1.0 "@backstage/cli": ^0.29.0 "@backstage/plugin-search-backend-node": ^1.3.5 "@backstage/plugin-search-common": ^1.2.15 "@backstage/test-utils": ^1.7.2 - "@procore-oss/backstage-plugin-announcements-node": ^0.3.3 "@testing-library/react": ^14.0.0 msw: ^1.3.2 react: ^18.3.1 @@ -2630,7 +2689,7 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-app-api@npm:^1.1.0": +"@backstage/backend-app-api@npm:^1.0.2, @backstage/backend-app-api@npm:^1.1.0": version: 1.1.0 resolution: "@backstage/backend-app-api@npm:1.1.0" dependencies: @@ -2744,6 +2803,83 @@ __metadata: languageName: node linkType: hard +"@backstage/backend-defaults@npm:^0.5.3": + version: 0.5.3 + resolution: "@backstage/backend-defaults@npm:0.5.3" + dependencies: + "@aws-sdk/abort-controller": ^3.347.0 + "@aws-sdk/client-codecommit": ^3.350.0 + "@aws-sdk/client-s3": ^3.350.0 + "@aws-sdk/credential-providers": ^3.350.0 + "@aws-sdk/types": ^3.347.0 + "@backstage/backend-app-api": ^1.0.2 + "@backstage/backend-dev-utils": ^0.1.5 + "@backstage/backend-plugin-api": ^1.0.2 + "@backstage/cli-common": ^0.1.15 + "@backstage/cli-node": ^0.2.10 + "@backstage/config": ^1.3.0 + "@backstage/config-loader": ^1.9.2 + "@backstage/errors": ^1.2.5 + "@backstage/integration": ^1.15.2 + "@backstage/integration-aws-node": ^0.1.13 + "@backstage/plugin-auth-node": ^0.5.4 + "@backstage/plugin-events-node": ^0.4.5 + "@backstage/plugin-permission-node": ^0.8.5 + "@backstage/types": ^1.2.0 + "@google-cloud/storage": ^7.0.0 + "@keyv/memcache": ^1.3.5 + "@keyv/redis": ^2.5.3 + "@manypkg/get-packages": ^1.1.3 + "@octokit/rest": ^19.0.3 + "@opentelemetry/api": ^1.3.0 + "@types/cors": ^2.8.6 + "@types/express": ^4.17.6 + archiver: ^7.0.0 + base64-stream: ^1.0.0 + better-sqlite3: ^11.0.0 + compression: ^1.7.4 + concat-stream: ^2.0.0 + cookie: ^0.7.0 + cors: ^2.8.5 + cron: ^3.0.0 + express: ^4.17.1 + express-promise-router: ^4.1.0 + fs-extra: ^11.2.0 + git-url-parse: ^15.0.0 + helmet: ^6.0.0 + isomorphic-git: ^1.23.0 + jose: ^5.0.0 + keyv: ^4.5.2 + knex: ^3.0.0 + lodash: ^4.17.21 + logform: ^2.3.2 + luxon: ^3.0.0 + minimatch: ^9.0.0 + minimist: ^1.2.5 + morgan: ^1.10.0 + mysql2: ^3.0.0 + node-fetch: ^2.7.0 + node-forge: ^1.3.1 + p-limit: ^3.1.0 + path-to-regexp: ^8.0.0 + pg: ^8.11.3 + pg-connection-string: ^2.3.0 + pg-format: ^1.0.4 + raw-body: ^2.4.1 + selfsigned: ^2.0.0 + stoppable: ^1.1.0 + tar: ^6.1.12 + triple-beam: ^1.4.1 + uuid: ^11.0.0 + winston: ^3.2.1 + winston-transport: ^4.5.0 + yauzl: ^3.0.0 + yn: ^4.0.0 + zod: ^3.22.4 + checksum: 92be8c95a2a41ee4c040a4046703026127a5d3194828f907e862413c5c49bc305181bdf9734970f2e95909ceba6021cc8e28513631df43e92d2d5658d4f1bcce + languageName: node + linkType: hard + "@backstage/backend-defaults@npm:^0.6.0": version: 0.6.2 resolution: "@backstage/backend-defaults@npm:0.6.2" @@ -2834,6 +2970,30 @@ __metadata: languageName: node linkType: hard +"@backstage/backend-openapi-utils@npm:^0.3.0": + version: 0.3.0 + resolution: "@backstage/backend-openapi-utils@npm:0.3.0" + dependencies: + "@apidevtools/swagger-parser": ^10.1.0 + "@backstage/backend-plugin-api": ^1.0.2 + "@backstage/errors": ^1.2.5 + "@backstage/types": ^1.2.0 + "@types/express": ^4.17.6 + "@types/express-serve-static-core": ^4.17.5 + ajv: ^8.16.0 + express: ^4.17.1 + express-openapi-validator: ^5.0.4 + express-promise-router: ^4.1.0 + get-port: ^5.1.1 + json-schema-to-ts: ^3.0.0 + lodash: ^4.17.21 + mockttp: ^3.13.0 + openapi-merge: ^1.3.2 + openapi3-ts: ^3.1.2 + checksum: 93b50291a994fd4431cad2b7148aee92b36afa7a2c09d51b414722d1696926a2a30a3c55c228bf28e5003e2594572fe8bf9ec3dee48e2f91f0eab305e8d10db9 + languageName: node + linkType: hard + "@backstage/backend-plugin-api@npm:^1.0.0, @backstage/backend-plugin-api@npm:^1.0.1, @backstage/backend-plugin-api@npm:^1.0.2, @backstage/backend-plugin-api@npm:^1.1.0": version: 1.1.0 resolution: "@backstage/backend-plugin-api@npm:1.1.0" @@ -2889,7 +3049,7 @@ __metadata: languageName: node linkType: hard -"@backstage/catalog-client@npm:^1.9.0": +"@backstage/catalog-client@npm:^1.8.0, @backstage/catalog-client@npm:^1.9.0": version: 1.9.0 resolution: "@backstage/catalog-client@npm:1.9.0" dependencies: @@ -2920,7 +3080,7 @@ __metadata: languageName: node linkType: hard -"@backstage/cli-node@npm:^0.2.11, @backstage/cli-node@npm:^0.2.9": +"@backstage/cli-node@npm:^0.2.10, @backstage/cli-node@npm:^0.2.11, @backstage/cli-node@npm:^0.2.9": version: 0.2.11 resolution: "@backstage/cli-node@npm:0.2.11" dependencies: @@ -3085,7 +3245,7 @@ __metadata: languageName: node linkType: hard -"@backstage/config-loader@npm:^1.9.1, @backstage/config-loader@npm:^1.9.3, @backstage/config-loader@npm:^1.9.4": +"@backstage/config-loader@npm:^1.9.1, @backstage/config-loader@npm:^1.9.2, @backstage/config-loader@npm:^1.9.3, @backstage/config-loader@npm:^1.9.4": version: 1.9.4 resolution: "@backstage/config-loader@npm:1.9.4" dependencies: @@ -3108,7 +3268,7 @@ __metadata: languageName: node linkType: hard -"@backstage/config@npm:^1.2.0, @backstage/config@npm:^1.3.1": +"@backstage/config@npm:^1.2.0, @backstage/config@npm:^1.3.0, @backstage/config@npm:^1.3.1": version: 1.3.1 resolution: "@backstage/config@npm:1.3.1" dependencies: @@ -3400,7 +3560,7 @@ __metadata: languageName: node linkType: hard -"@backstage/integration-aws-node@npm:^0.1.12, @backstage/integration-aws-node@npm:^0.1.14": +"@backstage/integration-aws-node@npm:^0.1.12, @backstage/integration-aws-node@npm:^0.1.13, @backstage/integration-aws-node@npm:^0.1.14": version: 0.1.14 resolution: "@backstage/integration-aws-node@npm:0.1.14" dependencies: @@ -3436,7 +3596,7 @@ __metadata: languageName: node linkType: hard -"@backstage/integration@npm:^1.15.0, @backstage/integration@npm:^1.16.0": +"@backstage/integration@npm:^1.15.0, @backstage/integration@npm:^1.15.2, @backstage/integration@npm:^1.16.0": version: 1.16.0 resolution: "@backstage/integration@npm:1.16.0" dependencies: @@ -3480,7 +3640,306 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-auth-node@npm:^0.5.2, @backstage/plugin-auth-node@npm:^0.5.5": +"@backstage/plugin-auth-backend-module-atlassian-provider@npm:^0.3.3": + version: 0.3.3 + resolution: "@backstage/plugin-auth-backend-module-atlassian-provider@npm:0.3.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.18.2 + passport: ^0.7.0 + passport-atlassian-oauth2: ^2.1.0 + checksum: 500819d2d4597d6745f84b706525425f64aa6e1027f4bfde39d23225b9c0155aad61214ad20ba64aa9106cc32ec7fb80bcdf465b705cdaaa87b7277fe144006c + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-auth0-provider@npm:^0.1.3": + version: 0.1.3 + resolution: "@backstage/plugin-auth-backend-module-auth0-provider@npm:0.1.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.17.1 + passport-auth0: ^1.4.3 + passport-oauth2: ^1.6.1 + checksum: 40fb863f1e951ba6b1426606cb84916bc5ac56c4248b2e26e92cb8bd9b73bf54fc81a8c9f33468cf459f473bf7904ab805f00a1d3598eb2f487b339ff0c15b4a + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-aws-alb-provider@npm:^0.3.1": + version: 0.3.1 + resolution: "@backstage/plugin-auth-backend-module-aws-alb-provider@npm:0.3.1" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-backend": ^0.24.1 + "@backstage/plugin-auth-node": ^0.5.5 + jose: ^5.0.0 + node-cache: ^5.1.2 + checksum: d6e91c7523947c25c83d31a0a9bd307a0bf8a70ca6198cd7654868000a2be53afdcdd5b280e2c962a81362f2c1de3dee95132af9d1a9a7420e02300cf9a87614 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-azure-easyauth-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-azure-easyauth-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/catalog-model": ^1.7.2 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-node": ^0.5.5 + "@types/passport": ^1.0.16 + express: ^4.19.2 + jose: ^5.0.0 + passport: ^0.7.0 + checksum: 2c9c2ff7f1829f1123a14bcfe22a0623f4d5769d27701606d69617c9f2f2beb91b5059625b230d30f3f612fede06ca7c922a1e80d0ebd11bf9326f786e58c02b + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-bitbucket-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-bitbucket-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.18.2 + passport: ^0.7.0 + passport-bitbucket-oauth2: ^0.1.2 + checksum: bfa7fbe3fc94d639908a4eb3f288f2f2fd3684b8094f760a878f9fd608d8d86eac4257f84c59a5f4251f52849bb6e9621767006f7e0960a72226789a17847314 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-bitbucket-server-provider@npm:^0.1.3": + version: 0.1.3 + resolution: "@backstage/plugin-auth-backend-module-bitbucket-server-provider@npm:0.1.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + passport: ^0.7.0 + passport-oauth2: ^1.6.1 + checksum: b4c2d9fcfcca85c094166daeef1f8fb7e3d14c60b2f60627793e7af563502e750c5a29085af71d22cdb5793bf3a1c93e7b69041040e628ecb90db1db64b5346a + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-cloudflare-access-provider@npm:^0.3.3": + version: 0.3.3 + resolution: "@backstage/plugin-auth-backend-module-cloudflare-access-provider@npm:0.3.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/config": ^1.3.1 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.18.2 + jose: ^5.0.0 + checksum: 3078d994dd0a31c345cfa017c88855de1fe2a3408d78bbf4cef957c35eb3ffac8930669dae5431fef2ee677a74cff8788b9eb03514ef8c282410a3e341628a9e + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-gcp-iap-provider@npm:^0.3.3": + version: 0.3.3 + resolution: "@backstage/plugin-auth-backend-module-gcp-iap-provider@npm:0.3.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-node": ^0.5.5 + "@backstage/types": ^1.2.0 + google-auth-library: ^9.0.0 + checksum: 911cba93765c81bf64093c93e9d7e145d85dc836aa9ccfeff4e846eb335a97cafca81fffff8ee627951c3e8b141d850f4d3fec118679b9750cb8695baa747335 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-github-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-github-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + passport-github2: ^0.1.12 + checksum: b0e995bbfc91dcd6b0ecc167ec08cc0499e04e96f50b4c48c783c7b09c44d727789b3ac09831170c69c978a216fe5b2cd29e8ef47d493e5cfe0fd770ecb95cc8 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-gitlab-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-gitlab-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.18.2 + passport: ^0.7.0 + passport-gitlab2: ^5.0.0 + checksum: 0129778e83d8fc9d8952d496f50cd5c882655f992df193935c4eefad5775b1fcecfeca88485dee65ec8382e5109a2b9b080b7668d08eab59318b168257eaa150 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-google-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-google-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + google-auth-library: ^9.0.0 + passport-google-oauth20: ^2.0.0 + checksum: 5e4a2392f8206e4ebe362162e22b1b797b20dd6ad28e6218b59f93596420937e6efd6f56148fa95a0fc20bccaa7381264b329a70643de5bb5b2af51080cf6a5a + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-guest-provider@npm:^0.2.2": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-guest-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/catalog-model": ^1.7.2 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-node": ^0.5.5 + passport-oauth2: ^1.7.0 + checksum: 763570fda58c20404824c71f5c0f639e09bc947e9cdafaf0948251eaa3a2d2398ee5555eaaa9d14e7d0f1a62a0b6674d37457cc4421d2107d2321c5ead48fb15 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-microsoft-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-microsoft-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.18.2 + jose: ^5.0.0 + passport-microsoft: ^1.0.0 + checksum: ac56d374990a340263ba42b70100812aa561e05741752c615aba67d94b4364286dc3defb6b338764ad8c834987259c7f29dbb943ec21ea9707f58d3f479131a4 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-oauth2-provider@npm:^0.3.3": + version: 0.3.3 + resolution: "@backstage/plugin-auth-backend-module-oauth2-provider@npm:0.3.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + passport: ^0.7.0 + passport-oauth2: ^1.6.1 + checksum: 9021087768985da64550651872496c94ea056bcf8f0eb3c04bed8229c6ac10fc7148ffc978a6beaf9170bc6142e8e450d4c993e1e8aafb284813abf53f8be285 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-oauth2-proxy-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-oauth2-proxy-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-node": ^0.5.5 + jose: ^5.0.0 + checksum: 0003eda5c3a80ed193d97b569c272da58b4f251c889f8b68d58b5c088e5485283160249bdb556296d72570da1987bc3c491c292c658a7e56197c857b13c79835 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-oidc-provider@npm:^0.3.3": + version: 0.3.3 + resolution: "@backstage/plugin-auth-backend-module-oidc-provider@npm:0.3.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-backend": ^0.24.1 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.18.2 + openid-client: ^5.5.0 + passport: ^0.7.0 + checksum: fb20f84b97ae2f69547531ccb44fd6f3a2fb28529205d5a46b63ba5969e71bee27050fac0df498efd6ad0ee3cbc2aa3f916090f9b4ff5d583f158e0929f77c6a + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-okta-provider@npm:^0.1.3": + version: 0.1.3 + resolution: "@backstage/plugin-auth-backend-module-okta-provider@npm:0.1.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + "@davidzemon/passport-okta-oauth": ^0.0.5 + express: ^4.18.2 + passport: ^0.7.0 + checksum: 70c683063260d8cd712c9a07c0b1e2fc5ebed27237318350704d7c2dd0a515e4c06f54201f4ef9c57977ab0695f9107421f3907602977e13ddea3842229ebf4b + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend-module-onelogin-provider@npm:^0.2.3": + version: 0.2.3 + resolution: "@backstage/plugin-auth-backend-module-onelogin-provider@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + express: ^4.18.2 + passport: ^0.7.0 + passport-onelogin-oauth: ^0.0.1 + checksum: db99e6645b7f386163cfb87f08e0d5a8fb7cf45b0f4113c0babae4a79522029fa3421712530cb77a403fb7dce2c81bbce51babec48fa4fa98ad7185cc05eed26 + languageName: node + linkType: hard + +"@backstage/plugin-auth-backend@npm:^0.24.0, @backstage/plugin-auth-backend@npm:^0.24.1": + version: 0.24.1 + resolution: "@backstage/plugin-auth-backend@npm:0.24.1" + dependencies: + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/catalog-client": ^1.9.0 + "@backstage/catalog-model": ^1.7.2 + "@backstage/config": ^1.3.1 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-backend-module-atlassian-provider": ^0.3.3 + "@backstage/plugin-auth-backend-module-auth0-provider": ^0.1.3 + "@backstage/plugin-auth-backend-module-aws-alb-provider": ^0.3.1 + "@backstage/plugin-auth-backend-module-azure-easyauth-provider": ^0.2.3 + "@backstage/plugin-auth-backend-module-bitbucket-provider": ^0.2.3 + "@backstage/plugin-auth-backend-module-bitbucket-server-provider": ^0.1.3 + "@backstage/plugin-auth-backend-module-cloudflare-access-provider": ^0.3.3 + "@backstage/plugin-auth-backend-module-gcp-iap-provider": ^0.3.3 + "@backstage/plugin-auth-backend-module-github-provider": ^0.2.3 + "@backstage/plugin-auth-backend-module-gitlab-provider": ^0.2.3 + "@backstage/plugin-auth-backend-module-google-provider": ^0.2.3 + "@backstage/plugin-auth-backend-module-microsoft-provider": ^0.2.3 + "@backstage/plugin-auth-backend-module-oauth2-provider": ^0.3.3 + "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": ^0.2.3 + "@backstage/plugin-auth-backend-module-oidc-provider": ^0.3.3 + "@backstage/plugin-auth-backend-module-okta-provider": ^0.1.3 + "@backstage/plugin-auth-backend-module-onelogin-provider": ^0.2.3 + "@backstage/plugin-auth-node": ^0.5.5 + "@backstage/plugin-catalog-node": ^1.15.0 + "@backstage/types": ^1.2.0 + "@google-cloud/firestore": ^7.0.0 + "@node-saml/passport-saml": ^5.0.0 + "@types/express": ^4.17.6 + "@types/passport": ^1.0.3 + compression: ^1.7.4 + connect-session-knex: ^4.0.0 + cookie-parser: ^1.4.5 + cors: ^2.8.5 + express: ^4.17.1 + express-promise-router: ^4.1.0 + express-session: ^1.17.1 + fs-extra: ^11.2.0 + google-auth-library: ^9.0.0 + jose: ^5.0.0 + knex: ^3.0.0 + lodash: ^4.17.21 + luxon: ^3.0.0 + minimatch: ^9.0.0 + morgan: ^1.10.0 + node-cache: ^5.1.2 + openid-client: ^5.2.1 + passport: ^0.7.0 + passport-auth0: ^1.4.3 + passport-github2: ^0.1.12 + passport-google-oauth20: ^2.0.0 + passport-microsoft: ^1.0.0 + passport-oauth2: ^1.6.1 + passport-onelogin-oauth: ^0.0.1 + uuid: ^11.0.0 + winston: ^3.2.1 + yn: ^4.0.0 + checksum: 968bbdc086813c92cdffab46932a334e867ba25a0cf8cd582f7d1d4a39ef0f6f3ead1d02c6f157c6477194a94969bbb905bd1ec197d052bc8f36e1e4429ffc12 + languageName: node + linkType: hard + +"@backstage/plugin-auth-node@npm:^0.5.2, @backstage/plugin-auth-node@npm:^0.5.4, @backstage/plugin-auth-node@npm:^0.5.5": version: 0.5.5 resolution: "@backstage/plugin-auth-node@npm:0.5.5" dependencies: @@ -3516,6 +3975,22 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-catalog-node@npm:^1.15.0": + version: 1.15.0 + resolution: "@backstage/plugin-catalog-node@npm:1.15.0" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/catalog-client": ^1.9.0 + "@backstage/catalog-model": ^1.7.2 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-catalog-common": ^1.1.2 + "@backstage/plugin-permission-common": ^0.8.3 + "@backstage/plugin-permission-node": ^0.8.6 + "@backstage/types": ^1.2.0 + checksum: 2d87606b8d02b7bed1fd1d3fc5b96008a6b8b6c46ea0f18246ddab6f1c8f9159bdfdf814192d0e858c829c1ade05f70061a840b02ab91fc4422ec5e45e979505 + languageName: node + linkType: hard + "@backstage/plugin-catalog-react@npm:^1.14.2, @backstage/plugin-catalog-react@npm:^1.15.0": version: 1.15.0 resolution: "@backstage/plugin-catalog-react@npm:1.15.0" @@ -3557,7 +4032,28 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-events-node@npm:^0.4.6": +"@backstage/plugin-events-backend@npm:^0.3.16": + version: 0.3.16 + resolution: "@backstage/plugin-events-backend@npm:0.3.16" + dependencies: + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-openapi-utils": ^0.3.0 + "@backstage/backend-plugin-api": ^1.0.2 + "@backstage/config": ^1.3.0 + "@backstage/errors": ^1.2.5 + "@backstage/plugin-events-node": ^0.4.5 + "@backstage/types": ^1.2.0 + "@types/express": ^4.17.6 + content-type: ^1.0.5 + express: ^4.17.1 + express-promise-router: ^4.1.0 + knex: ^3.0.0 + winston: ^3.2.1 + checksum: b08d4eb6e9a24d0a1249956c1c6250ff634b395975e82e4b147c5de93d2e1a56c6c7d16fb1835b7e03beaa76b49eed119b2ccb1415b83158bd0ef101a7c83e76 + languageName: node + linkType: hard + +"@backstage/plugin-events-node@npm:^0.4.5, @backstage/plugin-events-node@npm:^0.4.6": version: 0.4.6 resolution: "@backstage/plugin-events-node@npm:0.4.6" dependencies: @@ -3570,6 +4066,40 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-permission-backend-module-allow-all-policy@npm:^0.2.2": + version: 0.2.3 + resolution: "@backstage/plugin-permission-backend-module-allow-all-policy@npm:0.2.3" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/plugin-auth-node": ^0.5.5 + "@backstage/plugin-permission-common": ^0.8.3 + "@backstage/plugin-permission-node": ^0.8.6 + checksum: b89c187c6222d7fa9034b06821b72ea80d103ef58e8845f86fb6c71de345c1f86c11f59290257105a77124849c908758c44b27531f172af46176255b05b9c501 + languageName: node + linkType: hard + +"@backstage/plugin-permission-backend@npm:^0.5.51": + version: 0.5.52 + resolution: "@backstage/plugin-permission-backend@npm:0.5.52" + dependencies: + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/config": ^1.3.1 + "@backstage/errors": ^1.2.6 + "@backstage/plugin-auth-node": ^0.5.5 + "@backstage/plugin-permission-common": ^0.8.3 + "@backstage/plugin-permission-node": ^0.8.6 + "@types/express": ^4.17.6 + dataloader: ^2.0.0 + express: ^4.17.1 + express-promise-router: ^4.1.0 + lodash: ^4.17.21 + yn: ^4.0.0 + zod: ^3.22.4 + checksum: 1c69bb034181421a691460a2b091471e07b51b939a968ddc777cdd0dab36e3ad7302b7fb4cac1707622c269c6e81006ee9eba8ad9cf1d2f8b7579c4ae06586f3 + languageName: node + linkType: hard + "@backstage/plugin-permission-common@npm:^0.8.2, @backstage/plugin-permission-common@npm:^0.8.3": version: 0.8.3 resolution: "@backstage/plugin-permission-common@npm:0.8.3" @@ -3585,7 +4115,7 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-node@npm:^0.8.6": +"@backstage/plugin-permission-node@npm:^0.8.5, @backstage/plugin-permission-node@npm:^0.8.6": version: 0.8.6 resolution: "@backstage/plugin-permission-node@npm:0.8.6" dependencies: @@ -3682,6 +4212,45 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-signals-backend@npm:^0.2.3": + version: 0.2.4 + resolution: "@backstage/plugin-signals-backend@npm:0.2.4" + dependencies: + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/config": ^1.3.1 + "@backstage/plugin-auth-node": ^0.5.5 + "@backstage/plugin-events-node": ^0.4.6 + "@backstage/plugin-signals-node": ^0.1.15 + "@backstage/types": ^1.2.0 + "@types/express": ^4.17.6 + express: ^4.17.1 + express-promise-router: ^4.1.0 + http-proxy-middleware: ^2.0.0 + uuid: ^11.0.0 + winston: ^3.2.1 + ws: ^8.18.0 + yn: ^4.0.0 + checksum: 7e45391a17ef74682f6bfb77de67f9d4e88b267ddfe1b9626973c111dfd49cccd8df79529f94ea004b91b99eeaa3488b8927ff3e04701021ed62bb0ad179ba81 + languageName: node + linkType: hard + +"@backstage/plugin-signals-node@npm:^0.1.14, @backstage/plugin-signals-node@npm:^0.1.15": + version: 0.1.15 + resolution: "@backstage/plugin-signals-node@npm:0.1.15" + dependencies: + "@backstage/backend-plugin-api": ^1.1.0 + "@backstage/config": ^1.3.1 + "@backstage/plugin-auth-node": ^0.5.5 + "@backstage/plugin-events-node": ^0.4.6 + "@backstage/types": ^1.2.0 + express: ^4.17.1 + uuid: ^11.0.0 + ws: ^8.18.0 + checksum: 55554ae37d43aafa34a1c770aa56af8403bad75d99c6462ab6d5d4bfb8e264e4cae729a538ab2b9e5d9e1ea2f4e4055be8fad99e41e06c7f29d1f540945be898 + languageName: node + linkType: hard + "@backstage/plugin-signals-react@npm:^0.0.7": version: 0.0.7 resolution: "@backstage/plugin-signals-react@npm:0.0.7" @@ -4171,6 +4740,18 @@ __metadata: languageName: node linkType: hard +"@davidzemon/passport-okta-oauth@npm:^0.0.5": + version: 0.0.5 + resolution: "@davidzemon/passport-okta-oauth@npm:0.0.5" + dependencies: + "@types/passport-oauth2": ^1.4.11 + passport-oauth2: ^1.6.1 + pkginfo: ^0.4.1 + uid2: ^1.0.0 + checksum: 0bd7c33ffd34a7fed4c6a43704792817b8ea6d0783060c32a55619d50b05c79db6f0a8e23b15327a4c7ce0cd8ea2d7486f320eebae3d4ca73e36baa415802ec4 + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.13.5": version: 11.13.5 resolution: "@emotion/babel-plugin@npm:11.13.5" @@ -4716,6 +5297,19 @@ __metadata: languageName: node linkType: hard +"@google-cloud/firestore@npm:^7.0.0": + version: 7.11.0 + resolution: "@google-cloud/firestore@npm:7.11.0" + dependencies: + "@opentelemetry/api": ^1.3.0 + fast-deep-equal: ^3.1.1 + functional-red-black-tree: ^1.0.1 + google-gax: ^4.3.3 + protobufjs: ^7.2.6 + checksum: b926123db5e3f37704c0aa51baee1726b72910a37c7fe99bbfe048afb1fba7fa40d7e5f7c017c7284ebd9273c0237da5c00fac81772ba0de1bed97dc9b71e709 + languageName: node + linkType: hard + "@google-cloud/paginator@npm:^5.0.0": version: 5.0.2 resolution: "@google-cloud/paginator@npm:5.0.2" @@ -4763,6 +5357,118 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/merge@npm:8.3.1": + version: 8.3.1 + resolution: "@graphql-tools/merge@npm:8.3.1" + dependencies: + "@graphql-tools/utils": 8.9.0 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 16af6be2249f4f500a4c2f5d3db2e0efd56ad69b5e10499649c6fc979c257af12e131112304a16699654b54daab37a80737e0538478bc45a0053b9bc859a7ac1 + languageName: node + linkType: hard + +"@graphql-tools/schema@npm:^8.5.0": + version: 8.5.1 + resolution: "@graphql-tools/schema@npm:8.5.1" + dependencies: + "@graphql-tools/merge": 8.3.1 + "@graphql-tools/utils": 8.9.0 + tslib: ^2.4.0 + value-or-promise: 1.0.11 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 91363cd4371e347af40ef66f7d903b5d4f5998bfaec9214768e6a795136ef6372f9f225e05e18daacd929e23695811f15e791c6cbe082bf5b5d03b16b1f874f8 + languageName: node + linkType: hard + +"@graphql-tools/utils@npm:8.9.0": + version: 8.9.0 + resolution: "@graphql-tools/utils@npm:8.9.0" + dependencies: + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 8d1d8a11722e211dc8723cd3fd7a97fa5401ab22146e4240a0f9d45547792476c34814ff914524578beec961db7b0ff23a6ddff8fe059764537e594cff35c906 + languageName: node + linkType: hard + +"@graphql-tools/utils@npm:^8.8.0": + version: 8.13.1 + resolution: "@graphql-tools/utils@npm:8.13.1" + dependencies: + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: ff04fdeb29e9ac596ea53386cd5b23cd741bb14c1997c6b0ba3c34ca165bd82b528a355e8c8e2ba726eb39e833ba9cbb0851ba0addb8c6d367089a1145bf9a49 + languageName: node + linkType: hard + +"@grpc/grpc-js@npm:^1.10.9": + version: 1.12.5 + resolution: "@grpc/grpc-js@npm:1.12.5" + dependencies: + "@grpc/proto-loader": ^0.7.13 + "@js-sdsl/ordered-map": ^4.4.2 + checksum: 415bad10412b713f1f4094e6af3d2067d03794540fecc16cd3cdcd6079e4a632178da25485dfef9a07add8bf498cfccf1a54f8184d671eb256932c47cfe7f785 + languageName: node + linkType: hard + +"@grpc/proto-loader@npm:^0.7.13": + version: 0.7.13 + resolution: "@grpc/proto-loader@npm:0.7.13" + dependencies: + lodash.camelcase: ^4.3.0 + long: ^5.0.0 + protobufjs: ^7.2.5 + yargs: ^17.7.2 + bin: + proto-loader-gen-types: build/bin/proto-loader-gen-types.js + checksum: 399c1b8a4627f93dc31660d9636ea6bf58be5675cc7581e3df56a249369e5be02c6cd0d642c5332b0d5673bc8621619bc06fb045aa3e8f57383737b5d35930dc + languageName: node + linkType: hard + +"@httptoolkit/httpolyglot@npm:^2.2.1": + version: 2.2.2 + resolution: "@httptoolkit/httpolyglot@npm:2.2.2" + dependencies: + "@types/node": "*" + checksum: a08a7ef025bbcf2163dd2d3a9b2c4783c353bc5b0a8a07c65aef87fa530500dc77942db83e28e51bb5d1fc2cb992011622d05ae1347340aa4565c4eefa38ee22 + languageName: node + linkType: hard + +"@httptoolkit/subscriptions-transport-ws@npm:^0.11.2": + version: 0.11.2 + resolution: "@httptoolkit/subscriptions-transport-ws@npm:0.11.2" + dependencies: + backo2: ^1.0.2 + eventemitter3: ^3.1.0 + iterall: ^1.2.1 + symbol-observable: ^1.0.4 + ws: ^8.8.0 + peerDependencies: + graphql: ^15.7.2 || ^16.0.0 + checksum: a2d99b4d8e46b46fd5d4fac3456fa685dba7d876908e632c73af014fdcc92ae1f77f8c542e8b63ae747a164e9d2e4be95c5046665f9e7b5622f02dc6d7d04549 + languageName: node + linkType: hard + +"@httptoolkit/websocket-stream@npm:^6.0.1": + version: 6.0.1 + resolution: "@httptoolkit/websocket-stream@npm:6.0.1" + dependencies: + "@types/ws": "*" + duplexify: ^3.5.1 + inherits: ^2.0.1 + isomorphic-ws: ^4.0.1 + readable-stream: ^2.3.3 + safe-buffer: ^5.1.2 + ws: "*" + xtend: ^4.0.0 + checksum: e70059c24499abab695e7bc269aefc1a751d161296975a4af932577497c4ecd66b7745dc0c63608e06989442db996d76e563bce08156563bac7bc3411ad9bcee + languageName: node + linkType: hard + "@humanwhocodes/config-array@npm:^0.13.0": version: 0.13.0 resolution: "@humanwhocodes/config-array@npm:0.13.0" @@ -5155,7 +5861,14 @@ __metadata: languageName: node linkType: hard -"@jsdevtools/ono@npm:^7.1.3": +"@js-sdsl/ordered-map@npm:^4.4.2": + version: 4.4.2 + resolution: "@js-sdsl/ordered-map@npm:4.4.2" + checksum: a927ae4ff8565ecb75355cc6886a4f8fadbf2af1268143c96c0cce3ba01261d241c3f4ba77f21f3f017a00f91dfe9e0673e95f830255945c80a0e96c6d30508a + languageName: node + linkType: hard + +"@jsdevtools/ono@npm:7.1.3, @jsdevtools/ono@npm:^7.1.3": version: 7.1.3 resolution: "@jsdevtools/ono@npm:7.1.3" checksum: 2297fcd472ba810bffe8519d2249171132844c7174f3a16634f9260761c8c78bc0428a4190b5b6d72d45673c13918ab9844d706c3ed4ef8f62ab11a2627a08ad @@ -5840,22 +6553,22 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.16.12": - version: 5.16.12 - resolution: "@mui/core-downloads-tracker@npm:5.16.12" - checksum: ade13080e61da63394556e8e3da5c8d20147b1b51f73487f8972bbf25812efa90e1a757d83145e55b215f7e1c08a2e4b65a081e0f25ce2992e076f35aa17ba94 +"@mui/core-downloads-tracker@npm:^5.16.13": + version: 5.16.13 + resolution: "@mui/core-downloads-tracker@npm:5.16.13" + checksum: d9c6837dabd873e05b0bf81389c3dfb60fbc577cceff7f98f94c60f688f02d33a9200082e1a6756a0de4bd1985aa27932c677376ba7e6b1ad206a8b6887bda07 languageName: node linkType: hard "@mui/material@npm:^5.12.2, @mui/material@npm:^5.15.6": - version: 5.16.12 - resolution: "@mui/material@npm:5.16.12" + version: 5.16.13 + resolution: "@mui/material@npm:5.16.13" dependencies: "@babel/runtime": ^7.23.9 - "@mui/core-downloads-tracker": ^5.16.12 - "@mui/system": ^5.16.12 + "@mui/core-downloads-tracker": ^5.16.13 + "@mui/system": ^5.16.13 "@mui/types": ^7.2.15 - "@mui/utils": ^5.16.12 + "@mui/utils": ^5.16.13 "@popperjs/core": ^2.11.8 "@types/react-transition-group": ^4.4.10 clsx: ^2.1.0 @@ -5876,16 +6589,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: a29677300bb38fddf2e4455cf497233676a6a4ee982b1d4ff4c5b520ce608da526ba934d6670747e207bea354725e68854a4e5671c0980f70dba0f9cf20178c8 + checksum: 40a85c43e3556a01a80930a3742a04690a092a3e291527b9d94ec24a8c267c27a5da91fc9f6cd671d20eeb3a1eeeff7f97034ba8d44a08ed89ae1028719262e9 languageName: node linkType: hard -"@mui/private-theming@npm:^5.16.12": - version: 5.16.12 - resolution: "@mui/private-theming@npm:5.16.12" +"@mui/private-theming@npm:^5.16.13": + version: 5.16.13 + resolution: "@mui/private-theming@npm:5.16.13" dependencies: "@babel/runtime": ^7.23.9 - "@mui/utils": ^5.16.12 + "@mui/utils": ^5.16.13 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -5893,13 +6606,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: a51ddd672545be389528d501fe591c3fd03d1317373760eb942e6bd489e56a9bd0da7add01c9420a1007b113902caef2fadf7c9cb4f9b17ea9b2e0007979cb71 + checksum: 6cdc65d803abb36c80dbb7a7cb9d3e7cb3e947da16179c1d16c2367cd172c4c2b989be96ac0f72b8f037bedca1a7430fa9e6374c94c3f536d9bc0a8b8a3e4e93 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.16.12": - version: 5.16.12 - resolution: "@mui/styled-engine@npm:5.16.12" +"@mui/styled-engine@npm:^5.16.13": + version: 5.16.13 + resolution: "@mui/styled-engine@npm:5.16.13" dependencies: "@babel/runtime": ^7.23.9 "@emotion/cache": ^11.13.5 @@ -5914,19 +6627,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: fa762742ef0a41077dfa0c12c5e3441e32d357192f32fc16b29ee7897ce92a4665cd644b09655dea02fe402da4fc83649901bd34822af784ed359bcc6572ee39 + checksum: d9459ef4baac056d1a65e351e084b2fe1eb30516907fc48166f570c60e3db3cb30de2d0af2bf22a8caa004bf2c37a1b831ccad1069b1d03cfae202c247967e44 languageName: node linkType: hard -"@mui/system@npm:^5.16.12": - version: 5.16.12 - resolution: "@mui/system@npm:5.16.12" +"@mui/system@npm:^5.16.13": + version: 5.16.13 + resolution: "@mui/system@npm:5.16.13" dependencies: "@babel/runtime": ^7.23.9 - "@mui/private-theming": ^5.16.12 - "@mui/styled-engine": ^5.16.12 + "@mui/private-theming": ^5.16.13 + "@mui/styled-engine": ^5.16.13 "@mui/types": ^7.2.15 - "@mui/utils": ^5.16.12 + "@mui/utils": ^5.16.13 clsx: ^2.1.0 csstype: ^3.1.3 prop-types: ^15.8.1 @@ -5942,7 +6655,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 261fbf349e6ef1462f46d92221697efe0aefcde33975eeb214dd2fa97b77ca76236cae0c221bc9e30e84775b8d3ebd9a4dd779666e833f671cf7b3a11a50a39d + checksum: 95957ce47dedd41b3262eaf6b214284f407df985cca7d26fd26790a9f4609f11e6260a5918df9e3e11eee0830d3afa8958fcc366242f031dda54279d2aa92fb0 languageName: node linkType: hard @@ -5958,9 +6671,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.16.12": - version: 5.16.12 - resolution: "@mui/utils@npm:5.16.12" +"@mui/utils@npm:^5.16.13": + version: 5.16.13 + resolution: "@mui/utils@npm:5.16.13" dependencies: "@babel/runtime": ^7.23.9 "@mui/types": ^7.2.15 @@ -5974,7 +6687,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 0f6df27d39d9c7c5dcd041fc8a2e40bd222180aaa140c7c4f7f7a79e79edbd2f15ffcd407ab27ec58142a2cb9858f078cf20f0ccb0d854ec7a426475bf0dabce + checksum: 89cc2805afec56b96445e3ffacbd91024ada12c233456a3d00d9e2173c6b18168c62f131271af2bcde86586af719f9898727cd41782f2f49b96d49fcd6286994 languageName: node linkType: hard @@ -6038,6 +6751,40 @@ __metadata: 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" + dependencies: + "@types/debug": ^4.1.12 + "@types/qs": ^6.9.11 + "@types/xml-encryption": ^1.2.4 + "@types/xml2js": ^0.4.14 + "@xmldom/is-dom-node": ^1.0.1 + "@xmldom/xmldom": ^0.8.10 + debug: ^4.3.4 + xml-crypto: ^6.0.0 + xml-encryption: ^3.0.2 + xml2js: ^0.6.2 + xmlbuilder: ^15.1.1 + xpath: ^0.0.34 + checksum: 6a9ff9d922befc8ccb3338fe8f989eba66d3f781a3d1f39c4bd1d5c58fc1acd74ae05d94a08ef9c4ff1990ad38d0ca97135de52bbfe79196594e76f75e7b7e13 + languageName: node + linkType: hard + +"@node-saml/passport-saml@npm:^5.0.0": + version: 5.0.0 + resolution: "@node-saml/passport-saml@npm:5.0.0" + dependencies: + "@node-saml/node-saml": ^5.0.0 + "@types/express": ^4.17.21 + "@types/passport": ^1.0.16 + "@types/passport-strategy": ^0.2.38 + passport: ^0.7.0 + passport-strategy: ^1.0.0 + checksum: f5a5e3f731decd7cc3fa5effdd462e3265fa9da4455014041c62e678212b86200ec07e34083f6107c2db79157334e8f6af8658220bb865ad579317ca9465b05b + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -6415,7 +7162,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/api@npm:^1.9.0": +"@opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.9.0": version: 1.9.0 resolution: "@opentelemetry/api@npm:1.9.0" checksum: 9e88e59d53ced668f3daaecfd721071c5b85a67dd386f1c6f051d1be54375d850016c881f656ffbe9a03bedae85f7e89c2f2b635313f9c9b195ad033cdc31020 @@ -6482,18 +7229,6 @@ __metadata: languageName: node linkType: hard -"@procore-oss/backstage-plugin-announcements-node@npm:^0.3.3": - version: 0.3.4 - resolution: "@procore-oss/backstage-plugin-announcements-node@npm:0.3.4" - dependencies: - "@backstage/backend-plugin-api": ^1.0.2 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/errors": ^1.2.5 - "@procore-oss/backstage-plugin-announcements-common": ^0.2.9 - checksum: d1609b68dd6c8c40939066e8137264bf44096dfec1bcd3b105f3de542d8bf23060e0dd9e0dd99b6f1f9396918ad3742ac7f3c7c812fe9c0801b7ee0524bcde41 - languageName: node - linkType: hard - "@procore-oss/backstage-plugin-announcements-react@npm:^0.5.0": version: 0.5.0 resolution: "@procore-oss/backstage-plugin-announcements-react@npm:0.5.0" @@ -6509,6 +7244,79 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 011fe7ef0826b0fd1a95935a033a3c0fd08483903e1aa8f8b4e0704e3233406abb9ee25350ec0c20bbecb2aad8da0dcea58b392bbd77d6690736f02c143865d2 + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 67173ac34de1e242c55da52c2f5bdc65505d82453893f9b51dc74af9fe4c065cf4a657a4538e91b0d4a1a1e0a0642215e31894c31650ff6e3831471061e1ee9e + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 59240c850b1d3d0b56d8f8098dd04787dcaec5c5bd8de186fa548de86b86076e1c50e80144b90335e705a044edf5bc8b0998548474c2a10a98c7e004a1547e4b + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 0369163a3d226851682f855f81413cbf166cd98f131edb94a0f67f79e75342d86e89df9d7a1df08ac28be2bc77e0a7f0200526bb6c2a407abbfee1f0262d5fd7 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": ^1.1.1 + "@protobufjs/inquire": ^1.1.0 + checksum: 3fce7e09eb3f1171dd55a192066450f65324fd5f7cc01a431df01bb00d0a895e6bfb5b0c5561ce157ee1d886349c90703d10a4e11a1a256418ff591b969b3477 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 5781e1241270b8bd1591d324ca9e3a3128d2f768077a446187a049e36505e91bc4156ed5ac3159c3ce3d2ba3743dbc757b051b2d723eea9cd367bfd54ab29b2f + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: ca06f02eaf65ca36fb7498fc3492b7fc087bfcc85c702bac5b86fad34b692bdce4990e0ef444c1e2aea8c034227bd1f0484be02810d5d7e931c55445555646f4 + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 856eeb532b16a7aac071cacde5c5620df800db4c80cee6dbc56380524736205aae21e5ae47739114bf669ab5e8ba0e767a282ad894f3b5e124197cb9224445ee + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: d6a34fbbd24f729e2a10ee915b74e1d77d52214de626b921b2d77288bd8f2386808da2315080f2905761527cceffe7ec34c7647bd21a5ae41a25e8212ff79451 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: f9bf3163d13aaa3b6f5e6fbf37a116e094ea021c0e1f2a7ccd0e12a29e2ce08dafba4e8b36e13f8ed7397e1591610ce880ed1289af4d66cf4ace8a36a9557278 + languageName: node + linkType: hard + "@react-hookz/deep-equal@npm:^1.0.4": version: 1.0.4 resolution: "@react-hookz/deep-equal@npm:1.0.4" @@ -8436,6 +9244,13 @@ __metadata: languageName: node linkType: hard +"@types/cookiejar@npm:^2.1.5": + version: 2.1.5 + resolution: "@types/cookiejar@npm:2.1.5" + checksum: 04d5990e87b6387532d15a87d9ec9b2eb783039291193863751dcfd7fc723a3b3aa30ce4c06b03975cba58632e933772f1ff031af23eaa3ac7f94e71afa6e073 + languageName: node + linkType: hard + "@types/cors@npm:^2.8.6": version: 2.8.17 resolution: "@types/cors@npm:2.8.17" @@ -8445,7 +9260,7 @@ __metadata: languageName: node linkType: hard -"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.7": +"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.12, @types/debug@npm:^4.1.7": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" dependencies: @@ -8705,7 +9520,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 @@ -8737,6 +9552,13 @@ __metadata: languageName: node linkType: hard +"@types/long@npm:^4.0.0": + version: 4.0.2 + resolution: "@types/long@npm:4.0.2" + checksum: d16cde7240d834cf44ba1eaec49e78ae3180e724cd667052b194a372f350d024cba8dd3f37b0864931683dab09ca935d52f0c4c1687178af5ada9fc85b0635f4 + languageName: node + linkType: hard + "@types/lunr@npm:^2.3.3": version: 2.3.7 resolution: "@types/lunr@npm:2.3.7" @@ -8776,6 +9598,13 @@ __metadata: languageName: node linkType: hard +"@types/methods@npm:^1.1.4": + version: 1.1.4 + resolution: "@types/methods@npm:1.1.4" + checksum: ad2a7178486f2fd167750f3eb920ab032a947ff2e26f55c86670a6038632d790b46f52e5b6ead5823f1e53fc68028f1e9ddd15cfead7903e04517c88debd72b1 + languageName: node + linkType: hard + "@types/mime@npm:^1": version: 1.3.5 resolution: "@types/mime@npm:1.3.5" @@ -8790,6 +9619,15 @@ __metadata: languageName: node linkType: hard +"@types/multer@npm:^1.4.12": + version: 1.4.12 + resolution: "@types/multer@npm:1.4.12" + dependencies: + "@types/express": "*" + checksum: 719cacf88ec83ed77e250e45bee830fd7a505323825efa2a2c1144f5f3d7d36e67408ec988e571bcbaa571e0c214b5ede42d57ebb0f9b453a5eb8faba8ff12d0 + languageName: node + linkType: hard + "@types/node-forge@npm:^1.3.0": version: 1.3.11 resolution: "@types/node-forge@npm:1.3.11" @@ -8799,7 +9637,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": +"@types/node@npm:*, @types/node@npm:>=13.7.0": version: 22.10.2 resolution: "@types/node@npm:22.10.2" dependencies: @@ -8833,6 +9671,15 @@ __metadata: languageName: node linkType: hard +"@types/oauth@npm:*": + version: 0.9.6 + resolution: "@types/oauth@npm:0.9.6" + dependencies: + "@types/node": "*" + checksum: a35f3ce103a60b7f24d1233411f8b5e2db4c55476527c04da532989870ffd3af81247b3187741a87c2ee8da6dd2bea3438190bf3611be30d4557e323529abe63 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -8840,7 +9687,28 @@ __metadata: languageName: node linkType: hard -"@types/passport@npm:^1.0.3": +"@types/passport-oauth2@npm:^1.4.11": + version: 1.4.17 + resolution: "@types/passport-oauth2@npm:1.4.17" + dependencies: + "@types/express": "*" + "@types/oauth": "*" + "@types/passport": "*" + checksum: 4c5d2d6f717bb0b3d049669e47ca27cb166cbbef2073dccd302b10e62936c9e392074acabe6cb593f7eeb37a6a3cf81b9d3a4f35a46018a6645ac37d0f1706cb + languageName: node + linkType: hard + +"@types/passport-strategy@npm:^0.2.38": + version: 0.2.38 + resolution: "@types/passport-strategy@npm:0.2.38" + dependencies: + "@types/express": "*" + "@types/passport": "*" + checksum: b580e165182b137a6e57b6b7511904e6c875a5e372f08679ec54f456dc5c2a72d86f23d9373a52d8286b207fe8240946686f9e3d50b0bc1b4f7316f336a06fa2 + languageName: node + linkType: hard + +"@types/passport@npm:*, @types/passport@npm:^1.0.16, @types/passport@npm:^1.0.3": version: 1.0.17 resolution: "@types/passport@npm:1.0.17" dependencies: @@ -8863,7 +9731,7 @@ __metadata: languageName: node linkType: hard -"@types/qs@npm:*, @types/qs@npm:^6.9.6": +"@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: fc3beda0be70e820ddabaa361e8dfec5e09b482b8f6cf1515615479a027dd06cd5ba0ffbd612b654c2605523f45f484c8905a475623d6cd0c4cadcf5d0c517f5 @@ -9058,6 +9926,27 @@ __metadata: languageName: node linkType: hard +"@types/superagent@npm:*": + version: 8.1.9 + resolution: "@types/superagent@npm:8.1.9" + dependencies: + "@types/cookiejar": ^2.1.5 + "@types/methods": ^1.1.4 + "@types/node": "*" + form-data: ^4.0.0 + checksum: 530d8c2e87706315c82c8c9696500c40621de3353bc54ea9b104947f3530243abf54d0a49a6ae219d4947606a102ceb94bedfc43b9cc49f74069a18cbb3be8e2 + languageName: node + linkType: hard + +"@types/supertest@npm:^2.0.15": + version: 2.0.16 + resolution: "@types/supertest@npm:2.0.16" + dependencies: + "@types/superagent": "*" + checksum: 2fc998ea698e0467cdbe3bea0ebce2027ea3a45a13e51a6cecb0435f44b486faecf99c34d8702d2d7fe033e6e09fdd2b374af52ecc8d0c69a1deec66b8c0dd52 + languageName: node + linkType: hard + "@types/tough-cookie@npm:*": version: 4.0.5 resolution: "@types/tough-cookie@npm:4.0.5" @@ -9093,6 +9982,13 @@ __metadata: languageName: node linkType: hard +"@types/uuid@npm:^8.3.4": + version: 8.3.4 + resolution: "@types/uuid@npm:8.3.4" + checksum: 6f11f3ff70f30210edaa8071422d405e9c1d4e53abbe50fdce365150d3c698fe7bbff65c1e71ae080cbfb8fded860dbb5e174da96fdbbdfcaa3fb3daa474d20f + languageName: node + linkType: hard + "@types/uuid@npm:^9.0.1": version: 9.0.8 resolution: "@types/uuid@npm:9.0.8" @@ -9107,7 +10003,7 @@ __metadata: languageName: node linkType: hard -"@types/ws@npm:^8.5.10, @types/ws@npm:^8.5.3": +"@types/ws@npm:*, @types/ws@npm:^8.5.10, @types/ws@npm:^8.5.3": version: 8.5.13 resolution: "@types/ws@npm:8.5.13" dependencies: @@ -9116,6 +10012,24 @@ __metadata: languageName: node linkType: hard +"@types/xml-encryption@npm:^1.2.4": + version: 1.2.4 + resolution: "@types/xml-encryption@npm:1.2.4" + dependencies: + "@types/node": "*" + checksum: 1ef957dfb47cf55b12e114755e271a2343f73eb4c59ab6c68b0b7d1b8111d7e1bd8d2bfe0601d2aea09be83c66355bc77fc59f9b71aeff9bb9e15371bcfef5d3 + languageName: node + linkType: hard + +"@types/xml2js@npm:^0.4.14": + version: 0.4.14 + resolution: "@types/xml2js@npm:0.4.14" + dependencies: + "@types/node": "*" + checksum: df9f106b9953dcdec7ba3304ebc56d6c2f61d49bf556d600bed439f94a1733f73ca0bf2d0f64330b402191622862d9d6058bab9d7e3dcb5b0fe51ebdc4372aac + languageName: node + linkType: hard + "@types/yargs-parser@npm:*": version: 21.0.3 resolution: "@types/yargs-parser@npm:21.0.3" @@ -9554,7 +10468,14 @@ __metadata: languageName: node linkType: hard -"@xmldom/xmldom@npm:^0.8.3": +"@xmldom/is-dom-node@npm:^1.0.1": + version: 1.0.1 + resolution: "@xmldom/is-dom-node@npm:1.0.1" + checksum: 24a412fbd996b4de757c3905f4b4aad28578aaf6687fd4fc986f339d476dcf5153c50a4f408099c2a894961a1517c927163ec37a1ade9f73b5c0ad478b34190e + languageName: node + linkType: hard + +"@xmldom/xmldom@npm:^0.8.10, @xmldom/xmldom@npm:^0.8.3, @xmldom/xmldom@npm:^0.8.5": version: 0.8.10 resolution: "@xmldom/xmldom@npm:0.8.10" checksum: 4c136aec31fb3b49aaa53b6fcbfe524d02a1dc0d8e17ee35bd3bf35e9ce1344560481cd1efd086ad1a4821541482528672306d5e37cdbd187f33d7fadd3e2cf0 @@ -9820,7 +10741,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.17.1, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.9.0": +"ajv@npm:^8.0.0, ajv@npm:^8.10.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: @@ -9960,6 +10881,13 @@ __metadata: languageName: node linkType: hard +"append-field@npm:^1.0.0": + version: 1.0.0 + resolution: "append-field@npm:1.0.0" + checksum: 482ba08acc0ecef00fe7da6bf2f8e48359a9905ee1af525f3120c9260c02e91eedf0579b59d898e8d8455b6c199e340bc0a2fd4b9e02adaa29a8a86c722b37f9 + languageName: node + linkType: hard + "aproba@npm:^1.0.3 || ^2.0.0": version: 2.0.0 resolution: "aproba@npm:2.0.0" @@ -10171,6 +11099,13 @@ __metadata: languageName: node linkType: hard +"asap@npm:^2.0.0": + version: 2.0.6 + resolution: "asap@npm:2.0.6" + checksum: b296c92c4b969e973260e47523207cd5769abd27c245a68c26dc7a0fe8053c55bb04360237cb51cab1df52be939da77150ace99ad331fb7fb13b3423ed73ff3d + languageName: node + linkType: hard + "asn1.js@npm:^4.10.1": version: 4.10.1 resolution: "asn1.js@npm:4.10.1" @@ -10240,6 +11175,15 @@ __metadata: languageName: node linkType: hard +"async-mutex@npm:^0.5.0": + version: 0.5.0 + resolution: "async-mutex@npm:0.5.0" + dependencies: + tslib: ^2.4.0 + checksum: be1587f4875f3bb15e34e9fcce82eac2966daef4432c8d0046e61947fb9a1b95405284601bc7ce4869319249bc07c75100880191db6af11d1498931ac2a2f9ea + languageName: node + linkType: hard + "async-retry@npm:^1.3.3": version: 1.3.3 resolution: "async-retry@npm:1.3.3" @@ -10279,6 +11223,16 @@ __metadata: languageName: node linkType: hard +"atlassian-openapi@npm:^1.0.8": + version: 1.0.20 + resolution: "atlassian-openapi@npm:1.0.20" + dependencies: + jsonpointer: ^5.0.0 + urijs: ^1.19.10 + checksum: 9d154fb3de6256f30ce677266995a983852c05e58fb820110dbb05f785bae19ab4c1d539e2bced6c29db29255c8933cb4bc6345a3b3d6b9ad47794ff058d8de0 + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -10327,7 +11281,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.7.4": +"axios@npm:^1.6.0, axios@npm:^1.7.4": version: 1.7.9 resolution: "axios@npm:1.7.9" dependencies: @@ -10478,6 +11432,13 @@ __metadata: languageName: node linkType: hard +"backo2@npm:^1.0.2": + version: 1.0.2 + resolution: "backo2@npm:1.0.2" + checksum: fda8d0a0f4810068d23715f2f45153146d6ee8f62dd827ce1e0b6cc3c8328e84ad61e11399a83931705cef702fe7cbb457856bf99b9bd10c4ed57b0786252385 + languageName: node + linkType: hard + "bail@npm:^2.0.0": version: 2.0.2 resolution: "bail@npm:2.0.2" @@ -10535,6 +11496,13 @@ __metadata: languageName: node linkType: hard +"base64-arraybuffer@npm:^0.1.5": + version: 0.1.5 + resolution: "base64-arraybuffer@npm:0.1.5" + checksum: 44588c1b4460faf59643cf3bcf346a7ede9df70d97aec6dbee4fbae15f6b6220d679b8db076771ea4ef5713dd710e7db7a4a3f81bbb04c71fb06764697d9a021 + languageName: node + linkType: hard + "base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -10549,6 +11517,13 @@ __metadata: languageName: node linkType: hard +"base64url@npm:3.x.x": + version: 3.0.1 + resolution: "base64url@npm:3.0.1" + checksum: a77b2a3a526b3343e25be424de3ae0aa937d78f6af7c813ef9020ef98001c0f4e2323afcd7d8b2d2978996bf8c42445c3e9f60c218c622593e5fdfd54a3d6e18 + languageName: node + linkType: hard + "basic-auth@npm:~2.0.1": version: 2.0.1 resolution: "basic-auth@npm:2.0.1" @@ -10604,7 +11579,7 @@ __metadata: languageName: node linkType: hard -"better-sqlite3@npm:^11.0.0": +"better-sqlite3@npm:^11.0.0, better-sqlite3@npm:^11.3.0": version: 11.7.0 resolution: "better-sqlite3@npm:11.7.0" dependencies: @@ -10690,7 +11665,7 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.3": +"body-parser@npm:1.20.3, body-parser@npm:^1.15.2": version: 1.20.3 resolution: "body-parser@npm:1.20.3" dependencies: @@ -10776,6 +11751,13 @@ __metadata: languageName: node linkType: hard +"brotli-wasm@npm:^3.0.0": + version: 3.0.1 + resolution: "brotli-wasm@npm:3.0.1" + checksum: 48191b27265de8ffc59c940f9efef3a931448b6a15c26a4e360192fc3f0968e073c11fe0926510d019c305cc1d9c6d65df4d3e5752648a91cb0bbcccff7a8460 + languageName: node + linkType: hard + "browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": version: 1.2.0 resolution: "browserify-aes@npm:1.2.0" @@ -10979,6 +11961,15 @@ __metadata: languageName: node linkType: hard +"busboy@npm:^1.0.0": + version: 1.6.0 + resolution: "busboy@npm:1.6.0" + dependencies: + streamsearch: ^1.1.0 + checksum: 32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e + languageName: node + linkType: hard + "byline@npm:^5.0.0": version: 5.0.0 resolution: "byline@npm:5.0.0" @@ -11049,6 +12040,13 @@ __metadata: languageName: node linkType: hard +"cacheable-lookup@npm:^6.0.0": + version: 6.1.0 + resolution: "cacheable-lookup@npm:6.1.0" + checksum: 4e37afe897219b1035335b0765106a2c970ffa930497b43cac5000b860f3b17f48d004187279fae97e2e4cbf6a3693709b6d64af65279c7d6c8453321d36d118 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1": version: 1.0.1 resolution: "call-bind-apply-helpers@npm:1.0.1" @@ -11399,6 +12397,13 @@ __metadata: languageName: node linkType: hard +"clone@npm:2.x": + version: 2.1.2 + resolution: "clone@npm:2.1.2" + checksum: aaf106e9bc025b21333e2f4c12da539b568db4925c0501a1bf4070836c9e848c892fa22c35548ce0d1132b08bbbfa17a00144fe58fccdab6fa900fec4250f67d + languageName: node + linkType: hard + "clone@npm:^1.0.2": version: 1.0.4 resolution: "clone@npm:1.0.4" @@ -11624,6 +12629,13 @@ __metadata: languageName: node linkType: hard +"common-tags@npm:^1.8.0": + version: 1.8.2 + resolution: "common-tags@npm:1.8.2" + checksum: 767a6255a84bbc47df49a60ab583053bb29a7d9687066a18500a516188a062c4e4cd52de341f22de0b07062e699b1b8fe3cfa1cb55b241cb9301aeb4f45b4dff + languageName: node + linkType: hard + "commondir@npm:^1.0.1": version: 1.0.1 resolution: "commondir@npm:1.0.1" @@ -11638,6 +12650,13 @@ __metadata: languageName: node linkType: hard +"component-emitter@npm:^1.3.0": + version: 1.3.1 + resolution: "component-emitter@npm:1.3.1" + checksum: 94550aa462c7bd5a61c1bc480e28554aa306066930152d1b1844a0dd3845d4e5db7e261ddec62ae184913b3e59b55a2ad84093b9d3596a8f17c341514d6c483d + languageName: node + linkType: hard + "compress-commons@npm:^6.0.2": version: 6.0.2 resolution: "compress-commons@npm:6.0.2" @@ -11705,6 +12724,18 @@ __metadata: languageName: node linkType: hard +"concat-stream@npm:^1.5.2": + version: 1.6.2 + resolution: "concat-stream@npm:1.6.2" + dependencies: + buffer-from: ^1.0.0 + inherits: ^2.0.3 + readable-stream: ^2.2.2 + typedarray: ^0.0.6 + checksum: 1ef77032cb4459dcd5187bd710d6fc962b067b64ec6a505810de3d2b8cc0605638551b42f8ec91edf6fcd26141b32ef19ad749239b58fae3aba99187adc32285 + languageName: node + linkType: hard + "concat-stream@npm:^2.0.0": version: 2.0.0 resolution: "concat-stream@npm:2.0.0" @@ -11751,6 +12782,28 @@ __metadata: languageName: node linkType: hard +"connect-session-knex@npm:^4.0.0": + version: 4.0.2 + resolution: "connect-session-knex@npm:4.0.2" + dependencies: + bluebird: ^3.7.2 + knex: 3 + checksum: da4e097aee7737a2c087ec8f8a5e43962132d7968b009fbf2e65bf10a4aa07efa1305f6e5e2025256d5b872d7118b7d53e970beec07f4901e6216942132062f8 + languageName: node + linkType: hard + +"connect@npm:^3.7.0": + version: 3.7.0 + resolution: "connect@npm:3.7.0" + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: ~1.3.3 + utils-merge: 1.0.1 + checksum: 96e1c4effcf219b065c7823e57351c94366d2e2a6952fa95e8212bffb35c86f1d5a3f9f6c5796d4cd3a5fdda628368b1c3cc44bf19c66cfd68fe9f9cab9177e2 + languageName: node + linkType: hard + "consola@npm:^2.15.0": version: 2.15.3 resolution: "consola@npm:2.15.3" @@ -11797,7 +12850,7 @@ __metadata: languageName: node linkType: hard -"content-type@npm:^1.0.4, content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:^1.0.4, content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 @@ -11818,6 +12871,16 @@ __metadata: languageName: node linkType: hard +"cookie-parser@npm:^1.4.5": + version: 1.4.7 + resolution: "cookie-parser@npm:1.4.7" + dependencies: + cookie: 0.7.2 + cookie-signature: 1.0.6 + checksum: 243fa13f217e793d20a57675e6552beea08c5989fcc68495d543997a31646875335e0e82d687b42dcfd466df57891d22bae7f5ba6ab33b7705ed2dd6eb989105 + languageName: node + linkType: hard + "cookie-signature@npm:1.0.6": version: 1.0.6 resolution: "cookie-signature@npm:1.0.6" @@ -11825,6 +12888,13 @@ __metadata: languageName: node linkType: hard +"cookie-signature@npm:1.0.7": + version: 1.0.7 + resolution: "cookie-signature@npm:1.0.7" + checksum: 1a62808cd30d15fb43b70e19829b64d04b0802d8ef00275b57d152de4ae6a3208ca05c197b6668d104c4d9de389e53ccc2d3bc6bcaaffd9602461417d8c40710 + languageName: node + linkType: hard + "cookie@npm:0.7.1": version: 0.7.1 resolution: "cookie@npm:0.7.1" @@ -11832,6 +12902,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:0.7.2, cookie@npm:^0.7.0": + version: 0.7.2 + resolution: "cookie@npm:0.7.2" + checksum: 9bf8555e33530affd571ea37b615ccad9b9a34febbf2c950c86787088eb00a8973690833b0f8ebd6b69b753c62669ea60cec89178c1fb007bf0749abed74f93e + languageName: node + linkType: hard + "cookie@npm:^0.4.2": version: 0.4.2 resolution: "cookie@npm:0.4.2" @@ -11839,10 +12916,10 @@ __metadata: languageName: node linkType: hard -"cookie@npm:^0.7.0": - version: 0.7.2 - resolution: "cookie@npm:0.7.2" - checksum: 9bf8555e33530affd571ea37b615ccad9b9a34febbf2c950c86787088eb00a8973690833b0f8ebd6b69b753c62669ea60cec89178c1fb007bf0749abed74f93e +"cookiejar@npm:^2.1.4": + version: 2.1.4 + resolution: "cookiejar@npm:2.1.4" + checksum: c4442111963077dc0e5672359956d6556a195d31cbb35b528356ce5f184922b99ac48245ac05ed86cf993f7df157c56da10ab3efdadfed79778a0d9b1b092d5b languageName: node linkType: hard @@ -11895,7 +12972,14 @@ __metadata: languageName: node linkType: hard -"cors@npm:^2.8.5": +"cors-gate@npm:^1.1.3": + version: 1.1.3 + resolution: "cors-gate@npm:1.1.3" + checksum: 8480e24ccc77a0a150c3cb555ae07fc4e2fa0034a2585c0c91efa3c44b91936d31abf1c5a87b09726253b491e0b66ed491face942502bbc38f87bb309f931fc6 + languageName: node + linkType: hard + +"cors@npm:^2.8.4, cors@npm:^2.8.5": version: 2.8.5 resolution: "cors@npm:2.8.5" dependencies: @@ -12058,7 +13142,7 @@ __metadata: languageName: node linkType: hard -"cross-fetch@npm:^3.1.8": +"cross-fetch@npm:^3.1.5, cross-fetch@npm:^3.1.8": version: 3.2.0 resolution: "cross-fetch@npm:3.2.0" dependencies: @@ -12329,9 +13413,9 @@ __metadata: linkType: hard "ctrlc-windows@npm:^2.1.0": - version: 2.1.0 - resolution: "ctrlc-windows@npm:2.1.0" - checksum: 0f0582ba9516290d3e90ea7b91710f8b9b110e1ed29b7c84ebd44c16368b2553722b86a17226120ca3ea0ef679ac3596f48104cc113cfb7c3d07260f6c92e38b + version: 2.2.0 + resolution: "ctrlc-windows@npm:2.2.0" + checksum: 4f69ce1b19c6533396c1ac05669f1e7fa96f676a6dd0c70320281974630b50716b454f8cee51f3207719498cf9029b052f21a38fda01ad402ad87ac4b76a829f languageName: node linkType: hard @@ -12510,6 +13594,13 @@ __metadata: languageName: node linkType: hard +"dataloader@npm:^2.0.0": + version: 2.2.3 + resolution: "dataloader@npm:2.2.3" + checksum: cc272181f6cad0ea20511c0a0d270cbc1df960a3526ab24941bbeb2cb7120499a598fe2cd41b4818527367acf7bc1be0723b6e5034637db4759a396c904b78a6 + languageName: node + linkType: hard + "date-fns@npm:^2.16.1": version: 2.30.0 resolution: "date-fns@npm:2.30.0" @@ -12812,6 +13903,15 @@ __metadata: languageName: node linkType: hard +"destroyable-server@npm:^1.0.2": + version: 1.0.2 + resolution: "destroyable-server@npm:1.0.2" + dependencies: + "@types/node": "*" + checksum: 81fd70b9132d43c3633a7a819adfe1fc68b52a55154ff8a36f42f4655e7b71b8468559888caadfd324c1aa824f0d236796a8f356e8a00e7438649e647ea654b2 + languageName: node + linkType: hard + "detect-indent@npm:^6.0.0": version: 6.1.0 resolution: "detect-indent@npm:6.1.0" @@ -12862,6 +13962,16 @@ __metadata: languageName: node linkType: hard +"dezalgo@npm:^1.0.4": + version: 1.0.4 + resolution: "dezalgo@npm:1.0.4" + dependencies: + asap: ^2.0.0 + wrappy: 1 + checksum: 895389c6aead740d2ab5da4d3466d20fa30f738010a4d3f4dcccc9fc645ca31c9d10b7e1804ae489b1eb02c7986f9f1f34ba132d409b043082a86d9a4e745624 + languageName: node + linkType: hard + "diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -13116,7 +14226,19 @@ __metadata: languageName: node linkType: hard -"duplexify@npm:^4.1.3": +"duplexify@npm:^3.5.1": + version: 3.7.1 + resolution: "duplexify@npm:3.7.1" + dependencies: + end-of-stream: ^1.0.0 + inherits: ^2.0.1 + readable-stream: ^2.0.0 + stream-shift: ^1.0.0 + checksum: 3c2ed2223d956a5da713dae12ba8295acb61d9acd966ccbba938090d04f4574ca4dca75cca089b5077c2d7e66101f32e6ea9b36a78ca213eff574e7a8b8accf2 + languageName: node + linkType: hard + +"duplexify@npm:^4.0.0, duplexify@npm:^4.1.3": version: 4.1.3 resolution: "duplexify@npm:4.1.3" dependencies: @@ -13266,7 +14388,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": +"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.4 resolution: "end-of-stream@npm:1.4.4" dependencies: @@ -14182,6 +15304,13 @@ __metadata: languageName: node linkType: hard +"eventemitter3@npm:^3.1.0": + version: 3.1.2 + resolution: "eventemitter3@npm:3.1.2" + checksum: 81e4e82b8418f5cfd986d2b4a2fa5397ac4eb8134e09bcb47005545e22fdf8e9e61d5c053d34651112245aae411bdfe6d0ad5511da0400743fef5fc38bfcfbe3 + languageName: node + linkType: hard + "eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.4": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" @@ -14267,6 +15396,29 @@ __metadata: languageName: node linkType: hard +"express-openapi-validator@npm:^5.0.4": + version: 5.3.9 + resolution: "express-openapi-validator@npm:5.3.9" + dependencies: + "@apidevtools/json-schema-ref-parser": ^11.7.0 + "@types/multer": ^1.4.12 + ajv: ^8.17.1 + ajv-draft-04: ^1.0.0 + ajv-formats: ^2.1.1 + content-type: ^1.0.5 + json-schema-traverse: ^1.0.0 + lodash.clonedeep: ^4.5.0 + lodash.get: ^4.4.2 + media-typer: ^1.1.0 + multer: ^1.4.5-lts.1 + ono: ^7.1.3 + path-to-regexp: ^8.1.0 + peerDependencies: + express: "*" + checksum: 0469b383b769f070dfad9c9148b18857c5aaa9aa14c596e1ada155dac63e1c355e455d42f3c81af62c4aefd3db4ad8b892d34a432e170e4eb7af73d7dbd2f644 + languageName: node + linkType: hard + "express-promise-router@npm:^4.1.0": version: 4.1.1 resolution: "express-promise-router@npm:4.1.1" @@ -14284,7 +15436,23 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.17.1, express@npm:^4.21.2": +"express-session@npm:^1.17.1": + version: 1.18.1 + resolution: "express-session@npm:1.18.1" + dependencies: + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: ~2.0.0 + on-headers: ~1.0.2 + parseurl: ~1.3.3 + safe-buffer: 5.2.1 + uid-safe: ~2.1.5 + checksum: e712cb3399300d9e300b51769ee3e81da6a4a54acc39137945134bf61a452f27ee9afde337f3c0f300457a88b3a12d0b5c711625684d7c8d998e9d2bd34d9e18 + languageName: node + linkType: hard + +"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.18.2, express@npm:^4.19.2, express@npm:^4.21.2": version: 4.21.2 resolution: "express@npm:4.21.2" dependencies: @@ -14389,7 +15557,7 @@ __metadata: languageName: node linkType: hard -"fast-json-patch@npm:^3.1.0": +"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: c4525b61b2471df60d4b025b4118b036d99778a93431aa44d1084218182841d82ce93056f0f3bbd731a24e6a8e69820128adf1873eb2199a26c62ef58d137833 @@ -14417,7 +15585,7 @@ __metadata: languageName: node linkType: hard -"fast-safe-stringify@npm:2.1.1": +"fast-safe-stringify@npm:2.1.1, fast-safe-stringify@npm:^2.1.1": version: 2.1.1 resolution: "fast-safe-stringify@npm:2.1.1" checksum: a851cbddc451745662f8f00ddb622d6766f9bd97642dabfd9a405fb0d646d69fc0b9a1243cbf67f5f18a39f40f6fa821737651ff1bceeba06c9992ca2dc5bd3d @@ -14563,6 +15731,21 @@ __metadata: languageName: node linkType: hard +"finalhandler@npm:1.1.2": + version: 1.1.2 + resolution: "finalhandler@npm:1.1.2" + dependencies: + debug: 2.6.9 + encodeurl: ~1.0.2 + escape-html: ~1.0.3 + on-finished: ~2.3.0 + parseurl: ~1.3.3 + statuses: ~1.5.0 + unpipe: ~1.0.0 + checksum: 617880460c5138dd7ccfd555cb5dde4d8f170f4b31b8bd51e4b646bb2946c30f7db716428a1f2882d730d2b72afb47d1f67cc487b874cb15426f95753a88965e + languageName: node + linkType: hard + "finalhandler@npm:1.3.1": version: 1.3.1 resolution: "finalhandler@npm:1.3.1" @@ -14788,6 +15971,18 @@ __metadata: languageName: node linkType: hard +"formidable@npm:^2.1.2": + version: 2.1.2 + resolution: "formidable@npm:2.1.2" + dependencies: + dezalgo: ^1.0.4 + hexoid: ^1.0.0 + once: ^1.4.0 + qs: ^6.11.0 + checksum: 81c8e5d89f5eb873e992893468f0de22c01678ca3d315db62be0560f9de1c77d4faefc9b1f4575098eb2263b3c81ba1024833a9fc3206297ddbac88a4f69b7a8 + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -14944,6 +16139,13 @@ __metadata: languageName: node linkType: hard +"functional-red-black-tree@npm:^1.0.1": + version: 1.0.1 + resolution: "functional-red-black-tree@npm:1.0.1" + checksum: ca6c170f37640e2d94297da8bb4bf27a1d12bea3e00e6a3e007fd7aa32e37e000f5772acf941b4e4f3cf1c95c3752033d0c509af157ad8f526e7f00723b9eb9f + languageName: node + linkType: hard + "functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" @@ -15335,7 +16537,7 @@ __metadata: languageName: node linkType: hard -"google-auth-library@npm:^9.6.3": +"google-auth-library@npm:^9.0.0, google-auth-library@npm:^9.3.0, google-auth-library@npm:^9.6.3": version: 9.15.0 resolution: "google-auth-library@npm:9.15.0" dependencies: @@ -15349,6 +16551,26 @@ __metadata: languageName: node linkType: hard +"google-gax@npm:^4.3.3": + version: 4.4.1 + resolution: "google-gax@npm:4.4.1" + dependencies: + "@grpc/grpc-js": ^1.10.9 + "@grpc/proto-loader": ^0.7.13 + "@types/long": ^4.0.0 + abort-controller: ^3.0.0 + duplexify: ^4.0.0 + google-auth-library: ^9.3.0 + node-fetch: ^2.7.0 + object-hash: ^3.0.0 + proto3-json-serializer: ^2.0.2 + protobufjs: ^7.3.2 + retry-request: ^7.0.0 + uuid: ^9.0.1 + checksum: 945dc57fa80a9e95621460585f99319ef123c3eb904f0c5f4d10197bfa7981294d7f600c77e481a0cb071f8c08d692d394d81cd06f7f3dd3c34c581c65100f6a + languageName: node + linkType: hard + "gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" @@ -15379,7 +16601,27 @@ __metadata: languageName: node linkType: hard -"graphql-tag@npm:^2.10.3": +"graphql-http@npm:^1.22.0": + version: 1.22.3 + resolution: "graphql-http@npm:1.22.3" + peerDependencies: + graphql: ">=0.11 <=16" + checksum: c523bb6fadb6caa99777f48d9fd3a598d4415cd7b12855fe0af05439849d636642c3ced5867e888606089d5ad2145192f6b6d9dd634d60e6f870d8fdc5c11fd7 + languageName: node + linkType: hard + +"graphql-subscriptions@npm:^1.1.0": + version: 1.2.1 + resolution: "graphql-subscriptions@npm:1.2.1" + dependencies: + iterall: ^1.3.0 + peerDependencies: + graphql: ^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + checksum: 2b9533c6774e7be46acd6fbee528aab06429f15dc222eabd991e82c02bf74e390b638dffa1a3fd86c1e26212c40a42a0418d7f4a7c3a1edf0534978ef128e528 + languageName: node + linkType: hard + +"graphql-tag@npm:^2.10.3, graphql-tag@npm:^2.12.6": version: 2.12.6 resolution: "graphql-tag@npm:2.12.6" dependencies: @@ -15390,6 +16632,13 @@ __metadata: languageName: node linkType: hard +"graphql@npm:^14.0.2 || ^15.5": + version: 15.9.0 + resolution: "graphql@npm:15.9.0" + checksum: fecf48b878baf8bd1d943b79860554f9e0bdf8d23a8f014356209fedcc1f1353729388538842d8a4a79078ea75b3f24d504d074223c815acf9b6059837c5c934 + languageName: node + linkType: hard + "graphql@npm:^16.0.0, graphql@npm:^16.8.1": version: 16.10.0 resolution: "graphql@npm:16.10.0" @@ -15837,6 +17086,13 @@ __metadata: languageName: node linkType: hard +"hexoid@npm:^1.0.0": + version: 1.0.0 + resolution: "hexoid@npm:1.0.0" + checksum: 27a148ca76a2358287f40445870116baaff4a0ed0acc99900bf167f0f708ffd82e044ff55e9949c71963852b580fc024146d3ac6d5d76b508b78d927fa48ae2d + languageName: node + linkType: hard + "highlight.js@npm:^10.4.1, highlight.js@npm:~10.7.0": version: 10.7.3 resolution: "highlight.js@npm:10.7.3" @@ -16019,6 +17275,17 @@ __metadata: languageName: node linkType: hard +"http-encoding@npm:^2.0.1": + version: 2.0.1 + resolution: "http-encoding@npm:2.0.1" + dependencies: + brotli-wasm: ^3.0.0 + pify: ^5.0.0 + zstd-codec: ^0.1.5 + checksum: c34a1cd81ad1c08e6c6aba5aef3f4d4bc4a6c84f8b3511776eb62006beeee48a104ce1630e3c8497f66d5c0913195dea596e776336dd5a598bd7fe06d27e1395 + languageName: node + linkType: hard + "http-errors@npm:2.0.0": version: 2.0.0 resolution: "http-errors@npm:2.0.0" @@ -16085,7 +17352,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-middleware@npm:^2.0.7": +"http-proxy-middleware@npm:^2.0.0, http-proxy-middleware@npm:^2.0.7": version: 2.0.7 resolution: "http-proxy-middleware@npm:2.0.7" dependencies: @@ -16125,6 +17392,16 @@ __metadata: languageName: node linkType: hard +"http2-wrapper@npm:^2.2.1": + version: 2.2.1 + resolution: "http2-wrapper@npm:2.2.1" + dependencies: + quick-lru: ^5.1.1 + resolve-alpn: ^1.2.0 + checksum: e95e55e22c6fd61182ce81fecb9b7da3af680d479febe8ad870d05f7ebbc9f076e455193766f4e7934e50913bf1d8da3ba121fb5cd2928892390b58cf9d5c509 + languageName: node + linkType: hard + "https-browserify@npm:^1.0.0": version: 1.0.0 resolution: "https-browserify@npm:1.0.0" @@ -17082,6 +18359,15 @@ __metadata: languageName: node linkType: hard +"isomorphic-ws@npm:^4.0.1": + version: 4.0.1 + resolution: "isomorphic-ws@npm:4.0.1" + peerDependencies: + ws: "*" + checksum: d7190eadefdc28bdb93d67b5f0c603385aaf87724fa2974abb382ac1ec9756ed2cfb27065cbe76122879c2d452e2982bc4314317f3d6c737ddda6c047328771a + languageName: node + linkType: hard + "isstream@npm:~0.1.2": version: 0.1.2 resolution: "isstream@npm:0.1.2" @@ -17154,6 +18440,13 @@ __metadata: languageName: node linkType: hard +"iterall@npm:^1.2.1, iterall@npm:^1.3.0": + version: 1.3.0 + resolution: "iterall@npm:1.3.0" + checksum: c78b99678f8c99be488cca7f33e4acca9b72c1326e050afbaf023f086e55619ee466af0464af94a0cb3f292e60cb5bac53a8fd86bd4249ecad26e09f17bb158b + languageName: node + linkType: hard + "iterare@npm:1.2.1": version: 1.2.1 resolution: "iterare@npm:1.2.1" @@ -17875,6 +19168,16 @@ __metadata: languageName: node linkType: hard +"json-schema-to-ts@npm:^3.0.0": + version: 3.1.1 + resolution: "json-schema-to-ts@npm:3.1.1" + dependencies: + "@babel/runtime": ^7.18.3 + ts-algebra: ^2.0.0 + checksum: b616f1c2d7492502e11eec4f8e4539ee1e897543a679d929494afdc164d9557275cead8372747b73f239b1e68056ffbf551b03ae82d0047bba0dfe2bbd6b64f4 + languageName: node + linkType: hard + "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -18246,7 +19549,7 @@ __metadata: languageName: node linkType: hard -"knex@npm:^3.0.0": +"knex@npm:3, knex@npm:^3.0.0, knex@npm:^3.0.1": version: 3.1.0 resolution: "knex@npm:3.1.0" dependencies: @@ -18534,6 +19837,13 @@ __metadata: languageName: node linkType: hard +"lodash.clonedeep@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.clonedeep@npm:4.5.0" + checksum: 92c46f094b064e876a23c97f57f81fbffd5d760bf2d8a1c61d85db6d1e488c66b0384c943abee4f6af7debf5ad4e4282e74ff83177c9e63d8ff081a4837c3489 + languageName: node + linkType: hard + "lodash.clonedeepwith@npm:4.5.0": version: 4.5.0 resolution: "lodash.clonedeepwith@npm:4.5.0" @@ -18562,6 +19872,13 @@ __metadata: languageName: node linkType: hard +"lodash.get@npm:^4.4.2": + version: 4.4.2 + resolution: "lodash.get@npm:4.4.2" + checksum: e403047ddb03181c9d0e92df9556570e2b67e0f0a930fcbbbd779370972368f5568e914f913e93f3b08f6d492abc71e14d4e9b7a18916c31fa04bd2306efe545 + languageName: node + linkType: hard + "lodash.groupby@npm:^4.6.0": version: 4.6.0 resolution: "lodash.groupby@npm:4.6.0" @@ -18674,7 +19991,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, 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": +"lodash@npm:4.17.21, 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: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -18725,7 +20042,7 @@ __metadata: languageName: node linkType: hard -"long@npm:^5.2.1": +"long@npm:^5.0.0, long@npm:^5.2.1": version: 5.2.3 resolution: "long@npm:5.2.3" checksum: 885ede7c3de4facccbd2cacc6168bae3a02c3e836159ea4252c87b6e34d40af819824b2d4edce330bfb5c4d6e8ce3ec5864bdcf9473fa1f53a4f8225860e5897 @@ -18794,7 +20111,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^7.14.1, lru-cache@npm:^7.7.1": +"lru-cache@npm:^7.14.0, lru-cache@npm:^7.14.1, lru-cache@npm:^7.7.1": version: 7.18.3 resolution: "lru-cache@npm:7.18.3" checksum: e550d772384709deea3f141af34b6d4fa392e2e418c1498c078de0ee63670f1f46f5eee746e8ef7e69e1c895af0d4224e62ee33e66a543a14763b0f2e74c1356 @@ -19359,6 +20676,13 @@ __metadata: languageName: node linkType: hard +"media-typer@npm:^1.1.0": + version: 1.1.0 + resolution: "media-typer@npm:1.1.0" + checksum: a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd + languageName: node + linkType: hard + "memfs@npm:^3.1.2, memfs@npm:^3.4.1": version: 3.5.3 resolution: "memfs@npm:3.5.3" @@ -19415,7 +20739,7 @@ __metadata: languageName: node linkType: hard -"methods@npm:^1.0.0, methods@npm:~1.1.2": +"methods@npm:^1.0.0, methods@npm:^1.1.2, methods@npm:~1.1.2": version: 1.1.2 resolution: "methods@npm:1.1.2" checksum: 0917ff4041fa8e2f2fda5425a955fe16ca411591fbd123c0d722fcf02b73971ed6f764d85f0a6f547ce49ee0221ce2c19a5fa692157931cecb422984f1dcd13a @@ -20134,6 +21458,15 @@ __metadata: languageName: node linkType: hard +"mime@npm:2.6.0": + version: 2.6.0 + resolution: "mime@npm:2.6.0" + bin: + mime: cli.js + checksum: 1497ba7b9f6960694268a557eae24b743fd2923da46ec392b042469f4b901721ba0adcf8b0d3c2677839d0e243b209d76e5edcbd09cfdeffa2dfb6bb4df4b862 + languageName: node + linkType: hard + "mime@npm:^3.0.0": version: 3.0.0 resolution: "mime@npm:3.0.0" @@ -20392,7 +21725,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^0.5.6": +"mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.6": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -20421,6 +21754,58 @@ __metadata: languageName: node linkType: hard +"mockttp@npm:^3.13.0": + version: 3.15.5 + resolution: "mockttp@npm:3.15.5" + dependencies: + "@graphql-tools/schema": ^8.5.0 + "@graphql-tools/utils": ^8.8.0 + "@httptoolkit/httpolyglot": ^2.2.1 + "@httptoolkit/subscriptions-transport-ws": ^0.11.2 + "@httptoolkit/websocket-stream": ^6.0.1 + "@types/cors": ^2.8.6 + "@types/node": "*" + async-mutex: ^0.5.0 + base64-arraybuffer: ^0.1.5 + body-parser: ^1.15.2 + cacheable-lookup: ^6.0.0 + common-tags: ^1.8.0 + connect: ^3.7.0 + cors: ^2.8.4 + cors-gate: ^1.1.3 + cross-fetch: ^3.1.5 + destroyable-server: ^1.0.2 + express: ^4.14.0 + fast-json-patch: ^3.1.1 + graphql: ^14.0.2 || ^15.5 + graphql-http: ^1.22.0 + graphql-subscriptions: ^1.1.0 + graphql-tag: ^2.12.6 + http-encoding: ^2.0.1 + http2-wrapper: ^2.2.1 + https-proxy-agent: ^5.0.1 + isomorphic-ws: ^4.0.1 + lodash: ^4.16.4 + lru-cache: ^7.14.0 + native-duplexpair: ^1.0.0 + node-forge: ^1.2.1 + pac-proxy-agent: ^7.0.0 + parse-multipart-data: ^1.4.0 + performance-now: ^2.1.0 + portfinder: ^1.0.32 + read-tls-client-hello: ^1.0.0 + semver: ^7.5.3 + socks-proxy-agent: ^7.0.0 + typed-error: ^3.0.2 + urlpattern-polyfill: ^8.0.0 + uuid: ^8.3.2 + ws: ^8.8.0 + bin: + mockttp: dist/admin/admin-bin.js + checksum: 410d8b39cddb7975aeb2289a1735d8d65b28bf032e8b0e8990ce78ddbaa4c7c96108c54714a36a745b4784cf2bf129ddafa93a5458deacce2ca56a4adfd524e9 + languageName: node + linkType: hard + "morgan@npm:^1.10.0": version: 1.10.0 resolution: "morgan@npm:1.10.0" @@ -20496,6 +21881,21 @@ __metadata: languageName: node linkType: hard +"multer@npm:^1.4.5-lts.1": + version: 1.4.5-lts.1 + resolution: "multer@npm:1.4.5-lts.1" + dependencies: + append-field: ^1.0.0 + busboy: ^1.0.0 + concat-stream: ^1.5.2 + mkdirp: ^0.5.4 + object-assign: ^4.1.1 + type-is: ^1.6.4 + xtend: ^4.0.0 + checksum: d6dfa78a6ec592b74890412f8962da8a87a3dcfe20f612e039b735b8e0faa72c735516c447f7de694ee0d981eb0a1b892fb9e2402a0348dc6091d18c38d89ecc + languageName: node + linkType: hard + "multicast-dns@npm:^7.2.5": version: 7.2.5 resolution: "multicast-dns@npm:7.2.5" @@ -20596,6 +21996,13 @@ __metadata: languageName: node linkType: hard +"native-duplexpair@npm:^1.0.0": + version: 1.0.0 + resolution: "native-duplexpair@npm:1.0.0" + checksum: d849a8cb78c59eb12326fde2a84fedc26568b4317da46d061e7110a35961230b674a04ec2496860c2eb5f05288176c7ce0eb3a51eb0ed6b76a4263f637461f9d + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -20698,6 +22105,15 @@ __metadata: languageName: node linkType: hard +"node-cache@npm:^5.1.2": + version: 5.1.2 + resolution: "node-cache@npm:5.1.2" + dependencies: + clone: 2.x + checksum: b0bdd81a6fee4754fb984a05246b510bb35dc54721116d465899bf4229ee3287fdafb47da526900ee9924fb402ed5c7d8050049d37d8bf2d26dbafc23a2c3205 + languageName: node + linkType: hard + "node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" @@ -20712,7 +22128,7 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^1, node-forge@npm:^1.3.1": +"node-forge@npm:^1, node-forge@npm:^1.2.1, node-forge@npm:^1.3.1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" checksum: 08fb072d3d670599c89a1704b3e9c649ff1b998256737f0e06fbd1a5bf41cae4457ccaee32d95052d80bbafd9ffe01284e078c8071f0267dc9744e51c5ed42a9 @@ -20943,6 +22359,20 @@ __metadata: languageName: node linkType: hard +"oauth@npm:0.10.x": + version: 0.10.0 + resolution: "oauth@npm:0.10.0" + checksum: 68fbcd9fc382985fd6a4856245bb9f78281c08ea238e814288c51e6cfb65e442c9c4eea67d54ec595384eb3f007e7b64ae3b8e67ec309228df44aba64cc9e0c7 + languageName: node + linkType: hard + +"oauth@npm:0.9.x": + version: 0.9.15 + resolution: "oauth@npm:0.9.15" + checksum: 957c0d8d85300398dcb0e293953650c0fc3facc795bee8228238414f19f59cef5fd4ee8d17a972c142924c10c5f6ec50ef80f77f4a6cc6e3c98f9d22c027801c + languageName: node + linkType: hard + "object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -20957,6 +22387,13 @@ __metadata: languageName: node linkType: hard +"object-hash@npm:^3.0.0": + version: 3.0.0 + resolution: "object-hash@npm:3.0.0" + checksum: 80b4904bb3857c52cc1bfd0b52c0352532ca12ed3b8a6ff06a90cd209dfda1b95cee059a7625eb9da29537027f68ac4619363491eedb2f5d3dddbba97494fd6c + languageName: node + linkType: hard + "object-inspect@npm:^1.13.3": version: 1.13.3 resolution: "object-inspect@npm:1.13.3" @@ -21114,6 +22551,15 @@ __metadata: languageName: node linkType: hard +"ono@npm:^7.1.3": + version: 7.1.3 + resolution: "ono@npm:7.1.3" + dependencies: + "@jsdevtools/ono": 7.1.3 + checksum: d341681f1bdd08071760a8d92d37e0e5fb483c6f5c510543a17896c8ee7bdd399a375c632d39f9c78bd2aeab4e5e2eaae9ae0ab71c9738276ba8459c18ce41c4 + languageName: node + linkType: hard + "open@npm:^10.0.3": version: 10.1.0 resolution: "open@npm:10.1.0" @@ -21137,6 +22583,17 @@ __metadata: languageName: node linkType: hard +"openapi-merge@npm:^1.3.2": + version: 1.3.3 + resolution: "openapi-merge@npm:1.3.3" + dependencies: + atlassian-openapi: ^1.0.8 + lodash: ^4.17.15 + ts-is-present: ^1.1.1 + checksum: d23ed060facb72f52088cf59bf10abbd36e169bf727c634582904ab0cddfa697b2af0d0e720d908154c2966b80344a8d59811827582949e1e9ffd2acdbc70537 + languageName: node + linkType: hard + "openapi-types@npm:^12.0.2": version: 12.1.3 resolution: "openapi-types@npm:12.1.3" @@ -21144,7 +22601,16 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.3.0": +"openapi3-ts@npm:^3.1.2": + version: 3.2.0 + resolution: "openapi3-ts@npm:3.2.0" + dependencies: + yaml: ^2.2.1 + checksum: 8796a29a1363bc892ba1acb3ddffd9e6b80e8f83cbfad4cd507262e957317139cac2528ab4b14c1b30bf350ebc9cc4c43ad32a89da4d7c4b85f7e815ffba3ebe + languageName: node + linkType: hard + +"openid-client@npm:^5.2.1, openid-client@npm:^5.3.0, openid-client@npm:^5.5.0": version: 5.7.1 resolution: "openid-client@npm:5.7.1" dependencies: @@ -21366,7 +22832,7 @@ __metadata: languageName: node linkType: hard -"pac-proxy-agent@npm:^7.0.1": +"pac-proxy-agent@npm:^7.0.0, pac-proxy-agent@npm:^7.0.1": version: 7.1.0 resolution: "pac-proxy-agent@npm:7.1.0" dependencies: @@ -21494,6 +22960,13 @@ __metadata: languageName: node linkType: hard +"parse-multipart-data@npm:^1.4.0": + version: 1.5.0 + resolution: "parse-multipart-data@npm:1.5.0" + checksum: a385fb6609a7b393ee7e82042d5f923beaa7fb7d81d430db560869b719574f62f39a30e77fd711fbfa6fe3e212a8e6f81fd2126a80876a3c13dc1ae975eb5d91 + languageName: node + linkType: hard + "parse-numeric-range@npm:^1.3.0": version: 1.3.0 resolution: "parse-numeric-range@npm:1.3.0" @@ -21552,7 +23025,118 @@ __metadata: languageName: node linkType: hard -"passport-strategy@npm:1.x.x": +"passport-atlassian-oauth2@npm:^2.1.0": + version: 2.1.0 + resolution: "passport-atlassian-oauth2@npm:2.1.0" + dependencies: + passport-oauth2: ^1.4.0 + checksum: fc1d46951018d03a792a469a0c856d16f4c21df13d743aa5a0111f60253588c042881c560c737c77d85f4751e42b9ad3a485db7a5d5ea39e0f76160bc4010182 + languageName: node + linkType: hard + +"passport-auth0@npm:^1.4.3": + version: 1.4.4 + resolution: "passport-auth0@npm:1.4.4" + dependencies: + axios: ^1.6.0 + passport-oauth: ^1.0.0 + passport-oauth2: ^1.6.0 + checksum: 537c2a9d60fd3e8663cc5686bb34808412bccefaed8fa99c782f5e24fc2e103ddb14db1a8fdea38a89bd2eaa797d6f6a9c2d0309d83617dde9466ab1de4cf36b + languageName: node + linkType: hard + +"passport-bitbucket-oauth2@npm:^0.1.2": + version: 0.1.2 + resolution: "passport-bitbucket-oauth2@npm:0.1.2" + dependencies: + passport-oauth2: ^1.1.2 + pkginfo: 0.2.x + checksum: eef3db0967d8d4e6d5363dab5b188ff0ad32d333cfa246c1c3a4e796e62e225297a01f21ad0e1d42c4b2d635c119909d7bb0f22c686fc2c87b9f3d9796895721 + languageName: node + linkType: hard + +"passport-github2@npm:^0.1.12": + version: 0.1.12 + resolution: "passport-github2@npm:0.1.12" + dependencies: + passport-oauth2: 1.x.x + checksum: 2d33c1bdd808c617a5faef51f6079f8775a4dbb8864b2be073e5e043ed2b7e8f9addd66a5844c7604f26be99a5899ae6cd9f8adac85999714b2a19649aef2b35 + languageName: node + linkType: hard + +"passport-gitlab2@npm:^5.0.0": + version: 5.0.0 + resolution: "passport-gitlab2@npm:5.0.0" + dependencies: + passport-oauth2: ^1.4.0 + checksum: 06e105e994d7241712c05cd6182d06fbbef3f7ea919bdda532f90102fa5290d918648b0ed8d20729aff4c2497cd874fc3726166a338e413373b3b9e4a3b79e7b + languageName: node + linkType: hard + +"passport-google-oauth20@npm:^2.0.0": + version: 2.0.0 + resolution: "passport-google-oauth20@npm:2.0.0" + dependencies: + passport-oauth2: 1.x.x + checksum: 1d34f4c2da059504b6a3c149b261b9063d0390c84d500fa314b3895d599d7f96ce9750e48a5b715df92fba57ef4ecb5e66d3ce99ded5cc9b17d201a06ba8701e + languageName: node + linkType: hard + +"passport-microsoft@npm:^1.0.0": + version: 1.1.0 + resolution: "passport-microsoft@npm:1.1.0" + dependencies: + passport-oauth2: 1.8.0 + checksum: 97cb68f3adba8914a9375ebf1b0a05f33d8ca53ddad50948a254219e01672e726fc8eb7152d4e31de86041ab603dea950cec4f3dee5c6ade3bcc3de23aa44408 + languageName: node + linkType: hard + +"passport-oauth1@npm:1.x.x": + version: 1.3.0 + resolution: "passport-oauth1@npm:1.3.0" + dependencies: + oauth: 0.9.x + passport-strategy: 1.x.x + utils-merge: 1.x.x + checksum: 69a0538221f11509aa405de0cadf510e635a6723e1e7e6179db34b4d21d82db8eff8a1e95a6e9eaeca3233e8e1fa5dce87999cd3ec32387238a73a552f95ca16 + languageName: node + linkType: hard + +"passport-oauth2@npm:1.8.0, passport-oauth2@npm:1.x.x, passport-oauth2@npm:^1.1.2, passport-oauth2@npm:^1.4.0, passport-oauth2@npm:^1.6.0, passport-oauth2@npm:^1.6.1, passport-oauth2@npm:^1.7.0": + version: 1.8.0 + resolution: "passport-oauth2@npm:1.8.0" + dependencies: + base64url: 3.x.x + oauth: 0.10.x + passport-strategy: 1.x.x + uid2: 0.0.x + utils-merge: 1.x.x + checksum: a9a80b968343c9c1906f74ef613b346ec2d6a6acfe17af81e673fd774779b436729252485755c3ce182f2cdba2434d75067418952d722404d65b93c0360ca02b + languageName: node + linkType: hard + +"passport-oauth@npm:1.0.0, passport-oauth@npm:^1.0.0": + version: 1.0.0 + resolution: "passport-oauth@npm:1.0.0" + dependencies: + passport-oauth1: 1.x.x + passport-oauth2: 1.x.x + checksum: e6d908ac6c305db1f4040538360c29ca1427b27772c74abaa75db24647db7ee1ccd9c6ccc1bb74649bca090f31f3225540539219b4a97b31c0c1434f4a9ee7b3 + languageName: node + linkType: hard + +"passport-onelogin-oauth@npm:^0.0.1": + version: 0.0.1 + resolution: "passport-onelogin-oauth@npm:0.0.1" + dependencies: + passport-oauth: 1.0.0 + pkginfo: 0.2.x + uid2: 0.0.3 + checksum: 5664bbcca717e7499be5ec1336cc34ada3266fccdc92a026883d6113c2ab30ec215b7df810fb0abd3adb79afb728c6d7fa0782f8661afba25c4df198ed84470e + languageName: node + linkType: hard + +"passport-strategy@npm:1.x.x, passport-strategy@npm:^1.0.0": version: 1.0.0 resolution: "passport-strategy@npm:1.0.0" checksum: 5086693f2508e538dffa55a338c89fe8192fb5f4478c71f80cd5890b8573419a098f4fec88b505374f60bbe9049f6f24b9f3992678612528a3370b4dc73354a2 @@ -21657,7 +23241,7 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^8.0.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: 56e13e45962e776e9e7cd72e87a441cfe41f33fd539d097237ceb16adc922281136ca12f5a742962e33d8dda9569f630ba594de56d8b7b6e49adf31803c5e771 @@ -21867,6 +23451,20 @@ __metadata: languageName: node linkType: hard +"pkginfo@npm:0.2.x": + version: 0.2.3 + resolution: "pkginfo@npm:0.2.3" + checksum: 2dc005c4821d716e2a20d2940fb136e0585a801941db4937ac8ec2c2404af3c194c34171474067ebdbb34c582187fc3ab08cfca47ef75b988f0fa1de3f833550 + languageName: node + linkType: hard + +"pkginfo@npm:^0.4.1": + version: 0.4.1 + resolution: "pkginfo@npm:0.4.1" + checksum: 0f13694f3682345647b7cb887fb6fe258df51b635f252324cd75eeb8181b4381cb8b9d91dc2d869849e857192b403bea65038d2f7c05b524eeae69ece5048209 + languageName: node + linkType: hard + "pluralize@npm:^8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" @@ -22561,6 +24159,35 @@ __metadata: languageName: node linkType: hard +"proto3-json-serializer@npm:^2.0.2": + version: 2.0.2 + resolution: "proto3-json-serializer@npm:2.0.2" + dependencies: + protobufjs: ^7.2.5 + checksum: 21b8aa65be6dac2bb24920e5bdabef48b249bdf65b1498ae7e69ac4e70722275b083cd60a21d2b4be3ead9d768de2f6f5fb6b188bd177d51c824a539b5ba55cc + languageName: node + linkType: hard + +"protobufjs@npm:^7.2.5, protobufjs@npm:^7.2.6, protobufjs@npm:^7.3.2": + version: 7.4.0 + resolution: "protobufjs@npm:7.4.0" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: ba0e6b60541bbf818bb148e90f5eb68bd99004e29a6034ad9895a381cbd352be8dce5376e47ae21b2e05559f2505b4a5f4a3c8fa62402822c6ab4dcdfb89ffb3 + languageName: node + linkType: hard + "protocols@npm:^2.0.0, protocols@npm:^2.0.1": version: 2.0.1 resolution: "protocols@npm:2.0.1" @@ -22664,7 +24291,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.12.3, qs@npm:^6.9.4": +"qs@npm:^6.11.0, qs@npm:^6.12.3, qs@npm:^6.9.4": version: 6.13.1 resolution: "qs@npm:6.13.1" dependencies: @@ -22708,6 +24335,13 @@ __metadata: languageName: node linkType: hard +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: a516faa25574be7947969883e6068dbe4aa19e8ef8e8e0fd96cddd6d36485e9106d85c0041a27153286b0770b381328f4072aa40d3b18a19f5f7d2b78b94b5ed + languageName: node + linkType: hard + "raf-schd@npm:^4.0.2": version: 4.0.3 resolution: "raf-schd@npm:4.0.3" @@ -22722,6 +24356,13 @@ __metadata: languageName: node linkType: hard +"random-bytes@npm:~1.0.0": + version: 1.0.0 + resolution: "random-bytes@npm:1.0.0" + checksum: 09faa256394aa2ca9754aa57e92a27c452c3e97ffb266e98bebb517332e9df7168fea393159f88d884febce949ba8bec8ddb02f03342da6c6023ecc7b155e0ae + languageName: node + linkType: hard + "randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" @@ -23177,6 +24818,15 @@ __metadata: languageName: node linkType: hard +"read-tls-client-hello@npm:^1.0.0": + version: 1.0.1 + resolution: "read-tls-client-hello@npm:1.0.1" + dependencies: + "@types/node": "*" + checksum: 532c1c32ef049c245b59473ad7a06ad5db61bd22258ccfb54923be24173e8cafbb1a6a17bcc783884dce9b98db15db76a9569ea9c95b2b9b729be990439b931b + languageName: node + linkType: hard + "read-yaml-file@npm:^1.1.0": version: 1.1.0 resolution: "read-yaml-file@npm:1.1.0" @@ -23200,7 +24850,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.5, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.6, readable-stream@npm:^2.3.8": +"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.6, readable-stream@npm:^2.3.8": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -23736,6 +25386,13 @@ __metadata: languageName: node linkType: hard +"resolve-alpn@npm:^1.2.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: f558071fcb2c60b04054c99aebd572a2af97ef64128d59bef7ab73bd50d896a222a056de40ffc545b633d99b304c259ea9d0c06830d5c867c34f0bfa60b8eae0 + languageName: node + linkType: hard + "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -24234,6 +25891,13 @@ __metadata: languageName: node linkType: hard +"sax@npm:>=0.6.0": + version: 1.4.1 + resolution: "sax@npm:1.4.1" + checksum: 3ad64df16b743f0f2eb7c38ced9692a6d924f1cd07bbe45c39576c2cf50de8290d9d04e7b2228f924c7d05fecc4ec5cf651423278e0c7b63d260c387ef3af84a + languageName: node + linkType: hard + "saxes@npm:^6.0.0": version: 6.0.0 resolution: "saxes@npm:6.0.0" @@ -24317,7 +25981,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.3, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": +"semver@npm:7.6.3, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": version: 7.6.3 resolution: "semver@npm:7.6.3" bin: @@ -24643,7 +26307,7 @@ __metadata: languageName: node linkType: hard -"slugify@npm:1.6.6": +"slugify@npm:1.6.6, slugify@npm:^1.6.6": version: 1.6.6 resolution: "slugify@npm:1.6.6" checksum: 04773c2d3b7aea8d2a61fa47cc7e5d29ce04e1a96cbaec409da57139df906acb3a449fac30b167d203212c806e73690abd4ff94fbad0a9a7b7ea109a2a638ae9 @@ -25027,7 +26691,7 @@ __metadata: languageName: node linkType: hard -"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2, statuses@npm:^1.5.0": +"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2, statuses@npm:^1.5.0, statuses@npm:~1.5.0": version: 1.5.0 resolution: "statuses@npm:1.5.0" checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c @@ -25090,7 +26754,7 @@ __metadata: languageName: node linkType: hard -"stream-shift@npm:^1.0.2": +"stream-shift@npm:^1.0.0, stream-shift@npm:^1.0.2": version: 1.0.3 resolution: "stream-shift@npm:1.0.3" checksum: a24c0a3f66a8f9024bd1d579a533a53be283b4475d4e6b4b3211b964031447bdf6532dd1f3c2b0ad66752554391b7c62bd7ca4559193381f766534e723d50242 @@ -25108,6 +26772,13 @@ __metadata: languageName: node linkType: hard +"streamsearch@npm:^1.1.0": + version: 1.1.0 + resolution: "streamsearch@npm:1.1.0" + checksum: 1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942 + languageName: node + linkType: hard + "streamx@npm:^2.15.0, streamx@npm:^2.21.0": version: 2.21.1 resolution: "streamx@npm:2.21.1" @@ -25470,6 +27141,34 @@ __metadata: languageName: node linkType: hard +"superagent@npm:^8.1.2": + version: 8.1.2 + resolution: "superagent@npm:8.1.2" + dependencies: + component-emitter: ^1.3.0 + cookiejar: ^2.1.4 + debug: ^4.3.4 + fast-safe-stringify: ^2.1.1 + form-data: ^4.0.0 + formidable: ^2.1.2 + methods: ^1.1.2 + mime: 2.6.0 + qs: ^6.11.0 + semver: ^7.3.8 + checksum: f3601c5ccae34d5ba684a03703394b5d25931f4ae2e1e31a1de809f88a9400e997ece037f9accf148a21c408f950dc829db1e4e23576a7f9fe0efa79fd5c9d2f + languageName: node + linkType: hard + +"supertest@npm:^6.3.3": + version: 6.3.4 + resolution: "supertest@npm:6.3.4" + dependencies: + methods: ^1.1.2 + superagent: ^8.1.2 + checksum: 875c6fa7940f21e5be9bb646579cdb030d4057bf2da643e125e1f0480add1200395d2b17e10b8e54e1009efc63e047422501e9eb30e12828668498c0910f295f + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -25552,6 +27251,13 @@ __metadata: languageName: node linkType: hard +"symbol-observable@npm:^1.0.4": + version: 1.2.0 + resolution: "symbol-observable@npm:1.2.0" + checksum: 48ffbc22e3d75f9853b3ff2ae94a44d84f386415110aea5effc24d84c502e03a4a6b7a8f75ebaf7b585780bda34eb5d6da3121f826a6f93398429d30032971b6 + languageName: node + linkType: hard + "symbol-tree@npm:^3.2.4": version: 3.2.4 resolution: "symbol-tree@npm:3.2.4" @@ -26034,6 +27740,13 @@ __metadata: languageName: node linkType: hard +"ts-algebra@npm:^2.0.0": + version: 2.0.0 + resolution: "ts-algebra@npm:2.0.0" + checksum: 970b0e7db49cf8c1a8ff2a816eb047fac8add47511f5e4995e4998c56c6f7b226399284412de88f3e137ab55c857a4262c0d8f02f0765730e7d3a021de2ea7ef + languageName: node + linkType: hard + "ts-api-utils@npm:^1.0.1, ts-api-utils@npm:^1.3.0": version: 1.4.3 resolution: "ts-api-utils@npm:1.4.3" @@ -26066,6 +27779,13 @@ __metadata: languageName: node linkType: hard +"ts-is-present@npm:^1.1.1": + version: 1.2.2 + resolution: "ts-is-present@npm:1.2.2" + checksum: 3620ecf48219d0dd108e493260a207f4733d8e39a18dffec23c7ed2b1ef2aba7158d0dfafe36f3f27d0092472535a5e474ce04ade54e972e64b2b6329d20ab0b + languageName: node + linkType: hard + "ts-morph@npm:^23.0.0": version: 23.0.0 resolution: "ts-morph@npm:23.0.0" @@ -26251,7 +27971,7 @@ __metadata: languageName: node linkType: hard -"type-is@npm:^1.6.16, type-is@npm:~1.6.18": +"type-is@npm:^1.6.16, type-is@npm:^1.6.4, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" dependencies: @@ -26314,6 +28034,13 @@ __metadata: languageName: node linkType: hard +"typed-error@npm:^3.0.2": + version: 3.2.2 + resolution: "typed-error@npm:3.2.2" + checksum: 90d0d2ebef72a3655153d7d4ffe8607ebb38a39e38f9f19642a55542c0459afc887862ff5353d57ee77502c5c438341843b21309ecd0cf2b19a344034c9fedef + languageName: node + linkType: hard + "typedarray@npm:^0.0.6": version: 0.0.6 resolution: "typedarray@npm:0.0.6" @@ -26408,6 +28135,36 @@ __metadata: languageName: node linkType: hard +"uid-safe@npm:~2.1.5": + version: 2.1.5 + resolution: "uid-safe@npm:2.1.5" + dependencies: + random-bytes: ~1.0.0 + checksum: 07536043da9a026f4a2bc397543d0ace7587449afa1d9d2c4fd3ce76af8a5263a678788bcc429dff499ef29d45843cd5ee9d05434450fcfc19cc661229f703d1 + languageName: node + linkType: hard + +"uid2@npm:0.0.3": + version: 0.0.3 + resolution: "uid2@npm:0.0.3" + checksum: c8f64acfa94aa42d90c1a61ba9df0162f0db0d28c211e21cf5792b3d70b7ad9fd75d19c7cadcce81896ea111335e57e65891a3b6d0a1343a9adf45abf3d4c47d + languageName: node + linkType: hard + +"uid2@npm:0.0.x": + version: 0.0.4 + resolution: "uid2@npm:0.0.4" + checksum: e92325ce2e3b7be504b19e835dbb5a8b0495031f364b08ca46745468ed0ae0f202a4fdaf99a1a2715844156efc3ab410456ae24a0f7c0ae4b0a2e9f2784edfd9 + languageName: node + linkType: hard + +"uid2@npm:^1.0.0": + version: 1.0.0 + resolution: "uid2@npm:1.0.0" + checksum: 7efad0da3839ef2bebc6fae4bd29905702cd64233b3907e3300aa2d7ea1a00c1ae8c41a5e16ca34ac2db2d25c5607d5989673e1df51a2a076fefbeed51605ec3 + languageName: node + linkType: hard + "uid@npm:2.0.2": version: 2.0.2 resolution: "uid@npm:2.0.2" @@ -26761,7 +28518,7 @@ __metadata: languageName: node linkType: hard -"urijs@npm:^1.19.11": +"urijs@npm:^1.19.10, urijs@npm:^1.19.11": version: 1.19.11 resolution: "urijs@npm:1.19.11" checksum: f9b95004560754d30fd7dbee44b47414d662dc9863f1cf5632a7c7983648df11d23c0be73b9b4f9554463b61d5b0a520b70df9e1ee963ebb4af02e6da2cc80f3 @@ -26795,6 +28552,13 @@ __metadata: languageName: node linkType: hard +"urlpattern-polyfill@npm:^8.0.0": + version: 8.0.2 + resolution: "urlpattern-polyfill@npm:8.0.2" + checksum: d2cc0905a613c77e330c426e8697ee522dd9640eda79ac51160a0f6350e103f09b8c327623880989f8ba7325e8d95267b745aa280fdcc2aead80b023e16bd09d + languageName: node + linkType: hard + "use-memo-one@npm:^1.1.1": version: 1.1.3 resolution: "use-memo-one@npm:1.1.3" @@ -26865,7 +28629,7 @@ __metadata: languageName: node linkType: hard -"utils-merge@npm:1.0.1, utils-merge@npm:^1.0.1": +"utils-merge@npm:1.0.1, utils-merge@npm:1.x.x, utils-merge@npm:^1.0.1": version: 1.0.1 resolution: "utils-merge@npm:1.0.1" checksum: c81095493225ecfc28add49c106ca4f09cdf56bc66731aa8dabc2edbbccb1e1bfe2de6a115e5c6a380d3ea166d1636410b62ef216bb07b3feb1cfde1d95d5080 @@ -26980,6 +28744,13 @@ __metadata: languageName: node linkType: hard +"value-or-promise@npm:1.0.11": + version: 1.0.11 + resolution: "value-or-promise@npm:1.0.11" + checksum: 13f8f2ef620118c73b4d1beee8ce6045d7182bbf15090ecfbcafb677ec43698506a5e9ace6bea5ea35c32bc612c9b1f824bb59b6581cdfb5c919052745c277d5 + languageName: node + linkType: hard + "vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" @@ -27503,7 +29274,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.18.0, ws@npm:^8.11.0, ws@npm:^8.18.0": +"ws@npm:*, ws@npm:8.18.0, ws@npm:^8.11.0, ws@npm:^8.18.0, ws@npm:^8.8.0": version: 8.18.0 resolution: "ws@npm:8.18.0" peerDependencies: @@ -27518,6 +29289,28 @@ __metadata: languageName: node linkType: hard +"xml-crypto@npm:^6.0.0": + version: 6.0.0 + resolution: "xml-crypto@npm:6.0.0" + dependencies: + "@xmldom/is-dom-node": ^1.0.1 + "@xmldom/xmldom": ^0.8.10 + xpath: ^0.0.33 + checksum: 1c679ed66e4cea6309602cf8d536973f7832b69bd400310802365af972c9a0261c9a456c64015e0e92b8c93f168f9f13a355bbbd04d1219ca61c2a3f544d1208 + languageName: node + linkType: hard + +"xml-encryption@npm:^3.0.2": + version: 3.0.2 + resolution: "xml-encryption@npm:3.0.2" + dependencies: + "@xmldom/xmldom": ^0.8.5 + escape-html: ^1.0.3 + xpath: 0.0.32 + checksum: aac1b987d5de5becfc747c88c3a656c00799a153ab541078b875a69e1ac1f1c2f29bf85f22eab6a78382dc2919f79401a916cc392aba7994475919e0695893eb + languageName: node + linkType: hard + "xml-name-validator@npm:^4.0.0": version: 4.0.0 resolution: "xml-name-validator@npm:4.0.0" @@ -27525,6 +29318,30 @@ __metadata: languageName: node linkType: hard +"xml2js@npm:^0.6.2": + version: 0.6.2 + resolution: "xml2js@npm:0.6.2" + dependencies: + sax: ">=0.6.0" + xmlbuilder: ~11.0.0 + checksum: 458a83806193008edff44562c0bdb982801d61ee7867ae58fd35fab781e69e17f40dfeb8fc05391a4648c9c54012066d3955fe5d993ffbe4dc63399023f32ac2 + languageName: node + linkType: hard + +"xmlbuilder@npm:^15.1.1": + version: 15.1.1 + resolution: "xmlbuilder@npm:15.1.1" + checksum: 14f7302402e28d1f32823583d121594a9dca36408d40320b33f598bd589ca5163a352d076489c9c64d2dc1da19a790926a07bf4191275330d4de2b0d85bb1843 + languageName: node + linkType: hard + +"xmlbuilder@npm:~11.0.0": + version: 11.0.1 + resolution: "xmlbuilder@npm:11.0.1" + checksum: 7152695e16f1a9976658215abab27e55d08b1b97bca901d58b048d2b6e106b5af31efccbdecf9b07af37c8377d8e7e821b494af10b3a68b0ff4ae60331b415b0 + languageName: node + linkType: hard + "xmlchars@npm:^2.2.0": version: 2.2.0 resolution: "xmlchars@npm:2.2.0" @@ -27532,6 +29349,27 @@ __metadata: languageName: node linkType: hard +"xpath@npm:0.0.32": + version: 0.0.32 + resolution: "xpath@npm:0.0.32" + checksum: 887e9747b960ea45fb47a9464744424512de0a49205e82c2ad6be662d7a2f1a75145662a143304340864c6da68fd8d767cce4065cc198ee07a3d4897e0a3d4bb + languageName: node + linkType: hard + +"xpath@npm:^0.0.33": + version: 0.0.33 + resolution: "xpath@npm:0.0.33" + checksum: 075cd553819302b9df0ae11526b666016ee286b72e0600a923c7565d847fcfa7ff195db3065ec86b9a12f1f81bfc82f1a316fc53442a8572c31582e87ccaec4a + languageName: node + linkType: hard + +"xpath@npm:^0.0.34": + version: 0.0.34 + resolution: "xpath@npm:0.0.34" + checksum: c10ae2b7be442460462e80a9ef79ca1c9b529abcf696ec3859cddd5a52b64b7e55a54c2c5352ac9c5d195939e2b3aefe708a7428780d7ec0ae7565257ab2a224 + languageName: node + linkType: hard + "xtend@npm:^4.0.0": version: 4.0.2 resolution: "xtend@npm:4.0.2" @@ -27596,7 +29434,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.0.0, yaml@npm:^2.0.0-10, yaml@npm:^2.2.2": +"yaml@npm:^2.0.0, yaml@npm:^2.0.0-10, yaml@npm:^2.2.1, yaml@npm:^2.2.2": version: 2.6.1 resolution: "yaml@npm:2.6.1" bin: @@ -27740,6 +29578,13 @@ __metadata: languageName: node linkType: hard +"zstd-codec@npm:^0.1.5": + version: 0.1.5 + resolution: "zstd-codec@npm:0.1.5" + checksum: ba62bf643c3ca9759fedc090b73a0c3b1e506364fcae902a70b112c1f5b30bc6aabff3184808cc4430f2ab6644cabae979368152ae908c1d8ef39cd8c3223c85 + languageName: node + linkType: hard + "zwitch@npm:^2.0.0, zwitch@npm:^2.0.4": version: 2.0.4 resolution: "zwitch@npm:2.0.4"