@ecomcx/create-ecomweb 1.25.0 → 1.27.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/lib/npm.mjs +0 -8
- package/lib/pack.mjs +0 -5
- package/lib/upgrade.mjs +5 -7
- package/lib/validate.mjs +18 -21
- package/package.json +5 -9
- /package/bin/{cms.mjs → ecomweb.mjs} +0 -0
package/lib/npm.mjs
CHANGED
|
@@ -3,13 +3,5 @@ import { readFileSync } from "node:fs";
|
|
|
3
3
|
// Gói npm (org @ecomcx) — theme/plugin import đúng tên này
|
|
4
4
|
export const THEME_SDK = "@ecomcx/ecomweb-theme-sdk", ADMIN_SDK = "@ecomcx/ecomweb-admin-sdk", CONTENT = "@ecomcx/ecomweb-content";
|
|
5
5
|
export const CLI = "@ecomcx/create-ecomweb";
|
|
6
|
-
/**
|
|
7
|
-
* Tên cũ → tên mới: core vẫn hiểu import cũ, validate nhắc đổi, upgrade giữ bí danh để code cũ còn chạy.
|
|
8
|
-
* "@cms/…" = trước khi lên npm; "@ecomcx/nexus-…" = tên sản phẩm trước Ecomweb.
|
|
9
|
-
*/
|
|
10
|
-
export const OLD_NAMES = {
|
|
11
|
-
"@cms/theme-sdk": THEME_SDK, "@cms/admin-sdk": ADMIN_SDK, "@cms/content": CONTENT,
|
|
12
|
-
"@ecomcx/nexus-theme-sdk": THEME_SDK, "@ecomcx/nexus-admin-sdk": ADMIN_SDK, "@ecomcx/nexus-content": CONTENT,
|
|
13
|
-
};
|
|
14
6
|
/** Phiên bản của CLI = phiên bản SDK phát hành cùng đợt. */
|
|
15
7
|
export const VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
package/lib/pack.mjs
CHANGED
|
@@ -63,11 +63,6 @@ export async function buildAdmin(dir, outFile, name = "index") {
|
|
|
63
63
|
"@ecomcx/ecomweb-admin-sdk": path.join(sdk, "index" + ext),
|
|
64
64
|
// defineBlock (file khối dùng chung admin + website): dùng bản đi kèm CLI — plugin không cần cài gì thêm
|
|
65
65
|
"@ecomcx/ecomweb-content": createRequire(import.meta.url).resolve("@ecomcx/ecomweb-content"),
|
|
66
|
-
// Tên cũ (plugin viết trước khi SDK lên npm / trước khi đổi tên Ecomweb)
|
|
67
|
-
"@cms/admin-sdk": path.join(sdk, "index" + ext),
|
|
68
|
-
"@cms/content": createRequire(import.meta.url).resolve("@ecomcx/ecomweb-content"),
|
|
69
|
-
"@ecomcx/nexus-admin-sdk": path.join(sdk, "index" + ext),
|
|
70
|
-
"@ecomcx/nexus-content": createRequire(import.meta.url).resolve("@ecomcx/ecomweb-content"),
|
|
71
66
|
},
|
|
72
67
|
logLevel: "warning",
|
|
73
68
|
});
|
package/lib/upgrade.mjs
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { execFileSync } from "node:child_process";
|
|
4
|
-
import { ADMIN_SDK,
|
|
4
|
+
import { ADMIN_SDK, THEME_SDK, VERSION } from "./npm.mjs";
|
|
5
5
|
import { c, readJson, run } from "./util.mjs";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
const SDK = [THEME_SDK, ADMIN_SDK, "@cms/theme-sdk", "@cms/admin-sdk", "@ecomcx/nexus-theme-sdk", "@ecomcx/nexus-admin-sdk"];
|
|
7
|
+
const SDK = [THEME_SDK, ADMIN_SDK];
|
|
9
8
|
/** Phiên bản mới nhất trên npm (dự phòng: phiên bản của CLI đang chạy). */
|
|
10
9
|
function latest(npmName) {
|
|
11
10
|
try { return execFileSync("npm", ["view", npmName, "version"], { encoding: "utf8", shell: process.platform === "win32" }).trim(); }
|
|
12
11
|
catch { return VERSION; }
|
|
13
12
|
}
|
|
14
|
-
const spec = (key) =>
|
|
13
|
+
const spec = (key) => `^${latest(key)}`;
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
|
-
* Đưa project theme/plugin lên SDK mới nhất trên npm (@ecomcx/ecomweb-theme-sdk, @ecomcx/ecomweb-admin-sdk).
|
|
18
|
-
*
|
|
19
|
-
* (validate nhắc đổi import sang tên mới). Bỏ bản đang cài khỏi node_modules + package-lock.json rồi cài lại.
|
|
16
|
+
* Đưa project theme/plugin lên SDK mới nhất trên npm (@ecomcx/ecomweb-theme-sdk, @ecomcx/ecomweb-admin-sdk).
|
|
17
|
+
* Bỏ bản đang cài khỏi node_modules + package-lock.json rồi cài lại.
|
|
20
18
|
* Website không phụ thuộc bản này: CMS build theme/plugin bằng SDK của chính nó; bản trong project dùng cho gợi ý code,
|
|
21
19
|
* kiểm tra kiểu và `pack`.
|
|
22
20
|
*/
|
package/lib/validate.mjs
CHANGED
|
@@ -2,7 +2,6 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { IntlMessageFormat } from "intl-messageformat";
|
|
4
4
|
import { readJson, backendSources, expandSources } from "./util.mjs";
|
|
5
|
-
import { OLD_NAMES } from "./npm.mjs";
|
|
6
5
|
|
|
7
6
|
const SLUG = /^[a-z0-9][a-z0-9-]{1,63}$/;
|
|
8
7
|
const SEMVER = /^\d+\.\d+\.\d+(?:[-+].*)?$/;
|
|
@@ -24,7 +23,6 @@ export function validate(dir) {
|
|
|
24
23
|
if (!SEMVER.test(manifest.version ?? "")) errors.push("version phải theo semver, vd 1.0.0");
|
|
25
24
|
const dicts = checkLocales(dir, errors, warnings);
|
|
26
25
|
checkLabelKeys(manifest, dicts, kind, errors, warnings);
|
|
27
|
-
checkOldImports(dir, warnings);
|
|
28
26
|
// Bản dịch kiểu cũ (khoá là chuỗi gốc): { "en": { "Chuỗi gốc": "Translation" } } — vẫn chạy, nên chuyển sang locales/*.json
|
|
29
27
|
if (manifest.translations !== undefined) {
|
|
30
28
|
warnings.push(kind === "plugin"
|
|
@@ -37,6 +35,7 @@ export function validate(dir) {
|
|
|
37
35
|
}
|
|
38
36
|
if (!manifest.requires?.cms) warnings.push('Nên khai báo requires.cms, vd ">=1.0.0 <2.0.0"');
|
|
39
37
|
checkPermissions(manifest.permissions, errors, warnings);
|
|
38
|
+
checkCsp(manifest.csp, errors);
|
|
40
39
|
|
|
41
40
|
if (kind === "theme") {
|
|
42
41
|
const templates = path.join(dir, "templates");
|
|
@@ -151,6 +150,23 @@ function argsOf(ast, out = new Set()) {
|
|
|
151
150
|
|
|
152
151
|
/** locales/{ngôn-ngữ}.json: { "khoa": "thông điệp ICU" } — cú pháp ICU, khoá và biến khớp giữa các ngôn ngữ. */
|
|
153
152
|
/** Quyền trong manifest: viết sai → lỗi; quyền toàn phần mà chỉ cần vài domain / thư mục riêng → gợi ý quyền hẹp (CMS ≥ 1.8.0). */
|
|
153
|
+
const CSP_DIRECTIVES = ["script-src", "style-src", "img-src", "font-src", "connect-src", "frame-src", "media-src", "worker-src", "form-action"];
|
|
154
|
+
// Giữ khớp CspSources (Cms.Packaging): host https/wss cụ thể, được "*." đầu host, cổng, đường dẫn
|
|
155
|
+
const CSP_SOURCE = /^(https|wss):\/\/(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*(:(\d{1,5}|\*))?(\/[A-Za-z0-9._~!$&()*+=:@%/-]*)?$/;
|
|
156
|
+
|
|
157
|
+
/** "csp": nguồn ngoài website cần nạp, vd { "font-src": ["https://fonts.gstatic.com"] } — CMS gộp vào CSP của website. */
|
|
158
|
+
function checkCsp(csp, errors) {
|
|
159
|
+
if (csp === undefined) return;
|
|
160
|
+
if (!csp || typeof csp !== "object" || Array.isArray(csp)) { errors.push('"csp" phải có dạng { "script-src": ["https://cdn.example.com"] }'); return; }
|
|
161
|
+
for (const [directive, list] of Object.entries(csp)) {
|
|
162
|
+
if (!CSP_DIRECTIVES.includes(directive)) { errors.push(`csp: chỉ thị "${directive}" không hỗ trợ (dùng: ${CSP_DIRECTIVES.join(", ")})`); continue; }
|
|
163
|
+
if (!Array.isArray(list)) { errors.push(`csp.${directive} phải là mảng nguồn`); continue; }
|
|
164
|
+
for (const src of list)
|
|
165
|
+
if (typeof src !== "string" || src.length > 300 || !CSP_SOURCE.test(src))
|
|
166
|
+
errors.push(`csp.${directive}: nguồn "${src}" không hợp lệ — chỉ nhận host https:// hoặc wss:// cụ thể, vd https://cdn.example.com (không "*", "https:", 'unsafe-…')`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
154
170
|
function checkPermissions(perms, errors, warnings) {
|
|
155
171
|
if (perms === undefined) return;
|
|
156
172
|
if (!Array.isArray(perms) || perms.some((p) => typeof p !== "string")) { errors.push('"permissions" phải là mảng chuỗi'); return; }
|
|
@@ -257,22 +273,3 @@ function findLegacyCalls(srcDir) {
|
|
|
257
273
|
return out;
|
|
258
274
|
}
|
|
259
275
|
|
|
260
|
-
/** Import tên cũ "@cms/…" / "@ecomcx/nexus-…": CMS vẫn chạy được, nhắc đổi sang tên gói npm hiện tại. */
|
|
261
|
-
function checkOldImports(dir, warnings) {
|
|
262
|
-
const found = new Map();
|
|
263
|
-
const walk = (d, depth = 0) => {
|
|
264
|
-
if (depth > 6 || !fs.existsSync(d)) return;
|
|
265
|
-
for (const e of fs.readdirSync(d, { withFileTypes: true })) {
|
|
266
|
-
if (["node_modules", "dist", ".next", ".git"].includes(e.name)) continue;
|
|
267
|
-
const p = path.join(d, e.name);
|
|
268
|
-
if (e.isDirectory()) walk(p, depth + 1);
|
|
269
|
-
else if (/\.(tsx?|jsx?|mjs)$/.test(e.name))
|
|
270
|
-
for (const m of fs.readFileSync(p, "utf8").matchAll(/["'](@cms\/(theme-sdk|admin-sdk|content)|@ecomcx\/nexus-(theme-sdk|admin-sdk|content))["']/g))
|
|
271
|
-
if (!found.has(m[1])) found.set(m[1], path.relative(dir, p));
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
walk(dir);
|
|
275
|
-
const NEW = OLD_NAMES;
|
|
276
|
-
for (const [old, file] of found)
|
|
277
|
-
warnings.push(`${file}: import "${old}" là tên cũ — đổi sang "${NEW[old]}" (cài: npm i -D ${NEW[old]}; hoặc npx @ecomcx/create-ecomweb upgrade)`);
|
|
278
|
-
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecomcx/create-ecomweb",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.0",
|
|
4
4
|
"description": "CLI tạo, kiểm tra, đóng gói và triển khai theme/plugin cho Ecomweb",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"create-ecomweb": "bin/
|
|
8
|
-
"ecomweb": "bin/
|
|
9
|
-
"create-nexus": "bin/cms.mjs",
|
|
10
|
-
"nexus": "bin/cms.mjs",
|
|
11
|
-
"create-cms": "bin/cms.mjs",
|
|
12
|
-
"cms": "bin/cms.mjs"
|
|
7
|
+
"create-ecomweb": "bin/ecomweb.mjs",
|
|
8
|
+
"ecomweb": "bin/ecomweb.mjs"
|
|
13
9
|
},
|
|
14
10
|
"files": [
|
|
15
11
|
"bin",
|
|
@@ -17,7 +13,7 @@
|
|
|
17
13
|
"README.md"
|
|
18
14
|
],
|
|
19
15
|
"dependencies": {
|
|
20
|
-
"@ecomcx/ecomweb-admin-sdk": "1.
|
|
16
|
+
"@ecomcx/ecomweb-admin-sdk": "1.27.0",
|
|
21
17
|
"@ecomcx/ecomweb-content": "^1.14.0",
|
|
22
18
|
"adm-zip": "0.5.18",
|
|
23
19
|
"esbuild": "0.25.12",
|
|
@@ -29,7 +25,7 @@
|
|
|
29
25
|
"repository": {
|
|
30
26
|
"type": "git",
|
|
31
27
|
"url": "git+https://github.com/Ecomcx-Jsc/ecomweb-sdk.git",
|
|
32
|
-
"directory": "packages/create-
|
|
28
|
+
"directory": "packages/create-ecomweb"
|
|
33
29
|
},
|
|
34
30
|
"homepage": "https://github.com/Ecomcx-Jsc/ecomweb-sdk#readme",
|
|
35
31
|
"license": "MIT",
|
|
File without changes
|