New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@backstage/frontend-plugin-api

Package Overview
Dependencies
Maintainers
3
Versions
505
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@backstage/frontend-plugin-api - npm Package Compare versions

Comparing version 0.0.0-nightly-20231017021237 to 0.0.0-nightly-20231018021545

29

CHANGELOG.md
# @backstage/frontend-plugin-api
## 0.0.0-nightly-20231017021237
## 0.0.0-nightly-20231018021545
### Minor Changes
- 06432f900c84: Extension attachment point is now configured via `attachTo: { id, input }` instead of `at: 'id/input'`.
- 4461d87d5a48: Removed support for the new `useRouteRef`.
- 68fc9dc60e10: Added `RouteRef`, `SubRouteRef`, `ExternalRouteRef`, and related types. All exports from this package that previously relied on the types with the same name from `@backstage/core-plugin-api` now use the new types instead. To convert and existing legacy route ref to be compatible with the APIs from this package, use the `convertLegacyRouteRef` utility from `@backstage/core-plugin-api/alpha`.
### Patch Changes
- d3a37f55c086: Add support for `SidebarGroup` on the sidebar item extension.
- 2ecd33618a7f: Plugins can now be assigned `routes` and `externalRoutes` when created.
- 9a1fce352e6a: Updated dependency `@testing-library/jest-dom` to `^6.0.0`.
- c1e9ca650049: Added `createExtensionOverrides` which can be used to install a collection of extensions in an app that will replace any existing ones.
- 52366db5b36a: Added `createThemeExtension` and `coreExtensionData.theme`.
- Updated dependencies
- @backstage/core-plugin-api@0.0.0-nightly-20231017021237
- @backstage/core-plugin-api@0.0.0-nightly-20231018021545
## 0.2.0
### Minor Changes
- 06432f900c: Extension attachment point is now configured via `attachTo: { id, input }` instead of `at: 'id/input'`.
- 4461d87d5a: Removed support for the new `useRouteRef`.
### Patch Changes
- d3a37f55c0: Add support for `SidebarGroup` on the sidebar item extension.
- 2ecd33618a: Plugins can now be assigned `routes` and `externalRoutes` when created.
- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`.
- c1e9ca6500: Added `createExtensionOverrides` which can be used to install a collection of extensions in an app that will replace any existing ones.
- 52366db5b3: Added `createThemeExtension` and `coreExtensionData.theme`.
- Updated dependencies
- @backstage/core-plugin-api@1.7.0
- @backstage/types@1.1.1

@@ -20,0 +31,0 @@

/// <reference types="react" />
import React, { JSX as JSX$1, ReactNode } from 'react';
import { IconComponent, RouteRef, AnyApiFactory, AppTheme, AnyRoutes, AnyExternalRoutes, AnyApiRef } from '@backstage/core-plugin-api';
import { JsonObject } from '@backstage/types';
import { IconComponent, AnyApiFactory, AppTheme, AnyApiRef } from '@backstage/core-plugin-api';
import { z, ZodSchema, ZodTypeDef } from 'zod';
/**
* Catch-all type for route params.
*
* @public
*/
type AnyRouteRefParams = {
[param in string]: string;
} | undefined;
/**
* Absolute route reference.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @public
*/
interface RouteRef<TParams extends AnyRouteRefParams = AnyRouteRefParams> {
readonly $$type: '@backstage/RouteRef';
readonly T: TParams;
}
/**
* Create a {@link RouteRef} from a route descriptor.
*
* @param config - Description of the route reference to be created.
* @public
*/
declare function createRouteRef<TParams extends {
[param in TParamKeys]: string;
} | undefined = undefined, TParamKeys extends string = string>(config?: {
/** A list of parameter names that the path that this route ref is bound to must contain */
readonly params: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[];
}): RouteRef<keyof TParams extends never ? undefined : string extends TParamKeys ? TParams : {
[param in TParamKeys]: string;
}>;
/**
* Descriptor of a route relative to an absolute {@link RouteRef}.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @public
*/
interface SubRouteRef<TParams extends AnyRouteRefParams = AnyRouteRefParams> {
readonly $$type: '@backstage/SubRouteRef';
readonly T: TParams;
readonly path: string;
}
/**
* Used in {@link PathParams} type declaration.
* @ignore
*/
type ParamPart<S extends string> = S extends `:${infer Param}` ? Param : never;
/**
* Used in {@link PathParams} type declaration.
* @ignore
*/
type ParamNames<S extends string> = S extends `${infer Part}/${infer Rest}` ? ParamPart<Part> | ParamNames<Rest> : ParamPart<S>;
/**
* This utility type helps us infer a Param object type from a string path
* For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }`
* @ignore
*/
type PathParams<S extends string> = {
[name in ParamNames<S>]: string;
};
/**
* Merges a param object type with an optional params type into a params object.
* @ignore
*/
type MergeParams<P1 extends {
[param in string]: string;
}, P2 extends AnyRouteRefParams> = (P1[keyof P1] extends never ? {} : P1) & (P2 extends undefined ? {} : P2);
/**
* Convert empty params to undefined.
* @ignore
*/
type TrimEmptyParams<Params extends {
[param in string]: string;
}> = keyof Params extends never ? undefined : Params;
/**
* Creates a SubRouteRef type given the desired parameters and parent route parameters.
* The parameters types are merged together while ensuring that there is no overlap between the two.
*
* @ignore
*/
type MakeSubRouteRef<Params extends {
[param in string]: string;
}, ParentParams extends AnyRouteRefParams> = keyof Params & keyof ParentParams extends never ? SubRouteRef<TrimEmptyParams<MergeParams<Params, ParentParams>>> : never;
/**
* Create a {@link SubRouteRef} from a route descriptor.
*
* @param config - Description of the route reference to be created.
* @public
*/
declare function createSubRouteRef<Path extends string, ParentParams extends AnyRouteRefParams = never>(config: {
path: Path;
parent: RouteRef<ParentParams>;
}): MakeSubRouteRef<PathParams<Path>, ParentParams>;
/**
* Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @public
*/
interface ExternalRouteRef<TParams extends AnyRouteRefParams = AnyRouteRefParams, TOptional extends boolean = boolean> {
readonly $$type: '@backstage/ExternalRouteRef';
readonly T: TParams;
readonly optional: TOptional;
}
/**
* Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @param options - Description of the route reference to be created.
* @public
*/
declare function createExternalRouteRef<TParams extends {
[param in TParamKeys]: string;
} | undefined = undefined, TOptional extends boolean = false, TParamKeys extends string = string>(options?: {
/**
* The parameters that will be provided to the external route reference.
*/
readonly params?: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[];
/**
* Whether or not this route is optional, defaults to false.
*
* Optional external routes are not required to be bound in the app, and
* if they aren't, `useExternalRouteRef` will return `undefined`.
*/
optional?: TOptional;
}): ExternalRouteRef<keyof TParams extends never ? undefined : string extends TParamKeys ? TParams : {
[param in TParamKeys]: string;
}, TOptional>;
/**
* TS magic for handling route parameters.
*
* @remarks
*
* The extra TS magic here is to require a single params argument if the RouteRef
* had at least one param defined, but require 0 arguments if there are no params defined.
* Without this we'd have to pass in empty object to all parameter-less RouteRefs
* just to make TypeScript happy, or we would have to make the argument optional in
* which case you might forget to pass it in when it is actually required.
*
* @public
*/
type RouteFunc<TParams extends AnyRouteRefParams> = (...[params]: TParams extends undefined ? readonly [] : readonly [params: TParams]) => string;
/**
* React hook for constructing URLs to routes.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}
*
* @param routeRef - The ref to route that should be converted to URL.
* @returns A function that will in turn return the concrete URL of the `routeRef`.
* @public
*/
declare function useRouteRef<TOptional extends boolean, TParams extends AnyRouteRefParams>(routeRef: ExternalRouteRef<TParams, TOptional>): TParams extends true ? RouteFunc<TParams> | undefined : RouteFunc<TParams>;
/**
* React hook for constructing URLs to routes.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}
*
* @param routeRef - The ref to route that should be converted to URL.
* @returns A function that will in turn return the concrete URL of the `routeRef`.
* @public
*/
declare function useRouteRef<TParams extends AnyRouteRefParams>(routeRef: RouteRef<TParams> | SubRouteRef<TParams>): RouteFunc<TParams>;
/**
* React hook for retrieving dynamic params from the current URL.
* @param _routeRef - Ref of the current route.
* @public
*/
declare function useRouteRefParams<Params extends AnyRouteRefParams>(_routeRef: RouteRef<Params> | SubRouteRef<Params>): Params;
/** @public */

@@ -31,3 +222,3 @@ type ExtensionDataRef<TData, TConfig extends {

icon: IconComponent;
routeRef: RouteRef<{}>;
routeRef: RouteRef<undefined>;
};

@@ -39,3 +230,3 @@ /** @public */

apiFactory: ConfigurableExtensionDataRef<AnyApiFactory, {}>;
routeRef: ConfigurableExtensionDataRef<RouteRef, {}>;
routeRef: ConfigurableExtensionDataRef<RouteRef<AnyRouteRefParams>, {}>;
navTarget: ConfigurableExtensionDataRef<NavTarget, {}>;

@@ -54,2 +245,10 @@ theme: ConfigurableExtensionDataRef<AppTheme, {}>;

/**
* Utility type to expand type aliases into their equivalent type.
* @ignore
*/
type Expand<T> = T extends infer O ? {
[K in keyof O]: O[K];
} : never;
/** @public */

@@ -74,2 +273,10 @@ interface ExtensionInput<TExtensionData extends AnyExtensionDataMap, TConfig extends {

/** @public */
type AnyRoutes = {
[name in string]: RouteRef;
};
/** @public */
type AnyExternalRoutes = {
[name in string]: ExternalRouteRef;
};
/** @public */
interface PluginOptions<Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes> {

@@ -90,3 +297,3 @@ id: string;

/** @public */
declare function createPlugin<Routes extends AnyRoutes = AnyRoutes, ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes>(options: PluginOptions<Routes, ExternalRoutes>): BackstagePlugin<Routes, ExternalRoutes>;
declare function createPlugin<Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}>(options: PluginOptions<Routes, ExternalRoutes>): BackstagePlugin<Routes, ExternalRoutes>;

@@ -107,9 +314,2 @@ /** @public */

/**
* Utility type to expand type aliases into their equivalent type.
* @ignore
*/
type Expand<T> = T extends infer O ? {
[K in keyof O]: O[K];
} : never;
/**
* Converts an extension data map into the matching concrete data values type.

@@ -241,3 +441,3 @@ * @public

id: string;
routeRef: RouteRef;
routeRef: RouteRef<undefined>;
title: string;

@@ -252,2 +452,2 @@ icon: IconComponent;

export { AnyExtensionDataMap, AnyExtensionInputMap, BackstagePlugin, ConfigurableExtensionDataRef, CreateExtensionOptions, Extension, ExtensionBoundary, ExtensionBoundaryProps, ExtensionDataRef, ExtensionDataValues, ExtensionInput, ExtensionInputValues, ExtensionOverrides, ExtensionOverridesOptions, NavTarget, PluginOptions, PortableSchema, coreExtensionData, createApiExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createNavItemExtension, createPageExtension, createPlugin, createSchemaFromZod, createThemeExtension };
export { AnyExtensionDataMap, AnyExtensionInputMap, AnyExternalRoutes, AnyRouteRefParams, AnyRoutes, BackstagePlugin, ConfigurableExtensionDataRef, CreateExtensionOptions, Extension, ExtensionBoundary, ExtensionBoundaryProps, ExtensionDataRef, ExtensionDataValues, ExtensionInput, ExtensionInputValues, ExtensionOverrides, ExtensionOverridesOptions, ExternalRouteRef, NavTarget, PluginOptions, PortableSchema, RouteFunc, RouteRef, SubRouteRef, coreExtensionData, createApiExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSubRouteRef, createThemeExtension, useRouteRef, useRouteRefParams };

@@ -1,4 +0,6 @@

import React from 'react';
import React, { useMemo } from 'react';
import { z } from 'zod';
import zodToJsonSchema from 'zod-to-json-schema';
import { useLocation, useParams } from 'react-router-dom';
import { useVersionedContext } from '@backstage/version-bridge';

@@ -193,3 +195,241 @@ function ExtensionBoundary(props) {

export { ExtensionBoundary, coreExtensionData, createApiExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createNavItemExtension, createPageExtension, createPlugin, createSchemaFromZod, createThemeExtension };
const MESSAGE_MARKER = "eHgtF5hmbrXyiEvo";
function describeParentCallSite(ErrorConstructor = Error) {
const { stack } = new ErrorConstructor(MESSAGE_MARKER);
if (!stack) {
return "<unknown>";
}
const startIndex = stack.includes(MESSAGE_MARKER) ? stack.indexOf("\n") + 1 : 0;
const secondEntryStart = stack.indexOf("\n", stack.indexOf("\n", startIndex) + 1) + 1;
const secondEntryEnd = stack.indexOf("\n", secondEntryStart);
const line = stack.substring(secondEntryStart, secondEntryEnd).trim();
if (!line) {
return "unknown";
}
if (line.includes("(")) {
return line.substring(line.indexOf("(") + 1, line.indexOf(")"));
}
if (line.includes("@")) {
return line.substring(line.indexOf("@") + 1);
}
return line;
}
var __defProp$2 = Object.defineProperty;
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField$2 = (obj, key, value) => {
__defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck$1 = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet$1 = (obj, member, getter) => {
__accessCheck$1(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd$1 = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet$1 = (obj, member, value, setter) => {
__accessCheck$1(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var _id, _params$1, _creationSite, _name, name_get;
function toInternalRouteRef(resource) {
const r = resource;
if (r.$$type !== "@backstage/RouteRef") {
throw new Error(`Invalid RouteRef, bad type '${r.$$type}'`);
}
return r;
}
class RouteRefImpl {
constructor(params = [], creationSite) {
this.params = params;
__privateAdd$1(this, _name);
__publicField$2(this, "$$type", "@backstage/RouteRef");
__publicField$2(this, "version", "v1");
__privateAdd$1(this, _id, void 0);
__privateAdd$1(this, _params$1, void 0);
__privateAdd$1(this, _creationSite, void 0);
__privateSet$1(this, _params$1, params);
__privateSet$1(this, _creationSite, creationSite);
}
getParams() {
return __privateGet$1(this, _params$1);
}
getDescription() {
if (__privateGet$1(this, _id)) {
return __privateGet$1(this, _id);
}
return `created at '${__privateGet$1(this, _creationSite)}'`;
}
setId(id) {
if (!id) {
throw new Error(`${__privateGet$1(this, _name, name_get)} id must be a non-empty string`);
}
if (__privateGet$1(this, _id)) {
throw new Error(
`${__privateGet$1(this, _name, name_get)} was referenced twice as both '${__privateGet$1(this, _id)}' and '${id}'`
);
}
__privateSet$1(this, _id, id);
}
toString() {
return `${__privateGet$1(this, _name, name_get)}{${this.getDescription()}}`;
}
}
_id = new WeakMap();
_params$1 = new WeakMap();
_creationSite = new WeakMap();
_name = new WeakSet();
name_get = function() {
return this.$$type.slice("@backstage/".length);
};
function createRouteRef(config) {
return new RouteRefImpl(
config == null ? void 0 : config.params,
describeParentCallSite()
);
}
var __defProp$1 = Object.defineProperty;
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField$1 = (obj, key, value) => {
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var _params, _parent;
const PARAM_PATTERN = /^\w+$/;
class SubRouteRefImpl {
constructor(path, params, parent) {
this.path = path;
__publicField$1(this, "$$type", "@backstage/SubRouteRef");
__publicField$1(this, "version", "v1");
__privateAdd(this, _params, void 0);
__privateAdd(this, _parent, void 0);
__privateSet(this, _params, params);
__privateSet(this, _parent, parent);
}
getParams() {
return __privateGet(this, _params);
}
getParent() {
return __privateGet(this, _parent);
}
getDescription() {
const parent = toInternalRouteRef(__privateGet(this, _parent));
return `at ${this.path} with parent ${parent.getDescription()}`;
}
toString() {
return `SubRouteRef{${this.getDescription()}}`;
}
}
_params = new WeakMap();
_parent = new WeakMap();
function createSubRouteRef(config) {
const { path, parent } = config;
const internalParent = toInternalRouteRef(parent);
const parentParams = internalParent.getParams();
const pathParams = path.split("/").filter((p) => p.startsWith(":")).map((p) => p.substring(1));
const params = [...parentParams, ...pathParams];
if (parentParams.some((p) => pathParams.includes(p))) {
throw new Error(
"SubRouteRef may not have params that overlap with its parent"
);
}
if (!path.startsWith("/")) {
throw new Error(`SubRouteRef path must start with '/', got '${path}'`);
}
if (path.endsWith("/")) {
throw new Error(`SubRouteRef path must not end with '/', got '${path}'`);
}
for (const param of pathParams) {
if (!PARAM_PATTERN.test(param)) {
throw new Error(`SubRouteRef path has invalid param, got '${param}'`);
}
}
const subRouteRef = new SubRouteRefImpl(
path,
params,
parent
);
return subRouteRef;
}
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
class ExternalRouteRefImpl extends RouteRefImpl {
constructor(optional, params = [], creationSite) {
super(params, creationSite);
this.optional = optional;
this.params = params;
__publicField(this, "$$type", "@backstage/ExternalRouteRef");
}
}
function createExternalRouteRef(options) {
return new ExternalRouteRefImpl(
Boolean(options == null ? void 0 : options.optional),
options == null ? void 0 : options.params,
describeParentCallSite()
);
}
function useRouteRef(routeRef) {
const { pathname } = useLocation();
const versionedContext = useVersionedContext(
"routing-context"
);
if (!versionedContext) {
throw new Error("Routing context is not available");
}
const resolver = versionedContext.atVersion(1);
const routeFunc = useMemo(
() => resolver && resolver.resolve(routeRef, { pathname }),
[resolver, routeRef, pathname]
);
if (!versionedContext) {
throw new Error("useRouteRef used outside of routing context");
}
if (!resolver) {
throw new Error("RoutingContext v1 not available");
}
const isOptional = "optional" in routeRef && routeRef.optional;
if (!routeFunc && !isOptional) {
throw new Error(`No path for ${routeRef}`);
}
return routeFunc;
}
function useRouteRefParams(_routeRef) {
return useParams();
}
export { ExtensionBoundary, coreExtensionData, createApiExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSubRouteRef, createThemeExtension, useRouteRef, useRouteRefParams };
//# sourceMappingURL=index.esm.js.map
{
"name": "@backstage/frontend-plugin-api",
"version": "0.0.0-nightly-20231017021237",
"version": "0.0.0-nightly-20231018021545",
"main": "dist/index.esm.js",

@@ -26,7 +26,9 @@ "types": "dist/index.d.ts",

"devDependencies": {
"@backstage/cli": "^0.0.0-nightly-20231017021237",
"@backstage/frontend-app-api": "^0.0.0-nightly-20231017021237",
"@backstage/test-utils": "^0.0.0-nightly-20231017021237",
"@backstage/cli": "^0.23.0",
"@backstage/frontend-app-api": "^0.0.0-nightly-20231018021545",
"@backstage/test-utils": "^0.0.0-nightly-20231018021545",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^12.1.3"
"@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^8.0.1",
"history": "^5.3.0"
},

@@ -41,4 +43,5 @@ "files": [

"dependencies": {
"@backstage/core-plugin-api": "^0.0.0-nightly-20231017021237",
"@backstage/core-plugin-api": "^0.0.0-nightly-20231018021545",
"@backstage/types": "^1.1.1",
"@backstage/version-bridge": "^1.0.6",
"@types/react": "^16.13.1 || ^17.0.0",

@@ -45,0 +48,0 @@ "lodash": "^4.17.21",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc