@wp-blocks/make-pot 1.6.3 → 1.6.4
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/biome.json +1 -1
- package/lib/cli/parseCli.js +1 -1
- package/lib/cli/parseCli.js.map +2 -2
- package/lib/extractors/auditStrings.js +4 -3
- package/lib/extractors/auditStrings.js.map +2 -2
- package/lib/extractors/headers.js +7 -6
- package/lib/extractors/headers.js.map +3 -3
- package/lib/extractors/json.js +1 -1
- package/lib/extractors/json.js.map +2 -2
- package/lib/extractors/schema.js +3 -4
- package/lib/extractors/schema.js.map +2 -2
- package/lib/fs/fs.js +2 -2
- package/lib/fs/fs.js.map +2 -2
- package/lib/fs/glob.js +1 -1
- package/lib/fs/glob.js.map +2 -2
- package/lib/parser/exec.js +1 -1
- package/lib/parser/exec.js.map +2 -2
- package/lib/parser/makeJson.js +1 -1
- package/lib/parser/makeJson.js.map +2 -2
- package/lib/parser/makePot.js.map +1 -1
- package/lib/parser/process.js +1 -1
- package/lib/parser/process.js.map +2 -2
- package/lib/parser/progress.js.map +2 -2
- package/lib/parser/taskRunner.js +2 -2
- package/lib/parser/taskRunner.js.map +2 -2
- package/lib/parser/tree.js +2 -1
- package/lib/parser/tree.js.map +2 -2
- package/lib/types.js.map +1 -1
- package/lib/utils/common.js.map +2 -2
- package/lib/utils/extractors.js +1 -1
- package/lib/utils/extractors.js.map +2 -2
- package/lib/utils/output.js +1 -1
- package/lib/utils/output.js.map +2 -2
- package/package.json +14 -11
- package/tests/extract-headers.test.js +69 -1
- package/tests/generate-header.test.js +27 -0
- package/tests/tree.test.js +74 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wp-blocks/make-pot",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.4",
|
|
4
4
|
"license": "GPL-3.0-or-later",
|
|
5
5
|
"homepage": "https://wp-blocks.github.io/make-pot/",
|
|
6
6
|
"description": "A Node.js script for generating a POT file from source code",
|
|
@@ -50,8 +50,10 @@
|
|
|
50
50
|
"build": "npx esbuild ./src/**/* ./src/*.ts --format=cjs --minify --outdir=lib --platform=node",
|
|
51
51
|
"watch": "tsc --watch",
|
|
52
52
|
"lint": "npx @biomejs/biome check --write src",
|
|
53
|
+
"type-check": "npx tsc --noEmit",
|
|
54
|
+
"update-pkg": "npm upgrade -S",
|
|
53
55
|
"rm": "rmdir /s /q lib",
|
|
54
|
-
"test:build": "npx esbuild ./src/**/* --format=cjs --sourcemap --outdir=lib --platform=node",
|
|
56
|
+
"test:build": "npx esbuild ./src/**/* ./src/*.ts --format=cjs --sourcemap --outdir=lib --platform=node",
|
|
55
57
|
"test": "npm run test:build && node --test",
|
|
56
58
|
"build:build-ci": "npx esbuild ./src/index.ts --format=cjs --outdir=lib --bundle --external:tree-sitter --external:tree-sitter-typescript --external:tree-sitter-php --external:tree-sitter-javascript --external:@babel/preset-typescript --platform=node",
|
|
57
59
|
"test:ci": "npm run build:build-ci && npm run test",
|
|
@@ -59,26 +61,27 @@
|
|
|
59
61
|
"test:coverage": "node --test --experimental-test-coverage"
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"@babel/core": "^7.
|
|
63
|
-
"@babel/preset-env": "^7.
|
|
64
|
+
"@babel/core": "^7.29.0",
|
|
65
|
+
"@babel/preset-env": "^7.29.0",
|
|
64
66
|
"cli-progress": "^3.12.0",
|
|
65
67
|
"gettext-merger": "^1.2.1",
|
|
66
|
-
"gettext-parser": "^4.0
|
|
67
|
-
"glob": "^11.0
|
|
68
|
+
"gettext-parser": "^4.2.0",
|
|
69
|
+
"glob": "^11.1.0",
|
|
68
70
|
"tannin": "^1.2.0",
|
|
69
71
|
"tree-sitter": "^0.21.1",
|
|
70
72
|
"tree-sitter-javascript": "^0.23.1",
|
|
71
73
|
"tree-sitter-php": "^0.23.12",
|
|
72
74
|
"tree-sitter-typescript": "^0.23.2",
|
|
73
|
-
"yargs": "^17.7.
|
|
75
|
+
"yargs": "^17.7.2"
|
|
74
76
|
},
|
|
75
77
|
"devDependencies": {
|
|
76
|
-
"@biomejs/biome": "2.
|
|
78
|
+
"@biomejs/biome": "2.3.14",
|
|
79
|
+
"@types/babel__core": "^7.20.5",
|
|
77
80
|
"@types/cli-progress": "^3.11.6",
|
|
78
81
|
"@types/gettext-parser": "^4.0.4",
|
|
79
|
-
"@types/node": "^22.
|
|
80
|
-
"@types/yargs": "^17.0.
|
|
82
|
+
"@types/node": "^22.19.11",
|
|
83
|
+
"@types/yargs": "^17.0.35",
|
|
81
84
|
"esbuild": "0.25.9",
|
|
82
|
-
"typescript": "^5.9.
|
|
85
|
+
"typescript": "^5.9.3"
|
|
83
86
|
}
|
|
84
87
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { describe, it } = require("node:test");
|
|
2
2
|
const { join } = require("node:path");
|
|
3
3
|
const assert = require("node:assert");
|
|
4
|
-
const { extractMainFileData } = require("../lib");
|
|
4
|
+
const { extractMainFileData, getAuthorFromPackage } = require("../lib");
|
|
5
5
|
|
|
6
6
|
describe("should parse plugin main file", () => {
|
|
7
7
|
describe("should parse plugin.php", () => {
|
|
@@ -52,3 +52,71 @@ describe("should parse theme main file", () => {
|
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
|
+
|
|
56
|
+
describe("getAuthorFromPackage", () => {
|
|
57
|
+
it("extracts author from string with name and email", () => {
|
|
58
|
+
const pkgJson = {
|
|
59
|
+
author: "My Name <myname@example.com>",
|
|
60
|
+
};
|
|
61
|
+
const author = getAuthorFromPackage(pkgJson);
|
|
62
|
+
assert.deepStrictEqual(author, {
|
|
63
|
+
name: "My Name",
|
|
64
|
+
email: "myname@example.com",
|
|
65
|
+
website: undefined,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("extracts author from string with specific user format", () => {
|
|
70
|
+
const pkgJson = {
|
|
71
|
+
author: "my name <myname@asdasdasdasd.it>",
|
|
72
|
+
};
|
|
73
|
+
const author = getAuthorFromPackage(pkgJson);
|
|
74
|
+
assert.deepStrictEqual(author, {
|
|
75
|
+
name: "my name",
|
|
76
|
+
email: "myname@asdasdasdasd.it",
|
|
77
|
+
website: undefined,
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("extracts author from string with name, email and url", () => {
|
|
82
|
+
const pkgJson = {
|
|
83
|
+
author: "My Name <myname@example.com> (https://example.com)",
|
|
84
|
+
};
|
|
85
|
+
const author = getAuthorFromPackage(pkgJson);
|
|
86
|
+
assert.deepStrictEqual(author, {
|
|
87
|
+
name: "My Name",
|
|
88
|
+
email: "myname@example.com",
|
|
89
|
+
website: "https://example.com",
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("extracts author from object", () => {
|
|
94
|
+
const pkgJson = {
|
|
95
|
+
author: {
|
|
96
|
+
name: "Object Author",
|
|
97
|
+
email: "obj@example.com",
|
|
98
|
+
website: "https://obj.example.com"
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const author = getAuthorFromPackage(pkgJson);
|
|
102
|
+
assert.deepStrictEqual(author, {
|
|
103
|
+
name: "Object Author",
|
|
104
|
+
email: "obj@example.com",
|
|
105
|
+
website: "https://obj.example.com",
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("extracts author from array of strings", () => {
|
|
110
|
+
const pkgJson = {
|
|
111
|
+
authors: [
|
|
112
|
+
"Array Author <array@example.com>"
|
|
113
|
+
]
|
|
114
|
+
};
|
|
115
|
+
const author = getAuthorFromPackage(pkgJson);
|
|
116
|
+
assert.deepStrictEqual(author, {
|
|
117
|
+
name: "Array Author",
|
|
118
|
+
email: "array@example.com",
|
|
119
|
+
website: undefined
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { describe, it } = require("node:test");
|
|
2
|
+
const assert = require("node:assert");
|
|
3
|
+
const { generateHeader } = require("../lib/extractors/headers");
|
|
4
|
+
const process = require("node:process");
|
|
5
|
+
|
|
6
|
+
describe("generateHeader", () => {
|
|
7
|
+
it("should return default headers when silent is true and fields are missing", async () => {
|
|
8
|
+
const args = {
|
|
9
|
+
slug: "test-slug",
|
|
10
|
+
debug: false,
|
|
11
|
+
domain: "plugin",
|
|
12
|
+
paths: { cwd: process.cwd(), out: "languages" },
|
|
13
|
+
options: { silent: true },
|
|
14
|
+
headers: {
|
|
15
|
+
version: "0.0.1",
|
|
16
|
+
author: "AUTHOR",
|
|
17
|
+
email: "AUTHOR EMAIL"
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const headers = await generateHeader(args);
|
|
22
|
+
|
|
23
|
+
assert.ok(headers, "Headers should be generated");
|
|
24
|
+
assert.strictEqual(headers["Project-Id-Version"], "test-slug 0.0.1");
|
|
25
|
+
assert.strictEqual(headers["Last-Translator"], "AUTHOR <AUTHOR EMAIL>");
|
|
26
|
+
});
|
|
27
|
+
});
|
package/tests/tree.test.js
CHANGED
|
@@ -35,7 +35,7 @@ describe("doTree php", () => {
|
|
|
35
35
|
translator: undefined,
|
|
36
36
|
},
|
|
37
37
|
msgctxt: undefined,
|
|
38
|
-
msgid: "You
|
|
38
|
+
msgid: "You're a silly monkey",
|
|
39
39
|
msgid_plural: undefined,
|
|
40
40
|
msgstr: [""],
|
|
41
41
|
});
|
|
@@ -214,3 +214,76 @@ describe("doTree php _n, _nx", async () => {
|
|
|
214
214
|
assert.strictEqual(r.filter((block) => block.msgctxt === 'context').length, 1);
|
|
215
215
|
});
|
|
216
216
|
});
|
|
217
|
+
|
|
218
|
+
describe("doTree php escape sequences", async () => {
|
|
219
|
+
it("should correctly unescape newlines, tabs, and quotes in double-quoted strings", () => {
|
|
220
|
+
const content = `<?php
|
|
221
|
+
// Double quotes with escape sequences
|
|
222
|
+
__("Line 1\\nLine 2", "text-domain");
|
|
223
|
+
|
|
224
|
+
// Double quotes with escaped quotes
|
|
225
|
+
_e("Hello \\"World\\"", "text-domain");
|
|
226
|
+
|
|
227
|
+
// Double quotes with tabs
|
|
228
|
+
__("Col1\\tCol2", "text-domain");
|
|
229
|
+
`;
|
|
230
|
+
|
|
231
|
+
const filename = "escapes.php";
|
|
232
|
+
const r = doTree(content, filename).blocks;
|
|
233
|
+
|
|
234
|
+
// 1. Verify newline
|
|
235
|
+
const newlineBlock = r.find(b => b.msgid.includes('Line 1'));
|
|
236
|
+
// The msgid should contain an actual newline character, not the literal characters '\' and 'n'
|
|
237
|
+
assert.strictEqual(newlineBlock?.msgid, "Line 1\nLine 2");
|
|
238
|
+
|
|
239
|
+
// 2. Verify escaped quotes
|
|
240
|
+
const quoteBlock = r.find(b => b.msgid.includes('Hello'));
|
|
241
|
+
assert.strictEqual(quoteBlock?.msgid, 'Hello "World"');
|
|
242
|
+
|
|
243
|
+
// 3. Verify tabs
|
|
244
|
+
const tabBlock = r.find(b => b.msgid.includes('Col1'));
|
|
245
|
+
assert.strictEqual(tabBlock?.msgid, "Col1\tCol2");
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
describe("doTree php single quotes", async () => {
|
|
250
|
+
it("should treat escape sequences as literals in single-quoted strings", () => {
|
|
251
|
+
const content = `<?php
|
|
252
|
+
// Single quotes should NOT interpret \\n as newline
|
|
253
|
+
__('Line 1\\nLine 2', 'text-domain');
|
|
254
|
+
|
|
255
|
+
// Single quotes SHOULD handle escaped single quotes
|
|
256
|
+
__('It\\'s a sunny day', 'text-domain');
|
|
257
|
+
`;
|
|
258
|
+
|
|
259
|
+
const filename = "single_quotes.php";
|
|
260
|
+
const r = doTree(content, filename).blocks;
|
|
261
|
+
|
|
262
|
+
// 1. Verify literal \\n
|
|
263
|
+
const literalBlock = r.find(b => b.msgid.includes('Line 1'));
|
|
264
|
+
// In single quotes, \\n is two characters: backslash and n
|
|
265
|
+
assert.strictEqual(literalBlock?.msgid, "Line 1\\nLine 2");
|
|
266
|
+
|
|
267
|
+
// 2. Verify escaped single quote
|
|
268
|
+
const quoteBlock = r.find(b => b.msgid.includes('sunny'));
|
|
269
|
+
assert.strictEqual(quoteBlock?.msgid, "It's a sunny day");
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
describe("doTree php variables in strings", async () => {
|
|
274
|
+
it("should preserve PHP variables inside double-quoted strings", () => {
|
|
275
|
+
const content = `<?php
|
|
276
|
+
$name = 'John';
|
|
277
|
+
// Variable interpolation
|
|
278
|
+
__("Hello $name, how are you?", "text-domain");
|
|
279
|
+
`;
|
|
280
|
+
|
|
281
|
+
const filename = "variables.php";
|
|
282
|
+
const r = doTree(content, filename).blocks;
|
|
283
|
+
|
|
284
|
+
const varBlock = r.find(b => b.msgid.startsWith('Hello'));
|
|
285
|
+
|
|
286
|
+
// We expect the variable name to be preserved in the msgid
|
|
287
|
+
assert.strictEqual(varBlock?.msgid, "Hello $name, how are you?");
|
|
288
|
+
});
|
|
289
|
+
});
|