@vendure/ui-devkit
Version:
A library for authoring Vendure Admin UI extensions
455 lines (454 loc) • 15.4 kB
TypeScript
import { LanguageCode } from '@vendure/common/lib/generated-types';
export type Extension = AdminUiExtension | TranslationExtension | StaticAssetExtension | GlobalStylesExtension | SassVariableOverridesExtension;
/**
* @description
* Defines extensions to the Admin UI translations. Can be used as a stand-alone extension definition which only adds translations
* without adding new UI functionality, or as part of a full {@link AdminUiExtension}.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export interface TranslationExtension {
/**
* @description
* Optional object defining any translation files for the Admin UI. The value should be an object with
* the key as a 2-character [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes),
* and the value being a [glob](https://github.com/isaacs/node-glob) for any relevant
* translation files in JSON format.
*
* @example
* ```ts
* translations: {
* en: path.join(__dirname, 'translations/*.en.json'),
* de: path.join(__dirname, 'translations/*.de.json'),
* }
* ```
*/
translations: {
[languageCode in LanguageCode]?: string;
};
}
/**
* @description
* Defines extensions which copy static assets to the custom Admin UI application source asset directory.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export interface StaticAssetExtension {
/**
* @description
* Optional array of paths to static assets which will be copied over to the Admin UI app's `/static`
* directory.
*/
staticAssets: StaticAssetDefinition[];
}
/**
* @description
* Defines extensions which add global styles to the custom Admin UI application.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export interface GlobalStylesExtension {
/**
* @description
* Specifies a path (or array of paths) to global style files (css or Sass) which will be
* incorporated into the Admin UI app global stylesheet.
*/
globalStyles: string[] | string;
}
/**
* @description
* Defines an extension which allows overriding Clarity Design System's Sass variables used in styles on the Admin UI.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export interface SassVariableOverridesExtension {
/**
* @description
* Specifies a path to a Sass style file containing variable declarations, which will take precedence over
* default values defined in Clarity.
*/
sassVariableOverrides: string;
}
/**
* @description
* Defines a route which will be added to the Admin UI application.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export interface UiExtensionRouteDefinition {
/**
* @description
* The name of the route. This will be used as the path in the URL.
*/
route: string;
/**
* @description
* The path to the file which exports an array of Angular route definitions.
*/
filePath: string;
/**
* @description
* All extensions will be mounted under the `/extensions/` route. This option allows you to specify a
* custom prefix rather than `/extensions/`. For example, setting this to `custom` would cause the extension
* to be mounted at `/custom/<route>` instead.
*
* A common use case for this is to mount the extension at the root of the Admin UI, by setting this to an empty string.
* This is useful when the extension is intended to replace the default Admin UI, rather than extend it.
*
* @since 2.2.0
*/
prefix?: string;
}
/**
* @description
* Defines extensions to the Admin UI application by specifying additional
* Angular [NgModules](https://angular.io/guide/ngmodules) which are compiled
* into the application.
*
* See [Extending the Admin UI](/guides/extending-the-admin-ui/getting-started/) for
* detailed instructions.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
* @docsWeight 0
*/
export interface AdminUiExtension extends Partial<TranslationExtension>, Partial<StaticAssetExtension>, Partial<GlobalStylesExtension> {
/**
* @description
* An optional ID for the extension module. Only used internally for generating
* import paths to your module. If not specified, a unique hash will be used as the id.
*/
id?: string;
/**
* @description
* The path to the directory containing the extension module(s). The entire contents of this directory
* will be copied into the Admin UI app, including all TypeScript source files, html templates,
* scss style sheets etc.
*/
extensionPath: string;
/**
* @description
* One or more Angular modules which extend the default Admin UI.
*
* @deprecated use `routes` instead of lazy modules, and `providers` instead of shared modules in combination
* with Angular standalone components.
*/
ngModules?: Array<AdminUiExtensionSharedModule | AdminUiExtensionLazyModule>;
/**
* @description
* Defines the paths to a file that exports an array of shared providers such as nav menu items, custom form inputs,
* custom detail components, action bar items, custom history entry components.
*/
providers?: string[];
/**
* @description
* Defines routes that will be lazy-loaded at the `/extensions/` route. The filePath should point to a file
* relative to the `extensionPath` which exports an array of Angular route definitions.
*/
routes?: UiExtensionRouteDefinition[];
/**
* @description
* An optional alias for the module so it can be referenced by other UI extension modules.
*
* By default, Angular modules declared in an AdminUiExtension do not have access to code outside the directory
* defined by the `extensionPath`. A scenario in which that can be useful though is in a monorepo codebase where
* a common NgModule is shared across different plugins, each defined in its own package. An example can be found
* below - note that the main `tsconfig.json` also maps the target module but using a path relative to the project's
* root folder. The UI module is not part of the main TypeScript build task as explained in
* [Extending the Admin UI](https://www.vendure.io/docs/plugins/extending-the-admin-ui/) but having `paths`
* properly configured helps with usual IDE code editing features such as code completion and quick navigation, as
* well as linting.
*
* @example
* ```ts title="packages/common-ui-module/src/ui/ui-shared.module.ts"
* import { NgModule } from '\@angular/core';
* import { SharedModule } from '\@vendure/admin-ui/core';
* import { CommonUiComponent } from './components/common-ui/common-ui.component';
*
* export { CommonUiComponent };
*
* \@NgModule({
* imports: [SharedModule],
* exports: [CommonUiComponent],
* declarations: [CommonUiComponent],
* })
* export class CommonSharedUiModule {}
* ```
*
* ```ts title="packages/common-ui-module/src/index.ts"
* import path from 'path';
*
* import { AdminUiExtension } from '\@vendure/ui-devkit/compiler';
*
* export const uiExtensions: AdminUiExtension = {
* // highlight-next-line
* pathAlias: '\@common-ui-module', // this is the important part
* extensionPath: path.join(__dirname, 'ui'),
* ngModules: [
* {
* type: 'shared' as const,
* ngModuleFileName: 'ui-shared.module.ts',
* ngModuleName: 'CommonSharedUiModule',
* },
* ],
* };
* ```
*
* ```json title="tsconfig.json"
* {
* "compilerOptions": {
* "baseUrl": ".",
* "paths": {
* // highlight-next-line
* "\@common-ui-module/*": ["packages/common-ui-module/src/ui/*"]
* }
* }
* }
* ```
*
* ```ts title="packages/sample-plugin/src/ui/ui-extension.module.ts"
* import { NgModule } from '\@angular/core';
* import { SharedModule } from '\@vendure/admin-ui/core';
* // highlight-start
* // the import below works both in the context of the custom Admin UI app as well as the main project
* // '\@common-ui-module' is the value of "pathAlias" and 'ui-shared.module' is the file we want to reference inside "extensionPath"
* import { CommonSharedUiModule, CommonUiComponent } from '\@common-ui-module/ui-shared.module';
* // highlight-end
*
* \@NgModule({
* imports: [
* SharedModule,
* CommonSharedUiModule,
* RouterModule.forChild([
* {
* path: '',
* pathMatch: 'full',
* component: CommonUiComponent,
* },
* ]),
* ],
* })
* export class SampleUiExtensionModule {}
* ```
*/
pathAlias?: string;
/**
* @description
* Optional array specifying filenames or [glob](https://github.com/isaacs/node-glob) patterns that should
* be skipped when copying the directory defined by `extensionPath`.
*
* @example
* ```ts
* exclude: ['**\/*.spec.ts']
* ```
*/
exclude?: string[];
}
/**
* @description
* A static asset can be provided as a path to the asset, or as an object containing a path and a new
* name, which will cause the compiler to copy and then rename the asset.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export type StaticAssetDefinition = string | {
path: string;
rename: string;
};
/**
* @description
* Configuration defining a single NgModule with which to extend the Admin UI.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export interface AdminUiExtensionSharedModule {
/**
* @description
* Shared modules are directly imported into the main AppModule of the Admin UI
* and should be used to declare custom form components and define custom
* navigation items.
*/
type: 'shared';
/**
* @description
* The name of the file containing the extension module class.
*/
ngModuleFileName: string;
/**
* @description
* The name of the extension module class.
*/
ngModuleName: string;
}
/**
* @description
* Configuration defining a single NgModule with which to extend the Admin UI.
*
* @docsCategory UiDevkit
* @docsPage AdminUiExtension
*/
export interface AdminUiExtensionLazyModule {
/**
* @description
* Lazy modules are lazy-loaded at the `/extensions/` route and should be used for
* modules which define new views for the Admin UI.
*/
type: 'lazy';
/**
* @description
* The route specifies the route at which the module will be lazy-loaded. E.g. a value
* of `'foo'` will cause the module to lazy-load when the `/extensions/foo` route
* is activated.
*/
route: string;
/**
* @description
* The name of the file containing the extension module class.
*/
ngModuleFileName: string;
/**
* @description
* The name of the extension module class.
*/
ngModuleName: string;
}
/**
* @description
* Argument to configure process (watch or compile)
*
* @docsCategory UiDevkit
*/
export type UiExtensionCompilerProcessArgument = string | [string, any];
/**
* @description
* The package manager to use when invoking the Angular CLI to build UI extensions.
*
* @docsCategory UiDevkit
*/
export type UiExtensionBuildCommand = 'npm' | 'yarn' | 'pnpm';
/**
* @description
* Options to configure how the Admin UI should be compiled.
*
* @docsCategory UiDevkit
*/
export interface UiExtensionCompilerOptions {
/**
* @description
* The directory into which the sources for the extended Admin UI will be copied.
*/
outputPath: string;
/**
* @description
* An array of objects which configure Angular modules and/or
* translations with which to extend the Admin UI.
*/
extensions: Extension[];
/**
* @description
* Allows you to manually specify the path to the Angular CLI compiler script. This can be useful in scenarios
* where for some reason the built-in start/build scripts are unable to locate the `ng` command.
*
* This option should not usually be required.
*
* @example
* ```ts
* compileUiExtensions({
* ngCompilerPath: path.join(__dirname, '../../node_modules/@angular/cli/bin/ng.js'),
* outputPath: path.join(__dirname, '../admin-ui'),
* extensions: [
* // ...
* ],
* })
* ```
*
* @since 2.1.0
*/
ngCompilerPath?: string | undefined;
/**
* @description
* Set to `true` in order to compile the Admin UI in development mode (using the Angular CLI
* [ng serve](https://angular.io/cli/serve) command). When in dev mode, any changes to
* UI extension files will be watched and trigger a rebuild of the Admin UI with live
* reloading.
*
* @default false
*/
devMode?: boolean;
/**
* @description
* Allows the baseHref of the compiled Admin UI app to be set. This determines the prefix
* of the app, for example with the default value of `'/admin/'`, the Admin UI app
* will be configured to be served from `http://<host>/admin/`.
*
* Note: if you are using this in conjunction with the {@link AdminUiPlugin} then you should
* also set the `route` option to match this value.
*
* @example
* ```ts
* AdminUiPlugin.init({
* route: 'my-route',
* port: 5001,
* app: compileUiExtensions({
* baseHref: '/my-route/',
* outputPath: path.join(__dirname, './custom-admin-ui'),
* extensions: [],
* devMode: true,
* }),
* }),
* ```
*
* @default '/admin/'
*/
baseHref?: string;
/**
* @description
* In watch mode, allows the port of the dev server to be specified. Defaults to the Angular CLI default
* of `4200`.
*
* @default 4200 | undefined
*/
watchPort?: number;
/**
* @description
* Internally, the Angular CLI will be invoked as an npm script. By default, the compiler will use Yarn
* to run the script if it is detected, otherwise it will use npm. This setting allows you to explicitly
* set which command to use, including pnpm, rather than relying on the default behavior.
*
* @since 1.5.0
*/
command?: UiExtensionBuildCommand;
/**
* @description
* Additional command-line arguments which will get passed to the [ng build](https://angular.io/cli/build)
* command (or [ng serve](https://angular.io/cli/serve) if `devMode = true`).
*
* @example
* ['--disable-host-check'] // to disable host check
*
* @default undefined
*
* @since 1.5.0
*/
additionalProcessArguments?: UiExtensionCompilerProcessArgument[];
}
export type Translations = {
[section: string]: {
[token: string]: string;
};
};
export interface BrandingOptions {
smallLogoPath?: string;
largeLogoPath?: string;
faviconPath?: string;
}
export interface AdminUiExtensionWithId extends AdminUiExtension {
id: string;
}