Files
authentik/packages/prettier-config/lib/imports.js
Teffen Ellis a8e765257e web: Update Deprecated NPM Packages (#18335)
* core: Bump packages.

* Bump Live Reload dependencies.

* Bump tsconfig.

* Bum ESLint config deps. Fix formatting.

* Bump Prettier deps. Fix ESlint config.

* Bump live reload deps. Fix linter.

* Bump website deps.

* web: Update dependencies. Fix Playwright issues.

* Fix deprecations.

* Fix linter warnings.

* Fix override, run audit.

* Fix import path.

* Tidy types.

* Format.

* Update ignore patterns.

* Fix import path.

* Update deps. Clean up workspace linting.

* Update deps, options.

* Hide icons in navbar.

* Format.

* Remove deprecated option.

* Use relative packages.

* Add scripts. Tidy.

* Bump engines.

* Clarify order.

* Clarify order. Install base deps.

* Format.

* Fix stale user during tests.

* Fix runtime errors.

* Fix redirect during tests, UI change.

* web: Fix danger button hover background color.

* web: Adjust colors, padding.

* web: Fix sidebar colors, padding.

* Fix alignment.

* Fix background contrast.
2025-11-24 13:31:42 -05:00

184 lines
4.4 KiB
JavaScript

/**
* @file Prettier import plugin.
*
* @import { Plugin, ParserOptions } from "prettier";
*/
import { createRequire } from "node:module";
import { formatSourceFromFile } from "format-imports";
import { parsers as babelParsers } from "prettier/plugins/babel";
import { parsers as typescriptParsers } from "prettier/plugins/typescript";
const require = createRequire(`${process.cwd()}/`);
const AK_KEEP_UNUSED_IMPORTS = !!process.env.AK_KEEP_UNUSED_IMPORTS;
/**
* @param {string} name
* @returns {string | null}
*/
function resolveModule(name) {
try {
return require.resolve(name);
} catch (_error) {
return null;
}
}
const webSubmodules = [
// ---
"common",
"elements",
"components",
"user",
"admin",
"flow",
];
/**
* Ensure that every import without an extension adds one.
* @param {string} input
* @returns {string}
*/
function normalizeExtensions(input) {
return input.replace(/(?:import|from)\s*["']((?:\.\.?\/).*?)(?<!\.\w+)["']/gm, (line, path) => {
return line.replace(path, `${path}.js`);
});
}
/**
* @param {string} filepath
* @param {string} input
* @returns {string}
*/
function normalizeImports(filepath, input) {
let output = input;
// Replace all TypeScript imports with the paths resolved by Node/Browser import maps.
for (const submodule of webSubmodules) {
const legacyPattern = new RegExp(
[
// ---
`(?:import|from)`,
`\\(?\\n?\\s*`,
`"(?<suffix>@goauthentik/${submodule}/)`,
`(?<path>[^"'.]+)`,
`(?:.[^"']+)?["']`,
`\\n?\\s*\\)?;`,
].join(""),
"gm",
);
output = output.replace(
legacyPattern,
/**
* @param {string} line
* @param {string} suffix
* @param {string} path
*/
(line, suffix, path) => {
const exported = `@goauthentik/web/${submodule}/${path}`;
let imported = `#${submodule}/${path}`;
let module = resolveModule(`${exported}.ts`);
if (!module) {
module = resolveModule(`${exported}/index.ts`);
imported += "/index";
}
if (imported.endsWith(".css")) {
imported += ".js";
}
if (!module) {
console.warn(`\nCannot resolve module ${exported} from ${filepath}`, {
line,
path,
exported,
imported,
module,
});
process.exit(1);
}
return (
line
// ---
.replace(suffix + path, imported)
.replace(`${imported}.js`, imported)
);
},
);
}
return output;
}
const useLegacyCleanup = process.env.AK_FIX_LEGACY_IMPORTS === "true";
/**
* @param {string} input
* @param {ParserOptions} options
*/
const preprocess = (input, { filepath, printWidth }) => {
if (input?.includes("ts-import-sorter: disable")) {
return input;
}
let output = input;
if (output.startsWith("/**\n")) {
output = output.replace(/(^\s\*\/\n)(import)/m, "$1\n$2");
}
if (useLegacyCleanup) {
output = normalizeExtensions(input);
output = normalizeImports(filepath, output);
}
const value = formatSourceFromFile.sync(output, filepath, {
nodeProtocol: "always",
maxLineLength: printWidth,
wrappingStyle: "prettier",
keepUnused: AK_KEEP_UNUSED_IMPORTS ? [".*"] : [],
groupRules: [
"^node:",
"^[./]",
...webSubmodules.map((submodule) => `^(@goauthentik/|#)${submodule}.+`),
"^#.+",
"^@goauthentik.+",
{}, // Other imports.
"^(@?)lit(.*)$",
"\\.css$",
"^@goauthentik/api$",
],
});
return value || input;
};
/**
* @type {Plugin}
*/
const importsPlugin = {
parsers: {
typescript: {
...typescriptParsers.typescript,
preprocess,
},
babel: {
...babelParsers.babel,
preprocess,
},
},
};
export default importsPlugin;