@esgettext/tools 1.2.0 → 1.3.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.
@@ -31,9 +31,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
31
31
  step((generator = generator.apply(thisArg, _arguments || [])).next());
32
32
  });
33
33
  };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
34
37
  Object.defineProperty(exports, "__esModule", { value: true });
35
38
  exports.ConfigurationFactory = exports.ConfigurationSchema = void 0;
36
39
  const runtime_1 = require("@esgettext/runtime");
40
+ const package_json_1 = __importDefault(require("@npmcli/package-json"));
41
+ const normalize_package_data_1 = __importDefault(require("normalize-package-data"));
37
42
  const fs = __importStar(require("fs"));
38
43
  const path = __importStar(require("path"));
39
44
  const v = __importStar(require("valibot"));
@@ -46,10 +51,10 @@ const bugsAddressSchema = v.union([
46
51
  ]);
47
52
  const programSchema = (program) => {
48
53
  return v.strictObject({
49
- path: v.pipe(v.string(), v.nonEmpty(gtx._x("The field '{field}' must not be empty!", {
54
+ path: v.optional(v.pipe(v.string(), v.nonEmpty(gtx._x("The field '{field}' must not be empty!", {
50
55
  field: `programs.${program}.path`,
51
- }))),
52
- options: v.array(v.pipe(v.string(), v.regex(new RegExp('^(?:[A-Z]|[-a-z]{2,})')), v.nonEmpty())),
56
+ })))),
57
+ options: v.optional(v.array(v.pipe(v.string(), v.regex(new RegExp('^(?:[A-Z]|[-a-z]{2,})')), v.nonEmpty()))),
53
58
  });
54
59
  };
55
60
  exports.ConfigurationSchema = v.strictObject({
@@ -77,12 +82,16 @@ exports.ConfigurationSchema = v.strictObject({
77
82
  })))),
78
83
  'files-from': v.optional(v.pipe(v.string(gtx._x("The field '{field}' must be a string!", {
79
84
  field: 'package.files-from',
80
- })), v.nonEmpty(gtx._x("The field '{field}' must not be empty!", { field: 'package.files-from' })))),
85
+ })), v.nonEmpty(gtx._x("The field '{field}' must not be empty!", {
86
+ field: 'package.files-from',
87
+ })))),
81
88
  })),
82
89
  po: v.optional(v.strictObject({
83
90
  directory: v.optional(v.pipe(v.string(gtx._x("The field '{field}' must be a string!", {
84
91
  field: 'po.directory',
85
- })), v.nonEmpty(gtx._x("The field '{field}' must not be empty!", { field: 'po.directory' })))),
92
+ })), v.nonEmpty(gtx._x("The field '{field}' must not be empty!", {
93
+ field: 'po.directory',
94
+ })))),
86
95
  locales: v.optional(v.array(v.pipe(v.string(gtx._("The entries in 'po.locales' must be strings!")), v.nonEmpty(gtx._("The entries in 'po.locales' must not be empty!"))))),
87
96
  })),
88
97
  install: v.optional(v.strictObject({
@@ -92,24 +101,24 @@ exports.ConfigurationSchema = v.strictObject({
92
101
  msgmerge: v.optional(programSchema('msgmerge')),
93
102
  msgfmt: v.optional(programSchema('msgfmt')),
94
103
  })),
95
- files: v.array(v.string()),
104
+ files: v.optional(v.array(v.string())),
96
105
  });
97
106
  class ConfigurationFactory {
98
107
  constructor() { }
99
108
  static create(jsConfigFiles, pkgJsonFile, lang) {
100
109
  return __awaiter(this, void 0, void 0, function* () {
101
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
110
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
102
111
  if (ConfigurationFactory.instance) {
103
112
  return ConfigurationFactory.instance;
104
113
  }
105
114
  if (lang && !lang.match(/^zh-/)) {
106
115
  lang = lang.replace(/-.*/, '');
107
116
  }
108
- let jsConfigFilePath;
109
- let msgidBugsAddressFilePath;
110
- let nameFilePath;
111
- let copyrightHolderFilePath;
112
- let versionFilePath;
117
+ let jsConfigFile;
118
+ let msgidBugsAddressFile;
119
+ let nameFile;
120
+ let copyrightHolderFile;
121
+ let versionFile;
113
122
  const rootPath = process.cwd();
114
123
  let configuration = null;
115
124
  for (const file of jsConfigFiles) {
@@ -119,18 +128,18 @@ class ConfigurationFactory {
119
128
  if (data) {
120
129
  configuration = data;
121
130
  configuration.files = [file];
122
- jsConfigFilePath = file;
131
+ jsConfigFile = file;
123
132
  if ((_a = configuration.package) === null || _a === void 0 ? void 0 : _a['msgid-bugs-address']) {
124
- msgidBugsAddressFilePath = filePath;
133
+ msgidBugsAddressFile = filePath;
125
134
  }
126
135
  if ((_b = configuration.package) === null || _b === void 0 ? void 0 : _b.name) {
127
- nameFilePath = filePath;
136
+ nameFile = filePath;
128
137
  }
129
138
  if ((_c = configuration.package) === null || _c === void 0 ? void 0 : _c['copyright-holder']) {
130
- copyrightHolderFilePath = filePath;
139
+ copyrightHolderFile = filePath;
131
140
  }
132
141
  if ((_d = configuration.package) === null || _d === void 0 ? void 0 : _d.version) {
133
- versionFilePath = filePath;
142
+ versionFile = filePath;
134
143
  }
135
144
  break;
136
145
  }
@@ -147,102 +156,136 @@ class ConfigurationFactory {
147
156
  !configuration.package['name'] ||
148
157
  !configuration.package['copyright-holder'] ||
149
158
  !configuration.package['version']) {
150
- const packageJsonPath = pkgJsonFile;
151
- if (fs.existsSync(packageJsonPath)) {
152
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
153
- let fileUsed = false;
154
- if (!configuration && packageJson.esgettext) {
155
- configuration = packageJson.esgettext;
156
- configuration.files = [];
159
+ const packageJson = yield ConfigurationFactory.getPackageJson();
160
+ let fileUsed = false;
161
+ if (!configuration && packageJson.esgettext) {
162
+ configuration = packageJson.esgettext;
163
+ configuration.files = [];
164
+ fileUsed = true;
165
+ }
166
+ if (!configuration)
167
+ configuration = { files: [] };
168
+ if (!((_e = configuration.package) === null || _e === void 0 ? void 0 : _e['msgid-bugs-address'])) {
169
+ if ((_f = packageJson.bugs) === null || _f === void 0 ? void 0 : _f.url) {
170
+ (_g = configuration.package) !== null && _g !== void 0 ? _g : (configuration.package = {});
171
+ configuration.package['msgid-bugs-address'] = packageJson.bugs.url;
172
+ msgidBugsAddressFile = 'package.json: bugs.url';
157
173
  fileUsed = true;
158
174
  }
159
- if (!configuration)
160
- configuration = { files: [] };
161
- if (!((_e = configuration.package) === null || _e === void 0 ? void 0 : _e['msgid-bugs-address'])) {
162
- if ((_f = packageJson.bugs) === null || _f === void 0 ? void 0 : _f.email) {
163
- (_g = configuration.package) !== null && _g !== void 0 ? _g : (configuration.package = {});
164
- configuration.package['msgid-bugs-address'] =
165
- packageJson.bugs.email;
166
- msgidBugsAddressFilePath = 'package.json';
167
- fileUsed = true;
168
- }
169
- else if ((_h = packageJson.bugs) === null || _h === void 0 ? void 0 : _h.url) {
170
- (_j = configuration.package) !== null && _j !== void 0 ? _j : (configuration.package = {});
171
- configuration.package['msgid-bugs-address'] = packageJson.bugs.url;
172
- msgidBugsAddressFilePath = 'package.json';
173
- fileUsed = true;
174
- }
175
+ else if ((_h = packageJson.bugs) === null || _h === void 0 ? void 0 : _h.email) {
176
+ (_j = configuration.package) !== null && _j !== void 0 ? _j : (configuration.package = {});
177
+ configuration.package['msgid-bugs-address'] = packageJson.bugs.email;
178
+ msgidBugsAddressFile = 'package.json: bugs.email';
179
+ fileUsed = true;
175
180
  }
176
- if (!((_k = configuration.package) === null || _k === void 0 ? void 0 : _k.name)) {
177
- if (packageJson.name) {
178
- (_l = configuration.package) !== null && _l !== void 0 ? _l : (configuration.package = {});
179
- configuration.package.name = packageJson.name;
180
- nameFilePath = 'package.json';
181
- fileUsed = true;
182
- }
181
+ else if ((_l = (_k = packageJson.people) === null || _k === void 0 ? void 0 : _k.author) === null || _l === void 0 ? void 0 : _l.email) {
182
+ (_m = configuration.package) !== null && _m !== void 0 ? _m : (configuration.package = {});
183
+ configuration.package['msgid-bugs-address'] =
184
+ packageJson.people.author.email;
185
+ msgidBugsAddressFile = 'package.json: people.author';
186
+ fileUsed = true;
183
187
  }
184
- if (!((_m = configuration.package) === null || _m === void 0 ? void 0 : _m['copyright-holder'])) {
185
- if ((_o = packageJson.people) === null || _o === void 0 ? void 0 : _o.author) {
186
- (_p = configuration.package) !== null && _p !== void 0 ? _p : (configuration.package = {});
187
- configuration.package['copyright-holder'] =
188
- packageJson.people.author;
189
- copyrightHolderFilePath = 'package.json';
190
- fileUsed = true;
191
- }
188
+ }
189
+ if (!((_o = configuration.package) === null || _o === void 0 ? void 0 : _o.name)) {
190
+ if (packageJson.name) {
191
+ (_p = configuration.package) !== null && _p !== void 0 ? _p : (configuration.package = {});
192
+ configuration.package.name = packageJson.name;
193
+ nameFile = 'package.json';
194
+ fileUsed = true;
192
195
  }
193
- if (!((_q = configuration.package) === null || _q === void 0 ? void 0 : _q.version)) {
194
- if (packageJson.version) {
195
- (_r = configuration.package) !== null && _r !== void 0 ? _r : (configuration.package = {});
196
- configuration.package.version = packageJson.version;
197
- nameFilePath = 'package.json';
198
- fileUsed = true;
196
+ }
197
+ if (!((_q = configuration.package) === null || _q === void 0 ? void 0 : _q['copyright-holder'])) {
198
+ if ((_r = packageJson.people) === null || _r === void 0 ? void 0 : _r.author) {
199
+ (_s = configuration.package) !== null && _s !== void 0 ? _s : (configuration.package = {});
200
+ configuration.package['copyright-holder'] =
201
+ packageJson.people.author.name;
202
+ if (packageJson.people.author.email) {
203
+ configuration.package['copyright-holder'] +=
204
+ ` <${packageJson.people.author.email}>`;
199
205
  }
206
+ if (packageJson.people.author.url) {
207
+ configuration.package['copyright-holder'] +=
208
+ ` <${packageJson.people.author.url}>`;
209
+ }
210
+ copyrightHolderFile = 'package.json';
211
+ fileUsed = true;
200
212
  }
201
- if (fileUsed) {
202
- configuration.files.push('package.json');
213
+ }
214
+ if (!((_t = configuration.package) === null || _t === void 0 ? void 0 : _t.version)) {
215
+ if (packageJson.version) {
216
+ (_u = configuration.package) !== null && _u !== void 0 ? _u : (configuration.package = {});
217
+ configuration.package.version = packageJson.version;
218
+ nameFile = 'package.json';
219
+ fileUsed = true;
203
220
  }
204
221
  }
222
+ if (fileUsed) {
223
+ (_v = configuration.files) === null || _v === void 0 ? void 0 : _v.push('package.json');
224
+ }
205
225
  }
206
226
  if (!configuration)
207
- configuration = { files: [] };
208
- const result = v.safeParse(exports.ConfigurationSchema, configuration, { lang });
209
- if (!result.success) {
210
- const issues = result.issues;
211
- console.error(gtx._nx('There is one configuration error:', 'There are {num} configuration errors:', issues.length, { num: issues.length }));
212
- for (const issue of issues) {
213
- const path = v.getDotPath(issue) || gtx._('[path not set]');
214
- const message = issue.issues ? issue.issues[0].message : issue.message;
215
- let filename;
216
- switch (path) {
217
- case 'package.msgid-bugs-address':
218
- filename = msgidBugsAddressFilePath;
219
- break;
220
- case 'name':
221
- filename = nameFilePath;
222
- break;
223
- case 'copyright-holder':
224
- filename = copyrightHolderFilePath;
225
- break;
226
- case 'version':
227
- filename = versionFilePath;
228
- break;
229
- default:
230
- filename = jsConfigFilePath;
231
- break;
232
- }
233
- console.error(' ' +
234
- gtx._x('{programName}: error: {filename}: {variable}: {message}.', {
235
- variable: path,
236
- programName: 'esgettext',
237
- filename,
238
- message,
239
- }));
240
- }
227
+ configuration = {};
228
+ if (!this.validate(configuration, {
229
+ msgidBugsAddressFile: msgidBugsAddressFile,
230
+ nameFile: nameFile,
231
+ copyrightHolderFile: copyrightHolderFile,
232
+ versionFile: versionFile,
233
+ jsConfigFile: jsConfigFile,
234
+ }, lang)) {
241
235
  return null;
242
236
  }
243
237
  return configuration;
244
238
  });
245
239
  }
240
+ static validate(configuration, files, lang) {
241
+ const result = v.safeParse(exports.ConfigurationSchema, configuration, { lang });
242
+ if (!result.success) {
243
+ const issues = result.issues;
244
+ console.error(gtx._nx('There is one configuration error:', 'There are {num} configuration errors:', issues.length, { num: issues.length }));
245
+ for (const issue of issues) {
246
+ const path = v.getDotPath(issue) || gtx._('[path not set]');
247
+ const message = issue.issues ? issue.issues[0].message : issue.message;
248
+ let filename;
249
+ switch (path) {
250
+ case 'package.msgid-bugs-address':
251
+ filename = files.msgidBugsAddressFile;
252
+ break;
253
+ case 'name':
254
+ filename = files.nameFile;
255
+ break;
256
+ case 'copyright-holder':
257
+ filename = files.copyrightHolderFile;
258
+ break;
259
+ case 'version':
260
+ filename = files.versionFile;
261
+ break;
262
+ default:
263
+ filename = files.jsConfigFile;
264
+ break;
265
+ }
266
+ console.error('\t', gtx._x('{programName}: Error: {filename}: {variable}: {message}.', {
267
+ variable: path,
268
+ programName: 'esgettext',
269
+ filename,
270
+ message,
271
+ }));
272
+ }
273
+ return false;
274
+ }
275
+ return true;
276
+ }
277
+ static getPackageJson() {
278
+ return __awaiter(this, void 0, void 0, function* () {
279
+ try {
280
+ const data = yield package_json_1.default.load(process.cwd());
281
+ (0, normalize_package_data_1.default)(data.content);
282
+ return data.content;
283
+ }
284
+ catch (error) {
285
+ return {};
286
+ }
287
+ });
288
+ }
246
289
  static loadFile(filePath) {
247
290
  return __awaiter(this, void 0, void 0, function* () {
248
291
  const extension = path.extname(filePath);
package/dist/index.js CHANGED
@@ -22,12 +22,18 @@ const msgmerge_all_js_1 = require("./commands/msgmerge-all.js");
22
22
  const install_js_1 = require("./commands/install.js");
23
23
  const convert_js_1 = require("./commands/convert.js");
24
24
  const msgfmt_all_js_1 = require("./commands/msgfmt-all.js");
25
+ const init_js_1 = require("./commands/init.js");
26
+ const potfiles_js_1 = require("./commands/potfiles.js");
27
+ const add_language_js_1 = require("./commands/add-language.js");
25
28
  const commandNames = [
26
- 'xgettext',
27
- 'msgmerge-all',
28
- 'msgfmt-all',
29
- 'install',
29
+ 'add-language',
30
30
  'convert',
31
+ 'install',
32
+ 'init',
33
+ 'msgfmt-all',
34
+ 'msgmerge-all',
35
+ 'potfiles',
36
+ 'xgettext',
31
37
  ];
32
38
  const configFiles = locateConfigFiles();
33
39
  const pkgJsonFile = locatePkgJsonFile();
@@ -35,6 +41,7 @@ const gtx = runtime_1.Textdomain.getInstance('com.cantanea.esgettext-tools');
35
41
  gtx
36
42
  .resolve()
37
43
  .then(() => __awaiter(void 0, void 0, void 0, function* () {
44
+ var _a;
38
45
  const locale = runtime_1.Textdomain.selectLocale(['en-US', 'en-GB', 'de']);
39
46
  const ulocale = locale.replace('-', '_');
40
47
  const configuration = yield configuration_js_1.ConfigurationFactory.create(configFiles, pkgJsonFile, locale);
@@ -46,6 +53,9 @@ gtx
46
53
  'msgfmt-all': new msgfmt_all_js_1.MsgfmtAll(configuration),
47
54
  install: new install_js_1.Install(configuration),
48
55
  convert: new convert_js_1.Convert(configuration),
56
+ init: new init_js_1.Init(configuration),
57
+ potfiles: new potfiles_js_1.Potfiles(configuration),
58
+ 'add-language': new add_language_js_1.AddLanguage(configuration),
49
59
  };
50
60
  const program = (0, yargs_1.default)(process.argv.slice(2))
51
61
  .locale(ulocale)
@@ -55,21 +65,21 @@ gtx
55
65
  alias: ['config-file'],
56
66
  type: 'string',
57
67
  describe: gtx._('Path to configuration file'),
58
- default: 'esgettext.config.{mjs,cjs,js,json}'
68
+ default: 'esgettext.config.{mjs,cjs,js,json}',
59
69
  },
60
70
  package: {
61
71
  alias: ['package-json'],
62
72
  type: 'string',
63
73
  describe: gtx._("Path to 'package.json'"),
64
74
  default: 'package.json',
65
- }
75
+ },
66
76
  })
67
77
  .showHelpOnFail(false, gtx._x("Try {programName} '--help' for more information!", {
68
78
  programName: package_js_1.Package.getName(),
69
79
  }))
70
80
  .demandCommand(1, gtx._('Error: No command given.'))
71
81
  .scriptName(package_js_1.Package.getName());
72
- let epilogue = configuration.files.length
82
+ let epilogue = ((_a = configuration.files) === null || _a === void 0 ? void 0 : _a.length)
73
83
  ? gtx._x('Additional defaults read from: {files}.', {
74
84
  files: configuration.files.join(', '),
75
85
  }) + '\n\n'
@@ -126,7 +136,14 @@ function getArgument(option) {
126
136
  function locateConfigFiles() {
127
137
  var _a;
128
138
  const configFile = (_a = getArgument('config-file')) !== null && _a !== void 0 ? _a : getArgument('configuration');
129
- return configFile !== null ? [configFile] : ['esgettext.config.mjs', 'esgettext.config.cjs', 'esgettext.config.js', 'esgettext.config.json'];
139
+ return configFile !== null
140
+ ? [configFile]
141
+ : [
142
+ 'esgettext.config.mjs',
143
+ 'esgettext.config.cjs',
144
+ 'esgettext.config.js',
145
+ 'esgettext.config.json',
146
+ ];
130
147
  }
131
148
  function locatePkgJsonFile() {
132
149
  var _a;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.coerceOptions = void 0;
4
+ const runtime_1 = require("@esgettext/runtime");
5
+ const package_1 = require("./package");
6
+ const gtx = runtime_1.Textdomain.getInstance('com.cantanea.esgettext-tools');
7
+ function coerceOptions(args, optspecs) {
8
+ for (const optname in optspecs) {
9
+ const optspec = optspecs[optname];
10
+ const optkey = optname.replace(/-(.)/g, (_, group1) => group1.toUpperCase());
11
+ const arg = args[optkey];
12
+ const isArray = typeof arg === 'object' && Array.isArray(arg);
13
+ if (optspec.multi) {
14
+ if (typeof arg !== 'undefined' && !isArray) {
15
+ args[optkey] = [args[optkey]];
16
+ }
17
+ }
18
+ else {
19
+ if (isArray) {
20
+ console.error(gtx._x('{programName}: Error: The option' +
21
+ ' {optname} cannot be specified more than once!', { programName: package_1.Package.getName(), optname }));
22
+ return false;
23
+ }
24
+ }
25
+ }
26
+ return true;
27
+ }
28
+ exports.coerceOptions = coerceOptions;
package/dist/package.js CHANGED
@@ -9,7 +9,10 @@ class Package {
9
9
  return 'https://github.com/gflohr/esgettext/issues';
10
10
  }
11
11
  static getVersion() {
12
- return '1.2.0';
12
+ return '1.3.1';
13
+ }
14
+ static getNpmRunAllVersion() {
15
+ return '^4.1.5';
13
16
  }
14
17
  }
15
18
  exports.Package = Package;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esgettext/tools",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "Gettext-like po creation and manipulation",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -24,7 +24,7 @@
24
24
  "scripts": {
25
25
  "build": "npm run clean && tsc --project tsconfig-build.json && chmod +x dist/index.js",
26
26
  "prebuild": "node ./write-package.mjs >src/package.ts",
27
- "prepublishOnly": "npm run check:clean && npm run build",
27
+ "prepublishOnly": "npm run build",
28
28
  "check:clean": "../../check-clean",
29
29
  "format": "prettier --write 'src/**/*.ts'",
30
30
  "watch": "tsc --watch",
@@ -53,7 +53,7 @@
53
53
  "^@esgettext/runtime$": "<rootDir>/../../runtime/src"
54
54
  },
55
55
  "rootDir": "src",
56
- "testRegex": ".spec.ts$",
56
+ "testRegex": "\\.spec\\.ts$",
57
57
  "transform": {
58
58
  "^.+\\.ts$": "ts-jest"
59
59
  },
@@ -77,9 +77,11 @@
77
77
  "@types/jest": "^29.5.12",
78
78
  "@types/jsonfile": "^6.1.4",
79
79
  "@types/node": "^20.14.2",
80
+ "@types/npmcli__package-json": "^4.0.4",
80
81
  "@types/yargs": "^17.0.32",
81
82
  "eslint": "^8.56.0",
82
83
  "jest": "^29.7.0",
84
+ "npm-run-all": "^4.1.5",
83
85
  "prettier": "^3.3.2",
84
86
  "rimraf": "^5.0.7",
85
87
  "tsx": "^4.15.4",
@@ -89,7 +91,9 @@
89
91
  "dependencies": {
90
92
  "@babel/parser": "^7.24.7",
91
93
  "@babel/traverse": "^7.24.7",
92
- "@esgettext/runtime": "^1.2.0",
94
+ "@esgettext/runtime": "^1.3.0",
95
+ "@inquirer/prompts": "^5.0.6",
96
+ "@npmcli/package-json": "^5.2.0",
93
97
  "@valibot/i18n": "^0.15.0",
94
98
  "iconv-lite": "^0.6.3",
95
99
  "jsonfile": "^6.1.0",
@@ -97,5 +101,5 @@
97
101
  "valibot": "^0.31.1",
98
102
  "yargs": "^17.7.2"
99
103
  },
100
- "gitHead": "b3027a2934ec19444374e984673099f26cfccff7"
104
+ "gitHead": "cdc3f0b16ceb2692722109bbcc3078d156c3d2ec"
101
105
  }