@backstage/backend-plugin-api 1.6.1 → 1.7.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/index.d.ts +31 -2
- package/dist/paths.cjs.js +5 -5
- package/dist/paths.cjs.js.map +1 -1
- package/dist/testUtils.cjs.js +3 -3
- package/dist/testUtils.cjs.js.map +1 -1
- package/dist/wiring/createBackendModule.cjs.js +13 -3
- package/dist/wiring/createBackendModule.cjs.js.map +1 -1
- package/dist/wiring/createBackendPlugin.cjs.js +13 -3
- package/dist/wiring/createBackendPlugin.cjs.js.map +1 -1
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @backstage/backend-plugin-api
|
|
2
2
|
|
|
3
|
+
## 1.7.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f1d29b4: Added support for extension point factories. This makes it possible to call `registerExtensionPoint` with a single options argument and provide a factory for the extension point rather than a direct implementation. The factory is passed a context with a `reportModuleStartupFailure` method that makes it possible for plugins to report and attribute startup errors to the module that consumed the extension point.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 7455dae: Use node prefix on native imports
|
|
12
|
+
- 69d880e: Bump to latest zod to ensure it has the latest features
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/cli-common@0.1.18-next.0
|
|
15
|
+
- @backstage/plugin-auth-node@0.6.12-next.0
|
|
16
|
+
- @backstage/plugin-permission-common@0.9.5-next.0
|
|
17
|
+
- @backstage/plugin-permission-node@0.10.9-next.0
|
|
18
|
+
- @backstage/config@1.3.6
|
|
19
|
+
- @backstage/errors@1.2.7
|
|
20
|
+
- @backstage/types@1.2.2
|
|
21
|
+
|
|
3
22
|
## 1.6.1
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Knex } from 'knex';
|
|
|
5
5
|
import { PermissionRule, PermissionResourceRef, PermissionRuleset } from '@backstage/plugin-permission-node';
|
|
6
6
|
import { Config } from '@backstage/config';
|
|
7
7
|
import { Duration } from 'luxon';
|
|
8
|
-
import { Readable } from 'stream';
|
|
8
|
+
import { Readable } from 'node:stream';
|
|
9
9
|
export { isChildPath } from '@backstage/cli-common';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -1907,6 +1907,21 @@ type ExtensionPoint<T> = {
|
|
|
1907
1907
|
toString(): string;
|
|
1908
1908
|
$$type: '@backstage/ExtensionPoint';
|
|
1909
1909
|
};
|
|
1910
|
+
/**
|
|
1911
|
+
* Context provided to extension point factories.
|
|
1912
|
+
*
|
|
1913
|
+
* @public
|
|
1914
|
+
*/
|
|
1915
|
+
interface ExtensionPointFactoryContext {
|
|
1916
|
+
/**
|
|
1917
|
+
* Report a startup failure that happened as part of using an extension that
|
|
1918
|
+
* the module provided. This should be called before the plugin's `init`
|
|
1919
|
+
* function returns.
|
|
1920
|
+
*/
|
|
1921
|
+
reportModuleStartupFailure(options: {
|
|
1922
|
+
error: Error;
|
|
1923
|
+
}): void;
|
|
1924
|
+
}
|
|
1910
1925
|
/** @ignore */
|
|
1911
1926
|
type DepsToInstances<TDeps extends {
|
|
1912
1927
|
[key in string]: ServiceRef<unknown> | ExtensionPoint<unknown>;
|
|
@@ -1919,7 +1934,17 @@ type DepsToInstances<TDeps extends {
|
|
|
1919
1934
|
* @public
|
|
1920
1935
|
*/
|
|
1921
1936
|
interface BackendPluginRegistrationPoints {
|
|
1937
|
+
/**
|
|
1938
|
+
* Registers an implementation for an extension point.
|
|
1939
|
+
*/
|
|
1922
1940
|
registerExtensionPoint<TExtensionPoint>(ref: ExtensionPoint<TExtensionPoint>, impl: TExtensionPoint): void;
|
|
1941
|
+
/**
|
|
1942
|
+
* Registers a factory that produces a separate implementation for an extension point for each module.
|
|
1943
|
+
*/
|
|
1944
|
+
registerExtensionPoint<TExtensionPoint>(options: {
|
|
1945
|
+
extensionPoint: ExtensionPoint<TExtensionPoint>;
|
|
1946
|
+
factory: (context: ExtensionPointFactoryContext) => TExtensionPoint;
|
|
1947
|
+
}): void;
|
|
1923
1948
|
registerInit<TDeps extends {
|
|
1924
1949
|
[name in string]: ServiceRef<unknown>;
|
|
1925
1950
|
}>(options: {
|
|
@@ -1934,6 +1959,10 @@ interface BackendPluginRegistrationPoints {
|
|
|
1934
1959
|
*/
|
|
1935
1960
|
interface BackendModuleRegistrationPoints {
|
|
1936
1961
|
registerExtensionPoint<TExtensionPoint>(ref: ExtensionPoint<TExtensionPoint>, impl: TExtensionPoint): void;
|
|
1962
|
+
registerExtensionPoint<TExtensionPoint>(options: {
|
|
1963
|
+
extensionPoint: ExtensionPoint<TExtensionPoint>;
|
|
1964
|
+
factory: (context: ExtensionPointFactoryContext) => TExtensionPoint;
|
|
1965
|
+
}): void;
|
|
1937
1966
|
registerInit<TDeps extends {
|
|
1938
1967
|
[name in string]: ServiceRef<unknown> | ExtensionPoint<unknown>;
|
|
1939
1968
|
}>(options: {
|
|
@@ -2046,4 +2075,4 @@ declare function createBackendFeatureLoader<TDeps extends {
|
|
|
2046
2075
|
}>(options: CreateBackendFeatureLoaderOptions<TDeps>): BackendFeature;
|
|
2047
2076
|
|
|
2048
2077
|
export { coreServices, createBackendFeatureLoader, createBackendModule, createBackendPlugin, createExtensionPoint, createServiceFactory, createServiceRef, isDatabaseConflictError, readSchedulerServiceTaskScheduleDefinitionFromConfig, resolvePackagePath, resolveSafeChildPath };
|
|
2049
|
-
export type { AuditorService, AuditorServiceCreateEventOptions, AuditorServiceEvent, AuditorServiceEventSeverityLevel, AuthService, BackendFeature, BackendModuleRegistrationPoints, BackendPluginRegistrationPoints, BackstageCredentials, BackstageNonePrincipal, BackstagePrincipalAccessRestrictions, BackstagePrincipalTypes, BackstageServicePrincipal, BackstageUserInfo, BackstageUserPrincipal, CacheService, CacheServiceOptions, CacheServiceSetOptions, CreateBackendFeatureLoaderOptions, CreateBackendModuleOptions, CreateBackendPluginOptions, CreateExtensionPointOptions, DatabaseService, DiscoveryService, ExtensionPoint, HttpAuthService, HttpRouterService, HttpRouterServiceAuthPolicy, LifecycleService, LifecycleServiceShutdownHook, LifecycleServiceShutdownOptions, LifecycleServiceStartupHook, LifecycleServiceStartupOptions, LoggerService, PermissionsRegistryService, PermissionsRegistryServiceAddResourceTypeOptions, PermissionsService, PermissionsServiceRequestOptions, PluginMetadataService, PluginServiceFactoryOptions, RootConfigService, RootHealthService, RootHttpRouterService, RootInstanceMetadataService, RootInstanceMetadataServicePluginInfo, RootLifecycleService, RootLoggerService, RootServiceFactoryOptions, SchedulerService, SchedulerServiceTaskDescriptor, SchedulerServiceTaskFunction, SchedulerServiceTaskInvocationDefinition, SchedulerServiceTaskRunner, SchedulerServiceTaskScheduleDefinition, SchedulerServiceTaskScheduleDefinitionConfig, ServiceFactory, ServiceRef, ServiceRefOptions, UrlReaderService, UrlReaderServiceReadTreeOptions, UrlReaderServiceReadTreeResponse, UrlReaderServiceReadTreeResponseDirOptions, UrlReaderServiceReadTreeResponseFile, UrlReaderServiceReadUrlOptions, UrlReaderServiceReadUrlResponse, UrlReaderServiceSearchOptions, UrlReaderServiceSearchResponse, UrlReaderServiceSearchResponseFile, UserInfoService };
|
|
2078
|
+
export type { AuditorService, AuditorServiceCreateEventOptions, AuditorServiceEvent, AuditorServiceEventSeverityLevel, AuthService, BackendFeature, BackendModuleRegistrationPoints, BackendPluginRegistrationPoints, BackstageCredentials, BackstageNonePrincipal, BackstagePrincipalAccessRestrictions, BackstagePrincipalTypes, BackstageServicePrincipal, BackstageUserInfo, BackstageUserPrincipal, CacheService, CacheServiceOptions, CacheServiceSetOptions, CreateBackendFeatureLoaderOptions, CreateBackendModuleOptions, CreateBackendPluginOptions, CreateExtensionPointOptions, DatabaseService, DiscoveryService, ExtensionPoint, ExtensionPointFactoryContext, HttpAuthService, HttpRouterService, HttpRouterServiceAuthPolicy, LifecycleService, LifecycleServiceShutdownHook, LifecycleServiceShutdownOptions, LifecycleServiceStartupHook, LifecycleServiceStartupOptions, LoggerService, PermissionsRegistryService, PermissionsRegistryServiceAddResourceTypeOptions, PermissionsService, PermissionsServiceRequestOptions, PluginMetadataService, PluginServiceFactoryOptions, RootConfigService, RootHealthService, RootHttpRouterService, RootInstanceMetadataService, RootInstanceMetadataServicePluginInfo, RootLifecycleService, RootLoggerService, RootServiceFactoryOptions, SchedulerService, SchedulerServiceTaskDescriptor, SchedulerServiceTaskFunction, SchedulerServiceTaskInvocationDefinition, SchedulerServiceTaskRunner, SchedulerServiceTaskScheduleDefinition, SchedulerServiceTaskScheduleDefinitionConfig, ServiceFactory, ServiceRef, ServiceRefOptions, UrlReaderService, UrlReaderServiceReadTreeOptions, UrlReaderServiceReadTreeResponse, UrlReaderServiceReadTreeResponseDirOptions, UrlReaderServiceReadTreeResponseFile, UrlReaderServiceReadUrlOptions, UrlReaderServiceReadUrlResponse, UrlReaderServiceSearchOptions, UrlReaderServiceSearchResponse, UrlReaderServiceSearchResponseFile, UserInfoService };
|
package/dist/paths.cjs.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var cliCommon = require('@backstage/cli-common');
|
|
4
4
|
var errors = require('@backstage/errors');
|
|
5
|
-
var
|
|
5
|
+
var node_path = require('node:path');
|
|
6
6
|
|
|
7
7
|
const packagePathMocks = /* @__PURE__ */ new Map();
|
|
8
8
|
function resolvePackagePath(name, ...paths) {
|
|
@@ -14,16 +14,16 @@ function resolvePackagePath(name, ...paths) {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
const req = typeof __non_webpack_require__ === "undefined" ? require : __non_webpack_require__;
|
|
17
|
-
return
|
|
17
|
+
return node_path.resolve(req.resolve(`${name}/package.json`), "..", ...paths);
|
|
18
18
|
}
|
|
19
|
-
function resolveSafeChildPath(base, path
|
|
20
|
-
const targetPath =
|
|
19
|
+
function resolveSafeChildPath(base, path) {
|
|
20
|
+
const targetPath = node_path.resolve(base, path);
|
|
21
21
|
if (!cliCommon.isChildPath(base, targetPath)) {
|
|
22
22
|
throw new errors.NotAllowedError(
|
|
23
23
|
"Relative path is not allowed to refer to a directory outside its parent"
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
|
-
return
|
|
26
|
+
return node_path.resolve(base, path);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
Object.defineProperty(exports, "isChildPath", {
|
package/dist/paths.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.cjs.js","sources":["../src/paths.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { isChildPath } from '@backstage/cli-common';\nimport { NotAllowedError } from '@backstage/errors';\nimport { resolve as resolvePath } from 'path';\n\n/** @internal */\nexport const packagePathMocks = new Map<\n string,\n (paths: string[]) => string | undefined\n>();\n\n/**\n * Resolve a path relative to the root of a package directory.\n * Additional path arguments are resolved relative to the package dir.\n *\n * This is particularly useful when you want to access assets shipped with\n * your backend plugin package. When doing so, do not forget to include the assets\n * in your published package by adding them to `files` in your `package.json`.\n *\n * @public\n */\nexport function resolvePackagePath(name: string, ...paths: string[]) {\n const mockedResolve = packagePathMocks.get(name);\n if (mockedResolve) {\n const resolved = mockedResolve(paths);\n if (resolved) {\n return resolved;\n }\n }\n\n const req =\n typeof __non_webpack_require__ === 'undefined'\n ? require\n : __non_webpack_require__;\n\n return resolvePath(req.resolve(`${name}/package.json`), '..', ...paths);\n}\n\n/**\n * Resolves a target path from a base path while guaranteeing that the result is\n * a path that point to or within the base path. This is useful for resolving\n * paths from user input, as it otherwise opens up for vulnerabilities.\n *\n * @public\n * @param base - The base directory to resolve the path from.\n * @param path - The target path, relative or absolute\n * @returns A path that is guaranteed to point to or within the base path.\n */\nexport function resolveSafeChildPath(base: string, path: string): string {\n const targetPath = resolvePath(base, path);\n\n if (!isChildPath(base, targetPath)) {\n throw new NotAllowedError(\n 'Relative path is not allowed to refer to a directory outside its parent',\n );\n }\n\n // Don't return the resolved path as the original could be a symlink\n return resolvePath(base, path);\n}\n\n// Re-export isChildPath so that backend packages don't need to depend on cli-common\nexport { isChildPath };\n"],"names":["resolvePath","
|
|
1
|
+
{"version":3,"file":"paths.cjs.js","sources":["../src/paths.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { isChildPath } from '@backstage/cli-common';\nimport { NotAllowedError } from '@backstage/errors';\nimport { resolve as resolvePath } from 'node:path';\n\n/** @internal */\nexport const packagePathMocks = new Map<\n string,\n (paths: string[]) => string | undefined\n>();\n\n/**\n * Resolve a path relative to the root of a package directory.\n * Additional path arguments are resolved relative to the package dir.\n *\n * This is particularly useful when you want to access assets shipped with\n * your backend plugin package. When doing so, do not forget to include the assets\n * in your published package by adding them to `files` in your `package.json`.\n *\n * @public\n */\nexport function resolvePackagePath(name: string, ...paths: string[]) {\n const mockedResolve = packagePathMocks.get(name);\n if (mockedResolve) {\n const resolved = mockedResolve(paths);\n if (resolved) {\n return resolved;\n }\n }\n\n const req =\n typeof __non_webpack_require__ === 'undefined'\n ? require\n : __non_webpack_require__;\n\n return resolvePath(req.resolve(`${name}/package.json`), '..', ...paths);\n}\n\n/**\n * Resolves a target path from a base path while guaranteeing that the result is\n * a path that point to or within the base path. This is useful for resolving\n * paths from user input, as it otherwise opens up for vulnerabilities.\n *\n * @public\n * @param base - The base directory to resolve the path from.\n * @param path - The target path, relative or absolute\n * @returns A path that is guaranteed to point to or within the base path.\n */\nexport function resolveSafeChildPath(base: string, path: string): string {\n const targetPath = resolvePath(base, path);\n\n if (!isChildPath(base, targetPath)) {\n throw new NotAllowedError(\n 'Relative path is not allowed to refer to a directory outside its parent',\n );\n }\n\n // Don't return the resolved path as the original could be a symlink\n return resolvePath(base, path);\n}\n\n// Re-export isChildPath so that backend packages don't need to depend on cli-common\nexport { isChildPath };\n"],"names":["resolvePath","isChildPath","NotAllowedError"],"mappings":";;;;;;AAqBO,MAAM,gBAAA,uBAAuB,GAAA;AAe7B,SAAS,kBAAA,CAAmB,SAAiB,KAAA,EAAiB;AACnE,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA;AAC/C,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,MAAM,QAAA,GAAW,cAAc,KAAK,CAAA;AACpC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,MAAM,GAAA,GACJ,OAAO,uBAAA,KAA4B,WAAA,GAC/B,OAAA,GACA,uBAAA;AAEN,EAAA,OAAOA,iBAAA,CAAY,IAAI,OAAA,CAAQ,CAAA,EAAG,IAAI,CAAA,aAAA,CAAe,CAAA,EAAG,IAAA,EAAM,GAAG,KAAK,CAAA;AACxE;AAYO,SAAS,oBAAA,CAAqB,MAAc,IAAA,EAAsB;AACvE,EAAA,MAAM,UAAA,GAAaA,iBAAA,CAAY,IAAA,EAAM,IAAI,CAAA;AAEzC,EAAA,IAAI,CAACC,qBAAA,CAAY,IAAA,EAAM,UAAU,CAAA,EAAG;AAClC,IAAA,MAAM,IAAIC,sBAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAGA,EAAA,OAAOF,iBAAA,CAAY,MAAM,IAAI,CAAA;AAC/B;;;;;;;;;;"}
|
package/dist/testUtils.cjs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var paths = require('./paths.cjs.js');
|
|
4
|
-
var
|
|
4
|
+
var node_path = require('node:path');
|
|
5
5
|
|
|
6
6
|
function overridePackagePathResolution(options) {
|
|
7
7
|
const name = options.packageName;
|
|
@@ -11,13 +11,13 @@ function overridePackagePathResolution(options) {
|
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
paths.packagePathMocks.set(name, (paths) => {
|
|
14
|
-
const joinedPath =
|
|
14
|
+
const joinedPath = node_path.posix.join(...paths);
|
|
15
15
|
const localResolver = options.paths?.[joinedPath];
|
|
16
16
|
if (localResolver) {
|
|
17
17
|
return typeof localResolver === "function" ? localResolver() : localResolver;
|
|
18
18
|
}
|
|
19
19
|
if (options.path) {
|
|
20
|
-
return
|
|
20
|
+
return node_path.resolve(options.path, ...paths);
|
|
21
21
|
}
|
|
22
22
|
return void 0;
|
|
23
23
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testUtils.cjs.js","sources":["../src/testUtils.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { packagePathMocks } from './paths';\nimport { posix as posixPath, resolve as resolvePath } from 'path';\n\n/** @public */\nexport interface PackagePathResolutionOverride {\n /** Restores the normal behavior of resolvePackagePath */\n restore(): void;\n}\n\n/** @public */\nexport interface OverridePackagePathResolutionOptions {\n /** The name of the package to mock the resolved path of */\n packageName: string;\n\n /** A replacement for the root package path */\n path?: string;\n\n /**\n * Replacements for package sub-paths, each key must be an exact match of the posix-style path\n * that is being resolved within the package.\n *\n * For example, code calling `resolvePackagePath('x', 'foo', 'bar')` would match only the following\n * configuration: `overridePackagePathResolution({ packageName: 'x', paths: { 'foo/bar': baz } })`\n */\n paths?: { [path in string]: string | (() => string) };\n}\n\n/**\n * This utility helps you override the paths returned by `resolvePackagePath` for a given package.\n *\n * @public\n */\nexport function overridePackagePathResolution(\n options: OverridePackagePathResolutionOptions,\n): PackagePathResolutionOverride {\n const name = options.packageName;\n\n if (packagePathMocks.has(name)) {\n throw new Error(\n `Tried to override resolution for '${name}' more than once for package '${name}'`,\n );\n }\n\n packagePathMocks.set(name, paths => {\n const joinedPath = posixPath.join(...paths);\n const localResolver = options.paths?.[joinedPath];\n if (localResolver) {\n return typeof localResolver === 'function'\n ? localResolver()\n : localResolver;\n }\n if (options.path) {\n return resolvePath(options.path, ...paths);\n }\n return undefined;\n });\n\n return {\n restore() {\n packagePathMocks.delete(name);\n },\n };\n}\n"],"names":["packagePathMocks","posixPath","resolvePath"],"mappings":";;;;;AAgDO,SAAS,8BACd,OAAA,EAC+B;AAC/B,EAAA,MAAM,OAAO,OAAA,CAAQ,WAAA;AAErB,EAAA,IAAIA,sBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,kCAAA,EAAqC,IAAI,CAAA,8BAAA,EAAiC,IAAI,CAAA,CAAA;AAAA,KAChF;AAAA,EACF;AAEA,EAAAA,sBAAA,CAAiB,GAAA,CAAI,MAAM,CAAA,KAAA,KAAS;AAClC,IAAA,MAAM,UAAA,GAAaC,
|
|
1
|
+
{"version":3,"file":"testUtils.cjs.js","sources":["../src/testUtils.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { packagePathMocks } from './paths';\nimport { posix as posixPath, resolve as resolvePath } from 'node:path';\n\n/** @public */\nexport interface PackagePathResolutionOverride {\n /** Restores the normal behavior of resolvePackagePath */\n restore(): void;\n}\n\n/** @public */\nexport interface OverridePackagePathResolutionOptions {\n /** The name of the package to mock the resolved path of */\n packageName: string;\n\n /** A replacement for the root package path */\n path?: string;\n\n /**\n * Replacements for package sub-paths, each key must be an exact match of the posix-style path\n * that is being resolved within the package.\n *\n * For example, code calling `resolvePackagePath('x', 'foo', 'bar')` would match only the following\n * configuration: `overridePackagePathResolution({ packageName: 'x', paths: { 'foo/bar': baz } })`\n */\n paths?: { [path in string]: string | (() => string) };\n}\n\n/**\n * This utility helps you override the paths returned by `resolvePackagePath` for a given package.\n *\n * @public\n */\nexport function overridePackagePathResolution(\n options: OverridePackagePathResolutionOptions,\n): PackagePathResolutionOverride {\n const name = options.packageName;\n\n if (packagePathMocks.has(name)) {\n throw new Error(\n `Tried to override resolution for '${name}' more than once for package '${name}'`,\n );\n }\n\n packagePathMocks.set(name, paths => {\n const joinedPath = posixPath.join(...paths);\n const localResolver = options.paths?.[joinedPath];\n if (localResolver) {\n return typeof localResolver === 'function'\n ? localResolver()\n : localResolver;\n }\n if (options.path) {\n return resolvePath(options.path, ...paths);\n }\n return undefined;\n });\n\n return {\n restore() {\n packagePathMocks.delete(name);\n },\n };\n}\n"],"names":["packagePathMocks","posixPath","resolvePath"],"mappings":";;;;;AAgDO,SAAS,8BACd,OAAA,EAC+B;AAC/B,EAAA,MAAM,OAAO,OAAA,CAAQ,WAAA;AAErB,EAAA,IAAIA,sBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,kCAAA,EAAqC,IAAI,CAAA,8BAAA,EAAiC,IAAI,CAAA,CAAA;AAAA,KAChF;AAAA,EACF;AAEA,EAAAA,sBAAA,CAAiB,GAAA,CAAI,MAAM,CAAA,KAAA,KAAS;AAClC,IAAA,MAAM,UAAA,GAAaC,eAAA,CAAU,IAAA,CAAK,GAAG,KAAK,CAAA;AAC1C,IAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,KAAA,GAAQ,UAAU,CAAA;AAChD,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,OAAO,OAAO,aAAA,KAAkB,UAAA,GAC5B,aAAA,EAAc,GACd,aAAA;AAAA,IACN;AACA,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,OAAOC,iBAAA,CAAY,OAAA,CAAQ,IAAA,EAAM,GAAG,KAAK,CAAA;AAAA,IAC3C;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,OAAA,GAAU;AACR,MAAAF,sBAAA,CAAiB,OAAO,IAAI,CAAA;AAAA,IAC9B;AAAA,GACF;AACF;;;;"}
|
|
@@ -5,11 +5,21 @@ function createBackendModule(options) {
|
|
|
5
5
|
const extensionPoints = [];
|
|
6
6
|
let init = void 0;
|
|
7
7
|
options.register({
|
|
8
|
-
registerExtensionPoint(
|
|
8
|
+
registerExtensionPoint(extOrOpts, impl) {
|
|
9
9
|
if (init) {
|
|
10
10
|
throw new Error("registerExtensionPoint called after registerInit");
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
if (typeof extOrOpts === "object" && extOrOpts !== null && "extensionPoint" in extOrOpts) {
|
|
13
|
+
extensionPoints.push({
|
|
14
|
+
extensionPoint: extOrOpts.extensionPoint,
|
|
15
|
+
factory: extOrOpts.factory
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
extensionPoints.push({
|
|
19
|
+
extensionPoint: extOrOpts,
|
|
20
|
+
factory: () => impl
|
|
21
|
+
});
|
|
22
|
+
}
|
|
13
23
|
},
|
|
14
24
|
registerInit(regInit) {
|
|
15
25
|
if (init) {
|
|
@@ -28,7 +38,7 @@ function createBackendModule(options) {
|
|
|
28
38
|
}
|
|
29
39
|
return [
|
|
30
40
|
{
|
|
31
|
-
type: "module",
|
|
41
|
+
type: "module-v1.1",
|
|
32
42
|
pluginId: options.pluginId,
|
|
33
43
|
moduleId: options.moduleId,
|
|
34
44
|
extensionPoints,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBackendModule.cjs.js","sources":["../../src/wiring/createBackendModule.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature } from '../types';\nimport {\n BackendModuleRegistrationPoints,\n
|
|
1
|
+
{"version":3,"file":"createBackendModule.cjs.js","sources":["../../src/wiring/createBackendModule.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature } from '../types';\nimport {\n BackendModuleRegistrationPoints,\n ExtensionPoint,\n ExtensionPointFactoryContext,\n InternalBackendModuleRegistrationV1_1,\n InternalBackendRegistrations,\n} from './types';\n\n/**\n * The configuration options passed to {@link createBackendModule}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateBackendModuleOptions {\n /**\n * Should exactly match the `id` of the plugin that the module extends.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n pluginId: string;\n\n /**\n * The ID of this module, used to identify the module and ensure that it is not installed twice.\n */\n moduleId: string;\n register(reg: BackendModuleRegistrationPoints): void;\n}\n\n/**\n * Creates a new backend module for a given plugin.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport function createBackendModule(\n options: CreateBackendModuleOptions,\n): BackendFeature {\n function getRegistrations() {\n const extensionPoints: InternalBackendModuleRegistrationV1_1['extensionPoints'] =\n [];\n let init: InternalBackendModuleRegistrationV1_1['init'] | undefined =\n undefined;\n\n options.register({\n registerExtensionPoint<TExtensionPoint>(\n extOrOpts:\n | ExtensionPoint<TExtensionPoint>\n | {\n extensionPoint: ExtensionPoint<TExtensionPoint>;\n factory: (\n context: ExtensionPointFactoryContext,\n ) => TExtensionPoint;\n },\n impl?: TExtensionPoint,\n ) {\n if (init) {\n throw new Error('registerExtensionPoint called after registerInit');\n }\n if (\n typeof extOrOpts === 'object' &&\n extOrOpts !== null &&\n 'extensionPoint' in extOrOpts\n ) {\n extensionPoints.push({\n extensionPoint: extOrOpts.extensionPoint,\n factory: extOrOpts.factory as (\n context: ExtensionPointFactoryContext,\n ) => unknown,\n });\n } else {\n extensionPoints.push({\n extensionPoint: extOrOpts,\n factory: () => impl,\n });\n }\n },\n registerInit(regInit) {\n if (init) {\n throw new Error('registerInit must only be called once');\n }\n init = {\n deps: regInit.deps,\n func: regInit.init,\n };\n },\n });\n\n if (!init) {\n throw new Error(\n `registerInit was not called by register in ${options.moduleId} module for ${options.pluginId}`,\n );\n }\n\n return [\n {\n type: 'module-v1.1',\n pluginId: options.pluginId,\n moduleId: options.moduleId,\n extensionPoints,\n init,\n },\n ];\n }\n\n return {\n $$type: '@backstage/BackendFeature' as const,\n featureType: 'registrations',\n version: 'v1',\n getRegistrations,\n } as InternalBackendRegistrations;\n}\n"],"names":[],"mappings":";;AAsDO,SAAS,oBACd,OAAA,EACgB;AAChB,EAAA,SAAS,gBAAA,GAAmB;AAC1B,IAAA,MAAM,kBACJ,EAAC;AACH,IAAA,IAAI,IAAA,GACF,MAAA;AAEF,IAAA,OAAA,CAAQ,QAAA,CAAS;AAAA,MACf,sBAAA,CACE,WAQA,IAAA,EACA;AACA,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,QACpE;AACA,QAAA,IACE,OAAO,SAAA,KAAc,QAAA,IACrB,SAAA,KAAc,IAAA,IACd,oBAAoB,SAAA,EACpB;AACA,UAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,YACnB,gBAAgB,SAAA,CAAU,cAAA;AAAA,YAC1B,SAAS,SAAA,CAAU;AAAA,WAGpB,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,YACnB,cAAA,EAAgB,SAAA;AAAA,YAChB,SAAS,MAAM;AAAA,WAChB,CAAA;AAAA,QACH;AAAA,MACF,CAAA;AAAA,MACA,aAAa,OAAA,EAAS;AACpB,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,QACzD;AACA,QAAA,IAAA,GAAO;AAAA,UACL,MAAM,OAAA,CAAQ,IAAA;AAAA,UACd,MAAM,OAAA,CAAQ;AAAA,SAChB;AAAA,MACF;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,2CAAA,EAA8C,OAAA,CAAQ,QAAQ,CAAA,YAAA,EAAe,QAAQ,QAAQ,CAAA;AAAA,OAC/F;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,aAAA;AAAA,QACN,UAAU,OAAA,CAAQ,QAAA;AAAA,QAClB,UAAU,OAAA,CAAQ,QAAA;AAAA,QAClB,eAAA;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,2BAAA;AAAA,IACR,WAAA,EAAa,eAAA;AAAA,IACb,OAAA,EAAS,IAAA;AAAA,IACT;AAAA,GACF;AACF;;;;"}
|
|
@@ -5,11 +5,21 @@ function createBackendPlugin(options) {
|
|
|
5
5
|
const extensionPoints = [];
|
|
6
6
|
let init = void 0;
|
|
7
7
|
options.register({
|
|
8
|
-
registerExtensionPoint(
|
|
8
|
+
registerExtensionPoint(extOrOpts, impl) {
|
|
9
9
|
if (init) {
|
|
10
10
|
throw new Error("registerExtensionPoint called after registerInit");
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
if (typeof extOrOpts === "object" && extOrOpts !== null && "extensionPoint" in extOrOpts) {
|
|
13
|
+
extensionPoints.push({
|
|
14
|
+
extensionPoint: extOrOpts.extensionPoint,
|
|
15
|
+
factory: extOrOpts.factory
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
extensionPoints.push({
|
|
19
|
+
extensionPoint: extOrOpts,
|
|
20
|
+
factory: () => impl
|
|
21
|
+
});
|
|
22
|
+
}
|
|
13
23
|
},
|
|
14
24
|
registerInit(regInit) {
|
|
15
25
|
if (init) {
|
|
@@ -28,7 +38,7 @@ function createBackendPlugin(options) {
|
|
|
28
38
|
}
|
|
29
39
|
return [
|
|
30
40
|
{
|
|
31
|
-
type: "plugin",
|
|
41
|
+
type: "plugin-v1.1",
|
|
32
42
|
pluginId: options.pluginId,
|
|
33
43
|
extensionPoints,
|
|
34
44
|
init
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBackendPlugin.cjs.js","sources":["../../src/wiring/createBackendPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature } from '../types';\nimport {\n BackendPluginRegistrationPoints,\n
|
|
1
|
+
{"version":3,"file":"createBackendPlugin.cjs.js","sources":["../../src/wiring/createBackendPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature } from '../types';\nimport {\n BackendPluginRegistrationPoints,\n ExtensionPoint,\n ExtensionPointFactoryContext,\n InternalBackendPluginRegistrationV1_1,\n InternalBackendRegistrations,\n} from './types';\n\n/**\n * The configuration options passed to {@link createBackendPlugin}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateBackendPluginOptions {\n /**\n * The ID of this plugin.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n pluginId: string;\n register(reg: BackendPluginRegistrationPoints): void;\n}\n\n/**\n * Creates a new backend plugin.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport function createBackendPlugin(\n options: CreateBackendPluginOptions,\n): BackendFeature {\n function getRegistrations() {\n const extensionPoints: InternalBackendPluginRegistrationV1_1['extensionPoints'] =\n [];\n let init: InternalBackendPluginRegistrationV1_1['init'] | undefined =\n undefined;\n\n options.register({\n registerExtensionPoint<TExtensionPoint>(\n extOrOpts:\n | ExtensionPoint<TExtensionPoint>\n | {\n extensionPoint: ExtensionPoint<TExtensionPoint>;\n factory: (\n context: ExtensionPointFactoryContext,\n ) => TExtensionPoint;\n },\n impl?: TExtensionPoint,\n ) {\n if (init) {\n throw new Error('registerExtensionPoint called after registerInit');\n }\n if (\n typeof extOrOpts === 'object' &&\n extOrOpts !== null &&\n 'extensionPoint' in extOrOpts\n ) {\n extensionPoints.push({\n extensionPoint: extOrOpts.extensionPoint,\n factory: extOrOpts.factory as (\n context: ExtensionPointFactoryContext,\n ) => unknown,\n });\n } else {\n extensionPoints.push({\n extensionPoint: extOrOpts,\n factory: () => impl,\n });\n }\n },\n registerInit(regInit) {\n if (init) {\n throw new Error('registerInit must only be called once');\n }\n init = {\n deps: regInit.deps,\n func: regInit.init,\n };\n },\n });\n\n if (!init) {\n throw new Error(\n `registerInit was not called by register in ${options.pluginId}`,\n );\n }\n\n return [\n {\n type: 'plugin-v1.1',\n pluginId: options.pluginId,\n extensionPoints,\n init,\n },\n ];\n }\n\n return {\n $$type: '@backstage/BackendFeature' as const,\n version: 'v1',\n featureType: 'registrations',\n getRegistrations,\n } as InternalBackendRegistrations;\n}\n"],"names":[],"mappings":";;AAiDO,SAAS,oBACd,OAAA,EACgB;AAChB,EAAA,SAAS,gBAAA,GAAmB;AAC1B,IAAA,MAAM,kBACJ,EAAC;AACH,IAAA,IAAI,IAAA,GACF,MAAA;AAEF,IAAA,OAAA,CAAQ,QAAA,CAAS;AAAA,MACf,sBAAA,CACE,WAQA,IAAA,EACA;AACA,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,QACpE;AACA,QAAA,IACE,OAAO,SAAA,KAAc,QAAA,IACrB,SAAA,KAAc,IAAA,IACd,oBAAoB,SAAA,EACpB;AACA,UAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,YACnB,gBAAgB,SAAA,CAAU,cAAA;AAAA,YAC1B,SAAS,SAAA,CAAU;AAAA,WAGpB,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,YACnB,cAAA,EAAgB,SAAA;AAAA,YAChB,SAAS,MAAM;AAAA,WAChB,CAAA;AAAA,QACH;AAAA,MACF,CAAA;AAAA,MACA,aAAa,OAAA,EAAS;AACpB,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,QACzD;AACA,QAAA,IAAA,GAAO;AAAA,UACL,MAAM,OAAA,CAAQ,IAAA;AAAA,UACd,MAAM,OAAA,CAAQ;AAAA,SAChB;AAAA,MACF;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,2CAAA,EAA8C,QAAQ,QAAQ,CAAA;AAAA,OAChE;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,aAAA;AAAA,QACN,UAAU,OAAA,CAAQ,QAAA;AAAA,QAClB,eAAA;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,2BAAA;AAAA,IACR,OAAA,EAAS,IAAA;AAAA,IACT,WAAA,EAAa,eAAA;AAAA,IACb;AAAA,GACF;AACF;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-plugin-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0-next.0",
|
|
4
4
|
"description": "Core API used by Backstage backend plugins",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -65,24 +65,24 @@
|
|
|
65
65
|
"test": "backstage-cli package test"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@backstage/cli-common": "
|
|
69
|
-
"@backstage/config": "
|
|
70
|
-
"@backstage/errors": "
|
|
71
|
-
"@backstage/plugin-auth-node": "
|
|
72
|
-
"@backstage/plugin-permission-common": "
|
|
73
|
-
"@backstage/plugin-permission-node": "
|
|
74
|
-
"@backstage/types": "
|
|
68
|
+
"@backstage/cli-common": "0.1.18-next.0",
|
|
69
|
+
"@backstage/config": "1.3.6",
|
|
70
|
+
"@backstage/errors": "1.2.7",
|
|
71
|
+
"@backstage/plugin-auth-node": "0.6.12-next.0",
|
|
72
|
+
"@backstage/plugin-permission-common": "0.9.5-next.0",
|
|
73
|
+
"@backstage/plugin-permission-node": "0.10.9-next.0",
|
|
74
|
+
"@backstage/types": "1.2.2",
|
|
75
75
|
"@types/express": "^4.17.6",
|
|
76
76
|
"@types/json-schema": "^7.0.6",
|
|
77
77
|
"@types/luxon": "^3.0.0",
|
|
78
78
|
"json-schema": "^0.4.0",
|
|
79
79
|
"knex": "^3.0.0",
|
|
80
80
|
"luxon": "^3.0.0",
|
|
81
|
-
"zod": "^3.
|
|
81
|
+
"zod": "^3.25.76"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@backstage/backend-test-utils": "
|
|
85
|
-
"@backstage/cli": "
|
|
84
|
+
"@backstage/backend-test-utils": "1.10.4-next.0",
|
|
85
|
+
"@backstage/cli": "0.35.3-next.0"
|
|
86
86
|
},
|
|
87
87
|
"configSchema": "config.d.ts"
|
|
88
88
|
}
|