web: Fix issues surrounding Vite/ESBuild types.
This commit is contained in:
		
				
					committed by
					
						
						Teffen Ellis
					
				
			
			
				
	
			
			
			
						parent
						
							92629578dd
						
					
				
				
					commit
					e8b1f82c3e
				
			@ -3,13 +3,11 @@
 | 
			
		||||
 * @import { StorybookConfig } from "@storybook/web-components-vite";
 | 
			
		||||
 * @import { InlineConfig, Plugin } from "vite";
 | 
			
		||||
 */
 | 
			
		||||
import { cwd } from "process";
 | 
			
		||||
import { createBundleDefinitions } from "@goauthentik/web/scripts/esbuild/environment";
 | 
			
		||||
import postcssLit from "rollup-plugin-postcss-lit";
 | 
			
		||||
import tsconfigPaths from "vite-tsconfig-paths";
 | 
			
		||||
 | 
			
		||||
const NODE_ENV = process.env.NODE_ENV || "development";
 | 
			
		||||
 | 
			
		||||
const CSSImportPattern = /import [\w\$]+ from .+\.(css)/g;
 | 
			
		||||
const CSSImportPattern = /import [\w$]+ from .+\.(css)/g;
 | 
			
		||||
const JavaScriptFilePattern = /\.m?(js|ts|tsx)$/;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -54,11 +52,7 @@ const config = {
 | 
			
		||||
         */
 | 
			
		||||
        const mergedConfig = {
 | 
			
		||||
            ...config,
 | 
			
		||||
            define: {
 | 
			
		||||
                "process.env.NODE_ENV": JSON.stringify(NODE_ENV),
 | 
			
		||||
                "process.env.CWD": JSON.stringify(cwd()),
 | 
			
		||||
                "process.env.AK_API_BASE_PATH": JSON.stringify(process.env.AK_API_BASE_PATH || ""),
 | 
			
		||||
            },
 | 
			
		||||
            define: createBundleDefinitions(),
 | 
			
		||||
            plugins: [inlineCSSPlugin, ...plugins, postcssLit(), tsconfigPaths()],
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ const log = console.debug.bind(console, logPrefix);
 | 
			
		||||
 * ESBuild may tree-shake it out of production builds.
 | 
			
		||||
 *
 | 
			
		||||
 * ```ts
 | 
			
		||||
 * if (process.env.NODE_ENV === "development") {
 | 
			
		||||
 * if (import.meta.env.NODE_ENV=== "development") {
 | 
			
		||||
 *   await import("@goauthentik/esbuild-plugin-live-reload/client")
 | 
			
		||||
 *     .catch(() => console.warn("Failed to import watcher"))
 | 
			
		||||
 * }
 | 
			
		||||
 | 
			
		||||
@ -4,15 +4,20 @@
 | 
			
		||||
 | 
			
		||||
export {};
 | 
			
		||||
declare global {
 | 
			
		||||
    /**
 | 
			
		||||
     * Environment variables injected by ESBuild.
 | 
			
		||||
     */
 | 
			
		||||
    interface ImportMetaEnv {
 | 
			
		||||
        /**
 | 
			
		||||
         * The injected watcher URL for ESBuild.
 | 
			
		||||
         * This is used for live reloading in development mode.
 | 
			
		||||
         *
 | 
			
		||||
         * @format url
 | 
			
		||||
         */
 | 
			
		||||
        readonly ESBUILD_WATCHER_URL?: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interface ImportMeta {
 | 
			
		||||
        readonly env: {
 | 
			
		||||
            /**
 | 
			
		||||
             * The injected watcher URL for ESBuild.
 | 
			
		||||
             * This is used for live reloading in development mode.
 | 
			
		||||
             *
 | 
			
		||||
             * @format url
 | 
			
		||||
             */
 | 
			
		||||
            ESBUILD_WATCHER_URL: string;
 | 
			
		||||
        };
 | 
			
		||||
        readonly env: ImportMetaEnv;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file Constants for JavaScript and TypeScript files.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/// <reference types="../../types/global.js" />
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The current Node.js environment, defaulting to "development" when not set.
 | 
			
		||||
 *
 | 
			
		||||
 * Note, this should only be used during the build process.
 | 
			
		||||
 *
 | 
			
		||||
 * If you need to check the environment at runtime, use `process.env.NODE_ENV` to
 | 
			
		||||
 * ensure that module tree-shaking works correctly.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
export const NodeEnvironment = process.env.NODE_ENV || "development";
 | 
			
		||||
@ -1,6 +1,20 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file Utility functions for building and copying files.
 | 
			
		||||
 * @file Utility functions for working with environment variables.
 | 
			
		||||
 */
 | 
			
		||||
/// <reference types="./types/global.js" />
 | 
			
		||||
 | 
			
		||||
//#region Constants
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The current Node.js environment, defaulting to "development" when not set.
 | 
			
		||||
 *
 | 
			
		||||
 * Note, this should only be used during the build process.
 | 
			
		||||
 *
 | 
			
		||||
 * If you need to check the environment at runtime, use `process.env.NODE_ENV` to
 | 
			
		||||
 * ensure that module tree-shaking works correctly.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
export const NodeEnvironment = process.env.NODE_ENV || "development";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A source environment variable, which can be a string, number, boolean, null, or undefined.
 | 
			
		||||
@ -14,19 +28,26 @@
 | 
			
		||||
 * @typedef {T extends string ? `"${T}"` : T} JSONify
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//#endregion
 | 
			
		||||
 | 
			
		||||
//#region Utilities
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Given an object of environment variables, returns a new object with the same keys and values, but
 | 
			
		||||
 * with the values serialized as strings.
 | 
			
		||||
 *
 | 
			
		||||
 * @template {Record<string, EnvironmentVariable>} EnvRecord
 | 
			
		||||
 * @template {string} [Prefix='process.env.']
 | 
			
		||||
 * @template {string} [Prefix='import.meta.env.']
 | 
			
		||||
 *
 | 
			
		||||
 * @param {EnvRecord} input
 | 
			
		||||
 * @param {Prefix} [prefix='process.env.']
 | 
			
		||||
 * @param {Prefix} [prefix='import.meta.env.']
 | 
			
		||||
 *
 | 
			
		||||
 * @returns {{[K in keyof EnvRecord as `${Prefix}${K}`]: JSONify<EnvRecord[K]>}}
 | 
			
		||||
 */
 | 
			
		||||
export function serializeEnvironmentVars(input, prefix = /** @type {Prefix} */ ("process.env.")) {
 | 
			
		||||
export function serializeEnvironmentVars(
 | 
			
		||||
    input,
 | 
			
		||||
    prefix = /** @type {Prefix} */ ("import.meta.env."),
 | 
			
		||||
) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {Record<string, string>}
 | 
			
		||||
     */
 | 
			
		||||
@ -40,3 +61,5 @@ export function serializeEnvironmentVars(input, prefix = /** @type {Prefix} */ (
 | 
			
		||||
 | 
			
		||||
    return /** @type {any} */ (env);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//#endregion
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
/// <reference types="./types/global.js" />
 | 
			
		||||
 | 
			
		||||
export * from "./paths.js";
 | 
			
		||||
export * from "./constants.js";
 | 
			
		||||
export * from "./build.js";
 | 
			
		||||
export * from "./environment.js";
 | 
			
		||||
export * from "./version.js";
 | 
			
		||||
export * from "./scripting.js";
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
/// <reference types="../types/esbuild.js" />
 | 
			
		||||
/**
 | 
			
		||||
 * @file ESBuild script for building the authentik web UI.
 | 
			
		||||
 *
 | 
			
		||||
@ -9,7 +10,6 @@ import {
 | 
			
		||||
    NodeEnvironment,
 | 
			
		||||
    readBuildIdentifier,
 | 
			
		||||
    resolvePackage,
 | 
			
		||||
    serializeEnvironmentVars,
 | 
			
		||||
} from "@goauthentik/monorepo";
 | 
			
		||||
import { DistDirectory, DistDirectoryName, EntryPoint, PackageRoot } from "@goauthentik/web/paths";
 | 
			
		||||
import { deepmerge } from "deepmerge-ts";
 | 
			
		||||
@ -20,15 +20,10 @@ import * as fs from "node:fs/promises";
 | 
			
		||||
import * as path from "node:path";
 | 
			
		||||
 | 
			
		||||
import { mdxPlugin } from "./esbuild/build-mdx-plugin.mjs";
 | 
			
		||||
import { createBundleDefinitions } from "./esbuild/environment.mjs";
 | 
			
		||||
 | 
			
		||||
const logPrefix = "[Build]";
 | 
			
		||||
 | 
			
		||||
const definitions = serializeEnvironmentVars({
 | 
			
		||||
    NODE_ENV: NodeEnvironment,
 | 
			
		||||
    CWD: process.cwd(),
 | 
			
		||||
    AK_API_BASE_PATH: process.env.AK_API_BASE_PATH,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const patternflyPath = resolvePackage("@patternfly/patternfly");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -86,7 +81,7 @@ const BASE_ESBUILD_OPTIONS = {
 | 
			
		||||
            root: MonoRepoRoot,
 | 
			
		||||
        }),
 | 
			
		||||
    ],
 | 
			
		||||
    define: definitions,
 | 
			
		||||
    define: createBundleDefinitions(),
 | 
			
		||||
    format: "esm",
 | 
			
		||||
    logOverride: {
 | 
			
		||||
        /**
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								web/scripts/esbuild/environment.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								web/scripts/esbuild/environment.mjs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file ESBuild environment utilities.
 | 
			
		||||
 */
 | 
			
		||||
import { AuthentikVersion, NodeEnvironment, serializeEnvironmentVars } from "@goauthentik/monorepo";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a mapping of environment variables to their respective runtime constants.
 | 
			
		||||
 */
 | 
			
		||||
export function createBundleDefinitions() {
 | 
			
		||||
    const SerializedNodeEnvironment = /** @type {`"development"` | `"production"`} */ (
 | 
			
		||||
        JSON.stringify(NodeEnvironment)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @satisfies {Record<ESBuildImportEnvKey, string>}
 | 
			
		||||
     */
 | 
			
		||||
    const envRecord = {
 | 
			
		||||
        AK_VERSION: AuthentikVersion,
 | 
			
		||||
        AK_API_BASE_PATH: process.env.AK_API_BASE_PATH ?? "",
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        ...serializeEnvironmentVars(envRecord),
 | 
			
		||||
        // We need to explicitly set this for NPM packages that use `process`
 | 
			
		||||
        // to determine their environment.
 | 
			
		||||
        "process.env.NODE_ENV": SerializedNodeEnvironment,
 | 
			
		||||
        "import.meta.env.NODE_ENV": SerializedNodeEnvironment,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@ -43,7 +43,7 @@ import {
 | 
			
		||||
    renderSidebarItems,
 | 
			
		||||
} from "./AdminSidebar.js";
 | 
			
		||||
 | 
			
		||||
if (process.env.NODE_ENV === "development") {
 | 
			
		||||
if (import.meta.env.NODE_ENV === "development") {
 | 
			
		||||
    await import("@goauthentik/esbuild-plugin-live-reload/client");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -223,7 +223,7 @@ export function inspectStyleSheetTree(element: ReactiveElement): InspectedStyleS
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (process.env.NODE_ENV === "development") {
 | 
			
		||||
if (import.meta.env.NODE_ENV === "development") {
 | 
			
		||||
    Object.assign(window, {
 | 
			
		||||
        inspectStyleSheetTree,
 | 
			
		||||
        serializeStyleSheet,
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,6 @@ import "@goauthentik/flow/stages/password/PasswordStage";
 | 
			
		||||
 | 
			
		||||
// end of stage import
 | 
			
		||||
 | 
			
		||||
if (process.env.NODE_ENV === "development") {
 | 
			
		||||
if (import.meta.env.NODE_ENV === "development") {
 | 
			
		||||
    await import("@goauthentik/esbuild-plugin-live-reload/client");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";
 | 
			
		||||
 | 
			
		||||
import { CurrentBrand, EventsApi, SessionUser } from "@goauthentik/api";
 | 
			
		||||
 | 
			
		||||
if (process.env.NODE_ENV === "development") {
 | 
			
		||||
if (import.meta.env.NODE_ENV === "development") {
 | 
			
		||||
    await import("@goauthentik/esbuild-plugin-live-reload/client");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								web/types/esbuild.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								web/types/esbuild.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file Import meta environment variables available via ESBuild.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export {};
 | 
			
		||||
declare global {
 | 
			
		||||
    interface ESBuildImportEnv {
 | 
			
		||||
        /**
 | 
			
		||||
         * The authentik version injected by ESBuild during build time.
 | 
			
		||||
         *
 | 
			
		||||
         * @format semver
 | 
			
		||||
         */
 | 
			
		||||
        readonly AK_VERSION: string;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @todo Determine where this is used and if it is needed,
 | 
			
		||||
         * give it a better name.
 | 
			
		||||
         * @deprecated
 | 
			
		||||
         */
 | 
			
		||||
        readonly AK_API_BASE_PATH: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type ESBuildImportEnvKey = keyof ESBuildImportEnv;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Environment variables injected by ESBuild.
 | 
			
		||||
     */
 | 
			
		||||
    interface ImportMetaEnv extends ESBuildImportEnv {
 | 
			
		||||
        /**
 | 
			
		||||
         * An environment variable used to determine
 | 
			
		||||
         * whether Node.js is running in production mode.
 | 
			
		||||
         */
 | 
			
		||||
        readonly NODE_ENV: "development" | "production";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interface ImportMeta {
 | 
			
		||||
        readonly env: ImportMetaEnv;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								web/types/global.d.ts → web/types/node.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								web/types/global.d.ts → web/types/node.d.ts
									
									
									
									
										vendored
									
									
								
							@ -1,5 +1,5 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file Environment variables available via ESBuild.
 | 
			
		||||
 * @file Global variables provided by Node.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
declare module "module" {
 | 
			
		||||
@ -14,8 +14,8 @@ declare module "module" {
 | 
			
		||||
         * const relativeDirname = dirname(fileURLToPath(import.meta.url));
 | 
			
		||||
         * ```
 | 
			
		||||
         */
 | 
			
		||||
        // eslint-disable-next-line no-var
 | 
			
		||||
        var __dirname: string;
 | 
			
		||||
 | 
			
		||||
        const __dirname: string;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,13 +23,16 @@ declare module "process" {
 | 
			
		||||
    global {
 | 
			
		||||
        namespace NodeJS {
 | 
			
		||||
            interface ProcessEnv {
 | 
			
		||||
                CWD: string;
 | 
			
		||||
                /**
 | 
			
		||||
                 * Node environment, if any.
 | 
			
		||||
                 */
 | 
			
		||||
                readonly NODE_ENV?: "development" | "production";
 | 
			
		||||
                /**
 | 
			
		||||
                 * @todo Determine where this is used and if it is needed,
 | 
			
		||||
                 * give it a better name.
 | 
			
		||||
                 * @deprecated
 | 
			
		||||
                 */
 | 
			
		||||
                AK_API_BASE_PATH: string;
 | 
			
		||||
                readonly AK_API_BASE_PATH?: string;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -1,17 +1,15 @@
 | 
			
		||||
import replace from "@rollup/plugin-replace";
 | 
			
		||||
/// <reference types="@wdio/browser-runner" />
 | 
			
		||||
import { browser } from "@wdio/globals";
 | 
			
		||||
import type { Options } from "@wdio/types";
 | 
			
		||||
import path from "path";
 | 
			
		||||
import { cwd } from "process";
 | 
			
		||||
import { fileURLToPath } from "url";
 | 
			
		||||
import type { UserConfig } from "vite";
 | 
			
		||||
import litCss from "vite-plugin-lit-css";
 | 
			
		||||
import path from "node:path";
 | 
			
		||||
import { fileURLToPath } from "node:url";
 | 
			
		||||
import { createBundleDefinitions } from "scripts/esbuild/environment.mjs";
 | 
			
		||||
import type { InlineConfig } from "vite";
 | 
			
		||||
import litCSS from "vite-plugin-lit-css";
 | 
			
		||||
import tsconfigPaths from "vite-tsconfig-paths";
 | 
			
		||||
 | 
			
		||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
 | 
			
		||||
 | 
			
		||||
const isProdBuild = process.env.NODE_ENV === "production";
 | 
			
		||||
const apiBasePath = process.env.AK_API_BASE_PATH || "";
 | 
			
		||||
const runHeadless = process.env.CI !== undefined;
 | 
			
		||||
 | 
			
		||||
const testSafari = process.env.WDIO_TEST_SAFARI !== undefined;
 | 
			
		||||
@ -72,21 +70,9 @@ export const config: Options.Testrunner = {
 | 
			
		||||
    runner: [
 | 
			
		||||
        "browser",
 | 
			
		||||
        {
 | 
			
		||||
            viteConfig: (userConfig: UserConfig = { plugins: [] }) => ({
 | 
			
		||||
                ...userConfig,
 | 
			
		||||
                plugins: [
 | 
			
		||||
                    litCss(),
 | 
			
		||||
                    replace({
 | 
			
		||||
                        "process.env.NODE_ENV": JSON.stringify(
 | 
			
		||||
                            isProdBuild ? "production" : "development",
 | 
			
		||||
                        ),
 | 
			
		||||
                        "process.env.CWD": JSON.stringify(cwd()),
 | 
			
		||||
                        "process.env.AK_API_BASE_PATH": JSON.stringify(apiBasePath),
 | 
			
		||||
                        "preventAssignment": true,
 | 
			
		||||
                    }),
 | 
			
		||||
                    ...(userConfig?.plugins ?? []),
 | 
			
		||||
                    tsconfigPaths(),
 | 
			
		||||
                ],
 | 
			
		||||
            viteConfig: {
 | 
			
		||||
                define: createBundleDefinitions(),
 | 
			
		||||
                plugins: [litCSS(), tsconfigPaths()],
 | 
			
		||||
                resolve: {
 | 
			
		||||
                    alias: {
 | 
			
		||||
                        "@goauthentik/admin": path.resolve(__dirname, "src/admin"),
 | 
			
		||||
@ -101,7 +87,7 @@ export const config: Options.Testrunner = {
 | 
			
		||||
                        "@goauthentik/user": path.resolve(__dirname, "src/user"),
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            }),
 | 
			
		||||
            } satisfies InlineConfig,
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user