web/NPM Workspaces: ESbuild version cleanup (#14541)
* web: Check JS files. Add types. * web: Fix issues surrounding Vite/ESBuild types. * web: Clean up version constants. Tidy types * web: Clean up docs, types. * web: Clean up package paths. * web: (ESLint) no-lonely-if * web: Render slot before navbar. * web: Fix line-height alignment. * web: Truncate long headers. * web: Clean up page header declarations. Add story. Update paths. * web: Ignore out directory. * web: Lint Lit. * web: Use private alias. * web: Fix implicit CJS mode. * web: Update deps. * web: await all imports.
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
# `@goauthentik/monorepo`
|
||||
# `@goauthentik/core`
|
||||
|
||||
This package contains utility scripts common to all TypeScript and JavaScript packages in the
|
||||
`@goauthentik` monorepo.
|
66
web/packages/core/environment/node.js
Normal file
66
web/packages/core/environment/node.js
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file Utility functions for working with environment variables.
|
||||
*/
|
||||
/// <reference types="../types/node.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.
|
||||
*
|
||||
* @category Environment
|
||||
* @runtime node
|
||||
*/
|
||||
export const NodeEnvironment = process.env.NODE_ENV || "development";
|
||||
|
||||
/**
|
||||
* A source environment variable, which can be a string, number, boolean, null, or undefined.
|
||||
* @typedef {string | number | boolean | null | undefined} EnvironmentVariable
|
||||
*/
|
||||
|
||||
/**
|
||||
* A type helper for serializing environment variables.
|
||||
*
|
||||
* @category Environment
|
||||
* @template {EnvironmentVariable} T
|
||||
* @typedef {T extends string ? `"${T}"` : T} JSONify
|
||||
*/
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Utilities
|
||||
|
||||
/**
|
||||
* Given an object of environment variables, serializes them into a mapping of
|
||||
* environment variable names to their respective runtime constants.
|
||||
*
|
||||
* This is useful for defining environment variables while bundling with ESBuild, Vite, etc.
|
||||
*
|
||||
* @category Environment
|
||||
* @runtime node
|
||||
*
|
||||
* @template {Record<string, EnvironmentVariable>} EnvRecord
|
||||
* @template {string} [Prefix='import.meta.env.']
|
||||
*
|
||||
* @param {EnvRecord} input
|
||||
* @param {Prefix} [prefix='import.meta.env.']
|
||||
*
|
||||
* @returns {{[K in keyof EnvRecord as `${Prefix}${K}`]: JSONify<EnvRecord[K]>}}
|
||||
*/
|
||||
export function serializeEnvironmentVars(
|
||||
input,
|
||||
prefix = /** @type {Prefix} */ ("import.meta.env."),
|
||||
) {
|
||||
const env = Object.fromEntries(
|
||||
Object.entries(input).map(([key, value]) => [prefix + key, JSON.stringify(value ?? "")]),
|
||||
);
|
||||
|
||||
return /** @type {any} */ (env);
|
||||
}
|
||||
|
||||
//#endregion
|
12
web/packages/core/index.js
Normal file
12
web/packages/core/index.js
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @file Dummy entry point for the `core` package.
|
||||
*
|
||||
* This exists to make TypeScript's module resolution more predictable.
|
||||
*
|
||||
* @internal
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
export {};
|
||||
|
||||
export default {};
|
59
web/packages/core/package.json
Normal file
59
web/packages/core/package.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "@goauthentik/core",
|
||||
"version": "1.0.0",
|
||||
"description": "Core functionality for the authentik monorepo",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsc -p .",
|
||||
"prettier": "prettier --write .",
|
||||
"prettier-check": "prettier --check ."
|
||||
},
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
"./*/browser": {
|
||||
"types": "./out/*/browser.d.ts",
|
||||
"import": "./*/browser.js"
|
||||
},
|
||||
"./*/node": {
|
||||
"types": "./out/*/node.d.ts",
|
||||
"import": "./*/node.js"
|
||||
},
|
||||
"./*": {
|
||||
"types": "./out/*/index.d.ts",
|
||||
"import": "./*/index.js"
|
||||
},
|
||||
".": {
|
||||
"import": "./index.js",
|
||||
"types": "./out/index.d.ts"
|
||||
}
|
||||
},
|
||||
"imports": {
|
||||
"#*/browser": {
|
||||
"types": "./out/*/browser.d.ts",
|
||||
"import": "./*/browser.js"
|
||||
},
|
||||
"#*/node": {
|
||||
"types": "./out/*/node.d.ts",
|
||||
"import": "./*/node.js"
|
||||
},
|
||||
"#*": {
|
||||
"types": "./out/*/index.d.ts",
|
||||
"import": "./*/index.js"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@goauthentik/prettier-config": "^1.0.4",
|
||||
"@goauthentik/tsconfig": "^1.0.4",
|
||||
"@types/node": "^22.14.1",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "^5.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.11"
|
||||
},
|
||||
"types": "./out/index.d.ts",
|
||||
"prettier": "@goauthentik/prettier-config"
|
||||
}
|
@ -10,22 +10,26 @@ const relativeDirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
/**
|
||||
* The root of the authentik monorepo.
|
||||
*
|
||||
* @runtime node
|
||||
*/
|
||||
// TODO: Revise when this package is moved to the monorepo's `packages/monorepo` directory.
|
||||
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (
|
||||
resolve(relativeDirname, "..", "..", "..")
|
||||
resolve(relativeDirname, "..", "..", "..", "..")
|
||||
);
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
/**
|
||||
* Resolve a package name to its location in the monorepo to the single node_modules directory.
|
||||
* @param {string} packageName
|
||||
*
|
||||
* @param {string} packageName
|
||||
* @param {ImportMeta} [meta] The `import.meta` object of the module.
|
||||
*
|
||||
* @runtime node
|
||||
* @returns {string} The resolved path to the package.
|
||||
* @throws {Error} If the package cannot be resolved.
|
||||
*/
|
||||
export function resolvePackage(packageName) {
|
||||
export function resolvePackage(packageName, meta) {
|
||||
const require = createRequire(meta ? meta.url : import.meta.url);
|
||||
|
||||
const relativePackageJSONPath = join(packageName, "package.json");
|
||||
|
||||
/** @type {string} */
|
||||
@ -34,7 +38,7 @@ export function resolvePackage(packageName) {
|
||||
try {
|
||||
absolutePackageJSONPath = require.resolve(relativePackageJSONPath);
|
||||
} catch (cause) {
|
||||
const error = new Error(`Failed to resolve package "${packageName}"`);
|
||||
const error = new Error(`🚫 Failed to resolve package "${packageName}"`);
|
||||
|
||||
error.cause = cause;
|
||||
|
@ -9,6 +9,7 @@ import { fileURLToPath } from "node:url";
|
||||
* @param {ImportMeta} meta The `import.meta` object of the module.
|
||||
*
|
||||
* @return {boolean} Whether the module was run directly.
|
||||
* @runtime node
|
||||
*/
|
||||
export function isMain(meta) {
|
||||
// Are we not in a module context?
|
@ -1,9 +1,11 @@
|
||||
{
|
||||
"extends": "@goauthentik/tsconfig",
|
||||
"compilerOptions": {
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": ".",
|
||||
"checkJs": true,
|
||||
"allowJs": true,
|
||||
"emitDeclarationOnly": true
|
||||
}
|
||||
}
|
54
web/packages/core/types/node.d.ts
vendored
Normal file
54
web/packages/core/types/node.d.ts
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file Global variables provided by Node.js
|
||||
*/
|
||||
|
||||
declare module "module" {
|
||||
global {
|
||||
/**
|
||||
* @deprecated This is not present in ESM files.
|
||||
*
|
||||
* ```js
|
||||
* import { dirname } from "node:path";
|
||||
* import { fileURLToPath } from "node:url";
|
||||
*
|
||||
* const relativeDirname = dirname(fileURLToPath(import.meta.url));
|
||||
* ```
|
||||
*/
|
||||
// eslint-disable-next-line no-var
|
||||
var __dirname: string;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "process" {
|
||||
global {
|
||||
namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
/**
|
||||
* The port used by the Docker Compose HTTP service.
|
||||
*/
|
||||
COMPOSE_PORT_HTTP?: string;
|
||||
|
||||
/**
|
||||
* The port used by the Docker Compose HTTPS service.
|
||||
*/
|
||||
COMPOSE_PORT_HTTPS?: string;
|
||||
|
||||
/**
|
||||
* An environment variable used to determine
|
||||
* whether Node.js is running in production mode.
|
||||
*
|
||||
* @see {@link https://nodejs.org/en/learn/getting-started/nodejs-the-difference-between-development-and-production | The difference between development and production}
|
||||
* @runtime node
|
||||
*/
|
||||
readonly NODE_ENV?: "development" | "production";
|
||||
/**
|
||||
* @todo Determine where this is used and if it is needed,
|
||||
* give it a better name.
|
||||
* @deprecated
|
||||
* @runtime node
|
||||
*/
|
||||
readonly AK_API_BASE_PATH?: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
web/packages/core/version/index.js
Normal file
21
web/packages/core/version/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @file Utility functions for working with semantic versions.
|
||||
*
|
||||
* @runtime common
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a URL to the release notes for the given version.
|
||||
*
|
||||
* @param {string} semver
|
||||
* @returns {URL}
|
||||
* @runtime common
|
||||
*/
|
||||
export function createReleaseNotesURL(semver) {
|
||||
const segments = semver.split(".");
|
||||
const versionFamily = segments.slice(0, -1).join(".");
|
||||
|
||||
const release = `${versionFamily}#fixed-in-${segments.join("")}`;
|
||||
|
||||
return new URL(`/docs/releases/${release}`, "https://goauthentik.io");
|
||||
}
|
@ -1,16 +1,24 @@
|
||||
/**
|
||||
* @file Utility functions for working with semantic versions.
|
||||
*
|
||||
* @runtime node
|
||||
*/
|
||||
import { MonoRepoRoot } from "#paths/node";
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
import PackageJSON from "../../../package.json" with { type: "json" };
|
||||
import { MonoRepoRoot } from "./paths.js";
|
||||
import PackageJSON from "../../../../package.json" with { type: "json" };
|
||||
|
||||
/**
|
||||
* The current version of authentik in SemVer format.
|
||||
*
|
||||
* @runtime node
|
||||
*/
|
||||
export const AuthentikVersion = /**@type {`${number}.${number}.${number}`} */ (PackageJSON.version);
|
||||
|
||||
/**
|
||||
* Reads the last commit hash from the current git repository.
|
||||
*
|
||||
* @runtime node
|
||||
*/
|
||||
export function readGitBuildHash() {
|
||||
try {
|
||||
@ -34,6 +42,7 @@ export function readGitBuildHash() {
|
||||
*
|
||||
* This must match the behavior defined in authentik's server-side `get_full_version` function.
|
||||
*
|
||||
* @runtime node
|
||||
* @see {@link "authentik\_\_init\_\_.py"}
|
||||
*/
|
||||
export function readBuildIdentifier() {
|
@ -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 (process.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,42 +0,0 @@
|
||||
/**
|
||||
* @file Utility functions for building and copying files.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A source environment variable, which can be a string, number, boolean, null, or undefined.
|
||||
* @typedef {string | number | boolean | null | undefined} EnvironmentVariable
|
||||
*/
|
||||
|
||||
/**
|
||||
* A type helper for serializing environment variables.
|
||||
*
|
||||
* @template {EnvironmentVariable} T
|
||||
* @typedef {T extends string ? `"${T}"` : T} JSONify
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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.']
|
||||
*
|
||||
* @param {EnvRecord} input
|
||||
* @param {Prefix} [prefix='process.env.']
|
||||
*
|
||||
* @returns {{[K in keyof EnvRecord as `${Prefix}${K}`]: JSONify<EnvRecord[K]>}}
|
||||
*/
|
||||
export function serializeEnvironmentVars(input, prefix = /** @type {Prefix} */ ("process.env.")) {
|
||||
/**
|
||||
* @type {Record<string, string>}
|
||||
*/
|
||||
const env = {};
|
||||
|
||||
for (const [key, value] of Object.entries(input)) {
|
||||
const namespaceKey = prefix + key;
|
||||
|
||||
env[namespaceKey] = JSON.stringify(value || "");
|
||||
}
|
||||
|
||||
return /** @type {any} */ (env);
|
||||
}
|
@ -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,7 +0,0 @@
|
||||
/// <reference types="./types/global.js" />
|
||||
|
||||
export * from "./paths.js";
|
||||
export * from "./constants.js";
|
||||
export * from "./build.js";
|
||||
export * from "./version.js";
|
||||
export * from "./scripting.js";
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "@goauthentik/monorepo",
|
||||
"version": "1.0.0",
|
||||
"description": "Utilities for the authentik monorepo.",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"types": "./out/index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@goauthentik/prettier-config": "^1.0.4",
|
||||
"@goauthentik/tsconfig": "^1.0.4",
|
||||
"@types/node": "^22.14.1",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "^5.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.11"
|
||||
},
|
||||
"types": "./out/index.d.ts",
|
||||
"prettier": "@goauthentik/prettier-config"
|
||||
}
|
15
web/packages/monorepo/types/global.d.ts
vendored
15
web/packages/monorepo/types/global.d.ts
vendored
@ -1,15 +0,0 @@
|
||||
declare module "process" {
|
||||
global {
|
||||
namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
/**
|
||||
* An environment variable used to determine
|
||||
* whether Node.js is running in production mode.
|
||||
*
|
||||
* @see {@link https://nodejs.org/en/learn/getting-started/nodejs-the-difference-between-development-and-production | The difference between development and production}
|
||||
*/
|
||||
NODE_ENV?: "production" | "development";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user