Skip to content

Commit

Permalink
💠 Add kdjs type types
Browse files Browse the repository at this point in the history
  • Loading branch information
KimlikDAO-bot committed Feb 5, 2025
1 parent 523ac1d commit eb2dfa8
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 29 deletions.
11 changes: 6 additions & 5 deletions kastro/transpiler/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DomIdMapper } from "./domIdMapper";
* default: !Object<string, string>
* }}
*/
const CssModule = {};
export const CssModule = {};

/** @const {!RegExp} */
const ExportAsPattern = /@export\s*{(.*)}/;
Expand Down Expand Up @@ -138,7 +138,7 @@ const getEnum = (file, content, domIdMapper) => {
* @param {!DomIdMapper} domIdMapper
* @return {string} js code that exports the enum
*/
const transpileCss = (file, content, domIdMapper) => {
const transpile = (file, content, domIdMapper) => {
return "\n/** @enum {string} */\nconst Style = "
+ getEnum(file, content, domIdMapper)
+ ";\n\nexport default Style;\n";
Expand All @@ -156,7 +156,7 @@ const transpileCss = (file, content, domIdMapper) => {
* enumEntries: (!Object<string, string>)
* }}
*/
const minifyCss = (file, content, domIdMapper) => {
const minify = (file, content, domIdMapper) => {
/** @const {string} */
const context = `${splitFullExt(file)[0]}.jsx`;
/** @const {!csstree.StyleSheet} */
Expand Down Expand Up @@ -234,8 +234,9 @@ const minifyCss = (file, content, domIdMapper) => {
};

export default {
EnumModule: CssModule,
getEnum,
minifyCss,
minify,
selectorToEnumKey,
transpileCss
transpile
};
4 changes: 2 additions & 2 deletions kastro/transpiler/jsx.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const SpecifierState = {
* @param {DomIdMapper} domIdMapper
* @return {string} The transpiled js file
*/
const transpileJsx = (isEntry, file, content, domIdMapper) => {
const transpile = (isEntry, file, content, domIdMapper) => {
/** @const {!Array<!acorn.Comment>} */
const comments = [];
/** @const {!Array<Update>} */
Expand Down Expand Up @@ -268,4 +268,4 @@ const transpileJsx = (isEntry, file, content, domIdMapper) => {
return update(content, updates);
};

export default { transpileJsx };
export default { transpile };
144 changes: 144 additions & 0 deletions kastro/transpiler/test/css.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { describe, expect, it } from "bun:test";
import { importCode } from "../../../util/reflection";
import css, { CssModule } from "../css";
import { GlobalMapper } from "../domIdMapper";

describe("selectorToEnumKey", () => {
it("should convert selector to enum key", () => {
expect(css.selectorToEnumKey("blue-button")).toBe("BlueButton");
expect(css.selectorToEnumKey("blue_button")).toBe("BlueButton");
expect(css.selectorToEnumKey("blueButton")).toBe("blueButton");
expect(css.selectorToEnumKey("PascalCase")).toBe("PascalCase");
expect(css.selectorToEnumKey("a__PascalCase")).toBe("APascalCase");
expect(css.selectorToEnumKey("a-PascalCase")).toBe("APascalCase");
expect(css.selectorToEnumKey("mina")).toBe("mina");
expect(css.selectorToEnumKey("x1")).toBe("x1");
});
});

describe("transpileCss", () => {
it("should parse exported selectors", async () => {
const domIdMapper = new GlobalMapper();
const cssCode = css.transpile("test.jsx", `
body { color: red; }
/** @export */
.blue-button { color: blue; }
/** @export */ .green-button { color: green; }
`, domIdMapper);

/** @const {CssModule} */
const cssModule = /** @type {CssModule} */(await importCode(cssCode));
expect(cssModule.default).toEqual({
"BlueButton": domIdMapper.map("mpa", "test.jsx", "blue-button"),
"GreenButton": domIdMapper.map("mpa", "test.jsx", "green-button"),
});
});
it("should parse export as directives", async () => {
const domIdMapper = new GlobalMapper();
const cssCode = css.transpile("test.jsx", `
body { color: red; }
/** @export {ButtonWhichIsBlue} */
.blue-button { color: blue; }
`, domIdMapper);

const cssModule = /** @type {CssModule} */(await importCode(cssCode));
expect(cssModule.default).toEqual({
"ButtonWhichIsBlue": domIdMapper.map("mpa", "test.jsx", "blue-button"),
});
});
it("should parse domNamespace directive", async () => {
const domIdMapper = new GlobalMapper();
const cssCode = css.transpile("test.jsx", `
body { color: red; }
/** @domNamespace {iframe1} */
/** @export */
.blue-button { color: blue; }
`, domIdMapper);

const cssModule = /** @type {CssModule} */(await importCode(cssCode));
expect(cssModule.default).toEqual({
"BlueButton": domIdMapper.map("iframe1", "test.jsx", "blue-button"),
});
});
it("should throw on retroactive domNamespace directive", () => {
const domIdMapper = new GlobalMapper();
expect(() => css.transpile("test.jsx", `
body { color: red; }
/** @export */
.blue-button { color: blue; }
/** @domNamespace {iframe1} */
/** @export */
.green-button { color: green; }
`, domIdMapper)).toThrow();
});
it("should handle pseudo-classes", async () => {
const domIdMapper = new GlobalMapper();
const cssCode = css.transpile("test.jsx", `
/** @export {GreenishButton} */
.green-button:hover { color: green; }
/** @export */
.blue-button:active { color: blue; }
`, domIdMapper);
const cssModule = /** @type {CssModule} */(await importCode(cssCode));
expect(cssModule.default).toEqual({
"GreenishButton": domIdMapper.map("mpa", "test.jsx", "green-button"),
"BlueButton": domIdMapper.map("mpa", "test.jsx", "blue-button"),
});
});
});

describe("minifyCss", () => {
it("should create enum entries for all selectors", () => {
const domIdMapper = new GlobalMapper();
const minified = css.minify("test.jsx", `
/** @domNamespace {iframe1} */
.blue-button > .green-button, .red-button { color: blue; }
`, domIdMapper);

expect(minified.enumEntries["BlueButton"])
.toBe(domIdMapper.map("iframe1", "test.jsx", "blue-button"));
expect(minified.enumEntries["GreenButton"])
.toBe(domIdMapper.map("iframe1", "test.jsx", "green-button"));
expect(minified.enumEntries["RedButton"])
.toBe(domIdMapper.map("iframe1", "test.jsx", "red-button"));
});

it("should handle pseudo-classes", () => {
const domIdMapper = new GlobalMapper();
const minified = css.minify("test.jsx", `
/** @domNamespace {iframe1} */
.blue-button:active > .green-button:hover, .red-button { color: blue; }
`, domIdMapper);

expect(minified.enumEntries["BlueButton"])
.toBe(domIdMapper.map("iframe1", "test.jsx", "blue-button"));
expect(minified.enumEntries["GreenButton"])
.toBe(domIdMapper.map("iframe1", "test.jsx", "green-button"));
expect(minified.enumEntries["RedButton"])
.toBe(domIdMapper.map("iframe1", "test.jsx", "red-button"));
});

it("should respect export as directives", () => {
const domIdMapper = new GlobalMapper();
const minified = css.minify("test.jsx", `
/**
* @domNamespace {spa}
* @export {ButtonWhichIsBlue}
*/
.blue-button { color: blue; }
`, domIdMapper);

expect(minified.enumEntries["ButtonWhichIsBlue"])
.toBe(domIdMapper.map("spa", "test.jsx", "blue-button"));
});

it("should throw on retroactive export as directive", () => {
const domIdMapper = new GlobalMapper();
expect(() => css.minify("test.jsx", `
/** @export {ButtonWhichIsBlue} */
.green-button { color: green; }
/** @domNamespace {iframe1} */
.blue-button { color: blue; }
`, domIdMapper)).toThrow();
});
});
10 changes: 5 additions & 5 deletions kastro/transpiler/transpiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import jsx from "./jsx";
const Mapper = new GlobalMapper();

const minifyCss = (content, file) =>
css.minifyCss(file, content, Mapper);
css.minify(file, content, Mapper);

const transpileCss = (content, file) =>
css.transpileCss(file, content, Mapper);
css.transpile(file, content, Mapper);

const transpileJsx = (content, file, isEntry) =>
jsx.transpileJsx(isEntry, file, content, Mapper);
jsx.transpile(isEntry, file, content, Mapper);

const transpile = (content, file, isEntry) => file.endsWith(".jsx")
? transpileJsx(content, file, isEntry)
: transpileCss(content, file);
? jsx.transpile(isEntry, file, content, Mapper)
: css.transpile(file, content, Mapper)

export {
minifyCss,
Expand Down
38 changes: 37 additions & 1 deletion kdjs/types/test/types.test.js
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
import { test, expect } from "bun:test";
import { expect, test } from "bun:test";
import {
FunctionType,
GenericType,
PrimitiveType,
UnionType
} from "../types";

test("FunctionType.toString()", () => {
const returnType = new PrimitiveType("string", false);
const paramTypes = [
new PrimitiveType("number", false),
new PrimitiveType("boolean", true)
];
const fn = new FunctionType(returnType, paramTypes, 1);
expect(fn.toString()).toBe("function(number,?boolean=):string");
});

test("GenericType.toString()", () => {
const arrayType = new GenericType("Array", [new PrimitiveType("string")], false);
console.log(arrayType.toString());
expect(arrayType.toString()).toBe("!Array<string>");

const objectType = new GenericType("Object", [
new PrimitiveType("string"), new PrimitiveType("number")
], false);
expect(objectType.toString()).toBe("!Object<string, number>");
});

test("UnionType.toString()", () => {
const unionType = new UnionType([
new PrimitiveType("string"),
new PrimitiveType("number"),
new PrimitiveType("null")
]);
expect(unionType.toString()).toBe("string | number | null");
});
Loading

0 comments on commit eb2dfa8

Please sign in to comment.