import { Plugin, PluginOption } from "vite"; import { JSX, ReactNode } from "react"; import { ChunkExtractor } from "@loadable/server"; import { Express, RequestHandler } from "express"; import { Linter } from "eslint"; import { TestUserConfig } from "vitest/node"; //#region src/types/types.d.ts type ViteRenderFunction = (options: { createUnsafeNonce?: () => string; clientEntry: string; } & SharedRenderProps) => Promise; type SkuProvider = ({ children }: { children: ReactNode; }) => ReactNode; interface RenderCallbackParams { SkuProvider: SkuProvider; addLanguageChunk: (language: string) => void; getBodyTags: () => string; getHeadTags: (options?: { excludeJs?: boolean; excludeCss?: boolean; }) => string; flushHeadTags: (options?: { excludeJs?: boolean; excludeCss?: boolean; }) => string; extractor: ChunkExtractor; registerScript?: (script: string) => void; } interface Server { renderCallback: (params: RenderCallbackParams, ...requestHandlerParams: Parameters) => void; onStart?: (app: Express) => void; middleware?: RequestHandler | RequestHandler[]; } interface RenderableRoute { routeName: string; route: string; environment: string; site: string; language: string; } interface SharedRenderProps extends RenderableRoute { libraryName?: string; libraryFile?: string; webpackStats?: any; } interface RenderAppProps extends SharedRenderProps { SkuProvider: ({ children }: { children: ReactNode; }) => JSX.Element; _addChunk: (chunkName: string) => void; renderToStringAsync: (element: ReactNode) => Promise; createUnsafeNonce?: (nonce: string) => void; } interface RenderDocumentProps extends SharedRenderProps { app: App; headTags: string; bodyTags: string; } interface Render { renderApp(p: RenderAppProps): Promise | App; provideClientContext?(p: SharedRenderProps & { app: App; }): Promise | any; renderDocument(p: RenderDocumentProps): Promise | string; } interface SkuRouteObject { route: string; name?: string; entry?: string; languages?: readonly string[]; } type SkuRoute = string | SkuRouteObject; interface SkuSiteObject { name: string; host?: string; routes?: readonly SkuRoute[]; languages?: readonly string[]; } type SkuSite = string | SkuSiteObject; interface TransformOutputPathFunctionParams { environment: string | undefined; site: string | undefined; route: string; } type TransformOutputPathFunction = (input: TransformOutputPathFunctionParams) => string; type SkuLanguage = string | { name: string; extends?: string; }; interface SkuConfigBase { /** * Selects request-time SSR or the static generation behavior. * * `'ssr'` (SSR) is experimental and not for production use. */ buildType?: 'ssr' | 'static'; /** * The bundler that sku uses to build the application. * * Vite supports static apps and experimental SSR via `buildType: 'ssr'`. * * @default "webpack" */ bundler?: 'webpack' | 'vite'; /** * The test runner that sku uses to run the tests. * * @default: "jest" */ testRunner?: 'vitest' | 'jest'; /** * The client entry point to the app. * * @default "./src/client.tsx" * @link https://seek-oss.github.io/sku/configuration#cliententry */ clientEntry?: string; /** * An array of `node_modules` to be compiled as if they were part of your source code. * * Ideally, this setting should only be used for internally controlled packages. * * @default "[]" * @link https://seek-oss.github.io/sku/configuration#compilepackages */ compilePackages?: string[]; /** * **Unavailable for libraries** * * Enable content security policy feature. More info at https://seek-oss.github.io/sku/csp * * @default false * @link https://seek-oss.github.io/sku/configuration#cspenabled */ cspEnabled?: boolean; /** * Extra external hosts to allow in your `script-src` content security policy. Only relevant if {@link cspEnabled} is set to `true`. * * @default [] * @link https://seek-oss.github.io/sku/configuration#cspextrascriptsrchosts */ cspExtraScriptSrcHosts?: string[]; /** * This function provides a way to modify sku's ESLint configuration. * It should only be used in exceptional circumstances where a solution cannot be achieved by adjusting standard configuration options. * * Before customizing your ESLint configuration, please reach out via the [support page](https://seek-oss.github.io/sku/support) to discuss your requirements and potential alternative solutions. * * ESLint rules help to maintain code quality and consistency. * Some rules even prevent potential bugs in your code, e.g. React rules. * Rather than disabling a rule purely because it causes frequent errors, consider whether these errors may be a symptom of a larger problem in your codebase. * * If you believe other consumers would benefit from the addition/removal/modificaton of a rule, consider contributing the change to [`eslint-config-seek`](https://github.com/seek-oss/eslint-config-seek). * * Sku provides no guarantees that its ESLint configuration will remain compatible with any customizations made within this function. * It is the responsibility of the user to ensure that their customizations are compatible with sku. * * @link https://seek-oss.github.io/sku/configuration#dangerouslyseteslintconfig */ dangerouslySetESLintConfig?: (skuESLintConfig: Linter.Config[]) => Linter.Config[]; /** * This function provides a way to modify sku's Jest configuration. * It should only be used in exceptional circumstances where a solution cannot be achieved by adjusting standard configuration options. * * Before customizing your Jest configuration, please reach out via the [support page](https://seek-oss.github.io/sku/support) to discuss your requirements and potential alternative solutions. * * Sku provides no guarantees that its Jest configuration will remain compatible with any customizations made within this function. * It is the responsibility of the user to ensure that their customizations are compatible with sku. * * @link https://seek-oss.github.io/sku/configuration#dangerouslysetjestconfig */ dangerouslySetJestConfig?: (skuJestConfig: any) => any; /** * This function provides a way to modify sku's TypeScript configuration. * It should only be used in exceptional circumstances where a solution cannot be achieved by adjusting standard configuration options. * * Before customizing your TypeScript configuration, please reach out via the [support page](https://seek-oss.github.io/sku/support) to discuss your requirements and potential alternative solutions. * * Sku provides no guarantees that its TypeScript configuration will remain compatible with any customizations made within this function. * It is the responsibility of the user to ensure that their customizations are compatible with sku. * * @link https://seek-oss.github.io/sku/configuration#dangerouslysettsconfig */ dangerouslySetTSConfig?: (skuTSConfig: any) => any; /** * This function provides a way to modify sku's Vitest configuration. * It should only be used in exceptional circumstances where a solution cannot be achieved by adjusting standard configuration options. * * Before customizing your Vitest configuration, please reach out via the [support page](https://seek-oss.github.io/sku/support) to discuss your requirements and potential alternative solutions. * * @link https://seek-oss.github.io/sku/configuration#dangerouslysetvitestconfig */ dangerouslySetVitestConfig?: (config: TestUserConfig) => TestUserConfig; /** * Path to a file in your project that exports a function that can receive the Express server. * This can be used to extend to the dev server middleware. * * @link https://seek-oss.github.io/sku/configuration#devservermiddleware */ devServerMiddleware?: string; /** * Adds static `displayName` properties to React components in production. * This setting is designed for usage on sites that generate React code snippets, e.g. Braid. * * @default false * @link https://seek-oss.github.io/sku/configuration#displaynamesprod */ displayNamesProd?: boolean; /** * **Only for static apps** * * An array of environments the app supports. * Apps should have one environment for local development plus one for each environment they’re deployed to. * * @default [] * @link https://seek-oss.github.io/sku/configuration#environments */ environments?: readonly string[]; /** * Paths and files to be ignored by ESLint. * See [the ESLint documentation](https://eslint.org/docs/latest/use/configure/ignore#ignoring-files) for more information. * * @default [] * @link https://seek-oss.github.io/sku/configuration#eslintIgnore */ eslintIgnore?: readonly string[]; /** * By default, sku compiles all node_modules in builds that target node. * Setting this option to `true` will instead externalize all node_modules, excluding `compilePackages`. * * @default false * @link https://seek-oss.github.io/sku/configuration#externalizenodemodules */ externalizeNodeModules?: boolean; /** * An array of custom hosts the app can be served off when running `sku start`. * You must have configured your hosts file to point to localhost as well. * * @default ['localhost'] * @link https://seek-oss.github.io/sku/configuration#hosts */ hosts?: readonly string[]; /** * Whether or not to use https for the local development server with a self-signed certificate. * This is useful when testing authentication flows that require access to `window.crypto`. * * @default false * @link https://seek-oss.github.io/sku/configuration#httpsdevserver */ httpsDevServer?: boolean; /** * The browser URL to open when running `sku start` or `sku start-ssr`. * It will default to the first `route` in the {@link routes} array. * * @default routes[0].route * @link https://seek-oss.github.io/sku/configuration#initialpath */ initialPath?: string; /** * The languages your application supports. * * @link https://seek-oss.github.io/sku/configuration#languages */ languages?: readonly SkuLanguage[]; /** * **Only for libraries** * * The entry file for the library. If set, sku will assume the project is a library. Must export its API from this file. * * @link https://seek-oss.github.io/sku/configuration#libraryentry */ libraryEntry?: string; /** * **Only for libraries** * * The global name of the library. Will be added to the `window` object under `window[libraryName]`. * * @link https://seek-oss.github.io/sku/configuration#libraryname */ libraryName?: string; /** * **Only for libraries** * * The file name of the library. The main bundle of the library will be output to `dist/${libraryFile}.js` - note that the * `.js` extension will be added automatically and should not be included in the configuration option itself. * * If `libraryFile` is not specified then `libraryName` will be used instead. * * @link https://seek-oss.github.io/sku/configuration#libraryfile */ libraryFile?: string; /** * An array of polyfills to be included into all client entry points. * * @default [] * @link https://seek-oss.github.io/sku/configuration#polyfills */ polyfills?: string[]; /** * The port the app is hosted on when running `sku start`. * * For SSR (`buildType: 'ssr'`), this is also the baked production default * listen port (`__SKU_DEFAULT_SERVER_PORT__`), overridable via `process.env.PORT`. * * @default 8080 * @link https://seek-oss.github.io/sku/configuration#port */ port?: number; /** * A folder of public assets to be copied into the `target` directory after `sku build` or `sku build-ssr`. * * Not supported for SSR (`buildType: 'ssr'`): if this directory exists on disk, * `sku start` / `sku build` fail. Import assets from modules instead. * * @default 'public' * @link https://seek-oss.github.io/sku/configuration#public */ public?: string; /** * The URL all the static assets of the app are accessible under. * * @default '/' * @link https://seek-oss.github.io/sku/configuration#publicpath */ publicPath?: string; /** * **Only for static apps and libraries** * * The render entry file to the app. This file should export the required functions for static rendering. * * @default "./src/render.js" * @link https://seek-oss.github.io/sku/configuration#renderentry */ renderEntry?: string; /** * **Only for static apps** * * An array of routes for the app. Each route must specify a name and a route corresponding to the path it is hosted under. Each route may also have a custom client entry, which can help with bundle splitting. See static-rendering for more info. * * Can be used to limit the languages rendered for a specific route. Any listed language must exist in the top level languages attribute. * * @default ['/'] * @link https://seek-oss.github.io/sku/configuration#routes */ routes?: readonly SkuRoute[]; /** * **Only for SSR apps** * * The entry file for the server. * * @default "./src/server.tsx" * @link https://seek-oss.github.io/sku/configuration#serverentry */ serverEntry?: string; /** * Point to a JS file that will run before your tests to setup the testing environment. * * @link https://seek-oss.github.io/sku/configuration#setuptests */ setupTests?: string | string[]; /** * An array of sites the app supports. These usually correspond to each domain the app is hosted under. * * **SSR:** optional. Empty or omitted soft-defaults to a single synthetic site name `'default'`. * Sku pre-builds a route tree per resolved site name from * [`routesEntry`](https://seek-oss.github.io/sku/configuration#routesentry); apps select via `getSite` * (required when >1 site; sole resolved name when omitted on 0–1 site). * `sites[].host` remains local-dev listen / setup-hosts only. * * @default [] * @link https://seek-oss.github.io/sku/configuration#sites */ sites?: readonly SkuSite[]; /** * When running `sku build`, sku will compile all your external packages (`node_modules`) through `@babel/preset-env`. * This is to ensure external packages satisfy the browser support policy. * However, this can cause very slow builds when large packages are processed. * * The `skipPackageCompatibilityCompilation` option allows you to pass a list of trusted packages to skip this behaviour. * * @default [] * @link https://seek-oss.github.io/sku/configuration#skippackagecompatibilitycompilation */ skipPackageCompatibilityCompilation?: string[]; /** * Source maps are always generated for development builds. * To disable source maps for production builds, set this option to `false`. * * @default true * @link https://seek-oss.github.io/sku/configuration#sourcemapsprod */ sourceMapsProd?: boolean; /** * The `browserslist` query describing the apps browser support policy. * * @default browserslist-config-seek * @link https://seek-oss.github.io/sku/configuration#supportedbrowsers */ supportedBrowsers?: string[]; /** * The directory to build your assets into when running `sku build` or `sku build-ssr`. * * @default 'dist' * @link https://seek-oss.github.io/sku/configuration#target */ target?: string; /** * **Only for static apps** * * This function returns the output path within {@link target} for each rendered page. Generally, this value should be sufficient. * * If you think you need to modify this setting, please reach out via the [support page](https://seek-oss.github.io/sku/support) first to discuss. * * @link https://seek-oss.github.io/sku/configuration#transformoutputpath */ transformOutputPath?: TransformOutputPathFunction; /** * Path alias mappings for module resolution. * Each alias maps a pattern to a destination path relative to the project root. * * This option generates `tsconfig.json#paths` so TypeScript can resolve these imports, and `sku` * mirrors it into your `package.json#imports` field so the aliases resolve natively at build time. * * Subpath import specifiers must be prefixed with `#`. * * Example `sku.config.ts`: `{ "#components/*": "./src/components/*" }` * * @default {} * @see https://www.typescriptlang.org/docs/handbook/modules/reference.html#paths * @see https://nodejs.org/api/packages.html#subpath-imports */ pathAliases?: Record; } interface WebpackSkuConfig { /** * **Webpack SSR only** (`sku start-ssr` / `sku build-ssr`) * * The port the server is hosted on when running `sku start-ssr`, and the * default listen port for the webpack production server. * * Not valid for SSR (`buildType: 'ssr'`) — use {@link SkuConfigBase.port}. * * @default 8181 * @link https://seek-oss.github.io/sku/configuration#serverport */ serverPort?: number; /** * An array of directories holding your apps source code. * By default, sku expects your source code to be in a directory named `src` in the root of your project. * * Use this option if your source code needs to be arranged differently. * * @default ['./src'] * @link https://seek-oss.github.io/sku/configuration#srcpaths */ srcPaths?: string[]; /** * This function provides a way to modify sku's Webpack configuration. * It should only be used in exceptional circumstances where a solution cannot be achieved by adjusting standard configuration options. * * Before customizing your Webpack configuration, please reach out via the [support page](https://seek-oss.github.io/sku/support) to discuss your requirements and potential alternative solutions. * * As sku creates two webpack configs (`client` & `server|render`), this function will actually run twice. * If you only need to modify one of these configs, then you can check `config.name` within. * * Sku provides no guarantees that its Webpack configuration will remain compatible with any customizations made within this function. * It is the responsibility of the user to ensure that their customizations are compatible with sku. * * @link https://seek-oss.github.io/sku/configuration#dangerouslysetwebpackconfig */ dangerouslySetWebpackConfig?: (skuWebpackConfig: any) => any; } interface ViteSkuConfig { /** * **Only for Managed Data Mode** * * Module that exports named `routes` (`SkuRouteObject[]`) for both * the server and client graphs. Optional `sites` on routes declares * multi-site membership; apps select the tree via `getSite` (required when * config has more than one site; sole config site when omitted on single-site). * Optional named `mapRoutePath` maps one logical path (including index * homes via `path: ''`) to concrete paths while sku pre-builds each site tree. * * @default "./src/routes.tsx" * @link https://seek-oss.github.io/sku/configuration#routesentry */ routesEntry?: string; /** * An array of cjs import paths that have both a default and named exports. * This is used to enable CommonJS interop for these dependencies when using the `vite` bundler. * See https://github.com/cyco130/vite-plugin-cjs-interop for more information. * This is an experimental option that may change or be removed without notice. * * Note: This option is only relevant when using the `vite` bundler. * * @default: [] */ __UNSAFE_EXPERIMENTAL__cjsInteropDependencies?: string[]; /** * Provides a way to add additional Vite plugins to the Vite config. * * Note: This option is only relevant when using the `vite` bundler. * * Not supported for SSR (`buildType: 'ssr'`): providing this option fails config validation. * Raise exceptional customisation needs via the [support page](https://seek-oss.github.io/sku/support) with your use-case. * * @default: [] */ vitePlugins?: PluginOption[]; /** * **SSR only** (`buildType: 'ssr'`) * * When `true`, sku sets Express `app.set('trust proxy', 1)` (hop count `1`) * before listen — the common single reverse-proxy case. * Omit or `false` leaves Express’s default (`false`). * Other trust-proxy values (`false`, `2`, IP lists, …) override in server-entry * [`onListen`](https://seek-oss.github.io/sku/ssr/entries#onlisten). * * @default false * @link https://seek-oss.github.io/sku/configuration#expresstrustproxy */ expressTrustProxy?: boolean; /** * The way the enforcing content security policy is delivered for **static Vite** apps. * Only relevant if {@link SkuConfigBase#cspEnabled} is set to `true`. * Ignored for SSR (`buildType: 'ssr'`), which always uses HTTP CSP headers. * * @default 'tag' * @link https://seek-oss.github.io/sku/configuration#cspdelivery */ cspDelivery?: 'tag' | 'header'; /** * Where to report content security policy violations. Only relevant if {@link SkuConfigBase#cspEnabled} is set to `true` and {@link cspDelivery} is set to `'header'`. * For SSR (`buildType: 'ssr'`) {@link cspDelivery} is ignored, so this applies whenever {@link SkuConfigBase#cspEnabled} is `true`. * * @link https://seek-oss.github.io/sku/docs/configuration#cspreportto */ cspReportTo?: string | [string, string]; /** * **Unavailable for libraries** * * Enable report-only content security policy feature. More info at https://seek-oss.github.io/sku/csp * * @default false * @link https://seek-oss.github.io/sku/configuration#cspreportonlyenabled */ cspReportOnlyEnabled?: boolean; /** * Extra external hosts to allow in your `script-src` report-only content security policy. Only relevant if {@link cspReportOnlyEnabled} is set to `true`. * * @default {@link SkuConfigBase#cspExtraScriptSrcHosts} * @link https://seek-oss.github.io/sku/configuration#cspreportonlyextrascriptsrchosts */ cspReportOnlyExtraScriptSrcHosts?: string[]; /** * Where to report report-only content security policy violations. Only relevant if {@link cspReportOnlyEnabled} is set to `true`. * * @default {@link cspReportTo} * @link https://seek-oss.github.io/sku/docs/configuration#cspreportonlyreportto */ cspReportOnlyReportTo?: string | [string, string]; /** * This function provides a way to modify sku's Vite configuration. * It should only be used in exceptional circumstances where a solution cannot be achieved by adjusting standard configuration options. * * Not supported for SSR (`buildType: 'ssr'`): providing this option fails config validation. * Raise exceptional customisation needs via the [support page](https://seek-oss.github.io/sku/support) with your use-case. * * Before customizing your Vite configuration, please reach out via the [support page](https://seek-oss.github.io/sku/support) to discuss your requirements and potential alternative solutions. * * As sku creates two Vite configs (`client` & `render`), this function will actually run twice. * If you only need to modify one of these configs, then you can check `env.mode` from the second argument within. * * This function can return a partial config object that will be deeply merged into existing config (recommended), or directly mutate the config (if the default merging cannot achieve the desired result). * * Sku provides no guarantees that its Vite configuration will remain compatible with any customizations made within this function. * It is the responsibility of the user to ensure that their customizations are compatible with sku. * * @link https://seek-oss.github.io/sku/configuration#dangerouslysetviteconfig */ dangerouslySetViteConfig?: Plugin['config']; } type SkuConfig = SkuConfigBase & (({ bundler?: 'webpack' | undefined; } & WebpackSkuConfig) | ({ bundler: 'vite'; } & ViteSkuConfig)); //#endregion export { Render, RenderAppProps, RenderCallbackParams, RenderableRoute, Server, SkuConfig, SkuConfigBase, SkuLanguage, SkuProvider, SkuRoute, SkuRouteObject, SkuSiteObject, TransformOutputPathFunctionParams, ViteRenderFunction, ViteSkuConfig, WebpackSkuConfig };