@backstage/frontend-plugin-api 0.16.2 → 0.17.0-next.1

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,16 +1,26 @@
1
1
  # @backstage/frontend-plugin-api
2
2
 
3
- ## 0.16.2
3
+ ## 0.17.0-next.1
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - bc41a91: Updated error messages and deprecation warnings to clarify that the `zod/v4` subpath export from the Zod v3 package is not supported by `configSchema`, since it does not include JSON Schema conversion. The `zod` dependency has been bumped to `^4.0.0`.
7
+ - ab1cdbb: Removed a handful of internal imports that referenced the package by its own name. Value imports were switched to relative paths, and type-only imports to `import type`. These self-referential imports could trigger circular initialization errors in bundled ESM and when the package was loaded via `jest.requireActual` most visibly `Cannot access '_AppRootElementBlueprintesm' before initialization` from `@backstage/frontend-plugin-api`. There are no user-facing API changes.
8
8
 
9
- ## 0.16.1
9
+ ## 0.17.0-next.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 8738203: **BREAKING**: Removed the deprecated property form of `PortableSchema.schema`. The `schema` member is now a plain method that must be called as `schema()` — direct property access like `schema.type` or `schema.properties` is no longer supported.
10
14
 
11
15
  ### Patch Changes
12
16
 
13
- - 6b60bd7: Replaced old config schema values from existing extensions and blueprints.
17
+ - cad156e: Replaced old config schema values from existing extensions and blueprints.
18
+ - 72a552f: Updated error messages and deprecation warnings to clarify that the `zod/v4` subpath export from the Zod v3 package is not supported by `configSchema`, since it does not include JSON Schema conversion. The `zod` dependency has been bumped to `^4.0.0`.
19
+ - Updated dependencies
20
+ - @backstage/errors@1.3.1-next.0
21
+ - @backstage/filter-predicates@0.1.3-next.0
22
+ - @backstage/types@1.2.2
23
+ - @backstage/version-bridge@1.0.12
14
24
 
15
25
  ## 0.16.0
16
26
 
package/dist/alpha.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AnyRouteRefParams, e as ApiHolder, d as ApiRef, b as AppNode, i as AppNodeEdges, j as AppNodeInstance, k as AppNodeSpec, l as AppTree, C as ConfigurableExtensionDataRef, r as Extension, s as ExtensionAttachTo, t as ExtensionBlueprint, u as ExtensionBlueprintDefineParams, v as ExtensionBlueprintParameters, w as ExtensionBlueprintParams, x as ExtensionDataContainer, y as ExtensionDataRef, z as ExtensionDataValue, B as ExtensionDefinition, D as ExtensionDefinitionAttachTo, G as ExtensionDefinitionParameters, J as ExtensionInput, E as ExternalRouteRef, c as FrontendPlugin, M as FrontendPluginInfo, I as IconElement, O as OverridableExtensionDefinition, U as PluginWrapperApi, V as PluginWrapperBlueprint, W as PluginWrapperDefinition, X as PortableSchema, R as RouteRef, S as SubRouteRef, $ as createExtensionBlueprintParams, a7 as pluginWrapperApiRef } from './types/alpha.d-D3gnSOzm.js';
1
+ export { A as AnyRouteRefParams, e as ApiHolder, d as ApiRef, b as AppNode, i as AppNodeEdges, j as AppNodeInstance, k as AppNodeSpec, l as AppTree, C as ConfigurableExtensionDataRef, r as Extension, s as ExtensionAttachTo, t as ExtensionBlueprint, u as ExtensionBlueprintDefineParams, v as ExtensionBlueprintParameters, w as ExtensionBlueprintParams, x as ExtensionDataContainer, y as ExtensionDataRef, z as ExtensionDataValue, B as ExtensionDefinition, D as ExtensionDefinitionAttachTo, G as ExtensionDefinitionParameters, J as ExtensionInput, E as ExternalRouteRef, c as FrontendPlugin, M as FrontendPluginInfo, I as IconElement, O as OverridableExtensionDefinition, U as PluginWrapperApi, V as PluginWrapperBlueprint, W as PluginWrapperDefinition, X as PortableSchema, R as RouteRef, S as SubRouteRef, $ as createExtensionBlueprintParams, a7 as pluginWrapperApiRef } from './types/alpha.d-CP8HTsBe.js';
2
2
  export { StandardSchemaV1 } from '@standard-schema/spec';
3
3
  import '@backstage/frontend-plugin-api';
4
4
  import 'react';
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { ExtensionBoundary } from '@backstage/frontend-plugin-api';
2
+ import { ExtensionBoundary } from '../components/ExtensionBoundary.esm.js';
3
3
  import { coreExtensionData } from '../wiring/coreExtensionData.esm.js';
4
4
  import 'zod/v3';
5
5
  import 'zod-to-json-schema';
@@ -1 +1 @@
1
- {"version":3,"file":"AppRootElementBlueprint.esm.js","sources":["../../src/blueprints/AppRootElementBlueprint.tsx"],"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 { ExtensionBoundary } from '@backstage/frontend-plugin-api';\nimport { coreExtensionData, createExtensionBlueprint } from '../wiring';\n\n/**\n * Creates extensions that render a React element at the app root, outside of\n * the app layout. This is useful for example for shared popups and similar.\n *\n * @public\n */\nexport const AppRootElementBlueprint = createExtensionBlueprint({\n kind: 'app-root-element',\n attachTo: { id: 'app/root', input: 'elements' },\n output: [coreExtensionData.reactElement],\n *factory(params: { element: JSX.Element }, { node }) {\n yield coreExtensionData.reactElement(\n <ExtensionBoundary node={node} errorPresentation=\"error-api\">\n {params.element}\n </ExtensionBoundary>,\n );\n },\n});\n"],"names":[],"mappings":";;;;;;;AAyBO,MAAM,0BAA0B,wBAAA,CAAyB;AAAA,EAC9D,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,EAAE,EAAA,EAAI,UAAA,EAAY,OAAO,UAAA,EAAW;AAAA,EAC9C,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,CAAC,OAAA,CAAQ,MAAA,EAAkC,EAAE,MAAK,EAAG;AACnD,IAAA,MAAM,iBAAA,CAAkB,YAAA;AAAA,0BACrB,iBAAA,EAAA,EAAkB,IAAA,EAAY,iBAAA,EAAkB,WAAA,EAC9C,iBAAO,OAAA,EACV;AAAA,KACF;AAAA,EACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"AppRootElementBlueprint.esm.js","sources":["../../src/blueprints/AppRootElementBlueprint.tsx"],"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 { ExtensionBoundary } from '../components/ExtensionBoundary';\nimport { coreExtensionData, createExtensionBlueprint } from '../wiring';\n\n/**\n * Creates extensions that render a React element at the app root, outside of\n * the app layout. This is useful for example for shared popups and similar.\n *\n * @public\n */\nexport const AppRootElementBlueprint = createExtensionBlueprint({\n kind: 'app-root-element',\n attachTo: { id: 'app/root', input: 'elements' },\n output: [coreExtensionData.reactElement],\n *factory(params: { element: JSX.Element }, { node }) {\n yield coreExtensionData.reactElement(\n <ExtensionBoundary node={node} errorPresentation=\"error-api\">\n {params.element}\n </ExtensionBoundary>,\n );\n },\n});\n"],"names":[],"mappings":";;;;;;;AAyBO,MAAM,0BAA0B,wBAAA,CAAyB;AAAA,EAC9D,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,EAAE,EAAA,EAAI,UAAA,EAAY,OAAO,UAAA,EAAW;AAAA,EAC9C,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,CAAC,OAAA,CAAQ,MAAA,EAAkC,EAAE,MAAK,EAAG;AACnD,IAAA,MAAM,iBAAA,CAAkB,YAAA;AAAA,0BACrB,iBAAA,EAAA,EAAkB,IAAA,EAAY,iBAAA,EAAkB,WAAA,EAC9C,iBAAO,OAAA,EACV;AAAA,KACF;AAAA,EACF;AACF,CAAC;;;;"}
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, JSX as JSX$1, ComponentType, PropsWithChildren } from 'react';
4
4
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
5
- import { I as IconElement, R as RouteRef, A as AnyRouteRefParams, S as SubRouteRef, E as ExternalRouteRef, F as FrontendFeature, a as IconComponent, b as AppNode, c as FrontendPlugin, d as ApiRef, e as ApiHolder, T as TypesToApiRefs, f as ApiFactory, g as AnyApiFactory } from './types/alpha.d-D3gnSOzm.js';
6
- export { h as AnyApiRef, i as AppNodeEdges, j as AppNodeInstance, k as AppNodeSpec, l as AppTree, m as AppTreeApi, C as ConfigurableExtensionDataRef, n as CreateExtensionBlueprintOptions, o as CreateExtensionOptions, p as CreateFrontendModuleOptions, q as CreateFrontendPluginOptions, r as Extension, s as ExtensionAttachTo, t as ExtensionBlueprint, u as ExtensionBlueprintDefineParams, v as ExtensionBlueprintParameters, w as ExtensionBlueprintParams, x as ExtensionDataContainer, y as ExtensionDataRef, z as ExtensionDataValue, B as ExtensionDefinition, D as ExtensionDefinitionAttachTo, G as ExtensionDefinitionParameters, H as ExtensionFactoryMiddleware, J as ExtensionInput, K as FeatureFlagConfig, L as FrontendModule, M as FrontendPluginInfo, N as FrontendPluginInfoOptions, O as OverridableExtensionDefinition, P as OverridableFrontendPlugin, Q as PluginOptions, U as PluginWrapperApi, V as PluginWrapperBlueprint, W as PluginWrapperDefinition, X as PortableSchema, Y as appTreeApiRef, Z as createExtension, _ as createExtensionBlueprint, $ as createExtensionBlueprintParams, a0 as createExtensionDataRef, a1 as createExtensionInput, a2 as createExternalRouteRef, a3 as createFrontendModule, a4 as createFrontendPlugin, a5 as createRouteRef, a6 as createSubRouteRef, a7 as pluginWrapperApiRef } from './types/alpha.d-D3gnSOzm.js';
5
+ import { I as IconElement, R as RouteRef, A as AnyRouteRefParams, S as SubRouteRef, E as ExternalRouteRef, F as FrontendFeature, a as IconComponent, b as AppNode, c as FrontendPlugin, d as ApiRef, e as ApiHolder, T as TypesToApiRefs, f as ApiFactory, g as AnyApiFactory } from './types/alpha.d-CP8HTsBe.js';
6
+ export { h as AnyApiRef, i as AppNodeEdges, j as AppNodeInstance, k as AppNodeSpec, l as AppTree, m as AppTreeApi, C as ConfigurableExtensionDataRef, n as CreateExtensionBlueprintOptions, o as CreateExtensionOptions, p as CreateFrontendModuleOptions, q as CreateFrontendPluginOptions, r as Extension, s as ExtensionAttachTo, t as ExtensionBlueprint, u as ExtensionBlueprintDefineParams, v as ExtensionBlueprintParameters, w as ExtensionBlueprintParams, x as ExtensionDataContainer, y as ExtensionDataRef, z as ExtensionDataValue, B as ExtensionDefinition, D as ExtensionDefinitionAttachTo, G as ExtensionDefinitionParameters, H as ExtensionFactoryMiddleware, J as ExtensionInput, K as FeatureFlagConfig, L as FrontendModule, M as FrontendPluginInfo, N as FrontendPluginInfoOptions, O as OverridableExtensionDefinition, P as OverridableFrontendPlugin, Q as PluginOptions, U as PluginWrapperApi, V as PluginWrapperBlueprint, W as PluginWrapperDefinition, X as PortableSchema, Y as appTreeApiRef, Z as createExtension, _ as createExtensionBlueprint, $ as createExtensionBlueprintParams, a0 as createExtensionDataRef, a1 as createExtensionInput, a2 as createExternalRouteRef, a3 as createFrontendModule, a4 as createFrontendPlugin, a5 as createRouteRef, a6 as createSubRouteRef, a7 as pluginWrapperApiRef } from './types/alpha.d-CP8HTsBe.js';
7
7
  import { Observable, JsonValue, Expand, ExpandRecursive } from '@backstage/types';
8
8
  import { Config } from '@backstage/config';
9
9
  export { StandardSchemaV1 } from '@standard-schema/spec';
@@ -53,25 +53,18 @@ function buildPortableSchema(fields) {
53
53
  }
54
54
  return result2;
55
55
  }
56
+ let cached;
56
57
  const result = {
57
58
  parse,
58
- schema: void 0,
59
- _fields: fields
60
- };
61
- let cached;
62
- Object.defineProperty(result, "schema", {
63
- get() {
59
+ schema() {
64
60
  if (!cached) {
65
- const jsonSchema = buildObjectJsonSchema(fields);
66
- const callable = Object.assign(
67
- () => ({ schema: jsonSchema }),
68
- jsonSchema
69
- );
70
- cached = callable;
61
+ cached = { schema: buildObjectJsonSchema(fields) };
71
62
  }
72
63
  return cached;
73
- },
74
- configurable: true,
64
+ }
65
+ };
66
+ Object.defineProperty(result, "_fields", {
67
+ value: fields,
75
68
  enumerable: false
76
69
  });
77
70
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"createPortableSchema.esm.js","sources":["../../src/schema/createPortableSchema.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 { JsonObject } from '@backstage/types';\nimport { z as zodV3, type ZodType } from 'zod/v3';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { PortableSchema } from './types';\n\n/**\n * The Standard Schema interface.\n * @public\n */\nexport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { type StandardSchemaV1 } from '@standard-schema/spec';\n\n/** @internal */\nexport function createDeprecatedConfigSchema(\n fields: Record<string, (zImpl: typeof zodV3) => ZodType>,\n): MergeablePortableSchema {\n const resolved: Record<string, ResolvedField> = {};\n\n for (const [key, field] of Object.entries(fields)) {\n resolved[key] = resolveZodField(key, field(zodV3));\n }\n\n return buildPortableSchema(resolved);\n}\n\n/**\n * Per-field resolved schema — validation is eager, JSON Schema is lazy.\n * @internal\n */\ninterface ResolvedField {\n validate(value: unknown): { value: unknown } | { errors: string[] };\n toJsonSchema(): JsonObject;\n required: boolean;\n}\n\n/**\n * Internal representation that carries per-field resolvers alongside the\n * public PortableSchema surface, enabling schema merging.\n * @internal\n */\nexport interface MergeablePortableSchema<TOutput = any, TInput = any>\n extends PortableSchema<TOutput, TInput> {\n /** @internal */\n readonly _fields: Record<string, ResolvedField>;\n}\n\n/**\n * Resolves each field, eagerly validates JSON Schema support, and returns\n * a PortableSchema whose JSON Schema conversion is lazy.\n * @internal\n */\nexport function createConfigSchema(\n fields: Record<string, StandardSchemaV1>,\n): MergeablePortableSchema {\n const resolved: Record<string, ResolvedField> = {};\n\n for (const [key, field] of Object.entries(fields)) {\n resolved[key] = resolveField(key, field);\n }\n\n return buildPortableSchema(resolved);\n}\n\n/**\n * Combines schemas from different sources for blueprint + override\n * composition. Each source may use a completely different schema library.\n * Because we track per-field resolvers, merging is just combining the\n * field maps.\n * @internal\n */\nexport function mergePortableSchemas<A, B>(\n a: MergeablePortableSchema<A> | undefined,\n b: MergeablePortableSchema<B> | undefined,\n): MergeablePortableSchema<A & B> | undefined {\n if (!a && !b) {\n return undefined;\n }\n if (!a) {\n return b as MergeablePortableSchema<A & B>;\n }\n if (!b) {\n return a as MergeablePortableSchema<A & B>;\n }\n\n return buildPortableSchema<A & B>({\n ...a._fields,\n ...b._fields,\n });\n}\n\n/**\n * Assembles resolved fields into a PortableSchema with per-field\n * validation (eager) and lazy JSON Schema generation.\n */\nfunction buildPortableSchema<TOutput = unknown>(\n fields: Record<string, ResolvedField>,\n): MergeablePortableSchema<TOutput> {\n function parse(input: unknown) {\n if (\n input !== undefined &&\n input !== null &&\n (typeof input !== 'object' || Array.isArray(input))\n ) {\n throw new Error(\n `Invalid config input, expected object but got ${\n Array.isArray(input) ? 'array' : typeof input\n }`,\n );\n }\n const inputObj = (input ?? {}) as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n const errors: string[] = [];\n\n for (const [key, field] of Object.entries(fields)) {\n const validated = field.validate(inputObj[key]);\n if ('errors' in validated) {\n errors.push(...validated.errors);\n } else if (validated.value !== undefined || key in inputObj) {\n result[key] = validated.value;\n }\n }\n\n if (errors.length > 0) {\n throw new Error(errors.join('; '));\n }\n\n return result as TOutput;\n }\n\n const result: MergeablePortableSchema<TOutput> = {\n parse,\n schema: undefined as any,\n _fields: fields,\n };\n\n // Lazy getter — computes JSON Schema on first access, then caches it.\n let cached: PortableSchema['schema'] | undefined;\n Object.defineProperty(result, 'schema', {\n get() {\n if (!cached) {\n const jsonSchema = buildObjectJsonSchema(fields);\n const callable = Object.assign(\n () => ({ schema: jsonSchema }),\n jsonSchema,\n );\n cached = callable as PortableSchema['schema'];\n }\n return cached;\n },\n configurable: true,\n enumerable: false,\n });\n\n return result;\n}\n\n/**\n * Wraps a single schema into a ResolvedField. Eagerly validates that\n * JSON Schema conversion will be possible, but defers the actual\n * conversion until toJsonSchema() is called.\n */\nfunction resolveField(key: string, schema: unknown): ResolvedField {\n if (isZodV3Type(schema)) {\n throw new Error(\n `Config schema for field '${key}' uses a Zod v3 schema, which is ` +\n `not supported by the \\`configSchema\\` option. Upgrade to the ` +\n `\\`zod\\` v4 package (\\`zod@^4.0.0\\`). Note that the \\`zod/v4\\` ` +\n `subpath export from the zod v3 package is also not supported, ` +\n `as it does not include JSON Schema conversion.`,\n );\n }\n if (isStandardSchema(schema)) {\n if (!hasJsonSchemaConverter(schema)) {\n throw new Error(\n `Config schema for field '${key}' does not support JSON Schema ` +\n `conversion. Use a schema library that implements the Standard ` +\n `JSON Schema interface (like zod v4+).`,\n );\n }\n return resolveStandardField(key, schema);\n }\n throw new Error(\n `Config schema for field '${key}' is not a valid Standard Schema`,\n );\n}\n\nfunction resolveZodField(key: string, schema: ZodType): ResolvedField {\n const wrapper = zodV3.object({ [key]: schema });\n\n return {\n validate(value) {\n const result = wrapper.safeParse({ [key]: value });\n if (result.success) {\n return { value: result.data[key] };\n }\n return { errors: result.error.issues.map(formatZodIssue) };\n },\n toJsonSchema() {\n const wholeJsonSchema = zodToJsonSchema(wrapper) as Record<string, any>;\n return (wholeJsonSchema.properties?.[key] ?? {}) as JsonObject;\n },\n required: !schema.isOptional(),\n };\n}\n\nfunction resolveStandardField(\n key: string,\n schema: StandardSchemaV1 & {\n '~standard': { jsonSchema: { input: Function } };\n },\n): ResolvedField {\n const required = isFieldRequired(schema);\n\n return {\n validate(value) {\n const result = schema['~standard'].validate(value);\n if (result instanceof Promise) {\n throw new Error(\n `Config schema for '${key}' returned a Promise — async schemas are not supported`,\n );\n }\n if (result.issues) {\n return {\n errors: Array.from(result.issues).map(issue =>\n formatStandardIssue(key, issue),\n ),\n };\n }\n return { value: result.value };\n },\n toJsonSchema() {\n const raw = schema['~standard'].jsonSchema.input({ target: 'draft-07' });\n const { $schema: _, ...rest } = raw;\n return rest as JsonObject;\n },\n required,\n };\n}\n\n/** Assembles per-field JSON Schemas into a single object-level JSON Schema. */\nfunction buildObjectJsonSchema(\n fields: Record<string, ResolvedField>,\n): JsonObject {\n const properties: Record<string, JsonObject> = {};\n const required: string[] = [];\n\n for (const [key, field] of Object.entries(fields)) {\n properties[key] = field.toJsonSchema();\n if (field.required) {\n required.push(key);\n }\n }\n\n const schema: Record<string, unknown> = {\n type: 'object',\n properties,\n additionalProperties: false,\n };\n\n if (required.length > 0) {\n schema.required = required;\n }\n\n return schema as JsonObject;\n}\n\nfunction isZodV3Type(value: unknown): value is ZodType {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as any)._parse === 'function' &&\n '_def' in value\n );\n}\n\nfunction isStandardSchema(value: unknown): value is StandardSchemaV1 {\n return (\n typeof value === 'object' &&\n value !== null &&\n '~standard' in value &&\n typeof (value as any)['~standard']?.validate === 'function'\n );\n}\n\nfunction hasJsonSchemaConverter(\n schema: StandardSchemaV1,\n): schema is StandardSchemaV1 & {\n '~standard': { jsonSchema: { input: Function } };\n} {\n const std = schema['~standard'] as any;\n return typeof std?.jsonSchema?.input === 'function';\n}\n\nfunction isFieldRequired(schema: StandardSchemaV1): boolean {\n const result = schema['~standard'].validate(undefined);\n if (result instanceof Promise) {\n return true;\n }\n return (result.issues?.length ?? 0) > 0;\n}\n\nfunction formatZodIssue(issue: {\n code: string;\n message: string;\n path: Array<string | number>;\n unionErrors?: Array<{ issues: Array<any> }>;\n}): string {\n if (issue.code === 'invalid_union' && issue.unionErrors?.[0]?.issues?.[0]) {\n return formatZodIssue(issue.unionErrors[0].issues[0]);\n }\n let message = issue.message;\n if (message === 'Required') {\n message = 'Missing required value';\n }\n if (issue.path.length) {\n message += ` at '${issue.path.join('.')}'`;\n }\n return message;\n}\n\nfunction formatStandardIssue(\n fieldKey: string,\n issue: StandardSchemaV1.Issue,\n): string {\n let message = issue.message;\n if (message === 'Required') {\n message = 'Missing required value';\n }\n const path = issue.path?.length\n ? `${fieldKey}.${issue.path\n .map((p: PropertyKey | StandardSchemaV1.PathSegment) =>\n typeof p === 'object' ? p.key : p,\n )\n .join('.')}`\n : fieldKey;\n return `${message} at '${path}'`;\n}\n\n/** @internal */\nexport function warnConfigSchemaPropDeprecation(callSite: string) {\n // eslint-disable-next-line no-console\n console.warn(\n `DEPRECATION WARNING: The \\`config.schema\\` option for extension config is deprecated. ` +\n `Use the \\`configSchema\\` option instead with Standard Schema values, for example ` +\n `\\`configSchema: { title: z.string() }\\` using the \\`zod\\` v4 package ` +\n `(\\`zod@^4.0.0\\`). Declared at ${callSite}`,\n );\n}\n"],"names":["zodV3","result"],"mappings":"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"}
1
+ {"version":3,"file":"createPortableSchema.esm.js","sources":["../../src/schema/createPortableSchema.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 { JsonObject } from '@backstage/types';\nimport { z as zodV3, type ZodType } from 'zod/v3';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { PortableSchema } from './types';\n\n/**\n * The Standard Schema interface.\n * @public\n */\nexport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { type StandardSchemaV1 } from '@standard-schema/spec';\n\n/** @internal */\nexport function createDeprecatedConfigSchema(\n fields: Record<string, (zImpl: typeof zodV3) => ZodType>,\n): MergeablePortableSchema {\n const resolved: Record<string, ResolvedField> = {};\n\n for (const [key, field] of Object.entries(fields)) {\n resolved[key] = resolveZodField(key, field(zodV3));\n }\n\n return buildPortableSchema(resolved);\n}\n\n/**\n * Per-field resolved schema — validation is eager, JSON Schema is lazy.\n * @internal\n */\ninterface ResolvedField {\n validate(value: unknown): { value: unknown } | { errors: string[] };\n toJsonSchema(): JsonObject;\n required: boolean;\n}\n\n/**\n * Internal representation that carries per-field resolvers alongside the\n * public PortableSchema surface, enabling schema merging.\n * @internal\n */\nexport interface MergeablePortableSchema<TOutput = any, TInput = any>\n extends PortableSchema<TOutput, TInput> {\n /** @internal */\n readonly _fields: Record<string, ResolvedField>;\n}\n\n/**\n * Resolves each field, eagerly validates JSON Schema support, and returns\n * a PortableSchema whose JSON Schema conversion is lazy.\n * @internal\n */\nexport function createConfigSchema(\n fields: Record<string, StandardSchemaV1>,\n): MergeablePortableSchema {\n const resolved: Record<string, ResolvedField> = {};\n\n for (const [key, field] of Object.entries(fields)) {\n resolved[key] = resolveField(key, field);\n }\n\n return buildPortableSchema(resolved);\n}\n\n/**\n * Combines schemas from different sources for blueprint + override\n * composition. Each source may use a completely different schema library.\n * Because we track per-field resolvers, merging is just combining the\n * field maps.\n * @internal\n */\nexport function mergePortableSchemas<A, B>(\n a: MergeablePortableSchema<A> | undefined,\n b: MergeablePortableSchema<B> | undefined,\n): MergeablePortableSchema<A & B> | undefined {\n if (!a && !b) {\n return undefined;\n }\n if (!a) {\n return b as MergeablePortableSchema<A & B>;\n }\n if (!b) {\n return a as MergeablePortableSchema<A & B>;\n }\n\n return buildPortableSchema<A & B>({\n ...a._fields,\n ...b._fields,\n });\n}\n\n/**\n * Assembles resolved fields into a PortableSchema with per-field\n * validation (eager) and lazy JSON Schema generation.\n */\nfunction buildPortableSchema<TOutput = unknown>(\n fields: Record<string, ResolvedField>,\n): MergeablePortableSchema<TOutput> {\n function parse(input: unknown) {\n if (\n input !== undefined &&\n input !== null &&\n (typeof input !== 'object' || Array.isArray(input))\n ) {\n throw new Error(\n `Invalid config input, expected object but got ${\n Array.isArray(input) ? 'array' : typeof input\n }`,\n );\n }\n const inputObj = (input ?? {}) as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n const errors: string[] = [];\n\n for (const [key, field] of Object.entries(fields)) {\n const validated = field.validate(inputObj[key]);\n if ('errors' in validated) {\n errors.push(...validated.errors);\n } else if (validated.value !== undefined || key in inputObj) {\n result[key] = validated.value;\n }\n }\n\n if (errors.length > 0) {\n throw new Error(errors.join('; '));\n }\n\n return result as TOutput;\n }\n\n let cached: { schema: JsonObject } | undefined;\n\n const result: MergeablePortableSchema<TOutput> = {\n parse,\n schema() {\n if (!cached) {\n cached = { schema: buildObjectJsonSchema(fields) };\n }\n return cached;\n },\n } as MergeablePortableSchema<TOutput>;\n\n Object.defineProperty(result, '_fields', {\n value: fields,\n enumerable: false,\n });\n\n return result;\n}\n\n/**\n * Wraps a single schema into a ResolvedField. Eagerly validates that\n * JSON Schema conversion will be possible, but defers the actual\n * conversion until toJsonSchema() is called.\n */\nfunction resolveField(key: string, schema: unknown): ResolvedField {\n if (isZodV3Type(schema)) {\n throw new Error(\n `Config schema for field '${key}' uses a Zod v3 schema, which is ` +\n `not supported by the \\`configSchema\\` option. Upgrade to the ` +\n `\\`zod\\` v4 package (\\`zod@^4.0.0\\`). Note that the \\`zod/v4\\` ` +\n `subpath export from the zod v3 package is also not supported, ` +\n `as it does not include JSON Schema conversion.`,\n );\n }\n if (isStandardSchema(schema)) {\n if (!hasJsonSchemaConverter(schema)) {\n throw new Error(\n `Config schema for field '${key}' does not support JSON Schema ` +\n `conversion. Use a schema library that implements the Standard ` +\n `JSON Schema interface (like zod v4+).`,\n );\n }\n return resolveStandardField(key, schema);\n }\n throw new Error(\n `Config schema for field '${key}' is not a valid Standard Schema`,\n );\n}\n\nfunction resolveZodField(key: string, schema: ZodType): ResolvedField {\n const wrapper = zodV3.object({ [key]: schema });\n\n return {\n validate(value) {\n const result = wrapper.safeParse({ [key]: value });\n if (result.success) {\n return { value: result.data[key] };\n }\n return { errors: result.error.issues.map(formatZodIssue) };\n },\n toJsonSchema() {\n const wholeJsonSchema = zodToJsonSchema(wrapper) as Record<string, any>;\n return (wholeJsonSchema.properties?.[key] ?? {}) as JsonObject;\n },\n required: !schema.isOptional(),\n };\n}\n\nfunction resolveStandardField(\n key: string,\n schema: StandardSchemaV1 & {\n '~standard': { jsonSchema: { input: Function } };\n },\n): ResolvedField {\n const required = isFieldRequired(schema);\n\n return {\n validate(value) {\n const result = schema['~standard'].validate(value);\n if (result instanceof Promise) {\n throw new Error(\n `Config schema for '${key}' returned a Promise — async schemas are not supported`,\n );\n }\n if (result.issues) {\n return {\n errors: Array.from(result.issues).map(issue =>\n formatStandardIssue(key, issue),\n ),\n };\n }\n return { value: result.value };\n },\n toJsonSchema() {\n const raw = schema['~standard'].jsonSchema.input({ target: 'draft-07' });\n const { $schema: _, ...rest } = raw;\n return rest as JsonObject;\n },\n required,\n };\n}\n\n/** Assembles per-field JSON Schemas into a single object-level JSON Schema. */\nfunction buildObjectJsonSchema(\n fields: Record<string, ResolvedField>,\n): JsonObject {\n const properties: Record<string, JsonObject> = {};\n const required: string[] = [];\n\n for (const [key, field] of Object.entries(fields)) {\n properties[key] = field.toJsonSchema();\n if (field.required) {\n required.push(key);\n }\n }\n\n const schema: Record<string, unknown> = {\n type: 'object',\n properties,\n additionalProperties: false,\n };\n\n if (required.length > 0) {\n schema.required = required;\n }\n\n return schema as JsonObject;\n}\n\nfunction isZodV3Type(value: unknown): value is ZodType {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as any)._parse === 'function' &&\n '_def' in value\n );\n}\n\nfunction isStandardSchema(value: unknown): value is StandardSchemaV1 {\n return (\n typeof value === 'object' &&\n value !== null &&\n '~standard' in value &&\n typeof (value as any)['~standard']?.validate === 'function'\n );\n}\n\nfunction hasJsonSchemaConverter(\n schema: StandardSchemaV1,\n): schema is StandardSchemaV1 & {\n '~standard': { jsonSchema: { input: Function } };\n} {\n const std = schema['~standard'] as any;\n return typeof std?.jsonSchema?.input === 'function';\n}\n\nfunction isFieldRequired(schema: StandardSchemaV1): boolean {\n const result = schema['~standard'].validate(undefined);\n if (result instanceof Promise) {\n return true;\n }\n return (result.issues?.length ?? 0) > 0;\n}\n\nfunction formatZodIssue(issue: {\n code: string;\n message: string;\n path: Array<string | number>;\n unionErrors?: Array<{ issues: Array<any> }>;\n}): string {\n if (issue.code === 'invalid_union' && issue.unionErrors?.[0]?.issues?.[0]) {\n return formatZodIssue(issue.unionErrors[0].issues[0]);\n }\n let message = issue.message;\n if (message === 'Required') {\n message = 'Missing required value';\n }\n if (issue.path.length) {\n message += ` at '${issue.path.join('.')}'`;\n }\n return message;\n}\n\nfunction formatStandardIssue(\n fieldKey: string,\n issue: StandardSchemaV1.Issue,\n): string {\n let message = issue.message;\n if (message === 'Required') {\n message = 'Missing required value';\n }\n const path = issue.path?.length\n ? `${fieldKey}.${issue.path\n .map((p: PropertyKey | StandardSchemaV1.PathSegment) =>\n typeof p === 'object' ? p.key : p,\n )\n .join('.')}`\n : fieldKey;\n return `${message} at '${path}'`;\n}\n\n/** @internal */\nexport function warnConfigSchemaPropDeprecation(callSite: string) {\n // eslint-disable-next-line no-console\n console.warn(\n `DEPRECATION WARNING: The \\`config.schema\\` option for extension config is deprecated. ` +\n `Use the \\`configSchema\\` option instead with Standard Schema values, for example ` +\n `\\`configSchema: { title: z.string() }\\` using the \\`zod\\` v4 package ` +\n `(\\`zod@^4.0.0\\`). Declared at ${callSite}`,\n );\n}\n"],"names":["zodV3","result"],"mappings":"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"}
@@ -283,20 +283,8 @@ declare function createFrontendModule<TId extends string, TExtensions extends re
283
283
  /** @public */
284
284
  type PortableSchema<TOutput = unknown, TInput = TOutput> = {
285
285
  parse: (input: TInput) => TOutput;
286
- /**
287
- * The JSON Schema for this portable schema.
288
- *
289
- * @remarks
290
- * Can be accessed as a property for backward compatibility (returns the
291
- * JSON Schema object directly), or called as a method which returns
292
- * `{ schema: JsonObject }`. Both forms compute the schema lazily on
293
- * first access. The property form is deprecated — prefer `schema()`.
294
- */
295
- schema: {
296
- (): {
297
- schema: JsonObject;
298
- };
299
- [key: string]: any;
286
+ schema: () => {
287
+ schema: JsonObject;
300
288
  };
301
289
  };
302
290
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/frontend-plugin-api",
3
- "version": "0.16.2",
3
+ "version": "0.17.0-next.1",
4
4
  "backstage": {
5
5
  "role": "web-library"
6
6
  },
@@ -52,20 +52,20 @@
52
52
  "test": "backstage-cli package test"
53
53
  },
54
54
  "dependencies": {
55
- "@backstage/errors": "^1.3.0",
56
- "@backstage/filter-predicates": "^0.1.2",
57
- "@backstage/types": "^1.2.2",
58
- "@backstage/version-bridge": "^1.0.12",
55
+ "@backstage/errors": "1.3.1-next.0",
56
+ "@backstage/filter-predicates": "0.1.3-next.0",
57
+ "@backstage/types": "1.2.2",
58
+ "@backstage/version-bridge": "1.0.12",
59
59
  "@standard-schema/spec": "^1.1.0",
60
60
  "zod": "^4.0.0",
61
61
  "zod-to-json-schema": "^3.25.1"
62
62
  },
63
63
  "devDependencies": {
64
- "@backstage/cli": "^0.36.1",
65
- "@backstage/config": "^1.3.7",
66
- "@backstage/frontend-app-api": "^0.16.2",
67
- "@backstage/frontend-test-utils": "^0.5.2",
68
- "@backstage/test-utils": "^1.7.17",
64
+ "@backstage/cli": "0.36.2-next.1",
65
+ "@backstage/config": "1.3.8-next.0",
66
+ "@backstage/frontend-app-api": "0.16.3-next.1",
67
+ "@backstage/frontend-test-utils": "0.5.3-next.1",
68
+ "@backstage/test-utils": "1.7.18-next.0",
69
69
  "@testing-library/jest-dom": "^6.0.0",
70
70
  "@testing-library/react": "^16.0.0",
71
71
  "@types/react": "^18.0.0",