Skip to content

Commit

Permalink
ci: 调整 polyfill 生成逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnAngela committed Jan 23, 2024
1 parent d800730 commit df7bb24
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 22 deletions.
12 changes: 9 additions & 3 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const ignores = [
"**/dist/**",
"**/.*/**",
"node_modules",
"src/gadgets/libPolyfill/MediaWiki:Gadget-libPolyfill.*.js",
"src/gadgets/libPolyfill/*",
];

const srcESlintrcFiles = (await readDir("./src")).filter((n) => path.basename(n) === ".eslintrc.yaml");
Expand All @@ -35,15 +35,21 @@ const fileSpec = {
browser: {
files: [
"src/**/*",
"scripts/generatePolyfill/customPolyfills/**/*",
],
ignores: [
...ignores,
],
ignores,
},
node: {
files: [
"scripts/**/*",
"eslint.config.js",
],
ignores,
ignores: [
...ignores,
"scripts/generatePolyfill/customPolyfills/**/*",
],
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* 引自 [email protected]
*/

/**
* @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/regex.js
*/
const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;

/**
* @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/validate.js
*/
const validate = (uuid) => "string" === typeof uuid && REGEX.test(uuid);

/**
* @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/rng-browser.js
*/
const rnds8 = new Uint8Array(16);
const rng = () => crypto.getRandomValues(rnds8);

/**
* @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/stringify.js
*/
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 256).toString(16).substring(1));
}
const unsafeStringify = (arr, offset = 0) => `${byteToHex[arr[offset + 0]]}${byteToHex[arr[offset + 1]]}${byteToHex[arr[offset + 2]]}${byteToHex[arr[offset + 3]]}-${byteToHex[arr[offset + 4]]}${byteToHex[arr[offset + 5]]}-${byteToHex[arr[offset + 6]]}${byteToHex[arr[offset + 7]]}-${byteToHex[arr[offset + 8]]}${byteToHex[arr[offset + 9]]}-${byteToHex[arr[offset + 10]]}${byteToHex[arr[offset + 11]]}${byteToHex[arr[offset + 12]]}${byteToHex[arr[offset + 13]]}${byteToHex[arr[offset + 14]]}${byteToHex[arr[offset + 15]]}`.toLowerCase();

/**
* @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/v4.js
*/
const v4 = (options = {}, buf, offset = 0) => {
const rnds = options.random || (options.rng || rng)();
rnds[6] = rnds[6] & 0x0f | 0x40;
rnds[8] = rnds[8] & 0x3f | 0x80;
if (buf) {
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return unsafeStringify(rnds);
};

/**
* main polyfill
*/
try {
if (!validate(crypto.randomUUID())) {
throw void 0;
}
} catch {
crypto.randomUUID = () => v4();
}
30 changes: 30 additions & 0 deletions scripts/generatePolyfill/customPolyfill/main.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"crypto.randomUUID": {
"aliases": [
"default"
],
"spec": "https://w3c.github.io/webcrypto/#Crypto-method-randomUUID",
"docs": "https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID",
"notes": [
"In [email protected], there is no polyfill for this feature."
],
"browsers": {
"android": "<92",
"chrome": "<92",
"edge": "<92",
"edge_mob": "<92",
"firefox": "<95",
"firefox_mob": "<95",
"ios_saf": "<15.4",
"op_mini": "<65",
"opera": "<78",
"safari": "<15.4",
"samsung_mob": "<16.0"
},
"baseDir": "crypto.randomUUID",
"hasTests": false,
"isTestable": false,
"isPublic": true,
"size": 2063
}
}
3 changes: 3 additions & 0 deletions scripts/generatePolyfill/customPolyfill/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
47 changes: 34 additions & 13 deletions scripts/generatePolyfill/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import createCommit from "../modules/createCommit.js";

const polyfillGadgetDefinitionPath = "src/gadgets/libPolyfill/definition.yaml";
const polyfillGadgetDefinition = await yamlModule.readFile(polyfillGadgetDefinitionPath);
const getPolyfillGadgetFiles = async () => (await fs.promises.readdir("src/gadgets/libPolyfill/")).filter((file) => file.startsWith("MediaWiki:Gadget-libPolyfill") && file.endsWith(".js"));
const getPolyfillGadgetFiles = async () => (await fs.promises.readdir("src/gadgets/libPolyfill/")).filter((file) => path.extname(file) === ".js");

/**
* @type { { TARGET_CHROMIUM_VERSION: string | number, TARGET_ALIASES: string[] } }
Expand All @@ -33,7 +33,9 @@ endGroup();

const polyfillGadgetFiles = await getPolyfillGadgetFiles();
const polyfillMainJSONPath = path.join(POLYFILL_PATH, "main.json");
const customPolyfillMainJSONPath = "./scripts/generatePolyfill/customPolyfill/main.json";
const polyfillLibraryPath = path.join(POLYFILL_PATH, "library");
const customPolyfillLibraryPath = "./scripts/generatePolyfill/customPolyfill/library";

console.info("Start to delete old polyfill files:");
for (const file of polyfillGadgetFiles) {
Expand All @@ -48,10 +50,20 @@ for (const file of polyfillGadgetFiles) {
console.info("\tDeleteting", file, "done.");
}
console.info("Start to read polyfill JSON...");
const polyfillMainJSONArray = Object.entries(await jsonModule.readFile(polyfillMainJSONPath)).map(([id, v]) => ({
id,
...JSON.parse(v),
}));
const polyfillMainJSONArray = [
...Object.entries(await jsonModule.readFile(polyfillMainJSONPath)).map(([id, v]) => ({
id,
...JSON.parse(v),
})),
...Object.entries(await jsonModule.readFile(customPolyfillMainJSONPath)).map(([id, v]) => ({
id,
...v,
})),
];
console.info("Start to merge custom polyfill...");
for (const dir of await fs.promises.readdir(customPolyfillLibraryPath)) {
await fs.promises.cp(path.join(customPolyfillLibraryPath, dir), path.join(polyfillLibraryPath, dir), { recursive: true });
}
const polyfillMainJSON = Object.fromEntries(polyfillMainJSONArray.map((v) => [v.id, v]));
console.info("Get", polyfillMainJSONArray.length, "polyfill entries.");
const polyfillList = polyfillMainJSONArray.filter(({ aliases }) => Array.isArray(aliases) && TARGET_ALIASES.some((targetAliases) => aliases.includes(targetAliases)));
Expand All @@ -60,13 +72,13 @@ const polyfillListAllowed = polyfillList.filter(({ browsers }) => browsers?.chro
console.info("Get", polyfillListAllowed.length, "polyfill entries with aliases and target browsers.");

const readPolyfillRawJS = async (dir) => {
console.info("\t[readPolyfillRawJS]", "Testing", dir);
if (await fs.promises.access(dir).then(() => true).catch(() => false)) {
console.info("\t[readPolyfillRawJS]", dir, "exist, reading raw js.");
return (await fs.promises.readFile(path.join(dir, "raw.js"), { encoding: "utf-8" })).split("\n");
const rawJSPath = path.join(dir, "raw.js");
try {
return (await fs.promises.readFile(rawJSPath, { encoding: "utf-8" })).trim().split("\n");
} catch (e) {
console.info("\t[readPolyfillRawJS]", rawJSPath, "not exist, return false:", e);
return false;
}
console.info("\t[readPolyfillRawJS]", dir, "not exist, return false.");
return false;
};
const polyfillAlreadyInjected = {};
const getPolyfillContent = async (polyfill, _rootPolyfillID = false) => {
Expand All @@ -80,7 +92,11 @@ const getPolyfillContent = async (polyfill, _rootPolyfillID = false) => {
}
polyfillAlreadyInjected[rootPolyfillID].push(polyfill.id);
console.info("\t[getPolyfillContent]", `[${polyfill.id}@${rootPolyfillID}]`, "Processing", polyfill.id);
const content = [];
const content = [
"",
`// Polyfill ${polyfill.id} start`,
"",
];
const detectSource = polyfill.detectSource?.trim();
console.info("\t[getPolyfillContent]", `[${polyfill.id}@${rootPolyfillID}]`, "detectSource:", detectSource);
if (detectSource) {
Expand Down Expand Up @@ -108,6 +124,11 @@ const getPolyfillContent = async (polyfill, _rootPolyfillID = false) => {
if (detectSource) {
content.push("}");
}
content.push(
"",
`// Polyfill ${polyfill.id} end`,
"",
);
console.info("\t[getPolyfillContent]", `[${polyfill.id}@${rootPolyfillID}]`, "Done.");
return content;
};
Expand All @@ -127,7 +148,7 @@ for (const polyfill of polyfillListAllowed) {
...await getPolyfillContent(polyfill),
"})();",
];
const gadgetFilePath = path.join("src/gadgets/libPolyfill/", `MediaWiki:Gadget-libPolyfill.${polyfill.id}.js`);
const gadgetFilePath = path.join("src/gadgets/libPolyfill/", `MediaWiki:Gadget-libPolyfill-${polyfill.id}.js`);
console.info("Start to write polyfill file:", polyfill.id, "@", gadgetFilePath);
await fs.promises.writeFile(gadgetFilePath, content.join("\n"));
console.info("Done.");
Expand Down
6 changes: 1 addition & 5 deletions scripts/modules/getUpstream.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import console from "./console.js";
import git from "./git.js";
import { isInGithubActions } from "./octokit.js";
if (!isInGithubActions) {
console.info("Not running in github actions, exit.");
process.exit(0);
}

/**
* @type { string | false } when false, it means the HEAD does not point to a branch.
*/
Expand Down
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
"./node_modules/@annangela/eslint-config/dist/tsconfigs/tsconfig.browser.json"
],
"compilerOptions": {
"outDir": "dist/",
"outDir": "./dist/",
"baseUrl": ".",
"lib": [
"ESNext",
"DOM"
],
},
"include": [
"src",
"scripts",
],
"exclude": [
"dist",
Expand Down
6 changes: 6 additions & 0 deletions tsconfig.production.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./dist/",
"baseUrl": "./",
"rootDir": "./src/",
"target": "ES3",
"ignoreDeprecations": "5.0",
},
"exclude": [
"scripts",
],
}

0 comments on commit df7bb24

Please sign in to comment.