@backstage/frontend-plugin-api 0.6.8-next.1 → 0.7.0-next.2

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @backstage/frontend-plugin-api
2
2
 
3
+ ## 0.7.0-next.2
4
+
5
+ ### Minor Changes
6
+
7
+ - 72754db: **BREAKING**: All types of route refs are always considered optional by `useRouteRef`, which means the caller must always handle a potential `undefined` return value. Related to this change, the `optional` option from `createExternalRouteRef` has been removed, since it is no longer necessary.
8
+
9
+ This is released as an immediate breaking change as we expect the usage of the new route refs to be extremely low or zero, since plugins that support the new system will still use route refs and `useRouteRef` from `@backstage/core-plugin-api` in combination with `convertLegacyRouteRef` from `@backstage/core-compat-api`.
10
+
11
+ ### Patch Changes
12
+
13
+ - 210d066: Added support for using the `params` in other properties of the `createExtensionBlueprint` options by providing a callback.
14
+ - Updated dependencies
15
+ - @backstage/core-components@0.14.10-next.0
16
+ - @backstage/core-plugin-api@1.9.3
17
+ - @backstage/types@1.1.1
18
+ - @backstage/version-bridge@1.0.8
19
+
3
20
  ## 0.6.8-next.1
4
21
 
5
22
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"RouteResolutionApi.esm.js","sources":["../../../src/apis/definitions/RouteResolutionApi.ts"],"sourcesContent":["/*\n * Copyright 2024 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 {\n AnyRouteRefParams,\n RouteRef,\n SubRouteRef,\n ExternalRouteRef,\n} from '../../routing';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * TS magic for handling route parameters.\n *\n * @remarks\n *\n * The extra TS magic here is to require a single params argument if the RouteRef\n * had at least one param defined, but require 0 arguments if there are no params defined.\n * Without this we'd have to pass in empty object to all parameter-less RouteRefs\n * just to make TypeScript happy, or we would have to make the argument optional in\n * which case you might forget to pass it in when it is actually required.\n *\n * @public\n */\nexport type RouteFunc<TParams extends AnyRouteRefParams> = (\n ...[params]: TParams extends undefined\n ? readonly []\n : readonly [params: TParams]\n) => string;\n\n/**\n * @public\n */\nexport type RouteResolutionApiResolveOptions = {\n /**\n * An absolute path to use as a starting point when resolving the route.\n * If no path is provided the route will be resolved from the root of the app.\n */\n sourcePath?: string;\n};\n\n/**\n * @public\n */\nexport interface RouteResolutionApi {\n resolve<TParams extends AnyRouteRefParams>(\n anyRouteRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams, any>,\n options?: RouteResolutionApiResolveOptions,\n ): RouteFunc<TParams> | undefined;\n}\n\n/**\n * The `ApiRef` of {@link RouteResolutionApi}.\n *\n * @public\n */\nexport const routeResolutionApiRef = createApiRef<RouteResolutionApi>({\n id: 'core.route-resolution',\n});\n"],"names":[],"mappings":";;AAwEO,MAAM,wBAAwB,YAAiC,CAAA;AAAA,EACpE,EAAI,EAAA,uBAAA;AACN,CAAC;;;;"}
1
+ {"version":3,"file":"RouteResolutionApi.esm.js","sources":["../../../src/apis/definitions/RouteResolutionApi.ts"],"sourcesContent":["/*\n * Copyright 2024 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 {\n AnyRouteRefParams,\n RouteRef,\n SubRouteRef,\n ExternalRouteRef,\n} from '../../routing';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * TS magic for handling route parameters.\n *\n * @remarks\n *\n * The extra TS magic here is to require a single params argument if the RouteRef\n * had at least one param defined, but require 0 arguments if there are no params defined.\n * Without this we'd have to pass in empty object to all parameter-less RouteRefs\n * just to make TypeScript happy, or we would have to make the argument optional in\n * which case you might forget to pass it in when it is actually required.\n *\n * @public\n */\nexport type RouteFunc<TParams extends AnyRouteRefParams> = (\n ...[params]: TParams extends undefined\n ? readonly []\n : readonly [params: TParams]\n) => string;\n\n/**\n * @public\n */\nexport type RouteResolutionApiResolveOptions = {\n /**\n * An absolute path to use as a starting point when resolving the route.\n * If no path is provided the route will be resolved from the root of the app.\n */\n sourcePath?: string;\n};\n\n/**\n * @public\n */\nexport interface RouteResolutionApi {\n resolve<TParams extends AnyRouteRefParams>(\n anyRouteRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams>,\n options?: RouteResolutionApiResolveOptions,\n ): RouteFunc<TParams> | undefined;\n}\n\n/**\n * The `ApiRef` of {@link RouteResolutionApi}.\n *\n * @public\n */\nexport const routeResolutionApiRef = createApiRef<RouteResolutionApi>({\n id: 'core.route-resolution',\n});\n"],"names":[],"mappings":";;AAwEO,MAAM,wBAAwB,YAAiC,CAAA;AAAA,EACpE,EAAI,EAAA,uBAAA;AACN,CAAC;;;;"}
package/dist/index.d.ts CHANGED
@@ -160,10 +160,9 @@ declare function createSubRouteRef<Path extends string, ParentParams extends Any
160
160
  *
161
161
  * @public
162
162
  */
163
- interface ExternalRouteRef<TParams extends AnyRouteRefParams = AnyRouteRefParams, TOptional extends boolean = boolean> {
163
+ interface ExternalRouteRef<TParams extends AnyRouteRefParams = AnyRouteRefParams> {
164
164
  readonly $$type: '@backstage/ExternalRouteRef';
165
165
  readonly T: TParams;
166
- readonly optional: TOptional;
167
166
  }
168
167
  /**
169
168
  * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.
@@ -177,18 +176,11 @@ interface ExternalRouteRef<TParams extends AnyRouteRefParams = AnyRouteRefParams
177
176
  */
178
177
  declare function createExternalRouteRef<TParams extends {
179
178
  [param in TParamKeys]: string;
180
- } | undefined = undefined, TOptional extends boolean = false, TParamKeys extends string = string>(options?: {
179
+ } | undefined = undefined, TParamKeys extends string = string>(options?: {
181
180
  /**
182
181
  * The parameters that will be provided to the external route reference.
183
182
  */
184
183
  readonly params?: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[];
185
- /**
186
- * Whether or not this route is optional, defaults to false.
187
- *
188
- * Optional external routes are not required to be bound in the app, and
189
- * if they aren't, `useExternalRouteRef` will return `undefined`.
190
- */
191
- optional?: TOptional;
192
184
  /**
193
185
  * The route (typically in another plugin) that this should map to by default.
194
186
  *
@@ -198,7 +190,7 @@ declare function createExternalRouteRef<TParams extends {
198
190
  defaultTarget?: string;
199
191
  }): ExternalRouteRef<keyof TParams extends never ? undefined : string extends TParamKeys ? TParams : {
200
192
  [param in TParamKeys]: string;
201
- }, TOptional>;
193
+ }>;
202
194
 
203
195
  /**
204
196
  * React hook for constructing URLs to routes.
@@ -208,22 +200,10 @@ declare function createExternalRouteRef<TParams extends {
208
200
  * See {@link https://backstage.io/docs/plugins/composability#routing-system}
209
201
  *
210
202
  * @param routeRef - The ref to route that should be converted to URL.
211
- * @returns A function that will in turn return the concrete URL of the `routeRef`.
212
- * @public
213
- */
214
- declare function useRouteRef<TOptional extends boolean, TParams extends AnyRouteRefParams>(routeRef: ExternalRouteRef<TParams, TOptional>): TOptional extends true ? RouteFunc<TParams> | undefined : RouteFunc<TParams>;
215
- /**
216
- * React hook for constructing URLs to routes.
217
- *
218
- * @remarks
219
- *
220
- * See {@link https://backstage.io/docs/plugins/composability#routing-system}
221
- *
222
- * @param routeRef - The ref to route that should be converted to URL.
223
- * @returns A function that will in turn return the concrete URL of the `routeRef`.
203
+ * @returns A function that will in turn return the concrete URL of the `routeRef`, or `undefined` if the route is not available.
224
204
  * @public
225
205
  */
226
- declare function useRouteRef<TParams extends AnyRouteRefParams>(routeRef: RouteRef<TParams> | SubRouteRef<TParams>): RouteFunc<TParams>;
206
+ declare function useRouteRef<TParams extends AnyRouteRefParams>(routeRef: RouteRef<TParams> | SubRouteRef<TParams> | ExternalRouteRef<TParams>): RouteFunc<TParams> | undefined;
227
207
 
228
208
  /**
229
209
  * React hook for retrieving dynamic params from the current URL.
@@ -443,8 +423,10 @@ interface LegacyCreateExtensionOptions<TOutput extends AnyExtensionDataMap, TInp
443
423
  }): Expand<ExtensionDataValues<TOutput>>;
444
424
  }
445
425
  /** @ignore */
446
- type VerifyExtensionFactoryOutput<UDeclaredOutput extends AnyExtensionDataRef, UFactoryOutput extends ExtensionDataValue<any, any>> = (UDeclaredOutput extends any ? UDeclaredOutput['config']['optional'] extends true ? never : UDeclaredOutput['id'] : never) extends infer IRequiredOutputIds ? [IRequiredOutputIds] extends [UFactoryOutput['id']] ? {} : {
447
- 'Error: The extension factory is missing the following outputs': Exclude<IRequiredOutputIds, UFactoryOutput['id']>;
426
+ type VerifyExtensionFactoryOutput<UDeclaredOutput extends AnyExtensionDataRef, UFactoryOutput extends ExtensionDataValue<any, any>> = (UDeclaredOutput extends any ? UDeclaredOutput['config']['optional'] extends true ? never : UDeclaredOutput['id'] : never) extends infer IRequiredOutputIds ? [IRequiredOutputIds] extends [UFactoryOutput['id']] ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']] ? {} : {
427
+ 'Error: The extension factory has undeclared output(s)': Exclude<UFactoryOutput['id'], UDeclaredOutput['id']>;
428
+ } : {
429
+ 'Error: The extension factory is missing the following output(s)': Exclude<IRequiredOutputIds, UFactoryOutput['id']>;
448
430
  } : never;
449
431
  /** @public */
450
432
  type CreateExtensionOptions<UOutput extends AnyExtensionDataRef, TInputs extends {
@@ -592,7 +574,7 @@ type CreateExtensionBlueprintOptions<TParams, UOutput extends AnyExtensionDataRe
592
574
  [name in string]: AnyExtensionDataRef;
593
575
  }> = {
594
576
  kind: string;
595
- namespace?: string;
577
+ namespace?: string | ((params: TParams) => string);
596
578
  attachTo: {
597
579
  id: string;
598
580
  input: string;
@@ -600,8 +582,9 @@ type CreateExtensionBlueprintOptions<TParams, UOutput extends AnyExtensionDataRe
600
582
  disabled?: boolean;
601
583
  inputs?: TInputs;
602
584
  output: Array<UOutput>;
585
+ name?: string | ((params: TParams) => string);
603
586
  config?: {
604
- schema: TConfigSchema;
587
+ schema: TConfigSchema | ((params: TParams) => TConfigSchema);
605
588
  };
606
589
  factory(params: TParams, context: {
607
590
  node: AppNode;
@@ -906,7 +889,7 @@ type RouteResolutionApiResolveOptions = {
906
889
  * @public
907
890
  */
908
891
  interface RouteResolutionApi {
909
- resolve<TParams extends AnyRouteRefParams>(anyRouteRef: RouteRef<TParams> | SubRouteRef<TParams> | ExternalRouteRef<TParams, any>, options?: RouteResolutionApiResolveOptions): RouteFunc<TParams> | undefined;
892
+ resolve<TParams extends AnyRouteRefParams>(anyRouteRef: RouteRef<TParams> | SubRouteRef<TParams> | ExternalRouteRef<TParams>, options?: RouteResolutionApiResolveOptions): RouteFunc<TParams> | undefined;
910
893
  }
911
894
  /**
912
895
  * The `ApiRef` of {@link RouteResolutionApi}.
@@ -2,9 +2,8 @@ import { RouteRefImpl } from './RouteRef.esm.js';
2
2
  import { describeParentCallSite } from './describeParentCallSite.esm.js';
3
3
 
4
4
  class ExternalRouteRefImpl extends RouteRefImpl {
5
- constructor(optional, params = [], defaultTarget, creationSite) {
5
+ constructor(params = [], defaultTarget, creationSite) {
6
6
  super(params, creationSite);
7
- this.optional = optional;
8
7
  this.params = params;
9
8
  this.defaultTarget = defaultTarget;
10
9
  }
@@ -15,7 +14,6 @@ class ExternalRouteRefImpl extends RouteRefImpl {
15
14
  }
16
15
  function createExternalRouteRef(options) {
17
16
  return new ExternalRouteRefImpl(
18
- Boolean(options?.optional),
19
17
  options?.params,
20
18
  options?.defaultTarget,
21
19
  describeParentCallSite()
@@ -1 +1 @@
1
- {"version":3,"file":"ExternalRouteRef.esm.js","sources":["../../src/routing/ExternalRouteRef.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 { RouteRefImpl } from './RouteRef';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface ExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> {\n readonly $$type: '@backstage/ExternalRouteRef';\n readonly T: TParams;\n readonly optional: TOptional;\n}\n\n/** @internal */\nexport interface InternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> extends ExternalRouteRef<TParams, TOptional> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n getDefaultTarget(): string | undefined;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n>(\n resource: ExternalRouteRef<TParams, TOptional>,\n): InternalExternalRouteRef<TParams, TOptional> {\n const r = resource as InternalExternalRouteRef<TParams, TOptional>;\n if (r.$$type !== '@backstage/ExternalRouteRef') {\n throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isExternalRouteRef(opaque: {\n $$type: string;\n}): opaque is ExternalRouteRef {\n return opaque.$$type === '@backstage/ExternalRouteRef';\n}\n\n/** @internal */\nclass ExternalRouteRefImpl\n extends RouteRefImpl\n implements InternalExternalRouteRef\n{\n readonly $$type = '@backstage/ExternalRouteRef' as any;\n\n constructor(\n readonly optional: boolean,\n readonly params: string[] = [],\n readonly defaultTarget: string | undefined,\n creationSite: string,\n ) {\n super(params, creationSite);\n }\n\n getDefaultTarget() {\n return this.defaultTarget;\n }\n}\n\n/**\n * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @param options - Description of the route reference to be created.\n * @public\n */\nexport function createExternalRouteRef<\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TOptional extends boolean = false,\n TParamKeys extends string = string,\n>(options?: {\n /**\n * The parameters that will be provided to the external route reference.\n */\n readonly params?: string extends TParamKeys\n ? (keyof TParams)[]\n : TParamKeys[];\n\n /**\n * Whether or not this route is optional, defaults to false.\n *\n * Optional external routes are not required to be bound in the app, and\n * if they aren't, `useExternalRouteRef` will return `undefined`.\n */\n optional?: TOptional;\n\n /**\n * The route (typically in another plugin) that this should map to by default.\n *\n * The string is expected to be on the standard `<plugin id>.<route id>` form,\n * for example `techdocs.docRoot`.\n */\n defaultTarget?: string;\n}): ExternalRouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string },\n TOptional\n> {\n return new ExternalRouteRefImpl(\n Boolean(options?.optional),\n options?.params as string[] | undefined,\n options?.defaultTarget,\n describeParentCallSite(),\n ) as ExternalRouteRef<any, any>;\n}\n"],"names":[],"mappings":";;;AA0EA,MAAM,6BACI,YAEV,CAAA;AAAA,EAGE,YACW,QACA,EAAA,MAAA,GAAmB,EAAC,EACpB,eACT,YACA,EAAA;AACA,IAAA,KAAA,CAAM,QAAQ,YAAY,CAAA,CAAA;AALjB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA,CAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AACA,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA,CAAA;AAAA,GAIX;AAAA,EATS,MAAS,GAAA,6BAAA,CAAA;AAAA,EAWlB,gBAAmB,GAAA;AACjB,IAAA,OAAO,IAAK,CAAA,aAAA,CAAA;AAAA,GACd;AACF,CAAA;AAYO,SAAS,uBAId,OA8BA,EAAA;AACA,EAAA,OAAO,IAAI,oBAAA;AAAA,IACT,OAAA,CAAQ,SAAS,QAAQ,CAAA;AAAA,IACzB,OAAS,EAAA,MAAA;AAAA,IACT,OAAS,EAAA,aAAA;AAAA,IACT,sBAAuB,EAAA;AAAA,GACzB,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"ExternalRouteRef.esm.js","sources":["../../src/routing/ExternalRouteRef.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 { RouteRefImpl } from './RouteRef';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface ExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/ExternalRouteRef';\n readonly T: TParams;\n}\n\n/** @internal */\nexport interface InternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends ExternalRouteRef<TParams> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n getDefaultTarget(): string | undefined;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: ExternalRouteRef<TParams>): InternalExternalRouteRef<TParams> {\n const r = resource as InternalExternalRouteRef<TParams>;\n if (r.$$type !== '@backstage/ExternalRouteRef') {\n throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isExternalRouteRef(opaque: {\n $$type: string;\n}): opaque is ExternalRouteRef {\n return opaque.$$type === '@backstage/ExternalRouteRef';\n}\n\n/** @internal */\nclass ExternalRouteRefImpl\n extends RouteRefImpl\n implements InternalExternalRouteRef\n{\n readonly $$type = '@backstage/ExternalRouteRef' as any;\n\n constructor(\n readonly params: string[] = [],\n readonly defaultTarget: string | undefined,\n creationSite: string,\n ) {\n super(params, creationSite);\n }\n\n getDefaultTarget() {\n return this.defaultTarget;\n }\n}\n\n/**\n * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @param options - Description of the route reference to be created.\n * @public\n */\nexport function createExternalRouteRef<\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TParamKeys extends string = string,\n>(options?: {\n /**\n * The parameters that will be provided to the external route reference.\n */\n readonly params?: string extends TParamKeys\n ? (keyof TParams)[]\n : TParamKeys[];\n\n /**\n * The route (typically in another plugin) that this should map to by default.\n *\n * The string is expected to be on the standard `<plugin id>.<route id>` form,\n * for example `techdocs.docRoot`.\n */\n defaultTarget?: string;\n}): ExternalRouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string }\n> {\n return new ExternalRouteRefImpl(\n options?.params as string[] | undefined,\n options?.defaultTarget,\n describeParentCallSite(),\n );\n}\n"],"names":[],"mappings":";;;AAoEA,MAAM,6BACI,YAEV,CAAA;AAAA,EAGE,WACW,CAAA,MAAA,GAAmB,EAAC,EACpB,eACT,YACA,EAAA;AACA,IAAA,KAAA,CAAM,QAAQ,YAAY,CAAA,CAAA;AAJjB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AACA,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA,CAAA;AAAA,GAIX;AAAA,EARS,MAAS,GAAA,6BAAA,CAAA;AAAA,EAUlB,gBAAmB,GAAA;AACjB,IAAA,OAAO,IAAK,CAAA,aAAA,CAAA;AAAA,GACd;AACF,CAAA;AAYO,SAAS,uBAGd,OAqBA,EAAA;AACA,EAAA,OAAO,IAAI,oBAAA;AAAA,IACT,OAAS,EAAA,MAAA;AAAA,IACT,OAAS,EAAA,aAAA;AAAA,IACT,sBAAuB,EAAA;AAAA,GACzB,CAAA;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"describeParentCallSite.esm.js","sources":["../../src/routing/describeParentCallSite.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\nconst MESSAGE_MARKER = 'eHgtF5hmbrXyiEvo';\n\n/**\n * Internal helper that describes the location of the parent caller.\n * @internal\n */\nexport function describeParentCallSite(\n ErrorConstructor: { new (message: string): Error } = Error,\n): string {\n const { stack } = new ErrorConstructor(MESSAGE_MARKER);\n if (!stack) {\n return '<unknown>';\n }\n\n // Safari and Firefox don't include the error itself in the stack\n const startIndex = stack.includes(MESSAGE_MARKER)\n ? stack.indexOf('\\n') + 1\n : 0;\n const secondEntryStart =\n stack.indexOf('\\n', stack.indexOf('\\n', startIndex) + 1) + 1;\n const secondEntryEnd = stack.indexOf('\\n', secondEntryStart);\n\n const line = stack.substring(secondEntryStart, secondEntryEnd).trim();\n if (!line) {\n return 'unknown';\n }\n\n // Below we try to extract the location for different browsers.\n // Since RouteRefs are declared at the top-level of modules the caller name isn't interesting.\n\n // Chrome\n if (line.includes('(')) {\n return line.substring(line.indexOf('(') + 1, line.indexOf(')'));\n }\n\n // Safari & Firefox\n if (line.includes('@')) {\n return line.substring(line.indexOf('@') + 1);\n }\n\n // Give up\n return line;\n}\n"],"names":[],"mappings":"AAgBA,MAAM,cAAiB,GAAA,kBAAA,CAAA;AAMP,SAAA,sBAAA,CACd,mBAAqD,KAC7C,EAAA;AACR,EAAA,MAAM,EAAE,KAAA,EAAU,GAAA,IAAI,iBAAiB,cAAc,CAAA,CAAA;AACrD,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAO,OAAA,WAAA,CAAA;AAAA,GACT;AAGA,EAAM,MAAA,UAAA,GAAa,MAAM,QAAS,CAAA,cAAc,IAC5C,KAAM,CAAA,OAAA,CAAQ,IAAI,CAAA,GAAI,CACtB,GAAA,CAAA,CAAA;AACJ,EAAM,MAAA,gBAAA,GACJ,KAAM,CAAA,OAAA,CAAQ,IAAM,EAAA,KAAA,CAAM,QAAQ,IAAM,EAAA,UAAU,CAAI,GAAA,CAAC,CAAI,GAAA,CAAA,CAAA;AAC7D,EAAA,MAAM,cAAiB,GAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,EAAM,gBAAgB,CAAA,CAAA;AAE3D,EAAA,MAAM,OAAO,KAAM,CAAA,SAAA,CAAU,gBAAkB,EAAA,cAAc,EAAE,IAAK,EAAA,CAAA;AACpE,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAO,OAAA,SAAA,CAAA;AAAA,GACT;AAMA,EAAI,IAAA,IAAA,CAAK,QAAS,CAAA,GAAG,CAAG,EAAA;AACtB,IAAO,OAAA,IAAA,CAAK,SAAU,CAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAG,EAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,CAAC,CAAA,CAAA;AAAA,GAChE;AAGA,EAAI,IAAA,IAAA,CAAK,QAAS,CAAA,GAAG,CAAG,EAAA;AACtB,IAAA,OAAO,KAAK,SAAU,CAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAC,CAAA,CAAA;AAAA,GAC7C;AAGA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
1
+ {"version":3,"file":"describeParentCallSite.esm.js","sources":["../../src/routing/describeParentCallSite.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\nconst MESSAGE_MARKER = 'eHgtF5hmbrXyiEvo';\n\n// NOTE: This function is also imported and used in backend code\n\n/**\n * Internal helper that describes the location of the parent caller.\n * @internal\n */\nexport function describeParentCallSite(\n ErrorConstructor: { new (message: string): Error } = Error,\n): string {\n const { stack } = new ErrorConstructor(MESSAGE_MARKER);\n if (!stack) {\n return '<unknown>';\n }\n\n // Safari and Firefox don't include the error itself in the stack\n const startIndex = stack.includes(MESSAGE_MARKER)\n ? stack.indexOf('\\n') + 1\n : 0;\n const secondEntryStart =\n stack.indexOf('\\n', stack.indexOf('\\n', startIndex) + 1) + 1;\n const secondEntryEnd = stack.indexOf('\\n', secondEntryStart);\n\n const line = stack.substring(secondEntryStart, secondEntryEnd).trim();\n if (!line) {\n return 'unknown';\n }\n\n // Below we try to extract the location for different browsers.\n // Since RouteRefs are declared at the top-level of modules the caller name isn't interesting.\n\n // Chrome\n if (line.includes('(')) {\n return line.substring(line.indexOf('(') + 1, line.indexOf(')'));\n }\n\n // Safari & Firefox\n if (line.includes('@')) {\n return line.substring(line.indexOf('@') + 1);\n }\n\n // Give up\n return line;\n}\n"],"names":[],"mappings":"AAgBA,MAAM,cAAiB,GAAA,kBAAA,CAAA;AAQP,SAAA,sBAAA,CACd,mBAAqD,KAC7C,EAAA;AACR,EAAA,MAAM,EAAE,KAAA,EAAU,GAAA,IAAI,iBAAiB,cAAc,CAAA,CAAA;AACrD,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAO,OAAA,WAAA,CAAA;AAAA,GACT;AAGA,EAAM,MAAA,UAAA,GAAa,MAAM,QAAS,CAAA,cAAc,IAC5C,KAAM,CAAA,OAAA,CAAQ,IAAI,CAAA,GAAI,CACtB,GAAA,CAAA,CAAA;AACJ,EAAM,MAAA,gBAAA,GACJ,KAAM,CAAA,OAAA,CAAQ,IAAM,EAAA,KAAA,CAAM,QAAQ,IAAM,EAAA,UAAU,CAAI,GAAA,CAAC,CAAI,GAAA,CAAA,CAAA;AAC7D,EAAA,MAAM,cAAiB,GAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,EAAM,gBAAgB,CAAA,CAAA;AAE3D,EAAA,MAAM,OAAO,KAAM,CAAA,SAAA,CAAU,gBAAkB,EAAA,cAAc,EAAE,IAAK,EAAA,CAAA;AACpE,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAO,OAAA,SAAA,CAAA;AAAA,GACT;AAMA,EAAI,IAAA,IAAA,CAAK,QAAS,CAAA,GAAG,CAAG,EAAA;AACtB,IAAO,OAAA,IAAA,CAAK,SAAU,CAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAG,EAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,CAAC,CAAA,CAAA;AAAA,GAChE;AAGA,EAAI,IAAA,IAAA,CAAK,QAAS,CAAA,GAAG,CAAG,EAAA;AACtB,IAAA,OAAO,KAAK,SAAU,CAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAC,CAAA,CAAA;AAAA,GAC7C;AAGA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
@@ -14,10 +14,6 @@ function useRouteRef(routeRef) {
14
14
  () => routeResolutionApi.resolve(routeRef, { sourcePath: pathname }),
15
15
  [routeResolutionApi, routeRef, pathname]
16
16
  );
17
- const isOptional = "optional" in routeRef && routeRef.optional;
18
- if (!routeFunc && !isOptional) {
19
- throw new Error(`No path for ${routeRef}`);
20
- }
21
17
  return routeFunc;
22
18
  }
23
19
 
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteRef.esm.js","sources":["../../src/routing/useRouteRef.tsx"],"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 { useMemo } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { AnyRouteRefParams } from './types';\nimport { RouteRef } from './RouteRef';\nimport { SubRouteRef } from './SubRouteRef';\nimport { ExternalRouteRef } from './ExternalRouteRef';\nimport { RouteFunc, routeResolutionApiRef, useApi } from '../apis';\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<\n TOptional extends boolean,\n TParams extends AnyRouteRefParams,\n>(\n routeRef: ExternalRouteRef<TParams, TOptional>,\n): TOptional extends true ? RouteFunc<TParams> | undefined : RouteFunc<TParams>;\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<TParams extends AnyRouteRefParams>(\n routeRef: RouteRef<TParams> | SubRouteRef<TParams>,\n): RouteFunc<TParams>;\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<TParams extends AnyRouteRefParams>(\n routeRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams, any>,\n): RouteFunc<TParams> | undefined {\n const { pathname } = useLocation();\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n const routeFunc = useMemo(\n () => routeResolutionApi.resolve(routeRef, { sourcePath: pathname }),\n [routeResolutionApi, routeRef, pathname],\n );\n\n const isOptional = 'optional' in routeRef && routeRef.optional;\n if (!routeFunc && !isOptional) {\n throw new Error(`No path for ${routeRef}`);\n }\n\n return routeFunc;\n}\n"],"names":[],"mappings":";;;;;;;;;AAoEO,SAAS,YACd,QAIgC,EAAA;AAChC,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,WAAY,EAAA,CAAA;AACjC,EAAM,MAAA,kBAAA,GAAqB,OAAO,qBAAqB,CAAA,CAAA;AAEvD,EAAA,MAAM,SAAY,GAAA,OAAA;AAAA,IAChB,MAAM,kBAAmB,CAAA,OAAA,CAAQ,UAAU,EAAE,UAAA,EAAY,UAAU,CAAA;AAAA,IACnE,CAAC,kBAAoB,EAAA,QAAA,EAAU,QAAQ,CAAA;AAAA,GACzC,CAAA;AAEA,EAAM,MAAA,UAAA,GAAa,UAAc,IAAA,QAAA,IAAY,QAAS,CAAA,QAAA,CAAA;AACtD,EAAI,IAAA,CAAC,SAAa,IAAA,CAAC,UAAY,EAAA;AAC7B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAe,YAAA,EAAA,QAAQ,CAAE,CAAA,CAAA,CAAA;AAAA,GAC3C;AAEA,EAAO,OAAA,SAAA,CAAA;AACT;;;;"}
1
+ {"version":3,"file":"useRouteRef.esm.js","sources":["../../src/routing/useRouteRef.tsx"],"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 { useMemo } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { AnyRouteRefParams } from './types';\nimport { RouteRef } from './RouteRef';\nimport { SubRouteRef } from './SubRouteRef';\nimport { ExternalRouteRef } from './ExternalRouteRef';\nimport { RouteFunc, routeResolutionApiRef, useApi } from '../apis';\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`, or `undefined` if the route is not available.\n * @public\n */\nexport function useRouteRef<TParams extends AnyRouteRefParams>(\n routeRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams>,\n): RouteFunc<TParams> | undefined {\n const { pathname } = useLocation();\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n const routeFunc = useMemo(\n () => routeResolutionApi.resolve(routeRef, { sourcePath: pathname }),\n [routeResolutionApi, routeRef, pathname],\n );\n\n return routeFunc;\n}\n"],"names":[],"mappings":";;;;;;;;;AAmCO,SAAS,YACd,QAIgC,EAAA;AAChC,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,WAAY,EAAA,CAAA;AACjC,EAAM,MAAA,kBAAA,GAAqB,OAAO,qBAAqB,CAAA,CAAA;AAEvD,EAAA,MAAM,SAAY,GAAA,OAAA;AAAA,IAChB,MAAM,kBAAmB,CAAA,OAAA,CAAQ,UAAU,EAAE,UAAA,EAAY,UAAU,CAAA;AAAA,IACnE,CAAC,kBAAoB,EAAA,QAAA,EAAU,QAAQ,CAAA;AAAA,GACzC,CAAA;AAEA,EAAO,OAAA,SAAA,CAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"createExtension.esm.js","sources":["../../src/wiring/createExtension.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 { AppNode } from '../apis';\nimport { PortableSchema, createSchemaFromZod } from '../schema';\nimport { Expand } from '../types';\nimport {\n AnyExtensionDataRef,\n ExtensionDataRef,\n ExtensionDataValue,\n} from './createExtensionDataRef';\nimport { ExtensionInput, LegacyExtensionInput } from './createExtensionInput';\nimport { z } from 'zod';\n\n/**\n * @public\n * @deprecated Extension data maps will be removed.\n */\nexport type AnyExtensionDataMap = {\n [name in string]: AnyExtensionDataRef;\n};\n\n/**\n * @public\n * @deprecated This type will be removed.\n */\nexport type AnyExtensionInputMap = {\n [inputName in string]: LegacyExtensionInput<\n AnyExtensionDataMap,\n { optional: boolean; singleton: boolean }\n >;\n};\n\n/**\n * Converts an extension data map into the matching concrete data values type.\n * @public\n * @deprecated Extension data maps will be removed.\n */\nexport type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? never\n : DataName]: TExtensionData[DataName]['T'];\n} & {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? DataName\n : never]?: TExtensionData[DataName]['T'];\n};\n\n/** @public */\nexport type ExtensionDataContainer<UExtensionData extends AnyExtensionDataRef> =\n {\n get<TId extends UExtensionData['id']>(\n ref: ExtensionDataRef<any, TId, any>,\n ): UExtensionData extends ExtensionDataRef<infer IData, TId, infer IConfig>\n ? IConfig['optional'] extends true\n ? IData | undefined\n : IData\n : never;\n };\n\n/**\n * Convert a single extension input into a matching resolved input.\n * @public\n */\nexport type ResolvedExtensionInput<\n TExtensionInput extends ExtensionInput<any, any>,\n> = TExtensionInput['extensionData'] extends Array<AnyExtensionDataRef>\n ? {\n node: AppNode;\n } & ExtensionDataContainer<TExtensionInput['extensionData'][number]>\n : TExtensionInput['extensionData'] extends AnyExtensionDataMap\n ? {\n node: AppNode;\n output: ExtensionDataValues<TExtensionInput['extensionData']>;\n }\n : never;\n\n/**\n * Converts an extension input map into a matching collection of resolved inputs.\n * @public\n */\nexport type ResolvedExtensionInputs<\n TInputs extends {\n [name in string]: ExtensionInput<any, any> | LegacyExtensionInput<any, any>;\n },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ResolvedExtensionInput<TInputs[InputName]>>\n : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>;\n};\n\n/**\n * @public\n * @deprecated This way of structuring the options is deprecated, this type will be removed in the future\n */\nexport interface LegacyCreateExtensionOptions<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n> {\n kind?: string;\n namespace?: string;\n name?: string;\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: TOutput;\n /** @deprecated - use `config.schema` instead */\n configSchema?: PortableSchema<TConfig, TConfigInput>;\n config?: {\n schema: TConfigSchema;\n };\n factory(context: {\n node: AppNode;\n config: TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n });\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }): Expand<ExtensionDataValues<TOutput>>;\n}\n\n/** @ignore */\nexport type VerifyExtensionFactoryOutput<\n UDeclaredOutput extends AnyExtensionDataRef,\n UFactoryOutput extends ExtensionDataValue<any, any>,\n> = (\n UDeclaredOutput extends any\n ? UDeclaredOutput['config']['optional'] extends true\n ? never\n : UDeclaredOutput['id']\n : never\n) extends infer IRequiredOutputIds\n ? [IRequiredOutputIds] extends [UFactoryOutput['id']]\n ? {}\n : {\n 'Error: The extension factory is missing the following outputs': Exclude<\n IRequiredOutputIds,\n UFactoryOutput['id']\n >;\n }\n : never;\n\n/** @public */\nexport type CreateExtensionOptions<\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n> = {\n kind?: string;\n namespace?: string;\n name?: string;\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: Array<UOutput>;\n /** @deprecated - use `config.schema` instead */\n configSchema?: PortableSchema<TConfig, TConfigInput>;\n config?: {\n schema: TConfigSchema;\n };\n factory(context: {\n node: AppNode;\n config: TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n });\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }): Iterable<UFactoryOutput>;\n} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;\n\n/** @public */\nexport interface ExtensionDefinition<TConfig, TConfigInput = TConfig> {\n $$type: '@backstage/ExtensionDefinition';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: { id: string; input: string };\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<TConfig, TConfigInput>;\n}\n\n/** @internal */\nexport type InternalExtensionDefinition<TConfig, TConfigInput> =\n ExtensionDefinition<TConfig, TConfigInput> &\n (\n | {\n readonly version: 'v1';\n readonly inputs: AnyExtensionInputMap;\n readonly output: AnyExtensionDataMap;\n factory(context: {\n node: AppNode;\n config: TConfig;\n inputs: ResolvedExtensionInputs<AnyExtensionInputMap>;\n }): ExtensionDataValues<any>;\n }\n | {\n readonly version: 'v2';\n readonly inputs: {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n };\n readonly output: Array<AnyExtensionDataRef>;\n factory(context: {\n node: AppNode;\n config: TConfig;\n inputs: ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n }>;\n }): Iterable<ExtensionDataValue<any, any>>;\n }\n );\n\n/** @internal */\nexport function toInternalExtensionDefinition<TConfig, TConfigInput>(\n overrides: ExtensionDefinition<TConfig, TConfigInput>,\n): InternalExtensionDefinition<TConfig, TConfigInput> {\n const internal = overrides as InternalExtensionDefinition<\n TConfig,\n TConfigInput\n >;\n if (internal.$$type !== '@backstage/ExtensionDefinition') {\n throw new Error(\n `Invalid extension definition instance, bad type '${internal.$$type}'`,\n );\n }\n const version = internal.version;\n if (version !== 'v1' && version !== 'v2') {\n throw new Error(\n `Invalid extension definition instance, bad version '${version}'`,\n );\n }\n return internal;\n}\n\n/** @public */\nexport function createExtension<\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n>(\n options: CreateExtensionOptions<\n UOutput,\n TInputs,\n TConfig,\n TConfigInput,\n TConfigSchema,\n UFactoryOutput\n >,\n): ExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n>;\n/**\n * @public\n * @deprecated - use the array format of `output` instead, see TODO-doc-link\n */\nexport function createExtension<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n>(\n options: LegacyCreateExtensionOptions<\n TOutput,\n TInputs,\n TConfig,\n TConfigInput,\n TConfigSchema\n >,\n): ExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n>;\nexport function createExtension<\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TLegacyInputs extends AnyExtensionInputMap,\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n>(\n options:\n | CreateExtensionOptions<\n UOutput,\n TInputs,\n TConfig,\n TConfigInput,\n TConfigSchema,\n UFactoryOutput\n >\n | LegacyCreateExtensionOptions<\n AnyExtensionDataMap,\n TLegacyInputs,\n TConfig,\n TConfigInput,\n TConfigSchema\n >,\n): ExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n> {\n const newConfigSchema = options.config?.schema;\n if (newConfigSchema && options.configSchema) {\n throw new Error(`Cannot provide both configSchema and config.schema`);\n }\n const configSchema = newConfigSchema\n ? createSchemaFromZod(innerZ =>\n innerZ.object(\n Object.fromEntries(\n Object.entries(newConfigSchema).map(([k, v]) => [k, v(innerZ)]),\n ),\n ),\n )\n : options.configSchema;\n\n return {\n $$type: '@backstage/ExtensionDefinition',\n version: Symbol.iterator in options.output ? 'v2' : 'v1',\n kind: options.kind,\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo,\n disabled: options.disabled ?? false,\n inputs: options.inputs ?? {},\n output: options.output,\n configSchema,\n factory: options.factory,\n toString() {\n const parts: string[] = [];\n if (options.kind) {\n parts.push(`kind=${options.kind}`);\n }\n if (options.namespace) {\n parts.push(`namespace=${options.namespace}`);\n }\n if (options.name) {\n parts.push(`name=${options.name}`);\n }\n parts.push(`attachTo=${options.attachTo.id}@${options.attachTo.input}`);\n return `ExtensionDefinition{${parts.join(',')}}`;\n },\n } as InternalExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n >;\n}\n"],"names":[],"mappings":";;AAgQO,SAAS,8BACd,SACoD,EAAA;AACpD,EAAA,MAAM,QAAW,GAAA,SAAA,CAAA;AAIjB,EAAI,IAAA,QAAA,CAAS,WAAW,gCAAkC,EAAA;AACxD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iDAAA,EAAoD,SAAS,MAAM,CAAA,CAAA,CAAA;AAAA,KACrE,CAAA;AAAA,GACF;AACA,EAAA,MAAM,UAAU,QAAS,CAAA,OAAA,CAAA;AACzB,EAAI,IAAA,OAAA,KAAY,IAAQ,IAAA,OAAA,KAAY,IAAM,EAAA;AACxC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,uDAAuD,OAAO,CAAA,CAAA,CAAA;AAAA,KAChE,CAAA;AAAA,GACF;AACA,EAAO,OAAA,QAAA,CAAA;AACT,CAAA;AA0EO,SAAS,gBAcd,OA+BA,EAAA;AACA,EAAM,MAAA,eAAA,GAAkB,QAAQ,MAAQ,EAAA,MAAA,CAAA;AACxC,EAAI,IAAA,eAAA,IAAmB,QAAQ,YAAc,EAAA;AAC3C,IAAM,MAAA,IAAI,MAAM,CAAoD,kDAAA,CAAA,CAAA,CAAA;AAAA,GACtE;AACA,EAAA,MAAM,eAAe,eACjB,GAAA,mBAAA;AAAA,IAAoB,YAClB,MAAO,CAAA,MAAA;AAAA,MACL,MAAO,CAAA,WAAA;AAAA,QACL,MAAO,CAAA,OAAA,CAAQ,eAAe,CAAA,CAAE,IAAI,CAAC,CAAC,CAAG,EAAA,CAAC,MAAM,CAAC,CAAA,EAAG,CAAE,CAAA,MAAM,CAAC,CAAC,CAAA;AAAA,OAChE;AAAA,KACF;AAAA,MAEF,OAAQ,CAAA,YAAA,CAAA;AAEZ,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,gCAAA;AAAA,IACR,OAAS,EAAA,MAAA,CAAO,QAAY,IAAA,OAAA,CAAQ,SAAS,IAAO,GAAA,IAAA;AAAA,IACpD,MAAM,OAAQ,CAAA,IAAA;AAAA,IACd,WAAW,OAAQ,CAAA,SAAA;AAAA,IACnB,MAAM,OAAQ,CAAA,IAAA;AAAA,IACd,UAAU,OAAQ,CAAA,QAAA;AAAA,IAClB,QAAA,EAAU,QAAQ,QAAY,IAAA,KAAA;AAAA,IAC9B,MAAA,EAAQ,OAAQ,CAAA,MAAA,IAAU,EAAC;AAAA,IAC3B,QAAQ,OAAQ,CAAA,MAAA;AAAA,IAChB,YAAA;AAAA,IACA,SAAS,OAAQ,CAAA,OAAA;AAAA,IACjB,QAAW,GAAA;AACT,MAAA,MAAM,QAAkB,EAAC,CAAA;AACzB,MAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,QAAA,KAAA,CAAM,IAAK,CAAA,CAAA,KAAA,EAAQ,OAAQ,CAAA,IAAI,CAAE,CAAA,CAAA,CAAA;AAAA,OACnC;AACA,MAAA,IAAI,QAAQ,SAAW,EAAA;AACrB,QAAA,KAAA,CAAM,IAAK,CAAA,CAAA,UAAA,EAAa,OAAQ,CAAA,SAAS,CAAE,CAAA,CAAA,CAAA;AAAA,OAC7C;AACA,MAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,QAAA,KAAA,CAAM,IAAK,CAAA,CAAA,KAAA,EAAQ,OAAQ,CAAA,IAAI,CAAE,CAAA,CAAA,CAAA;AAAA,OACnC;AACA,MAAM,KAAA,CAAA,IAAA,CAAK,YAAY,OAAQ,CAAA,QAAA,CAAS,EAAE,CAAI,CAAA,EAAA,OAAA,CAAQ,QAAS,CAAA,KAAK,CAAE,CAAA,CAAA,CAAA;AACtE,MAAA,OAAO,CAAuB,oBAAA,EAAA,KAAA,CAAM,IAAK,CAAA,GAAG,CAAC,CAAA,CAAA,CAAA,CAAA;AAAA,KAC/C;AAAA,GACF,CAAA;AAkBF;;;;"}
1
+ {"version":3,"file":"createExtension.esm.js","sources":["../../src/wiring/createExtension.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 { AppNode } from '../apis';\nimport { PortableSchema, createSchemaFromZod } from '../schema';\nimport { Expand } from '../types';\nimport {\n AnyExtensionDataRef,\n ExtensionDataRef,\n ExtensionDataValue,\n} from './createExtensionDataRef';\nimport { ExtensionInput, LegacyExtensionInput } from './createExtensionInput';\nimport { z } from 'zod';\n\n/**\n * @public\n * @deprecated Extension data maps will be removed.\n */\nexport type AnyExtensionDataMap = {\n [name in string]: AnyExtensionDataRef;\n};\n\n/**\n * @public\n * @deprecated This type will be removed.\n */\nexport type AnyExtensionInputMap = {\n [inputName in string]: LegacyExtensionInput<\n AnyExtensionDataMap,\n { optional: boolean; singleton: boolean }\n >;\n};\n\n/**\n * Converts an extension data map into the matching concrete data values type.\n * @public\n * @deprecated Extension data maps will be removed.\n */\nexport type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? never\n : DataName]: TExtensionData[DataName]['T'];\n} & {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? DataName\n : never]?: TExtensionData[DataName]['T'];\n};\n\n/** @public */\nexport type ExtensionDataContainer<UExtensionData extends AnyExtensionDataRef> =\n {\n get<TId extends UExtensionData['id']>(\n ref: ExtensionDataRef<any, TId, any>,\n ): UExtensionData extends ExtensionDataRef<infer IData, TId, infer IConfig>\n ? IConfig['optional'] extends true\n ? IData | undefined\n : IData\n : never;\n };\n\n/**\n * Convert a single extension input into a matching resolved input.\n * @public\n */\nexport type ResolvedExtensionInput<\n TExtensionInput extends ExtensionInput<any, any>,\n> = TExtensionInput['extensionData'] extends Array<AnyExtensionDataRef>\n ? {\n node: AppNode;\n } & ExtensionDataContainer<TExtensionInput['extensionData'][number]>\n : TExtensionInput['extensionData'] extends AnyExtensionDataMap\n ? {\n node: AppNode;\n output: ExtensionDataValues<TExtensionInput['extensionData']>;\n }\n : never;\n\n/**\n * Converts an extension input map into a matching collection of resolved inputs.\n * @public\n */\nexport type ResolvedExtensionInputs<\n TInputs extends {\n [name in string]: ExtensionInput<any, any> | LegacyExtensionInput<any, any>;\n },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ResolvedExtensionInput<TInputs[InputName]>>\n : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>;\n};\n\n/**\n * @public\n * @deprecated This way of structuring the options is deprecated, this type will be removed in the future\n */\nexport interface LegacyCreateExtensionOptions<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n> {\n kind?: string;\n namespace?: string;\n name?: string;\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: TOutput;\n /** @deprecated - use `config.schema` instead */\n configSchema?: PortableSchema<TConfig, TConfigInput>;\n config?: {\n schema: TConfigSchema;\n };\n factory(context: {\n node: AppNode;\n config: TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n });\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }): Expand<ExtensionDataValues<TOutput>>;\n}\n\n/** @ignore */\nexport type VerifyExtensionFactoryOutput<\n UDeclaredOutput extends AnyExtensionDataRef,\n UFactoryOutput extends ExtensionDataValue<any, any>,\n> = (\n UDeclaredOutput extends any\n ? UDeclaredOutput['config']['optional'] extends true\n ? never\n : UDeclaredOutput['id']\n : never\n) extends infer IRequiredOutputIds\n ? [IRequiredOutputIds] extends [UFactoryOutput['id']]\n ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']]\n ? {}\n : {\n 'Error: The extension factory has undeclared output(s)': Exclude<\n UFactoryOutput['id'],\n UDeclaredOutput['id']\n >;\n }\n : {\n 'Error: The extension factory is missing the following output(s)': Exclude<\n IRequiredOutputIds,\n UFactoryOutput['id']\n >;\n }\n : never;\n\n/** @public */\nexport type CreateExtensionOptions<\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n> = {\n kind?: string;\n namespace?: string;\n name?: string;\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: Array<UOutput>;\n /** @deprecated - use `config.schema` instead */\n configSchema?: PortableSchema<TConfig, TConfigInput>;\n config?: {\n schema: TConfigSchema;\n };\n factory(context: {\n node: AppNode;\n config: TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n });\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }): Iterable<UFactoryOutput>;\n} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;\n\n/** @public */\nexport interface ExtensionDefinition<TConfig, TConfigInput = TConfig> {\n $$type: '@backstage/ExtensionDefinition';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: { id: string; input: string };\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<TConfig, TConfigInput>;\n}\n\n/** @internal */\nexport type InternalExtensionDefinition<TConfig, TConfigInput> =\n ExtensionDefinition<TConfig, TConfigInput> &\n (\n | {\n readonly version: 'v1';\n readonly inputs: AnyExtensionInputMap;\n readonly output: AnyExtensionDataMap;\n factory(context: {\n node: AppNode;\n config: TConfig;\n inputs: ResolvedExtensionInputs<AnyExtensionInputMap>;\n }): ExtensionDataValues<any>;\n }\n | {\n readonly version: 'v2';\n readonly inputs: {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n };\n readonly output: Array<AnyExtensionDataRef>;\n factory(context: {\n node: AppNode;\n config: TConfig;\n inputs: ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n }>;\n }): Iterable<ExtensionDataValue<any, any>>;\n }\n );\n\n/** @internal */\nexport function toInternalExtensionDefinition<TConfig, TConfigInput>(\n overrides: ExtensionDefinition<TConfig, TConfigInput>,\n): InternalExtensionDefinition<TConfig, TConfigInput> {\n const internal = overrides as InternalExtensionDefinition<\n TConfig,\n TConfigInput\n >;\n if (internal.$$type !== '@backstage/ExtensionDefinition') {\n throw new Error(\n `Invalid extension definition instance, bad type '${internal.$$type}'`,\n );\n }\n const version = internal.version;\n if (version !== 'v1' && version !== 'v2') {\n throw new Error(\n `Invalid extension definition instance, bad version '${version}'`,\n );\n }\n return internal;\n}\n\n/** @public */\nexport function createExtension<\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n>(\n options: CreateExtensionOptions<\n UOutput,\n TInputs,\n TConfig,\n TConfigInput,\n TConfigSchema,\n UFactoryOutput\n >,\n): ExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n>;\n/**\n * @public\n * @deprecated - use the array format of `output` instead, see TODO-doc-link\n */\nexport function createExtension<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n>(\n options: LegacyCreateExtensionOptions<\n TOutput,\n TInputs,\n TConfig,\n TConfigInput,\n TConfigSchema\n >,\n): ExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n>;\nexport function createExtension<\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TLegacyInputs extends AnyExtensionInputMap,\n TConfig,\n TConfigInput,\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n>(\n options:\n | CreateExtensionOptions<\n UOutput,\n TInputs,\n TConfig,\n TConfigInput,\n TConfigSchema,\n UFactoryOutput\n >\n | LegacyCreateExtensionOptions<\n AnyExtensionDataMap,\n TLegacyInputs,\n TConfig,\n TConfigInput,\n TConfigSchema\n >,\n): ExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n> {\n const newConfigSchema = options.config?.schema;\n if (newConfigSchema && options.configSchema) {\n throw new Error(`Cannot provide both configSchema and config.schema`);\n }\n const configSchema = newConfigSchema\n ? createSchemaFromZod(innerZ =>\n innerZ.object(\n Object.fromEntries(\n Object.entries(newConfigSchema).map(([k, v]) => [k, v(innerZ)]),\n ),\n ),\n )\n : options.configSchema;\n\n return {\n $$type: '@backstage/ExtensionDefinition',\n version: Symbol.iterator in options.output ? 'v2' : 'v1',\n kind: options.kind,\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo,\n disabled: options.disabled ?? false,\n inputs: options.inputs ?? {},\n output: options.output,\n configSchema,\n factory: options.factory,\n toString() {\n const parts: string[] = [];\n if (options.kind) {\n parts.push(`kind=${options.kind}`);\n }\n if (options.namespace) {\n parts.push(`namespace=${options.namespace}`);\n }\n if (options.name) {\n parts.push(`name=${options.name}`);\n }\n parts.push(`attachTo=${options.attachTo.id}@${options.attachTo.input}`);\n return `ExtensionDefinition{${parts.join(',')}}`;\n },\n } as InternalExtensionDefinition<\n TConfig &\n (string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n }),\n TConfigInput &\n (string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >)\n >;\n}\n"],"names":[],"mappings":";;AAuQO,SAAS,8BACd,SACoD,EAAA;AACpD,EAAA,MAAM,QAAW,GAAA,SAAA,CAAA;AAIjB,EAAI,IAAA,QAAA,CAAS,WAAW,gCAAkC,EAAA;AACxD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iDAAA,EAAoD,SAAS,MAAM,CAAA,CAAA,CAAA;AAAA,KACrE,CAAA;AAAA,GACF;AACA,EAAA,MAAM,UAAU,QAAS,CAAA,OAAA,CAAA;AACzB,EAAI,IAAA,OAAA,KAAY,IAAQ,IAAA,OAAA,KAAY,IAAM,EAAA;AACxC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,uDAAuD,OAAO,CAAA,CAAA,CAAA;AAAA,KAChE,CAAA;AAAA,GACF;AACA,EAAO,OAAA,QAAA,CAAA;AACT,CAAA;AA0EO,SAAS,gBAcd,OA+BA,EAAA;AACA,EAAM,MAAA,eAAA,GAAkB,QAAQ,MAAQ,EAAA,MAAA,CAAA;AACxC,EAAI,IAAA,eAAA,IAAmB,QAAQ,YAAc,EAAA;AAC3C,IAAM,MAAA,IAAI,MAAM,CAAoD,kDAAA,CAAA,CAAA,CAAA;AAAA,GACtE;AACA,EAAA,MAAM,eAAe,eACjB,GAAA,mBAAA;AAAA,IAAoB,YAClB,MAAO,CAAA,MAAA;AAAA,MACL,MAAO,CAAA,WAAA;AAAA,QACL,MAAO,CAAA,OAAA,CAAQ,eAAe,CAAA,CAAE,IAAI,CAAC,CAAC,CAAG,EAAA,CAAC,MAAM,CAAC,CAAA,EAAG,CAAE,CAAA,MAAM,CAAC,CAAC,CAAA;AAAA,OAChE;AAAA,KACF;AAAA,MAEF,OAAQ,CAAA,YAAA,CAAA;AAEZ,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,gCAAA;AAAA,IACR,OAAS,EAAA,MAAA,CAAO,QAAY,IAAA,OAAA,CAAQ,SAAS,IAAO,GAAA,IAAA;AAAA,IACpD,MAAM,OAAQ,CAAA,IAAA;AAAA,IACd,WAAW,OAAQ,CAAA,SAAA;AAAA,IACnB,MAAM,OAAQ,CAAA,IAAA;AAAA,IACd,UAAU,OAAQ,CAAA,QAAA;AAAA,IAClB,QAAA,EAAU,QAAQ,QAAY,IAAA,KAAA;AAAA,IAC9B,MAAA,EAAQ,OAAQ,CAAA,MAAA,IAAU,EAAC;AAAA,IAC3B,QAAQ,OAAQ,CAAA,MAAA;AAAA,IAChB,YAAA;AAAA,IACA,SAAS,OAAQ,CAAA,OAAA;AAAA,IACjB,QAAW,GAAA;AACT,MAAA,MAAM,QAAkB,EAAC,CAAA;AACzB,MAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,QAAA,KAAA,CAAM,IAAK,CAAA,CAAA,KAAA,EAAQ,OAAQ,CAAA,IAAI,CAAE,CAAA,CAAA,CAAA;AAAA,OACnC;AACA,MAAA,IAAI,QAAQ,SAAW,EAAA;AACrB,QAAA,KAAA,CAAM,IAAK,CAAA,CAAA,UAAA,EAAa,OAAQ,CAAA,SAAS,CAAE,CAAA,CAAA,CAAA;AAAA,OAC7C;AACA,MAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,QAAA,KAAA,CAAM,IAAK,CAAA,CAAA,KAAA,EAAQ,OAAQ,CAAA,IAAI,CAAE,CAAA,CAAA,CAAA;AAAA,OACnC;AACA,MAAM,KAAA,CAAA,IAAA,CAAK,YAAY,OAAQ,CAAA,QAAA,CAAS,EAAE,CAAI,CAAA,EAAA,OAAA,CAAQ,QAAS,CAAA,KAAK,CAAE,CAAA,CAAA,CAAA;AACtE,MAAA,OAAO,CAAuB,oBAAA,EAAA,KAAA,CAAM,IAAK,CAAA,GAAG,CAAC,CAAA,CAAA,CAAA,CAAA;AAAA,KAC/C;AAAA,GACF,CAAA;AAkBF;;;;"}
@@ -7,14 +7,17 @@ class ExtensionBlueprintImpl {
7
7
  }
8
8
  dataRefs;
9
9
  make(args) {
10
+ const optionsSchema = typeof this.options.config?.schema === "function" ? this.options.config?.schema(args.params) : this.options.config?.schema;
10
11
  const schema = {
11
- ...this.options.config?.schema,
12
+ ...optionsSchema,
12
13
  ...args.config?.schema
13
14
  };
15
+ const namespace = typeof this.options.namespace === "function" ? this.options.namespace(args.params) : this.options.namespace;
16
+ const name = typeof this.options.name === "function" ? this.options.name(args.params) : this.options.name;
14
17
  return createExtension({
15
18
  kind: this.options.kind,
16
- namespace: args.namespace ?? this.options.namespace,
17
- name: args.name,
19
+ namespace: args.namespace ?? namespace,
20
+ name: args.name ?? name,
18
21
  attachTo: args.attachTo ?? this.options.attachTo,
19
22
  disabled: args.disabled ?? this.options.disabled,
20
23
  inputs: args.inputs ?? this.options.inputs,
@@ -1 +1 @@
1
- {"version":3,"file":"createExtensionBlueprint.esm.js","sources":["../../src/wiring/createExtensionBlueprint.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { AppNode } from '../apis';\nimport { Expand } from '../types';\nimport {\n CreateExtensionOptions,\n ExtensionDefinition,\n ResolvedExtensionInputs,\n VerifyExtensionFactoryOutput,\n createExtension,\n} from './createExtension';\nimport { z } from 'zod';\nimport { ExtensionInput } from './createExtensionInput';\nimport {\n AnyExtensionDataRef,\n ExtensionDataRefToValue,\n ExtensionDataValue,\n} from './createExtensionDataRef';\n\n/**\n * @public\n */\nexport type CreateExtensionBlueprintOptions<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n TDataRefs extends { [name in string]: AnyExtensionDataRef },\n> = {\n kind: string;\n namespace?: string;\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: Array<UOutput>;\n config?: {\n schema: TConfigSchema;\n };\n factory(\n params: TParams,\n context: {\n node: AppNode;\n config: {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n\n dataRefs?: TDataRefs;\n} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;\n\n/**\n * @public\n */\nexport interface ExtensionBlueprint<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n UExtraOutput extends AnyExtensionDataRef,\n TConfig extends { [key in string]: unknown },\n TConfigInput extends { [key in string]: unknown },\n TDataRefs extends { [name in string]: AnyExtensionDataRef },\n> {\n dataRefs: TDataRefs;\n\n /**\n * Creates a new extension from the blueprint.\n *\n * You must either pass `params` directly, or define a `factory` that can\n * optionally call the original factory with the same params.\n */\n make<\n TExtensionConfigSchema extends {\n [key in string]: (zImpl: typeof z) => z.ZodType;\n },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n >(\n args: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output?: Array<UExtraOutput>;\n config?: {\n schema: TExtensionConfigSchema & {\n [KName in keyof TConfig]?: `Error: Config key '${KName &\n string}' is already defined in parent schema`;\n };\n };\n } & (\n | ({\n factory(\n originalFactory: (\n params: TParams,\n context?: {\n config?: TConfig;\n inputs?: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ) => Iterable<ExtensionDataRefToValue<UOutput>>,\n context: {\n node: AppNode;\n config: TConfig & {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n } & VerifyExtensionFactoryOutput<\n UOutput & UExtraOutput,\n UFactoryOutput\n >)\n | {\n params: TParams;\n }\n ),\n ): ExtensionDefinition<\n {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & TConfig,\n z.input<\n z.ZodObject<{\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n }>\n > &\n TConfigInput\n >;\n}\n\n/**\n * @internal\n */\nclass ExtensionBlueprintImpl<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n UExtraOutput extends AnyExtensionDataRef,\n TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },\n TDataRefs extends { [name in string]: AnyExtensionDataRef },\n> {\n constructor(\n private readonly options: CreateExtensionBlueprintOptions<\n TParams,\n UOutput,\n TInputs,\n TConfigSchema,\n any,\n TDataRefs\n >,\n ) {\n this.dataRefs = options.dataRefs!;\n }\n\n dataRefs: TDataRefs;\n\n public make<\n TExtensionConfigSchema extends {\n [key in string]: (zImpl: typeof z) => z.ZodType;\n },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n >(args: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output?: Array<UExtraOutput>;\n params?: TParams;\n config?: {\n schema: TExtensionConfigSchema;\n };\n factory?(\n originalFactory: (\n params: TParams,\n context?: {\n config?: {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n };\n inputs?: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ) => Iterable<ExtensionDataRefToValue<UOutput>>,\n context: {\n node: AppNode;\n config: {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n }): ExtensionDefinition<\n {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n },\n z.input<\n z.ZodObject<\n {\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n } & {\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }\n >\n >\n > {\n const schema = {\n ...this.options.config?.schema,\n ...args.config?.schema,\n } as TConfigSchema & TExtensionConfigSchema;\n return createExtension({\n kind: this.options.kind,\n namespace: args.namespace ?? this.options.namespace,\n name: args.name,\n attachTo: args.attachTo ?? this.options.attachTo,\n disabled: args.disabled ?? this.options.disabled,\n inputs: args.inputs ?? this.options.inputs,\n output: [...(args.output ?? []), ...this.options.output],\n config: Object.keys(schema).length === 0 ? undefined : { schema },\n factory: ({ node, config, inputs }) => {\n if (args.factory) {\n return args.factory(\n (\n innerParams: TParams,\n innerContext?: {\n config?: {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n };\n inputs?: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<ExtensionDataRefToValue<UOutput>> => {\n return this.options.factory(innerParams, {\n node,\n config: innerContext?.config ?? config,\n inputs: innerContext?.inputs ?? inputs,\n });\n },\n {\n node,\n config,\n inputs,\n },\n );\n } else if (args.params) {\n return this.options.factory(args.params, {\n node,\n config,\n inputs,\n });\n }\n throw new Error('Either params or factory must be provided');\n },\n } as CreateExtensionOptions<\n UOutput,\n TInputs,\n {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n },\n z.input<\n z.ZodObject<\n {\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n } & {\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }\n >\n >,\n TConfigSchema,\n UFactoryOutput\n >);\n }\n}\n\n/**\n * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating\n * types and instances of those types.\n *\n * @public\n */\nexport function createExtensionBlueprint<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n UExtraOutput extends AnyExtensionDataRef,\n TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n TDataRefs extends { [name in string]: AnyExtensionDataRef } = never,\n>(\n options: CreateExtensionBlueprintOptions<\n TParams,\n UOutput,\n TInputs,\n TConfigSchema,\n UFactoryOutput,\n TDataRefs\n >,\n): ExtensionBlueprint<\n TParams,\n UOutput,\n TInputs,\n UExtraOutput,\n string extends keyof TConfigSchema\n ? {}\n : { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>> },\n string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >,\n TDataRefs\n> {\n return new ExtensionBlueprintImpl(options) as ExtensionBlueprint<\n TParams,\n UOutput,\n TInputs,\n UExtraOutput,\n string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n },\n string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >,\n TDataRefs\n >;\n}\n"],"names":[],"mappings":";;AAoKA,MAAM,sBAYJ,CAAA;AAAA,EACA,YACmB,OAQjB,EAAA;AARiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA,CAAA;AASjB,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA,CAAA;AAAA,GAC1B;AAAA,EAEA,QAAA,CAAA;AAAA,EAEO,KAKL,IAsDA,EAAA;AACA,IAAA,MAAM,MAAS,GAAA;AAAA,MACb,GAAG,IAAK,CAAA,OAAA,CAAQ,MAAQ,EAAA,MAAA;AAAA,MACxB,GAAG,KAAK,MAAQ,EAAA,MAAA;AAAA,KAClB,CAAA;AACA,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,IAAA,EAAM,KAAK,OAAQ,CAAA,IAAA;AAAA,MACnB,SAAW,EAAA,IAAA,CAAK,SAAa,IAAA,IAAA,CAAK,OAAQ,CAAA,SAAA;AAAA,MAC1C,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,QAAU,EAAA,IAAA,CAAK,QAAY,IAAA,IAAA,CAAK,OAAQ,CAAA,QAAA;AAAA,MACxC,QAAU,EAAA,IAAA,CAAK,QAAY,IAAA,IAAA,CAAK,OAAQ,CAAA,QAAA;AAAA,MACxC,MAAQ,EAAA,IAAA,CAAK,MAAU,IAAA,IAAA,CAAK,OAAQ,CAAA,MAAA;AAAA,MACpC,MAAA,EAAQ,CAAC,GAAI,IAAK,CAAA,MAAA,IAAU,EAAK,EAAA,GAAG,IAAK,CAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,MACvD,MAAA,EAAQ,OAAO,IAAK,CAAA,MAAM,EAAE,MAAW,KAAA,CAAA,GAAI,KAAY,CAAA,GAAA,EAAE,MAAO,EAAA;AAAA,MAChE,SAAS,CAAC,EAAE,IAAM,EAAA,MAAA,EAAQ,QAAa,KAAA;AACrC,QAAA,IAAI,KAAK,OAAS,EAAA;AAChB,UAAA,OAAO,IAAK,CAAA,OAAA;AAAA,YACV,CACE,aACA,YAQ+C,KAAA;AAC/C,cAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,CAAQ,WAAa,EAAA;AAAA,gBACvC,IAAA;AAAA,gBACA,MAAA,EAAQ,cAAc,MAAU,IAAA,MAAA;AAAA,gBAChC,MAAA,EAAQ,cAAc,MAAU,IAAA,MAAA;AAAA,eACjC,CAAA,CAAA;AAAA,aACH;AAAA,YACA;AAAA,cACE,IAAA;AAAA,cACA,MAAA;AAAA,cACA,MAAA;AAAA,aACF;AAAA,WACF,CAAA;AAAA,SACF,MAAA,IAAW,KAAK,MAAQ,EAAA;AACtB,UAAA,OAAO,IAAK,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA,CAAK,MAAQ,EAAA;AAAA,YACvC,IAAA;AAAA,YACA,MAAA;AAAA,YACA,MAAA;AAAA,WACD,CAAA,CAAA;AAAA,SACH;AACA,QAAM,MAAA,IAAI,MAAM,2CAA2C,CAAA,CAAA;AAAA,OAC7D;AAAA,KAwBD,CAAA,CAAA;AAAA,GACH;AACF,CAAA;AAQO,SAAS,yBAcd,OAwBA,EAAA;AACA,EAAO,OAAA,IAAI,uBAAuB,OAAO,CAAA,CAAA;AAmB3C;;;;"}
1
+ {"version":3,"file":"createExtensionBlueprint.esm.js","sources":["../../src/wiring/createExtensionBlueprint.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { AppNode } from '../apis';\nimport { Expand } from '../types';\nimport {\n CreateExtensionOptions,\n ExtensionDefinition,\n ResolvedExtensionInputs,\n VerifyExtensionFactoryOutput,\n createExtension,\n} from './createExtension';\nimport { z } from 'zod';\nimport { ExtensionInput } from './createExtensionInput';\nimport {\n AnyExtensionDataRef,\n ExtensionDataRefToValue,\n ExtensionDataValue,\n} from './createExtensionDataRef';\n\n/**\n * @public\n */\nexport type CreateExtensionBlueprintOptions<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n TDataRefs extends { [name in string]: AnyExtensionDataRef },\n> = {\n kind: string;\n namespace?: string | ((params: TParams) => string);\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: Array<UOutput>;\n name?: string | ((params: TParams) => string);\n config?: {\n schema: TConfigSchema | ((params: TParams) => TConfigSchema);\n };\n factory(\n params: TParams,\n context: {\n node: AppNode;\n config: {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n\n dataRefs?: TDataRefs;\n} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;\n\n/**\n * @public\n */\nexport interface ExtensionBlueprint<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n UExtraOutput extends AnyExtensionDataRef,\n TConfig extends { [key in string]: unknown },\n TConfigInput extends { [key in string]: unknown },\n TDataRefs extends { [name in string]: AnyExtensionDataRef },\n> {\n dataRefs: TDataRefs;\n\n /**\n * Creates a new extension from the blueprint.\n *\n * You must either pass `params` directly, or define a `factory` that can\n * optionally call the original factory with the same params.\n */\n make<\n TExtensionConfigSchema extends {\n [key in string]: (zImpl: typeof z) => z.ZodType;\n },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n >(\n args: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output?: Array<UExtraOutput>;\n config?: {\n schema: TExtensionConfigSchema & {\n [KName in keyof TConfig]?: `Error: Config key '${KName &\n string}' is already defined in parent schema`;\n };\n };\n } & (\n | ({\n factory(\n originalFactory: (\n params: TParams,\n context?: {\n config?: TConfig;\n inputs?: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ) => Iterable<ExtensionDataRefToValue<UOutput>>,\n context: {\n node: AppNode;\n config: TConfig & {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n } & VerifyExtensionFactoryOutput<\n UOutput & UExtraOutput,\n UFactoryOutput\n >)\n | {\n params: TParams;\n }\n ),\n ): ExtensionDefinition<\n {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & TConfig,\n z.input<\n z.ZodObject<{\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n }>\n > &\n TConfigInput\n >;\n}\n\n/**\n * @internal\n */\nclass ExtensionBlueprintImpl<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n UExtraOutput extends AnyExtensionDataRef,\n TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },\n TDataRefs extends { [name in string]: AnyExtensionDataRef },\n> {\n constructor(\n private readonly options: CreateExtensionBlueprintOptions<\n TParams,\n UOutput,\n TInputs,\n TConfigSchema,\n any,\n TDataRefs\n >,\n ) {\n this.dataRefs = options.dataRefs!;\n }\n\n dataRefs: TDataRefs;\n\n public make<\n TExtensionConfigSchema extends {\n [key in string]: (zImpl: typeof z) => z.ZodType;\n },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n >(args: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output?: Array<UExtraOutput>;\n params?: TParams;\n config?: {\n schema: TExtensionConfigSchema;\n };\n factory?(\n originalFactory: (\n params: TParams,\n context?: {\n config?: {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n };\n inputs?: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ) => Iterable<ExtensionDataRefToValue<UOutput>>,\n context: {\n node: AppNode;\n config: {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n }): ExtensionDefinition<\n {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n },\n z.input<\n z.ZodObject<\n {\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n } & {\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }\n >\n >\n > {\n const optionsSchema =\n typeof this.options.config?.schema === 'function'\n ? this.options.config?.schema(args.params!)\n : this.options.config?.schema;\n\n const schema = {\n ...optionsSchema,\n ...args.config?.schema,\n } as TConfigSchema & TExtensionConfigSchema;\n\n const namespace =\n typeof this.options.namespace === 'function'\n ? this.options.namespace(args.params!)\n : this.options.namespace;\n\n const name =\n typeof this.options.name === 'function'\n ? this.options.name(args.params!)\n : this.options.name;\n\n return createExtension({\n kind: this.options.kind,\n namespace: args.namespace ?? namespace,\n name: args.name ?? name,\n attachTo: args.attachTo ?? this.options.attachTo,\n disabled: args.disabled ?? this.options.disabled,\n inputs: args.inputs ?? this.options.inputs,\n output: [...(args.output ?? []), ...this.options.output],\n config: Object.keys(schema).length === 0 ? undefined : { schema },\n factory: ({ node, config, inputs }) => {\n if (args.factory) {\n return args.factory(\n (\n innerParams: TParams,\n innerContext?: {\n config?: {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n };\n inputs?: Expand<ResolvedExtensionInputs<TInputs>>;\n },\n ): Iterable<ExtensionDataRefToValue<UOutput>> => {\n return this.options.factory(innerParams, {\n node,\n config: innerContext?.config ?? config,\n inputs: innerContext?.inputs ?? inputs,\n });\n },\n {\n node,\n config,\n inputs,\n },\n );\n } else if (args.params) {\n return this.options.factory(args.params, {\n node,\n config,\n inputs,\n });\n }\n throw new Error('Either params or factory must be provided');\n },\n } as CreateExtensionOptions<\n UOutput,\n TInputs,\n {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n } & {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n },\n z.input<\n z.ZodObject<\n {\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n } & {\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }\n >\n >,\n TConfigSchema,\n UFactoryOutput\n >);\n }\n}\n\n/**\n * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating\n * types and instances of those types.\n *\n * @public\n */\nexport function createExtensionBlueprint<\n TParams,\n UOutput extends AnyExtensionDataRef,\n TInputs extends {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n UExtraOutput extends AnyExtensionDataRef,\n TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n TDataRefs extends { [name in string]: AnyExtensionDataRef } = never,\n>(\n options: CreateExtensionBlueprintOptions<\n TParams,\n UOutput,\n TInputs,\n TConfigSchema,\n UFactoryOutput,\n TDataRefs\n >,\n): ExtensionBlueprint<\n TParams,\n UOutput,\n TInputs,\n UExtraOutput,\n string extends keyof TConfigSchema\n ? {}\n : { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>> },\n string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >,\n TDataRefs\n> {\n return new ExtensionBlueprintImpl(options) as ExtensionBlueprint<\n TParams,\n UOutput,\n TInputs,\n UExtraOutput,\n string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n },\n string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >,\n TDataRefs\n >;\n}\n"],"names":[],"mappings":";;AAqKA,MAAM,sBAYJ,CAAA;AAAA,EACA,YACmB,OAQjB,EAAA;AARiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA,CAAA;AASjB,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA,CAAA;AAAA,GAC1B;AAAA,EAEA,QAAA,CAAA;AAAA,EAEO,KAKL,IAsDA,EAAA;AACA,IAAA,MAAM,gBACJ,OAAO,IAAA,CAAK,OAAQ,CAAA,MAAA,EAAQ,WAAW,UACnC,GAAA,IAAA,CAAK,OAAQ,CAAA,MAAA,EAAQ,OAAO,IAAK,CAAA,MAAO,CACxC,GAAA,IAAA,CAAK,QAAQ,MAAQ,EAAA,MAAA,CAAA;AAE3B,IAAA,MAAM,MAAS,GAAA;AAAA,MACb,GAAG,aAAA;AAAA,MACH,GAAG,KAAK,MAAQ,EAAA,MAAA;AAAA,KAClB,CAAA;AAEA,IAAA,MAAM,SACJ,GAAA,OAAO,IAAK,CAAA,OAAA,CAAQ,SAAc,KAAA,UAAA,GAC9B,IAAK,CAAA,OAAA,CAAQ,SAAU,CAAA,IAAA,CAAK,MAAO,CAAA,GACnC,KAAK,OAAQ,CAAA,SAAA,CAAA;AAEnB,IAAA,MAAM,IACJ,GAAA,OAAO,IAAK,CAAA,OAAA,CAAQ,IAAS,KAAA,UAAA,GACzB,IAAK,CAAA,OAAA,CAAQ,IAAK,CAAA,IAAA,CAAK,MAAO,CAAA,GAC9B,KAAK,OAAQ,CAAA,IAAA,CAAA;AAEnB,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,IAAA,EAAM,KAAK,OAAQ,CAAA,IAAA;AAAA,MACnB,SAAA,EAAW,KAAK,SAAa,IAAA,SAAA;AAAA,MAC7B,IAAA,EAAM,KAAK,IAAQ,IAAA,IAAA;AAAA,MACnB,QAAU,EAAA,IAAA,CAAK,QAAY,IAAA,IAAA,CAAK,OAAQ,CAAA,QAAA;AAAA,MACxC,QAAU,EAAA,IAAA,CAAK,QAAY,IAAA,IAAA,CAAK,OAAQ,CAAA,QAAA;AAAA,MACxC,MAAQ,EAAA,IAAA,CAAK,MAAU,IAAA,IAAA,CAAK,OAAQ,CAAA,MAAA;AAAA,MACpC,MAAA,EAAQ,CAAC,GAAI,IAAK,CAAA,MAAA,IAAU,EAAK,EAAA,GAAG,IAAK,CAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,MACvD,MAAA,EAAQ,OAAO,IAAK,CAAA,MAAM,EAAE,MAAW,KAAA,CAAA,GAAI,KAAY,CAAA,GAAA,EAAE,MAAO,EAAA;AAAA,MAChE,SAAS,CAAC,EAAE,IAAM,EAAA,MAAA,EAAQ,QAAa,KAAA;AACrC,QAAA,IAAI,KAAK,OAAS,EAAA;AAChB,UAAA,OAAO,IAAK,CAAA,OAAA;AAAA,YACV,CACE,aACA,YAQ+C,KAAA;AAC/C,cAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,CAAQ,WAAa,EAAA;AAAA,gBACvC,IAAA;AAAA,gBACA,MAAA,EAAQ,cAAc,MAAU,IAAA,MAAA;AAAA,gBAChC,MAAA,EAAQ,cAAc,MAAU,IAAA,MAAA;AAAA,eACjC,CAAA,CAAA;AAAA,aACH;AAAA,YACA;AAAA,cACE,IAAA;AAAA,cACA,MAAA;AAAA,cACA,MAAA;AAAA,aACF;AAAA,WACF,CAAA;AAAA,SACF,MAAA,IAAW,KAAK,MAAQ,EAAA;AACtB,UAAA,OAAO,IAAK,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA,CAAK,MAAQ,EAAA;AAAA,YACvC,IAAA;AAAA,YACA,MAAA;AAAA,YACA,MAAA;AAAA,WACD,CAAA,CAAA;AAAA,SACH;AACA,QAAM,MAAA,IAAI,MAAM,2CAA2C,CAAA,CAAA;AAAA,OAC7D;AAAA,KAwBD,CAAA,CAAA;AAAA,GACH;AACF,CAAA;AAQO,SAAS,yBAcd,OAwBA,EAAA;AACA,EAAO,OAAA,IAAI,uBAAuB,OAAO,CAAA,CAAA;AAmB3C;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/frontend-plugin-api",
3
- "version": "0.6.8-next.1",
3
+ "version": "0.7.0-next.2",
4
4
  "backstage": {
5
5
  "role": "web-library"
6
6
  },
@@ -42,10 +42,10 @@
42
42
  "zod-to-json-schema": "^3.21.4"
43
43
  },
44
44
  "devDependencies": {
45
- "@backstage/cli": "^0.27.0-next.1",
46
- "@backstage/frontend-app-api": "^0.7.5-next.1",
47
- "@backstage/frontend-test-utils": "^0.1.12-next.1",
48
- "@backstage/test-utils": "^1.5.10-next.1",
45
+ "@backstage/cli": "^0.27.0-next.3",
46
+ "@backstage/frontend-app-api": "^0.7.5-next.2",
47
+ "@backstage/frontend-test-utils": "^0.1.12-next.2",
48
+ "@backstage/test-utils": "^1.5.10-next.2",
49
49
  "@testing-library/jest-dom": "^6.0.0",
50
50
  "@testing-library/react": "^15.0.0",
51
51
  "history": "^5.3.0"