@worldware/msg-cli 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-4Q2252JQ.mjs +50 -0
- package/dist/chunk-DBC2Y6VQ.mjs +167 -0
- package/dist/chunk-KKYCVD5M.mjs +136 -0
- package/dist/commands/create/project.cjs +293 -0
- package/dist/commands/create/project.d.mts +22 -0
- package/dist/commands/create/project.d.ts +22 -0
- package/dist/commands/create/project.mjs +151 -0
- package/dist/commands/create/resource.cjs +355 -0
- package/dist/commands/create/resource.d.mts +22 -0
- package/dist/commands/create/resource.d.ts +22 -0
- package/dist/commands/create/resource.mjs +143 -0
- package/dist/commands/init.cjs +259 -0
- package/dist/commands/init.d.mts +20 -0
- package/dist/commands/init.d.ts +20 -0
- package/dist/commands/init.mjs +133 -0
- package/dist/lib/create-project-helpers.cjs +163 -0
- package/dist/lib/create-project-helpers.d.mts +50 -0
- package/dist/lib/create-project-helpers.d.ts +50 -0
- package/dist/lib/create-project-helpers.mjs +14 -0
- package/dist/lib/create-resource-helpers.cjs +225 -0
- package/dist/lib/create-resource-helpers.d.mts +55 -0
- package/dist/lib/create-resource-helpers.d.ts +55 -0
- package/dist/lib/create-resource-helpers.mjs +15 -0
- package/dist/lib/init-helpers.cjs +203 -0
- package/dist/lib/init-helpers.d.mts +100 -0
- package/dist/lib/init-helpers.d.ts +100 -0
- package/dist/lib/init-helpers.mjs +30 -0
- package/dist/lib/utilities.cjs +203 -0
- package/dist/lib/utilities.d.mts +59 -0
- package/dist/lib/utilities.d.ts +59 -0
- package/dist/lib/utilities.mjs +172 -0
- package/package.json +7 -4
- package/dist/commands/create/project.js +0 -160
- package/dist/commands/create/resource.js +0 -169
- package/dist/commands/init.js +0 -131
- package/dist/lib/create-project-helpers.js +0 -112
- package/dist/lib/create-resource-helpers.js +0 -196
- package/dist/lib/init-helpers.js +0 -219
- package/dist/lib/utilities.js +0 -286
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { PackageJson } from './init-helpers.js';
|
|
2
|
+
|
|
3
|
+
/** Minimal type for MsgProject-like data we read from an existing project file. */
|
|
4
|
+
interface MsgProjectFileData {
|
|
5
|
+
project?: {
|
|
6
|
+
name?: string;
|
|
7
|
+
version?: number;
|
|
8
|
+
};
|
|
9
|
+
locales?: {
|
|
10
|
+
sourceLocale?: string;
|
|
11
|
+
pseudoLocale?: string;
|
|
12
|
+
targetLocales?: Record<string, string[]>;
|
|
13
|
+
};
|
|
14
|
+
loader?: unknown;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Calculates the relative path from the i18n projects directory to the l10n translations directory.
|
|
18
|
+
* @param projectsDir - Absolute path to i18n/projects (e.g. root/i18n/projects)
|
|
19
|
+
* @param translationsDir - Absolute path to l10n/translations (e.g. root/l10n/translations)
|
|
20
|
+
* @returns Relative path string from projects to translations, suitable for import()
|
|
21
|
+
*/
|
|
22
|
+
declare function calculateRelativePath(projectsDir: string, translationsDir: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Imports an existing MsgProject module from the projects directory.
|
|
25
|
+
* @param projectsDir - Absolute path to i18n/projects
|
|
26
|
+
* @param projectName - Name of the project (file name without extension)
|
|
27
|
+
* @returns The default export (MsgProject instance or data) or undefined if not found
|
|
28
|
+
*/
|
|
29
|
+
declare function importMsgProjectFile(projectsDir: string, projectName: string): Promise<MsgProjectFileData | undefined>;
|
|
30
|
+
/**
|
|
31
|
+
* Writes an MsgProject file to the projects directory.
|
|
32
|
+
* @param filePath - Absolute path of the file to write (including extension)
|
|
33
|
+
* @param content - Full file content string
|
|
34
|
+
*/
|
|
35
|
+
declare function writeMsgProjectFile(filePath: string, content: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Loads package.json from the given directory (walking up to find it).
|
|
38
|
+
* Requires directories.i18n and directories.l10n.
|
|
39
|
+
* @param cwd - Directory to start from (e.g. process.cwd())
|
|
40
|
+
* @returns Parsed package.json with directories.i18n and directories.l10n
|
|
41
|
+
* @throws Error if package.json not found or missing directories.i18n / directories.l10n
|
|
42
|
+
*/
|
|
43
|
+
declare function loadPackageJsonForCreateProject(cwd: string): PackageJson & {
|
|
44
|
+
directories: {
|
|
45
|
+
i18n: string;
|
|
46
|
+
l10n: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { type MsgProjectFileData, calculateRelativePath, importMsgProjectFile, loadPackageJsonForCreateProject, writeMsgProjectFile };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
calculateRelativePath,
|
|
3
|
+
importMsgProjectFile,
|
|
4
|
+
loadPackageJsonForCreateProject,
|
|
5
|
+
writeMsgProjectFile
|
|
6
|
+
} from "../chunk-4Q2252JQ.mjs";
|
|
7
|
+
import "../chunk-KKYCVD5M.mjs";
|
|
8
|
+
import "../chunk-DBC2Y6VQ.mjs";
|
|
9
|
+
export {
|
|
10
|
+
calculateRelativePath,
|
|
11
|
+
importMsgProjectFile,
|
|
12
|
+
loadPackageJsonForCreateProject,
|
|
13
|
+
writeMsgProjectFile
|
|
14
|
+
};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/create-resource-helpers.ts
|
|
21
|
+
var create_resource_helpers_exports = {};
|
|
22
|
+
__export(create_resource_helpers_exports, {
|
|
23
|
+
dynamicImportFromUrl: () => dynamicImportFromUrl,
|
|
24
|
+
generateMsgResourceContent: () => generateMsgResourceContent,
|
|
25
|
+
importMsgProjectForResource: () => importMsgProjectForResource,
|
|
26
|
+
readPackageJsonForCreateResource: () => readPackageJsonForCreateResource,
|
|
27
|
+
writeMsgResourceFile: () => writeMsgResourceFile
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(create_resource_helpers_exports);
|
|
30
|
+
var import_fs2 = require("fs");
|
|
31
|
+
var import_module = require("module");
|
|
32
|
+
var import_path2 = require("path");
|
|
33
|
+
var import_url = require("url");
|
|
34
|
+
|
|
35
|
+
// src/lib/init-helpers.ts
|
|
36
|
+
var import_fs = require("fs");
|
|
37
|
+
var import_path = require("path");
|
|
38
|
+
function findPackageJsonPath(cwd) {
|
|
39
|
+
let dir = cwd;
|
|
40
|
+
for (; ; ) {
|
|
41
|
+
const p = (0, import_path.join)(dir, "package.json");
|
|
42
|
+
if ((0, import_fs.existsSync)(p)) return p;
|
|
43
|
+
const parent = (0, import_path.dirname)(dir);
|
|
44
|
+
if (parent === dir) return null;
|
|
45
|
+
dir = parent;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function readPackageJson(pkgPath) {
|
|
49
|
+
const raw = (0, import_fs.readFileSync)(pkgPath, "utf-8");
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(raw);
|
|
52
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
53
|
+
throw new Error("package.json must be a JSON object");
|
|
54
|
+
}
|
|
55
|
+
return parsed;
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (err instanceof SyntaxError) {
|
|
58
|
+
throw new Error("Invalid package.json: " + err.message);
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function loadPackageJsonForMsg(cwd, options) {
|
|
64
|
+
const pkgPath = findPackageJsonPath(cwd);
|
|
65
|
+
if (!pkgPath) {
|
|
66
|
+
throw new Error("package.json not found. Run this command from the project root.");
|
|
67
|
+
}
|
|
68
|
+
let pkg;
|
|
69
|
+
try {
|
|
70
|
+
pkg = readPackageJson(pkgPath);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
const msg = err instanceof Error ? err.message : "package.json could not be parsed.";
|
|
73
|
+
throw new Error(msg);
|
|
74
|
+
}
|
|
75
|
+
const dirs = pkg.directories;
|
|
76
|
+
if (!dirs || typeof dirs !== "object" || !dirs.i18n) {
|
|
77
|
+
throw new Error("package.json must contain directories.i18n. Run 'msg init' first.");
|
|
78
|
+
}
|
|
79
|
+
if (options?.requireL10n && !dirs.l10n) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
"package.json must contain directories.i18n and directories.l10n. Run 'msg init' first."
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
const rootDir = (0, import_path.dirname)(pkgPath);
|
|
85
|
+
const useTypeScript = (0, import_fs.existsSync)((0, import_path.join)(rootDir, "tsconfig.json"));
|
|
86
|
+
const isEsm = pkg.type === "module";
|
|
87
|
+
return {
|
|
88
|
+
pkgPath,
|
|
89
|
+
rootDir,
|
|
90
|
+
pkg,
|
|
91
|
+
i18nDir: dirs.i18n,
|
|
92
|
+
l10nDir: dirs.l10n,
|
|
93
|
+
isEsm,
|
|
94
|
+
useTypeScript
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/lib/create-resource-helpers.ts
|
|
99
|
+
async function dynamicImportFromUrl(url) {
|
|
100
|
+
try {
|
|
101
|
+
return await import(
|
|
102
|
+
/* @vite-ignore */
|
|
103
|
+
url
|
|
104
|
+
);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
107
|
+
const useRequire = msg.includes("dynamic import callback") || msg.includes("ERR_VM_DYNAMIC_IMPORT");
|
|
108
|
+
if (useRequire) {
|
|
109
|
+
try {
|
|
110
|
+
const path = url.startsWith("file:") ? (0, import_url.fileURLToPath)(url) : url;
|
|
111
|
+
const base = (0, import_url.pathToFileURL)(process.cwd()).href;
|
|
112
|
+
const req = (0, import_module.createRequire)(base);
|
|
113
|
+
const mod = req(path);
|
|
114
|
+
return Promise.resolve(mod ?? {});
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
throw err;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function readPackageJsonForCreateResource(cwd) {
|
|
122
|
+
const ctx = loadPackageJsonForMsg(cwd);
|
|
123
|
+
return {
|
|
124
|
+
i18nDir: ctx.i18nDir,
|
|
125
|
+
isEsm: ctx.isEsm,
|
|
126
|
+
useTypeScript: ctx.useTypeScript
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function dirFromSourceLocale(sourceLocale) {
|
|
130
|
+
const lang = sourceLocale.split("-")[0]?.toLowerCase() ?? "";
|
|
131
|
+
return lang === "ar" || lang === "he" ? "rtl" : "ltr";
|
|
132
|
+
}
|
|
133
|
+
async function importMsgProjectForResource(projectsDir, projectName) {
|
|
134
|
+
const basePath = (0, import_path2.join)(projectsDir, projectName);
|
|
135
|
+
const exts = [".ts", ".js"];
|
|
136
|
+
for (const ext of exts) {
|
|
137
|
+
const p = `${basePath}${ext}`;
|
|
138
|
+
if ((0, import_fs2.existsSync)(p)) {
|
|
139
|
+
try {
|
|
140
|
+
const url = (0, import_url.pathToFileURL)(p).href;
|
|
141
|
+
const mod = await dynamicImportFromUrl(url);
|
|
142
|
+
const data = mod?.default ?? mod;
|
|
143
|
+
const sourceLocale = data?.locales?.sourceLocale;
|
|
144
|
+
if (!sourceLocale || typeof sourceLocale !== "string") {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`Project file must export a default with locales.sourceLocale (got ${typeof data?.locales?.sourceLocale}).`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
sourceLocale,
|
|
151
|
+
dir: dirFromSourceLocale(sourceLocale)
|
|
152
|
+
};
|
|
153
|
+
} catch (err) {
|
|
154
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Project file '${projectName}${ext}' could not be loaded: ${message}`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return void 0;
|
|
162
|
+
}
|
|
163
|
+
function generateMsgResourceContent(params) {
|
|
164
|
+
const { title, projectName, sourceLocale, dir, isEsm } = params;
|
|
165
|
+
const projectImport = isEsm ? `../projects/${projectName}.js` : `../projects/${projectName}`;
|
|
166
|
+
const messagesBlock = ` messages: [
|
|
167
|
+
{
|
|
168
|
+
key: 'example.message',
|
|
169
|
+
value: 'Example message.',
|
|
170
|
+
notes: [
|
|
171
|
+
{ type: 'description', content: 'This is an example message. You can delete it.' }
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
]`;
|
|
175
|
+
const titleStr = `'${title.replace(/'/g, "\\'")}'`;
|
|
176
|
+
const langStr = `'${sourceLocale.replace(/'/g, "\\'")}'`;
|
|
177
|
+
const dirStr = `'${dir}'`;
|
|
178
|
+
if (isEsm) {
|
|
179
|
+
return `import { MsgResource } from '@worldware/msg';
|
|
180
|
+
import project from '${projectImport}';
|
|
181
|
+
|
|
182
|
+
export default MsgResource.create({
|
|
183
|
+
title: ${titleStr},
|
|
184
|
+
attributes: {
|
|
185
|
+
lang: ${langStr},
|
|
186
|
+
dir: ${dirStr}
|
|
187
|
+
},
|
|
188
|
+
notes: [
|
|
189
|
+
{ type: 'DESCRIPTION', content: 'This is a generated file. Replace this description with your own.' }
|
|
190
|
+
],
|
|
191
|
+
${messagesBlock}
|
|
192
|
+
}, project);
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
return `const { MsgResource } = require('@worldware/msg');
|
|
196
|
+
const project = require('${projectImport}');
|
|
197
|
+
|
|
198
|
+
module.exports = MsgResource.create({
|
|
199
|
+
title: ${titleStr},
|
|
200
|
+
attributes: {
|
|
201
|
+
lang: ${langStr},
|
|
202
|
+
dir: ${dirStr}
|
|
203
|
+
},
|
|
204
|
+
notes: [
|
|
205
|
+
{ type: 'DESCRIPTION', content: 'This is a generated file. Replace this description with your own.' }
|
|
206
|
+
],
|
|
207
|
+
${messagesBlock}
|
|
208
|
+
}, project);
|
|
209
|
+
`;
|
|
210
|
+
}
|
|
211
|
+
function writeMsgResourceFile(filePath, content) {
|
|
212
|
+
const dir = (0, import_path2.dirname)(filePath);
|
|
213
|
+
if (!(0, import_fs2.existsSync)(dir)) {
|
|
214
|
+
(0, import_fs2.mkdirSync)(dir, { recursive: true });
|
|
215
|
+
}
|
|
216
|
+
(0, import_fs2.writeFileSync)(filePath, content, "utf-8");
|
|
217
|
+
}
|
|
218
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
219
|
+
0 && (module.exports = {
|
|
220
|
+
dynamicImportFromUrl,
|
|
221
|
+
generateMsgResourceContent,
|
|
222
|
+
importMsgProjectForResource,
|
|
223
|
+
readPackageJsonForCreateResource,
|
|
224
|
+
writeMsgResourceFile
|
|
225
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamically import a module from a file URL.
|
|
3
|
+
* Tries native import() first; on VM/runner errors (e.g. Vitest "dynamic import
|
|
4
|
+
* callback was not specified") falls back to require() so CJS files load.
|
|
5
|
+
*/
|
|
6
|
+
declare function dynamicImportFromUrl(url: string): Promise<Record<string, unknown>>;
|
|
7
|
+
/** Result of reading package.json for create-resource (i18n dir, module type). */
|
|
8
|
+
interface PackageJsonForCreateResource {
|
|
9
|
+
i18nDir: string;
|
|
10
|
+
isEsm: boolean;
|
|
11
|
+
useTypeScript: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Minimal type for MsgProject-like data we read to get sourceLocale and dir. */
|
|
14
|
+
interface MsgProjectForResource {
|
|
15
|
+
locales?: {
|
|
16
|
+
sourceLocale?: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reads package.json and returns i18n directory and module type info.
|
|
21
|
+
* @param cwd - Directory to start from (e.g. process.cwd())
|
|
22
|
+
* @returns Object with i18nDir, isEsm, useTypeScript
|
|
23
|
+
* @throws Error if package.json not found or missing directories.i18n
|
|
24
|
+
*/
|
|
25
|
+
declare function readPackageJsonForCreateResource(cwd: string): PackageJsonForCreateResource;
|
|
26
|
+
/**
|
|
27
|
+
* Imports the MsgProject module and returns sourceLocale and dir (ltr/rtl).
|
|
28
|
+
* @param projectsDir - Absolute path to i18n/projects
|
|
29
|
+
* @param projectName - Name of the project file (without extension)
|
|
30
|
+
* @returns Object with sourceLocale and dir, or undefined if project not found
|
|
31
|
+
*/
|
|
32
|
+
declare function importMsgProjectForResource(projectsDir: string, projectName: string): Promise<{
|
|
33
|
+
sourceLocale: string;
|
|
34
|
+
dir: "ltr" | "rtl";
|
|
35
|
+
} | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* Generates the MsgResource file content as a string.
|
|
38
|
+
* @param params - Title, projectName, sourceLocale, dir, and isEsm
|
|
39
|
+
* @returns The generated file content
|
|
40
|
+
*/
|
|
41
|
+
declare function generateMsgResourceContent(params: {
|
|
42
|
+
title: string;
|
|
43
|
+
projectName: string;
|
|
44
|
+
sourceLocale: string;
|
|
45
|
+
dir: "ltr" | "rtl";
|
|
46
|
+
isEsm: boolean;
|
|
47
|
+
}): string;
|
|
48
|
+
/**
|
|
49
|
+
* Writes the MsgResource content to file.
|
|
50
|
+
* @param filePath - Absolute path of the file to write (including extension)
|
|
51
|
+
* @param content - Full file content string
|
|
52
|
+
*/
|
|
53
|
+
declare function writeMsgResourceFile(filePath: string, content: string): void;
|
|
54
|
+
|
|
55
|
+
export { type MsgProjectForResource, type PackageJsonForCreateResource, dynamicImportFromUrl, generateMsgResourceContent, importMsgProjectForResource, readPackageJsonForCreateResource, writeMsgResourceFile };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamically import a module from a file URL.
|
|
3
|
+
* Tries native import() first; on VM/runner errors (e.g. Vitest "dynamic import
|
|
4
|
+
* callback was not specified") falls back to require() so CJS files load.
|
|
5
|
+
*/
|
|
6
|
+
declare function dynamicImportFromUrl(url: string): Promise<Record<string, unknown>>;
|
|
7
|
+
/** Result of reading package.json for create-resource (i18n dir, module type). */
|
|
8
|
+
interface PackageJsonForCreateResource {
|
|
9
|
+
i18nDir: string;
|
|
10
|
+
isEsm: boolean;
|
|
11
|
+
useTypeScript: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Minimal type for MsgProject-like data we read to get sourceLocale and dir. */
|
|
14
|
+
interface MsgProjectForResource {
|
|
15
|
+
locales?: {
|
|
16
|
+
sourceLocale?: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reads package.json and returns i18n directory and module type info.
|
|
21
|
+
* @param cwd - Directory to start from (e.g. process.cwd())
|
|
22
|
+
* @returns Object with i18nDir, isEsm, useTypeScript
|
|
23
|
+
* @throws Error if package.json not found or missing directories.i18n
|
|
24
|
+
*/
|
|
25
|
+
declare function readPackageJsonForCreateResource(cwd: string): PackageJsonForCreateResource;
|
|
26
|
+
/**
|
|
27
|
+
* Imports the MsgProject module and returns sourceLocale and dir (ltr/rtl).
|
|
28
|
+
* @param projectsDir - Absolute path to i18n/projects
|
|
29
|
+
* @param projectName - Name of the project file (without extension)
|
|
30
|
+
* @returns Object with sourceLocale and dir, or undefined if project not found
|
|
31
|
+
*/
|
|
32
|
+
declare function importMsgProjectForResource(projectsDir: string, projectName: string): Promise<{
|
|
33
|
+
sourceLocale: string;
|
|
34
|
+
dir: "ltr" | "rtl";
|
|
35
|
+
} | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* Generates the MsgResource file content as a string.
|
|
38
|
+
* @param params - Title, projectName, sourceLocale, dir, and isEsm
|
|
39
|
+
* @returns The generated file content
|
|
40
|
+
*/
|
|
41
|
+
declare function generateMsgResourceContent(params: {
|
|
42
|
+
title: string;
|
|
43
|
+
projectName: string;
|
|
44
|
+
sourceLocale: string;
|
|
45
|
+
dir: "ltr" | "rtl";
|
|
46
|
+
isEsm: boolean;
|
|
47
|
+
}): string;
|
|
48
|
+
/**
|
|
49
|
+
* Writes the MsgResource content to file.
|
|
50
|
+
* @param filePath - Absolute path of the file to write (including extension)
|
|
51
|
+
* @param content - Full file content string
|
|
52
|
+
*/
|
|
53
|
+
declare function writeMsgResourceFile(filePath: string, content: string): void;
|
|
54
|
+
|
|
55
|
+
export { type MsgProjectForResource, type PackageJsonForCreateResource, dynamicImportFromUrl, generateMsgResourceContent, importMsgProjectForResource, readPackageJsonForCreateResource, writeMsgResourceFile };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dynamicImportFromUrl,
|
|
3
|
+
generateMsgResourceContent,
|
|
4
|
+
importMsgProjectForResource,
|
|
5
|
+
readPackageJsonForCreateResource,
|
|
6
|
+
writeMsgResourceFile
|
|
7
|
+
} from "../chunk-KKYCVD5M.mjs";
|
|
8
|
+
import "../chunk-DBC2Y6VQ.mjs";
|
|
9
|
+
export {
|
|
10
|
+
dynamicImportFromUrl,
|
|
11
|
+
generateMsgResourceContent,
|
|
12
|
+
importMsgProjectForResource,
|
|
13
|
+
readPackageJsonForCreateResource,
|
|
14
|
+
writeMsgResourceFile
|
|
15
|
+
};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/init-helpers.ts
|
|
21
|
+
var init_helpers_exports = {};
|
|
22
|
+
__export(init_helpers_exports, {
|
|
23
|
+
DEFAULT_I18N_DIR: () => DEFAULT_I18N_DIR,
|
|
24
|
+
DEFAULT_L10N_DIR: () => DEFAULT_L10N_DIR,
|
|
25
|
+
addDirectoriesToPackageJson: () => addDirectoriesToPackageJson,
|
|
26
|
+
addImportAliasesToPackageJson: () => addImportAliasesToPackageJson,
|
|
27
|
+
addScriptsToPackageJson: () => addScriptsToPackageJson,
|
|
28
|
+
addTsconfigPaths: () => addTsconfigPaths,
|
|
29
|
+
ensureDirectoriesWithGitkeep: () => ensureDirectoriesWithGitkeep,
|
|
30
|
+
findPackageJsonPath: () => findPackageJsonPath,
|
|
31
|
+
isAlreadyInitialized: () => isAlreadyInitialized,
|
|
32
|
+
loadPackageJsonForMsg: () => loadPackageJsonForMsg,
|
|
33
|
+
readPackageJson: () => readPackageJson,
|
|
34
|
+
validatePaths: () => validatePaths,
|
|
35
|
+
writePackageJson: () => writePackageJson
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(init_helpers_exports);
|
|
38
|
+
var import_fs = require("fs");
|
|
39
|
+
var import_path = require("path");
|
|
40
|
+
var DEFAULT_I18N_DIR = "src/i18n";
|
|
41
|
+
var DEFAULT_L10N_DIR = "res/l10n";
|
|
42
|
+
function findPackageJsonPath(cwd) {
|
|
43
|
+
let dir = cwd;
|
|
44
|
+
for (; ; ) {
|
|
45
|
+
const p = (0, import_path.join)(dir, "package.json");
|
|
46
|
+
if ((0, import_fs.existsSync)(p)) return p;
|
|
47
|
+
const parent = (0, import_path.dirname)(dir);
|
|
48
|
+
if (parent === dir) return null;
|
|
49
|
+
dir = parent;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function readPackageJson(pkgPath) {
|
|
53
|
+
const raw = (0, import_fs.readFileSync)(pkgPath, "utf-8");
|
|
54
|
+
try {
|
|
55
|
+
const parsed = JSON.parse(raw);
|
|
56
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
57
|
+
throw new Error("package.json must be a JSON object");
|
|
58
|
+
}
|
|
59
|
+
return parsed;
|
|
60
|
+
} catch (err) {
|
|
61
|
+
if (err instanceof SyntaxError) {
|
|
62
|
+
throw new Error("Invalid package.json: " + err.message);
|
|
63
|
+
}
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function loadPackageJsonForMsg(cwd, options) {
|
|
68
|
+
const pkgPath = findPackageJsonPath(cwd);
|
|
69
|
+
if (!pkgPath) {
|
|
70
|
+
throw new Error("package.json not found. Run this command from the project root.");
|
|
71
|
+
}
|
|
72
|
+
let pkg;
|
|
73
|
+
try {
|
|
74
|
+
pkg = readPackageJson(pkgPath);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
const msg = err instanceof Error ? err.message : "package.json could not be parsed.";
|
|
77
|
+
throw new Error(msg);
|
|
78
|
+
}
|
|
79
|
+
const dirs = pkg.directories;
|
|
80
|
+
if (!dirs || typeof dirs !== "object" || !dirs.i18n) {
|
|
81
|
+
throw new Error("package.json must contain directories.i18n. Run 'msg init' first.");
|
|
82
|
+
}
|
|
83
|
+
if (options?.requireL10n && !dirs.l10n) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
"package.json must contain directories.i18n and directories.l10n. Run 'msg init' first."
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const rootDir = (0, import_path.dirname)(pkgPath);
|
|
89
|
+
const useTypeScript = (0, import_fs.existsSync)((0, import_path.join)(rootDir, "tsconfig.json"));
|
|
90
|
+
const isEsm = pkg.type === "module";
|
|
91
|
+
return {
|
|
92
|
+
pkgPath,
|
|
93
|
+
rootDir,
|
|
94
|
+
pkg,
|
|
95
|
+
i18nDir: dirs.i18n,
|
|
96
|
+
l10nDir: dirs.l10n,
|
|
97
|
+
isEsm,
|
|
98
|
+
useTypeScript
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function writePackageJson(pkgPath, pkg) {
|
|
102
|
+
const json = JSON.stringify(pkg, null, 2) + "\n";
|
|
103
|
+
(0, import_fs.writeFileSync)(pkgPath, json, "utf-8");
|
|
104
|
+
}
|
|
105
|
+
function validatePaths(rootDir, i18nDir, l10nDir) {
|
|
106
|
+
const trimmedI18n = i18nDir.trim();
|
|
107
|
+
const trimmedL10n = l10nDir.trim();
|
|
108
|
+
if (!trimmedI18n) return { valid: false, error: "i18n directory path cannot be empty" };
|
|
109
|
+
if (!trimmedL10n) return { valid: false, error: "l10n directory path cannot be empty" };
|
|
110
|
+
if (trimmedI18n.startsWith("/") || /^[A-Za-z]:/.test(trimmedI18n)) {
|
|
111
|
+
return { valid: false, error: "i18n path must be relative" };
|
|
112
|
+
}
|
|
113
|
+
if (trimmedL10n.startsWith("/") || /^[A-Za-z]:/.test(trimmedL10n)) {
|
|
114
|
+
return { valid: false, error: "l10n path must be relative" };
|
|
115
|
+
}
|
|
116
|
+
return { valid: true };
|
|
117
|
+
}
|
|
118
|
+
var GITKEEP = ".gitkeep";
|
|
119
|
+
function ensureDirectoriesWithGitkeep(rootDir, i18nDir, l10nDir, force) {
|
|
120
|
+
const leaves = [
|
|
121
|
+
(0, import_path.join)(rootDir, i18nDir, "projects"),
|
|
122
|
+
(0, import_path.join)(rootDir, i18nDir, "resources"),
|
|
123
|
+
(0, import_path.join)(rootDir, l10nDir, "translations"),
|
|
124
|
+
(0, import_path.join)(rootDir, l10nDir, "xliff")
|
|
125
|
+
];
|
|
126
|
+
for (const leaf of leaves) {
|
|
127
|
+
const parent = (0, import_path.dirname)(leaf);
|
|
128
|
+
if (!(0, import_fs.existsSync)(parent)) {
|
|
129
|
+
(0, import_fs.mkdirSync)(parent, { recursive: true });
|
|
130
|
+
}
|
|
131
|
+
if (!(0, import_fs.existsSync)(leaf)) {
|
|
132
|
+
(0, import_fs.mkdirSync)(leaf, { recursive: true });
|
|
133
|
+
}
|
|
134
|
+
const gitkeepPath = (0, import_path.join)(leaf, GITKEEP);
|
|
135
|
+
if (force || !(0, import_fs.existsSync)(gitkeepPath)) {
|
|
136
|
+
(0, import_fs.writeFileSync)(gitkeepPath, "", "utf-8");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function isAlreadyInitialized(pkg, rootDir, i18nDir, l10nDir) {
|
|
141
|
+
const dirs = pkg.directories;
|
|
142
|
+
if (!dirs || typeof dirs !== "object") return false;
|
|
143
|
+
if (dirs.i18n !== i18nDir || dirs.l10n !== l10nDir) return false;
|
|
144
|
+
const i18nFull = (0, import_path.join)(rootDir, i18nDir);
|
|
145
|
+
const l10nFull = (0, import_path.join)(rootDir, l10nDir);
|
|
146
|
+
return (0, import_fs.existsSync)(i18nFull) && (0, import_fs.existsSync)(l10nFull);
|
|
147
|
+
}
|
|
148
|
+
function addDirectoriesToPackageJson(pkg, i18nDir, l10nDir) {
|
|
149
|
+
const directories = { ...pkg.directories, i18n: i18nDir, l10n: l10nDir, root: "." };
|
|
150
|
+
return { ...pkg, directories };
|
|
151
|
+
}
|
|
152
|
+
function addImportAliasesToPackageJson(pkg, i18nDir, l10nDir) {
|
|
153
|
+
const imports = {
|
|
154
|
+
...pkg.imports,
|
|
155
|
+
"#i18n/*": `${i18nDir}/*`,
|
|
156
|
+
"#l10n/*": `${l10nDir}/*`,
|
|
157
|
+
"#root/*": "./*"
|
|
158
|
+
};
|
|
159
|
+
return { ...pkg, imports };
|
|
160
|
+
}
|
|
161
|
+
function addScriptsToPackageJson(pkg) {
|
|
162
|
+
const scripts = {
|
|
163
|
+
...pkg.scripts,
|
|
164
|
+
"i18n-export": "msg export:resources",
|
|
165
|
+
"l10n-import": "msg import:translations"
|
|
166
|
+
};
|
|
167
|
+
return { ...pkg, scripts };
|
|
168
|
+
}
|
|
169
|
+
function addTsconfigPaths(tsconfigPath, i18nDir, l10nDir) {
|
|
170
|
+
const raw = (0, import_fs.readFileSync)(tsconfigPath, "utf-8");
|
|
171
|
+
let config;
|
|
172
|
+
try {
|
|
173
|
+
config = JSON.parse(raw);
|
|
174
|
+
} catch {
|
|
175
|
+
throw new Error("Invalid tsconfig.json");
|
|
176
|
+
}
|
|
177
|
+
if (!config.compilerOptions) config.compilerOptions = {};
|
|
178
|
+
const co = config.compilerOptions;
|
|
179
|
+
co.baseUrl = co.baseUrl ?? ".";
|
|
180
|
+
co.paths = {
|
|
181
|
+
...co.paths,
|
|
182
|
+
"#i18n/*": [`${i18nDir}/*`],
|
|
183
|
+
"#l10n/*": [`${l10nDir}/*`],
|
|
184
|
+
"#root/*": ["./*"]
|
|
185
|
+
};
|
|
186
|
+
(0, import_fs.writeFileSync)(tsconfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
187
|
+
}
|
|
188
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
189
|
+
0 && (module.exports = {
|
|
190
|
+
DEFAULT_I18N_DIR,
|
|
191
|
+
DEFAULT_L10N_DIR,
|
|
192
|
+
addDirectoriesToPackageJson,
|
|
193
|
+
addImportAliasesToPackageJson,
|
|
194
|
+
addScriptsToPackageJson,
|
|
195
|
+
addTsconfigPaths,
|
|
196
|
+
ensureDirectoriesWithGitkeep,
|
|
197
|
+
findPackageJsonPath,
|
|
198
|
+
isAlreadyInitialized,
|
|
199
|
+
loadPackageJsonForMsg,
|
|
200
|
+
readPackageJson,
|
|
201
|
+
validatePaths,
|
|
202
|
+
writePackageJson
|
|
203
|
+
});
|