Replace npm + Corepack with pnpm

Migrate package management from npm + Corepack to pnpm across the root,
web, and website workspaces:

- Swap npm/Corepack tooling for pnpm: drop package-lock.json files and the
  bespoke Corepack bootstrap scripts (setup-corepack.mjs, utils/corepack.mjs,
  lint-lockfile.mjs); add pnpm-lock.yaml + pnpm-workspace.yaml per workspace.
- CI uses the official pnpm/action-setup + actions/setup-node; pin the pnpm
  store dir via PNPM_HOME so setup-node's `cache: pnpm` post-step succeeds.
- Docker sources pnpm from the official ghcr.io/pnpm/pnpm image via a
  ${BUILDPLATFORM}-pinned stage; the website docs build does a hoisted root
  install so @goauthentik/docusaurus-config resolves its own deps.
- Gate the web install on the `node` dep so runtime-only jobs don't invoke
  pnpm; scope the from-stable env setup so the new tooling doesn't run against
  the stable checkout's npm packageManager field.
- Resolve @goauthentik/api (client-ts) from its TypeScript source instead of a
  tsc-built dist, so it no longer depends on an install-time prepare having run
  (the storybook build's environment never built it); sfe's rollup gains .ts
  resolution to match.
- Netlify builds with pnpm; encode pnpm's supply-chain controls
  (onlyBuiltDependencies/allowBuilds, minimumReleaseAge) in the workspace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Teffen Ellis
2026-06-05 00:32:00 +02:00
parent 21666c8c1c
commit 6fb4bb543a
61 changed files with 48782 additions and 103766 deletions
+31 -42
View File
@@ -1,5 +1,5 @@
name: "Setup Node.js and NPM"
description: "Sets up Node.js with a specific NPM version via Corepack"
name: "Setup Node.js and pnpm"
description: "Installs pnpm via the version pinned in package.json#packageManager, then provisions Node.js with caching."
inputs:
working-directory:
description: "Path to the working directory containing the package.json file"
@@ -16,10 +16,7 @@ inputs:
cache-dependency-path:
description: "Path to dependency lock file for caching"
required: false
default: "package-lock.json"
cache:
description: "Package manager to cache"
default: "npm"
default: "pnpm-lock.yaml"
registry-url:
description: "npm registry URL"
default: "https://registry.npmjs.org"
@@ -27,51 +24,43 @@ inputs:
runs:
using: "composite"
steps:
- name: Setup Node.js (Corepack bootstrap)
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v4
with:
node-version-file: ${{ inputs.node-version-file }}
registry-url: ${{ inputs.registry-url }}
cache: ${{ inputs.cache }}
cache-dependency-path: |
${{ inputs.cache-dependency-path }}
${{ inputs.working-directory }}/${{ inputs.cache-dependency-path }}
- name: Install Corepack
working-directory: ${{ github.workspace}}
- name: Setup pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
- name: Pin pnpm store directory
# pnpm/action-setup points PNPM_HOME at its own bin directory, so
# `pnpm store path` derives a store inside that bin dir which never gets
# populated — actions/setup-node's `cache: pnpm` post-step then fails with
# "Path(s) specified in the action for caching do(es) not exist". pnpm
# honours PNPM_HOME above the npm_config_store_dir env var, so repoint
# PNPM_HOME (and the store) at a stable, writable path on the same
# filesystem as the workspace (so hardlinks keep working). This keeps the
# store-path probe, the installs and the cache save all in agreement.
shell: bash
run: | #shell
node ./scripts/node/setup-corepack.mjs --force
corepack enable
- name: Lint Node.js and NPM versions
shell: bash
run: node ./scripts/node/lint-runtime.mjs
run: |
echo "PNPM_HOME=${RUNNER_TEMP}/pnpm-home" >> "$GITHUB_ENV"
echo "npm_config_store_dir=${RUNNER_TEMP}/pnpm-home/store" >> "$GITHUB_ENV"
- name: Setup Node.js (Monorepo Root)
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v4
with:
node-version-file: ${{ inputs.node-version-file }}
registry-url: ${{ inputs.registry-url }}
cache: pnpm
cache-dependency-path: |
${{ inputs.cache-dependency-path }}
${{ inputs.working-directory }}/${{ inputs.cache-dependency-path }}
- name: Lint Node.js and pnpm versions
shell: bash
run: node ./scripts/node/lint-runtime.mjs
- name: Install monorepo dependencies
if: ${{ contains(inputs.dependencies, 'monorepo') }}
shell: bash
run: | #shell
node ./scripts/node/lint-lockfile.mjs
corepack npm ci
- name: Setup Node.js (Working Directory)
if: ${{ contains(inputs.dependencies, 'working-directory') }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v4
with:
node-version-file: ${{ inputs.working-directory }}/${{ inputs.node-version-file }}
registry-url: ${{ inputs.registry-url }}
run: pnpm install --frozen-lockfile
- name: Install working directory dependencies
if: ${{ contains(inputs.dependencies, 'working-directory') }}
if: ${{ contains(inputs.dependencies, 'working-directory') && inputs.working-directory != '.' }}
shell: bash
run: | # shell
corepack install
working-directory: ${{ inputs.working-directory }}
run: |
echo "node version: $(node --version)"
echo "npm version: $(corepack npm --version)"
node ./scripts/node/lint-lockfile.mjs ${{ inputs.working-directory }}
corepack npm ci --prefix ${{ inputs.working-directory }}
echo "pnpm version: $(pnpm --version)"
node ${{ github.workspace }}/scripts/node/lint-runtime.mjs
pnpm install --frozen-lockfile
+9 -1
View File
@@ -89,7 +89,15 @@ runs:
run: |
export PSQL_TAG=${{ inputs.postgresql_version }}
docker compose -f .github/actions/setup/compose.yml up -d --wait
corepack npm ci --prefix web
- name: Install web dependencies
# Only when node is also requested: pnpm is provided by the node setup
# above, and the web workspace needs a pnpm lockfile to install from. This
# keeps runtime-only jobs (e.g. rust, pending-migrations) and the legacy
# stable checkout — which predates the pnpm migration — from invoking pnpm.
if: ${{ contains(inputs.dependencies, 'runtime') && contains(inputs.dependencies, 'node') }}
shell: bash
working-directory: ${{ inputs.working-directory }}
run: pnpm --dir web install --frozen-lockfile
- name: Generate config
if: ${{ contains(inputs.dependencies, 'python') }}
shell: uv run python {0}
+4 -4
View File
@@ -26,7 +26,7 @@ jobs:
with:
working-directory: website
- name: Lint
run: corepack npm run ${{ matrix.command }} --prefix website
run: pnpm --dir website run ${{ matrix.command }}
build:
runs-on: ubuntu-latest
@@ -41,14 +41,14 @@ jobs:
${{ github.workspace }}/website/api/.docusaurus
${{ github.workspace }}/website/api/**/.cache
key: |
${{ runner.os }}-docusaurus-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
${{ runner.os }}-docusaurus-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
restore-keys: |
${{ runner.os }}-docusaurus-${{ hashFiles('**/package-lock.json') }}
${{ runner.os }}-docusaurus-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Build API Docs via Docusaurus
working-directory: website
env:
NODE_ENV: production
run: corepack npm run build -w api
run: pnpm run build:api
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4
with:
name: api-docs
+1 -3
View File
@@ -27,6 +27,4 @@ jobs:
env:
NETLIFY_SITE_ID: eb246b7b-1d83-4f69-89f7-01a936b4ca59
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
run: |
npm install -g netlify-cli
netlify deploy --dir=source_docs --prod
run: pnpm dlx netlify-cli deploy --dir=source_docs --prod
+3 -3
View File
@@ -28,7 +28,7 @@ jobs:
with:
working-directory: website
- name: Lint
run: corepack npm run ${{ matrix.command }} --prefix website
run: pnpm --dir website run ${{ matrix.command }}
build-docs:
runs-on: ubuntu-latest
env:
@@ -40,7 +40,7 @@ jobs:
with:
working-directory: website
- name: Build Documentation via Docusaurus
run: corepack npm run build --prefix website
run: pnpm --dir website run build
build-integrations:
runs-on: ubuntu-latest
env:
@@ -51,7 +51,7 @@ jobs:
with:
working-directory: website
- name: Build Integrations via Docusaurus
run: corepack npm run build -w integrations --prefix website
run: pnpm --dir website run build:integrations
build-container:
runs-on: ubuntu-latest
permissions:
+13 -8
View File
@@ -134,6 +134,11 @@ jobs:
uses: ./.github/actions/setup
with:
postgresql_version: ${{ matrix.psql }}
# The stable checkout predates the pnpm migration, so its
# package.json still pins npm as the package manager. Skip node here
# (migrating to stable only needs Python + the database); pnpm/node is
# set up again for the current checkout below.
dependencies: "system,python,runtime"
- name: run migrations to stable
run: |
docker ps
@@ -266,16 +271,16 @@ jobs:
if: contains(matrix.job.profiles, 'selenium')
with:
path: web/dist
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b
key: ${{ runner.os }}-web-${{ hashFiles('web/pnpm-lock.yaml', 'pnpm-lock.yaml', 'web/src/**', 'web/packages/sfe/src/**') }}-b
- name: prepare web ui
if: steps.cache-web.outputs.cache-hit != 'true' && contains(matrix.job.profiles, 'selenium')
working-directory: web
env:
NODE_ENV: "production"
run: |
corepack npm ci
corepack npm run build
corepack npm run build:sfe
pnpm install --frozen-lockfile
pnpm run build
pnpm run build:sfe
- name: run e2e
run: |
uv run coverage run manage.py test ${{ matrix.job.glob }}
@@ -321,15 +326,15 @@ jobs:
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v4
with:
path: web/dist
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b
key: ${{ runner.os }}-web-${{ hashFiles('web/pnpm-lock.yaml', 'web/src/**', 'web/packages/sfe/src/**') }}-b
- name: prepare web ui
if: steps.cache-web.outputs.cache-hit != 'true'
env:
NODE_ENV: "production"
run: |
corepack npm ci --prefix web
corepack npm run build --prefix web
corepack npm run build:sfe --prefix web
pnpm --dir web install --frozen-lockfile
pnpm --dir web run build
pnpm --dir web run build:sfe
- name: run conformance
run: |
uv run coverage run manage.py test ${{ matrix.job.glob }}
+1 -1
View File
@@ -149,7 +149,7 @@ jobs:
with:
working-directory: web
- name: Build web
run: corepack npm run build-proxy --prefix web
run: pnpm --dir web run build-proxy
- name: Build outpost
run: |
set -x
+6 -6
View File
@@ -22,13 +22,13 @@ jobs:
with:
working-directory: web
- name: Lint
run: corepack npm run lint-check --prefix web
run: pnpm --dir web run lint-check
- name: Check types
run: corepack npm run tsc --prefix web
run: pnpm --dir web run tsc
- name: Check formatting
run: corepack npm run prettier-check --prefix web
run: pnpm --dir web run prettier-check
- name: Lit analyse
run: corepack npm run lit-analyse --prefix web
run: pnpm --dir web run lit-analyse
build:
runs-on: ubuntu-latest
@@ -42,7 +42,7 @@ jobs:
env:
NODE_ENV: "production"
working-directory: web/
run: corepack npm run build
run: pnpm run build
ci-web-mark:
if: always()
needs:
@@ -65,4 +65,4 @@ jobs:
working-directory: web
- name: test
working-directory: web/
run: corepack npm run test || exit 0
run: pnpm run test || exit 0
+2 -5
View File
@@ -36,8 +36,6 @@ jobs:
with:
fetch-depth: 2
- uses: ./.github/actions/setup-node
with:
working-directory: ${{ matrix.package }}
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # 24d32ffd492484c1d75e0c0b894501ddb9d30d62
@@ -48,6 +46,5 @@ jobs:
if: steps.changed-files.outputs.any_changed == 'true'
working-directory: ${{ matrix.package }}
run: |
corepack npm ci
corepack npm run build
corepack npm publish
pnpm run build
pnpm publish --no-git-checks
-2
View File
@@ -14,8 +14,6 @@ media
# Node
node_modules
corepack.tgz
.corepack
.cspellcache
cspell-report.*
+7 -14
View File
@@ -1,20 +1,13 @@
# Block lifecycle scripts (preinstall/install/postinstall/prepare) from dependencies.
# This neutralizes the dominant npm supply-chain attack vector.
#
# Packages that legitimately need a build step (e.g. esbuild, chromedriver, tree-sitter)
# must be rebuilt explicitly:
#
# npm rebuild --foreground-scripts esbuild chromedriver tree-sitter tree-sitter-json
ignore-scripts=true
# Fail fast if the active Node/npm doesn't match the "engines" field.
# Fail fast if the active Node/pnpm doesn't match the "engines" field.
engine-strict=true
# Pin exact versions so `npm install <pkg>` writes "1.2.3" not "^1.2.3".
# Pin exact versions so `pnpm add <pkg>` writes "1.2.3" not "^1.2.3".
save-exact=true
# Surface CVE warnings during install; doesn't block.
audit=true
# Suppress funding banners.
fund=false
# Lifecycle scripts are blocked by default in pnpm 10+. Per-project
# allow-lists live in the `pnpm.onlyBuiltDependencies` field of each
# `package.json` (replaces the prior `npm rebuild --foreground-scripts`
# dance keyed off `.npmrc`'s `ignore-scripts`).
+4 -1
View File
@@ -23,6 +23,10 @@ website/api/reference
## Yarn
.yarn/**/*
# PNPM
pnpm-workspace.yaml
pnpm-lock.yaml
## Node
node_modules
coverage
@@ -50,4 +54,3 @@ src/locales/
# Storybook
storybook-static/
.storybook/css-import-maps*
+34 -41
View File
@@ -107,8 +107,8 @@ migrate: ## Run the Authentik Django server's migrations
i18n-extract: core-i18n-extract web-i18n-extract ## Extract strings that require translation into files to send to a translation service
aws-cfn: node-install
corepack npm install --prefix lifecycle/aws
$(UV) run corepack npm run aws-cfn --prefix lifecycle/aws
pnpm --dir lifecycle/aws install
$(UV) run pnpm --dir lifecycle/aws run aws-cfn
run: ## Run the main authentik server and worker processes
$(UV) run ak allinone
@@ -163,7 +163,7 @@ endif
$(SED_INPLACE) 's/^VERSION = ".*"/VERSION = "$(version)"/' ${PWD}/authentik/__init__.py
$(SED_INPLACE) "s/version = \"${current_version}\"/version = \"$(version)\"/" ${PWD}/Cargo.toml ${PWD}/Cargo.lock
$(MAKE) gen-build gen-compose aws-cfn
$(SED_INPLACE) "s/\"${current_version}\"/\"$(version)\"/" ${PWD}/package.json ${PWD}/package-lock.json ${PWD}/web/package.json ${PWD}/web/package-lock.json
$(SED_INPLACE) "s/\"${current_version}\"/\"$(version)\"/" ${PWD}/package.json ${PWD}/web/package.json
echo -n $(version) > ${PWD}/internal/constants/VERSION
#########################
@@ -214,7 +214,7 @@ gen-client-rust: ## Build and install the authentik API for Rust
gen-client-ts: ## Build and install the authentik API for Typescript into the authentik UI Application
make -C "${PWD}/packages/client-ts" build
npm --prefix web install
pnpm --dir web install
_gen-clients: gen-client-go gen-client-rust gen-client-ts
gen-clients: ## Build and install API clients used by authentik
@@ -229,55 +229,48 @@ gen-dev-config: ## Generate a local development config file
## Node.js
#########################
# Packages whose install/postinstall scripts are required for correct
# operation (binary downloads, native bindings). The root .npmrc sets
# `ignore-scripts=true` to block dependency lifecycle scripts by default;
# this list is rebuilt explicitly with scripts re-enabled. Audit any
# additions: each entry runs arbitrary code at install time.
TRUSTED_INSTALL_SCRIPTS := esbuild chromedriver tree-sitter tree-sitter-json
# Lifecycle scripts are blocked by default in pnpm 10+ via
# `pnpm-workspace.yaml#onlyBuiltDependencies`. Adding a package to that list
# grants it arbitrary code execution at install — audit at review time.
node-preinstall: ## Install corepack and lint the runtime to ensure the correct Node.js version is being used before installing dependencies.
node ./scripts/node/setup-corepack.mjs
node-preinstall: ## Verify the active Node.js and pnpm versions match what's in package.json.
node ./scripts/node/lint-runtime.mjs
node-install: node-preinstall ## Install the necessary libraries to build Node.js packages
corepack npm ci
node-install: node-preinstall ## Install the necessary libraries to build Node.js packages
pnpm install --frozen-lockfile
#########################
## Web
#########################
web-install: ## Install the necessary libraries to build the Authentik UI
corepack npm ci --prefix web
web-postinstall: ## Trigger postinstall scripts for packages with native bindings or binary downloads, which are blocked by default for security reasons.
corepack npm rebuild --prefix web --ignore-scripts=false --foreground-scripts $(TRUSTED_INSTALL_SCRIPTS)
web-install: ## Install the necessary libraries to build the Authentik UI
pnpm --dir web install --frozen-lockfile
web-build: node-install ## Build the Authentik UI
corepack npm run --prefix web build
pnpm --dir web run build
web: web-lint-fix web-lint web-check-compile ## Automatically fix formatting issues in the Authentik UI source code, lint the code, and compile it
web-test: ## Run tests for the Authentik UI
corepack npm run --prefix web test
web-test: ## Run tests for the Authentik UI
pnpm --dir web run test
web-watch: ## Build and watch the Authentik UI for changes, updating automatically
corepack npm run --prefix web watch
pnpm --dir web run watch
web-storybook-watch: ## Build and run the storybook documentation server
corepack npm run --prefix web storybook
pnpm --dir web run storybook
web-lint-fix:
corepack npm run --prefix web prettier
pnpm --dir web run prettier
web-lint:
corepack npm run --prefix web lint
corepack npm run --prefix web lit-analyse
pnpm --dir web run lint
pnpm --dir web run lit-analyse
web-check-compile:
corepack npm run --prefix web tsc
pnpm --dir web run tsc
web-i18n-extract:
corepack npm run --prefix web extract-locales
pnpm --dir web run extract-locales
#########################
## Docs
@@ -286,35 +279,35 @@ web-i18n-extract:
docs: docs-lint-fix docs-build ## Automatically fix formatting issues in the Authentik docs source code, lint the code, and compile it
docs-install: node-install ## Install the necessary libraries to build the Authentik documentation
corepack npm ci --prefix website
pnpm --dir website install --frozen-lockfile
docs-lint-fix: lint-spellcheck
corepack npm run --prefix website prettier
pnpm --dir website run prettier
docs-build:
node ./scripts/node/lint-runtime.mjs website
corepack npm run --prefix website build
pnpm --dir website run build
docs-watch: ## Build and watch the topics documentation
corepack npm run --prefix website start
pnpm --dir website run start
integrations: docs-lint-fix integrations-build ## Fix formatting issues in the integrations source code, lint the code, and compile it
integrations: docs-lint-fix integrations-build ## Fix formatting issues in the integrations source code, lint the code, and compile it
integrations-build:
corepack npm run --prefix website -w integrations build
pnpm --dir website run build:integrations
integrations-watch: ## Build and watch the Integrations documentation
corepack npm run --prefix website -w integrations start
pnpm --filter "./website/integrations" run start
docs-api-build:
corepack npm run --prefix website -w api build
pnpm --dir website run build:api
docs-api-watch: ## Build and watch the API documentation
corepack npm run --prefix website -w api generate
corepack npm run --prefix website -w api start
pnpm --filter "./website/api" run generate
pnpm --filter "./website/api" run start
docs-api-clean: ## Clean generated API documentation
corepack npm run --prefix website -w api build:api:clean
docs-api-clean: ## Clean generated API documentation
pnpm --filter "./website/api" run clean
#########################
## Docker
+2 -1
View File
@@ -220,7 +220,8 @@
"LICENSE", // License file
".gitignore", // Git ignore file
".gitattributes", // Git attributes file
"*-lock.{json,yaml}", // Lock files (NPM, Yarn, Pip, Cargo)
"*-lock.{json,yaml}", // Lock files (NPM, Yarn, Pnpm, Pip, Cargo)
"pnpm-workspace.yaml", // PNPM workspace + override config
"CHANGELOG*.md", // Changelog files
".vscode/**", // VSCode configuration
"out", // TypeScript type-checking output
-130
View File
@@ -1,130 +0,0 @@
{
"name": "@goauthentik/lifecycle-aws",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@goauthentik/lifecycle-aws",
"version": "0.0.0",
"license": "MIT",
"devDependencies": {
"aws-cdk": "^2.1126.0",
"cross-env": "^10.1.0"
},
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
}
},
"node_modules/@epic-web/invariant": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
"dev": true,
"license": "MIT"
},
"node_modules/aws-cdk": {
"version": "2.1126.0",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1126.0.tgz",
"integrity": "sha512-uNoocb3vCPiAT3j9+SwL6pn/VVggHWBsgC2XpxyhNvYQYt6cE9BM/149GWwtdcwnLrPjnwW1+CV/5nSSh5dV+w==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"cdk": "bin/cdk"
},
"engines": {
"node": ">= 18.0.0"
}
},
"node_modules/cross-env": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@epic-web/invariant": "^1.0.0",
"cross-spawn": "^7.0.6"
},
"bin": {
"cross-env": "dist/bin/cross-env.js",
"cross-env-shell": "dist/bin/cross-env-shell.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"license": "ISC"
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
}
}
}
+2 -7
View File
@@ -12,19 +12,14 @@
},
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"pnpm": ">=11.5.1"
},
"devEngines": {
"runtime": {
"name": "node",
"onFail": "warn",
"version": ">=24"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"onFail": "warn"
}
},
"packageManager": "npm@11.14.1+sha512.6a8a4d67478497a2dbc6815cad72e64c43f33413717e242756047d466241ab39bee61e691683a64658e94496ec5f1a1c05e4a5ec62dcc773280dfd949443a367"
"packageManager": "pnpm@11.5.1+sha512.93f7b57422ea7068257235b4c16eb60762eb68e1dc23723199cc739043ea9be2c4143274a399d8c6defa2b1176226d9ca1c4b63482d6200c1a8fbaa78c1d1485"
}
+15 -9
View File
@@ -1,5 +1,9 @@
# syntax=docker/dockerfile:1
# Tag must track the root package.json `packageManager` version. ${BUILDPLATFORM}
# keeps the binary's arch aligned with the builder stage on cross-arch builds.
FROM --platform=${BUILDPLATFORM} ghcr.io/pnpm/pnpm:11.5.1@sha256:3cbdefab0d887dee497ddc8dfe6d871257317d69520fe30f9ccec0a84bde6e89 AS pnpm
# Stage: Build webui
FROM --platform=${BUILDPLATFORM} docker.io/library/node:26-trixie-slim@sha256:aa27a5fbf5acb298116a38133794f080406c6f8dfe52e2e2836bb55dc7cae8f0 AS node-builder
@@ -9,36 +13,38 @@ ENV NODE_ENV=production
WORKDIR /work
COPY --from=pnpm /opt/pnpm /opt/pnpm
ENV PATH="/opt/pnpm:${PATH}"
RUN --mount=type=bind,target=/work/package.json,src=./package.json \
--mount=type=bind,target=/work/package-lock.json,src=./package-lock.json \
--mount=type=bind,target=/work/web/package.json,src=./web/package.json \
--mount=type=bind,target=/work/web/package-lock.json,src=./web/package-lock.json \
--mount=type=bind,target=/work/web/pnpm-lock.yaml,src=./web/pnpm-lock.yaml \
--mount=type=bind,target=/work/scripts/node/,src=./scripts/node/ \
--mount=type=bind,target=/work/packages/logger-js/,src=./packages/logger-js/ \
node ./scripts/node/setup-corepack.mjs --force && \
node ./scripts/node/lint-runtime.mjs ./web
WORKDIR /work/web
# These files need to be copied and cannot be mounted as `npm ci` will build the client's typescript
# These files need to be copied and cannot be mounted as `pnpm install` will build the client's typescript
COPY ./packages /work/packages
COPY ./web/packages /work/web/packages
RUN --mount=type=bind,target=/work/.npmrc,src=./.npmrc \
--mount=type=bind,target=/work/web/package.json,src=./web/package.json \
--mount=type=bind,target=/work/web/package-lock.json,src=./web/package-lock.json \
--mount=type=bind,target=/work/web/pnpm-lock.yaml,src=./web/pnpm-lock.yaml \
--mount=type=bind,target=/work/web/pnpm-workspace.yaml,src=./web/pnpm-workspace.yaml \
--mount=type=bind,target=/work/web/packages/sfe/package.json,src=./web/packages/sfe/package.json \
--mount=type=bind,target=/work/web/scripts,src=./web/scripts \
--mount=type=cache,id=npm-ak,sharing=shared,target=/root/.npm \
corepack npm ci
--mount=type=cache,id=pnpm-ak,sharing=shared,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
COPY ./package.json /work
COPY ./web /work/web/
# TODO: Update this after moving website to docs
COPY ./website /work/website/
RUN npm run build && \
npm run build:sfe
RUN pnpm run build && \
pnpm run build:sfe
# Stage: Build go proxy
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.4-trixie@sha256:0dcba0d95dbfb072e9917a106b9e07d7cc298097dc83e9307056ef1889de654d AS go-builder
+14 -8
View File
@@ -1,35 +1,41 @@
# syntax=docker/dockerfile:1
# Tag must track the root package.json `packageManager` version. ${BUILDPLATFORM}
# keeps the binary's arch aligned with the builder stage on cross-arch builds.
FROM --platform=${BUILDPLATFORM} ghcr.io/pnpm/pnpm:11.5.1@sha256:3cbdefab0d887dee497ddc8dfe6d871257317d69520fe30f9ccec0a84bde6e89 AS pnpm
# Stage 1: Build web
FROM --platform=${BUILDPLATFORM} docker.io/library/node:26 AS web-builder
ENV NODE_ENV=production
WORKDIR /static
# These files need to be copied and cannot be mounted as `npm ci` will build the client's typescript
# These files need to be copied and cannot be mounted as `pnpm install` will build the client's typescript
COPY ./packages /packages
COPY ./web/packages /static/packages
COPY --from=pnpm /opt/pnpm /opt/pnpm
ENV PATH="/opt/pnpm:${PATH}"
RUN --mount=type=bind,target=/static/package.json,src=./package.json \
--mount=type=bind,target=/static/package-lock.json,src=./package-lock.json \
--mount=type=bind,target=/static/web/package.json,src=./web/package.json \
--mount=type=bind,target=/static/web/package-lock.json,src=./web/package-lock.json \
--mount=type=bind,target=/static/web/pnpm-lock.yaml,src=./web/pnpm-lock.yaml \
--mount=type=bind,target=/static/scripts/node/,src=./scripts/node/ \
--mount=type=bind,target=/static/packages/logger-js/,src=./packages/logger-js/ \
node ./scripts/node/setup-corepack.mjs --force && \
node ./scripts/node/lint-runtime.mjs ./web
COPY package.json /
RUN --mount=type=bind,target=/static/.npmrc,src=./.npmrc \
--mount=type=bind,target=/static/package.json,src=./web/package.json \
--mount=type=bind,target=/static/package-lock.json,src=./web/package-lock.json \
--mount=type=bind,target=/static/pnpm-lock.yaml,src=./web/pnpm-lock.yaml \
--mount=type=bind,target=/static/pnpm-workspace.yaml,src=./web/pnpm-workspace.yaml \
--mount=type=bind,target=/static/scripts,src=./web/scripts \
--mount=type=cache,target=/root/.npm \
corepack npm ci
--mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
COPY web .
RUN npm run build-proxy
RUN pnpm run build-proxy
# Stage 2: Build
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.4-trixie@sha256:0dcba0d95dbfb072e9917a106b9e07d7cc298097dc83e9307056ef1889de654d AS builder
-24327
View File
File diff suppressed because it is too large Load Diff
+9 -30
View File
@@ -3,8 +3,7 @@
"version": "2026.8.0-rc1",
"private": true,
"scripts": {
"lint": "run-s lint:runtime lint:spellcheck lint:lockfile",
"lint:lockfile": "node ./scripts/node/lint-lockfile.mjs",
"lint": "run-s lint:runtime lint:spellcheck",
"lint:runtime": "node ./scripts/node/lint-runtime.mjs",
"lint:spellcheck": "cspell . --config cspell.config.jsonc"
},
@@ -14,11 +13,11 @@
},
"dependencies": {
"@eslint/js": "^9.39.3",
"@goauthentik/docusaurus-config": "./packages/docusaurus-config",
"@goauthentik/eslint-config": "./packages/eslint-config",
"@goauthentik/logger-js": "./packages/logger-js",
"@goauthentik/prettier-config": "./packages/prettier-config",
"@goauthentik/tsconfig": "./packages/tsconfig",
"@goauthentik/docusaurus-config": "workspace:*",
"@goauthentik/eslint-config": "workspace:*",
"@goauthentik/logger-js": "workspace:*",
"@goauthentik/prettier-config": "workspace:*",
"@goauthentik/tsconfig": "workspace:*",
"cspell": "^10.0.0",
"eslint": "^9.39.3",
"npm-run-all": "^4.1.5",
@@ -29,37 +28,17 @@
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.3"
},
"workspaces": [],
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"pnpm": ">=11.5.1"
},
"devEngines": {
"runtime": {
"name": "node",
"onFail": "warn",
"version": ">=24"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"onFail": "warn"
}
},
"packageManager": "npm@11.14.1+sha512.6a8a4d67478497a2dbc6815cad72e64c43f33413717e242756047d466241ab39bee61e691683a64658e94496ec5f1a1c05e4a5ec62dcc773280dfd949443a367",
"prettier": "@goauthentik/prettier-config",
"overrides": {
"@typescript-eslint/eslint-plugin": {
"typescript": "$typescript"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"format-imports": {
"eslint": "$eslint"
},
"typescript-eslint": {
"typescript": "$typescript"
}
}
"packageManager": "pnpm@11.5.1+sha512.93f7b57422ea7068257235b4c16eb60762eb68e1dc23723199cc739043ea9be2c4143274a399d8c6defa2b1176226d9ca1c4b63482d6200c1a8fbaa78c1d1485",
"prettier": "@goauthentik/prettier-config"
}
+6 -5
View File
@@ -8,18 +8,19 @@
"url": "https://github.com/goauthentik/authentik.git"
},
"scripts": {
"build": "npm run clean && tsc -b tsconfig.json tsconfig.esm.json",
"build": "pnpm run clean && tsc -b tsconfig.json tsconfig.esm.json",
"clean": "tsc -b --clean tsconfig.json tsconfig.esm.json",
"prepare": "npm run build"
"prepare": "pnpm run build"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"main": "./src/index.ts",
"types": "./src/index.ts",
"devDependencies": {
"@goauthentik/prettier-config": "^3.5.0",
"prettier": "^3.8.1",
"typescript": "^4.0 || ^5.0"
},
"packageManager": "pnpm@11.5.1+sha512.93f7b57422ea7068257235b4c16eb60762eb68e1dc23723199cc739043ea9be2c4143274a399d8c6defa2b1176226d9ca1c4b63482d6200c1a8fbaa78c1d1485",
"prettier": "@goauthentik/prettier-config",
"sideEffects": false,
"module": "./dist/esm/index.js"
"module": "./src/index.ts"
}
File diff suppressed because it is too large Load Diff
+6 -18
View File
@@ -34,9 +34,9 @@
"@docusaurus/theme-search-algolia": "^3.10.0",
"@docusaurus/types": "^3.10.0",
"@eslint/js": "^9.39.3",
"@goauthentik/eslint-config": "../eslint-config",
"@goauthentik/prettier-config": "../prettier-config",
"@goauthentik/tsconfig": "../tsconfig",
"@goauthentik/eslint-config": "link:../eslint-config",
"@goauthentik/prettier-config": "link:../prettier-config",
"@goauthentik/tsconfig": "link:../tsconfig",
"@types/node": "^25.7.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
@@ -65,8 +65,7 @@
"out/**/*"
],
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
},
"devEngines": {
"runtime": {
@@ -75,23 +74,12 @@
"version": ">=24"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"name": "pnpm",
"version": ">=11.5.1",
"onFail": "warn"
}
},
"prettier": "@goauthentik/prettier-config",
"overrides": {
"@typescript-eslint/eslint-plugin": {
"typescript": "$typescript"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"typescript-eslint": {
"typescript": "$typescript"
}
},
"peerDependenciesMeta": {
"@docusaurus/theme-search-algolia": {
"optional": true
File diff suppressed because it is too large Load Diff
@@ -45,10 +45,10 @@
},
"devDependencies": {
"@eslint/js": "^9.39.3",
"@goauthentik/eslint-config": "../eslint-config",
"@goauthentik/logger-js": "../logger-js",
"@goauthentik/prettier-config": "../prettier-config",
"@goauthentik/tsconfig": "../tsconfig",
"@goauthentik/eslint-config": "link:../eslint-config",
"@goauthentik/logger-js": "link:../logger-js",
"@goauthentik/prettier-config": "link:../prettier-config",
"@goauthentik/tsconfig": "link:../tsconfig",
"@types/node": "^25.7.0",
"esbuild": "^0.27.4",
"eslint": "^9.39.3",
@@ -72,8 +72,7 @@
"out/**/*"
],
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
},
"devEngines": {
"runtime": {
@@ -82,8 +81,8 @@
"version": ">=24"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"name": "pnpm",
"version": ">=11.5.1",
"onFail": "warn"
}
},
@@ -96,20 +95,6 @@
"reload",
"authentik"
],
"overrides": {
"@typescript-eslint/eslint-plugin": {
"typescript": "$typescript"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"format-imports": {
"eslint": "$eslint"
},
"typescript-eslint": {
"typescript": "$typescript"
}
},
"peerDependenciesMeta": {
"@goauthentik/logger-js": {
"optional": true
File diff suppressed because it is too large Load Diff
+5 -20
View File
@@ -45,8 +45,8 @@
"eslint-plugin-wc": "^3.1.0"
},
"devDependencies": {
"@goauthentik/prettier-config": "../prettier-config",
"@goauthentik/tsconfig": "../tsconfig",
"@goauthentik/prettier-config": "link:../prettier-config",
"@goauthentik/tsconfig": "link:../tsconfig",
"@types/eslint": "^9.6.1",
"@types/node": "^25.7.0",
"typescript": "^6.0.3",
@@ -64,8 +64,7 @@
"out/**/*"
],
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
},
"devEngines": {
"runtime": {
@@ -74,26 +73,12 @@
"onFail": "warn"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"name": "pnpm",
"version": ">=11.5.1",
"onFail": "warn"
}
},
"prettier": "@goauthentik/prettier-config",
"overrides": {
"@typescript-eslint/eslint-plugin": {
"typescript": "$typescript"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"format-imports": {
"eslint": "$eslint"
},
"typescript-eslint": {
"typescript": "$typescript"
}
},
"peerDependenciesMeta": {
"react": {
"optional": true
File diff suppressed because it is too large Load Diff
+5 -20
View File
@@ -29,8 +29,8 @@
},
"devDependencies": {
"@eslint/js": "^9.39.3",
"@goauthentik/prettier-config": "../prettier-config",
"@goauthentik/tsconfig": "../tsconfig",
"@goauthentik/prettier-config": "link:../prettier-config",
"@goauthentik/tsconfig": "link:../tsconfig",
"@types/node": "^25.7.0",
"eslint": "^9.39.3",
"pino": "^10.3.1",
@@ -50,8 +50,7 @@
"out/**/*"
],
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
},
"devEngines": {
"runtime": {
@@ -60,26 +59,12 @@
"onFail": "ignore"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"name": "pnpm",
"version": ">=11.5.1",
"onFail": "ignore"
}
},
"prettier": "@goauthentik/prettier-config",
"overrides": {
"@typescript-eslint/eslint-plugin": {
"typescript": "$typescript"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"format-imports": {
"eslint": "$eslint"
},
"typescript-eslint": {
"typescript": "$typescript"
}
},
"peerDependenciesMeta": {
"pino": {
"optional": true
File diff suppressed because it is too large Load Diff
+5 -20
View File
@@ -37,8 +37,8 @@
},
"devDependencies": {
"@eslint/js": "^9.39.3",
"@goauthentik/eslint-config": "../eslint-config",
"@goauthentik/tsconfig": "../tsconfig",
"@goauthentik/eslint-config": "link:../eslint-config",
"@goauthentik/tsconfig": "link:../tsconfig",
"@types/node": "^25.7.0",
"eslint": "^9.39.3",
"prettier": "^3.8.3",
@@ -56,8 +56,7 @@
"out/**/*"
],
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
},
"devEngines": {
"runtime": {
@@ -66,26 +65,12 @@
"onFail": "warn"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"name": "pnpm",
"version": ">=11.5.1",
"onFail": "warn"
}
},
"prettier": "./index.js",
"overrides": {
"@typescript-eslint/eslint-plugin": {
"typescript": "$typescript"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"format-imports": {
"eslint": "$eslint"
},
"typescript-eslint": {
"typescript": "$typescript"
}
},
"publishConfig": {
"access": "public"
}
-17
View File
@@ -1,17 +0,0 @@
{
"name": "@goauthentik/tsconfig",
"version": "2.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@goauthentik/tsconfig",
"version": "2.0.0",
"license": "MIT",
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
}
}
}
}
+3 -4
View File
@@ -14,8 +14,7 @@
"main": "tsconfig.json",
"type": "module",
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
},
"devEngines": {
"runtime": {
@@ -24,8 +23,8 @@
"onFail": "warn"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"name": "pnpm",
"version": ">=11.5.1",
"onFail": "warn"
}
},
+14849
View File
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
packages:
- "packages/docusaurus-config"
- "packages/esbuild-plugin-live-reload"
- "packages/eslint-config"
- "packages/logger-js"
- "packages/prettier-config"
- "packages/tsconfig"
- "lifecycle/aws"
overrides:
"@typescript-eslint/eslint-plugin>typescript": "$typescript"
"@typescript-eslint/parser>typescript": "$typescript"
"format-imports>eslint": "$eslint"
"typescript-eslint>typescript": "$typescript"
# Allow-list of dependencies whose install/postinstall scripts may run.
# Everything else is blocked, replacing the prior `ignore-scripts=true` +
# `npm rebuild --foreground-scripts <pkg>` pattern from #20400. Each entry is
# audited at review time — adding a package here grants it arbitrary code
# execution at install.
onlyBuiltDependencies:
- esbuild
# Explicit approval map for pnpm 11+. `true` = allowed (mirror onlyBuiltDependencies);
# `false` = explicitly declined (silences the "pending approval" prompt
# without running the script).
allowBuilds:
core-js: false
esbuild: true
-280
View File
@@ -1,280 +0,0 @@
#!/usr/bin/env node
/**
* @file Lints the package-lock.json file to ensure it is in sync with package.json.
*
* Usage:
* lint-lockfile [options] [directory]
*
* Options:
* --warn Report issues as warnings instead of failing. The lockfile is
* still regenerated on disk, but the process exits 0.
*
* Exit codes:
* 0 Lockfile is in sync (or --warn was passed)
* 1 Unexpected error
* 2 Lockfile drift detected
*/
/// <reference lib="esnext" />
import * as assert from "node:assert/strict";
import { findPackageJSON } from "node:module";
import { dirname } from "node:path";
import { isDeepStrictEqual, parseArgs } from "node:util";
import { ConsoleLogger } from "../../packages/logger-js/lib/node.js";
import { parseCWD, reportAndExit } from "./utils/commands.mjs";
import { corepack } from "./utils/corepack.mjs";
import { gitStatus } from "./utils/git.mjs";
import { findNPMPackage, loadJSON, npm, pluckDependencyFields } from "./utils/node.mjs";
//#region Constants
const logger = ConsoleLogger.prefix("lint:lockfile");
const { values: options, positionals } = parseArgs({
options: {
"warn": {
type: "boolean",
default: false,
description: "Report issues as warnings instead of failing",
},
"skip-git": {
type: "boolean",
default: !!process.env.CI,
description:
"Skip checking for uncommitted changes (use with --warn to ignore drift without reporting)",
},
},
allowPositionals: true,
});
const cwd = parseCWD(positionals);
const ignoredProperties = new Set([
// ---
"peer",
"engines",
"optional",
]);
//#region Utilities
/**
* @param {Record<string, unknown>} actual
* @param {Record<string, unknown>} expected
* @param {string[]} [prefix]
* @returns {Set<string>[]}
*/
function extractDiffedProperties(actual, expected, prefix = []) {
const a = actual ?? {};
const b = expected ?? {};
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
/** @type {Set<string>[]} */
const diffs = [];
for (const key of keys) {
const path = [...prefix, key];
const valA = a[key];
const valB = b[key];
if (
valA !== null &&
valB !== null &&
typeof valA === "object" &&
typeof valB === "object" &&
!Array.isArray(valA) &&
!Array.isArray(valB)
) {
// @ts-ignore
diffs.push(...extractDiffedProperties(valA, valB, path));
} else if (!isDeepStrictEqual(valA, valB)) {
diffs.push(new Set(path));
}
}
return diffs;
}
//#endregion
/**
* Exit code when lockfile drift is detected (distinct from general errors)
*/
const EXIT_DRIFT = 2;
/**
* @returns {Promise<string[]>} The list of issues detected.
*/
async function run() {
/** @type {string[]} */
const issues = [];
/**
* Records an issue. In strict mode, throws immediately.
* In warn mode, collects the message for later reporting.
*
* @param {boolean} ok
* @param {string} message
*/
const check = (ok, message) => {
if (ok) return;
if (options.warn) {
issues.push(message);
return;
}
assert.fail(message);
};
/**
* Checks deep equality of two values. In strict mode, throws if they are not equal.
* In warn mode, records an issue instead.
*
* @param {unknown} actual
* @param {unknown} expected
* @param {string} message
*/
const checkDeep = (actual, expected, message) => {
if (options.warn) {
if (!isDeepStrictEqual(actual, expected)) {
issues.push(message);
}
return;
}
assert.deepStrictEqual(actual, expected, message);
};
logger.info(`Linting lockfile integrity in: ${cwd}`);
// MARK: Locate files
const resolvedPath = import.meta.resolve(cwd);
const packageJSONPath = findPackageJSON(resolvedPath);
assert.ok(
packageJSONPath,
"Could not find package.json in the current directory or any parent directories",
);
const packageDir = dirname(packageJSONPath);
const { packageLockPath } = await findNPMPackage(packageDir);
const lockfileDir = dirname(packageLockPath);
const isWorkspace = lockfileDir !== packageDir;
const corepackVersion = await corepack`--version`().catch(() => null);
const useCorepack = !!corepackVersion;
logger.info(`corepack: ${corepackVersion || "disabled"}`);
const expected = {
lockfile: await loadJSON(packageLockPath),
package: await loadJSON(packageJSONPath).then(pluckDependencyFields),
};
logger.info(`package.json: ${packageJSONPath} (${expected.package.name})`);
logger.info(`package-lock.json: ${packageLockPath}${isWorkspace ? " (workspace root)" : ""}`);
// MARK: Uncommitted changes
if (options["skip-git"]) {
logger.warn("Skipping git status check");
} else {
const packageStatus = await gitStatus(packageJSONPath);
const lockfileStatus = await gitStatus(packageLockPath);
if (!packageStatus.available || !lockfileStatus.available) {
logger.warn("Git is not available; skipping uncommitted change detection.");
} else {
check(packageStatus.clean, `package.json has uncommitted changes: ${packageJSONPath}`);
check(
lockfileStatus.clean,
`package-lock.json has uncommitted changes: ${packageLockPath}`,
);
}
}
// MARK: Regenerate
const npmVersion = await npm`--version`({ useCorepack });
logger.info(`Detected npm version: ${npmVersion}`);
await npm`install --package-lock-only`({
cwd: lockfileDir,
useCorepack,
});
logger.info("npm install complete.");
const actual = {
lockfile: await loadJSON(packageLockPath),
package: await loadJSON(packageJSONPath).then(pluckDependencyFields),
};
// MARK: Compare
assert.deepStrictEqual(
actual.package,
expected.package,
`package.json was unexpectedly modified during lockfile check: ${packageJSONPath}`,
);
try {
checkDeep(
actual.lockfile,
expected.lockfile,
`package-lock.json is out of sync with package.json`,
);
} catch (error) {
if (!(error instanceof assert.AssertionError)) {
throw error;
}
// NPM versions <=11.10 has issues with deterministic lockfile generation,
// especially around optional peer dependencies.
const diffedProperties = extractDiffedProperties(actual.lockfile, expected.lockfile).filter(
(segments) => segments.isDisjointFrom(ignoredProperties),
);
if (diffedProperties.length) {
const formatted = diffedProperties
.map((segments) => Array.from(segments).join("."))
.join("\n");
throw new Error(`Lockfile drift detected:\n${formatted}`, { cause: error });
}
logger.warn(
"Permissible dependency differences detected. Run `npm install` to update the lockfile.",
);
}
return issues;
}
run()
.then((issues) => {
if (issues.length) {
logger.warn(`⚠️ ${issues.length} issue(s) detected:`);
for (const issue of issues) {
logger.warn(` - ${issue}`);
}
if (options.warn) {
logger.warn(
"The lockfile on disk has been regenerated. Review and commit the changes.",
);
process.exit(EXIT_DRIFT);
}
} else {
logger.info("✅ Lockfile is in sync.");
}
process.exit(0);
})
.catch((error) => reportAndExit(error, logger));
+20 -40
View File
@@ -1,9 +1,9 @@
#!/usr/bin/env node
/**
* @file Lints the installed Node.js and npm versions against the requirements specified in package.json.
* @file Lints the installed Node.js and pnpm versions against the requirements specified in package.json.
*
* Usage:
* lint-node [options] [directory]
* lint-runtime [options] [directory]
*
* Exit codes:
* 0 Versions are in sync
@@ -14,10 +14,9 @@ import * as assert from "node:assert/strict";
import { parseArgs } from "node:util";
import { ConsoleLogger } from "../../packages/logger-js/lib/node.js";
import { CommandError, parseCWD, reportAndExit } from "./utils/commands.mjs";
import { corepack } from "./utils/corepack.mjs";
import { parseCWD, reportAndExit } from "./utils/commands.mjs";
import { resolveRepoRoot } from "./utils/git.mjs";
import { compareVersions, findNPMPackage, loadJSON, node, npm, parseRange } from "./utils/node.mjs";
import { compareVersions, findNPMPackage, loadJSON, node, pnpm, parseRange } from "./utils/node.mjs";
const logger = ConsoleLogger.prefix("lint-runtime");
@@ -33,10 +32,10 @@ async function readRequirements(start) {
const nodeVersion = await node`--version`().then((output) => output.replace(/^v/, ""));
const requiredNpmVersion = packageJSONData.engines?.npm;
const requiredPnpmVersion = packageJSONData.engines?.pnpm;
const requiredNodeVersion = packageJSONData.engines?.node;
return { nodeVersion, requiredNpmVersion, requiredNodeVersion };
return { nodeVersion, requiredPnpmVersion, requiredNodeVersion };
}
async function main() {
@@ -50,47 +49,28 @@ async function main() {
logger.info(`cwd ${cwd}`);
logger.info(`repository ${repoRoot || "not found"}`);
const corepackVersion = await corepack`--version`().catch(() => null);
const useCorepack = !!corepackVersion;
logger.info(`corepack ${corepackVersion || "disabled"}`);
const pnpmVersion = await pnpm`--version`({ cwd }).catch((error) => {
logger.warn(`Failed to read pnpm version: ${error.message}`);
return null;
});
const npmVersion = await npm`--version`({ cwd, useCorepack })
.then((version) => {
logger.info(`npm${corepackVersion ? " (via Corepack)" : ""} ${version}`);
if (pnpmVersion) {
logger.info(`pnpm ${pnpmVersion}`);
}
return version;
})
.catch((error) => {
if (error instanceof CommandError && corepackVersion) {
logger.warn(`Failed to read npm version via Corepack ${error.message}`);
logger.info(`Attempting to read npm version directly without Corepack...`);
// Corepack might be misconfigured or outdated.
// Attempting a second read without Corepack can help us distinguish
// between a general npm issue and a Corepack-specific one.
return npm`--version`({ cwd }).then((version) => {
logger.info(`npm (direct) ${version}`);
return version;
});
}
throw error;
});
const { nodeVersion, requiredNpmVersion, requiredNodeVersion } = await readRequirements(cwd);
const { nodeVersion, requiredPnpmVersion, requiredNodeVersion } = await readRequirements(cwd);
logger.info(`node ${nodeVersion}`);
if (requiredNpmVersion) {
logger.info(`package.json npm ${requiredNpmVersion}`);
if (requiredPnpmVersion && pnpmVersion) {
logger.info(`package.json pnpm ${requiredPnpmVersion}`);
const { operator, version: required } = parseRange(requiredNpmVersion);
const result = compareVersions(npmVersion, required);
const { operator, version: required } = parseRange(requiredPnpmVersion);
const result = compareVersions(pnpmVersion, required);
assert.ok(
operator === ">=" ? result >= 0 : result === 0,
`npm version ${npmVersion} does not satisfy required version ${requiredNpmVersion}`,
`pnpm version ${pnpmVersion} does not satisfy required version ${requiredPnpmVersion}`,
);
}
@@ -109,7 +89,7 @@ async function main() {
main()
.then(() => {
logger.info("✅ Node.js and npm versions are in sync.");
logger.info("✅ Node.js and pnpm versions are in sync.");
process.exit(0);
})
.catch((error) => reportAndExit(error, logger));
-113
View File
@@ -1,113 +0,0 @@
#!/usr/bin/env node
/**
* @file Downloads the latest corepack tarball from the npm registry.
*/
import * as fs from "node:fs/promises";
import { parseArgs } from "node:util";
import { ConsoleLogger } from "../../packages/logger-js/lib/node.js";
import { $, parseCWD, reportAndExit } from "./utils/commands.mjs";
import { corepack, pullLatestCorepack, verifyPackageManagerIntegrity } from "./utils/corepack.mjs";
import { resolveRepoRoot } from "./utils/git.mjs";
import { findNPMPackage, loadJSON, npm } from "./utils/node.mjs";
/**
* @deprecated Remove after Corepack is merged into the monorepo and we can rely on the version specified in package.json.
*/
const FALLBACK_PACKAGE_MANAGER =
"npm@11.14.1+sha512.6a8a4d67478497a2dbc6815cad72e64c43f33413717e242756047d466241ab39bee61e691683a64658e94496ec5f1a1c05e4a5ec62dcc773280dfd949443a367";
const logger = ConsoleLogger.prefix("setup-corepack");
async function main() {
const parsedArgs = parseArgs({
options: {
force: {
type: "boolean",
default: false,
description: "Force re-download of corepack even if a version is already installed",
},
},
allowPositionals: true,
});
const cwdArg = parseCWD(parsedArgs.positionals);
const repoRoot = await resolveRepoRoot(cwdArg).catch(() => null);
const cwd = repoRoot || cwdArg;
const npmVersion = await npm`--version`({ cwd });
logger.info(`npm ${npmVersion}`);
const corepackVersion = await corepack`--version`({ cwd }).catch(() => null);
logger.info(`corepack ${corepackVersion || "not found"}`);
if (corepackVersion && !parsedArgs.values.force) {
logger.info("Corepack is already installed, skipping download (use --force to override)");
return;
}
await pullLatestCorepack(cwd);
await npm`install --force -g corepack@latest`({ cwd });
logger.info("Corepack installed successfully");
const { packageJSONPath } = await findNPMPackage(cwd);
logger.info(`Checking versions in ${packageJSONPath}`);
const packageJSONData = await loadJSON(packageJSONPath);
const packageManagerSpec = packageJSONData.packageManager || FALLBACK_PACKAGE_MANAGER;
const plusIndex = packageManagerSpec.indexOf("+");
const packageManager =
plusIndex === -1 ? packageManagerSpec : packageManagerSpec.slice(0, plusIndex);
const checksum = plusIndex === -1 ? "" : packageManagerSpec.slice(plusIndex + 1);
if (!checksum) {
throw new Error(
`Invalid packageManager field in package.json. Expected format "name@version+checksum". Got "${packageJSONData.packageManager}".`,
);
}
await verifyPackageManagerIntegrity(packageManager, checksum);
await $`corepack install -g ${packageManager}`({ cwd });
logger.info(`Setting up Corepack to use ${packageManager}...`);
const writablePackageJSON = await fs.access(packageJSONPath, fs.constants.W_OK).then(
() => true,
() => false,
);
/**
* @type {string}
*/
let subcommand;
if (!writablePackageJSON) {
if (!packageJSONData.packageManager) {
throw new Error(
`package.json is not writable and does not specify a packageManager field. Was the package.json file mounted via Docker?`,
);
}
subcommand = "install -g";
} else {
logger.info("package.json is writable");
subcommand = "use";
}
return $`corepack ${subcommand} ${packageManager}`({ cwd });
}
main()
.then(() => {
logger.info("Corepack setup completed successfully");
process.exit(0);
})
.catch((error) => reportAndExit(error, logger));
-165
View File
@@ -1,165 +0,0 @@
import * as crypto from "node:crypto";
import * as fs from "node:fs/promises";
import { join, relative } from "node:path";
import { ConsoleLogger } from "../../../packages/logger-js/lib/node.js";
import { $ } from "./commands.mjs";
const REGISTRY_BASE_URL = "https://registry.npmjs.org";
const REGISTRY_URL = `${REGISTRY_BASE_URL}/corepack`;
const OUTPUT_DIR = join(".corepack", "releases");
const OUTPUT_FILENAME = "latest.tgz";
export const corepack = $.bind("corepack");
/**
* Reads the installed Corepack version.
*
* @param {string} [cwd] The directory to run the command in.
* @returns {Promise<string | null>} The installed Corepack version
*/
export function readCorepackVersion(cwd = process.cwd()) {
return $`corepack --version`({ cwd });
}
const logger = ConsoleLogger.prefix("setup-corepack");
/**
* @param {string} baseDirectory
*/
export async function pullLatestCorepack(baseDirectory = process.cwd()) {
logger.info("Fetching corepack metadata from registry...");
const outputDir = join(baseDirectory, OUTPUT_DIR);
const outputPath = join(outputDir, OUTPUT_FILENAME);
const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(1000 * 60) });
if (!res.ok) {
throw new Error(`Failed to fetch registry metadata: ${res.status} ${res.statusText}`);
}
const metadata = await res.json();
const latestVersion = metadata["dist-tags"].latest;
const versionData = metadata.versions[latestVersion];
const tarballUrl = versionData.dist.tarball;
const expectedIntegrity = versionData.dist.integrity;
logger.info(`Latest corepack version: ${latestVersion}`);
logger.info(`Tarball URL: ${tarballUrl}`);
logger.info(`Expected integrity: ${expectedIntegrity}`);
logger.info({ url: tarballUrl }, "Downloading tarball...");
const tarballRes = await fetch(tarballUrl, {
signal: AbortSignal.timeout(1000 * 60),
});
if (!tarballRes.ok) {
throw new Error(
`Failed to download tarball: ${tarballRes.status} ${tarballRes.statusText}`,
);
}
const tarballBuffer = Buffer.from(await tarballRes.arrayBuffer());
logger.info("Verifying integrity...");
const [algorithm, expectedHash] = expectedIntegrity.split("-");
const actualHash = crypto.createHash(algorithm).update(tarballBuffer).digest("base64");
if (actualHash !== expectedHash) {
throw new Error(
`Integrity mismatch!\n Expected: ${expectedHash}\n Actual: ${actualHash}`,
);
}
logger.info("Integrity verified.");
await fs.mkdir(outputDir, { recursive: true });
await fs.writeFile(outputPath, tarballBuffer);
logger.info(`Saved to ${relative(baseDirectory, outputPath)}`);
logger.info(`corepack@${latestVersion} (${expectedIntegrity})`);
}
/**
* Downloads the tarball for a package manager spec from the npm registry and
* verifies it matches the expected Corepack-style checksum (`<algorithm>.<hex>`).
*
* Corepack's CLI does not enforce the `+integrity` suffix on the `packageManager`
* field when invoked via `corepack install -g`, so we verify the bytes ourselves
* before handing control back to Corepack.
*
* @param {string} packageManager E.g. `npm@11.14.1`.
* @param {string} expectedChecksum E.g. `sha512.6a8a4d67...`.
* @returns {Promise<void>}
*/
export async function verifyPackageManagerIntegrity(packageManager, expectedChecksum) {
const atIndex = packageManager.lastIndexOf("@");
if (atIndex <= 0) {
throw new Error(
`Invalid packageManager spec "${packageManager}". Expected "name@version".`,
);
}
const name = packageManager.slice(0, atIndex);
const version = packageManager.slice(atIndex + 1);
const separatorIndex = expectedChecksum.indexOf(".");
if (separatorIndex <= 0) {
throw new Error(
`Invalid checksum format "${expectedChecksum}". Expected "<algorithm>.<hex>".`,
);
}
const algorithm = expectedChecksum.slice(0, separatorIndex);
const expectedHex = expectedChecksum.slice(separatorIndex + 1).toLowerCase();
logger.info(`Verifying ${name}@${version} against ${algorithm} checksum...`);
const metadataUrl = `${REGISTRY_BASE_URL}/${encodeURIComponent(name)}/${encodeURIComponent(version)}`;
const metadataRes = await fetch(metadataUrl, {
signal: AbortSignal.timeout(1000 * 60),
});
if (!metadataRes.ok) {
throw new Error(
`Failed to fetch registry metadata for ${name}@${version}: ${metadataRes.status} ${metadataRes.statusText}`,
);
}
const versionData = await metadataRes.json();
const tarballUrl = versionData?.dist?.tarball;
if (!tarballUrl) {
throw new Error(`Registry response missing dist.tarball for ${name}@${version}.`);
}
logger.info({ url: tarballUrl }, "Downloading tarball...");
const tarballRes = await fetch(tarballUrl, {
signal: AbortSignal.timeout(1000 * 60),
});
if (!tarballRes.ok) {
throw new Error(
`Failed to download tarball: ${tarballRes.status} ${tarballRes.statusText}`,
);
}
const tarballBuffer = Buffer.from(await tarballRes.arrayBuffer());
const actualHex = crypto.createHash(algorithm).update(tarballBuffer).digest("hex");
if (actualHex !== expectedHex) {
throw new Error(
`Integrity mismatch for ${name}@${version}!\n Expected: ${algorithm}.${expectedHex}\n Actual: ${algorithm}.${actualHex}`,
);
}
logger.info(`Integrity verified for ${name}@${version}.`);
}
+7 -23
View File
@@ -10,19 +10,19 @@ import { dirname, join } from "node:path";
import { $ } from "./commands.mjs";
/**
* Find the nearest directory containing both package.json and package-lock.json,
* Find the nearest directory containing both package.json and pnpm-lock.yaml,
* starting from the given directory and walking upward.
*
* @param {string} start The directory to start searching from.
* @returns {Promise<{ packageJSONPath: string, packageLockPath: string }>}
* @throws {Error} If no co-located package.json and package-lock.json are found.
* @throws {Error} If no co-located package.json and pnpm-lock.yaml are found.
*/
export async function findNPMPackage(start) {
let currentDir = start;
while (currentDir !== dirname(currentDir)) {
const packageJSONPath = join(currentDir, "package.json");
const packageLockPath = join(currentDir, "package-lock.json");
const packageLockPath = join(currentDir, "pnpm-lock.yaml");
try {
await Promise.all([fs.access(packageJSONPath), fs.access(packageLockPath)]);
@@ -37,7 +37,7 @@ export async function findNPMPackage(start) {
currentDir = dirname(currentDir);
}
throw new Error(`No co-located package.json and package-lock.json found above ${start}`);
throw new Error(`No co-located package.json and pnpm-lock.yaml found above ${start}`);
}
/**
@@ -130,29 +130,13 @@ export function compareVersions(a, b) {
export const node = $.bind("node");
/**
* @typedef {object} NPMCommandOptions
* @property {boolean} [useCorepack] Whether to prefix the command with "corepack " to use Corepack's shims.
* @returns {Promise<string>}
*/
/**
* Runs an npm command and returns its stdout output as a string.
* Runs a pnpm command and returns its stdout output as a string.
*
* @param {TemplateStringsArray} strings
* @param {...unknown} expressions
* @returns {(options?: ExecOptions & NPMCommandOptions) => Promise<string>}
* @returns {(options?: ExecOptions) => Promise<string>}
*/
export function npm(strings, ...expressions) {
const subcommand = String.raw(strings, ...expressions);
return ({ useCorepack, ...options } = {}) => {
const command = [useCorepack ? "corepack" : "", "npm", subcommand]
.filter(Boolean)
.join(" ");
return $`${command}`(options);
};
}
export const pnpm = $.bind("pnpm");
/**
* Parses a version range string, stripping any leading >= and normalizing to three parts.
+4
View File
@@ -3,6 +3,10 @@
## Node
node_modules
# PNPM
pnpm-workspace.yaml
pnpm-lock.yaml
## Static Files
**/LICENSE
-21104
View File
File diff suppressed because it is too large Load Diff
+40 -94
View File
@@ -5,7 +5,7 @@
"private": true,
"scripts": {
"build": "wireit",
"build:sfe": "npm run build -w @goauthentik/web-sfe",
"build:sfe": "pnpm --filter @goauthentik/web-sfe run build",
"build-locales": "node scripts/build-locales.mjs",
"build-proxy": "wireit",
"bundler:watch": "node scripts/build-web.mjs --watch",
@@ -94,18 +94,18 @@
"@codemirror/lang-xml": "^6.1.0",
"@codemirror/legacy-modes": "^6.5.3",
"@codemirror/theme-one-dark": "^6.1.3",
"@eslint/js": "^9.39.3",
"@eslint/js": "^9.39.4",
"@floating-ui/dom": "^1.7.6",
"@formatjs/intl-listformat": "^8.3.8",
"@formatjs/intl-listformat": "^8.3.9",
"@fortawesome/fontawesome-free": "^7.2.0",
"@goauthentik/api": "0.0.0",
"@goauthentik/api": "link:packages/client-ts",
"@goauthentik/brand-assets": "^2.0.0",
"@goauthentik/core": "^1.0.0",
"@goauthentik/core": "workspace:*",
"@goauthentik/esbuild-plugin-live-reload": "^2.0.1",
"@goauthentik/eslint-config": "^1.3.0",
"@goauthentik/prettier-config": "^3.5.0",
"@goauthentik/tsconfig": "^1.0.9",
"@hcaptcha/types": "^1.1.0",
"@hcaptcha/types": "^1.2.0",
"@lit/context": "^1.1.6",
"@lit/localize": "^0.12.2",
"@lit/localize-tools": "^0.8.2",
@@ -118,7 +118,7 @@
"@openlayers-elements/core": "^0.4.0",
"@openlayers-elements/maps": "^0.4.0",
"@patternfly/elements": "^4.4.0",
"@patternfly/patternfly": "^4.224.2",
"@patternfly/patternfly": "^4.224.5",
"@playwright/test": "^1.60.0",
"@sentry/browser": "^10.56.0",
"@storybook/addon-docs": "^10.4.2",
@@ -128,15 +128,15 @@
"@types/codemirror": "^5.60.17",
"@types/grecaptcha": "^3.0.9",
"@types/guacamole-common-js": "^1.5.5",
"@types/node": "^25.7.0",
"@types/react": "^19.2.14",
"@types/node": "^25.9.1",
"@types/react": "^19.2.16",
"@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.60.1",
"@typescript-eslint/parser": "^8.60.0",
"@typescript-eslint/utils": "^8.60.0",
"@typescript/native-preview": "^7.0.0-dev.20260510.1",
"@typescript-eslint/parser": "^8.60.1",
"@typescript-eslint/utils": "^8.60.1",
"@typescript/native-preview": "7.0.0-dev.20260602.1",
"@vitest/browser": "^4.1.8",
"@vitest/browser-playwright": "^4.1.6",
"@vitest/browser-playwright": "^4.1.8",
"@webcomponents/webcomponentsjs": "^2.8.0",
"base64-js": "^1.5.1",
"change-case": "^5.4.4",
@@ -145,36 +145,36 @@
"codemirror": "^6.0.2",
"core-js": "^3.49.0",
"country-flag-icons": "^1.6.17",
"date-fns": "^4.1.0",
"date-fns": "^4.4.0",
"deepmerge-ts": "^7.1.5",
"dompurify": "^3.4.3",
"dompurify": "^3.4.7",
"esbuild": "^0.28.0",
"eslint": "^9.39.3",
"eslint": "^9.39.4",
"eslint-plugin-lit": "^2.3.1",
"eslint-plugin-wc": "^3.1.0",
"fuse.js": "^7.3.0",
"fuse.js": "^7.4.1",
"globals": "^17.6.0",
"guacamole-common-js": "^1.5.0",
"hastscript": "^9.0.1",
"knip": "^6.14.1",
"lex": "^2025.11.0",
"knip": "^6.15.0",
"lex": "workspace:*",
"lit": "^3.3.3",
"lit-analyzer": "^2.0.3",
"lit-element": "^4.2.2",
"lit-html": "^3.3.2",
"lit-html": "^3.3.3",
"md-front-matter": "^1.0.4",
"mermaid": "^11.15.0",
"node-domexception": "^2025.11.0",
"node-domexception": "workspace:*",
"npm-run-all": "^4.1.5",
"pino": "^10.3.1",
"pino-pretty": "^13.1.2",
"pino-pretty": "^13.1.3",
"playwright": "^1.60.0",
"prettier": "^3.8.3",
"prettier-plugin-packagejson": "^3.0.2",
"pseudolocale": "^2.2.0",
"rapidoc": "^9.3.8",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"rehype-highlight": "^7.0.2",
"rehype-mermaid": "^3.0.0",
"rehype-parse": "^9.0.1",
@@ -183,18 +183,18 @@
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
"remark-mdx-frontmatter": "^5.2.0",
"storybook": "^10.2.1",
"storybook": "^10.4.2",
"style-mod": "^4.1.3",
"stylelint": "^17.11.1",
"stylelint": "^17.12.0",
"trusted-types": "^2.0.0",
"ts-pattern": "^5.9.0",
"turnstile-types": "^1.2.3",
"type-fest": "^5.6.0",
"type-fest": "^5.7.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.3",
"typescript-eslint": "^8.60.1",
"unist-util-visit": "^5.1.0",
"vite": "^8.0.12",
"vitest": "^4.1.6",
"vite": "^8.0.16",
"vitest": "^4.1.8",
"webcomponent-qr-code": "^1.3.0",
"wireit": "^0.14.12",
"yaml": "^2.9.0"
@@ -203,14 +203,11 @@
"@esbuild/darwin-arm64": "^0.28.0",
"@esbuild/linux-arm64": "^0.28.0",
"@esbuild/linux-x64": "^0.28.0",
"@goauthentik/prettier-config-dev": "../packages/prettier-config",
"@rollup/rollup-darwin-arm64": "^4.57.1",
"@rollup/rollup-linux-arm64-gnu": "^4.57.1",
"@rollup/rollup-linux-x64-gnu": "^4.57.1"
"@goauthentik/prettier-config-dev": "link:../packages/prettier-config",
"@rollup/rollup-darwin-arm64": "^4.61.0",
"@rollup/rollup-linux-arm64-gnu": "^4.61.0",
"@rollup/rollup-linux-x64-gnu": "^4.61.0"
},
"workspaces": [
"./packages/*"
],
"wireit": {
"build": {
"command": "${NODE_RUNNER} scripts/build-web.mjs",
@@ -237,10 +234,10 @@
"./dist/styles/**"
],
"#comment": [
"`npm run build` and `npm run watch` are the most common ",
"`pnpm run build` and `pnpm run watch` are the most common ",
"commands you should be using when working on the front end",
"The files and output spec here expect you to use `npm run build --watch` ",
"instead of `npm run watch`. The former is more comprehensive, but ",
"The files and output spec here expect you to use `pnpm run build --watch` ",
"instead of `pnpm run watch`. The former is more comprehensive, but ",
"the latter is faster."
],
"env": {
@@ -294,66 +291,15 @@
},
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"pnpm": ">=11.5.1"
},
"devEngines": {
"runtime": {
"name": "node",
"onFail": "warn",
"version": ">=24"
},
"packageManager": {
"name": "npm",
"version": ">=11.14.1",
"onFail": "warn"
}
},
"packageManager": "npm@11.14.1+sha512.6a8a4d67478497a2dbc6815cad72e64c43f33413717e242756047d466241ab39bee61e691683a64658e94496ec5f1a1c05e4a5ec62dcc773280dfd949443a367",
"prettier": "./prettier.config.mjs",
"overrides": {
"@goauthentik/esbuild-plugin-live-reload": {
"esbuild": "$esbuild",
"typescript": "$typescript"
},
"@goauthentik/eslint-config": {
"typescript": "$typescript"
},
"@goauthentik/prettier-config": {
"prettier": "$prettier",
"prettier-plugin-packagejson": "$prettier-plugin-packagejson",
"typescript": "$typescript"
},
"@mrmarble/djangoql-completion": {
"lex": "$lex",
"lodash": "^4.18.1"
},
"@typescript-eslint/eslint-plugin": {
"typescript": "$typescript"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"@typescript-eslint/typescript-estree": {
"typescript": "$typescript"
},
"@typescript-eslint/utils": {
"typescript": "$typescript"
},
"format-imports": {
"eslint": "$eslint"
},
"node-fetch-commonjs": {
"node-domexception": "$node-domexception"
},
"rapidoc": {
"@apitools/openapi-parser": "0.0.37"
},
"tree-sitter": false,
"typescript-eslint": {
"typescript": "$typescript"
},
"wireit": {
"brace-expansion": "^1.1.14"
}
}
"packageManager": "pnpm@11.5.1+sha512.93f7b57422ea7068257235b4c16eb60762eb68e1dc23723199cc739043ea9be2c4143274a399d8c6defa2b1176226d9ca1c4b63482d6200c1a8fbaa78c1d1485",
"prettier": "./prettier.config.mjs"
}
+3 -4
View File
@@ -45,13 +45,12 @@
},
"dependencies": {
"@goauthentik/tsconfig": "^1.0.9",
"@types/node": "^25.7.0",
"@types/node": "^25.9.1",
"@types/semver": "^7.7.1",
"semver": "^7.7.4",
"semver": "^7.8.1",
"typescript": "^6.0.3"
},
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
}
}
+17 -17
View File
@@ -14,33 +14,33 @@
"./package.json": "./package.json"
},
"dependencies": {
"@goauthentik/api": "0.0.0",
"@goauthentik/core": "^1.0.0",
"@rollup/plugin-commonjs": "^29.0.2",
"@goauthentik/api": "link:../client-ts",
"@goauthentik/core": "workspace:*",
"@rollup/plugin-commonjs": "^29.0.3",
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-swc": "^0.4.0",
"@rollup/plugin-swc": "^0.4.1",
"@swc/cli": "^0.8.1",
"@swc/core": "^1.15.33",
"@swc/core": "^1.15.40",
"@webcomponents/template": "^1.5.1",
"base64-js": "^1.5.1",
"core-js": "^3.49.0",
"formdata-polyfill": "^2025.11.0",
"formdata-polyfill": "workspace:*",
"globby": "16.2.0",
"jquery": "^3.7.1",
"lit-html": "^1.4.1",
"rollup": "^4.57.1",
"rollup": "^4.61.0",
"weakmap-polyfill": "^2.0.4"
},
"optionalDependencies": {
"@swc/core-darwin-arm64": "^1.15.3",
"@swc/core-darwin-x64": "^1.15.3",
"@swc/core-linux-arm-gnueabihf": "^1.15.3",
"@swc/core-linux-arm64-gnu": "^1.15.3",
"@swc/core-linux-arm64-musl": "^1.15.3",
"@swc/core-linux-x64-gnu": "^1.15.3",
"@swc/core-linux-x64-musl": "^1.15.3",
"@swc/core-win32-arm64-msvc": "^1.15.3",
"@swc/core-win32-ia32-msvc": "^1.15.3",
"@swc/core-win32-x64-msvc": "^1.15.3"
"@swc/core-darwin-arm64": "^1.15.40",
"@swc/core-darwin-x64": "^1.15.40",
"@swc/core-linux-arm-gnueabihf": "^1.15.40",
"@swc/core-linux-arm64-gnu": "^1.15.40",
"@swc/core-linux-arm64-musl": "^1.15.40",
"@swc/core-linux-x64-gnu": "^1.15.40",
"@swc/core-linux-x64-musl": "^1.15.40",
"@swc/core-win32-arm64-msvc": "^1.15.40",
"@swc/core-win32-ia32-msvc": "^1.15.40",
"@swc/core-win32-x64-msvc": "^1.15.40"
}
}
+6 -1
View File
@@ -45,7 +45,12 @@ export async function createConfig() {
context: "window",
plugins: [
copyPlugin,
resolve({ browser: true }),
// `.ts`/`.tsx` so the linked `@goauthentik/api` source (resolved from
// its package `main`) and its relative imports resolve; swc transpiles them.
resolve({
browser: true,
extensions: [".mjs", ".js", ".json", ".node", ".ts", ".tsx"],
}),
commonjs(),
swc({
swc: {
+13591
View File
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
packages:
- "packages/*"
# client-ts is a symlink to the repo-root packages/client-ts; consuming it as
# a workspace member makes pnpm treat an out-of-root path as an importer, which
# it cannot represent in this lockfile. Link it as an external local package
# instead (see web + sfe package.json).
- "!packages/client-ts"
# pnpm's default isolated linker exposes packages strictly — only declared
# dependencies are visible. The web bundle relies on a handful of phantom
# deps that were hoisted by npm at the root of `node_modules` (lit-html
# internals, ol, mdast-util-to-string, etc.). Until each is added as an
# explicit dependency, fall back to the flat hoisted layout that mirrors
# npm's behavior.
nodeLinker: hoisted
overrides:
"@goauthentik/esbuild-plugin-live-reload>esbuild": "$esbuild"
"@goauthentik/esbuild-plugin-live-reload>typescript": "$typescript"
"@goauthentik/eslint-config>typescript": "$typescript"
"@goauthentik/prettier-config>prettier": "$prettier"
"@goauthentik/prettier-config>prettier-plugin-packagejson": "$prettier-plugin-packagejson"
"@goauthentik/prettier-config>typescript": "$typescript"
"@mrmarble/djangoql-completion>lex": "$lex"
"@mrmarble/djangoql-completion>lodash": "^4.18.1"
"@typescript-eslint/eslint-plugin>typescript": "$typescript"
"@typescript-eslint/parser>typescript": "$typescript"
"@typescript-eslint/typescript-estree>typescript": "$typescript"
"@typescript-eslint/utils>typescript": "$typescript"
"format-imports>eslint": "$eslint"
"node-fetch-commonjs>node-domexception": "$node-domexception"
"rapidoc>@apitools/openapi-parser": "0.0.37"
"typescript-eslint>typescript": "$typescript"
"wireit>brace-expansion": "^1.1.14"
# Allow-list of dependencies whose install/postinstall scripts may run.
# Everything else is blocked, replacing the prior `ignore-scripts=true` +
# `npm rebuild --foreground-scripts <pkg>` pattern from #20400. Each entry
# is audited at review time — adding a package here grants it arbitrary code
# execution at install.
onlyBuiltDependencies:
- chromedriver
- esbuild
- tree-sitter
- tree-sitter-json
- "@tree-sitter-grammars/tree-sitter-yaml"
# Explicit approval map for pnpm 11+. `true` = allowed (mirror
# onlyBuiltDependencies); `false` = explicitly declined to silence the
# "pending approval" prompt without running the install script.
allowBuilds:
"@scarf/scarf": false
"@swc/core": false
"@tree-sitter-grammars/tree-sitter-yaml": true
chromedriver: true
core-js: false
core-js-pure: false
esbuild: true
tree-sitter: true
tree-sitter-json: true
+7 -1
View File
@@ -3,7 +3,13 @@ build
out
coverage
.docusaurus
node_modules
help
static
scripts/docsmg/target/
## Node
node_modules
# PNPM
pnpm-workspace.yaml
pnpm-lock.yaml
+30 -18
View File
@@ -1,41 +1,53 @@
# Tag must track the root package.json `packageManager` version. ${BUILDPLATFORM}
# keeps the binary's arch aligned with the builder stage on cross-arch builds.
FROM --platform=${BUILDPLATFORM} ghcr.io/pnpm/pnpm:11.5.1@sha256:3cbdefab0d887dee497ddc8dfe6d871257317d69520fe30f9ccec0a84bde6e89 AS pnpm
FROM --platform=${BUILDPLATFORM} docker.io/library/node:26.3.0-trixie@sha256:e3ffe0cbaeebdcddbfe1ee7bca9b564a92863a8386d5b99a3d72677b3667b61d AS docs-builder
ENV NODE_ENV=production
WORKDIR /work
COPY --from=pnpm /opt/pnpm /opt/pnpm
ENV PATH="/opt/pnpm:${PATH}"
RUN --mount=type=bind,target=/work/package.json,src=./package.json \
--mount=type=bind,target=/work/package-lock.json,src=./package-lock.json \
--mount=type=bind,target=/work/scripts/node/,src=./scripts/node/ \
--mount=type=bind,target=/work/packages/logger-js/,src=./packages/logger-js/ \
--mount=type=bind,target=/work/packages/tsconfig/,src=./packages/tsconfig/ \
--mount=type=bind,target=/work/packages/eslint-config/,src=./packages/eslint-config/ \
--mount=type=bind,target=/work/packages/prettier-config/,src=./packages/prettier-config/ \
--mount=type=bind,target=/work/packages/docusaurus-config/,src=./packages/docusaurus-config/ \
--mount=type=bind,target=/work/website/package.json,src=./website/package.json \
--mount=type=bind,target=/work/website/package-lock.json,src=./website/package-lock.json \
node ./scripts/node/setup-corepack.mjs --force && \
--mount=type=bind,target=/work/website/pnpm-lock.yaml,src=./website/pnpm-lock.yaml \
node ./scripts/node/lint-runtime.mjs ./website
# Hoisted root install so `@goauthentik/docusaurus-config` resolves its own deps
# (e.g. `deepmerge-ts`) from /work/node_modules during the docs build; its source
# is bind-mounted read-only, so a per-package node_modules can't be written.
RUN --mount=type=bind,target=/work/.npmrc,src=./.npmrc \
--mount=type=bind,target=/work/package.json,src=./package.json \
--mount=type=bind,target=/work/package-lock.json,src=./package-lock.json \
--mount=type=bind,target=/work/scripts/node/,src=./scripts/node/ \
--mount=type=bind,target=/work/packages/logger-js/,src=./packages/logger-js/ \
--mount=type=bind,target=/work/packages/tsconfig/,src=./packages/tsconfig/ \
--mount=type=bind,target=/work/packages/eslint-config/,src=./packages/eslint-config/ \
--mount=type=bind,target=/work/packages/prettier-config/,src=./packages/prettier-config/ \
--mount=type=bind,target=/work/pnpm-lock.yaml,src=./pnpm-lock.yaml \
--mount=type=bind,target=/work/pnpm-workspace.yaml,src=./pnpm-workspace.yaml \
--mount=type=bind,target=/work/packages/docusaurus-config/package.json,src=./packages/docusaurus-config/package.json \
--mount=type=bind,target=/work/packages/esbuild-plugin-live-reload/package.json,src=./packages/esbuild-plugin-live-reload/package.json \
--mount=type=bind,target=/work/packages/eslint-config/package.json,src=./packages/eslint-config/package.json \
--mount=type=bind,target=/work/packages/logger-js/package.json,src=./packages/logger-js/package.json \
--mount=type=bind,target=/work/packages/prettier-config/package.json,src=./packages/prettier-config/package.json \
--mount=type=bind,target=/work/packages/tsconfig/package.json,src=./packages/tsconfig/package.json \
--mount=type=bind,target=/work/lifecycle/aws/package.json,src=./lifecycle/aws/package.json \
--mount=type=cache,id=pnpm-root,sharing=shared,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile --config.node-linker=hoisted \
--filter "@goauthentik/docusaurus-config"
RUN --mount=type=bind,target=/work/.npmrc,src=./.npmrc \
--mount=type=bind,target=/work/packages/docusaurus-config/,src=./packages/docusaurus-config/ \
--mount=type=bind,target=/work/website/package.json,src=./website/package.json \
--mount=type=bind,target=/work/website/package-lock.json,src=./website/package-lock.json \
--mount=type=bind,target=/work/website/pnpm-lock.yaml,src=./website/pnpm-lock.yaml \
--mount=type=bind,target=/work/website/pnpm-workspace.yaml,src=./website/pnpm-workspace.yaml \
--mount=type=bind,target=/work/website/vendored/detect-package-manager,src=./website/vendored/detect-package-manager \
--mount=type=bind,target=/work/website/docusaurus-theme/package.json,src=./website/docusaurus-theme/package.json \
--mount=type=bind,target=/work/website/api/package.json,src=./website/api/package.json \
--mount=type=bind,target=/work/website/integrations/package.json,src=./website/integrations/package.json \
--mount=type=bind,target=/work/website/docs/package.json,src=./website/docs/package.json \
--mount=type=cache,id=npm-website,sharing=shared,target=/root/.npm \
corepack npm ci && \
corepack npm ci --workspaces --include-workspace-root --prefix ./website
--mount=type=cache,id=pnpm-website,sharing=shared,target=/root/.local/share/pnpm/store \
pnpm --dir website install --frozen-lockfile
WORKDIR /work/website
@@ -46,7 +58,7 @@ COPY ./lifecycle/container/compose.yml /work/lifecycle/container/
COPY ./SECURITY.md /work/
RUN --mount=type=bind,target=/work/packages/docusaurus-config/,src=./packages/docusaurus-config/ \
corepack npm run build -w docs
pnpm run build
FROM docker.io/library/nginx:1.31.1-trixie@sha256:5aca99593157f4ae539a5dec1092a0ad8762f8e2eb1789085a13a0f5622369f6
LABEL org.opencontainers.image.authors="Authentik Security Inc." \
+2 -2
View File
@@ -10,11 +10,11 @@
[build]
base = "website"
package = "api"
command = "npm ci --prefix ../packages/docusaurus-config && npm run build -w api"
command = "pnpm --dir .. install --frozen-lockfile && pnpm install --frozen-lockfile && pnpm run build:api"
publish = "website/api/build"
[dev]
command = "npm start"
command = "pnpm start"
targetPort = 3000
[context.production.environment]
+7 -7
View File
@@ -5,7 +5,7 @@
"license": "MIT",
"private": true,
"scripts": {
"build": "run-s generate build:docusaurus",
"build": "docusaurus gen-api-docs all && docusaurus build",
"build:docusaurus": "docusaurus build",
"clean": "run-s generate:clean docusaurus:clean",
"docusaurus": "docusaurus",
@@ -29,12 +29,12 @@
"@docusaurus/theme-common": "^3.10.1",
"@docusaurus/tsconfig": "^3.10.1",
"@docusaurus/types": "^3.10.1",
"@goauthentik/docusaurus-config": "../../packages/docusaurus-config",
"@goauthentik/docusaurus-theme": "*",
"@goauthentik/tsconfig": "^1.0.7",
"@goauthentik/docusaurus-config": "link:../../packages/docusaurus-config",
"@goauthentik/docusaurus-theme": "workspace:*",
"@goauthentik/tsconfig": "^1.0.9",
"@mdx-js/react": "^3.1.1",
"@types/postman-collection": "^3.5.11",
"@types/react": "^19.2.14",
"@types/react": "^19.2.16",
"@types/react-dom": "^19.2.3",
"docusaurus-plugin-openapi-docs": "^5.0.2",
"docusaurus-theme-openapi-docs": "^5.0.2",
@@ -43,8 +43,8 @@
"postman-code-generators": "^2.1.1",
"postman-collection": "^5.3.0",
"prism-react-renderer": "^2.4.1",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"typescript": "^6.0.3"
},
"optionalDependencies": {
+2 -2
View File
@@ -10,11 +10,11 @@
[build]
base = "website"
package = "docs"
command = "npm ci --prefix ../packages/docusaurus-config && npm run build -w docs"
command = "pnpm --dir .. install --frozen-lockfile && pnpm install --frozen-lockfile && pnpm run build"
publish = "docs/build"
[dev]
command = "npm start"
command = "pnpm start"
targetPort = 3000
[context.production.environment]
+10 -11
View File
@@ -4,7 +4,7 @@
"license": "MIT",
"private": true,
"scripts": {
"build": "run-s build:docusaurus build:copy",
"build": "docusaurus build && cp -r ./build/ ../build/",
"build:copy": "cp -r ./build/ ../build/",
"build:docusaurus": "docusaurus build",
"check-types": "tsc -b .",
@@ -20,24 +20,23 @@
"@docusaurus/theme-mermaid": "^3.10.1",
"@docusaurus/tsconfig": "^3.10.1",
"@docusaurus/types": "^3.10.1",
"@goauthentik/docusaurus-config": "../../packages/docusaurus-config",
"@goauthentik/docusaurus-theme": "*",
"@iconify-json/fa7-regular": "^1.2.2",
"@iconify-json/fa7-solid": "^1.2.3",
"@goauthentik/docusaurus-config": "link:../../packages/docusaurus-config",
"@goauthentik/docusaurus-theme": "workspace:*",
"@iconify-json/fa7-regular": "^1.2.3",
"@iconify-json/fa7-solid": "^1.2.4",
"@iconify-json/fluent-mdl2": "^1.2.1",
"@iconify-json/mdi": "^1.2.3",
"@mdx-js/react": "^3.1.1",
"@types/react": "^19.2.14",
"@types/react": "^19.2.16",
"@types/react-dom": "^19.2.3",
"prism-react-renderer": "^2.4.1",
"react": "^19.2.6",
"react": "^19.2.7",
"react-before-after-slider-component": "^1.1.8",
"react-dom": "^19.2.6",
"react-dom": "^19.2.7",
"typescript": "^6.0.3",
"unist-util-visit": "^5.0.0"
"unist-util-visit": "^5.1.0"
},
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
}
}
+2 -2
View File
@@ -28,7 +28,7 @@
},
"dependencies": {
"@docusaurus/preset-classic": "^3.10.1",
"@goauthentik/docusaurus-config": "../../packages/docusaurus-config",
"@goauthentik/docusaurus-config": "link:../../packages/docusaurus-config",
"@types/semver": "^7.7.1",
"clsx": "^2.1.1",
"fast-glob": "^3.3.3",
@@ -36,6 +36,6 @@
"remark-github": "^12.0.0",
"semver": "^7.8.2",
"typescript": "^6.0.3",
"unist-util-visit": "^5.0.0"
"unist-util-visit": "^5.1.0"
}
}
+2 -2
View File
@@ -10,11 +10,11 @@
[build]
base = "website"
package = "integrations"
command = "npm ci --prefix ../packages/docusaurus-config && npm run build -w integrations"
command = "pnpm --dir .. install --frozen-lockfile && pnpm install --frozen-lockfile && pnpm run build:integrations"
publish = "integrations/build"
[dev]
command = "npm start"
command = "pnpm start"
targetPort = 3000
[context.production.environment]
+7 -8
View File
@@ -4,7 +4,7 @@
"license": "MIT",
"private": true,
"scripts": {
"build": "run-s build:docusaurus",
"build": "docusaurus build",
"build:docusaurus": "docusaurus build",
"clear": "docusaurus clear",
"docusaurus": "docusaurus",
@@ -19,18 +19,17 @@
"@docusaurus/theme-mermaid": "^3.10.1",
"@docusaurus/tsconfig": "^3.10.1",
"@docusaurus/types": "^3.10.1",
"@goauthentik/docusaurus-config": "../../packages/docusaurus-config",
"@goauthentik/docusaurus-theme": "*",
"@goauthentik/docusaurus-config": "link:../../packages/docusaurus-config",
"@goauthentik/docusaurus-theme": "workspace:*",
"@mdx-js/react": "^3.1.1",
"@types/react": "^19.2.14",
"@types/react": "^19.2.16",
"@types/react-dom": "^19.2.3",
"prism-react-renderer": "^2.4.1",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"typescript": "^6.0.3"
},
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"node": ">=24"
}
}
-25901
View File
File diff suppressed because it is too large Load Diff
+15 -68
View File
@@ -4,28 +4,27 @@
"license": "MIT",
"private": true,
"scripts": {
"build": "npm run build -w docs",
"build:api": "npm run build -w api",
"build:integrations": "npm run build -w integrations",
"build": "pnpm --filter \"./docs\" run build",
"build:api": "pnpm --filter \"./api\" run build",
"build:integrations": "pnpm --filter \"./integrations\" run build",
"check-types": "tsc -b",
"docusaurus": "docusaurus",
"lint": "eslint --fix .",
"lint-check": "eslint --max-warnings 0 .",
"prettier": "prettier --write .",
"prettier-check": "npm run prettier-prepare && prettier --check .",
"prettier-prepare": "npm ci --prefix ../packages/prettier-config",
"start": "npm start -w docs",
"prettier-check": "prettier --check .",
"start": "pnpm --filter \"./docs\" run start",
"test": "node --test"
},
"dependencies": {
"@eslint/js": "^9.39.3",
"@goauthentik/eslint-config": "../packages/eslint-config",
"@goauthentik/prettier-config": "../packages/prettier-config",
"@goauthentik/tsconfig": "../packages/tsconfig",
"@types/node": "^25.7.0",
"@eslint/js": "^9.39.4",
"@goauthentik/eslint-config": "link:../packages/eslint-config",
"@goauthentik/prettier-config": "link:../packages/prettier-config",
"@goauthentik/tsconfig": "link:../packages/tsconfig",
"@types/node": "^25.9.1",
"deepmerge-ts": "^7.1.5",
"escape-string-regexp": "^5.0.0",
"eslint": "^9.39.3",
"eslint": "^9.39.4",
"netlify-plugin-cache": "^1.0.3",
"netlify-redirect-parser": "^14.4.0",
"npm-run-all": "^4.1.5",
@@ -33,7 +32,7 @@
"prettier": "^3.8.3",
"prettier-plugin-packagejson": "^3.0.2",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.3"
"typescript-eslint": "^8.60.1"
},
"optionalDependencies": {
"@rspack/binding-darwin-arm64": "2.0.6",
@@ -49,69 +48,17 @@
"lightningcss-linux-arm64-gnu": "1.32.0",
"lightningcss-linux-x64-gnu": "1.32.0"
},
"workspaces": [
"vendored/*",
"docusaurus-theme",
"api",
"integrations",
"docs"
],
"engines": {
"node": ">=24",
"npm": ">=11.14.1"
"pnpm": ">=11.5.1"
},
"devEngines": {
"runtime": {
"name": "node",
"onFail": "error",
"version": ">=24"
},
"packageManager": {
"name": "npm",
"version": ">=11.6.2",
"onFail": "warn"
}
},
"packageManager": "npm@11.14.1+sha512.6a8a4d67478497a2dbc6815cad72e64c43f33413717e242756047d466241ab39bee61e691683a64658e94496ec5f1a1c05e4a5ec62dcc773280dfd949443a367",
"prettier": "@goauthentik/prettier-config",
"overrides": {
"@goauthentik/docusaurus-config": {
"react": "$react",
"react-dom": "$react-dom",
"@docusaurus/theme-common": "$@docusaurus/theme-common"
},
"@goauthentik/eslint-config": {
"typescript": "$typescript"
},
"@goauthentik/prettier-config": {
"prettier": "$prettier",
"prettier-plugin-packagejson": "$prettier-plugin-packagejson"
},
"@typescript-eslint/parser": {
"typescript": "$typescript"
},
"@typescript-eslint/utils": {
"typescript": "$typescript"
},
"docusaurus-theme-openapi-docs": {
"postman-code-generators": {
".": "^2.1.1",
"detect-package-manager": "file:./vendored/detect-package-manager",
"shelljs": "0.10.0"
}
},
"format-imports": {
"eslint": "$eslint"
},
"lodash": "^4.18.1",
"postman-code-generators": {
"detect-package-manager": "file:./vendored/detect-package-manager",
"shelljs": "0.10.0"
},
"postman-collection": "^5.3.0",
"typescript-eslint": {
"typescript": "$typescript"
},
"uuid": "^14.0.0"
}
"packageManager": "pnpm@11.5.1+sha512.93f7b57422ea7068257235b4c16eb60762eb68e1dc23723199cc739043ea9be2c4143274a399d8c6defa2b1176226d9ca1c4b63482d6200c1a8fbaa78c1d1485",
"prettier": "@goauthentik/prettier-config"
}
+19822
View File
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
packages:
- "vendored/*"
- "docusaurus-theme"
- "api"
- "integrations"
- "docs"
# Docusaurus and several first-party plugins rely on phantom deps
# (notably `@docusaurus/utils`) that npm hoisted. Until each is added as an
# explicit dependency, fall back to the flat hoisted layout that mirrors
# npm's behavior.
nodeLinker: hoisted
overrides:
"@goauthentik/docusaurus-config>react": "^19.2.6"
"@goauthentik/docusaurus-config>react-dom": "^19.2.6"
"@goauthentik/docusaurus-config>@docusaurus/theme-common": "^3.10.1"
"@goauthentik/eslint-config>typescript": "$typescript"
"@goauthentik/prettier-config>prettier": "$prettier"
"@goauthentik/prettier-config>prettier-plugin-packagejson": "$prettier-plugin-packagejson"
"@typescript-eslint/parser>typescript": "$typescript"
"@typescript-eslint/utils>typescript": "$typescript"
"docusaurus-theme-openapi-docs>postman-code-generators": "^2.1.1"
"docusaurus-theme-openapi-docs>detect-package-manager": "workspace:*"
"docusaurus-theme-openapi-docs>shelljs": "0.10.0"
"format-imports>eslint": "$eslint"
"lodash": "^4.18.1"
"postman-code-generators>detect-package-manager": "workspace:*"
"postman-code-generators>shelljs": "0.10.0"
"postman-collection": "^5.3.0"
"typescript-eslint>typescript": "$typescript"
"uuid": "^14.0.0"
# Allow-list of dependencies whose install/postinstall scripts may run.
# Everything else is blocked, replacing the prior `ignore-scripts=true` +
# `npm rebuild --foreground-scripts <pkg>` pattern from #20400. Each entry
# is audited at review time — adding a package here grants it arbitrary code
# execution at install.
onlyBuiltDependencies:
- "@parcel/watcher"
- "@swc/core"
# Explicit approval map for pnpm 11+. `true` = allowed (mirror
# onlyBuiltDependencies); `false` = explicitly declined to silence the
# "pending approval" prompt without running the install script.
allowBuilds:
"@parcel/watcher": true
"@swc/core": true
core-js: false
postman-code-generators: false
minimumReleaseAgeExclude:
- js-yaml@4.1.1
- serialize-javascript@7.0.3
- yaml@1.10.3
- serialize-javascript@7.0.5