ts2typebox
Version:
Creates TypeBox code from Typescript code
243 lines (234 loc) • 9.13 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.expectEqualIgnoreFormatting = void 0;
const node_test_1 = require("node:test");
const strict_1 = __importDefault(require("node:assert/strict"));
const prettier = __importStar(require("prettier"));
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const shelljs_1 = __importDefault(require("shelljs"));
const programmatic_usage_1 = require("../src/programmatic-usage");
const SHELLJS_RETURN_CODE_OK = 0;
const buildOsIndependentPath = (foldersOrFiles) => {
return foldersOrFiles.join(node_path_1.default.sep);
};
const formatWithPrettier = (input) => {
return prettier.format(input, { parser: "typescript" });
};
/**
* Formats given input with prettier and returns the result. This is used for
* testing to be able to compare generated types with expected types without
* having to take care of formatting.
* @throws Error
**/
const expectEqualIgnoreFormatting = (input1, input2) => {
strict_1.default.equal(formatWithPrettier(input1), formatWithPrettier(input2));
};
exports.expectEqualIgnoreFormatting = expectEqualIgnoreFormatting;
(0, node_test_1.describe)("programmatic usage API", () => {
(0, node_test_1.beforeEach)(() => {
// Reset the globally tracked mocks.
node_test_1.mock.reset();
});
(0, node_test_1.test)("generates TypeBox code", async () => {
// prepares and writes a test types.ts file.
const dummyTypes = `
type T = {
a: number;
b: string;
};
`;
const expectedOutput = `
/**
* ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
* your use case, there is a high chance that direct changes to this file get
* lost. Consider making changes to the underlying Typescript code you use to
* generate this file instead. The default file is called "types.ts", perhaps
* have a look there! :]
*/
import { Type, Static } from '@sinclair/typebox';
type T = Static<typeof T>;
const T = Type.Object({
a: Type.Number(),
b: Type.String(),
});
`;
const generatedTypeBox = await (0, programmatic_usage_1.ts2typebox)({
input: dummyTypes,
});
(0, exports.expectEqualIgnoreFormatting)(generatedTypeBox, expectedOutput);
});
(0, node_test_1.test)("disableAutogenComment option", async () => {
// prepares and writes a test types.ts file.
const dummyTypes = `
type T = {
a: number;
b: string;
};
`;
const expectedOutput = `
import { Type, Static } from '@sinclair/typebox';
type T = Static<typeof T>;
const T = Type.Object({
a: Type.Number(),
b: Type.String(),
});
`;
const generatedTypeBox = await (0, programmatic_usage_1.ts2typebox)({
input: dummyTypes,
disableAutogenComment: true,
});
(0, exports.expectEqualIgnoreFormatting)(generatedTypeBox, expectedOutput);
});
(0, node_test_1.test)("skipTypeCreation option", async () => {
const dummyTypes = `
type T = {
a: number;
b: string;
};
`;
const expectedOutput = `
/**
* ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
* your use case, there is a high chance that direct changes to this file get
* lost. Consider making changes to the underlying Typescript code you use to
* generate this file instead. The default file is called "types.ts", perhaps
* have a look there! :]
*/
import { Type } from '@sinclair/typebox';
const T = Type.Object({
a: Type.Number(),
b: Type.String(),
});
`;
const generatedTypeBox = await (0, programmatic_usage_1.ts2typebox)({
input: dummyTypes,
skipTypeCreation: true,
});
(0, exports.expectEqualIgnoreFormatting)(generatedTypeBox, expectedOutput);
});
(0, node_test_1.test)("with prettier config", async () => {
// TODO: .prettierrc.yml should not exist before
// prepares and writes a test prettierrc.yml file.
const dummyPretterConfig = "singleQuote: true";
const configFileAbsolute = buildOsIndependentPath([
__dirname,
"..",
"..",
".prettierrc.yml",
]);
// check that file does not exist yet
await strict_1.default.rejects(async () => {
return await node_fs_1.default.promises.access(configFileAbsolute);
});
node_fs_1.default.writeFileSync(configFileAbsolute, dummyPretterConfig);
const dummyTypes = `
type T = {
a: number;
b: string;
};
`;
const generatedTypeBox = await (0, programmatic_usage_1.ts2typebox)({
input: dummyTypes,
});
// We expect that all " will be converted to '
// Therefore something like (default)
// import { Type, Static } from "@sinclair/typebox";
// will become (with our custom config)
// import { Type, Static } from '@sinclair/typebox';
strict_1.default.equal(generatedTypeBox.includes("'@sinclair/typebox'"), true);
// cleanup generated files
const { code: returnCode } = shelljs_1.default.rm("-f", [configFileAbsolute]);
strict_1.default.equal(returnCode, SHELLJS_RETURN_CODE_OK);
});
(0, node_test_1.test)("with .ts2typeboxrc.cjs config", async () => {
const dummyTs2TypeboxRc = `
const transformTypeName = (input) => {
return "TestType" + input;
};
const transformValueName = (input) => {
return "testValue" + input;
};
module.exports = {
transformTypeName,
transformValueName,
};
`;
const configFileAbsolute = buildOsIndependentPath([
__dirname,
"..",
"..",
".ts2typeboxrc.cjs",
]);
// check that file does not exist yet
await strict_1.default.rejects(async () => {
return await node_fs_1.default.promises.access(configFileAbsolute);
});
node_fs_1.default.writeFileSync(configFileAbsolute, dummyTs2TypeboxRc);
// prepares and writes a test types.ts file.
const dummyTypes = `
type T = number;
export type U = number;
`;
const expectedOutput = `
/**
* ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
* your use case, there is a high chance that direct changes to this file get
* lost. Consider making changes to the underlying Typescript code you use to
* generate this file instead. The default file is called "types.ts", perhaps
* have a look there! :]
*/
import { Type, Static } from "@sinclair/typebox";
type TestTypeT = Static<typeof testValueT>;
const testValueT = Type.Number();
export type TestTypeU = Static<typeof testValueU>;
export const testValueU = Type.Number();
`;
const generatedTypeBox = await (0, programmatic_usage_1.ts2typebox)({
input: dummyTypes,
});
(0, exports.expectEqualIgnoreFormatting)(generatedTypeBox, expectedOutput);
// cleanup generated files
const { code: returnCode } = shelljs_1.default.rm("-f", [configFileAbsolute]);
strict_1.default.equal(returnCode, SHELLJS_RETURN_CODE_OK);
});
});
// TODO: create cli usage tests with the refactored/fixed new cli file
// describe("cli usage", () => {});
//# sourceMappingURL=index.js.map