mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-24 05:05:20 -04:00
refactor(rewrite): Reformat using prettier
This commit is contained in:
parent
9b7579aaae
commit
b469865fd7
@ -9,7 +9,7 @@ This is the working directory for the Pronouns.page rewrite.
|
||||
Run `setup.mjs` for a quick setup. It'll symlink some directories and will work as the equivalent of `make switch` et al.
|
||||
The reason for making this a script is that make was causing problems for Windows users.
|
||||
|
||||
This script does not yet depend on a package manager, so you're free to use whatever you like, provided it'll play nice
|
||||
This script does not yet depend on a package manager, so you're free to use whatever you like, provided it'll play nice
|
||||
with the remaining setup.
|
||||
|
||||
### Package managers
|
||||
|
@ -1,7 +1,3 @@
|
||||
{
|
||||
"watch": [
|
||||
"dist/**",
|
||||
"package.json",
|
||||
"tsconfig.json"
|
||||
]
|
||||
}
|
||||
"watch": ["dist/**", "package.json", "tsconfig.json"]
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
import "dotenv/config";
|
||||
import { identity, parseBool, parseIntOrThrow, toLowerCase } from "@pronounspage/common/util";
|
||||
import {
|
||||
identity,
|
||||
parseBool,
|
||||
parseIntOrThrow,
|
||||
toLowerCase,
|
||||
} from "@pronounspage/common/util";
|
||||
import * as path from "node:path";
|
||||
import * as fs from "node:fs";
|
||||
import type { log } from "#self/log";
|
||||
@ -11,7 +16,7 @@ export enum Environment {
|
||||
|
||||
export interface Config {
|
||||
environment: Environment;
|
||||
logLevel?: typeof log["level"];
|
||||
logLevel?: (typeof log)["level"];
|
||||
http: {
|
||||
baseUrl: string;
|
||||
host: string;
|
||||
@ -27,17 +32,17 @@ export interface Config {
|
||||
function envVarOrDefault<T>(
|
||||
key: string,
|
||||
parse: (value: string) => T,
|
||||
defaultValue: T,
|
||||
defaultValue: T
|
||||
): T;
|
||||
function envVarOrDefault<T>(
|
||||
key: string,
|
||||
parse: (value: string) => T,
|
||||
defaultValue?: undefined,
|
||||
defaultValue?: undefined
|
||||
): T | undefined;
|
||||
function envVarOrDefault<T>(
|
||||
key: string,
|
||||
parse: (value: string) => T,
|
||||
defaultValue: T | undefined = undefined,
|
||||
defaultValue: T | undefined = undefined
|
||||
): T | undefined {
|
||||
const value = process.env[key];
|
||||
return value == null ? defaultValue : parse(String(value));
|
||||
@ -73,7 +78,7 @@ export function loadConfigFromEnv(): Config {
|
||||
environment: envVarOrDefault(
|
||||
"ENVIRONMENT",
|
||||
parseEnvironment,
|
||||
Environment.DEVELOPMENT,
|
||||
Environment.DEVELOPMENT
|
||||
),
|
||||
logLevel: envVarOrDefault("LOG_LEVEL", toLowerCase, undefined),
|
||||
http: {
|
||||
@ -84,8 +89,16 @@ export function loadConfigFromEnv(): Config {
|
||||
security: {
|
||||
secret: envVarNotNull("SECRET", identity),
|
||||
},
|
||||
localeDataPath: envVarOrDefault("LOCALE_DATA_PATH", parsePath, "../locales"),
|
||||
allowUnpublishedLocales: envVarOrDefault("ALLOW_UNPUBLISHED_LOCALES", parseBool, false),
|
||||
localeDataPath: envVarOrDefault(
|
||||
"LOCALE_DATA_PATH",
|
||||
parsePath,
|
||||
"../locales"
|
||||
),
|
||||
allowUnpublishedLocales: envVarOrDefault(
|
||||
"ALLOW_UNPUBLISHED_LOCALES",
|
||||
parseBool,
|
||||
false
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@ -99,8 +112,11 @@ export function validateConfig(config: Config): string | undefined {
|
||||
if (secretLower === "changeme") {
|
||||
return `You didn't change the secret? The secret is quite literally "${secretLower}"`;
|
||||
}
|
||||
if (secretLower === "changemeonprod!" && config.environment === Environment.PRODUCTION) {
|
||||
return `Hey now, this is production! You have to change the secret on prod! Look, it says so: ${config.security.secret}`
|
||||
if (
|
||||
secretLower === "changemeonprod!" &&
|
||||
config.environment === Environment.PRODUCTION
|
||||
) {
|
||||
return `Hey now, this is production! You have to change the secret on prod! Look, it says so: ${config.security.secret}`;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
11
new/backend/src/global.d.ts
vendored
11
new/backend/src/global.d.ts
vendored
@ -19,12 +19,15 @@ type Log = typeof log;
|
||||
type TypeProvider = TypeBoxTypeProvider;
|
||||
|
||||
declare global {
|
||||
type AppInstance = FastifyInstance<RawServer,
|
||||
type AppInstance = FastifyInstance<
|
||||
RawServer,
|
||||
RequestExpr,
|
||||
ReplyExpr,
|
||||
typeof log,
|
||||
TypeProvider
|
||||
>;
|
||||
type AppPluginAsync<Options extends FastifyPluginOptions = Record<never, never>> = FastifyPluginAsync<Options, RawServer, TypeProvider, Log>;
|
||||
type AppReply = FastifyReply<RawServer, RequestExpr, ReplyExpr>
|
||||
}
|
||||
type AppPluginAsync<
|
||||
Options extends FastifyPluginOptions = Record<never, never>,
|
||||
> = FastifyPluginAsync<Options, RawServer, TypeProvider, Log>;
|
||||
type AppReply = FastifyReply<RawServer, RequestExpr, ReplyExpr>;
|
||||
}
|
||||
|
@ -2,7 +2,11 @@ import { startServer } from "#self/server";
|
||||
import { getConfig, validateConfig } from "#self/config";
|
||||
import log from "#self/log";
|
||||
import { exit, pid, ppid } from "node:process";
|
||||
import { getActiveLocaleDescriptions, loadAllLocales, loadLocaleDescriptions } from "./locales.js";
|
||||
import {
|
||||
getActiveLocaleDescriptions,
|
||||
loadAllLocales,
|
||||
loadLocaleDescriptions,
|
||||
} from "./locales.js";
|
||||
|
||||
log.info(`Pronouns.page Backend Server - PID: ${pid}, PPID: ${ppid}`);
|
||||
|
||||
@ -21,13 +25,17 @@ try {
|
||||
const localeDescriptions = await loadLocaleDescriptions();
|
||||
const active = getActiveLocaleDescriptions();
|
||||
await loadAllLocales();
|
||||
log.info(`${localeDescriptions.length} locale(s) are registered, of which ${active.length} are active`)
|
||||
log.info(
|
||||
`${localeDescriptions.length} locale(s) are registered, of which ${active.length} are active`
|
||||
);
|
||||
} catch (e) {
|
||||
log.error(`Could not load locales: ${e}`);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const memUsage = process.memoryUsage();
|
||||
const memUsagePercent = memUsage.heapUsed / memUsage.heapTotal * 100;
|
||||
log.info(`Finished preparations - system stats: MEM ${memUsagePercent.toFixed(2)}%`);
|
||||
const memUsagePercent = (memUsage.heapUsed / memUsage.heapTotal) * 100;
|
||||
log.info(
|
||||
`Finished preparations - system stats: MEM ${memUsagePercent.toFixed(2)}%`
|
||||
);
|
||||
await startServer();
|
||||
|
@ -8,7 +8,12 @@ import * as suml from "@pronounspage/common/suml";
|
||||
import fsp from "node:fs/promises";
|
||||
import log from "#self/log";
|
||||
import * as csv from "csv-parse/sync";
|
||||
import { capitalizeFirstLetter, compileTemplate, isNotBlank, parseBool } from "@pronounspage/common/util";
|
||||
import {
|
||||
capitalizeFirstLetter,
|
||||
compileTemplate,
|
||||
isNotBlank,
|
||||
parseBool,
|
||||
} from "@pronounspage/common/util";
|
||||
|
||||
export interface LocaleDescription {
|
||||
code: string;
|
||||
@ -25,10 +30,19 @@ let loadedDescriptions: Array<LocaleDescription>;
|
||||
let indexedDescriptions: Record<string, LocaleDescription>;
|
||||
let activeLocaleDescriptions: Array<LocaleDescription> | undefined;
|
||||
|
||||
export async function loadLocaleDescriptions(): Promise<Array<LocaleDescription>> {
|
||||
export async function loadLocaleDescriptions(): Promise<
|
||||
Array<LocaleDescription>
|
||||
> {
|
||||
if (loadedDescriptions == undefined) {
|
||||
loadedDescriptions = (await import("file://" + path.resolve(getConfig().localeDataPath, "locales.js"))).default;
|
||||
indexedDescriptions = Object.fromEntries(loadedDescriptions.map((v) => [v.code, v]));
|
||||
loadedDescriptions = (
|
||||
await import(
|
||||
"file://" +
|
||||
path.resolve(getConfig().localeDataPath, "locales.js")
|
||||
)
|
||||
).default;
|
||||
indexedDescriptions = Object.fromEntries(
|
||||
loadedDescriptions.map((v) => [v.code, v])
|
||||
);
|
||||
activeLocaleDescriptions = undefined;
|
||||
}
|
||||
return loadedDescriptions;
|
||||
@ -70,7 +84,7 @@ export interface Pronoun {
|
||||
thirdForm?: string;
|
||||
smallForm?: string;
|
||||
|
||||
forms: Record<string, { written: string, pronounced: string }>;
|
||||
forms: Record<string, { written: string; pronounced: string }>;
|
||||
}
|
||||
|
||||
export interface Example {
|
||||
@ -93,8 +107,14 @@ export class Locale {
|
||||
}
|
||||
|
||||
private async readFile(parts: Array<string>): Promise<string>;
|
||||
private async readFile<T>(parts: Array<string>, parser: (value: string) => T): Promise<T>;
|
||||
private async readFile<T>(pathParts: Array<string>, parser?: (value: string) => T) {
|
||||
private async readFile<T>(
|
||||
parts: Array<string>,
|
||||
parser: (value: string) => T
|
||||
): Promise<T>;
|
||||
private async readFile<T>(
|
||||
pathParts: Array<string>,
|
||||
parser?: (value: string) => T
|
||||
) {
|
||||
// Some may complain about this
|
||||
const filePath = this.path(pathParts);
|
||||
try {
|
||||
@ -106,7 +126,9 @@ export class Locale {
|
||||
return data;
|
||||
}
|
||||
} catch (e) {
|
||||
const err = new Error(`[${this.code}] Could not load file ${filePath}: ${e}`);
|
||||
const err = new Error(
|
||||
`[${this.code}] Could not load file ${filePath}: ${e}`
|
||||
);
|
||||
err.cause = e;
|
||||
throw err;
|
||||
}
|
||||
@ -118,11 +140,12 @@ export class Locale {
|
||||
log.trace(`[${this.code}] Importing file ${filePath} for locale`);
|
||||
return await import(`file://${filePath}`);
|
||||
} catch (e) {
|
||||
const err = new Error(`[${this.code}] Could not import file ${filePath}: ${e}`);
|
||||
const err = new Error(
|
||||
`[${this.code}] Could not import file ${filePath}: ${e}`
|
||||
);
|
||||
err.cause = e;
|
||||
throw err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private _config: unknown | null = null;
|
||||
@ -134,22 +157,29 @@ export class Locale {
|
||||
// private _morphemes: Array<string>;
|
||||
|
||||
public async load() {
|
||||
const tsvParse = (data: string) => csv.parse(data, {
|
||||
columns: true,
|
||||
cast: false,
|
||||
relaxColumnCount: true,
|
||||
relaxQuotes: true,
|
||||
delimiter: "\t",
|
||||
});
|
||||
const tsvParse = (data: string) =>
|
||||
csv.parse(data, {
|
||||
columns: true,
|
||||
cast: false,
|
||||
relaxColumnCount: true,
|
||||
relaxQuotes: true,
|
||||
delimiter: "\t",
|
||||
});
|
||||
this._config = await this.readFile(["config.suml"], suml.parse);
|
||||
this._translations = await this.readFile(["translations.suml"], suml.parse);
|
||||
this._translations = await this.readFile(
|
||||
["translations.suml"],
|
||||
suml.parse
|
||||
);
|
||||
// NOTE(tecc): This currently doesn't work because the morphemes.js files (as well as many others) rely on ESM syntax.
|
||||
// This is both inconsistent with the locales.js and expectedTranslations.js files,
|
||||
// and causes Node to throw an error.
|
||||
// this._morphemes = (await this.importFile("pronouns/morphemes.js")).default;
|
||||
this._pronouns = [];
|
||||
this._pronounsByAlias = {};
|
||||
const pronouns = await this.readFile(["pronouns/pronouns.tsv"], tsvParse);
|
||||
const pronouns = await this.readFile(
|
||||
["pronouns/pronouns.tsv"],
|
||||
tsvParse
|
||||
);
|
||||
for (const pronoun of pronouns) {
|
||||
const partial: Partial<Pronoun> = { forms: {} };
|
||||
for (const [key, value] of Object.entries<string>(pronoun)) {
|
||||
@ -191,7 +221,10 @@ export class Locale {
|
||||
this._pronounsByAlias[key] = i;
|
||||
}
|
||||
}
|
||||
this._examples = await this.readFile(["pronouns/examples.tsv"], tsvParse);
|
||||
this._examples = await this.readFile(
|
||||
["pronouns/examples.tsv"],
|
||||
tsvParse
|
||||
);
|
||||
}
|
||||
|
||||
public get code() {
|
||||
@ -220,7 +253,10 @@ export class Locale {
|
||||
return this._examples;
|
||||
}
|
||||
}
|
||||
export function examplesFor(pronoun: Pronoun, examples: Array<Example>): Array<string> {
|
||||
export function examplesFor(
|
||||
pronoun: Pronoun,
|
||||
examples: Array<Example>
|
||||
): Array<string> {
|
||||
const finished = [];
|
||||
|
||||
const templating: Record<string, string> = {};
|
||||
@ -257,7 +293,10 @@ export function getLocale(localeCode: string): Locale | null {
|
||||
}
|
||||
let locale = loadedLocales[localeCode];
|
||||
if (locale == null) {
|
||||
locale = new Locale(localeCode, path.resolve(getConfig().localeDataPath, localeCode));
|
||||
locale = new Locale(
|
||||
localeCode,
|
||||
path.resolve(getConfig().localeDataPath, localeCode)
|
||||
);
|
||||
loadedLocales[localeCode] = locale;
|
||||
}
|
||||
return locale;
|
||||
@ -269,9 +308,15 @@ export async function loadAllLocales() {
|
||||
for (const description of descriptions) {
|
||||
const locale = getLocale(description.code);
|
||||
if (locale) {
|
||||
promises.push(locale.load().then(() => log.debug(`Successfully loaded locale ${locale.code}`)));
|
||||
promises.push(
|
||||
locale
|
||||
.load()
|
||||
.then(() =>
|
||||
log.debug(`Successfully loaded locale ${locale.code}`)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
await Promise.all(promises);
|
||||
log.info("All active locales have been loaded into memory");
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,10 @@ const loggerConfigurations = {
|
||||
},
|
||||
} satisfies Record<Environment, LoggerOptions>;
|
||||
|
||||
|
||||
let environment, logLevel;
|
||||
try {
|
||||
const config = getConfig();
|
||||
environment = config.environment
|
||||
environment = config.environment;
|
||||
logLevel = config.logLevel;
|
||||
} catch (e) {
|
||||
environment = Environment.DEVELOPMENT;
|
||||
|
@ -9,9 +9,9 @@ export async function startServer() {
|
||||
logger: log,
|
||||
ajv: {
|
||||
customOptions: {
|
||||
coerceTypes: "array"
|
||||
}
|
||||
}
|
||||
coerceTypes: "array",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let start: Date;
|
||||
|
@ -18,7 +18,7 @@ export interface ApiErrorOptions {
|
||||
export function error<T extends ApiErrorOptions>(options: T) {
|
||||
const response: Record<string, unknown> = {
|
||||
code: options.code,
|
||||
message: options.message
|
||||
message: options.message,
|
||||
};
|
||||
if (options.detail) {
|
||||
response.detail = options.detail;
|
||||
@ -26,7 +26,10 @@ export function error<T extends ApiErrorOptions>(options: T) {
|
||||
return response;
|
||||
}
|
||||
|
||||
export function replyError<T extends ApiErrorOptions>(reply: AppReply, options: T): AppReply {
|
||||
export function replyError<T extends ApiErrorOptions>(
|
||||
reply: AppReply,
|
||||
options: T
|
||||
): AppReply {
|
||||
const response = error(options);
|
||||
return reply.status(options.code).send(response);
|
||||
}
|
||||
@ -34,12 +37,12 @@ export function replyError<T extends ApiErrorOptions>(reply: AppReply, options:
|
||||
const ApiError = {
|
||||
INVALID_LOCALE: {
|
||||
code: 404,
|
||||
message: "Invalid locale"
|
||||
message: "Invalid locale",
|
||||
},
|
||||
UNKNOWN_PRONOUN: {
|
||||
code: 404,
|
||||
message: "We aren't aware of any such pronoun. Perhaps there's a typo?"
|
||||
}
|
||||
message: "We aren't aware of any such pronoun. Perhaps there's a typo?",
|
||||
},
|
||||
} satisfies Record<string, ApiErrorOptions>;
|
||||
|
||||
/*
|
||||
@ -50,12 +53,12 @@ const ApiError = {
|
||||
|
||||
export const routes = async function (app: AppInstance) {
|
||||
const localeSpecific = Type.Object({
|
||||
locale: Type.String()
|
||||
locale: Type.String(),
|
||||
});
|
||||
|
||||
function transformPronoun(pronoun: Pronoun, examples: Array<Example>) {
|
||||
const morphemes: Record<string, string> = {};
|
||||
const pronunciations: Record<string, string> = {};
|
||||
const pronunciations: Record<string, string> = {};
|
||||
for (const [name, form] of Object.entries(pronoun.forms)) {
|
||||
morphemes[name] = form.written;
|
||||
pronunciations[name] = form.pronounced;
|
||||
@ -74,7 +77,7 @@ export const routes = async function (app: AppInstance) {
|
||||
thirdForm: pronoun.thirdForm ?? null,
|
||||
smallForm: pronoun.smallForm ?? null,
|
||||
sourcesInfo: pronoun.source ?? null,
|
||||
examples: examplesFor(pronoun, examples)
|
||||
examples: examplesFor(pronoun, examples),
|
||||
};
|
||||
}
|
||||
|
||||
@ -82,7 +85,7 @@ export const routes = async function (app: AppInstance) {
|
||||
"/:locale/pronouns",
|
||||
{
|
||||
schema: {
|
||||
params: localeSpecific
|
||||
params: localeSpecific,
|
||||
},
|
||||
},
|
||||
(request, reply) => {
|
||||
@ -93,7 +96,10 @@ export const routes = async function (app: AppInstance) {
|
||||
|
||||
const obj: Record<string, unknown> = {};
|
||||
for (const pronoun of locale.pronouns) {
|
||||
obj[pronoun.keys[0]] = transformPronoun(pronoun, locale.examples);
|
||||
obj[pronoun.keys[0]] = transformPronoun(
|
||||
pronoun,
|
||||
locale.examples
|
||||
);
|
||||
}
|
||||
|
||||
return obj;
|
||||
@ -104,10 +110,13 @@ export const routes = async function (app: AppInstance) {
|
||||
"/:locale/pronouns/*",
|
||||
{
|
||||
schema: {
|
||||
params: Type.Intersect([localeSpecific, Type.Object({ "*": Type.String() })]),
|
||||
params: Type.Intersect([
|
||||
localeSpecific,
|
||||
Type.Object({ "*": Type.String() }),
|
||||
]),
|
||||
querystring: Type.Object({
|
||||
'examples[]': Type.Array(Type.String(), { default: [] })
|
||||
})
|
||||
"examples[]": Type.Array(Type.String(), { default: [] }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
(req, reply) => {
|
||||
@ -124,7 +133,6 @@ export const routes = async function (app: AppInstance) {
|
||||
|
||||
const examples = req.query["examples[]"];
|
||||
|
||||
|
||||
return transformPronoun(found, locale.examples);
|
||||
}
|
||||
);
|
||||
|
2
new/common/src/global.d.ts
vendored
2
new/common/src/global.d.ts
vendored
@ -1 +1 @@
|
||||
declare module "suml";
|
||||
declare module "suml";
|
||||
|
@ -2,7 +2,7 @@ import * as SumlImpl from "suml";
|
||||
|
||||
declare module "suml";
|
||||
|
||||
console.log(SumlImpl)
|
||||
console.log(SumlImpl);
|
||||
const instance = new SumlImpl.default();
|
||||
|
||||
/**
|
||||
@ -18,4 +18,4 @@ export function parse(value: string): unknown {
|
||||
*/
|
||||
export function dump(value: unknown): string {
|
||||
return instance.dump(value);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,9 @@ export function identity<T>(value: T): T {
|
||||
|
||||
// Generally, don't use this function to define commonly used functions.
|
||||
// Prefer to write a manual implementation.
|
||||
export function not<Args extends Array<unknown>>(f: (...args: Args) => boolean): (...args: Args) => boolean {
|
||||
export function not<Args extends Array<unknown>>(
|
||||
f: (...args: Args) => boolean
|
||||
): (...args: Args) => boolean {
|
||||
return (...args: Args) => !f(...args);
|
||||
}
|
||||
export function isNotNull<T>(value: T | null | undefined): value is T {
|
||||
@ -24,12 +26,14 @@ export const isBlank = not(isNotBlank);
|
||||
|
||||
// This is unnecessarily typed but I don't really care, it works doesn't it?
|
||||
export function toLowerCase<S extends string>(value: S): Lowercase<S> {
|
||||
return value.toLowerCase() as Lowercase<S>
|
||||
return value.toLowerCase() as Lowercase<S>;
|
||||
}
|
||||
|
||||
export function parseIntOrThrow(value: string, radix?: number): number {
|
||||
if (radix != null && (radix < 2 || radix > 36)) {
|
||||
throw new Error(`invalid radix ${radix} - must be between 2 and 36 (inclusive)`);
|
||||
throw new Error(
|
||||
`invalid radix ${radix} - must be between 2 and 36 (inclusive)`
|
||||
);
|
||||
}
|
||||
const parsed = parseInt(value, radix);
|
||||
if (isNaN(parsed)) {
|
||||
@ -62,7 +66,10 @@ export function capitalizeFirstLetter(value: string) {
|
||||
return value.charAt(0).toUpperCase() + value.substring(1);
|
||||
}
|
||||
|
||||
export function compileTemplate(template: string, values: Record<string, string>): string {
|
||||
export function compileTemplate(
|
||||
template: string,
|
||||
values: Record<string, string>
|
||||
): string {
|
||||
let string = "";
|
||||
let key = null;
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
@ -93,4 +100,4 @@ export function compileTemplate(template: string, values: Record<string, string>
|
||||
string = string.replace(`{${key}}`, value);
|
||||
}*/
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
@ -2,32 +2,40 @@ import fsp from "node:fs/promises";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
console.log("Setting up project")
|
||||
console.log("Setting up project");
|
||||
|
||||
const url = new URL(import.meta.url);
|
||||
const projectDir = path.dirname(path.resolve(url.pathname.split('/').filter((v) => v && v.length > 0).join(path.sep)));
|
||||
const projectDir = path.dirname(
|
||||
path.resolve(
|
||||
url.pathname
|
||||
.split("/")
|
||||
.filter((v) => v && v.length > 0)
|
||||
.join(path.sep)
|
||||
)
|
||||
);
|
||||
const legacyDir = path.resolve(projectDir, "..");
|
||||
|
||||
console.log(`
|
||||
Project directory: ${projectDir}
|
||||
Legacy directory: ${legacyDir}
|
||||
`)
|
||||
`);
|
||||
|
||||
async function symlink(to, from) {
|
||||
if (!fs.existsSync(from)) {
|
||||
console.log(` Creating symlink from ${from} to ${to}`)
|
||||
await fsp.symlink(to, from, "dir")
|
||||
console.log(` Creating symlink from ${from} to ${to}`);
|
||||
await fsp.symlink(to, from, "dir");
|
||||
} else {
|
||||
console.log(` File ${from} already exists - not symlinking to ${to}`)
|
||||
console.log(` File ${from} already exists - not symlinking to ${to}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Create temporary symlinks
|
||||
// This step may very well be removed in the future.
|
||||
{
|
||||
const to = path.resolve(legacyDir, "locale"), from = path.resolve(projectDir, "locales");
|
||||
const to = path.resolve(legacyDir, "locale"),
|
||||
from = path.resolve(projectDir, "locales");
|
||||
await symlink(to, from);
|
||||
}
|
||||
|
||||
console.log(`
|
||||
Done!`)
|
||||
Done!`);
|
||||
|
Loading…
x
Reference in New Issue
Block a user