@backstage/frontend-plugin-api 0.16.0-next.2 → 0.16.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.
@@ -0,0 +1,207 @@
1
+ import { z } from 'zod/v3';
2
+ import zodToJsonSchema from 'zod-to-json-schema';
3
+
4
+ function createDeprecatedConfigSchema(fields) {
5
+ const resolved = {};
6
+ for (const [key, field] of Object.entries(fields)) {
7
+ resolved[key] = resolveZodField(key, field(z));
8
+ }
9
+ return buildPortableSchema(resolved);
10
+ }
11
+ function createConfigSchema(fields) {
12
+ const resolved = {};
13
+ for (const [key, field] of Object.entries(fields)) {
14
+ resolved[key] = resolveField(key, field);
15
+ }
16
+ return buildPortableSchema(resolved);
17
+ }
18
+ function mergePortableSchemas(a, b) {
19
+ if (!a && !b) {
20
+ return void 0;
21
+ }
22
+ if (!a) {
23
+ return b;
24
+ }
25
+ if (!b) {
26
+ return a;
27
+ }
28
+ return buildPortableSchema({
29
+ ...a._fields,
30
+ ...b._fields
31
+ });
32
+ }
33
+ function buildPortableSchema(fields) {
34
+ function parse(input) {
35
+ if (input !== void 0 && input !== null && (typeof input !== "object" || Array.isArray(input))) {
36
+ throw new Error(
37
+ `Invalid config input, expected object but got ${Array.isArray(input) ? "array" : typeof input}`
38
+ );
39
+ }
40
+ const inputObj = input ?? {};
41
+ const result2 = {};
42
+ const errors = [];
43
+ for (const [key, field] of Object.entries(fields)) {
44
+ const validated = field.validate(inputObj[key]);
45
+ if ("errors" in validated) {
46
+ errors.push(...validated.errors);
47
+ } else if (validated.value !== void 0 || key in inputObj) {
48
+ result2[key] = validated.value;
49
+ }
50
+ }
51
+ if (errors.length > 0) {
52
+ throw new Error(errors.join("; "));
53
+ }
54
+ return result2;
55
+ }
56
+ const result = {
57
+ parse,
58
+ schema: void 0,
59
+ _fields: fields
60
+ };
61
+ let cached;
62
+ Object.defineProperty(result, "schema", {
63
+ get() {
64
+ if (!cached) {
65
+ const jsonSchema = buildObjectJsonSchema(fields);
66
+ const callable = Object.assign(
67
+ () => ({ schema: jsonSchema }),
68
+ jsonSchema
69
+ );
70
+ cached = callable;
71
+ }
72
+ return cached;
73
+ },
74
+ configurable: true,
75
+ enumerable: false
76
+ });
77
+ return result;
78
+ }
79
+ function resolveField(key, schema) {
80
+ if (isZodV3Type(schema)) {
81
+ throw new Error(
82
+ `Config schema for field '${key}' uses a Zod v3 schema, which is not supported by the \`configSchema\` option. Either use \`import { z } from 'zod/v4'\` from the zod v3 package, or upgrade to zod v4.`
83
+ );
84
+ }
85
+ if (isStandardSchema(schema)) {
86
+ if (!hasJsonSchemaConverter(schema)) {
87
+ throw new Error(
88
+ `Config schema for field '${key}' does not support JSON Schema conversion. Use a schema library that implements the Standard JSON Schema interface (like zod v4+).`
89
+ );
90
+ }
91
+ return resolveStandardField(key, schema);
92
+ }
93
+ throw new Error(
94
+ `Config schema for field '${key}' is not a valid Standard Schema`
95
+ );
96
+ }
97
+ function resolveZodField(key, schema) {
98
+ const wrapper = z.object({ [key]: schema });
99
+ return {
100
+ validate(value) {
101
+ const result = wrapper.safeParse({ [key]: value });
102
+ if (result.success) {
103
+ return { value: result.data[key] };
104
+ }
105
+ return { errors: result.error.issues.map(formatZodIssue) };
106
+ },
107
+ toJsonSchema() {
108
+ const wholeJsonSchema = zodToJsonSchema(wrapper);
109
+ return wholeJsonSchema.properties?.[key] ?? {};
110
+ },
111
+ required: !schema.isOptional()
112
+ };
113
+ }
114
+ function resolveStandardField(key, schema) {
115
+ const required = isFieldRequired(schema);
116
+ return {
117
+ validate(value) {
118
+ const result = schema["~standard"].validate(value);
119
+ if (result instanceof Promise) {
120
+ throw new Error(
121
+ `Config schema for '${key}' returned a Promise \u2014 async schemas are not supported`
122
+ );
123
+ }
124
+ if (result.issues) {
125
+ return {
126
+ errors: Array.from(result.issues).map(
127
+ (issue) => formatStandardIssue(key, issue)
128
+ )
129
+ };
130
+ }
131
+ return { value: result.value };
132
+ },
133
+ toJsonSchema() {
134
+ const raw = schema["~standard"].jsonSchema.input({ target: "draft-07" });
135
+ const { $schema: _, ...rest } = raw;
136
+ return rest;
137
+ },
138
+ required
139
+ };
140
+ }
141
+ function buildObjectJsonSchema(fields) {
142
+ const properties = {};
143
+ const required = [];
144
+ for (const [key, field] of Object.entries(fields)) {
145
+ properties[key] = field.toJsonSchema();
146
+ if (field.required) {
147
+ required.push(key);
148
+ }
149
+ }
150
+ const schema = {
151
+ type: "object",
152
+ properties,
153
+ additionalProperties: false
154
+ };
155
+ if (required.length > 0) {
156
+ schema.required = required;
157
+ }
158
+ return schema;
159
+ }
160
+ function isZodV3Type(value) {
161
+ return typeof value === "object" && value !== null && typeof value._parse === "function" && "_def" in value;
162
+ }
163
+ function isStandardSchema(value) {
164
+ return typeof value === "object" && value !== null && "~standard" in value && typeof value["~standard"]?.validate === "function";
165
+ }
166
+ function hasJsonSchemaConverter(schema) {
167
+ const std = schema["~standard"];
168
+ return typeof std?.jsonSchema?.input === "function";
169
+ }
170
+ function isFieldRequired(schema) {
171
+ const result = schema["~standard"].validate(void 0);
172
+ if (result instanceof Promise) {
173
+ return true;
174
+ }
175
+ return (result.issues?.length ?? 0) > 0;
176
+ }
177
+ function formatZodIssue(issue) {
178
+ if (issue.code === "invalid_union" && issue.unionErrors?.[0]?.issues?.[0]) {
179
+ return formatZodIssue(issue.unionErrors[0].issues[0]);
180
+ }
181
+ let message = issue.message;
182
+ if (message === "Required") {
183
+ message = "Missing required value";
184
+ }
185
+ if (issue.path.length) {
186
+ message += ` at '${issue.path.join(".")}'`;
187
+ }
188
+ return message;
189
+ }
190
+ function formatStandardIssue(fieldKey, issue) {
191
+ let message = issue.message;
192
+ if (message === "Required") {
193
+ message = "Missing required value";
194
+ }
195
+ const path = issue.path?.length ? `${fieldKey}.${issue.path.map(
196
+ (p) => typeof p === "object" ? p.key : p
197
+ ).join(".")}` : fieldKey;
198
+ return `${message} at '${path}'`;
199
+ }
200
+ function warnConfigSchemaPropDeprecation(callSite) {
201
+ console.warn(
202
+ `DEPRECATION WARNING: The \`config.schema\` option for extension config is deprecated. Use the \`configSchema\` option instead with Standard Schema values, for example \`configSchema: { title: z.string() }\` using zod v4 (or \`import { z } from 'zod/v4'\` from the zod v3 package). Declared at ${callSite}`
203
+ );
204
+ }
205
+
206
+ export { createConfigSchema, createDeprecatedConfigSchema, mergePortableSchemas, warnConfigSchemaPropDeprecation };
207
+ //# sourceMappingURL=createPortableSchema.esm.js.map
@@ -0,0 +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. Either use ` +\n `\\`import { z } from 'zod/v4'\\` from the zod v3 package, or ` +\n `upgrade to zod v4.`,\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 zod v4 ` +\n `(or \\`import { z } from 'zod/v4'\\` from the zod v3 package). ` +\n `Declared at ${callSite}`,\n );\n}\n"],"names":["zodV3","result"],"mappings":"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"}
@@ -3,6 +3,7 @@ import { JSX, ComponentType, ReactNode } from 'react';
3
3
  import { Expand, JsonObject } from '@backstage/types';
4
4
  import { FilterPredicate } from '@backstage/filter-predicates';
5
5
  import { z } from 'zod/v3';
6
+ import { StandardSchemaV1 } from '@standard-schema/spec';
6
7
 
7
8
  /**
8
9
  * IconComponent is the common icon type used throughout Backstage when
@@ -280,9 +281,23 @@ interface FrontendModule {
280
281
  declare function createFrontendModule<TId extends string, TExtensions extends readonly ExtensionDefinition[]>(options: CreateFrontendModuleOptions<TId, TExtensions>): FrontendModule;
281
282
 
282
283
  /** @public */
283
- type PortableSchema<TOutput, TInput = TOutput> = {
284
+ type PortableSchema<TOutput = unknown, TInput = TOutput> = {
284
285
  parse: (input: TInput) => TOutput;
285
- schema: JsonObject;
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;
300
+ };
286
301
  };
287
302
 
288
303
  /** @public */
@@ -734,14 +749,23 @@ type CreateExtensionBlueprintOptions<TKind extends string, TParams extends objec
734
749
  [key in string]: (zImpl: typeof z) => z.ZodType;
735
750
  }, UFactoryOutput extends ExtensionDataValue<any, any>, TDataRefs extends {
736
751
  [name in string]: ExtensionDataRef;
737
- }, UParentInputs extends ExtensionDataRef> = {
752
+ }, UParentInputs extends ExtensionDataRef, TNewConfigSchema extends {
753
+ [key in string]: StandardSchemaV1;
754
+ } = {}> = {
738
755
  kind: TKind;
739
756
  attachTo: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<UOutput, UParentInputs>;
740
757
  disabled?: boolean;
741
758
  if?: FilterPredicate;
742
759
  inputs?: TInputs;
743
760
  output: Array<UOutput>;
761
+ configSchema?: TNewConfigSchema;
762
+ /**
763
+ * @deprecated Use {@link CreateExtensionBlueprintOptions.configSchema} instead.
764
+ */
744
765
  config?: {
766
+ /**
767
+ * @deprecated Use {@link CreateExtensionBlueprintOptions.configSchema} instead.
768
+ */
745
769
  schema: TConfigSchema;
746
770
  };
747
771
  /**
@@ -787,7 +811,9 @@ type CreateExtensionBlueprintOptions<TKind extends string, TParams extends objec
787
811
  node: AppNode;
788
812
  apis: ApiHolder;
789
813
  config: {
790
- [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
814
+ [key in keyof TNewConfigSchema]: StandardSchemaV1.InferOutput<TNewConfigSchema[key]>;
815
+ } & {
816
+ [key in keyof TConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TConfigSchema[key]>>;
791
817
  };
792
818
  inputs: Expand<ResolvedExtensionInputs<TInputs>>;
793
819
  }): Iterable<UFactoryOutput>;
@@ -846,6 +872,50 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
846
872
  * You must either pass `params` directly, or define a `factory` that can
847
873
  * optionally call the original factory with the same params.
848
874
  */
875
+ makeWithOverrides<TName extends string | undefined, UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends ExtensionDataRef, UParentInputs extends ExtensionDataRef, TExtraInputs extends {
876
+ [inputName in string]: ExtensionInput;
877
+ } = {}, TNewExtensionConfigSchema extends {
878
+ [key in string]: StandardSchemaV1;
879
+ } = {}>(args: {
880
+ name?: TName;
881
+ attachTo?: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UParentInputs>;
882
+ disabled?: boolean;
883
+ if?: FilterPredicate;
884
+ inputs?: TExtraInputs & {
885
+ [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`;
886
+ };
887
+ output?: Array<UNewOutput>;
888
+ config?: never;
889
+ configSchema?: TNewExtensionConfigSchema & {
890
+ [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`;
891
+ };
892
+ factory(originalFactory: <TParamsInput extends AnyParamsInput$1<NonNullable<T['params']>>>(params: TParamsInput extends ExtensionBlueprintDefineParams ? TParamsInput : T['params'] extends ExtensionBlueprintDefineParams ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`' : T['params'], context?: {
893
+ config?: T['config'];
894
+ inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;
895
+ }) => ExtensionDataContainer<NonNullable<T['output']>>, context: {
896
+ node: AppNode;
897
+ apis: ApiHolder;
898
+ config: T['config'] & {
899
+ [key in keyof TNewExtensionConfigSchema]: StandardSchemaV1.InferOutput<TNewExtensionConfigSchema[key]>;
900
+ };
901
+ inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
902
+ }): Iterable<UFactoryOutput> & VerifyExtensionFactoryOutput<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>;
903
+ }): OverridableExtensionDefinition<{
904
+ config: Expand<{
905
+ [key in keyof TNewExtensionConfigSchema]: StandardSchemaV1.InferOutput<TNewExtensionConfigSchema[key]>;
906
+ } & T['config']>;
907
+ configInput: Expand<{
908
+ [key in keyof TNewExtensionConfigSchema]?: StandardSchemaV1.InferInput<TNewExtensionConfigSchema[key]>;
909
+ } & T['configInput']>;
910
+ output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
911
+ inputs: Expand<T['inputs'] & TExtraInputs>;
912
+ kind: T['kind'];
913
+ name: string | undefined extends TName ? undefined : TName;
914
+ params: T['params'];
915
+ }>;
916
+ /**
917
+ * @deprecated Use the `configSchema` option instead of `config.schema`.
918
+ */
849
919
  makeWithOverrides<TName extends string | undefined, TExtensionConfigSchema extends {
850
920
  [key in string]: (zImpl: typeof z) => z.ZodType;
851
921
  }, UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends ExtensionDataRef, UParentInputs extends ExtensionDataRef, TExtraInputs extends {
@@ -859,6 +929,7 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
859
929
  [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`;
860
930
  };
861
931
  output?: Array<UNewOutput>;
932
+ configSchema?: never;
862
933
  config?: {
863
934
  schema: TExtensionConfigSchema & {
864
935
  [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`;
@@ -871,16 +942,16 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
871
942
  node: AppNode;
872
943
  apis: ApiHolder;
873
944
  config: T['config'] & {
874
- [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
945
+ [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>>;
875
946
  };
876
947
  inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
877
948
  }): Iterable<UFactoryOutput> & VerifyExtensionFactoryOutput<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>;
878
949
  }): OverridableExtensionDefinition<{
879
950
  config: Expand<(string extends keyof TExtensionConfigSchema ? {} : {
880
- [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
951
+ [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>>;
881
952
  }) & T['config']>;
882
953
  configInput: Expand<(string extends keyof TExtensionConfigSchema ? {} : z.input<z.ZodObject<{
883
- [key in keyof TExtensionConfigSchema]: ReturnType<TExtensionConfigSchema[key]>;
954
+ [key in keyof TExtensionConfigSchema]: ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>;
884
955
  }>>) & T['configInput']>;
885
956
  output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
886
957
  inputs: Expand<T['inputs'] & TExtraInputs>;
@@ -900,7 +971,7 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
900
971
  * in the frontend system documentation.
901
972
  *
902
973
  * Extension blueprints make it much easier for users to create new extensions
903
- * for your plugin. Rather than letting them use {@link createExtension}
974
+ * for your plugin. Rather than letting them use `createExtension`
904
975
  * directly, you can define a set of parameters and default factory for your
905
976
  * blueprint, removing a lot of the boilerplate and complexity that is otherwise
906
977
  * needed to create an extension.
@@ -940,20 +1011,83 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
940
1011
  */
941
1012
  declare function createExtensionBlueprint<TParams extends object | ExtensionBlueprintDefineParams, UOutput extends ExtensionDataRef, TInputs extends {
942
1013
  [inputName in string]: ExtensionInput;
1014
+ }, UFactoryOutput extends ExtensionDataValue<any, any>, TKind extends string, UParentInputs extends ExtensionDataRef, TDataRefs extends {
1015
+ [name in string]: ExtensionDataRef;
1016
+ } = never, TNewConfigSchema extends {
1017
+ [key in string]: StandardSchemaV1;
1018
+ } = {}>(options: {
1019
+ kind: TKind;
1020
+ attachTo: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<UOutput, UParentInputs>;
1021
+ disabled?: boolean;
1022
+ if?: FilterPredicate;
1023
+ inputs?: TInputs;
1024
+ output: Array<UOutput>;
1025
+ config?: never;
1026
+ configSchema?: TNewConfigSchema;
1027
+ defineParams?: TParams extends ExtensionBlueprintDefineParams ? TParams : 'The defineParams option must be a function if provided, see the docs for details';
1028
+ factory(params: TParams extends ExtensionBlueprintDefineParams ? ReturnType<TParams>['T'] : TParams, context: {
1029
+ node: AppNode;
1030
+ apis: ApiHolder;
1031
+ config: {
1032
+ [key in keyof TNewConfigSchema]: StandardSchemaV1.InferOutput<TNewConfigSchema[key]>;
1033
+ };
1034
+ inputs: Expand<ResolvedExtensionInputs<TInputs>>;
1035
+ }): Iterable<UFactoryOutput>;
1036
+ dataRefs?: TDataRefs;
1037
+ } & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>): ExtensionBlueprint<{
1038
+ kind: TKind;
1039
+ params: TParams;
1040
+ output: UOutput extends ExtensionDataRef<infer IData, infer IId, infer IConfig> ? ExtensionDataRef<IData, IId, IConfig> : never;
1041
+ inputs: string extends keyof TInputs ? {} : TInputs;
1042
+ config: {
1043
+ [key in keyof TNewConfigSchema]: StandardSchemaV1.InferOutput<TNewConfigSchema[key]>;
1044
+ };
1045
+ configInput: {
1046
+ [key in keyof TNewConfigSchema]?: StandardSchemaV1.InferInput<TNewConfigSchema[key]>;
1047
+ };
1048
+ dataRefs: TDataRefs;
1049
+ }>;
1050
+ /**
1051
+ * @deprecated Use the top-level `configSchema` option instead of `config.schema`.
1052
+ * @public
1053
+ */
1054
+ declare function createExtensionBlueprint<TParams extends object | ExtensionBlueprintDefineParams, UOutput extends ExtensionDataRef, TInputs extends {
1055
+ [inputName in string]: ExtensionInput;
943
1056
  }, TConfigSchema extends {
944
1057
  [key in string]: (zImpl: typeof z) => z.ZodType;
945
1058
  }, UFactoryOutput extends ExtensionDataValue<any, any>, TKind extends string, UParentInputs extends ExtensionDataRef, TDataRefs extends {
946
1059
  [name in string]: ExtensionDataRef;
947
- } = never>(options: CreateExtensionBlueprintOptions<TKind, TParams, UOutput, TInputs, TConfigSchema, UFactoryOutput, TDataRefs, UParentInputs>): ExtensionBlueprint<{
1060
+ } = never>(options: {
1061
+ kind: TKind;
1062
+ attachTo: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<UOutput, UParentInputs>;
1063
+ disabled?: boolean;
1064
+ if?: FilterPredicate;
1065
+ inputs?: TInputs;
1066
+ output: Array<UOutput>;
1067
+ configSchema?: never;
1068
+ config?: {
1069
+ schema: TConfigSchema;
1070
+ };
1071
+ defineParams?: TParams extends ExtensionBlueprintDefineParams ? TParams : 'The defineParams option must be a function if provided, see the docs for details';
1072
+ factory(params: TParams extends ExtensionBlueprintDefineParams ? ReturnType<TParams>['T'] : TParams, context: {
1073
+ node: AppNode;
1074
+ apis: ApiHolder;
1075
+ config: {
1076
+ [key in keyof TConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TConfigSchema[key]>>;
1077
+ };
1078
+ inputs: Expand<ResolvedExtensionInputs<TInputs>>;
1079
+ }): Iterable<UFactoryOutput>;
1080
+ dataRefs?: TDataRefs;
1081
+ } & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>): ExtensionBlueprint<{
948
1082
  kind: TKind;
949
1083
  params: TParams;
950
1084
  output: UOutput extends ExtensionDataRef<infer IData, infer IId, infer IConfig> ? ExtensionDataRef<IData, IId, IConfig> : never;
951
1085
  inputs: string extends keyof TInputs ? {} : TInputs;
952
1086
  config: string extends keyof TConfigSchema ? {} : {
953
- [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
1087
+ [key in keyof TConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TConfigSchema[key]>>;
954
1088
  };
955
1089
  configInput: string extends keyof TConfigSchema ? {} : z.input<z.ZodObject<{
956
- [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
1090
+ [key in keyof TConfigSchema]: ReturnType<((...args: any[]) => any) & TConfigSchema[key]>;
957
1091
  }>>;
958
1092
  dataRefs: TDataRefs;
959
1093
  }>;
@@ -1026,7 +1160,9 @@ type CreateExtensionOptions<TKind extends string | undefined, TName extends stri
1026
1160
  [inputName in string]: ExtensionInput;
1027
1161
  }, TConfigSchema extends {
1028
1162
  [key: string]: (zImpl: typeof z) => z.ZodType;
1029
- }, UFactoryOutput extends ExtensionDataValue<any, any>, UParentInputs extends ExtensionDataRef> = {
1163
+ }, UFactoryOutput extends ExtensionDataValue<any, any>, UParentInputs extends ExtensionDataRef, TNewConfigSchema extends {
1164
+ [key: string]: StandardSchemaV1;
1165
+ } = {}> = {
1030
1166
  kind?: TKind;
1031
1167
  name?: TName;
1032
1168
  attachTo: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<UOutput, UParentInputs>;
@@ -1034,14 +1170,23 @@ type CreateExtensionOptions<TKind extends string | undefined, TName extends stri
1034
1170
  if?: FilterPredicate;
1035
1171
  inputs?: TInputs;
1036
1172
  output: Array<UOutput>;
1173
+ configSchema?: TNewConfigSchema;
1174
+ /**
1175
+ * @deprecated Use {@link CreateExtensionOptions.configSchema} instead.
1176
+ */
1037
1177
  config?: {
1178
+ /**
1179
+ * @deprecated Use {@link CreateExtensionOptions.configSchema} instead.
1180
+ */
1038
1181
  schema: TConfigSchema;
1039
1182
  };
1040
1183
  factory(context: {
1041
1184
  node: AppNode;
1042
1185
  apis: ApiHolder;
1043
1186
  config: {
1044
- [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
1187
+ [key in keyof TNewConfigSchema]: StandardSchemaV1.InferOutput<TNewConfigSchema[key]>;
1188
+ } & {
1189
+ [key in keyof TConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TConfigSchema[key]>>;
1045
1190
  };
1046
1191
  inputs: Expand<ResolvedExtensionInputs<TInputs>>;
1047
1192
  }): Iterable<UFactoryOutput>;
@@ -1081,6 +1226,52 @@ interface OverridableExtensionDefinition<T extends ExtensionDefinitionParameters
1081
1226
  readonly inputs: {
1082
1227
  [K in keyof T['inputs']]: ExtensionInput<T['inputs'][K] extends ExtensionInput<infer IData> ? IData : never>;
1083
1228
  };
1229
+ override<UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends ExtensionDataRef, TExtraInputs extends {
1230
+ [inputName in string]: ExtensionInput;
1231
+ }, TParamsInput extends AnyParamsInput<NonNullable<T['params']>>, UParentInputs extends ExtensionDataRef, TNewExtensionConfigSchema extends {
1232
+ [key in string]: StandardSchemaV1;
1233
+ } = {}>(args: Expand<{
1234
+ attachTo?: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UParentInputs>;
1235
+ disabled?: boolean;
1236
+ if?: FilterPredicate;
1237
+ inputs?: TExtraInputs & {
1238
+ [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`;
1239
+ };
1240
+ output?: Array<UNewOutput>;
1241
+ config?: never;
1242
+ configSchema?: TNewExtensionConfigSchema & {
1243
+ [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`;
1244
+ };
1245
+ factory?(originalFactory: <TFactoryParamsReturn extends AnyParamsInput<NonNullable<T['params']>>>(context?: Expand<{
1246
+ config?: T['config'];
1247
+ inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;
1248
+ } & ([T['params']] extends [never] ? {} : {
1249
+ params?: TFactoryParamsReturn extends ExtensionBlueprintDefineParams ? TFactoryParamsReturn : T['params'] extends ExtensionBlueprintDefineParams ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`' : Partial<T['params']>;
1250
+ })>) => ExtensionDataContainer<NonNullable<T['output']>>, context: {
1251
+ node: AppNode;
1252
+ apis: ApiHolder;
1253
+ config: T['config'] & {
1254
+ [key in keyof TNewExtensionConfigSchema]: StandardSchemaV1.InferOutput<TNewExtensionConfigSchema[key]>;
1255
+ };
1256
+ inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
1257
+ }): Iterable<UFactoryOutput>;
1258
+ } & ([T['params']] extends [never] ? {} : {
1259
+ params?: TParamsInput extends ExtensionBlueprintDefineParams ? TParamsInput : T['params'] extends ExtensionBlueprintDefineParams ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`' : Partial<T['params']>;
1260
+ })> & VerifyExtensionFactoryOutput<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>): OverridableExtensionDefinition<{
1261
+ kind: T['kind'];
1262
+ name: T['name'];
1263
+ output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
1264
+ inputs: T['inputs'] & TExtraInputs;
1265
+ config: T['config'] & {
1266
+ [key in keyof TNewExtensionConfigSchema]: StandardSchemaV1.InferOutput<TNewExtensionConfigSchema[key]>;
1267
+ };
1268
+ configInput: T['configInput'] & {
1269
+ [key in keyof TNewExtensionConfigSchema]?: StandardSchemaV1.InferInput<TNewExtensionConfigSchema[key]>;
1270
+ };
1271
+ }>;
1272
+ /**
1273
+ * @deprecated Use the `configSchema` option instead of `config.schema`.
1274
+ */
1084
1275
  override<TExtensionConfigSchema extends {
1085
1276
  [key in string]: (zImpl: typeof z) => z.ZodType;
1086
1277
  }, UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends ExtensionDataRef, TExtraInputs extends {
@@ -1093,6 +1284,7 @@ interface OverridableExtensionDefinition<T extends ExtensionDefinitionParameters
1093
1284
  [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`;
1094
1285
  };
1095
1286
  output?: Array<UNewOutput>;
1287
+ configSchema?: never;
1096
1288
  config?: {
1097
1289
  schema: TExtensionConfigSchema & {
1098
1290
  [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`;
@@ -1107,7 +1299,7 @@ interface OverridableExtensionDefinition<T extends ExtensionDefinitionParameters
1107
1299
  node: AppNode;
1108
1300
  apis: ApiHolder;
1109
1301
  config: T['config'] & {
1110
- [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
1302
+ [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>>;
1111
1303
  };
1112
1304
  inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
1113
1305
  }): Iterable<UFactoryOutput>;
@@ -1119,10 +1311,10 @@ interface OverridableExtensionDefinition<T extends ExtensionDefinitionParameters
1119
1311
  output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
1120
1312
  inputs: T['inputs'] & TExtraInputs;
1121
1313
  config: T['config'] & {
1122
- [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
1314
+ [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>>;
1123
1315
  };
1124
1316
  configInput: T['configInput'] & z.input<z.ZodObject<{
1125
- [key in keyof TExtensionConfigSchema]: ReturnType<TExtensionConfigSchema[key]>;
1317
+ [key in keyof TExtensionConfigSchema]: ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>;
1126
1318
  }>>;
1127
1319
  }>;
1128
1320
  }
@@ -1163,14 +1355,39 @@ interface OverridableExtensionDefinition<T extends ExtensionDefinitionParameters
1163
1355
  */
1164
1356
  declare function createExtension<UOutput extends ExtensionDataRef, TInputs extends {
1165
1357
  [inputName in string]: ExtensionInput;
1358
+ }, UFactoryOutput extends ExtensionDataValue<any, any>, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined, UParentInputs extends ExtensionDataRef = ExtensionDataRef, TNewConfigSchema extends {
1359
+ [key: string]: StandardSchemaV1;
1360
+ } = {}>(options: CreateExtensionOptions<TKind, TName, UOutput, TInputs, {}, UFactoryOutput, UParentInputs, TNewConfigSchema> & {
1361
+ config?: never;
1362
+ }): OverridableExtensionDefinition<{
1363
+ config: {
1364
+ [key in keyof TNewConfigSchema]: StandardSchemaV1.InferOutput<TNewConfigSchema[key]>;
1365
+ };
1366
+ configInput: {
1367
+ [key in keyof TNewConfigSchema]?: StandardSchemaV1.InferInput<TNewConfigSchema[key]>;
1368
+ };
1369
+ output: UOutput extends ExtensionDataRef<infer IData, infer IId, infer IConfig> ? ExtensionDataRef<IData, IId, IConfig> : never;
1370
+ inputs: TInputs;
1371
+ params: never;
1372
+ kind: string | undefined extends TKind ? undefined : TKind;
1373
+ name: string | undefined extends TName ? undefined : TName;
1374
+ }>;
1375
+ /**
1376
+ * @deprecated Use the top-level `configSchema` option instead of `config.schema`.
1377
+ * @public
1378
+ */
1379
+ declare function createExtension<UOutput extends ExtensionDataRef, TInputs extends {
1380
+ [inputName in string]: ExtensionInput;
1166
1381
  }, TConfigSchema extends {
1167
1382
  [key: string]: (zImpl: typeof z) => z.ZodType;
1168
- }, UFactoryOutput extends ExtensionDataValue<any, any>, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined, UParentInputs extends ExtensionDataRef = ExtensionDataRef>(options: CreateExtensionOptions<TKind, TName, UOutput, TInputs, TConfigSchema, UFactoryOutput, UParentInputs>): OverridableExtensionDefinition<{
1383
+ }, UFactoryOutput extends ExtensionDataValue<any, any>, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined, UParentInputs extends ExtensionDataRef = ExtensionDataRef>(options: CreateExtensionOptions<TKind, TName, UOutput, TInputs, TConfigSchema, UFactoryOutput, UParentInputs, {}> & {
1384
+ configSchema?: never;
1385
+ }): OverridableExtensionDefinition<{
1169
1386
  config: string extends keyof TConfigSchema ? {} : {
1170
- [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
1387
+ [key in keyof TConfigSchema]: z.infer<ReturnType<((...args: any[]) => any) & TConfigSchema[key]>>;
1171
1388
  };
1172
1389
  configInput: string extends keyof TConfigSchema ? {} : z.input<z.ZodObject<{
1173
- [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
1390
+ [key in keyof TConfigSchema]: ReturnType<((...args: any[]) => any) & TConfigSchema[key]>;
1174
1391
  }>>;
1175
1392
  output: UOutput extends ExtensionDataRef<infer IData, infer IId, infer IConfig> ? ExtensionDataRef<IData, IId, IConfig> : never;
1176
1393
  inputs: TInputs;