Skip to content

Commit

Permalink
feat: use es2022
Browse files Browse the repository at this point in the history
Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
  • Loading branch information
neilime committed Nov 9, 2024
1 parent 73fcd62 commit 2821ca6
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 42 deletions.
108 changes: 108 additions & 0 deletions src/services/file/FileFactory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { writeFile } from "fs/promises";
import { resolve } from "path";

import container from "../../container";
import { DirResult, createTmpDir } from "../../tests/tmp-dir";
import { FileFactory } from "./FileFactory";
import { JsonFile } from "./JsonFile";
import { TomlFile } from "./TomlFile";
import { TypescriptFile } from "./TypescriptFile";
import { StdFile } from "./StdFile";

describe("FileFactory", () => {
let testDir: DirResult;
let fileFactory: FileFactory;

beforeEach(() => {
// Initialize service before each test to not be confused by cache
container.snapshot();
fileFactory = container.get(FileFactory);
});

afterEach(() => {
container.restore();
testDir?.removeCallback();
});

describe("fromFile", () => {
it("should create a file from a file path", async () => {
testDir = await createTmpDir();

const filepath = resolve(testDir.name, "test.txt");
await writeFile(filepath, "test");

const file = await fileFactory.fromFile(filepath);
expect(file).toBeInstanceOf(StdFile);

const content = await file.getContent();
expect(content).toBe("test");
});

it("should create a file from a file path with encoding", async () => {
testDir = await createTmpDir();

const filepath = resolve(testDir.name, "test.txt");
await writeFile(filepath, "test");

const file = await fileFactory.fromFile(filepath, "utf8");
expect(file).toBeInstanceOf(StdFile);

const content = await file.getContent();
expect(content).toBe("test");
});

it("should throw an error when the file does not exist", async () => {
await expect(fileFactory.fromFile("non-existing-file")).rejects.toThrow(
'File "non-existing-file" does not exist'
);
});
});

describe("fromString", () => {
it("should create a file from a string", async () => {
const file = await fileFactory.fromString("test", "test.txt");

expect(file).toBeInstanceOf(StdFile);
expect(await file.getContent()).toBe("test");
});

it("should create a file from a string with encoding", async () => {
const file = await fileFactory.fromString("test", "test.txt", "utf8");

expect(file).toBeInstanceOf(StdFile);
expect(await file.getContent()).toBe("test");
});

it("should create a Json file from a string", async () => {
const file = await fileFactory.fromString('{"test": "test"}', "test.json");

expect(file).toBeInstanceOf(JsonFile);
const jsonFile = file as JsonFile;

expect(await jsonFile.getContent()).toBe('{"test": "test"}');
expect(await jsonFile.getData()).toEqual({ test: "test" });
expect(await jsonFile.getData("test")).toEqual("test");
expect(await jsonFile.getData("unknown")).toBeUndefined();
});

it("should create a Toml file from a string", async () => {
const file = await fileFactory.fromString("test = 'test'", "test.toml");

expect(file).toBeInstanceOf(TomlFile);
expect(await file.getContent()).toBe("test = 'test'");
expect(await (file as TomlFile).getData()).toEqual({ test: "test" });
expect(await (file as TomlFile).getData("test")).toEqual("test");
expect(await (file as TomlFile).getData("unknown")).toBeUndefined();
});

it("should create a Typescript file from a string", async () => {
const file = await fileFactory.fromString("console.log('test')", "test.ts");

expect(file).toBeInstanceOf(TypescriptFile);
expect(await file.getContent()).toBe("console.log('test')");
});
});
});
function writeFileSync(filepath: string, arg1: string) {

Check failure on line 106 in src/services/file/FileFactory.spec.ts

View workflow job for this annotation

GitHub Actions / ci / continuous-integration / 👕 Lint

'writeFileSync' is defined but never used

Check failure on line 106 in src/services/file/FileFactory.spec.ts

View workflow job for this annotation

GitHub Actions / ci / continuous-integration / 👕 Lint

'filepath' is defined but never used

Check failure on line 106 in src/services/file/FileFactory.spec.ts

View workflow job for this annotation

GitHub Actions / ci / continuous-integration / 👕 Lint

'arg1' is defined but never used
throw new Error("Function not implemented.");
}
6 changes: 5 additions & 1 deletion src/services/file/FileFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ export class FileFactory {
}
}

fromString(content: string, file: string, encoding: BufferEncoding = "utf8"): StdFile {
fromString(
content: string,
file: string,
encoding: BufferEncoding = "utf8"
): StdFile | JsonFile | TomlFile | TypescriptFile {
const args = [
this.cliService,
this.directoryService,
Expand Down
44 changes: 39 additions & 5 deletions src/services/file/JsonFile.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { all } from "deepmerge";

import { StdFile } from "./StdFile";
import { CliService } from "../CliService";
import { DirectoryService } from "./DirectoryService";
import { FileDiffService } from "./FileDiffService";
import { FileFactory } from "./FileFactory";
import { FileService } from "./FileService";

type JsonArray = boolean[] | number[] | string[] | JsonFileData[] | Date[];
type AnyJson = boolean | number | string | JsonFileData | Date | JsonArray | JsonArray[];
Expand All @@ -10,10 +15,33 @@ export interface JsonFileData {
}

export class JsonFile extends StdFile {
protected data?: JsonFileData;
protected data?: JsonFileData = undefined;

constructor(
protected readonly cliService: CliService,
protected readonly directoryService: DirectoryService,
protected readonly fileService: FileService,
protected readonly fileDiffService: FileDiffService,
protected readonly fileFactory: FileFactory,
protected readonly file: string | null = null,
protected readonly encoding: BufferEncoding = "utf8",
content = ""
) {
super(
cliService,
directoryService,
fileService,
fileDiffService,
fileFactory,
file,
encoding,
content
);
this.setDataFromContent();
}

getContent(): string {
return JSON.stringify(this.data, null, " ");
return super.getContent();
}

appendContent(content: string): this {
Expand Down Expand Up @@ -44,8 +72,8 @@ export class JsonFile extends StdFile {
return data[property];
}

protected parseContent(content: string): string {
content = super.parseContent(content);
protected setDataFromContent(): this {
const content = this.getContent();
try {
this.data = JSON.parse(content);
} catch (error) {
Expand All @@ -55,6 +83,12 @@ export class JsonFile extends StdFile {
)} => "${content.trim()}"`
);
}
return content;
return this;
}

protected setContent(content: string): this {
super.setContent(content);
this.setDataFromContent();
return this;
}
}
57 changes: 50 additions & 7 deletions src/services/file/TomlFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,36 @@ import { AnyJson, JsonMap, parse, stringify } from "@iarna/toml";
import { all } from "deepmerge";

import { StdFile } from "./StdFile";
import { CliService } from "../CliService";
import { DirectoryService } from "./DirectoryService";
import { FileDiffService } from "./FileDiffService";
import { FileFactory } from "./FileFactory";
import { FileService } from "./FileService";

export class TomlFile extends StdFile {
protected data?: JsonMap;
protected data?: JsonMap = undefined;

protected parseContent(content: string): string {
content = super.parseContent(content);
this.data = parse(content);
return content;
constructor(
protected readonly cliService: CliService,
protected readonly directoryService: DirectoryService,
protected readonly fileService: FileService,
protected readonly fileDiffService: FileDiffService,
protected readonly fileFactory: FileFactory,
protected readonly file: string | null = null,
protected readonly encoding: BufferEncoding = "utf8",
content = ""
) {
super(
cliService,
directoryService,
fileService,
fileDiffService,
fileFactory,
file,
encoding,
content
);
this.setDataFromContent();
}

getContent(): string {
Expand All @@ -29,11 +51,32 @@ export class TomlFile extends StdFile {
return this.setContent(stringify(newData));
}

getData(property?: undefined): JsonMap | undefined;
getData(property?: string): AnyJson | undefined {
getData(): JsonMap | undefined;
getData(property: string | undefined): AnyJson | undefined;
getData(property: string | undefined = undefined): AnyJson | undefined {
if (!this.data) {
return this.data;
}
return property ? this.data[property] : this.data;
}

protected setDataFromContent(): this {
const content = this.getContent();
try {
this.data = parse(content);
} catch (error) {
throw new Error(
`An error occurred while parsing file content "${this.file}": ${JSON.stringify(
error instanceof Error ? error.message : error
)} => "${content.trim()}"`
);
}
return this;
}

protected setContent(content: string): this {
super.setContent(content);
this.setDataFromContent();
return this;
}
}
49 changes: 29 additions & 20 deletions src/services/file/TypescriptFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,38 @@ export class TypescriptFile extends StdFile {
protected declarations?: Array<string>;
protected defaultDeclaration?: string | null;

protected parseContent(content: string): string {
this.imports = [];
this.declarations = [];
this.defaultDeclaration = null;

content = super.parseContent(content);
const body = this.parseTypescriptContent(content);

for (const bodyItem of body) {
switch (bodyItem.kind) {
case SyntaxKind.ImportDeclaration:
this.parseImportDeclaration(bodyItem as ImportDeclaration);
break;
default:
this.declarations.push(content.substr(bodyItem.pos, bodyItem.end - bodyItem.pos));
}
}

protected setDataFromContent(): this {
const content = this.getContent();
try {
return this.getContent();
this.imports = [];
this.declarations = [];
this.defaultDeclaration = null;

const body = this.parseTypescriptContent(content);

for (const bodyItem of body) {
switch (bodyItem.kind) {
case SyntaxKind.ImportDeclaration:
this.parseImportDeclaration(bodyItem as ImportDeclaration);
break;
default:
this.declarations.push(content.substr(bodyItem.pos, bodyItem.end - bodyItem.pos));
}
}
} catch (error) {
throw new Error('An error occurred while parsing content "' + content + '", ' + error);
throw new Error(
`An error occurred while parsing file content "${this.file}": ${JSON.stringify(
error instanceof Error ? error.message : error
)} => "${content.trim()}"`
);
}
return this;
}

protected setContent(content: string): this {
super.setContent(content);
this.setDataFromContent();
return this;
}

protected parseTypescriptContent(content: string): NodeArray<Statement> {
Expand Down
18 changes: 10 additions & 8 deletions src/services/template/adapters/EtaAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@ import { TemplateAdapter } from "./TemplateAdapter";
import { TemplateAdapterHelper } from "./TemplateAdapterHelper";

export class EtaAdapter implements TemplateAdapter {
private readonly eta: Eta = new Eta({
views: this.templateFileService.getTemplateDirectory(),
debug: true,
cache: true, // Make Eta cache templates
autoEscape: false, // Not automatically XML-escape interpolations
autoTrim: false, // automatic whitespace trimming,
});
private readonly eta: Eta;

private readonly compiledTemplates: Map<string, TemplateFunction> = new Map();

constructor(
@inject(TemplateFileService) private readonly templateFileService: TemplateFileService,
@inject(TemplateAdapterHelper) private readonly templateAdapterHelper: TemplateAdapterHelper
) {}
) {
this.eta = new Eta({
views: this.templateFileService.getTemplateDirectory(),
debug: true,
cache: true, // Make Eta cache templates
autoEscape: false, // Not automatically XML-escape interpolations
autoTrim: false, // automatic whitespace trimming,
});
}

async renderTemplateString(template: string, context: TemplateContext): Promise<string> {
const compiledTemplate = await this.getCompiledTemplateString(template, template);
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es2018",
"target": "es2022",
"sourceMap": true,
"strict": true,
"outDir": "./dist",
Expand Down

0 comments on commit 2821ca6

Please sign in to comment.