You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					483 lines
				
				12 KiB
			
		
		
			
		
	
	
					483 lines
				
				12 KiB
			| 
											3 years ago
										 | import { ThemeOverride } from '@adminjs/design-system' | ||
|  | import { TransformOptions as BabelConfig } from 'babel-core' | ||
|  | 
 | ||
|  | import AdminJS from '.' | ||
|  | import BaseResource from './backend/adapters/resource/base-resource' | ||
|  | import BaseDatabase from './backend/adapters/database/base-database' | ||
|  | import { PageContext } from './backend/actions/action.interface' | ||
|  | import { ResourceOptions } from './backend/decorators/resource/resource-options.interface' | ||
|  | import { Locale } from './locale/config' | ||
|  | import { CurrentAdmin } from './current-admin.interface' | ||
|  | import { CoreScripts } from './core-scripts.interface' | ||
|  | import { ComponentLoader } from './backend/utils/component-loader' | ||
|  | 
 | ||
|  | /** | ||
|  |  * AdminJSOptions | ||
|  |  * | ||
|  |  * This is the heart of entire AdminJS - all options resides here. | ||
|  |  * | ||
|  |  * ### Usage with regular javascript | ||
|  |  * | ||
|  |  * ```javascript
 | ||
|  |  * const AdminJS = require('adminjs') | ||
|  |  * //...
 | ||
|  |  * const adminJS = new AdminJS({ | ||
|  |  *   rootPath: '/xyz-admin', | ||
|  |  *   logoutPath: '/xyz-admin/exit', | ||
|  |  *   loginPath: '/xyz-admin/sign-in', | ||
|  |  *   databases: [mongooseConnection], | ||
|  |  *   resources: [{ resource: ArticleModel, options: {...}}], | ||
|  |  *   branding: { | ||
|  |  *     companyName: 'XYZ c.o.', | ||
|  |  *   }, | ||
|  |  * }) | ||
|  |  * ```
 | ||
|  |  * | ||
|  |  * ### TypeScript | ||
|  |  * | ||
|  |  * ```
 | ||
|  |  * import { AdminJSOptions } from 'adminjs' | ||
|  |  * | ||
|  |  * const options: AdminJSOptions = { | ||
|  |  *   rootPath: '/xyz-admin', | ||
|  |  *   logoutPath: '/xyz-admin/exit', | ||
|  |  *   loginPath: '/xyz-admin/sign-in', | ||
|  |  *   databases: [mongooseConnection], | ||
|  |  *   resources: [{ resource: ArticleModel, options: {...}}], | ||
|  |  *   branding: { | ||
|  |  *     companyName: 'XYZ c.o.', | ||
|  |  *   }, | ||
|  |  * } | ||
|  |  * | ||
|  |  * const adminJs = new AdminJS(options) | ||
|  |  * ```
 | ||
|  |  */ | ||
|  | export interface AdminJSOptions { | ||
|  |   /** | ||
|  |    * path, under which, AdminJS will be available. Default to `/admin` | ||
|  |    * | ||
|  |    */ | ||
|  |   rootPath?: string; | ||
|  |   /** | ||
|  |    * url to a logout action, default to `/admin/logout` | ||
|  |    */ | ||
|  |   logoutPath?: string; | ||
|  |   /** | ||
|  |    * url to a login page, default to `/admin/login` | ||
|  |    */ | ||
|  |   loginPath?: string; | ||
|  |   /** | ||
|  |    * Array of all Databases which are supported by AdminJS via adapters | ||
|  |    */ | ||
|  |   databases?: Array<any>; | ||
|  | 
 | ||
|  |   componentLoader?: ComponentLoader; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * List of custom pages which will be visible below all resources | ||
|  |    * @example | ||
|  |    * pages: { | ||
|  |    *   customPage: { | ||
|  |    *     label: "Custom page", | ||
|  |    *     handler: async (request, response, context) => { | ||
|  |    *       return { | ||
|  |    *         text: 'I am fetched from the backend', | ||
|  |    *       } | ||
|  |    *     }, | ||
|  |    *     component: 'SomeStats', | ||
|  |    *   }, | ||
|  |    *   anotherPage: { | ||
|  |    *     label: "TypeScript page", | ||
|  |    *     component: 'TestComponent', | ||
|  |    *   }, | ||
|  |    * }, | ||
|  |    */ | ||
|  |   pages?: AdminPages; | ||
|  |   /** | ||
|  |    * Array of all Resources which are supported by AdminJS via adapters. | ||
|  |    * You can pass either resource or resource with an options and thus modify it. | ||
|  |    * @property {any} resources[].resource | ||
|  |    * @property {ResourceOptions} resources[].options | ||
|  |    * @property {Array<FeatureType>} resources[].features | ||
|  |    * | ||
|  |    * @see ResourceOptions | ||
|  |    */ | ||
|  |   resources?: Array<ResourceWithOptions | any>; | ||
|  |   /** | ||
|  |    * Option to modify the dashboard | ||
|  |    */ | ||
|  |   dashboard?: { | ||
|  |     /** | ||
|  |      * Handler function which can be triggered using {@link ApiClient#getDashboard}. | ||
|  |      */ | ||
|  |     handler?: PageHandler; | ||
|  |     /** | ||
|  |      * Bundled component name which should be rendered when user opens the dashboard | ||
|  |      */ | ||
|  |     component?: string; | ||
|  |   }; | ||
|  |   /** | ||
|  |    * Flag which indicates if version number should be visible on the UI | ||
|  |    */ | ||
|  |   version?: VersionSettings; | ||
|  |   /** | ||
|  |    * Options which are related to the branding. | ||
|  |    */ | ||
|  |   branding?: BrandingOptions | BrandingOptionsFunction; | ||
|  |   /** | ||
|  |    * Custom assets you want to pass to AdminJS | ||
|  |    */ | ||
|  |   assets?: Assets | AssetsFunction; | ||
|  |   /** | ||
|  |    * Indicates is bundled by AdminJS files like: | ||
|  |    * - components.bundle.js | ||
|  |    * - global.bundle.js | ||
|  |    * - design-system.bundle.js | ||
|  |    * - app.bundle.js | ||
|  |    * should be taken from the same server as other AdminJS routes (default) | ||
|  |    * or should be taken from an external CDN. | ||
|  |    * | ||
|  |    * If set - bundles will go from given CDN if unset - from the same server. | ||
|  |    * | ||
|  |    * When you can use this option? So let's say you want to deploy the app on | ||
|  |    * serverless environment like Firebase Cloud Functions. In that case you don't | ||
|  |    * want to serve static files with the same app because your function will be | ||
|  |    * invoked every time frontend asks for static assets. | ||
|  |    * | ||
|  |    * Solution would be to: | ||
|  |    * - create `public` folder in your app | ||
|  |    * - generate `bundle.js` file to `.adminjs/` folder by using {@link AdminJS#initialize} | ||
|  |    * function (with process.env.NODE_ENV set to 'production'). | ||
|  |    * - copy the before mentioned file to `public` folder and rename it to | ||
|  |    * components.bundle.js | ||
|  |    * - copy | ||
|  |    * './node_modules/adminjs/lib/frontend/assets/scripts/app-bundle.production.js' to | ||
|  |    * './public/app.bundle.js', | ||
|  |    * - copy | ||
|  |    * './node_modules/adminjs/lib/frontend/assets/scripts/global-bundle.production.js' to | ||
|  |    * './public/global.bundle.js' | ||
|  |    * * - copy | ||
|  |    * './node_modules/adminjs/node_modules/@adminjs/design-system/bundle.production.js' to | ||
|  |    * './public/design-system.bundle.js' | ||
|  |    * - host entire public folder under some domain (if you use firebase - you can host them | ||
|  |    * with firebase hosting) | ||
|  |    * - point {@link AdminJS.assetsCDN} to this domain | ||
|  |    */ | ||
|  |   assetsCDN?: string; | ||
|  |   /** | ||
|  |    * Environmental variables passed to the frontend. | ||
|  |    * | ||
|  |    * So let say you want to pass some _GOOGLE_MAP_API_TOKEN_ to the frontend. | ||
|  |    * You can do this by adding it here: | ||
|  |    * | ||
|  |    * ```javascript
 | ||
|  |    * new AdminJS({env: { | ||
|  |    *   GOOGLE_MAP_API_TOKEN: 'my-token', | ||
|  |    * }}) | ||
|  |    * ```
 | ||
|  |    * | ||
|  |    * and this token will be available on the frontend by using: | ||
|  |    * | ||
|  |    * ```javascript
 | ||
|  |    * AdminJS.env.GOOGLE_MAP_API_TOKEN | ||
|  |    * ```
 | ||
|  |    */ | ||
|  |   env?: Record<string, string>; | ||
|  | 
 | ||
|  |   /* cspell: disable */ | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Translation file. Change it in order to: | ||
|  |    * - localize admin panel | ||
|  |    * - change any arbitrary text in the UI | ||
|  |    * | ||
|  |    * This is the example for changing name of a couple of resources along with some | ||
|  |    * properties to Polish | ||
|  |    * | ||
|  |    * ```javascript
 | ||
|  |    * { | ||
|  |    *   ... | ||
|  |    *   locale: { | ||
|  |    *     language: 'pl', | ||
|  |    *     translations: { | ||
|  |    *       labels: { | ||
|  |    *         Comments: 'Komentarze', | ||
|  |    *       } | ||
|  |    *       resources: { | ||
|  |    *         Comments: { | ||
|  |    *           properties: { | ||
|  |    *             name: 'Nazwa Komentarza', | ||
|  |    *             content: 'Zawartość', | ||
|  |    *           } | ||
|  |    *         } | ||
|  |    *       } | ||
|  |    *     } | ||
|  |    *   } | ||
|  |    * } | ||
|  |    * ```
 | ||
|  |    * | ||
|  |    * As I mentioned you can use this technic to change any text even in english. | ||
|  |    * So to change button label for a "new action" from default "Create new" to "Create new Comment" | ||
|  |    * only for Comment resource you can do: | ||
|  |    * | ||
|  |    * ```javascript
 | ||
|  |    * { | ||
|  |    *   ... | ||
|  |    *   locale: { | ||
|  |    *     translations: { | ||
|  |    *       resources: { | ||
|  |    *         Comments: { | ||
|  |    *           actions: { | ||
|  |    *             new: 'Create new Comment', | ||
|  |    *           } | ||
|  |    *         } | ||
|  |    *       } | ||
|  |    *     } | ||
|  |    *   } | ||
|  |    * } | ||
|  |    * ```
 | ||
|  |    * | ||
|  |    * Check out the [i18n tutorial]{@tutorial i18n} to see how | ||
|  |    * internationalization in AdminJS works. | ||
|  |    */ | ||
|  |   locale?: Locale; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * rollup bundle options; | ||
|  |    */ | ||
|  |   bundler?: BundlerOptions; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Additional settings. | ||
|  |    */ | ||
|  |   settings?: Partial<AdminJSSettings>; | ||
|  | } | ||
|  | 
 | ||
|  | export type AdminJSSettings = { | ||
|  |   defaultPerPage: number; | ||
|  | }; | ||
|  | 
 | ||
|  | /* cspell: enable */ | ||
|  | 
 | ||
|  | /** | ||
|  |  * @memberof AdminJSOptions | ||
|  |  * @alias Assets | ||
|  |  * | ||
|  |  * Optional assets (stylesheets, and javascript libraries) which can be | ||
|  |  * appended to the HEAD of the page. | ||
|  |  * | ||
|  |  * you can also pass {@link AssetsFunction} instead. | ||
|  |  */ | ||
|  | export type Assets = { | ||
|  |   /** | ||
|  |    * List to urls of custom stylesheets. You can pass your font - icons here (as an example) | ||
|  |    */ | ||
|  |   styles?: Array<string>; | ||
|  |   /** | ||
|  |    * List of urls to custom scripts. If you use some particular js | ||
|  |    * library - you can pass its url here. | ||
|  |    */ | ||
|  |   scripts?: Array<string>; | ||
|  |   /** | ||
|  |    *  Mapping of core scripts in case you want to version your assets | ||
|  |    */ | ||
|  |   coreScripts?: CoreScripts; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * @alias AssetsFunction | ||
|  |  * @name AssetsFunction | ||
|  |  * @memberof AdminJSOptions | ||
|  |  * @returns {Assets | Promise<Assets>} | ||
|  |  * @description | ||
|  |  * Function returning {@link Assets} | ||
|  |  */ | ||
|  | export type AssetsFunction = (admin?: CurrentAdmin) => Assets | Promise<Assets> | ||
|  | 
 | ||
|  | /** | ||
|  |  * Version Props | ||
|  |  * @alias VersionProps | ||
|  |  * @memberof AdminJSOptions | ||
|  |  */ | ||
|  | export type VersionSettings = { | ||
|  |   /** | ||
|  |    * if set to true - current admin version will be visible | ||
|  |    */ | ||
|  |   admin?: boolean; | ||
|  |   /** | ||
|  |    * Here you can pass any arbitrary version text which will be seen in the US. | ||
|  |    * You can pass here your current API version. | ||
|  |    */ | ||
|  |   app?: string; | ||
|  | } | ||
|  | 
 | ||
|  | export type VersionProps = { | ||
|  |   admin?: string; | ||
|  |   app?: string; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Branding Options | ||
|  |  * | ||
|  |  * You can use them to change how AdminJS looks. For instance to change name and | ||
|  |  * colors (dark theme) run: | ||
|  |  * | ||
|  |  * ```javascript
 | ||
|  |  * new AdminJS({ | ||
|  |  *   branding: { | ||
|  |  *     companyName: 'John Doe Family Business', | ||
|  |  *     theme, | ||
|  |  *   } | ||
|  |  * }) | ||
|  |  * ```
 | ||
|  |  * | ||
|  |  * @alias BrandingOptions | ||
|  |  * @memberof AdminJSOptions | ||
|  |  */ | ||
|  | export type BrandingOptions = { | ||
|  |   /** | ||
|  |    * URL to a logo, or `false` if you want to hide the default one. | ||
|  |    */ | ||
|  |   logo?: string | false; | ||
|  |   /** | ||
|  |    * Name of your company, which will replace "AdminJS". | ||
|  |    */ | ||
|  |   companyName?: string; | ||
|  |   /** | ||
|  |    * CSS theme. | ||
|  |    */ | ||
|  |   theme?: Partial<ThemeOverride>; | ||
|  |   /** | ||
|  |    * Flag indicates if "made with love" tiny heart icon | ||
|  |    * should be visible on the bottom sidebar and login page. | ||
|  |    * @new since 6.0.0 | ||
|  |    */ | ||
|  |   withMadeWithLove?: boolean; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * URL to a favicon | ||
|  |    */ | ||
|  |   favicon?: string; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Branding Options Function | ||
|  |  * | ||
|  |  * function returning BrandingOptions. | ||
|  |  * | ||
|  |  * @alias BrandingOptionsFunction | ||
|  |  * @memberof AdminJSOptions | ||
|  |  * @returns {BrandingOptions | Promise<BrandingOptions>} | ||
|  |  */ | ||
|  | export type BrandingOptionsFunction = ( | ||
|  |   admin?: CurrentAdmin | ||
|  | ) => BrandingOptions | Promise<BrandingOptions> | ||
|  | 
 | ||
|  | /** | ||
|  |  * Object describing regular page in AdminJS | ||
|  |  * | ||
|  |  * @alias AdminPage | ||
|  |  * @memberof AdminJSOptions | ||
|  |  */ | ||
|  | export type AdminPage = { | ||
|  |   /** | ||
|  |    * Handler function | ||
|  |    */ | ||
|  |   handler?: PageHandler; | ||
|  |   /** | ||
|  |    * Component defined by using {@link ComponentLoader} | ||
|  |    */ | ||
|  |   component: string; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Page icon | ||
|  |    */ | ||
|  |   icon?: string; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Object describing map of regular pages in AdminJS | ||
|  |  * | ||
|  |  * @alias AdminPages | ||
|  |  * @memberof AdminJSOptions | ||
|  |  */ | ||
|  | export type AdminPages = Record<string, AdminPage> | ||
|  | 
 | ||
|  | /** | ||
|  |  * Default way of passing Options with a Resource | ||
|  |  * @alias ResourceWithOptions | ||
|  |  * @memberof AdminJSOptions | ||
|  |  */ | ||
|  | export type ResourceWithOptions = { | ||
|  |   resource: any; | ||
|  |   options: ResourceOptions; | ||
|  |   features?: Array<FeatureType>; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Function taking {@link ResourceOptions} and merging it with all other options | ||
|  |  * | ||
|  |  * @alias FeatureType | ||
|  |  * @type function | ||
|  |  * @returns {ResourceOptions} | ||
|  |  * @memberof AdminJSOptions | ||
|  |  */ | ||
|  | export type FeatureType = ( | ||
|  |   /** | ||
|  |    * AdminJS instance | ||
|  |    */ | ||
|  |   admin: AdminJS, | ||
|  |   /** | ||
|  |    * Options returned by the feature added before | ||
|  |    */ | ||
|  |   options: ResourceOptions | ||
|  | ) => ResourceOptions | ||
|  | 
 | ||
|  | /** | ||
|  |  * Function which is invoked when user enters given AdminPage | ||
|  |  * | ||
|  |  * @alias PageHandler | ||
|  |  * @memberof AdminJSOptions | ||
|  |  */ | ||
|  | export type PageHandler = ( | ||
|  |   request: any, | ||
|  |   response: any, | ||
|  |   context: PageContext, | ||
|  | ) => Promise<any> | ||
|  | 
 | ||
|  | /** | ||
|  |  * Bundle options | ||
|  |  * | ||
|  |  * @alias BundlerOptions | ||
|  |  * @memberof AdminJSOptions | ||
|  |  * @example | ||
|  |  * const adminJS = new AdminJS({ | ||
|  |     resources: [], | ||
|  |     rootPath: '/admin', | ||
|  |     babelConfig: './.adminJS.babelrc' | ||
|  |    }) | ||
|  |  */ | ||
|  | export type BundlerOptions = { | ||
|  |   /** | ||
|  |    * The file path to babel config file or json object of babel config. | ||
|  |    */ | ||
|  |   babelConfig?: BabelConfig | string; | ||
|  | } | ||
|  | 
 | ||
|  | export interface AdminJSOptionsWithDefault extends AdminJSOptions { | ||
|  |   rootPath: string; | ||
|  |   logoutPath: string; | ||
|  |   loginPath: string; | ||
|  |   databases?: Array<BaseDatabase>; | ||
|  |   resources?: Array<BaseResource | { | ||
|  |     resource: BaseResource; | ||
|  |     options: ResourceOptions; | ||
|  |   }>; | ||
|  |   dashboard: { | ||
|  |     handler?: PageHandler; | ||
|  |     component?: string; | ||
|  |   }; | ||
|  |   bundler: BundlerOptions; | ||
|  |   pages: AdminJSOptions['pages']; | ||
|  | } |