@worldware/msg-cli 0.0.5 → 0.1.1
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
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.calculateRelativePath = calculateRelativePath;
|
|
46
|
-
exports.importMsgProjectFile = importMsgProjectFile;
|
|
47
|
-
exports.writeMsgProjectFile = writeMsgProjectFile;
|
|
48
|
-
exports.loadPackageJsonForCreateProject = loadPackageJsonForCreateProject;
|
|
49
|
-
const fs_1 = require("fs");
|
|
50
|
-
const path_1 = require("path");
|
|
51
|
-
const url_1 = require("url");
|
|
52
|
-
const init_helpers_js_1 = require("./init-helpers.js");
|
|
53
|
-
/**
|
|
54
|
-
* Calculates the relative path from the i18n projects directory to the l10n translations directory.
|
|
55
|
-
* @param projectsDir - Absolute path to i18n/projects (e.g. root/i18n/projects)
|
|
56
|
-
* @param translationsDir - Absolute path to l10n/translations (e.g. root/l10n/translations)
|
|
57
|
-
* @returns Relative path string from projects to translations, suitable for import()
|
|
58
|
-
*/
|
|
59
|
-
function calculateRelativePath(projectsDir, translationsDir) {
|
|
60
|
-
const rel = (0, path_1.relative)(projectsDir, translationsDir);
|
|
61
|
-
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Imports an existing MsgProject module from the projects directory.
|
|
65
|
-
* @param projectsDir - Absolute path to i18n/projects
|
|
66
|
-
* @param projectName - Name of the project (file name without extension)
|
|
67
|
-
* @returns The default export (MsgProject instance or data) or undefined if not found
|
|
68
|
-
*/
|
|
69
|
-
function importMsgProjectFile(projectsDir, projectName) {
|
|
70
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
var _a;
|
|
72
|
-
const basePath = (0, path_1.join)(projectsDir, projectName);
|
|
73
|
-
const exts = [".ts", ".js"];
|
|
74
|
-
for (const ext of exts) {
|
|
75
|
-
const p = `${basePath}${ext}`;
|
|
76
|
-
if ((0, fs_1.existsSync)(p)) {
|
|
77
|
-
try {
|
|
78
|
-
const url = (0, url_1.pathToFileURL)(p).href;
|
|
79
|
-
const mod = yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
|
|
80
|
-
return ((_a = mod === null || mod === void 0 ? void 0 : mod.default) !== null && _a !== void 0 ? _a : mod);
|
|
81
|
-
}
|
|
82
|
-
catch (_b) {
|
|
83
|
-
return undefined;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return undefined;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Writes an MsgProject file to the projects directory.
|
|
92
|
-
* @param filePath - Absolute path of the file to write (including extension)
|
|
93
|
-
* @param content - Full file content string
|
|
94
|
-
*/
|
|
95
|
-
function writeMsgProjectFile(filePath, content) {
|
|
96
|
-
const dir = (0, path_1.dirname)(filePath);
|
|
97
|
-
if (!(0, fs_1.existsSync)(dir)) {
|
|
98
|
-
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
99
|
-
}
|
|
100
|
-
(0, fs_1.writeFileSync)(filePath, content, "utf-8");
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Loads package.json from the given directory (walking up to find it).
|
|
104
|
-
* Requires directories.i18n and directories.l10n.
|
|
105
|
-
* @param cwd - Directory to start from (e.g. process.cwd())
|
|
106
|
-
* @returns Parsed package.json with directories.i18n and directories.l10n
|
|
107
|
-
* @throws Error if package.json not found or missing directories.i18n / directories.l10n
|
|
108
|
-
*/
|
|
109
|
-
function loadPackageJsonForCreateProject(cwd) {
|
|
110
|
-
const ctx = (0, init_helpers_js_1.loadPackageJsonForMsg)(cwd, { requireL10n: true });
|
|
111
|
-
return ctx.pkg;
|
|
112
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.dynamicImportFromUrl = dynamicImportFromUrl;
|
|
46
|
-
exports.readPackageJsonForCreateResource = readPackageJsonForCreateResource;
|
|
47
|
-
exports.importMsgProjectForResource = importMsgProjectForResource;
|
|
48
|
-
exports.generateMsgResourceContent = generateMsgResourceContent;
|
|
49
|
-
exports.writeMsgResourceFile = writeMsgResourceFile;
|
|
50
|
-
const fs_1 = require("fs");
|
|
51
|
-
const path_1 = require("path");
|
|
52
|
-
const url_1 = require("url");
|
|
53
|
-
const init_helpers_js_1 = require("./init-helpers.js");
|
|
54
|
-
/**
|
|
55
|
-
* Dynamically import a module from a file URL.
|
|
56
|
-
* Tries native import() first (works in ESM/Vitest); falls back to Function-based
|
|
57
|
-
* import when running as compiled CJS (where import() would become require()).
|
|
58
|
-
*/
|
|
59
|
-
function dynamicImportFromUrl(url) {
|
|
60
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
-
try {
|
|
62
|
-
return yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
|
|
63
|
-
}
|
|
64
|
-
catch (_a) {
|
|
65
|
-
const load = new Function("url", "return import(url)");
|
|
66
|
-
return load(url);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Reads package.json and returns i18n directory and module type info.
|
|
72
|
-
* @param cwd - Directory to start from (e.g. process.cwd())
|
|
73
|
-
* @returns Object with i18nDir, isEsm, useTypeScript
|
|
74
|
-
* @throws Error if package.json not found or missing directories.i18n
|
|
75
|
-
*/
|
|
76
|
-
function readPackageJsonForCreateResource(cwd) {
|
|
77
|
-
const ctx = (0, init_helpers_js_1.loadPackageJsonForMsg)(cwd);
|
|
78
|
-
return {
|
|
79
|
-
i18nDir: ctx.i18nDir,
|
|
80
|
-
isEsm: ctx.isEsm,
|
|
81
|
-
useTypeScript: ctx.useTypeScript,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Derives dir (ltr/rtl) from a locale string based on language subtag.
|
|
86
|
-
* @param sourceLocale - Full locale (e.g. "en", "ar-SA", "he-IL")
|
|
87
|
-
* @returns "rtl" for ar/he, "ltr" otherwise
|
|
88
|
-
*/
|
|
89
|
-
function dirFromSourceLocale(sourceLocale) {
|
|
90
|
-
var _a, _b;
|
|
91
|
-
const lang = (_b = (_a = sourceLocale.split("-")[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : "";
|
|
92
|
-
return lang === "ar" || lang === "he" ? "rtl" : "ltr";
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Imports the MsgProject module and returns sourceLocale and dir (ltr/rtl).
|
|
96
|
-
* @param projectsDir - Absolute path to i18n/projects
|
|
97
|
-
* @param projectName - Name of the project file (without extension)
|
|
98
|
-
* @returns Object with sourceLocale and dir, or undefined if project not found
|
|
99
|
-
*/
|
|
100
|
-
function importMsgProjectForResource(projectsDir, projectName) {
|
|
101
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
-
var _a, _b, _c;
|
|
103
|
-
const basePath = (0, path_1.join)(projectsDir, projectName);
|
|
104
|
-
const exts = [".ts", ".js"];
|
|
105
|
-
for (const ext of exts) {
|
|
106
|
-
const p = `${basePath}${ext}`;
|
|
107
|
-
if ((0, fs_1.existsSync)(p)) {
|
|
108
|
-
try {
|
|
109
|
-
const url = (0, url_1.pathToFileURL)(p).href;
|
|
110
|
-
const mod = yield dynamicImportFromUrl(url);
|
|
111
|
-
const data = ((_a = mod === null || mod === void 0 ? void 0 : mod.default) !== null && _a !== void 0 ? _a : mod);
|
|
112
|
-
const sourceLocale = (_b = data === null || data === void 0 ? void 0 : data.locales) === null || _b === void 0 ? void 0 : _b.sourceLocale;
|
|
113
|
-
if (!sourceLocale || typeof sourceLocale !== "string") {
|
|
114
|
-
throw new Error(`Project file must export a default with locales.sourceLocale (got ${typeof ((_c = data === null || data === void 0 ? void 0 : data.locales) === null || _c === void 0 ? void 0 : _c.sourceLocale)}).`);
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
sourceLocale,
|
|
118
|
-
dir: dirFromSourceLocale(sourceLocale),
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
catch (err) {
|
|
122
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
123
|
-
throw new Error(`Project file '${projectName}${ext}' could not be loaded: ${message}`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return undefined;
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Generates the MsgResource file content as a string.
|
|
132
|
-
* @param params - Title, projectName, sourceLocale, dir, and isEsm
|
|
133
|
-
* @returns The generated file content
|
|
134
|
-
*/
|
|
135
|
-
function generateMsgResourceContent(params) {
|
|
136
|
-
const { title, projectName, sourceLocale, dir, isEsm } = params;
|
|
137
|
-
const projectImport = isEsm
|
|
138
|
-
? `../projects/${projectName}.js`
|
|
139
|
-
: `../projects/${projectName}`;
|
|
140
|
-
const messagesBlock = ` messages: [
|
|
141
|
-
{
|
|
142
|
-
key: 'example.message',
|
|
143
|
-
value: 'Example message.',
|
|
144
|
-
notes: [
|
|
145
|
-
{ type: 'description', content: 'This is an example message. You can delete it.' }
|
|
146
|
-
]
|
|
147
|
-
}
|
|
148
|
-
]`;
|
|
149
|
-
const titleStr = `'${title.replace(/'/g, "\\'")}'`;
|
|
150
|
-
const langStr = `'${sourceLocale.replace(/'/g, "\\'")}'`;
|
|
151
|
-
const dirStr = `'${dir}'`;
|
|
152
|
-
if (isEsm) {
|
|
153
|
-
return `import { MsgResource } from '@worldware/msg';
|
|
154
|
-
import project from '${projectImport}';
|
|
155
|
-
|
|
156
|
-
export default MsgResource.create({
|
|
157
|
-
title: ${titleStr},
|
|
158
|
-
attributes: {
|
|
159
|
-
lang: ${langStr},
|
|
160
|
-
dir: ${dirStr}
|
|
161
|
-
},
|
|
162
|
-
notes: [
|
|
163
|
-
{ type: 'DESCRIPTION', content: 'This is a generated file. Replace this description with your own.' }
|
|
164
|
-
],
|
|
165
|
-
${messagesBlock}
|
|
166
|
-
}, project);
|
|
167
|
-
`;
|
|
168
|
-
}
|
|
169
|
-
return `const { MsgResource } = require('@worldware/msg');
|
|
170
|
-
const project = require('${projectImport}');
|
|
171
|
-
|
|
172
|
-
module.exports = MsgResource.create({
|
|
173
|
-
title: ${titleStr},
|
|
174
|
-
attributes: {
|
|
175
|
-
lang: ${langStr},
|
|
176
|
-
dir: ${dirStr}
|
|
177
|
-
},
|
|
178
|
-
notes: [
|
|
179
|
-
{ type: 'DESCRIPTION', content: 'This is a generated file. Replace this description with your own.' }
|
|
180
|
-
],
|
|
181
|
-
${messagesBlock}
|
|
182
|
-
}, project);
|
|
183
|
-
`;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Writes the MsgResource content to file.
|
|
187
|
-
* @param filePath - Absolute path of the file to write (including extension)
|
|
188
|
-
* @param content - Full file content string
|
|
189
|
-
*/
|
|
190
|
-
function writeMsgResourceFile(filePath, content) {
|
|
191
|
-
const dir = (0, path_1.dirname)(filePath);
|
|
192
|
-
if (!(0, fs_1.existsSync)(dir)) {
|
|
193
|
-
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
194
|
-
}
|
|
195
|
-
(0, fs_1.writeFileSync)(filePath, content, "utf-8");
|
|
196
|
-
}
|
package/dist/lib/init-helpers.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_L10N_DIR = exports.DEFAULT_I18N_DIR = void 0;
|
|
4
|
-
exports.findPackageJsonPath = findPackageJsonPath;
|
|
5
|
-
exports.readPackageJson = readPackageJson;
|
|
6
|
-
exports.loadPackageJsonForMsg = loadPackageJsonForMsg;
|
|
7
|
-
exports.writePackageJson = writePackageJson;
|
|
8
|
-
exports.validatePaths = validatePaths;
|
|
9
|
-
exports.ensureDirectoriesWithGitkeep = ensureDirectoriesWithGitkeep;
|
|
10
|
-
exports.isAlreadyInitialized = isAlreadyInitialized;
|
|
11
|
-
exports.addDirectoriesToPackageJson = addDirectoriesToPackageJson;
|
|
12
|
-
exports.addImportAliasesToPackageJson = addImportAliasesToPackageJson;
|
|
13
|
-
exports.addScriptsToPackageJson = addScriptsToPackageJson;
|
|
14
|
-
exports.addTsconfigPaths = addTsconfigPaths;
|
|
15
|
-
const fs_1 = require("fs");
|
|
16
|
-
const path_1 = require("path");
|
|
17
|
-
/** Default relative path for the i18n directory. */
|
|
18
|
-
exports.DEFAULT_I18N_DIR = "src/i18n";
|
|
19
|
-
/** Default relative path for the l10n directory. */
|
|
20
|
-
exports.DEFAULT_L10N_DIR = "res/l10n";
|
|
21
|
-
/**
|
|
22
|
-
* Finds package.json by walking up from the given directory.
|
|
23
|
-
* @param cwd - Directory to start from (e.g. process.cwd())
|
|
24
|
-
* @returns Absolute path to package.json, or null if not found
|
|
25
|
-
*/
|
|
26
|
-
function findPackageJsonPath(cwd) {
|
|
27
|
-
let dir = cwd;
|
|
28
|
-
for (;;) {
|
|
29
|
-
const p = (0, path_1.join)(dir, "package.json");
|
|
30
|
-
if ((0, fs_1.existsSync)(p))
|
|
31
|
-
return p;
|
|
32
|
-
const parent = (0, path_1.dirname)(dir);
|
|
33
|
-
if (parent === dir)
|
|
34
|
-
return null;
|
|
35
|
-
dir = parent;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Reads and parses package.json.
|
|
40
|
-
* @param pkgPath - Absolute path to package.json
|
|
41
|
-
* @returns Parsed package.json object
|
|
42
|
-
* @throws Error if file is unreadable or invalid JSON
|
|
43
|
-
*/
|
|
44
|
-
function readPackageJson(pkgPath) {
|
|
45
|
-
const raw = (0, fs_1.readFileSync)(pkgPath, "utf-8");
|
|
46
|
-
try {
|
|
47
|
-
const parsed = JSON.parse(raw);
|
|
48
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
49
|
-
throw new Error("package.json must be a JSON object");
|
|
50
|
-
}
|
|
51
|
-
return parsed;
|
|
52
|
-
}
|
|
53
|
-
catch (err) {
|
|
54
|
-
if (err instanceof SyntaxError) {
|
|
55
|
-
throw new Error("Invalid package.json: " + err.message);
|
|
56
|
-
}
|
|
57
|
-
throw err;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Loads package.json for msg commands (create project, create resource, etc.).
|
|
62
|
-
* Finds package.json from cwd, validates directories, and derives module info.
|
|
63
|
-
* @param cwd - Directory to start from (e.g. process.cwd())
|
|
64
|
-
* @param options - requireL10n: if true, directories.l10n must exist (default: false)
|
|
65
|
-
* @returns Package context with pkgPath, rootDir, pkg, i18nDir, l10nDir?, isEsm, useTypeScript
|
|
66
|
-
* @throws Error if package.json not found or required directories missing
|
|
67
|
-
*/
|
|
68
|
-
function loadPackageJsonForMsg(cwd, options) {
|
|
69
|
-
const pkgPath = findPackageJsonPath(cwd);
|
|
70
|
-
if (!pkgPath) {
|
|
71
|
-
throw new Error("package.json not found. Run this command from the project root.");
|
|
72
|
-
}
|
|
73
|
-
let pkg;
|
|
74
|
-
try {
|
|
75
|
-
pkg = readPackageJson(pkgPath);
|
|
76
|
-
}
|
|
77
|
-
catch (err) {
|
|
78
|
-
const msg = err instanceof Error ? err.message : "package.json could not be parsed.";
|
|
79
|
-
throw new Error(msg);
|
|
80
|
-
}
|
|
81
|
-
const dirs = pkg.directories;
|
|
82
|
-
if (!dirs || typeof dirs !== "object" || !dirs.i18n) {
|
|
83
|
-
throw new Error("package.json must contain directories.i18n. Run 'msg init' first.");
|
|
84
|
-
}
|
|
85
|
-
if ((options === null || options === void 0 ? void 0 : options.requireL10n) && !dirs.l10n) {
|
|
86
|
-
throw new Error("package.json must contain directories.i18n and directories.l10n. Run 'msg init' first.");
|
|
87
|
-
}
|
|
88
|
-
const rootDir = (0, path_1.dirname)(pkgPath);
|
|
89
|
-
const useTypeScript = (0, fs_1.existsSync)((0, path_1.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
|
-
/**
|
|
102
|
-
* Writes package.json to disk with trailing newline.
|
|
103
|
-
* @param pkgPath - Absolute path to package.json
|
|
104
|
-
* @param pkg - Object to serialize
|
|
105
|
-
*/
|
|
106
|
-
function writePackageJson(pkgPath, pkg) {
|
|
107
|
-
const json = JSON.stringify(pkg, null, 2) + "\n";
|
|
108
|
-
(0, fs_1.writeFileSync)(pkgPath, json, "utf-8");
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Validates i18n and l10n paths (relative, non-empty, no absolute segments).
|
|
112
|
-
* @param rootDir - Project root (absolute)
|
|
113
|
-
* @param i18nDir - Relative i18n path
|
|
114
|
-
* @param l10nDir - Relative l10n path
|
|
115
|
-
* @returns Object with valid: boolean and optional error message
|
|
116
|
-
*/
|
|
117
|
-
function validatePaths(rootDir, i18nDir, l10nDir) {
|
|
118
|
-
const trimmedI18n = i18nDir.trim();
|
|
119
|
-
const trimmedL10n = l10nDir.trim();
|
|
120
|
-
if (!trimmedI18n)
|
|
121
|
-
return { valid: false, error: "i18n directory path cannot be empty" };
|
|
122
|
-
if (!trimmedL10n)
|
|
123
|
-
return { valid: false, error: "l10n directory path cannot be empty" };
|
|
124
|
-
if (trimmedI18n.startsWith("/") || /^[A-Za-z]:/.test(trimmedI18n)) {
|
|
125
|
-
return { valid: false, error: "i18n path must be relative" };
|
|
126
|
-
}
|
|
127
|
-
if (trimmedL10n.startsWith("/") || /^[A-Za-z]:/.test(trimmedL10n)) {
|
|
128
|
-
return { valid: false, error: "l10n path must be relative" };
|
|
129
|
-
}
|
|
130
|
-
return { valid: true };
|
|
131
|
-
}
|
|
132
|
-
const GITKEEP = ".gitkeep";
|
|
133
|
-
/**
|
|
134
|
-
* Ensures i18n and l10n directory trees exist and adds .gitkeep to leaf dirs.
|
|
135
|
-
* Leaf dirs: i18n/projects, i18n/resources, l10n/translations, l10n/xliff.
|
|
136
|
-
* @param rootDir - Project root (absolute)
|
|
137
|
-
* @param i18nDir - Relative i18n path
|
|
138
|
-
* @param l10nDir - Relative l10n path
|
|
139
|
-
* @param force - If true, overwrite/recreate even when dirs exist or are non-empty
|
|
140
|
-
*/
|
|
141
|
-
function ensureDirectoriesWithGitkeep(rootDir, i18nDir, l10nDir, force) {
|
|
142
|
-
const leaves = [
|
|
143
|
-
(0, path_1.join)(rootDir, i18nDir, "projects"),
|
|
144
|
-
(0, path_1.join)(rootDir, i18nDir, "resources"),
|
|
145
|
-
(0, path_1.join)(rootDir, l10nDir, "translations"),
|
|
146
|
-
(0, path_1.join)(rootDir, l10nDir, "xliff"),
|
|
147
|
-
];
|
|
148
|
-
for (const leaf of leaves) {
|
|
149
|
-
const parent = (0, path_1.dirname)(leaf);
|
|
150
|
-
if (!(0, fs_1.existsSync)(parent)) {
|
|
151
|
-
(0, fs_1.mkdirSync)(parent, { recursive: true });
|
|
152
|
-
}
|
|
153
|
-
if (!(0, fs_1.existsSync)(leaf)) {
|
|
154
|
-
(0, fs_1.mkdirSync)(leaf, { recursive: true });
|
|
155
|
-
}
|
|
156
|
-
const gitkeepPath = (0, path_1.join)(leaf, GITKEEP);
|
|
157
|
-
if (force || !(0, fs_1.existsSync)(gitkeepPath)) {
|
|
158
|
-
(0, fs_1.writeFileSync)(gitkeepPath, "", "utf-8");
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Returns true if package.json already has msg directories and they exist on disk.
|
|
164
|
-
*/
|
|
165
|
-
function isAlreadyInitialized(pkg, rootDir, i18nDir, l10nDir) {
|
|
166
|
-
const dirs = pkg.directories;
|
|
167
|
-
if (!dirs || typeof dirs !== "object")
|
|
168
|
-
return false;
|
|
169
|
-
if (dirs.i18n !== i18nDir || dirs.l10n !== l10nDir)
|
|
170
|
-
return false;
|
|
171
|
-
const i18nFull = (0, path_1.join)(rootDir, i18nDir);
|
|
172
|
-
const l10nFull = (0, path_1.join)(rootDir, l10nDir);
|
|
173
|
-
return (0, fs_1.existsSync)(i18nFull) && (0, fs_1.existsSync)(l10nFull);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Adds or overwrites directories.i18n, directories.l10n, directories.root in package.json.
|
|
177
|
-
*/
|
|
178
|
-
function addDirectoriesToPackageJson(pkg, i18nDir, l10nDir) {
|
|
179
|
-
const directories = Object.assign(Object.assign({}, pkg.directories), { i18n: i18nDir, l10n: l10nDir, root: "." });
|
|
180
|
-
return Object.assign(Object.assign({}, pkg), { directories });
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Adds import aliases #i18n/*, #l10n/*, #root/* to package.json imports.
|
|
184
|
-
*/
|
|
185
|
-
function addImportAliasesToPackageJson(pkg, i18nDir, l10nDir) {
|
|
186
|
-
const imports = Object.assign(Object.assign({}, pkg.imports), { "#i18n/*": `${i18nDir}/*`, "#l10n/*": `${l10nDir}/*`, "#root/*": "./*" });
|
|
187
|
-
return Object.assign(Object.assign({}, pkg), { imports });
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Adds i18n-export and l10n-import scripts to package.json.
|
|
191
|
-
*/
|
|
192
|
-
function addScriptsToPackageJson(pkg) {
|
|
193
|
-
const scripts = Object.assign(Object.assign({}, pkg.scripts), { "i18n-export": "msg export:resources", "l10n-import": "msg import:translations" });
|
|
194
|
-
return Object.assign(Object.assign({}, pkg), { scripts });
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Reads tsconfig.json, adds baseUrl and paths for #i18n/*, #l10n/*, #root/*, and writes it back.
|
|
198
|
-
* Merges into existing compilerOptions.paths and compilerOptions.baseUrl if present.
|
|
199
|
-
* @param tsconfigPath - Absolute path to tsconfig.json
|
|
200
|
-
* @param i18nDir - Relative i18n path
|
|
201
|
-
* @param l10nDir - Relative l10n path
|
|
202
|
-
*/
|
|
203
|
-
function addTsconfigPaths(tsconfigPath, i18nDir, l10nDir) {
|
|
204
|
-
var _a;
|
|
205
|
-
const raw = (0, fs_1.readFileSync)(tsconfigPath, "utf-8");
|
|
206
|
-
let config;
|
|
207
|
-
try {
|
|
208
|
-
config = JSON.parse(raw);
|
|
209
|
-
}
|
|
210
|
-
catch (_b) {
|
|
211
|
-
throw new Error("Invalid tsconfig.json");
|
|
212
|
-
}
|
|
213
|
-
if (!config.compilerOptions)
|
|
214
|
-
config.compilerOptions = {};
|
|
215
|
-
const co = config.compilerOptions;
|
|
216
|
-
co.baseUrl = (_a = co.baseUrl) !== null && _a !== void 0 ? _a : ".";
|
|
217
|
-
co.paths = Object.assign(Object.assign({}, co.paths), { "#i18n/*": [`${i18nDir}/*`], "#l10n/*": [`${l10nDir}/*`], "#root/*": ["./*"] });
|
|
218
|
-
(0, fs_1.writeFileSync)(tsconfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
219
|
-
}
|