Skip to content

Commit

Permalink
refactor: get paths from PathRegistry (stage 3) (#7)
Browse files Browse the repository at this point in the history
* refactor: get paths from PathDispatcher, instead of DEFAULTS constant usage (stage 3)

* fix: rename

* refactor: improve path registry idea

* 1.2.0
  • Loading branch information
sapachev authored Feb 2, 2023
1 parent 66046df commit 2247202
Show file tree
Hide file tree
Showing 17 changed files with 204 additions and 128 deletions.
43 changes: 31 additions & 12 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,23 @@ import { ILogger, Logger } from "./lib/classes/Logger";
import { Main } from "./lib/classes/Main";
import { IStyler, Styler } from "./lib/classes/Styler";

import { DI_TOKENS } from "./lib/tokens";
import { Config, ConfigProvider } from "./lib/interfaces";
import { DEFAULTS } from "./lib/constants";
import { Config } from "./lib/interfaces";
import { Messages } from "./lib/classes/Messages";
import { MessagesEnum } from "./messages";
import { PathRegistry } from "./lib/classes/PathRegistry";

import { DEFAULTS } from "./lib/constants";
import { DI_TOKENS } from "./lib/tokens";

// Resigstry of resolved paths used during the process
const pr = new PathRegistry({
assetsDist: `${DEFAULTS.DIST}/${DEFAULTS.ASSETS}`,
config: DEFAULTS.CONFIG,
dist: DEFAULTS.DIST,
package: DEFAULTS.PACKAGE,
snippets: DEFAULTS.SNIPPETS,
twndDist: `${DEFAULTS.DIST}/${DEFAULTS.ASSETS}/css/${DEFAULTS.TAILWIND_OUT}`,
});

// Register DI
const runContainer = new Container({ defaultScope: "Singleton" });
Expand All @@ -24,17 +36,24 @@ runContainer.bind<IFileSystemHelper>(DI_TOKENS.FS_HELPER).to(FileSystemHelper);
runContainer.bind<IFileSystemWrapper>(DI_TOKENS.FS).to(NodeFS);
runContainer.bind<ILogger>(DI_TOKENS.LOGGER).to(Logger);
runContainer.bind<IStyler>(DI_TOKENS.STYLER).to(Styler);

runContainer.bind<ConfigProvider>(DI_TOKENS.CONFIG_PROVIDER).toProvider<Config>((ctx) => {
return () => {
const fsHelper = ctx.container.get<IFileSystemHelper>(DI_TOKENS.FS_HELPER);
return fsHelper.readConfig(DEFAULTS.CONFIG);
};
});
runContainer.bind<PathRegistry>(DI_TOKENS.PATH).toConstantValue(pr);

runContainer
.resolve(Main)
.start()
.resolve(FileSystemHelper)
.readConfig(pr.get("config"))
.then((config) => {
runContainer.bind<Config>(DI_TOKENS.CONFIG).toConstantValue(config);

// Registry update with new paths, which depends on current config
pr.update({
assetsSrc: `${DEFAULTS.THEMES}/${config.theme}/${DEFAULTS.ASSETS}`,
theme: `${DEFAULTS.THEMES}/${config.theme}`,
src: `${DEFAULTS.SRC}/${config.locale}`,
twndSrc: `${DEFAULTS.THEMES}/${config.theme}/${DEFAULTS.ASSETS}/css/${DEFAULTS.TAILWIND_IN}`,
});

return runContainer.resolve(Main).start();
})
.catch((err) => {
runContainer.get<ILogger>(DI_TOKENS.LOGGER).print(Messages.error(MessagesEnum.OVERALL, err));
});
3 changes: 2 additions & 1 deletion lib/_constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exports.DefaultPaths = {
PACKAGE: "./package.json",
SNIPPETS: "./snippets",
SRC: "./src",
TAILWIND_ENTRY: "main.twnd.css",
TAILWIND_IN: "main.twnd.css",
TAILWIND_OUT: "main.css",
THEMES: "./themes",
};
43 changes: 15 additions & 28 deletions lib/classes/Compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { ILogger } from "./Logger";
import { Messages } from "./Messages";
import { Renderer } from "./Renderer";

import { DEFAULTS } from "../constants";
import { Config, ConfigProvider, TemplateVariables } from "../interfaces";
import { Config, TemplateVariables } from "../interfaces";
import { DI_TOKENS } from "../tokens";
import { MessagesEnum } from "../../messages";
import { PathRegistry } from "./PathRegistry";

export const SRC_CODE_PATTERN = /^[0-9]{3}(?=\.json$)/i;

Expand All @@ -22,37 +22,26 @@ export interface ICompiler {

@injectable()
export class Compiler implements ICompiler {
private config: Config;
private statusList: Set<number> = new Set();

constructor(
@inject(DI_TOKENS.CONFIG_PROVIDER) private configProvider: ConfigProvider,
@inject(DI_TOKENS.CONFIG) private config: Config,
@inject(DI_TOKENS.FS_HELPER) private fsHelper: IFileSystemHelper,
@inject(DI_TOKENS.LOGGER) private logger: ILogger
@inject(DI_TOKENS.LOGGER) private logger: ILogger,
@inject(DI_TOKENS.PATH) private pr: PathRegistry
) {}

async initTemplateVariables(): Promise<TemplateVariables> {
const config = await this.getConfig();

const pkg = await this.fsHelper.readJson<PackageId>(DEFAULTS.PACKAGE);
const pkg = await this.fsHelper.readJson<PackageId>(this.pr.get("package"));
return {
locale: config.locale,
locale: this.config.locale,
version: pkg.version,
};
}

async getConfig(): Promise<Config> {
if (!this.config) {
this.config = await this.configProvider();
}
return this.config;
}

async getStatusList(): Promise<Set<number>> {
const config = await this.getConfig();

if (this.statusList.size === 0) {
await this.fsHelper.readDir(`${DEFAULTS.SRC}/${config.locale}/`).then((files) => {
await this.fsHelper.readDir(this.pr.get("src")).then((files) => {
files.forEach((file) => {
const match = file.match(SRC_CODE_PATTERN);
if (match) {
Expand All @@ -65,19 +54,17 @@ export class Compiler implements ICompiler {
}

async makePages(): Promise<void> {
const config = await this.getConfig();

this.logger.print(Messages.info(MessagesEnum.COMPILE_PAGES));
const list = await this.getStatusList();
if (list.size > 0) {
const initVars = await this.initTemplateVariables();
const commonVars = await this.fsHelper.readJson<TemplateVariables>(`${DEFAULTS.SRC}/${config.locale}/common.json`);
const template = await this.fsHelper.readFile(`${DEFAULTS.THEMES}/${config.theme}/template.html`);
const commonVars = await this.fsHelper.readJson<TemplateVariables>(this.pr.join("src", "common.json"));
const template = await this.fsHelper.readFile(this.pr.join("theme", "template.html"));

await Promise.all(
Array.from(list).map(async (code) => {
const statusVars = await this.fsHelper.readJson<TemplateVariables>(`${DEFAULTS.SRC}/${config.locale}/${code}.json`);
const path = `${DEFAULTS.DIST}/${code}.html`;
const statusVars = await this.fsHelper.readJson<TemplateVariables>(this.pr.join("src", `${code}.json`));
const path = this.pr.join("dist", `${code}.html`);

this.logger.print(Messages.list(path));

Expand All @@ -93,15 +80,15 @@ export class Compiler implements ICompiler {
this.logger.print(Messages.info(MessagesEnum.COMPILE_CONFIGS));
const list = await this.getStatusList();
if (list.size > 0) {
const snippets = await this.fsHelper.readDir(`${DEFAULTS.SNIPPETS}/`);
const snippets = await this.fsHelper.readDir(this.pr.get("snippets"));

await Promise.all(
snippets.map(async (snippet) => {
const path = `${DEFAULTS.DIST}/${snippet}`;
const path = this.pr.join("dist", snippet);

this.logger.print(Messages.list(path));

const template = await this.fsHelper.readFile(`${DEFAULTS.SNIPPETS}/${snippet}`);
const template = await this.fsHelper.readFile(this.pr.join("snippets", snippet));
await this.fsHelper.writeFile(path, Renderer.renderTemplate(template, { codes: Array.from(list) }));
})
);
Expand Down
12 changes: 6 additions & 6 deletions lib/classes/FileSystemHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { injectable, inject } from "inversify";

import { Config } from "../interfaces";
import { Messages } from "./Messages";

import { MessagesEnum } from "../../messages";
import { MANDATORY_CONFIG_PROPS } from "../constants";
import { Styler } from "./Styler";
import { ILogger } from "./Logger";
import { DI_TOKENS } from "../tokens";
import { IFileSystemWrapper } from "./FileSystemWrapper";
import { Styler } from "./Styler";

import { DI_TOKENS } from "../tokens";
import { MANDATORY_CONFIG_PROPS } from "../constants";
import { MessagesEnum } from "../../messages";

export interface IFileSystemHelper {
copyAssets(src: string, dest: string): Promise<void>;
Expand All @@ -27,7 +27,7 @@ export class FileSystemHelper implements IFileSystemHelper {

async copyAssets(src: string, dest: string): Promise<void> {
if (await this.ensure(src)) {
this.logger.print(Messages.info(MessagesEnum.COPYING_ASSETS));
this.logger.print(Messages.info(MessagesEnum.COPYING_ASSETS, { dest }));
await this.fs.cp(src, dest, {
recursive: true,
// TODO: add Logger.print() to filter function
Expand Down
22 changes: 10 additions & 12 deletions lib/classes/Main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@ import { inject, injectable } from "inversify";
import { IFileSystemHelper } from "./FileSystemHelper";
import { ILogger } from "./Logger";
import { ICompiler } from "./Compiler";
import { IStyler } from "./Styler";
import { Messages } from "./Messages";
import { PathRegistry } from "./PathRegistry";

import { ConfigProvider } from "../interfaces";
import { DEFAULTS } from "../constants";
import { Config } from "../interfaces";
import { DI_TOKENS } from "../tokens";
import { MessagesEnum } from "../../messages";
import { IStyler } from "./Styler";

@injectable()
export class Main {
constructor(
@inject(DI_TOKENS.CONFIG_PROVIDER) private configProvider: ConfigProvider,
@inject(DI_TOKENS.COMPILER) private compiler: ICompiler,
@inject(DI_TOKENS.FS_HELPER) private fsHelper: IFileSystemHelper,
@inject(DI_TOKENS.LOGGER) private logger: ILogger,
@inject(DI_TOKENS.STYLER) private styler: IStyler
@inject(DI_TOKENS.STYLER) private styler: IStyler,
@inject(DI_TOKENS.CONFIG) private config: Config,
@inject(DI_TOKENS.PATH) private pr: PathRegistry
) {}

async start() {
const startTime = Date.now();
const config = await this.configProvider();

this.logger.print(Messages.info(MessagesEnum.START));

// Cleanup before new building
await this.fsHelper.flush(DEFAULTS.DIST);
await this.fsHelper.flush(this.pr.get("dist"));

// Generate static pages
await this.compiler.makePages();
Expand All @@ -37,16 +37,14 @@ export class Main {
await this.compiler.makeConfigs();

// Generate styles with Tailwind
if (config.tailwind) {
const input = `${DEFAULTS.THEMES}/${config.theme}/${DEFAULTS.ASSETS}/css/${DEFAULTS.TAILWIND_ENTRY}`;
const output = `${DEFAULTS.DIST}/${DEFAULTS.ASSETS}/css/${DEFAULTS.TAILWIND_ENTRY.replace(".twnd.css", ".css")}`;
await this.styler.buildTailwind(input, output);
if (this.config.tailwind) {
await this.styler.buildTailwind(this.pr.get("twndSrc"), this.pr.get("twndDist"));
} else {
this.logger.print(Messages.warn(MessagesEnum.TAILWIND_DISABLED));
}

// Copy assets to the dist directory
await this.fsHelper.copyAssets(`${DEFAULTS.THEMES}/${config.theme}/${DEFAULTS.ASSETS}`, `${DEFAULTS.DIST}/${DEFAULTS.ASSETS}`);
await this.fsHelper.copyAssets(this.pr.get("assetsSrc"), this.pr.get("assetsDist"));

this.logger.print(Messages.info(MessagesEnum.DONE, { duration: (Date.now() - startTime) / 1000 }));
}
Expand Down
41 changes: 41 additions & 0 deletions lib/classes/PathRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { resolve } from "path";

import { MessagesEnum } from "../../messages";
import { Messages } from "./Messages";

type AnyStringObject = { [key: string]: string };

export class PathRegistry {
private registry: Map<string, string>;

constructor(paths: AnyStringObject) {
this.init(paths);
}

private init(paths: AnyStringObject) {
this.registry = new Map(
Object.entries(paths).map(([key, value]) => {
return [key, this.resolveToCwd(value)];
})
);
}

private resolveToCwd(path: string): string {
return resolve(process.cwd(), path);
}

get(key: string): string {
if (this.registry.has(key)) {
return this.registry.get(key);
}
throw new Error(Messages.text(MessagesEnum.NO_PATH, { key }));
}

join(key: string, path: string): string {
return `${this.get(key)}/${path}`;
}

update(paths: AnyStringObject): void {
Object.entries(paths).forEach(([key, value]) => this.registry.set(key, this.resolveToCwd(value)));
}
}
2 changes: 1 addition & 1 deletion lib/classes/Styler.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { inject, injectable } from "inversify";

import { IChildProcessWrapper } from "./ChildProcessWrapper";
import { ILogger } from "./Logger";
import { Messages } from "./Messages";

import { DI_TOKENS } from "../tokens";
import { MessagesEnum } from "../../messages";
import { IChildProcessWrapper } from "./ChildProcessWrapper";

export const TAILWIND_STYLE = /\.twnd.css$/i;

Expand Down
3 changes: 2 additions & 1 deletion lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export const DEFAULTS: Defaults = {
SNIPPETS: DefaultPaths.SNIPPETS,
SRC: DefaultPaths.SRC,
THEMES: DefaultPaths.THEMES,
TAILWIND_ENTRY: DefaultPaths.TAILWIND_ENTRY,
TAILWIND_IN: DefaultPaths.TAILWIND_IN,
TAILWIND_OUT: DefaultPaths.TAILWIND_OUT,
};

export const MANDATORY_CONFIG_PROPS = ["locale", "theme", "tailwind"];
5 changes: 2 additions & 3 deletions lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export interface Defaults {
PACKAGE: string;
SNIPPETS: string;
SRC: string;
TAILWIND_ENTRY: string;
TAILWIND_IN: string;
TAILWIND_OUT: string;
THEMES: string;
}

Expand All @@ -27,5 +28,3 @@ export interface TemplateVariables extends AnyVariables {
export interface SnippetVariables {
codes: number[];
}

export type ConfigProvider = () => Promise<Config>;
29 changes: 0 additions & 29 deletions lib/style.ts

This file was deleted.

3 changes: 2 additions & 1 deletion lib/tokens.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
export const DI_TOKENS = {
COMPILER: Symbol.for("compiler"),
CONFIG_PROVIDER: Symbol.for("config-provider"),
CONFIG: Symbol.for("config"),
CHILD_PROCESS: Symbol.for("child-process"),
FS: Symbol.for("fs-promise"),
FS_HELPER: Symbol.for("fs-helper"),
LOGGER: Symbol.for("logger"),
PATH: Symbol.for("path-container"),
RENDERER: Symbol.for("renderer"),
STYLER: Symbol.for("styler"),
};
5 changes: 3 additions & 2 deletions messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ export enum MessagesEnum {
// Errors
NO_CONFIG_PROPERTY = "Please set '{{ prop }}' property in your configuration: {{ &path }}",
NO_DIRECTORY = "No directory to read: {{ &path }}",
NO_PATH = "No path in registry with '{{ key }}' key",
NO_SOURCE_DATA = "No source data to compile",
OVERALL = "An error occurred during compilation. Please, check 'README.md' to get more details about calling this process.\n\nError Message:\n{{ &message }}\n\nError stask:\n{{ &stack }}",
OVERALL = "An error occurred during compilation. Please, check 'README.md' to get more details about calling this process.\n\nDetails:\n{{ &stack }}",

// Info
COMPILE_PAGES = "Compile pages from source data:",
COMPILE_CONFIGS = "Compile web servers config snippets from source data:",
COPYING_ASSETS = "Copying assets to build directory",
COPYING_ASSETS = "Copying assets to '{{ &dest }}' directory",
DONE = "Building process was completed in {{ duration }}s",
FLUSH_DESTINATION = "Flush build directory '{{ &path }}'",
START = "Start building process",
Expand Down
Loading

0 comments on commit 2247202

Please sign in to comment.