Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat: is valid class name worker
  • Loading branch information
francoismassart committed Jul 11, 2025
commit edd276e59b13241a886cb3de517aa8d3f8557d18
6 changes: 6 additions & 0 deletions src/util/tailwindcss-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ export const getSortedClassNamesWorker: (
) => Array<string> = createSyncFn(
require.resolve("./worker/get-sorted-class-names.mjs")
);
export const isValidClassNameWorker: (
cssConfigPath: string,
className: string
) => boolean = createSyncFn(
require.resolve("./worker/is-valid-class-name.mjs")
);
12 changes: 6 additions & 6 deletions src/util/tailwindcss-api/worker/get-sorted-class-names.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ test(`Sort classnames based on "normal.css"`, () => {
"lg:flex",
"block",
"top-0",
"unkown",
"unknown",
"text-red-100",
];
const sorted = getSortedClassNamesWorker(path, unorderdClassNames);
// Unknown classnames should be first
expect(sorted[0]).toBe("unkown");
expect(sorted[0]).toBe("unknown");
// The rest should be sorted as well
expect(sorted).toStrictEqual([
"unkown",
"unknown",
"top-0",
"block",
"text-red-100",
Expand All @@ -28,16 +28,16 @@ test(`Sort "tw:" prefixed classnames based on "tiny-prefixed.css"`, () => {
const path = require.resolve("../../../../tests/stubs/css/tiny-prefixed.css");
const unorderdClassNames = [
"tw:flex",
"tw:unkown",
"tw:unknown",
"tw:hover:text-tiny",
"tw:top-0",
];
const sorted = getSortedClassNamesWorker(path, unorderdClassNames);
// Unknown classnames should be first
expect(sorted[0]).toBe("tw:unkown");
expect(sorted[0]).toBe("tw:unknown");
// The rest should be sorted as well
expect(sorted).toStrictEqual([
"tw:unkown",
"tw:unknown",
"tw:top-0",
"tw:flex",
"tw:hover:text-tiny",
Expand Down
40 changes: 40 additions & 0 deletions src/util/tailwindcss-api/worker/is-valid-class-name.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* ⚠️ This is a worker script which is ran in node's `worker_threads`.
* 🤓 This means that it is not executed in the main thread, but in a separate thread.
* 😅 Because of this, expect some disturbances, like:
* - `console.log` won't work `vitest`... (seems to work with `jest`).
* - You cannot pass complex objects as arguments, only serializable ones.
* - You cannot retun complex objects, only serializable ones.
* - e.g. You cannot return the `utils.context` directly, but you can return some of its properties...
*
* ℹ️ It uses the `*.mjs` extension to indicate that it is an ES module.
* ✅ We still check the syntax with TypeScript, but it is not a TypeScript file.
*/

// @ts-check

import { runAsWorker } from "synckit";
import { TailwindUtils } from "tailwind-api-utils";

runAsWorker(
async (
/**
* @type {string} The path to the Tailwind CSS config file
*/
cssConfigPath,
/**
* @type {string} Class name to validate
*/
className
) => {
const utils = new TailwindUtils();
await utils.loadConfigV4(cssConfigPath);
if (!utils.context) {
throw new Error(
`Failed to load the Tailwind CSS theme using: "${cssConfigPath}"`
);
}
const sorted = await utils.isValidClassName(className);
return sorted;
}
);
22 changes: 22 additions & 0 deletions src/util/tailwindcss-api/worker/is-valid-class-name.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { expect, test } from "vitest";

import { isValidClassNameWorker } from "..";

test(`Validate classnames based on "normal.css"`, () => {
const path = require.resolve("../../../../tests/stubs/css/normal.css");
// Unknown classnames should be invalid
expect(isValidClassNameWorker(path, "unknown")).toBe(false);
// Known classnames should be valid
expect(isValidClassNameWorker(path, "flex")).toBe(true);
});

test(`Validate "tw:" prefixed classnames based on "tiny-prefixed.css"`, () => {
const path = require.resolve("../../../../tests/stubs/css/tiny-prefixed.css");
// Unknown classnames should be invalid
expect(isValidClassNameWorker(path, "tw:unknown")).toBe(false);
// Known classnames should be valid
expect(isValidClassNameWorker(path, "tw:flex")).toBe(true);
expect(isValidClassNameWorker(path, "tw:border-tiny")).toBe(true);
// Unprefixed classnames should be invalid
expect(isValidClassNameWorker(path, "flex")).toBe(false);
});