chore: getting the tests working

Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com>
Co-authored-by: Camila Belo <camilaibs@users.noreply.github.com>
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2024-08-09 15:12:47 +02:00
parent 4bc224cc83
commit e6c763f76b
38 changed files with 578 additions and 281 deletions
@@ -30,6 +30,7 @@ describe('ApiBlueprint', () => {
params: {
factory,
},
namespace: 'test',
});
expect(extension).toMatchInlineSnapshot(`
@@ -60,7 +61,7 @@ describe('ApiBlueprint', () => {
const api = createApiRef<{ foo: string }>({ id: 'test' });
const factory = jest.fn(() => ({ foo: 'bar' }));
const extension = ApiBlueprint.make({
const extension = ApiBlueprint.makeWithOverrides({
config: {
schema: {
test: z => z.string().default('test'),
@@ -14,9 +14,10 @@
* limitations under the License.
*/
import { createExtensionBlueprint } from '../wiring';
import { createApiExtension } from './createApiExtension';
import { createApiExtension } from '../extensions/createApiExtension';
import { AnyApiFactory } from '@backstage/core-plugin-api';
/** @public */
export const ApiBlueprint = createExtensionBlueprint({
kind: 'api',
attachTo: { id: 'app', input: 'apis' },
@@ -27,5 +28,4 @@ export const ApiBlueprint = createExtensionBlueprint({
*factory(params: { factory: AnyApiFactory }) {
yield createApiExtension.factoryDataRef(params.factory);
},
namespace: ({ factory }) => factory.api.id,
});
@@ -15,6 +15,7 @@
*/
import { coreExtensionData, createExtensionBlueprint } from '../wiring';
/** @public */
export const AppRootElementBlueprint = createExtensionBlueprint({
kind: 'app-root-element',
attachTo: { id: 'app/root', input: 'elements' },
@@ -78,7 +78,7 @@ describe('AppRootWrapperBlueprint', () => {
});
it('should render the complex component wrapper', async () => {
const extension = AppRootWrapperBlueprint.make({
const extension = AppRootWrapperBlueprint.makeWithOverrides({
namespace: 'ns',
name: 'test',
config: {
@@ -94,6 +94,9 @@ describe('AppRootWrapperBlueprint', () => {
Component: ({ children }) => (
<div data-testid={`${config.name}-${inputs.children.length}`}>
{children}
{inputs.children.flatMap(c =>
c.get(coreExtensionData.reactElement),
)}
</div>
),
});
@@ -119,9 +122,9 @@ describe('AppRootWrapperBlueprint', () => {
.render();
await waitFor(() => {
expect(getByText('Its Me')).toBeInTheDocument();
expect(getByText('Hi')).toBeInTheDocument();
expect(getByTestId('Robin-1')).toBeInTheDocument();
expect(getByText('Its Me')).toBeInTheDocument();
});
});
});
@@ -17,8 +17,9 @@
import React from 'react';
import { ComponentType, PropsWithChildren } from 'react';
import { createExtensionBlueprint } from '../wiring';
import { createAppRootWrapperExtension } from './createAppRootWrapperExtension';
import { createAppRootWrapperExtension } from '../extensions/createAppRootWrapperExtension';
/** @public */
export const AppRootWrapperBlueprint = createExtensionBlueprint({
kind: 'app-root-wrapper',
attachTo: { id: 'app/root', input: 'wrappers' },
@@ -44,7 +44,6 @@ describe('NavItemBlueprint', () => {
"additionalProperties": false,
"properties": {
"title": {
"default": "TEST",
"type": "string",
},
},
@@ -17,8 +17,9 @@
import { IconComponent } from '@backstage/core-plugin-api';
import { RouteRef } from '../routing';
import { createExtensionBlueprint } from '../wiring';
import { createNavItemExtension } from './createNavItemExtension';
import { createNavItemExtension } from '../extensions/createNavItemExtension';
/** @public */
export const NavItemBlueprint = createExtensionBlueprint({
kind: 'nav-item',
attachTo: { id: 'app/nav', input: 'items' },
@@ -30,6 +31,7 @@ export const NavItemBlueprint = createExtensionBlueprint({
{
icon,
routeRef,
title,
}: {
title: string;
icon: IconComponent;
@@ -38,14 +40,14 @@ export const NavItemBlueprint = createExtensionBlueprint({
{ config },
) => [
createNavItemExtension.targetDataRef({
title: config.title,
title: config.title ?? title,
icon,
routeRef,
}),
],
config: {
schema: ({ title }) => ({
title: z => z.string().default(title),
}),
schema: {
title: z => z.string().optional(),
},
},
});
@@ -15,8 +15,9 @@
*/
import { createExtensionBlueprint } from '../wiring';
import { createNavLogoExtension } from './createNavLogoExtension';
import { createNavLogoExtension } from '../extensions/createNavLogoExtension';
/** @public */
export const NavLogoBlueprint = createExtensionBlueprint({
kind: 'nav-logo',
attachTo: { id: 'app/nav', input: 'logos' },
@@ -106,7 +106,7 @@ describe('PageBlueprint', () => {
});
it('should allow defining additional inputs to the extension', async () => {
const myPage = PageBlueprint.make({
const myPage = PageBlueprint.makeWithOverrides({
name: 'test-page',
inputs: {
cards: createExtensionInput([coreExtensionData.reactElement], {
@@ -18,6 +18,7 @@ import { RouteRef } from '../routing';
import { coreExtensionData, createExtensionBlueprint } from '../wiring';
import { ExtensionBoundary } from '../components';
/** @public */
export const PageBlueprint = createExtensionBlueprint({
kind: 'page',
attachTo: { id: 'app/routes', input: 'routes' },
@@ -37,7 +38,7 @@ export const PageBlueprint = createExtensionBlueprint({
loader,
routeRef,
}: {
defaultPath?: string;
defaultPath: string;
loader: () => Promise<JSX.Element>;
routeRef?: RouteRef;
},
@@ -47,7 +48,7 @@ export const PageBlueprint = createExtensionBlueprint({
loader().then(element => ({ default: () => element })),
);
yield coreExtensionData.routePath(config.path ?? defaultPath!);
yield coreExtensionData.routePath(config.path ?? defaultPath);
yield coreExtensionData.reactElement(
<ExtensionBoundary node={node}>
<ExtensionComponent />
@@ -97,7 +97,7 @@ describe('RouterBlueprint', () => {
});
it('should work with complex options and props', async () => {
const extension = RouterBlueprint.make({
const extension = RouterBlueprint.makeWithOverrides({
namespace: 'test',
name: 'test',
config: {
@@ -15,8 +15,9 @@
*/
import { ComponentType, PropsWithChildren } from 'react';
import { createExtensionBlueprint } from '../wiring';
import { createRouterExtension } from './createRouterExtension';
import { createRouterExtension } from '../extensions/createRouterExtension';
/** @public */
export const RouterBlueprint = createExtensionBlueprint({
kind: 'app-router-component',
attachTo: { id: 'app/root', input: 'router' },
@@ -15,10 +15,11 @@
*/
import React, { ComponentType, lazy } from 'react';
import { createExtensionBlueprint } from '../wiring';
import { createSignInPageExtension } from './createSignInPageExtension';
import { createSignInPageExtension } from '../extensions/createSignInPageExtension';
import { SignInPageProps } from '@backstage/core-plugin-api';
import { ExtensionBoundary } from '../components';
/** @public */
export const SignInPageBlueprint = createExtensionBlueprint({
kind: 'sign-in-page',
attachTo: { id: 'app/root', input: 'signInPage' },
@@ -27,7 +27,8 @@ describe('ThemeBlueprint', () => {
} as AppTheme;
it('should create an extension with sensible defaults', () => {
expect(ThemeBlueprint.make({ params: { theme } })).toMatchInlineSnapshot(`
expect(ThemeBlueprint.make({ name: 'light', params: { theme } }))
.toMatchInlineSnapshot(`
{
"$$type": "@backstage/ExtensionDefinition",
"attachTo": {
@@ -16,12 +16,12 @@
import { AppTheme } from '@backstage/core-plugin-api';
import { createExtensionBlueprint } from '../wiring';
import { createThemeExtension } from './createThemeExtension';
import { createThemeExtension } from '../extensions/createThemeExtension';
/** @public */
export const ThemeBlueprint = createExtensionBlueprint({
kind: 'theme',
namespace: 'app',
name: ({ theme }) => theme.id,
attachTo: { id: 'app', input: 'themes' },
output: [createThemeExtension.themeDataRef],
dataRefs: {
@@ -56,7 +56,7 @@ describe('TranslationBlueprint', () => {
"inputs": {},
"kind": "translation",
"name": "blob",
"namespace": "translationRefId",
"namespace": undefined,
"output": [
[Function],
],
@@ -15,12 +15,12 @@
*/
import { createExtensionBlueprint } from '../wiring';
import { createTranslationExtension } from './createTranslationExtension';
import { createTranslationExtension } from '../extensions/createTranslationExtension';
import { TranslationMessages, TranslationResource } from '../translation';
/** @public */
export const TranslationBlueprint = createExtensionBlueprint({
kind: 'translation',
namespace: ({ resource }) => resource.id,
attachTo: { id: 'app', input: 'translations' },
output: [createTranslationExtension.translationDataRef],
dataRefs: {
@@ -0,0 +1,27 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { ApiBlueprint } from './ApiBlueprint';
export { AppRootElementBlueprint } from './AppRootElementBlueprint';
export { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint';
export { IconBundleBlueprint } from './IconBundleBlueprint';
export { NavItemBlueprint } from './NavItemBlueprint';
export { NavLogoBlueprint } from './NavLogoBlueprint';
export { PageBlueprint } from './PageBlueprint';
export { RouterBlueprint } from './RouterBlueprint';
export { SignInPageBlueprint } from './SignInPageBlueprint';
export { ThemeBlueprint } from './ThemeBlueprint';
export { TranslationBlueprint } from './TranslationBlueprint';
@@ -24,7 +24,10 @@ import {
import { AnyExtensionInputMap } from '../wiring/createExtension';
import { Expand } from '../types';
/** @public */
/**
* @public
* @deprecated Use {@link ApiBlueprint} instead.
*/
export function createApiExtension<
TConfig extends {},
TInputs extends AnyExtensionInputMap,
@@ -30,6 +30,7 @@ import {
* the app layout. This is useful for example for shared popups and similar.
*
* @public
* @deprecated Use {@link AppRootElementBlueprint} instead.
*/
export function createAppRootElementExtension<
TConfig extends {},
@@ -31,6 +31,7 @@ import { Expand } from '../types';
* and similar.
*
* @public
* @deprecated Use {@link AppRootWrapperBlueprint} instead.
*/
export function createAppRootWrapperExtension<
TConfig extends {},
@@ -21,7 +21,9 @@ import { RouteRef } from '../routing';
/**
* Helper for creating extensions for a nav item.
*
* @public
* @deprecated Use {@link NavItemBlueprint} instead.
*/
export function createNavItemExtension(options: {
namespace?: string;
@@ -18,7 +18,9 @@ import { createExtension, createExtensionDataRef } from '../wiring';
/**
* Helper for creating extensions for a nav logos.
*
* @public
* @deprecated Use {@link NavLogoBlueprint} instead.
*/
export function createNavLogoExtension(options: {
name?: string;
@@ -31,6 +31,7 @@ import { ExtensionDefinition } from '../wiring/createExtension';
* Helper for creating extensions for a routable React page component.
*
* @public
* @deprecated Use {@link PageBlueprint} instead.
*/
export function createPageExtension<
TConfig extends { path: string },
@@ -31,6 +31,7 @@ import { Expand } from '../types';
* MemoryRouter in tests, or to add additional props to a BrowserRouter.
*
* @public
* @deprecated Use {@link RouterBlueprint} instead.
*/
export function createRouterExtension<
TConfig extends {},
@@ -30,6 +30,7 @@ import { SignInPageProps } from '@backstage/core-plugin-api';
/**
*
* @public
* @deprecated Use {@link SignInPageBlueprint} instead.
*/
export function createSignInPageExtension<
TConfig extends {},
@@ -17,7 +17,10 @@
import { createExtension, createExtensionDataRef } from '../wiring';
import { AppTheme } from '@backstage/core-plugin-api';
/** @public */
/**
* @public
* @deprecated Use {@link ThemeBlueprint} instead.
*/
export function createThemeExtension(theme: AppTheme) {
return createExtension({
kind: 'theme',
@@ -31,7 +34,10 @@ export function createThemeExtension(theme: AppTheme) {
});
}
/** @public */
/**
* @public
* @deprecated Use {@link ThemeBlueprint} instead.
*/
export namespace createThemeExtension {
export const themeDataRef = createExtensionDataRef<AppTheme>().with({
id: 'core.theme.theme',
@@ -17,7 +17,10 @@
import { TranslationMessages, TranslationResource } from '../translation';
import { createExtension, createExtensionDataRef } from '../wiring';
/** @public */
/**
* @public
* @deprecated Use {@link TranslationBlueprint} instead.
*/
export function createTranslationExtension(options: {
name?: string;
resource: TranslationResource | TranslationMessages;
@@ -34,7 +37,10 @@ export function createTranslationExtension(options: {
});
}
/** @public */
/**
* @public
* @deprecated Use {@link TranslationBlueprint} instead.
*/
export namespace createTranslationExtension {
export const translationDataRef = createExtensionDataRef<
TranslationResource | TranslationMessages
@@ -25,4 +25,3 @@ export { createSignInPageExtension } from './createSignInPageExtension';
export { createThemeExtension } from './createThemeExtension';
export { createComponentExtension } from './createComponentExtension';
export { createTranslationExtension } from './createTranslationExtension';
export { IconBundleBlueprint } from './IconBundleBlueprint';
@@ -22,6 +22,7 @@
export * from './analytics';
export * from './apis';
export * from './blueprints';
export * from './components';
export * from './extensions';
export * from './icons';
@@ -127,7 +127,7 @@ describe('createExtensionBlueprint', () => {
},
});
const extension = TestExtensionBlueprint.make({
const extension = TestExtensionBlueprint.makeWithOverrides({
name: 'my-extension',
factory(origFactory) {
return origFactory({
@@ -185,11 +185,8 @@ describe('createExtensionBlueprint', () => {
},
});
const extension = TestExtensionBlueprint.make({
const extension = TestExtensionBlueprint.makeWithOverrides({
name: 'my-extension',
params: {
text: 'Hello, world!',
},
config: {
schema: {
something: z => z.string(),
@@ -236,7 +233,7 @@ describe('createExtensionBlueprint', () => {
},
});
TestExtensionBlueprint.make({
TestExtensionBlueprint.makeWithOverrides({
name: 'my-extension',
params: {
text: 'Hello, world!',
@@ -266,11 +263,8 @@ describe('createExtensionBlueprint', () => {
},
});
const extension = TestExtensionBlueprint.make({
const extension = TestExtensionBlueprint.makeWithOverrides({
name: 'my-extension',
params: {
text: 'Hello, world!',
},
config: {
schema: {
something: z => z.string(),
@@ -341,65 +335,6 @@ describe('createExtensionBlueprint', () => {
expect(true).toBe(true);
});
it('should allow providing callback for properties to set with params', () => {
type TestParams = { test: string };
const Blueprint = createExtensionBlueprint({
kind: 'test-extension',
attachTo: { id: 'test', input: 'default' },
name: (params: TestParams) => `${params.test}-name`,
output: [coreExtensionData.reactElement],
namespace: (props: TestParams) => props.test,
config: {
schema: (props: TestParams) => ({
test: z => z.string().default(props.test),
}),
},
factory(params: TestParams) {
return [coreExtensionData.reactElement(<div>{params.test}</div>)];
},
});
expect(Blueprint.make({ params: { test: 'hello' } }))
.toMatchInlineSnapshot(`
{
"$$type": "@backstage/ExtensionDefinition",
"attachTo": {
"id": "test",
"input": "default",
},
"configSchema": {
"parse": [Function],
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"test": {
"default": "hello",
"type": "string",
},
},
"type": "object",
},
},
"disabled": false,
"factory": [Function],
"inputs": {},
"kind": "test-extension",
"name": "hello-name",
"namespace": "hello",
"output": [
[Function],
],
"override": [Function],
"toString": [Function],
"version": "v2",
}
`);
expect(true).toBe(true);
});
it('should allow merging of inputs', () => {
const blueprint = createExtensionBlueprint({
kind: 'test-extension',
@@ -418,7 +353,7 @@ describe('createExtensionBlueprint', () => {
},
});
blueprint.make({
blueprint.makeWithOverrides({
inputs: {
test2: createExtensionInput([coreExtensionData.reactElement], {
singleton: true,
@@ -453,7 +388,7 @@ describe('createExtensionBlueprint', () => {
},
});
blueprint.make({
blueprint.makeWithOverrides({
inputs: {
// @ts-expect-error
test: createExtensionInput([]), // Overrides are not allowed
@@ -480,7 +415,7 @@ describe('createExtensionBlueprint', () => {
});
const ext = toInternalExtensionDefinition(
blueprint.make({
blueprint.makeWithOverrides({
output: [testDataRef2],
factory(origFactory) {
const parent = origFactory({});
@@ -509,7 +444,7 @@ describe('createExtensionBlueprint', () => {
expect(
factoryOutput(
blueprint.make({
blueprint.makeWithOverrides({
output: [testDataRef1, testDataRef2],
*factory(origFactory) {
yield* origFactory({});
@@ -521,7 +456,7 @@ describe('createExtensionBlueprint', () => {
expect(
factoryOutput(
blueprint.make({
blueprint.makeWithOverrides({
output: [testDataRef1, testDataRef2],
factory(origFactory) {
return [...origFactory({}), testDataRef2('bar')];
@@ -544,9 +479,9 @@ describe('createExtensionBlueprint', () => {
},
});
// @ts-expect-error
blueprint.make({
blueprint.makeWithOverrides({
output: [testDataRef2.optional()],
// @ts-expect-error
*factory() {
yield testDataRef1('foo');
yield testDataRef2('bar');
@@ -555,7 +490,7 @@ describe('createExtensionBlueprint', () => {
expect(
factoryOutput(
blueprint.make({
blueprint.makeWithOverrides({
output: [testDataRef2.optional()],
*factory() {
yield testDataRef2('bar');
@@ -578,9 +513,9 @@ describe('createExtensionBlueprint', () => {
},
});
// @ts-expect-error
blueprint.make({
blueprint.makeWithOverrides({
output: [testDataRef1, testDataRef2],
// @ts-expect-error
*factory(origFactory) {
yield* origFactory({});
},
@@ -588,7 +523,7 @@ describe('createExtensionBlueprint', () => {
expect(
factoryOutput(
blueprint.make({
blueprint.makeWithOverrides({
output: [testDataRef1, testDataRef2],
*factory(origFactory) {
yield* origFactory({});
@@ -52,14 +52,14 @@ export type CreateExtensionBlueprintOptions<
TDataRefs extends { [name in string]: AnyExtensionDataRef },
> = {
kind: TKind;
namespace?: TNamespace | ((params: TParams) => TNamespace);
namespace?: TNamespace;
attachTo: { id: string; input: string };
disabled?: boolean;
inputs?: TInputs;
output: Array<UOutput>;
name?: TName | ((params: TParams) => TName);
name?: TName;
config?: {
schema: TConfigSchema | ((params: TParams) => TConfigSchema);
schema: TConfigSchema;
};
factory(
params: TParams,
@@ -96,13 +96,32 @@ export interface ExtensionBlueprint<
> {
dataRefs: TDataRefs;
make<
TNewNamespace extends string | undefined,
TNewName extends string | undefined,
>(args: {
namespace?: TNewNamespace;
name?: TNewName;
attachTo?: { id: string; input: string };
disabled?: boolean;
params: TParams;
}): ExtensionDefinition<
TConfig,
TConfigInput,
UOutput,
TInputs,
TKind,
string | undefined extends TNewNamespace ? TNamespace : TNewNamespace,
string | undefined extends TNewName ? TName : TNewName
>;
/**
* Creates a new extension from the blueprint.
*
* You must either pass `params` directly, or define a `factory` that can
* optionally call the original factory with the same params.
*/
make<
makeWithOverrides<
TNewNamespace extends string | undefined,
TNewName extends string | undefined,
TExtensionConfigSchema extends {
@@ -116,52 +135,45 @@ export interface ExtensionBlueprint<
{ optional: boolean; singleton: boolean }
>;
},
>(
args: {
namespace?: TNewNamespace;
name?: TNewName;
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TExtraInputs & {
[KName in keyof TInputs]?: `Error: Input '${KName &
string}' is already defined in parent definition`;
>(args: {
namespace?: TNewNamespace;
name?: TNewName;
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TExtraInputs & {
[KName in keyof TInputs]?: `Error: Input '${KName &
string}' is already defined in parent definition`;
};
output?: Array<UNewOutput>;
config?: {
schema: TExtensionConfigSchema & {
[KName in keyof TConfig]?: `Error: Config key '${KName &
string}' is already defined in parent schema`;
};
output?: Array<UNewOutput>;
config?: {
schema: TExtensionConfigSchema & {
[KName in keyof TConfig]?: `Error: Config key '${KName &
string}' is already defined in parent schema`;
};
factory(
originalFactory: (
params: TParams,
context?: {
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
) => ExtensionDataContainer<UOutput>,
context: {
node: AppNode;
config: TConfig & {
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
>;
};
};
} & (
| ({
factory(
originalFactory: (
params: TParams,
context?: {
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
) => ExtensionDataContainer<UOutput>,
context: {
node: AppNode;
config: TConfig & {
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
>;
};
inputs: Expand<ResolvedExtensionInputs<TInputs & TExtraInputs>>;
},
): Iterable<UFactoryOutput>;
} & VerifyExtensionFactoryOutput<
AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput,
UFactoryOutput
>)
| {
params: TParams;
}
),
): ExtensionDefinition<
inputs: Expand<ResolvedExtensionInputs<TInputs & TExtraInputs>>;
},
): Iterable<UFactoryOutput> &
VerifyExtensionFactoryOutput<
AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput,
UFactoryOutput
>;
}): ExtensionDefinition<
{
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
@@ -243,7 +255,7 @@ class ExtensionBlueprintImpl<
dataRefs: TDataRefs;
public make<
public makeWithOverrides<
TExtensionConfigSchema extends {
[key in string]: (zImpl: typeof z) => z.ZodType;
},
@@ -264,11 +276,10 @@ class ExtensionBlueprintImpl<
disabled?: boolean;
inputs?: TExtraInputs;
output?: Array<UNewOutput>;
params?: TParams;
config?: {
schema: TExtensionConfigSchema;
};
factory?(
factory(
originalFactory: (
params: TParams,
context?: {
@@ -312,77 +323,82 @@ class ExtensionBlueprintImpl<
>
>
> {
const optionsSchema = // can remove this args.params check with the split apart of .make
typeof this.options.config?.schema === 'function' && args.params
? this.options.config?.schema(args.params)
: this.options.config?.schema;
const schema = {
...optionsSchema,
...this.options.config?.schema,
...args.config?.schema,
} as TConfigSchema & TExtensionConfigSchema;
const namespace =
typeof this.options.namespace === 'function' && args.params
? this.options.namespace(args.params)
: this.options.namespace;
const name =
typeof this.options.name === 'function' && args.params
? this.options.name(args.params)
: this.options.name;
return createExtension({
kind: this.options.kind,
namespace: args.namespace ?? namespace,
name: args.name ?? name,
namespace: args.namespace ?? this.options.namespace,
name: args.name ?? this.options.name,
attachTo: args.attachTo ?? this.options.attachTo,
disabled: args.disabled ?? this.options.disabled,
inputs: { ...args.inputs, ...this.options.inputs },
output: args.output ?? this.options.output,
config: Object.keys(schema).length === 0 ? undefined : { schema },
factory: ({ node, config, inputs }) => {
if (args.factory) {
return args.factory(
(
innerParams: TParams,
innerContext?: {
config?: {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
};
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
): ExtensionDataContainer<UOutput> => {
return createDataContainer<UOutput>(
this.options.factory(innerParams, {
node,
config: innerContext?.config ?? config,
inputs: (innerContext?.inputs ?? inputs) as any, // TODO: Fix the way input values are overridden
}),
);
return args.factory(
(
innerParams: TParams,
innerContext?: {
config?: {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
};
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
{
node,
config,
inputs,
},
);
} else if (args.params) {
return this.options.factory(args.params, {
): ExtensionDataContainer<UOutput> => {
return createDataContainer<UOutput>(
this.options.factory(innerParams, {
node,
config: innerContext?.config ?? config,
inputs: (innerContext?.inputs ?? inputs) as any, // TODO: Fix the way input values are overridden
}),
);
},
{
node,
config,
// TODO: Figure out types once legacy data map input type is gone
inputs: inputs as unknown as Expand<
ResolvedExtensionInputs<TInputs>
>,
});
}
throw new Error('Either params or factory must be provided');
inputs,
},
);
},
} as CreateExtensionOptions<TKind, string | undefined extends TNewNamespace ? TNamespace : TNewNamespace, string | undefined extends TNewName ? TName : TNewName, AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, TInputs & TExtraInputs, TConfigSchema & TExtensionConfigSchema, UFactoryOutput>);
}
public make<
TNewNamespace extends string | undefined = undefined,
TNewName extends string | undefined = undefined,
>(args: {
namespace?: TNewNamespace;
name?: TNewName;
attachTo?: { id: string; input: string };
disabled?: boolean;
params: TParams;
}): ExtensionDefinition<
{
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
},
z.input<
z.ZodObject<{
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}>
>
> {
return createExtension({
kind: this.options.kind,
namespace: args.namespace ?? this.options.namespace,
name: args.name ?? this.options.name,
attachTo: args.attachTo ?? this.options.attachTo,
disabled: args.disabled ?? this.options.disabled,
inputs: this.options.inputs,
output: this.options.output,
config: this.options.config,
factory: ctx => this.options.factory(args.params, ctx),
} as CreateExtensionOptions<TKind, string | undefined extends TNewNamespace ? TNamespace : TNewNamespace, string | undefined extends TNewName ? TName : TNewName, UOutput, TInputs, TConfigSchema, any>);
}
}
/**