Merge pull request #15816 from backstage/rugvip/subpath
[PRFC] Add support for subpath exports
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/repo-tools': patch
|
||||
---
|
||||
|
||||
Tweaked type dependency check to trim wildcard type imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Added a new `migrate package-exports` command that synchronizes package exports fields in all `package.json`s.
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
|
||||
'@backstage/plugin-catalog-backend-module-bitbucket-server': patch
|
||||
'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch
|
||||
'@backstage/plugin-events-backend-module-bitbucket-cloud': patch
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
'@backstage/plugin-catalog-backend-module-gerrit': patch
|
||||
'@backstage/plugin-catalog-backend-module-github': patch
|
||||
'@backstage/plugin-catalog-backend-module-gitlab': patch
|
||||
'@backstage/plugin-events-backend-module-aws-sqs': patch
|
||||
'@backstage/plugin-catalog-backend-module-azure': patch
|
||||
'@backstage/plugin-events-backend-module-gerrit': patch
|
||||
'@backstage/plugin-events-backend-module-github': patch
|
||||
'@backstage/plugin-events-backend-module-gitlab': patch
|
||||
'@backstage/plugin-events-backend-module-azure': patch
|
||||
'@backstage/plugin-catalog-backend-module-aws': patch
|
||||
'@backstage/backend-plugin-api': patch
|
||||
'@backstage/backend-test-utils': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/backend-defaults': patch
|
||||
'@backstage/backend-app-api': patch
|
||||
'@backstage/core-plugin-api': patch
|
||||
'@backstage/plugin-scaffolder-react': patch
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
'@backstage/plugin-sonarqube-react': patch
|
||||
'@backstage/catalog-model': patch
|
||||
'@backstage/plugin-catalog-common': patch
|
||||
'@backstage/plugin-events-backend': patch
|
||||
'@backstage/plugin-jenkins-common': patch
|
||||
'@backstage/plugin-techdocs-react': patch
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
'@backstage/plugin-catalog-node': patch
|
||||
'@backstage/test-utils': patch
|
||||
'@backstage/plugin-app-backend': patch
|
||||
'@backstage/plugin-events-node': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
'@backstage/plugin-catalog': patch
|
||||
'@backstage/plugin-jenkins': patch
|
||||
---
|
||||
|
||||
Internal refactor of `/alpha` exports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/repo-tools': patch
|
||||
---
|
||||
|
||||
The API report generation process is now able to detect and generate reports for additional entry points declared in the package `"exports"` field.
|
||||
@@ -5,6 +5,7 @@ coverage
|
||||
*.hbs
|
||||
templates
|
||||
api-report.md
|
||||
*-api-report.md
|
||||
cli-report.md
|
||||
plugins/scaffolder-backend/sample-templates
|
||||
.vscode
|
||||
|
||||
@@ -650,8 +650,34 @@ The following is an excerpt of a typical setup of an isomorphic library package:
|
||||
"files": ["dist"],
|
||||
```
|
||||
|
||||
## Subpath Exports
|
||||
|
||||
The Backstage CLI supports implementation of subpath exports through the `"exports"` field in `package.json`. It might for example look like this:
|
||||
|
||||
```json
|
||||
"name": "@backstage/plugin-foo",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./components": "./src/components.ts",
|
||||
},
|
||||
```
|
||||
|
||||
This in turn would allow you to import anything exported in `src/index.ts` via `@backstage/plugins-foo`, and `src/components.ts` via `@backstage/plugins-foo/components`. Note that patterns are not supported, meaning the exports may not contain `*` wildcards.
|
||||
|
||||
As with the rest of the Backstage CLI build system, the setup is optimized for local development, which is why the `"exports"` targets point directly to source files. The `package build` command will detect the `"exports"` field and automatically generate the corresponding `dist` files, and the `prepublish` command will rewrite the `"exports"` field to point to the `dist` files, as well as generating folder-based entry points for backwards compatibility.
|
||||
|
||||
TypeScript support is currently handled though the `typesVersions` field, as there is not yet a module resolution mode that works well with `"exports"`. You can craft the `typesVersions` yourself, but it will also be automatically generated by the `migrate package-exports` command.
|
||||
|
||||
To add subpath exports to an existing package, simply add the desired `"exports"` fields and then run the following command:
|
||||
|
||||
```bash
|
||||
yarn backstage-cli package migrate package-exports
|
||||
```
|
||||
|
||||
## Experimental Type Build
|
||||
|
||||
> Note: Experimental type builds are deprecated and will be removed in the future. They have been replaced by [subpath exports](#subpath-exports).
|
||||
|
||||
The Backstage CLI has an experimental feature where multiple different type definition files can be generated for different release stages. The release stages are marked in the [TSDoc](https://tsdoc.org/) for each individual export, using either `@public`, `@alpha`, or `@beta`. Rather than just building a single `index.d.ts` file, the build process will instead output `index.d.ts`, `index.beta.d.ts`, and `index.alpha.d.ts`. Each of these files will have exports from more unstable release stages stripped, meaning that `index.d.ts` will omit all exports marked with `@alpha` or `@beta`, while `index.beta.d.ts` will omit all exports marked with `@alpha`.
|
||||
|
||||
This feature is aimed at projects that publish to package registries and wish to maintain different levels of API stability within each package. There is no need to use this within a single monorepo, as it has no effect due to only applying to built and published packages.
|
||||
|
||||
@@ -120,7 +120,6 @@ Build a package for production deployment or publishing
|
||||
Options:
|
||||
--role <name> Run the command with an explicit package role
|
||||
--minify Minify the generated code. Does not apply to app or backend packages.
|
||||
--experimental-type-build Enable experimental type build. Does not apply to app or backend packages.
|
||||
--skip-build-dependencies Skip the automatic building of local dependencies. Applies to backend packages only.
|
||||
--stats If bundle stats are available, write them to the output directory. Applies to app packages only.
|
||||
--config <path> Config files to load instead of app-config.yaml. Applies to app packages only. (default: [])
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
"build:backend": "yarn workspace backend build",
|
||||
"build:all": "backstage-cli repo build --all",
|
||||
"build:api-reports": "yarn build:api-reports:only --tsc",
|
||||
"build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type",
|
||||
"build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags",
|
||||
"build:api-docs": "LANG=en_EN yarn build:api-reports --docs",
|
||||
"tsc": "tsc",
|
||||
"tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false",
|
||||
|
||||
@@ -59,9 +59,9 @@ import { GraphiQLPage } from '@backstage/plugin-graphiql';
|
||||
import { HomepageCompositionRoot } from '@backstage/plugin-home';
|
||||
import { LighthousePage } from '@backstage/plugin-lighthouse';
|
||||
import { NewRelicPage } from '@backstage/plugin-newrelic';
|
||||
import { NextScaffolderPage } from '@backstage/plugin-scaffolder/alpha';
|
||||
import {
|
||||
ScaffolderPage,
|
||||
NextScaffolderPage,
|
||||
scaffolderPlugin,
|
||||
ScaffolderLayouts,
|
||||
} from '@backstage/plugin-scaffolder';
|
||||
@@ -104,7 +104,7 @@ import * as plugins from './plugins';
|
||||
import { techDocsPage } from './components/techdocs/TechDocsPage';
|
||||
import { ApacheAirflowPage } from '@backstage/plugin-apache-airflow';
|
||||
import { RequirePermission } from '@backstage/plugin-permission-react';
|
||||
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common';
|
||||
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';
|
||||
import { PlaylistIndexPage } from '@backstage/plugin-playlist';
|
||||
import { TwoColumnLayout } from './components/scaffolder/customScaffolderLayouts';
|
||||
import { ScoreBoardPage } from '@oriflame/backstage-plugin-score-card';
|
||||
|
||||
@@ -17,10 +17,11 @@ import React from 'react';
|
||||
import type { FieldValidation } from '@rjsf/utils';
|
||||
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
|
||||
import { TextField } from '@material-ui/core';
|
||||
|
||||
import {
|
||||
NextFieldExtensionComponentProps,
|
||||
createNextScaffolderFieldExtension,
|
||||
} from '@backstage/plugin-scaffolder-react/alpha';
|
||||
import {
|
||||
createScaffolderFieldExtension,
|
||||
FieldExtensionComponentProps,
|
||||
} from '@backstage/plugin-scaffolder-react';
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"backstage": {
|
||||
"role": "node-library"
|
||||
@@ -24,7 +23,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
## API Report File for "@backstage/backend-common"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { Duration } from 'luxon';
|
||||
|
||||
// @alpha
|
||||
export interface Context {
|
||||
readonly abortSignal: AbortSignal;
|
||||
readonly deadline: Date | undefined;
|
||||
value<T = unknown>(key: string): T | undefined;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export class Contexts {
|
||||
static root(): Context;
|
||||
static withAbort(
|
||||
parentCtx: Context,
|
||||
source: AbortController | AbortSignal,
|
||||
): Context;
|
||||
static withTimeoutDuration(parentCtx: Context, timeout: Duration): Context;
|
||||
static withTimeoutMillis(parentCtx: Context, timeout: number): Context;
|
||||
static withValue(
|
||||
parentCtx: Context,
|
||||
key: string,
|
||||
value: unknown | ((previous: unknown | undefined) => unknown),
|
||||
): Context;
|
||||
}
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -20,7 +20,6 @@ import { Config } from '@backstage/config';
|
||||
import { ConfigService } from '@backstage/backend-plugin-api';
|
||||
import cors from 'cors';
|
||||
import Docker from 'dockerode';
|
||||
import { Duration } from 'luxon';
|
||||
import { ErrorRequestHandler } from 'express';
|
||||
import express from 'express';
|
||||
import { GerritIntegration } from '@backstage/integration';
|
||||
@@ -211,29 +210,6 @@ export interface ContainerRunner {
|
||||
runContainer(opts: RunContainerOptions): Promise<void>;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export interface Context {
|
||||
readonly abortSignal: AbortSignal;
|
||||
readonly deadline: Date | undefined;
|
||||
value<T = unknown>(key: string): T | undefined;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export class Contexts {
|
||||
static root(): Context;
|
||||
static withAbort(
|
||||
parentCtx: Context,
|
||||
source: AbortController | AbortSignal,
|
||||
): Context;
|
||||
static withTimeoutDuration(parentCtx: Context, timeout: Duration): Context;
|
||||
static withTimeoutMillis(parentCtx: Context, timeout: number): Context;
|
||||
static withValue(
|
||||
parentCtx: Context,
|
||||
key: string,
|
||||
value: unknown | ((previous: unknown | undefined) => unknown),
|
||||
): Context;
|
||||
}
|
||||
|
||||
// @public
|
||||
export function createDatabaseClient(
|
||||
dbConfig: Config,
|
||||
|
||||
@@ -5,10 +5,22 @@
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "node-library"
|
||||
@@ -24,7 +36,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './context';
|
||||
@@ -24,7 +24,6 @@ export { legacyPlugin, makeLegacyPlugin } from './legacy';
|
||||
export type { LegacyCreateRouter } from './legacy';
|
||||
export * from './cache';
|
||||
export { loadBackendConfig } from './config';
|
||||
export * from './context';
|
||||
export * from './database';
|
||||
export * from './discovery';
|
||||
export * from './hot';
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { catalogPlugin } from '@backstage/plugin-catalog-backend';
|
||||
import { catalogModuleTemplateKind } from '@backstage/plugin-scaffolder-backend';
|
||||
import { catalogPlugin } from '@backstage/plugin-catalog-backend/alpha';
|
||||
import { catalogModuleTemplateKind } from '@backstage/plugin-scaffolder-backend/alpha';
|
||||
import { createBackend } from '@backstage/backend-defaults';
|
||||
import { appPlugin } from '@backstage/plugin-app-backend';
|
||||
import { appPlugin } from '@backstage/plugin-app-backend/alpha';
|
||||
import { todoPlugin } from '@backstage/plugin-todo-backend';
|
||||
|
||||
const backend = createBackend();
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"backstage": {
|
||||
"role": "node-library"
|
||||
@@ -24,7 +23,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
|
||||
@@ -5,10 +5,18 @@
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "node-library"
|
||||
@@ -25,7 +33,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -55,7 +63,6 @@
|
||||
"supertest": "^6.1.3"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"alpha"
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
## API Report File for "@backstage/catalog-model"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { SerializedError } from '@backstage/errors';
|
||||
|
||||
// @alpha
|
||||
export interface AlphaEntity extends Entity {
|
||||
status?: EntityStatus;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export type EntityStatus = {
|
||||
items?: EntityStatusItem[];
|
||||
};
|
||||
|
||||
// @alpha
|
||||
export type EntityStatusItem = {
|
||||
type: string;
|
||||
level: EntityStatusLevel;
|
||||
message: string;
|
||||
error?: SerializedError;
|
||||
};
|
||||
|
||||
// @alpha
|
||||
export type EntityStatusLevel = 'info' | 'warning' | 'error';
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -4,12 +4,6 @@
|
||||
|
||||
```ts
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { SerializedError } from '@backstage/errors';
|
||||
|
||||
// @alpha
|
||||
export interface AlphaEntity extends Entity {
|
||||
status?: EntityStatus;
|
||||
}
|
||||
|
||||
// @public
|
||||
export const ANNOTATION_EDIT_URL = 'backstage.io/edit-url';
|
||||
@@ -209,22 +203,6 @@ export function entitySchemaValidator<T extends Entity = Entity>(
|
||||
schema?: unknown,
|
||||
): (data: unknown) => T;
|
||||
|
||||
// @alpha
|
||||
export type EntityStatus = {
|
||||
items?: EntityStatusItem[];
|
||||
};
|
||||
|
||||
// @alpha
|
||||
export type EntityStatusItem = {
|
||||
type: string;
|
||||
level: EntityStatusLevel;
|
||||
message: string;
|
||||
error?: SerializedError;
|
||||
};
|
||||
|
||||
// @alpha
|
||||
export type EntityStatusLevel = 'info' | 'warning' | 'error';
|
||||
|
||||
// @public
|
||||
export class FieldFormatEntityPolicy implements EntityPolicy {
|
||||
constructor(validators?: Validators);
|
||||
|
||||
@@ -6,11 +6,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "common-library"
|
||||
@@ -25,7 +36,7 @@
|
||||
"backstage"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -48,7 +59,6 @@
|
||||
"yaml": "^2.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"alpha"
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type {
|
||||
EntityStatus,
|
||||
EntityStatusItem,
|
||||
EntityStatusLevel,
|
||||
} from './entity/EntityStatus';
|
||||
export type { AlphaEntity } from './entity/AlphaEntity';
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
// TODO(Rugvip): Figure out best way to allow this import
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { EntityStatus } from './EntityStatus';
|
||||
|
||||
/**
|
||||
* A version of the `Entity` type that contains unstable alpha fields.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* Available via the `@backstage/catalog-model/alpha` import.
|
||||
*
|
||||
* @alpha
|
||||
*/
|
||||
export interface AlphaEntity extends Entity {
|
||||
/**
|
||||
* The current status of the entity, as claimed by various sources.
|
||||
*
|
||||
* The keys are implementation defined and the values can be any JSON object
|
||||
* with semantics that match that implementation.
|
||||
*/
|
||||
status?: EntityStatus;
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { EntityStatus } from './EntityStatus';
|
||||
|
||||
/**
|
||||
* The parts of the format that's common to all versions/kinds of entity.
|
||||
@@ -54,25 +53,6 @@ export type Entity = {
|
||||
relations?: EntityRelation[];
|
||||
};
|
||||
|
||||
/**
|
||||
* A version of the {@link Entity} type that contains unstable alpha fields.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* Available via the `@backstage/catalog-model/alpha` import.
|
||||
*
|
||||
* @alpha
|
||||
*/
|
||||
export interface AlphaEntity extends Entity {
|
||||
/**
|
||||
* The current status of the entity, as claimed by various sources.
|
||||
*
|
||||
* The keys are implementation defined and the values can be any JSON object
|
||||
* with semantics that match that implementation.
|
||||
*/
|
||||
status?: EntityStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata fields common to all versions/kinds of entity.
|
||||
*
|
||||
|
||||
@@ -16,19 +16,8 @@
|
||||
|
||||
export * from './conditions';
|
||||
export * from './constants';
|
||||
export type {
|
||||
AlphaEntity,
|
||||
Entity,
|
||||
EntityLink,
|
||||
EntityMeta,
|
||||
EntityRelation,
|
||||
} from './Entity';
|
||||
export type { Entity, EntityLink, EntityMeta, EntityRelation } from './Entity';
|
||||
export type { EntityEnvelope } from './EntityEnvelope';
|
||||
export type {
|
||||
EntityStatus,
|
||||
EntityStatusItem,
|
||||
EntityStatusLevel,
|
||||
} from './EntityStatus';
|
||||
export * from './policies';
|
||||
export {
|
||||
getCompoundEntityRef,
|
||||
|
||||
@@ -127,11 +127,21 @@ Options:
|
||||
Commands:
|
||||
package-roles
|
||||
package-scripts
|
||||
package-exports
|
||||
package-lint-configs
|
||||
react-router-deps
|
||||
help [command]
|
||||
```
|
||||
|
||||
### `backstage-cli migrate package-exports`
|
||||
|
||||
```
|
||||
Usage: backstage-cli migrate package-exports [options]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
```
|
||||
|
||||
### `backstage-cli migrate package-lint-configs`
|
||||
|
||||
```
|
||||
|
||||
@@ -37,6 +37,7 @@ export async function buildBackend(options: BuildBackendOptions) {
|
||||
// We build the target package without generating type declarations.
|
||||
await buildPackage({
|
||||
targetDir: options.targetDir,
|
||||
packageJson: pkg,
|
||||
outputs: new Set([Output.cjs]),
|
||||
});
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ export function registerScriptCommand(program: Command) {
|
||||
)
|
||||
.option(
|
||||
'--experimental-type-build',
|
||||
'Enable experimental type build. Does not apply to app or backend packages.',
|
||||
'Enable experimental type build. Does not apply to app or backend packages. [DEPRECATED]',
|
||||
)
|
||||
.option(
|
||||
'--skip-build-dependencies',
|
||||
@@ -191,6 +191,13 @@ export function registerMigrateCommand(program: Command) {
|
||||
lazy(() => import('./migrate/packageScripts').then(m => m.command)),
|
||||
);
|
||||
|
||||
command
|
||||
.command('package-exports')
|
||||
.description('Synchronize package subpath export definitions')
|
||||
.action(
|
||||
lazy(() => import('./migrate/packageExports').then(m => m.command)),
|
||||
);
|
||||
|
||||
command
|
||||
.command('package-lint-configs')
|
||||
.description(
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2020 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 fs from 'fs-extra';
|
||||
import { resolve as resolvePath } from 'path';
|
||||
import { ExtendedPackageJSON, PackageGraph } from '../../lib/monorepo';
|
||||
|
||||
function trimRelative(path: string): string {
|
||||
if (path.startsWith('./')) {
|
||||
return path.slice(2);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
export async function command() {
|
||||
const packages = await PackageGraph.listTargetPackages();
|
||||
|
||||
await Promise.all(
|
||||
packages.map(async ({ dir, packageJson }) => {
|
||||
let changed = false;
|
||||
let newPackageJson = packageJson;
|
||||
|
||||
let { exports: exp } = newPackageJson;
|
||||
if (!exp) {
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(exp)) {
|
||||
throw new Error('Unexpected array in package.json exports field');
|
||||
}
|
||||
|
||||
// If exports is a string we rewrite it to an object to add package.json
|
||||
if (typeof exp === 'string') {
|
||||
changed = true;
|
||||
exp = { '.': exp };
|
||||
newPackageJson.exports = exp;
|
||||
} else if (typeof exp !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exp['./package.json']) {
|
||||
changed = true;
|
||||
exp['./package.json'] = './package.json';
|
||||
}
|
||||
|
||||
const existingTypesVersions = JSON.stringify(packageJson.typesVersions);
|
||||
|
||||
const typeEntries: Record<string, [string]> = {};
|
||||
for (const [path, value] of Object.entries(exp)) {
|
||||
// Main entry point does not need to be listed
|
||||
if (path === '.') {
|
||||
continue;
|
||||
}
|
||||
const newPath = trimRelative(path);
|
||||
|
||||
if (typeof value === 'string') {
|
||||
typeEntries[newPath] = [trimRelative(value)];
|
||||
} else if (
|
||||
value &&
|
||||
typeof value === 'object' &&
|
||||
!Array.isArray(value)
|
||||
) {
|
||||
if (typeof value.types === 'string') {
|
||||
typeEntries[newPath] = [trimRelative(value.types)];
|
||||
} else if (typeof value.default === 'string') {
|
||||
typeEntries[newPath] = [trimRelative(value.default)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const typesVersions = { '*': typeEntries };
|
||||
if (existingTypesVersions !== JSON.stringify(typesVersions)) {
|
||||
console.log(`Synchronizing exports in ${packageJson.name}`);
|
||||
const newPkgEntries = Object.entries(newPackageJson).filter(
|
||||
([name]) => name !== 'typesVersions',
|
||||
);
|
||||
newPkgEntries.splice(
|
||||
newPkgEntries.findIndex(([name]) => name === 'exports') + 1,
|
||||
0,
|
||||
['typesVersions', typesVersions],
|
||||
);
|
||||
|
||||
newPackageJson = Object.fromEntries(
|
||||
newPkgEntries,
|
||||
) as ExtendedPackageJSON;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Remove the legacy fields from publishConfig, which are no longer needed
|
||||
const publishConfig = newPackageJson.publishConfig as
|
||||
| Record<string, string>
|
||||
| undefined;
|
||||
if (publishConfig) {
|
||||
for (const field of ['main', 'module', 'browser', 'types']) {
|
||||
if (publishConfig[field]) {
|
||||
delete publishConfig[field];
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
await fs.writeJson(resolvePath(dir, 'package.json'), newPackageJson, {
|
||||
spaces: 2,
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -14,77 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import {
|
||||
productionPack,
|
||||
revertProductionPack,
|
||||
} from '../lib/packager/productionPack';
|
||||
import { paths } from '../lib/paths';
|
||||
import { join as joinPath } from 'path';
|
||||
|
||||
const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes'];
|
||||
|
||||
const PKG_PATH = 'package.json';
|
||||
const PKG_BACKUP_PATH = 'package.json-prepack';
|
||||
|
||||
function resolveEntrypoint(pkg: any, name: string) {
|
||||
const targetEntry = pkg.publishConfig[name] || pkg[name];
|
||||
return targetEntry && joinPath('..', targetEntry);
|
||||
}
|
||||
|
||||
// Writes e.g. alpha/package.json
|
||||
async function writeReleaseStageEntrypoint(pkg: any, stage: 'alpha' | 'beta') {
|
||||
await fs.ensureDir(paths.resolveTarget(stage));
|
||||
await fs.writeJson(
|
||||
paths.resolveTarget(stage, PKG_PATH),
|
||||
{
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
main: resolveEntrypoint(pkg, 'main'),
|
||||
module: resolveEntrypoint(pkg, 'module'),
|
||||
browser: resolveEntrypoint(pkg, 'browser'),
|
||||
types: joinPath('..', pkg.publishConfig[`${stage}Types`]),
|
||||
},
|
||||
{ encoding: 'utf8', spaces: 2 },
|
||||
);
|
||||
}
|
||||
|
||||
export const pre = async () => {
|
||||
const pkgPath = paths.resolveTarget(PKG_PATH);
|
||||
|
||||
const pkgContent = await fs.readFile(pkgPath, 'utf8');
|
||||
const pkg = JSON.parse(pkgContent);
|
||||
await fs.writeFile(PKG_BACKUP_PATH, pkgContent);
|
||||
|
||||
const publishConfig = pkg.publishConfig ?? {};
|
||||
for (const key of Object.keys(publishConfig)) {
|
||||
if (!SKIPPED_KEYS.includes(key)) {
|
||||
pkg[key] = publishConfig[key];
|
||||
}
|
||||
}
|
||||
await fs.writeJson(pkgPath, pkg, { encoding: 'utf8', spaces: 2 });
|
||||
|
||||
if (publishConfig.alphaTypes) {
|
||||
await writeReleaseStageEntrypoint(pkg, 'alpha');
|
||||
}
|
||||
if (publishConfig.betaTypes) {
|
||||
await writeReleaseStageEntrypoint(pkg, 'beta');
|
||||
}
|
||||
await productionPack({ packageDir: paths.targetDir });
|
||||
};
|
||||
|
||||
export const post = async () => {
|
||||
// postpack isn't called by yarn right now, so it needs to be called manually
|
||||
try {
|
||||
await fs.move(PKG_BACKUP_PATH, PKG_PATH, { overwrite: true });
|
||||
|
||||
// Check if we're shipping types for other release stages, clean up in that case
|
||||
const pkg = await fs.readJson(PKG_PATH);
|
||||
if (pkg.publishConfig?.alphaTypes) {
|
||||
await fs.remove(paths.resolveTarget('alpha'));
|
||||
}
|
||||
if (pkg.publishConfig?.betaTypes) {
|
||||
await fs.remove(paths.resolveTarget('beta'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`Failed to restore package.json during postpack, ${error}. ` +
|
||||
'Your package will be fine but you may have ended up with some garbage in the repo.',
|
||||
);
|
||||
}
|
||||
await revertProductionPack(paths.targetDir);
|
||||
};
|
||||
|
||||
@@ -130,6 +130,7 @@ export async function command(opts: OptionValues, cmd: Command): Promise<void> {
|
||||
|
||||
return {
|
||||
targetDir: pkg.dir,
|
||||
packageJson: pkg.packageJson,
|
||||
outputs,
|
||||
logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `,
|
||||
minify: buildOptions.minify,
|
||||
|
||||
@@ -24,6 +24,11 @@ describe('makeRollupConfigs', () => {
|
||||
|
||||
const [config] = await makeRollupConfigs({
|
||||
outputs: new Set([Output.cjs]),
|
||||
packageJson: {
|
||||
name: 'test',
|
||||
version: '0.0.0',
|
||||
main: './src/index.ts',
|
||||
},
|
||||
});
|
||||
const external = config.external as Exclude<
|
||||
ExternalOption,
|
||||
|
||||
@@ -31,6 +31,10 @@ import { forwardFileImports } from './plugins';
|
||||
import { BuildOptions, Output } from './types';
|
||||
import { paths } from '../paths';
|
||||
import { svgrTemplate } from '../svgrTemplate';
|
||||
import { ExtendedPackageJSON } from '../monorepo';
|
||||
import { readEntryPoints } from '../monorepo/entryPoints';
|
||||
|
||||
const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx'];
|
||||
|
||||
function isFileImport(source: string) {
|
||||
if (source.startsWith('.')) {
|
||||
@@ -50,6 +54,13 @@ export async function makeRollupConfigs(
|
||||
): Promise<RollupOptions[]> {
|
||||
const configs = new Array<RollupOptions>();
|
||||
const targetDir = options.targetDir ?? paths.targetDir;
|
||||
|
||||
let targetPkg = options.packageJson;
|
||||
if (!targetPkg) {
|
||||
const packagePath = resolvePath(targetDir, 'package.json');
|
||||
targetPkg = (await fs.readJson(packagePath)) as ExtendedPackageJSON;
|
||||
}
|
||||
|
||||
const onwarn = ({ code, message }: RollupWarning) => {
|
||||
if (code === 'EMPTY_BUNDLE') {
|
||||
return; // We don't care about this one
|
||||
@@ -62,111 +73,118 @@ export async function makeRollupConfigs(
|
||||
};
|
||||
|
||||
const distDir = resolvePath(targetDir, 'dist');
|
||||
const entryPoints = readEntryPoints(targetPkg);
|
||||
|
||||
if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) {
|
||||
const output = new Array<OutputOptions>();
|
||||
const mainFields = ['module', 'main'];
|
||||
|
||||
if (options.outputs.has(Output.cjs)) {
|
||||
output.push({
|
||||
dir: distDir,
|
||||
entryFileNames: 'index.cjs.js',
|
||||
chunkFileNames: 'cjs/[name]-[hash].cjs.js',
|
||||
format: 'commonjs',
|
||||
sourcemap: true,
|
||||
});
|
||||
}
|
||||
if (options.outputs.has(Output.esm)) {
|
||||
output.push({
|
||||
dir: distDir,
|
||||
entryFileNames: 'index.esm.js',
|
||||
chunkFileNames: 'esm/[name]-[hash].esm.js',
|
||||
format: 'module',
|
||||
sourcemap: true,
|
||||
});
|
||||
// Assume we're building for the browser if ESM output is included
|
||||
mainFields.unshift('browser');
|
||||
for (const { path, name, ext } of entryPoints) {
|
||||
if (!SCRIPT_EXTS.includes(ext)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
configs.push({
|
||||
input: resolvePath(targetDir, 'src/index.ts'),
|
||||
output,
|
||||
onwarn,
|
||||
preserveEntrySignatures: 'strict',
|
||||
// All module imports are always marked as external
|
||||
external: (source, importer, isResolved) =>
|
||||
Boolean(importer && !isResolved && !isFileImport(source)),
|
||||
plugins: [
|
||||
resolve({ mainFields }),
|
||||
commonjs({
|
||||
include: /node_modules/,
|
||||
exclude: [/\/[^/]+\.(?:stories|test)\.[^/]+$/],
|
||||
}),
|
||||
postcss(),
|
||||
forwardFileImports({
|
||||
exclude: /\.icon\.svg$/,
|
||||
include: [
|
||||
/\.svg$/,
|
||||
/\.png$/,
|
||||
/\.gif$/,
|
||||
/\.jpg$/,
|
||||
/\.jpeg$/,
|
||||
/\.eot$/,
|
||||
/\.woff$/,
|
||||
/\.woff2$/,
|
||||
/\.ttf$/,
|
||||
],
|
||||
}),
|
||||
json(),
|
||||
yaml(),
|
||||
svgr({
|
||||
include: /\.icon\.svg$/,
|
||||
template: svgrTemplate,
|
||||
}),
|
||||
esbuild({
|
||||
target: 'es2019',
|
||||
minify: options.minify,
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) {
|
||||
const output = new Array<OutputOptions>();
|
||||
const mainFields = ['module', 'main'];
|
||||
|
||||
if (options.outputs.has(Output.types) && !options.useApiExtractor) {
|
||||
const typesInput = paths.resolveTargetRoot(
|
||||
'dist-types',
|
||||
relativePath(paths.targetRoot, targetDir),
|
||||
'src/index.d.ts',
|
||||
);
|
||||
if (options.outputs.has(Output.cjs)) {
|
||||
output.push({
|
||||
dir: distDir,
|
||||
entryFileNames: `${name}.cjs.js`,
|
||||
chunkFileNames: `cjs/${name}/[name]-[hash].cjs.js`,
|
||||
format: 'commonjs',
|
||||
sourcemap: true,
|
||||
});
|
||||
}
|
||||
if (options.outputs.has(Output.esm)) {
|
||||
output.push({
|
||||
dir: distDir,
|
||||
entryFileNames: `${name}.esm.js`,
|
||||
chunkFileNames: `esm/${name}/[name]-[hash].esm.js`,
|
||||
format: 'module',
|
||||
sourcemap: true,
|
||||
});
|
||||
// Assume we're building for the browser if ESM output is included
|
||||
mainFields.unshift('browser');
|
||||
}
|
||||
|
||||
const declarationsExist = await fs.pathExists(typesInput);
|
||||
if (!declarationsExist) {
|
||||
const path = relativePath(targetDir, typesInput);
|
||||
throw new Error(
|
||||
`No declaration files found at ${path}, be sure to run ${chalk.bgRed.white(
|
||||
'yarn tsc',
|
||||
)} to generate .d.ts files before packaging`,
|
||||
configs.push({
|
||||
input: resolvePath(targetDir, path),
|
||||
output,
|
||||
onwarn,
|
||||
preserveEntrySignatures: 'strict',
|
||||
// All module imports are always marked as external
|
||||
external: (source, importer, isResolved) =>
|
||||
Boolean(importer && !isResolved && !isFileImport(source)),
|
||||
plugins: [
|
||||
resolve({ mainFields }),
|
||||
commonjs({
|
||||
include: /node_modules/,
|
||||
exclude: [/\/[^/]+\.(?:stories|test)\.[^/]+$/],
|
||||
}),
|
||||
postcss(),
|
||||
forwardFileImports({
|
||||
exclude: /\.icon\.svg$/,
|
||||
include: [
|
||||
/\.svg$/,
|
||||
/\.png$/,
|
||||
/\.gif$/,
|
||||
/\.jpg$/,
|
||||
/\.jpeg$/,
|
||||
/\.eot$/,
|
||||
/\.woff$/,
|
||||
/\.woff2$/,
|
||||
/\.ttf$/,
|
||||
],
|
||||
}),
|
||||
json(),
|
||||
yaml(),
|
||||
svgr({
|
||||
include: /\.icon\.svg$/,
|
||||
template: svgrTemplate,
|
||||
}),
|
||||
esbuild({
|
||||
target: 'es2019',
|
||||
minify: options.minify,
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (options.outputs.has(Output.types) && !options.useApiExtractor) {
|
||||
const typesInput = paths.resolveTargetRoot(
|
||||
'dist-types',
|
||||
relativePath(paths.targetRoot, targetDir),
|
||||
path.replace(/\.ts$/, '.d.ts'),
|
||||
);
|
||||
}
|
||||
|
||||
configs.push({
|
||||
input: typesInput,
|
||||
output: {
|
||||
file: resolvePath(distDir, 'index.d.ts'),
|
||||
format: 'es',
|
||||
},
|
||||
external: [
|
||||
/\.css$/,
|
||||
/\.scss$/,
|
||||
/\.sass$/,
|
||||
/\.svg$/,
|
||||
/\.eot$/,
|
||||
/\.woff$/,
|
||||
/\.woff2$/,
|
||||
/\.ttf$/,
|
||||
],
|
||||
onwarn,
|
||||
plugins: [dts()],
|
||||
});
|
||||
const declarationsExist = await fs.pathExists(typesInput);
|
||||
if (!declarationsExist) {
|
||||
const declarationPath = relativePath(targetDir, typesInput);
|
||||
throw new Error(
|
||||
`No declaration files found at ${declarationPath}, be sure to run ${chalk.bgRed.white(
|
||||
'yarn tsc',
|
||||
)} to generate .d.ts files before packaging`,
|
||||
);
|
||||
}
|
||||
|
||||
configs.push({
|
||||
input: typesInput,
|
||||
output: {
|
||||
file: resolvePath(distDir, `${name}.d.ts`),
|
||||
format: 'es',
|
||||
},
|
||||
external: [
|
||||
/\.css$/,
|
||||
/\.scss$/,
|
||||
/\.sass$/,
|
||||
/\.svg$/,
|
||||
/\.eot$/,
|
||||
/\.woff$/,
|
||||
/\.woff2$/,
|
||||
/\.ttf$/,
|
||||
],
|
||||
onwarn,
|
||||
plugins: [dts()],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return configs;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ExtendedPackageJSON } from '../monorepo';
|
||||
|
||||
export enum Output {
|
||||
esm,
|
||||
cjs,
|
||||
@@ -23,6 +25,7 @@ export enum Output {
|
||||
export type BuildOptions = {
|
||||
logPrefix?: string;
|
||||
targetDir?: string;
|
||||
packageJson?: ExtendedPackageJSON;
|
||||
outputs: Set<Output>;
|
||||
minify?: boolean;
|
||||
useApiExtractor?: boolean;
|
||||
|
||||
@@ -20,10 +20,15 @@ import { paths } from '../paths';
|
||||
import { PackageRole } from '../role';
|
||||
import { listChangedFiles, readFileAtRef } from '../git';
|
||||
import { Lockfile } from '../versioning';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
|
||||
type PackageJSON = Package['packageJson'];
|
||||
|
||||
export interface ExtendedPackageJSON extends PackageJSON {
|
||||
main?: string;
|
||||
module?: string;
|
||||
types?: string;
|
||||
|
||||
scripts?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
@@ -34,6 +39,19 @@ export interface ExtendedPackageJSON extends PackageJSON {
|
||||
backstage?: {
|
||||
role?: PackageRole;
|
||||
};
|
||||
|
||||
exports?: JsonValue;
|
||||
typesVersions?: Record<string, Record<string, string[]>>;
|
||||
|
||||
files?: string[];
|
||||
|
||||
publishConfig?: {
|
||||
access?: 'public' | 'restricted';
|
||||
directory?: string;
|
||||
registry?: string;
|
||||
alphaTypes?: string;
|
||||
betaTypes?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type ExtendedPackage = {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { extname } from 'path';
|
||||
import { ExtendedPackageJSON } from './PackageGraph';
|
||||
|
||||
export interface EntryPoint {
|
||||
mount: string;
|
||||
path: string;
|
||||
name: string;
|
||||
ext: string;
|
||||
}
|
||||
|
||||
// Unless explicitly specified in exports, the index entrypoint is always
|
||||
// assumed to be at src/index.ts for backwards compatibility.
|
||||
const defaultIndex = {
|
||||
mount: '.',
|
||||
path: 'src/index.ts',
|
||||
name: 'index',
|
||||
ext: '.ts',
|
||||
};
|
||||
|
||||
function parseEntryPoint(mount: string, path: string): EntryPoint {
|
||||
let name = mount;
|
||||
if (name === '.') {
|
||||
name = 'index';
|
||||
} else if (name.startsWith('./')) {
|
||||
name = name.slice(2);
|
||||
}
|
||||
if (name.includes('/')) {
|
||||
throw new Error(`Mount point '${mount}' may not contain multiple slashes`);
|
||||
}
|
||||
|
||||
return { mount, path, name, ext: extname(path) };
|
||||
}
|
||||
|
||||
export function readEntryPoints(pkg: ExtendedPackageJSON): Array<EntryPoint> {
|
||||
const exp = pkg.exports;
|
||||
if (typeof exp === 'string') {
|
||||
return [defaultIndex];
|
||||
} else if (exp && typeof exp === 'object' && !Array.isArray(exp)) {
|
||||
const entryPoints = new Array<{
|
||||
mount: string;
|
||||
path: string;
|
||||
name: string;
|
||||
ext: string;
|
||||
}>();
|
||||
|
||||
for (const mount of Object.keys(exp)) {
|
||||
const path = exp[mount];
|
||||
if (typeof path !== 'string') {
|
||||
throw new Error(
|
||||
`Exports field value must be a string, got '${JSON.stringify(path)}'`,
|
||||
);
|
||||
}
|
||||
|
||||
entryPoints.push(parseEntryPoint(mount, path));
|
||||
}
|
||||
|
||||
return entryPoints;
|
||||
}
|
||||
|
||||
return [defaultIndex];
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 fs from 'fs-extra';
|
||||
import npmPackList from 'npm-packlist';
|
||||
import { join as joinPath, resolve as resolvePath } from 'path';
|
||||
|
||||
const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes'];
|
||||
|
||||
function resolveEntrypoint(pkg: any, name: string) {
|
||||
const targetEntry = pkg.publishConfig[name] || pkg[name];
|
||||
return targetEntry && joinPath('..', targetEntry);
|
||||
}
|
||||
|
||||
// Writes e.g. alpha/package.json
|
||||
async function writeReleaseStageEntrypoint(
|
||||
pkg: any,
|
||||
stage: 'alpha' | 'beta',
|
||||
targetDir: string,
|
||||
) {
|
||||
await fs.ensureDir(resolvePath(targetDir, stage));
|
||||
await fs.writeJson(
|
||||
resolvePath(targetDir, stage, 'package.json'),
|
||||
{
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
main: resolveEntrypoint(pkg, 'main'),
|
||||
module: resolveEntrypoint(pkg, 'module'),
|
||||
browser: resolveEntrypoint(pkg, 'browser'),
|
||||
types: joinPath('..', pkg.publishConfig[`${stage}Types`]),
|
||||
},
|
||||
{ encoding: 'utf8', spaces: 2 },
|
||||
);
|
||||
}
|
||||
|
||||
export async function copyPackageDist(packageDir: string, targetDir: string) {
|
||||
const pkgPath = resolvePath(packageDir, 'package.json');
|
||||
const pkgContent = await fs.readFile(pkgPath, 'utf8');
|
||||
const pkg = JSON.parse(pkgContent);
|
||||
|
||||
const publishConfig = pkg.publishConfig ?? {};
|
||||
for (const key of Object.keys(publishConfig)) {
|
||||
if (!SKIPPED_KEYS.includes(key)) {
|
||||
pkg[key] = publishConfig[key];
|
||||
}
|
||||
}
|
||||
|
||||
// We remove the dependencies from package.json of packages that are marked
|
||||
// as bundled, so that yarn doesn't try to install them.
|
||||
if (pkg.bundled) {
|
||||
delete pkg.dependencies;
|
||||
delete pkg.devDependencies;
|
||||
delete pkg.peerDependencies;
|
||||
delete pkg.optionalDependencies;
|
||||
}
|
||||
|
||||
// Lists all dist files, respecting .npmignore, files field in package.json, etc.
|
||||
const filePaths = await npmPackList({
|
||||
path: packageDir,
|
||||
// This makes sure we use the update package.json when listing files
|
||||
packageJsonCache: new Map([[resolvePath(packageDir, 'package.json'), pkg]]),
|
||||
});
|
||||
|
||||
await fs.ensureDir(targetDir);
|
||||
for (const filePath of filePaths.sort()) {
|
||||
const target = resolvePath(targetDir, filePath);
|
||||
if (filePath === 'package.json') {
|
||||
await fs.writeJson(target, pkg, { encoding: 'utf8', spaces: 2 });
|
||||
} else {
|
||||
await fs.copy(resolvePath(packageDir, filePath), target);
|
||||
}
|
||||
}
|
||||
|
||||
if (publishConfig.alphaTypes) {
|
||||
await writeReleaseStageEntrypoint(pkg, 'alpha', targetDir);
|
||||
}
|
||||
if (publishConfig.betaTypes) {
|
||||
await writeReleaseStageEntrypoint(pkg, 'beta', targetDir);
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
getOutputsForRole,
|
||||
Output,
|
||||
} from '../builder';
|
||||
import { copyPackageDist } from './copyPackageDist';
|
||||
import { productionPack } from './productionPack';
|
||||
import { getRoleInfo } from '../role';
|
||||
import { runParallelWorkers } from '../parallel';
|
||||
|
||||
@@ -178,6 +178,7 @@ export async function createDistWorkspace(
|
||||
if (outputs.size > 0) {
|
||||
standardBuilds.push({
|
||||
targetDir: pkg.dir,
|
||||
packageJson: pkg.packageJson,
|
||||
outputs: outputs,
|
||||
logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `,
|
||||
// No need to detect these for the backend builds, we assume no minification or types
|
||||
@@ -257,7 +258,10 @@ async function moveToDistWorkspace(
|
||||
|
||||
const outputDir = relativePath(paths.targetRoot, target.dir);
|
||||
const absoluteOutputPath = resolvePath(workspaceDir, outputDir);
|
||||
await copyPackageDist(target.dir, absoluteOutputPath);
|
||||
await productionPack({
|
||||
packageDir: target.dir,
|
||||
targetDir: absoluteOutputPath,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import npmPackList from 'npm-packlist';
|
||||
import { join as joinPath, resolve as resolvePath } from 'path';
|
||||
import { ExtendedPackageJSON } from '../monorepo';
|
||||
import { readEntryPoints } from '../monorepo/entryPoints';
|
||||
|
||||
const PKG_PATH = 'package.json';
|
||||
const PKG_BACKUP_PATH = 'package.json-prepack';
|
||||
|
||||
const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes'];
|
||||
const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx'];
|
||||
|
||||
interface ProductionPackOptions {
|
||||
packageDir: string;
|
||||
targetDir?: string;
|
||||
}
|
||||
|
||||
export async function productionPack(options: ProductionPackOptions) {
|
||||
const { packageDir, targetDir } = options;
|
||||
const pkgPath = resolvePath(packageDir, PKG_PATH);
|
||||
const pkgContent = await fs.readFile(pkgPath, 'utf8');
|
||||
const pkg = JSON.parse(pkgContent) as ExtendedPackageJSON;
|
||||
|
||||
// If we're making the update in-line, back up the package.json
|
||||
if (!targetDir) {
|
||||
await fs.writeFile(PKG_BACKUP_PATH, pkgContent);
|
||||
}
|
||||
|
||||
const hasStageEntry =
|
||||
!!pkg.publishConfig?.alphaTypes || !!pkg.publishConfig?.betaTypes;
|
||||
if (pkg.exports && hasStageEntry) {
|
||||
throw new Error(
|
||||
'Combining both exports and alpha/beta types is not supported',
|
||||
);
|
||||
}
|
||||
|
||||
// This mutates pkg to fill in index exports, so call it before applying publishConfig
|
||||
const writeCompatibilityEntryPoints = await prepareExportsEntryPoints(
|
||||
pkg,
|
||||
packageDir,
|
||||
);
|
||||
|
||||
// TODO(Rugvip): Once exports are rolled out more broadly we should deprecate and remove this behavior
|
||||
const publishConfig = pkg.publishConfig ?? {};
|
||||
for (const key of Object.keys(publishConfig)) {
|
||||
if (!SKIPPED_KEYS.includes(key)) {
|
||||
(pkg as any)[key] = publishConfig[key as keyof typeof publishConfig];
|
||||
}
|
||||
}
|
||||
|
||||
// For published packages we rely on compatibility entry points rather than this
|
||||
delete pkg.typesVersions;
|
||||
|
||||
// We remove the dependencies from package.json of packages that are marked
|
||||
// as bundled, so that yarn doesn't try to install them.
|
||||
if (pkg.bundled) {
|
||||
delete pkg.dependencies;
|
||||
delete pkg.devDependencies;
|
||||
delete pkg.peerDependencies;
|
||||
delete pkg.optionalDependencies;
|
||||
}
|
||||
|
||||
if (targetDir) {
|
||||
// Lists all dist files, respecting .npmignore, files field in package.json, etc.
|
||||
const filePaths = await npmPackList({
|
||||
path: packageDir,
|
||||
// This makes sure we use the updated package.json when listing files
|
||||
packageJsonCache: new Map([
|
||||
[resolvePath(packageDir, PKG_PATH), pkg],
|
||||
]) as any, // Seems like this parameter type is wrong,
|
||||
});
|
||||
|
||||
await fs.ensureDir(targetDir);
|
||||
for (const filePath of filePaths.sort()) {
|
||||
const target = resolvePath(targetDir, filePath);
|
||||
if (filePath === PKG_PATH) {
|
||||
await fs.writeJson(target, pkg, { encoding: 'utf8', spaces: 2 });
|
||||
} else {
|
||||
await fs.copy(resolvePath(packageDir, filePath), target);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await fs.writeJson(pkgPath, pkg, { encoding: 'utf8', spaces: 2 });
|
||||
}
|
||||
|
||||
if (publishConfig.alphaTypes) {
|
||||
await writeReleaseStageEntrypoint(pkg, 'alpha', targetDir ?? packageDir);
|
||||
}
|
||||
if (publishConfig.betaTypes) {
|
||||
await writeReleaseStageEntrypoint(pkg, 'beta', targetDir ?? packageDir);
|
||||
}
|
||||
if (writeCompatibilityEntryPoints) {
|
||||
await writeCompatibilityEntryPoints(targetDir ?? packageDir);
|
||||
}
|
||||
}
|
||||
|
||||
// Reverts the changes made by productionPack when called without a targetDir.
|
||||
export async function revertProductionPack(packageDir: string) {
|
||||
// postpack isn't called by yarn right now, so it needs to be called manually
|
||||
try {
|
||||
await fs.move(PKG_BACKUP_PATH, PKG_PATH, { overwrite: true });
|
||||
|
||||
// Check if we're shipping types for other release stages, clean up in that case
|
||||
const pkg = await fs.readJson(PKG_PATH);
|
||||
if (pkg.publishConfig?.alphaTypes) {
|
||||
await fs.remove(resolvePath(packageDir, 'alpha'));
|
||||
}
|
||||
if (pkg.publishConfig?.betaTypes) {
|
||||
await fs.remove(resolvePath(packageDir, 'beta'));
|
||||
}
|
||||
|
||||
// Remove any extra entrypoint backwards compatibility directories
|
||||
const entryPoints = readEntryPoints(pkg);
|
||||
for (const entryPoint of entryPoints) {
|
||||
if (entryPoint.mount !== '.' && SCRIPT_EXTS.includes(entryPoint.ext)) {
|
||||
await fs.remove(resolvePath(packageDir, entryPoint.name));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`Failed to restore package.json, ${error}. ` +
|
||||
'Your package will be fine but you may have ended up with some garbage in the repo.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveEntrypoint(pkg: any, name: string) {
|
||||
const targetEntry = pkg.publishConfig[name] || pkg[name];
|
||||
return targetEntry && joinPath('..', targetEntry);
|
||||
}
|
||||
|
||||
// Writes e.g. alpha/package.json
|
||||
async function writeReleaseStageEntrypoint(
|
||||
pkg: ExtendedPackageJSON,
|
||||
stage: 'alpha' | 'beta',
|
||||
targetDir: string,
|
||||
) {
|
||||
await fs.ensureDir(resolvePath(targetDir, stage));
|
||||
await fs.writeJson(
|
||||
resolvePath(targetDir, stage, PKG_PATH),
|
||||
{
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
main: resolveEntrypoint(pkg, 'main'),
|
||||
module: resolveEntrypoint(pkg, 'module'),
|
||||
browser: resolveEntrypoint(pkg, 'browser'),
|
||||
types: joinPath('..', pkg.publishConfig![`${stage}Types`]!),
|
||||
},
|
||||
{ encoding: 'utf8', spaces: 2 },
|
||||
);
|
||||
}
|
||||
|
||||
const EXPORT_MAP = {
|
||||
import: '.esm.js',
|
||||
require: '.cjs.js',
|
||||
types: '.d.ts',
|
||||
};
|
||||
|
||||
/**
|
||||
* Rewrites the exports field in package.json to point to dist files, as
|
||||
* well as returning a function that creates backwards compatibility
|
||||
* entry points for importers that don't support exports.
|
||||
*/
|
||||
async function prepareExportsEntryPoints(
|
||||
pkg: ExtendedPackageJSON,
|
||||
packageDir: string,
|
||||
) {
|
||||
const distPath = resolvePath(packageDir, 'dist');
|
||||
if (!(await fs.pathExists(distPath))) {
|
||||
return undefined;
|
||||
}
|
||||
const distFiles = await fs.readdir(distPath);
|
||||
const outputExports = {} as Record<string, Record<string, string>>;
|
||||
|
||||
const compatibilityWriters = new Array<
|
||||
(targetDir: string) => Promise<void>
|
||||
>();
|
||||
|
||||
const entryPoints = readEntryPoints(pkg);
|
||||
for (const entryPoint of entryPoints) {
|
||||
if (!SCRIPT_EXTS.includes(entryPoint.ext)) {
|
||||
continue;
|
||||
}
|
||||
const exp = {} as Record<string, string>;
|
||||
for (const [key, ext] of Object.entries(EXPORT_MAP)) {
|
||||
const name = `${entryPoint.name}${ext}`;
|
||||
if (distFiles.includes(name)) {
|
||||
exp[key] = `./${joinPath(`dist`, name)}`;
|
||||
}
|
||||
}
|
||||
exp.default = exp.require ?? exp.import;
|
||||
|
||||
// This creates a directory with a lone package.json for backwards compatibility
|
||||
if (entryPoint.mount === '.') {
|
||||
if (exp.default) {
|
||||
pkg.main = exp.default;
|
||||
}
|
||||
if (exp.import) {
|
||||
pkg.module = exp.import;
|
||||
}
|
||||
if (exp.types) {
|
||||
pkg.types = exp.types;
|
||||
}
|
||||
} else {
|
||||
// This is deferred until after we have created the target directory
|
||||
compatibilityWriters.push(async targetDir => {
|
||||
const entryPointDir = resolvePath(targetDir, entryPoint.name);
|
||||
await fs.ensureDir(entryPointDir);
|
||||
await fs.writeJson(
|
||||
resolvePath(entryPointDir, PKG_PATH),
|
||||
{
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
...(exp.default ? { main: joinPath('..', exp.default) } : {}),
|
||||
...(exp.import ? { module: joinPath('..', exp.import) } : {}),
|
||||
...(exp.types ? { types: joinPath('..', exp.types) } : {}),
|
||||
},
|
||||
{ encoding: 'utf8', spaces: 2 },
|
||||
);
|
||||
});
|
||||
if (Array.isArray(pkg.files) && !pkg.files.includes(entryPoint.name)) {
|
||||
pkg.files.push(entryPoint.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(exp).length > 0) {
|
||||
outputExports[entryPoint.mount] = exp;
|
||||
}
|
||||
}
|
||||
|
||||
if (pkg.exports) {
|
||||
pkg.exports = outputExports;
|
||||
// We treat package.json as a fixed export that is always available in the published package
|
||||
pkg.exports['./package.json'] = './package.json';
|
||||
}
|
||||
|
||||
if (compatibilityWriters.length > 0) {
|
||||
return async (targetDir: string) => {
|
||||
await Promise.all(compatibilityWriters.map(writer => writer(targetDir)));
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
## API Report File for "@backstage/core-plugin-api"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
// @alpha
|
||||
export interface PluginOptionsProviderProps {
|
||||
// (undocumented)
|
||||
children: ReactNode;
|
||||
// (undocumented)
|
||||
plugin?: BackstagePlugin;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export const PluginProvider: (props: PluginOptionsProviderProps) => JSX.Element;
|
||||
|
||||
// @alpha
|
||||
export function usePluginOptions<
|
||||
TPluginOptions extends {} = {},
|
||||
>(): TPluginOptions;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -649,17 +649,6 @@ export type PluginFeatureFlagConfig = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
// @alpha
|
||||
export interface PluginOptionsProviderProps {
|
||||
// (undocumented)
|
||||
children: ReactNode;
|
||||
// (undocumented)
|
||||
plugin?: BackstagePlugin;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export const PluginProvider: (props: PluginOptionsProviderProps) => JSX.Element;
|
||||
|
||||
// @public
|
||||
export type ProfileInfo = {
|
||||
email?: string;
|
||||
@@ -760,11 +749,6 @@ export function useElementFilter<T>(
|
||||
dependencies?: any[],
|
||||
): T;
|
||||
|
||||
// @alpha
|
||||
export function usePluginOptions<
|
||||
TPluginOptions extends {} = {},
|
||||
>(): TPluginOptions;
|
||||
|
||||
// @public
|
||||
export function useRouteRef<Optional extends boolean, Params extends AnyParams>(
|
||||
routeRef: ExternalRouteRef<Params, Optional>,
|
||||
|
||||
@@ -3,10 +3,22 @@
|
||||
"description": "Core API used by Backstage plugins",
|
||||
"version": "1.4.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "web-library"
|
||||
@@ -24,7 +36,7 @@
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -60,7 +72,6 @@
|
||||
"msw": "^0.49.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"alpha"
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './plugin-options';
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
export * from './analytics';
|
||||
export * from './apis';
|
||||
export * from './plugin-options';
|
||||
export * from './app';
|
||||
export * from './extensions';
|
||||
export * from './icons';
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
createVersionedValueMap,
|
||||
useVersionedContext,
|
||||
} from '@backstage/version-bridge';
|
||||
import { BackstagePlugin } from '../plugin';
|
||||
import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
const contextKey: string = 'plugin-context';
|
||||
|
||||
@@ -29,6 +29,7 @@ Options:
|
||||
-a, --allow-warnings <allowWarningsPaths>
|
||||
--allow-all-warnings
|
||||
-o, --omit-messages <messageCodes>
|
||||
--validate-release-tags
|
||||
-h, --help
|
||||
```
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@types/is-glob": "^4.0.2",
|
||||
"@types/mock-fs": "^4.13.0",
|
||||
"mock-fs": "^5.1.0"
|
||||
|
||||
@@ -62,6 +62,7 @@ import { IMarkdownEmitterContext } from '@microsoft/api-documenter/lib/markdown/
|
||||
import { AstDeclaration } from '@microsoft/api-extractor/lib/analyzer/AstDeclaration';
|
||||
import { paths as cliPaths } from '../../lib/paths';
|
||||
import minimatch from 'minimatch';
|
||||
import { getPackageExportNames } from '../../lib/entryPoints';
|
||||
|
||||
const tmpDir = cliPaths.resolveTargetRoot(
|
||||
'./node_modules/.cache/api-extractor',
|
||||
@@ -237,10 +238,9 @@ export async function createTemporaryTsConfig(includedPackageDirs: string[]) {
|
||||
return path;
|
||||
}
|
||||
|
||||
export async function countApiReportWarnings(projectFolder: string) {
|
||||
const path = resolvePath(projectFolder, 'api-report.md');
|
||||
export async function countApiReportWarnings(reportPath: string) {
|
||||
try {
|
||||
const content = await fs.readFile(path, 'utf8');
|
||||
const content = await fs.readFile(reportPath, 'utf8');
|
||||
const lines = content.split('\n');
|
||||
|
||||
const lineWarnings = lines.filter(line =>
|
||||
@@ -300,6 +300,32 @@ function logApiReportInstructions() {
|
||||
console.log('');
|
||||
}
|
||||
|
||||
async function findPackageEntryPoints(packageDirs: string[]): Promise<
|
||||
Array<{
|
||||
packageDir: string;
|
||||
name: string;
|
||||
usesExperimentalTypeBuild?: boolean;
|
||||
}>
|
||||
> {
|
||||
return Promise.all(
|
||||
packageDirs.map(async packageDir => {
|
||||
const pkg = await fs.readJson(
|
||||
cliPaths.resolveTargetRoot(packageDir, 'package.json'),
|
||||
);
|
||||
|
||||
return (
|
||||
getPackageExportNames(pkg)?.map(name => ({ packageDir, name })) ?? {
|
||||
packageDir,
|
||||
name: 'index',
|
||||
usesExperimentalTypeBuild: pkg.scripts?.build?.includes(
|
||||
'--experimental-type-build',
|
||||
),
|
||||
}
|
||||
);
|
||||
}),
|
||||
).then(results => results.flat());
|
||||
}
|
||||
|
||||
interface ApiExtractionOptions {
|
||||
packageDirs: string[];
|
||||
outputDir: string;
|
||||
@@ -307,6 +333,7 @@ interface ApiExtractionOptions {
|
||||
tsconfigFilePath: string;
|
||||
allowWarnings?: boolean | string[];
|
||||
omitMessages?: string[];
|
||||
validateReleaseTags?: boolean;
|
||||
}
|
||||
|
||||
export async function runApiExtraction({
|
||||
@@ -316,12 +343,15 @@ export async function runApiExtraction({
|
||||
tsconfigFilePath,
|
||||
allowWarnings = false,
|
||||
omitMessages = [],
|
||||
validateReleaseTags = false,
|
||||
}: ApiExtractionOptions) {
|
||||
await fs.remove(outputDir);
|
||||
|
||||
const entryPoints = packageDirs.map(packageDir => {
|
||||
const packageEntryPoints = await findPackageEntryPoints(packageDirs);
|
||||
|
||||
const entryPoints = packageEntryPoints.map(({ packageDir, name }) => {
|
||||
return cliPaths.resolveTargetRoot(
|
||||
`./dist-types/${packageDir}/src/index.d.ts`,
|
||||
`./dist-types/${packageDir}/src/${name}.d.ts`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -337,7 +367,11 @@ export async function runApiExtraction({
|
||||
}
|
||||
const warnings = new Array<string>();
|
||||
|
||||
for (const packageDir of packageDirs) {
|
||||
for (const {
|
||||
packageDir,
|
||||
name,
|
||||
usesExperimentalTypeBuild,
|
||||
} of packageEntryPoints) {
|
||||
console.log(`## Processing ${packageDir}`);
|
||||
const noBail = Array.isArray(allowWarnings)
|
||||
? allowWarnings.some(aw => aw === packageDir || minimatch(packageDir, aw))
|
||||
@@ -349,11 +383,15 @@ export async function runApiExtraction({
|
||||
packageDir,
|
||||
);
|
||||
|
||||
const warningCountBefore = await countApiReportWarnings(projectFolder);
|
||||
const prefix = name === 'index' ? '' : `${name}-`;
|
||||
const reportFileName = `${prefix}api-report.md`;
|
||||
const reportPath = resolvePath(projectFolder, reportFileName);
|
||||
|
||||
const warningCountBefore = await countApiReportWarnings(reportPath);
|
||||
|
||||
const extractorConfig = ExtractorConfig.prepare({
|
||||
configObject: {
|
||||
mainEntryPointFilePath: resolvePath(packageFolder, 'src/index.d.ts'),
|
||||
mainEntryPointFilePath: resolvePath(packageFolder, `src/${name}.d.ts`),
|
||||
bundledPackages: [],
|
||||
|
||||
compiler: {
|
||||
@@ -362,16 +400,21 @@ export async function runApiExtraction({
|
||||
|
||||
apiReport: {
|
||||
enabled: true,
|
||||
reportFileName: 'api-report.md',
|
||||
reportFileName,
|
||||
reportFolder: projectFolder,
|
||||
reportTempFolder: resolvePath(outputDir, '<unscopedPackageName>'),
|
||||
reportTempFolder: resolvePath(
|
||||
outputDir,
|
||||
`${prefix}<unscopedPackageName>`,
|
||||
),
|
||||
},
|
||||
|
||||
docModel: {
|
||||
enabled: true,
|
||||
// TODO(Rugvip): This skips docs for non-index entry points. We can try to work around it, but
|
||||
// most likely it makes sense to wait for API Extractor to natively support exports.
|
||||
enabled: name === 'index',
|
||||
apiJsonFilePath: resolvePath(
|
||||
outputDir,
|
||||
'<unscopedPackageName>.api.json',
|
||||
`${prefix}<unscopedPackageName>.api.json`,
|
||||
),
|
||||
},
|
||||
|
||||
@@ -461,6 +504,35 @@ export async function runApiExtraction({
|
||||
compilerState,
|
||||
});
|
||||
|
||||
// This release tag validation makes sure that the release tag of known entry points match expectations.
|
||||
// The root index entrypoint is only allowed @public exports, while /alpha and /beta only allow @alpha and @beta.
|
||||
if (validateReleaseTags && !usesExperimentalTypeBuild) {
|
||||
if (['index', 'alpha', 'beta'].includes(name)) {
|
||||
const report = await fs.readFile(
|
||||
extractorConfig.reportFilePath,
|
||||
'utf8',
|
||||
);
|
||||
const lines = report.split(/\r?\n/);
|
||||
const expectedTag = name === 'index' ? 'public' : name;
|
||||
for (let i = 0; i < lines.length; i += 1) {
|
||||
const line = lines[i];
|
||||
const match = line.match(/^\/\/ @(alpha|beta|public)/);
|
||||
if (match && match[1] !== expectedTag) {
|
||||
// Because of limitations in the type script rollup logic we need to allow public exports from the other release stages
|
||||
// TODO(Rugvip): Try to work around the need for this exception
|
||||
if (expectedTag !== 'public' && match[1] === 'public') {
|
||||
continue;
|
||||
}
|
||||
throw new Error(
|
||||
`Unexpected release tag ${match[1]} in ${
|
||||
extractorConfig.reportFilePath
|
||||
} at line ${i + 1}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!extractorResult.succeeded) {
|
||||
if (shouldLogInstructions) {
|
||||
logApiReportInstructions();
|
||||
@@ -488,7 +560,7 @@ export async function runApiExtraction({
|
||||
);
|
||||
}
|
||||
|
||||
const warningCountAfter = await countApiReportWarnings(projectFolder);
|
||||
const warningCountAfter = await countApiReportWarnings(reportPath);
|
||||
if (noBail) {
|
||||
console.log(`Skipping warnings check for ${packageDir}`);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ type Options = {
|
||||
allowWarnings?: string;
|
||||
allowAllWarnings?: boolean;
|
||||
omitMessages?: string;
|
||||
validateReleaseTags?: boolean;
|
||||
} & OptionValues;
|
||||
|
||||
export const buildApiReports = async (paths: string[] = [], opts: Options) => {
|
||||
@@ -90,6 +91,7 @@ export const buildApiReports = async (paths: string[] = [], opts: Options) => {
|
||||
tsconfigFilePath,
|
||||
allowWarnings: allowAllWarnings || allowWarnings,
|
||||
omitMessages: Array.isArray(omitMessages) ? omitMessages : [],
|
||||
validateReleaseTags: opts.validateReleaseTags,
|
||||
});
|
||||
}
|
||||
if (cliPackageDirs.length > 0) {
|
||||
|
||||
@@ -37,6 +37,10 @@ export function registerCommands(program: Command) {
|
||||
'-o, --omit-messages <messageCodes>',
|
||||
'select some message code to be omited on the API Extractor (comma separated values i.e ae-cyclic-inherit-doc,ae-missing-getter )',
|
||||
)
|
||||
.option(
|
||||
'--validate-release-tags',
|
||||
'Turn on release tag validation for the public, beta, and alpha APIs',
|
||||
)
|
||||
.description('Generate an API report for selected packages')
|
||||
.action(
|
||||
lazy(() =>
|
||||
|
||||
@@ -20,6 +20,7 @@ import { resolve as resolvePath } from 'path';
|
||||
// eslint-disable-next-line @backstage/no-undeclared-imports
|
||||
import chalk from 'chalk';
|
||||
import { getPackages, Package } from '@manypkg/get-packages';
|
||||
import { getPackageExportNames } from '../../lib/entryPoints';
|
||||
|
||||
export default async () => {
|
||||
const { packages } = await getPackages(resolvePath('.'));
|
||||
@@ -96,16 +97,23 @@ function findAllDeps(declSrc: string) {
|
||||
* missing or incorrect in package.json
|
||||
*/
|
||||
function checkTypes(pkg: Package) {
|
||||
const typeDecl = fs.readFileSync(
|
||||
resolvePath(pkg.dir, 'dist/index.d.ts'),
|
||||
'utf8',
|
||||
);
|
||||
const allDeps = findAllDeps(typeDecl);
|
||||
const entryPointNames = getPackageExportNames(pkg.packageJson) ?? ['index'];
|
||||
|
||||
const allDeps = entryPointNames.flatMap(name => {
|
||||
const typeDecl = fs.readFileSync(
|
||||
resolvePath(pkg.dir, `dist/${name}.d.ts`),
|
||||
'utf8',
|
||||
);
|
||||
return findAllDeps(typeDecl);
|
||||
});
|
||||
const deps = Array.from(new Set(allDeps));
|
||||
|
||||
const errors = [];
|
||||
const typeDeps = [];
|
||||
for (const dep of deps) {
|
||||
for (let dep of deps) {
|
||||
if (dep.endsWith('/*')) {
|
||||
dep = dep.slice(0, -2);
|
||||
}
|
||||
try {
|
||||
const typeDep = findTypesPackage(dep, pkg);
|
||||
if (typeDep) {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { extname } from 'path';
|
||||
import type { JsonObject } from '@backstage/types';
|
||||
|
||||
export function getPackageExportNames(pkg: JsonObject): string[] | undefined {
|
||||
if (pkg.exports && typeof pkg.exports !== 'string') {
|
||||
return Object.entries(pkg.exports).flatMap(([mount, path]) => {
|
||||
const ext = extname(String(path));
|
||||
if (!['.ts', '.tsx', '.cts', '.mts'].includes(ext)) {
|
||||
return []; // Ignore non-TS entry points
|
||||
}
|
||||
let name = mount;
|
||||
if (name.startsWith('./')) {
|
||||
name = name.slice(2);
|
||||
}
|
||||
if (!name || name === '.') {
|
||||
return ['index'];
|
||||
}
|
||||
return [name];
|
||||
});
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
## API Report File for "@backstage/test-utils"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
// @alpha
|
||||
export const MockPluginProvider: ({
|
||||
children,
|
||||
}: PropsWithChildren<{}>) => JSX.Element;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -26,7 +26,6 @@ import { JsonValue } from '@backstage/types';
|
||||
import { MatcherFunction } from '@testing-library/react';
|
||||
import { Observable } from '@backstage/types';
|
||||
import { PermissionApi } from '@backstage/plugin-permission-react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { ReactElement } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { RenderOptions } from '@testing-library/react';
|
||||
@@ -167,11 +166,6 @@ export class MockPermissionApi implements PermissionApi {
|
||||
): Promise<EvaluatePermissionResponse>;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export const MockPluginProvider: ({
|
||||
children,
|
||||
}: PropsWithChildren<{}>) => JSX.Element;
|
||||
|
||||
// @public
|
||||
export class MockStorageApi implements StorageApi {
|
||||
// (undocumented)
|
||||
|
||||
@@ -3,10 +3,22 @@
|
||||
"description": "Utilities to test Backstage plugins and apps.",
|
||||
"version": "1.2.5",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "web-library"
|
||||
@@ -24,7 +36,7 @@
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -60,7 +72,6 @@
|
||||
"msw": "^0.49.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"alpha"
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './testUtils/MockPluginProvider';
|
||||
+2
-1
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { createPlugin, PluginProvider } from '@backstage/core-plugin-api';
|
||||
import { PluginProvider } from '@backstage/core-plugin-api/alpha';
|
||||
import { createPlugin } from '@backstage/core-plugin-api';
|
||||
|
||||
/**
|
||||
* Mock for PluginProvider to use in unit tests
|
||||
@@ -25,7 +25,6 @@ export {
|
||||
export type { TestAppOptions } from './appWrappers';
|
||||
export * from './msw';
|
||||
export * from './logCollector';
|
||||
export * from './providers';
|
||||
export * from './testingLibrary';
|
||||
export { TestApiProvider, TestApiRegistry } from './TestApiProvider';
|
||||
export type { TestApiProviderProps } from './TestApiProvider';
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
## API Report File for "@backstage/plugin-app-backend"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import express from 'express';
|
||||
|
||||
// @alpha
|
||||
export const appPlugin: (options: AppPluginOptions) => BackendFeature;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export type AppPluginOptions = {
|
||||
appPackageName?: string;
|
||||
staticFallbackHandler?: express.Handler;
|
||||
disableConfigInjection?: boolean;
|
||||
disableStaticFallbackCache?: boolean;
|
||||
};
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -3,23 +3,11 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import express from 'express';
|
||||
import { Logger } from 'winston';
|
||||
import { PluginDatabaseManager } from '@backstage/backend-common';
|
||||
|
||||
// @alpha
|
||||
export const appPlugin: (options: AppPluginOptions) => BackendFeature;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export type AppPluginOptions = {
|
||||
appPackageName?: string;
|
||||
staticFallbackHandler?: express.Handler;
|
||||
disableConfigInjection?: boolean;
|
||||
disableStaticFallbackCache?: boolean;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export function createRouter(options: RouterOptions): Promise<express.Router>;
|
||||
|
||||
|
||||
@@ -6,10 +6,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"alphaTypes": "dist/index.alpha.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin"
|
||||
@@ -25,7 +37,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -63,7 +75,6 @@
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"alpha",
|
||||
"migrations/**/*.{js,d.ts}",
|
||||
"static"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { appPlugin } from './service/appPlugin';
|
||||
export type { AppPluginOptions } from './service/appPlugin';
|
||||
@@ -21,5 +21,3 @@
|
||||
*/
|
||||
|
||||
export * from './service/router';
|
||||
export { appPlugin } from './service/appPlugin';
|
||||
export type { AppPluginOptions } from './service/appPlugin';
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## API Report File for "@backstage/plugin-catalog-backend-module-aws"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
|
||||
// @alpha
|
||||
export const awsS3EntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -3,7 +3,6 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogProcessor } from '@backstage/plugin-catalog-backend';
|
||||
import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
|
||||
import { CatalogProcessorParser } from '@backstage/plugin-catalog-backend';
|
||||
@@ -88,7 +87,4 @@ export class AwsS3EntityProvider implements EntityProvider {
|
||||
// (undocumented)
|
||||
refresh(logger: Logger): Promise<void>;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export const awsS3EntityProviderCatalogModule: () => BackendFeature;
|
||||
```
|
||||
|
||||
@@ -6,10 +6,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"alphaTypes": "dist/index.alpha.d.ts",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin-module"
|
||||
@@ -25,7 +37,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -60,7 +72,6 @@
|
||||
"yaml": "^2.0.0"
|
||||
},
|
||||
"files": [
|
||||
"alpha",
|
||||
"config.d.ts",
|
||||
"dist"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { awsS3EntityProviderCatalogModule } from './service/AwsS3EntityProviderCatalogModule';
|
||||
@@ -22,5 +22,4 @@
|
||||
|
||||
export * from './processors';
|
||||
export * from './providers';
|
||||
export { awsS3EntityProviderCatalogModule } from './service/AwsS3EntityProviderCatalogModule';
|
||||
export * from './types';
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import {
|
||||
} from '@backstage/backend-tasks';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { Duration } from 'luxon';
|
||||
import { awsS3EntityProviderCatalogModule } from './AwsS3EntityProviderCatalogModule';
|
||||
import { AwsS3EntityProvider } from '../providers';
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
coreServices,
|
||||
createBackendModule,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { AwsS3EntityProvider } from '../providers';
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## API Report File for "@backstage/plugin-catalog-backend-module-azure"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
|
||||
// @alpha
|
||||
export const azureDevOpsEntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -3,7 +3,6 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogProcessor } from '@backstage/plugin-catalog-backend';
|
||||
import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
|
||||
import { Config } from '@backstage/config';
|
||||
@@ -56,7 +55,4 @@ export class AzureDevOpsEntityProvider implements EntityProvider {
|
||||
// (undocumented)
|
||||
refresh(logger: Logger): Promise<void>;
|
||||
}
|
||||
|
||||
// @alpha
|
||||
export const azureDevOpsEntityProviderCatalogModule: () => BackendFeature;
|
||||
```
|
||||
|
||||
@@ -6,10 +6,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"alphaTypes": "dist/index.alpha.d.ts",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin-module"
|
||||
@@ -25,7 +37,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -56,7 +68,6 @@
|
||||
"msw": "^0.49.0"
|
||||
},
|
||||
"files": [
|
||||
"alpha",
|
||||
"config.d.ts",
|
||||
"dist"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { azureDevOpsEntityProviderCatalogModule } from './service/AzureDevOpsEntityProviderCatalogModule';
|
||||
@@ -22,4 +22,3 @@
|
||||
|
||||
export { AzureDevOpsDiscoveryProcessor } from './processors';
|
||||
export { AzureDevOpsEntityProvider } from './providers';
|
||||
export { azureDevOpsEntityProviderCatalogModule } from './service/AzureDevOpsEntityProviderCatalogModule';
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import {
|
||||
} from '@backstage/backend-tasks';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { Duration } from 'luxon';
|
||||
import { azureDevOpsEntityProviderCatalogModule } from './AzureDevOpsEntityProviderCatalogModule';
|
||||
import { AzureDevOpsEntityProvider } from '../providers';
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import {
|
||||
createBackendModule,
|
||||
coreServices,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { AzureDevOpsEntityProvider } from '../providers';
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## API Report File for "@backstage/plugin-catalog-backend-module-bitbucket-cloud"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const bitbucketCloudEntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -3,7 +3,6 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import { EntityProvider } from '@backstage/plugin-catalog-backend';
|
||||
@@ -46,7 +45,4 @@ export class BitbucketCloudEntityProvider
|
||||
// (undocumented)
|
||||
supportsEventTopics(): string[];
|
||||
}
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const bitbucketCloudEntityProviderCatalogModule: () => BackendFeature;
|
||||
```
|
||||
|
||||
@@ -6,10 +6,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"alphaTypes": "dist/index.alpha.d.ts",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin-module"
|
||||
@@ -25,7 +37,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -56,7 +68,6 @@
|
||||
"msw": "^0.49.0"
|
||||
},
|
||||
"files": [
|
||||
"alpha",
|
||||
"config.d.ts",
|
||||
"dist"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { bitbucketCloudEntityProviderCatalogModule } from './service/BitbucketCloudEntityProviderCatalogModule';
|
||||
@@ -21,4 +21,3 @@
|
||||
*/
|
||||
|
||||
export { BitbucketCloudEntityProvider } from './BitbucketCloudEntityProvider';
|
||||
export { bitbucketCloudEntityProviderCatalogModule } from './service/BitbucketCloudEntityProviderCatalogModule';
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@ import {
|
||||
TaskScheduleDefinition,
|
||||
} from '@backstage/backend-tasks';
|
||||
import { startTestBackend, mockServices } from '@backstage/backend-test-utils';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { Duration } from 'luxon';
|
||||
import { bitbucketCloudEntityProviderCatalogModule } from './BitbucketCloudEntityProviderCatalogModule';
|
||||
import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider';
|
||||
|
||||
+2
-2
@@ -22,8 +22,8 @@ import {
|
||||
import {
|
||||
catalogProcessingExtensionPoint,
|
||||
catalogServiceRef,
|
||||
} from '@backstage/plugin-catalog-node';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node';
|
||||
} from '@backstage/plugin-catalog-node/alpha';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider';
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## API Report File for "@backstage/plugin-catalog-backend-module-bitbucket-server"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const bitbucketServerEntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -3,7 +3,6 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { BitbucketServerIntegrationConfig } from '@backstage/integration';
|
||||
import { Config } from '@backstage/config';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
@@ -68,9 +67,6 @@ export class BitbucketServerEntityProvider implements EntityProvider {
|
||||
refresh(logger: Logger): Promise<void>;
|
||||
}
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const bitbucketServerEntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// @public (undocumented)
|
||||
export type BitbucketServerListOptions = {
|
||||
[key: string]: number | undefined;
|
||||
|
||||
@@ -5,10 +5,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"alphaTypes": "dist/index.alpha.d.ts",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin-module"
|
||||
@@ -24,7 +36,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
@@ -53,7 +65,6 @@
|
||||
"msw": "^0.49.0"
|
||||
},
|
||||
"files": [
|
||||
"alpha",
|
||||
"config.d.ts",
|
||||
"dist"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { bitbucketServerEntityProviderCatalogModule } from './service/BitbucketServerEntityProviderCatalogModule';
|
||||
@@ -29,4 +29,3 @@ export type {
|
||||
} from './lib';
|
||||
export { BitbucketServerEntityProvider } from './providers';
|
||||
export type { BitbucketServerLocationParser } from './providers';
|
||||
export { bitbucketServerEntityProviderCatalogModule } from './service/BitbucketServerEntityProviderCatalogModule';
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import {
|
||||
TaskScheduleDefinition,
|
||||
} from '@backstage/backend-tasks';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { bitbucketServerEntityProviderCatalogModule } from './BitbucketServerEntityProviderCatalogModule';
|
||||
import { Duration } from 'luxon';
|
||||
import { BitbucketServerEntityProvider } from '../providers';
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import {
|
||||
coreServices,
|
||||
createBackendModule,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { BitbucketServerEntityProvider } from '../providers';
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## API Report File for "@backstage/plugin-catalog-backend-module-gerrit"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const gerritEntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -3,7 +3,6 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import { EntityProvider } from '@backstage/plugin-catalog-backend';
|
||||
import { EntityProviderConnection } from '@backstage/plugin-catalog-backend';
|
||||
@@ -30,8 +29,5 @@ export class GerritEntityProvider implements EntityProvider {
|
||||
refresh(logger: Logger): Promise<void>;
|
||||
}
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const gerritEntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
|
||||
@@ -5,10 +5,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"alphaTypes": "dist/index.alpha.d.ts",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin-module"
|
||||
@@ -21,7 +33,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build --experimental-type-build",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { gerritEntityProviderCatalogModule } from './service/GerritEntityProviderCatalogModule';
|
||||
@@ -15,4 +15,3 @@
|
||||
*/
|
||||
|
||||
export { GerritEntityProvider } from './providers/GerritEntityProvider';
|
||||
export { gerritEntityProviderCatalogModule } from './service/GerritEntityProviderCatalogModule';
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import {
|
||||
} from '@backstage/backend-tasks';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { Duration } from 'luxon';
|
||||
import { gerritEntityProviderCatalogModule } from './GerritEntityProviderCatalogModule';
|
||||
import { GerritEntityProvider } from '../providers/GerritEntityProvider';
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import {
|
||||
coreServices,
|
||||
createBackendModule,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { GerritEntityProvider } from '../providers/GerritEntityProvider';
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## API Report File for "@backstage/plugin-catalog-backend-module-github"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
|
||||
// @alpha
|
||||
export const githubEntityProviderCatalogModule: () => BackendFeature;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user