Skip to content

Commit

Permalink
chore: add locale locale-generator
Browse files Browse the repository at this point in the history
  • Loading branch information
pipinet committed Oct 1, 2024
1 parent e0a4683 commit 29aac5f
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/locale-generator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- TODO
53 changes: 53 additions & 0 deletions packages/locale-generator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "@dorami/locale-generator",
"version": "0.0.0",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
"publishConfig": {
"main": "./index.mjs",
"module": "./index.mjs",
"types": "./index.d.mts",
"exports": {
".": {
"types": "./index.d.mts",
"import": "./index.mjs"
}
},
"directory": "dist",
"linkDirectory": false,
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"build": "NODE_ENV=production INPUT_DIR=./ OUTPUT_DIR=dist/ pnpm run build:package",
"build:package": "pnpm run build:prebuild && tsup && pnpm run build:postbuild",
"build:prebuild": "tsx ./scripts/prebuild.ts",
"build:postbuild": "tsx ./scripts/postbuild.ts",
"dev:link": "pnpm link --global && npm link"
},
"dependencies": {
"lodash-es": "^4.17.21",
"properties-file": "^3.5.4",
"yaml": "^2.4.5"
},
"devDependencies": {
"tsup": "^8.2.4",
"tsx": "^4.16.2"
},
"author": "Qwlabs",
"homepage": "https://github.com/qwlabs/dorami",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/qwlabs/dorami.git",
"directory": "packages/locale-generator"
},
"bugs": {
"url": "https://github.com/qwlabs/dorami/issues"
},
"engines": {
"node": ">=20.17.0",
"pnpm": ">=9"
}
}
11 changes: 11 additions & 0 deletions packages/locale-generator/scripts/postbuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as path from 'node:path';
import * as fs from 'fs-extra';
import { clearPackageJson, resolvePath } from '../../../scripts/build-helper';

const { __dirname, __workspace, OUTPUT_DIR } = resolvePath(import.meta.url);

fs.copySync(path.resolve(__dirname, '../package.json'), `${OUTPUT_DIR}/package.json`);
fs.copySync(path.resolve(__dirname, '../README.md'), `${OUTPUT_DIR}/README.md`);
fs.copySync(path.resolve(__workspace, './LICENSE.md'), `${OUTPUT_DIR}/LICENSE.md`);

clearPackageJson(path.resolve(__dirname, `../${OUTPUT_DIR}/package.json`));
5 changes: 5 additions & 0 deletions packages/locale-generator/scripts/prebuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as path from 'node:path';
import { removeBuild, resolvePath, updatePackageJson } from '../../../scripts/build-helper';

removeBuild(import.meta.url);
updatePackageJson(path.resolve(resolvePath(import.meta.url).__dirname, '../package.json'));
56 changes: 56 additions & 0 deletions packages/locale-generator/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { glob } from 'glob';
import { assign } from 'lodash-es';
import { lookupLoader } from './loaders';

export interface BuildLocaleEntry {
locale: string;
includes: string[];
}

interface BuildLocaleMessages {
locale: string;
messages: Record<string, string>;
}

const loadFile = (file: string): Promise<Record<string, string>> => {
const loader = lookupLoader(file);
if (!loader) {
return Promise.resolve({});
}
return loader.load(file);
};

const loadLocale = async (entry: BuildLocaleEntry): Promise<BuildLocaleMessages> => {
const files = await glob(entry.includes);
const allMessages: Record<string, string> = await Promise.all(files.map(loadFile)).then((values) => {
return assign({}, ...values);
});
return {
locale: entry.locale,
messages: allMessages,
};
};

const loadLocales = (entries: BuildLocaleEntry[]): Promise<Record<string, Record<string, string>>> => {
return new Promise((resolve) => {
const promises = entries.map(loadLocale);
Promise.all(promises).then((localeMessages) => {
const result: Record<string, Record<string, string>> = {};
localeMessages.forEach((localeMessage) => {
result[localeMessage.locale] = localeMessage.messages;
});
resolve(result);
});
});
};

export const generateLocale = async (outputDir: string, entries: BuildLocaleEntry[]) => {
const loadedLocales = await loadLocales(entries);
for (const locale in loadedLocales) {
const messages = loadedLocales[locale];
const filePath = join(outputDir, `${locale}.json`);
writeFileSync(filePath, JSON.stringify(messages), { encoding: 'utf-8' });
}
};
4 changes: 4 additions & 0 deletions packages/locale-generator/src/loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface Loader {
load: (file: string) => Promise<Record<string, string>>;
supported: (file: string) => boolean;
}
9 changes: 9 additions & 0 deletions packages/locale-generator/src/loaders/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Loader } from '../loader.ts';
import { YamlLoader } from './yaml-loader.ts';
import { PropertiesLoader } from './properties-loader.ts';

const LOADERS: Loader[] = [new YamlLoader(), new PropertiesLoader()];

export const lookupLoader = (file: string): Loader | undefined => {
return LOADERS.find((loader) => loader.supported(file));
};
13 changes: 13 additions & 0 deletions packages/locale-generator/src/loaders/properties-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { readFileSync } from 'node:fs';
import { getProperties } from 'properties-file';
import type { Loader } from '../loader.ts';

export class PropertiesLoader implements Loader {
async load(file: string): Promise<Record<string, string>> {
return getProperties(readFileSync(file, { encoding: 'utf-8' })) as unknown as Record<string, string>;
}

supported(file: string): boolean {
return file.endsWith('.properties');
}
}
14 changes: 14 additions & 0 deletions packages/locale-generator/src/loaders/yaml-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Loader } from '../loader.ts';

export class YamlLoader implements Loader {
load(file: string): Promise<Record<string, string>> {
// TODO
return Promise.resolve({});
// parse(readFileSync(file, 'utf-8'))
// return Promise.resolve(undefined);
}

supported(file: string): boolean {
return file.endsWith('.yaml');
}
}
8 changes: 8 additions & 0 deletions packages/locale-generator/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
"baseUrl": ".",
},
"exclude": ["node_modules", "dist"]
}
8 changes: 8 additions & 0 deletions packages/locale-generator/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from 'tsup';

export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
splitting: false,
});
30 changes: 30 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 29aac5f

Please sign in to comment.