@m2c2kit/build-helpers 0.3.5 → 0.3.7
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/index.d.ts +2 -1
- package/dist/index.js +346 -358
- package/package.json +8 -7
package/dist/index.d.ts
CHANGED
|
@@ -29,9 +29,10 @@ import { InputOptions } from 'rollup';
|
|
|
29
29
|
*
|
|
30
30
|
* @param rootDir - root directory of build, usually "dist" because you
|
|
31
31
|
* usually hash only production builds
|
|
32
|
+
* @param cwd - current working directory; used only for testing.
|
|
32
33
|
* @returns
|
|
33
34
|
*/
|
|
34
|
-
declare function hashM2c2kitAssets(rootDir: string): {
|
|
35
|
+
declare function hashM2c2kitAssets(rootDir: string, cwd?: string): {
|
|
35
36
|
name: string;
|
|
36
37
|
closeBundle: {
|
|
37
38
|
sequential: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,9 @@
|
|
|
1
|
-
import { dirname as dirname_m2c2kit_build_helpers } from 'path';
|
|
2
|
-
import { fileURLToPath as fileURLToPath_m2c2kit_build_helpers} from 'url';
|
|
3
|
-
const __filename = fileURLToPath_m2c2kit_build_helpers(import.meta.url);
|
|
4
|
-
const __dirname = dirname_m2c2kit_build_helpers(__filename);
|
|
5
1
|
import { existsSync, renameSync, readFileSync } from 'fs';
|
|
6
2
|
import { readFile, writeFile } from 'fs/promises';
|
|
7
3
|
import path from 'path';
|
|
8
4
|
import { createHash } from 'crypto';
|
|
9
5
|
import { fileURLToPath } from 'url';
|
|
10
6
|
|
|
11
|
-
/******************************************************************************
|
|
12
|
-
Copyright (c) Microsoft Corporation.
|
|
13
|
-
|
|
14
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
15
|
-
purpose with or without fee is hereby granted.
|
|
16
|
-
|
|
17
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
18
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
19
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
20
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
21
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
22
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
23
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
24
|
-
***************************************************************************** */
|
|
25
|
-
|
|
26
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
27
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
28
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
29
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
30
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
31
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
32
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
7
|
// Generated using scripts/write-decode-map.ts
|
|
37
8
|
var htmlDecodeTree = new Uint16Array(
|
|
38
9
|
// prettier-ignore
|
|
@@ -11158,10 +11129,10 @@ if (!String.prototype.endsWith) {
|
|
|
11158
11129
|
}
|
|
11159
11130
|
|
|
11160
11131
|
const OPERATOR_PRECEDENCE = {
|
|
11161
|
-
'||':
|
|
11132
|
+
'||': 2,
|
|
11133
|
+
'??': 3,
|
|
11162
11134
|
'&&': 4,
|
|
11163
11135
|
'|': 5,
|
|
11164
|
-
'??': 5,
|
|
11165
11136
|
'^': 6,
|
|
11166
11137
|
'&': 7,
|
|
11167
11138
|
'==': 8,
|
|
@@ -11263,6 +11234,14 @@ function expressionNeedsParenthesis(state, node, parentNode, isRightHand) {
|
|
|
11263
11234
|
// Exponentiation operator has right-to-left associativity
|
|
11264
11235
|
return !isRightHand
|
|
11265
11236
|
}
|
|
11237
|
+
if (
|
|
11238
|
+
nodePrecedence === 13 &&
|
|
11239
|
+
parentNodePrecedence === 13 &&
|
|
11240
|
+
(node.operator === '??' || parentNode.operator === '??')
|
|
11241
|
+
) {
|
|
11242
|
+
// Nullish coalescing and boolean operators cannot be combined
|
|
11243
|
+
return true
|
|
11244
|
+
}
|
|
11266
11245
|
if (isRightHand) {
|
|
11267
11246
|
// Parenthesis are used if both operators have the same precedence
|
|
11268
11247
|
return (
|
|
@@ -12305,349 +12284,358 @@ function generate(node, options) {
|
|
|
12305
12284
|
return state.output
|
|
12306
12285
|
}
|
|
12307
12286
|
|
|
12308
|
-
/** We use MD5 for hashing, but keep only the first 16 characters. */
|
|
12309
12287
|
const HASH_CHARACTER_LENGTH = 16;
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
|
|
12332
|
-
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
|
|
12338
|
-
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
.map((p) => p);
|
|
12411
|
-
const identifiers = properties
|
|
12412
|
-
.filter((p) => p.key.type === "Identifier")
|
|
12413
|
-
.map((p) => p.key.name);
|
|
12414
|
-
const urlFontAssetProperties = ["fontName", "url"];
|
|
12415
|
-
const propCount = identifiers.filter((i) => urlFontAssetProperties.indexOf(i) !== -1).length;
|
|
12416
|
-
if (propCount === 2) {
|
|
12417
|
-
// the object expression has the 2 properties
|
|
12418
|
-
const maybeArrayExpression = ancestors.slice(-4)[0];
|
|
12419
|
-
if (maybeArrayExpression.type === "ArrayExpression") {
|
|
12420
|
-
const maybeProperty = ancestors.slice(-5)[0];
|
|
12421
|
-
if (maybeProperty.type === "Property") {
|
|
12422
|
-
const property = maybeProperty;
|
|
12423
|
-
if (property.key.type === "Identifier" &&
|
|
12424
|
-
property.key.name == "fonts") {
|
|
12425
|
-
// property is fonts
|
|
12426
|
-
const literal = node;
|
|
12427
|
-
const originalUrlValue = literal.value;
|
|
12428
|
-
try {
|
|
12429
|
-
const hashedUrlValue = addHashToUrl(originalUrlValue, rootDir);
|
|
12430
|
-
literal.value = literal.value.replace(originalUrlValue, hashedUrlValue);
|
|
12431
|
-
literal.raw = literal.raw.replace(originalUrlValue, hashedUrlValue);
|
|
12432
|
-
addFileToFilesToBeRenamed(rootDir, originalUrlValue, hashedUrlValue, fileRenames);
|
|
12433
|
-
}
|
|
12434
|
-
catch (_b) {
|
|
12435
|
-
}
|
|
12436
|
-
}
|
|
12437
|
-
}
|
|
12438
|
-
}
|
|
12439
|
-
}
|
|
12440
|
-
}
|
|
12441
|
-
}
|
|
12442
|
-
}
|
|
12443
|
-
}
|
|
12444
|
-
// we'll be looking back 5 levels
|
|
12445
|
-
if (ancestors.length >= 5) {
|
|
12446
|
-
const maybeProperty = ancestors.slice(-2)[0];
|
|
12447
|
-
if (maybeProperty.type === "Property") {
|
|
12448
|
-
const property = maybeProperty;
|
|
12449
|
-
if (property.key.type === "Identifier" &&
|
|
12450
|
-
property.key.name == "url") {
|
|
12451
|
-
// property is url
|
|
12452
|
-
const maybeObjExpression = ancestors.slice(-3)[0];
|
|
12453
|
-
if (maybeObjExpression.type === "ObjectExpression") {
|
|
12454
|
-
const objExpression = maybeObjExpression;
|
|
12455
|
-
const properties = objExpression.properties
|
|
12456
|
-
.filter((p) => p.type === "Property")
|
|
12457
|
-
.map((p) => p);
|
|
12458
|
-
const identifiers = properties
|
|
12459
|
-
.filter((p) => p.key.type === "Identifier")
|
|
12460
|
-
.map((p) => p.key.name);
|
|
12461
|
-
const urlBrowserImageProperties = [
|
|
12462
|
-
"imageName",
|
|
12463
|
-
"height",
|
|
12464
|
-
"width",
|
|
12465
|
-
"url",
|
|
12466
|
-
];
|
|
12467
|
-
const propCount = identifiers.filter((i) => urlBrowserImageProperties.indexOf(i) !== -1).length;
|
|
12468
|
-
if (propCount === 4) {
|
|
12469
|
-
// the object expression has the 4 properties
|
|
12470
|
-
const maybeArrayExpression = ancestors.slice(-4)[0];
|
|
12471
|
-
if (maybeArrayExpression.type === "ArrayExpression") {
|
|
12472
|
-
const maybeProperty = ancestors.slice(-5)[0];
|
|
12473
|
-
if (maybeProperty.type === "Property") {
|
|
12474
|
-
const property = maybeProperty;
|
|
12475
|
-
if (property.key.type === "Identifier" &&
|
|
12476
|
-
property.key.name == "images") {
|
|
12477
|
-
// property is images
|
|
12478
|
-
const literal = node;
|
|
12479
|
-
const originalUrlValue = literal.value;
|
|
12480
|
-
try {
|
|
12481
|
-
const hashedUrlValue = addHashToUrl(originalUrlValue, rootDir);
|
|
12482
|
-
literal.value = literal.value.replace(originalUrlValue, hashedUrlValue);
|
|
12483
|
-
literal.raw = literal.raw.replace(originalUrlValue, hashedUrlValue);
|
|
12484
|
-
addFileToFilesToBeRenamed(rootDir, originalUrlValue, hashedUrlValue, fileRenames);
|
|
12485
|
-
}
|
|
12486
|
-
catch (_c) {
|
|
12487
|
-
}
|
|
12488
|
-
}
|
|
12489
|
-
}
|
|
12490
|
-
}
|
|
12491
|
-
}
|
|
12492
|
-
}
|
|
12493
|
-
}
|
|
12494
|
-
}
|
|
12495
|
-
}
|
|
12496
|
-
},
|
|
12497
|
-
});
|
|
12498
|
-
const indexJsCode = generate(ast);
|
|
12499
|
-
yield writeFile(indexJsFile, indexJsCode);
|
|
12500
|
-
// Parse links in index.html using htmlparser2
|
|
12501
|
-
// note: if link has attribute hash="false", then hashing
|
|
12502
|
-
// is skipped for that link
|
|
12503
|
-
const rawHtml = yield readFile(indexHtmlFile, "utf-8");
|
|
12504
|
-
const dom = parseDocument(rawHtml);
|
|
12505
|
-
// handle the css links
|
|
12506
|
-
const links = selectAll("link", dom);
|
|
12507
|
-
links
|
|
12508
|
-
.map((link) => link)
|
|
12509
|
-
.forEach((link) => {
|
|
12510
|
-
var _a;
|
|
12511
|
-
if (link.attribs["href"].endsWith(".css") &&
|
|
12512
|
-
!(((_a = link.attribs["hash"]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "false")) {
|
|
12513
|
-
const originalUrl = link.attribs["href"];
|
|
12288
|
+
function hashM2c2kitAssets(rootDir, cwd = "") {
|
|
12289
|
+
const indexHtmlFile = path.join(cwd, rootDir, "index.html");
|
|
12290
|
+
const indexJsFile = path.join(cwd, rootDir, "index.js");
|
|
12291
|
+
return {
|
|
12292
|
+
name: "hash-m2c2kit-assets",
|
|
12293
|
+
closeBundle: {
|
|
12294
|
+
sequential: true,
|
|
12295
|
+
async handler() {
|
|
12296
|
+
const fileRenames = new Array();
|
|
12297
|
+
let indexjs;
|
|
12298
|
+
try {
|
|
12299
|
+
indexjs = await readFile(indexJsFile, "utf-8");
|
|
12300
|
+
} catch {
|
|
12301
|
+
throw new Error(
|
|
12302
|
+
"could not hash m2c2 assets because there was an error reading index.js. This is a fatal problem because index.js is required."
|
|
12303
|
+
);
|
|
12304
|
+
}
|
|
12305
|
+
let ast;
|
|
12306
|
+
try {
|
|
12307
|
+
ast = parse(indexjs, { ecmaVersion: 2020 });
|
|
12308
|
+
} catch {
|
|
12309
|
+
throw new Error(
|
|
12310
|
+
"could not hash m2c2 assets because there was an error parsing index.js. This is a fatal problem because index.js is not valid JavaScript."
|
|
12311
|
+
);
|
|
12312
|
+
}
|
|
12313
|
+
ancestor(ast, {
|
|
12314
|
+
// this code will be run each time the walker visits a literal
|
|
12315
|
+
Literal(node, ancestors) {
|
|
12316
|
+
if (ancestors.length >= 2) {
|
|
12317
|
+
const maybeProperty = ancestors.slice(-2)[0];
|
|
12318
|
+
if (maybeProperty.type === "Property") {
|
|
12319
|
+
const property = maybeProperty;
|
|
12320
|
+
if (property.key.type === "Identifier" && property.key.name == "canvasKitWasmUrl") {
|
|
12321
|
+
const literal = node;
|
|
12322
|
+
const originalUrlValue = literal.value;
|
|
12323
|
+
try {
|
|
12324
|
+
const hashedUrlValue = addHashToUrl(
|
|
12325
|
+
originalUrlValue,
|
|
12326
|
+
/**
|
|
12327
|
+
* by our convention, the wasm file will be served from
|
|
12328
|
+
* the assets directory, so the location is
|
|
12329
|
+
* `assets/${canvasKitWasmUrl}` not `${canvasKitWasmUrl}`
|
|
12330
|
+
*/
|
|
12331
|
+
`${rootDir}/assets`,
|
|
12332
|
+
cwd
|
|
12333
|
+
);
|
|
12334
|
+
literal.value = literal.value.replace(
|
|
12335
|
+
originalUrlValue,
|
|
12336
|
+
hashedUrlValue
|
|
12337
|
+
);
|
|
12338
|
+
literal.raw = literal.raw.replace(
|
|
12339
|
+
originalUrlValue,
|
|
12340
|
+
hashedUrlValue
|
|
12341
|
+
);
|
|
12342
|
+
addFileToFilesToBeRenamed(
|
|
12343
|
+
`${rootDir}/assets`,
|
|
12344
|
+
originalUrlValue,
|
|
12345
|
+
hashedUrlValue,
|
|
12346
|
+
fileRenames
|
|
12347
|
+
);
|
|
12348
|
+
} catch {
|
|
12349
|
+
console.log(
|
|
12350
|
+
`warning: could not hash canvaskit.wasm resource because it was not found at ${originalUrlValue}`
|
|
12351
|
+
);
|
|
12352
|
+
}
|
|
12353
|
+
}
|
|
12354
|
+
}
|
|
12355
|
+
}
|
|
12356
|
+
if (ancestors.length >= 5) {
|
|
12357
|
+
const maybeProperty = ancestors.slice(-2)[0];
|
|
12358
|
+
if (maybeProperty.type === "Property") {
|
|
12359
|
+
const property = maybeProperty;
|
|
12360
|
+
if (property.key.type === "Identifier" && property.key.name == "url") {
|
|
12361
|
+
const maybeObjExpression = ancestors.slice(-3)[0];
|
|
12362
|
+
if (maybeObjExpression.type === "ObjectExpression") {
|
|
12363
|
+
const objExpression = maybeObjExpression;
|
|
12364
|
+
const properties = objExpression.properties.filter((p) => p.type === "Property").map((p) => p);
|
|
12365
|
+
const identifiers = properties.filter((p) => p.key.type === "Identifier").map((p) => p.key.name);
|
|
12366
|
+
const urlFontAssetProperties = ["fontName", "url"];
|
|
12367
|
+
const propCount = identifiers.filter(
|
|
12368
|
+
(i) => urlFontAssetProperties.indexOf(i) !== -1
|
|
12369
|
+
).length;
|
|
12370
|
+
if (propCount === 2) {
|
|
12371
|
+
const maybeArrayExpression = ancestors.slice(-4)[0];
|
|
12372
|
+
if (maybeArrayExpression.type === "ArrayExpression") {
|
|
12373
|
+
const maybeProperty2 = ancestors.slice(-5)[0];
|
|
12374
|
+
if (maybeProperty2.type === "Property") {
|
|
12375
|
+
const property2 = maybeProperty2;
|
|
12376
|
+
if (property2.key.type === "Identifier" && property2.key.name == "fonts") {
|
|
12377
|
+
const literal = node;
|
|
12378
|
+
const originalUrlValue = literal.value;
|
|
12379
|
+
const optionsDeclarator = ancestors.slice(
|
|
12380
|
+
-7
|
|
12381
|
+
)[0];
|
|
12382
|
+
const objExpression2 = optionsDeclarator.init;
|
|
12383
|
+
const properties2 = objExpression2.properties;
|
|
12384
|
+
const gameIdProperty = properties2.filter(
|
|
12385
|
+
(p) => p.key.type === "Identifier" && p.key.name == "id"
|
|
12386
|
+
)[0];
|
|
12387
|
+
const gameId = gameIdProperty.value.value;
|
|
12514
12388
|
try {
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12389
|
+
const hashedUrlValue = addHashToUrl(
|
|
12390
|
+
originalUrlValue,
|
|
12391
|
+
path.join(rootDir, "assets", gameId),
|
|
12392
|
+
cwd
|
|
12393
|
+
);
|
|
12394
|
+
literal.value = literal.value.replace(
|
|
12395
|
+
originalUrlValue,
|
|
12396
|
+
hashedUrlValue
|
|
12397
|
+
);
|
|
12398
|
+
literal.raw = literal.raw.replace(
|
|
12399
|
+
originalUrlValue,
|
|
12400
|
+
hashedUrlValue
|
|
12401
|
+
);
|
|
12402
|
+
addFileToFilesToBeRenamed(
|
|
12403
|
+
path.join(rootDir, "assets", gameId),
|
|
12404
|
+
originalUrlValue,
|
|
12405
|
+
hashedUrlValue,
|
|
12406
|
+
fileRenames
|
|
12407
|
+
);
|
|
12408
|
+
} catch {
|
|
12520
12409
|
}
|
|
12410
|
+
}
|
|
12521
12411
|
}
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
|
|
12529
|
-
|
|
12530
|
-
|
|
12412
|
+
}
|
|
12413
|
+
}
|
|
12414
|
+
}
|
|
12415
|
+
}
|
|
12416
|
+
}
|
|
12417
|
+
}
|
|
12418
|
+
if (ancestors.length >= 5) {
|
|
12419
|
+
const maybeProperty = ancestors.slice(-2)[0];
|
|
12420
|
+
if (maybeProperty.type === "Property") {
|
|
12421
|
+
const property = maybeProperty;
|
|
12422
|
+
if (property.key.type === "Identifier" && property.key.name == "url") {
|
|
12423
|
+
const maybeObjExpression = ancestors.slice(-3)[0];
|
|
12424
|
+
if (maybeObjExpression.type === "ObjectExpression") {
|
|
12425
|
+
const objExpression = maybeObjExpression;
|
|
12426
|
+
const properties = objExpression.properties.filter((p) => p.type === "Property").map((p) => p);
|
|
12427
|
+
const identifiers = properties.filter((p) => p.key.type === "Identifier").map((p) => p.key.name);
|
|
12428
|
+
const urlBrowserImageProperties = [
|
|
12429
|
+
"imageName",
|
|
12430
|
+
"height",
|
|
12431
|
+
"width",
|
|
12432
|
+
"url"
|
|
12433
|
+
];
|
|
12434
|
+
const propCount = identifiers.filter(
|
|
12435
|
+
(i) => urlBrowserImageProperties.indexOf(i) !== -1
|
|
12436
|
+
).length;
|
|
12437
|
+
if (propCount === 4) {
|
|
12438
|
+
const maybeArrayExpression = ancestors.slice(-4)[0];
|
|
12439
|
+
if (maybeArrayExpression.type === "ArrayExpression") {
|
|
12440
|
+
const maybeProperty2 = ancestors.slice(-5)[0];
|
|
12441
|
+
if (maybeProperty2.type === "Property") {
|
|
12442
|
+
const property2 = maybeProperty2;
|
|
12443
|
+
if (property2.key.type === "Identifier" && property2.key.name == "images") {
|
|
12444
|
+
const literal = node;
|
|
12445
|
+
const originalUrlValue = literal.value;
|
|
12446
|
+
const optionsDeclarator = ancestors.slice(
|
|
12447
|
+
-7
|
|
12448
|
+
)[0];
|
|
12449
|
+
const objExpression2 = optionsDeclarator.init;
|
|
12450
|
+
const properties2 = objExpression2.properties;
|
|
12451
|
+
const gameIdProperty = properties2.filter(
|
|
12452
|
+
(p) => p.key.type === "Identifier" && p.key.name == "id"
|
|
12453
|
+
)[0];
|
|
12454
|
+
const gameId = gameIdProperty.value.value;
|
|
12531
12455
|
try {
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12456
|
+
const hashedUrlValue = addHashToUrl(
|
|
12457
|
+
originalUrlValue,
|
|
12458
|
+
path.join(rootDir, "assets", gameId),
|
|
12459
|
+
cwd
|
|
12460
|
+
);
|
|
12461
|
+
literal.value = literal.value.replace(
|
|
12462
|
+
originalUrlValue,
|
|
12463
|
+
hashedUrlValue
|
|
12464
|
+
);
|
|
12465
|
+
literal.raw = literal.raw.replace(
|
|
12466
|
+
originalUrlValue,
|
|
12467
|
+
hashedUrlValue
|
|
12468
|
+
);
|
|
12469
|
+
addFileToFilesToBeRenamed(
|
|
12470
|
+
path.join(rootDir, "assets", gameId),
|
|
12471
|
+
originalUrlValue,
|
|
12472
|
+
hashedUrlValue,
|
|
12473
|
+
fileRenames
|
|
12474
|
+
);
|
|
12475
|
+
} catch {
|
|
12538
12476
|
}
|
|
12477
|
+
}
|
|
12539
12478
|
}
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12479
|
+
}
|
|
12480
|
+
}
|
|
12481
|
+
}
|
|
12482
|
+
}
|
|
12483
|
+
}
|
|
12484
|
+
}
|
|
12485
|
+
}
|
|
12486
|
+
});
|
|
12487
|
+
const indexJsCode = generate(ast);
|
|
12488
|
+
await writeFile(indexJsFile, indexJsCode);
|
|
12489
|
+
const rawHtml = await readFile(indexHtmlFile, "utf-8");
|
|
12490
|
+
const dom = parseDocument(rawHtml);
|
|
12491
|
+
const links = selectAll("link", dom);
|
|
12492
|
+
links.map((link) => link).forEach((link) => {
|
|
12493
|
+
if (link.attribs["href"].endsWith(".css") && !(link.attribs["hash"]?.toLowerCase() === "false")) {
|
|
12494
|
+
const originalUrl = link.attribs["href"];
|
|
12495
|
+
try {
|
|
12496
|
+
link.attribs["href"] = addHashToUrl(
|
|
12497
|
+
link.attribs["href"],
|
|
12498
|
+
rootDir,
|
|
12499
|
+
cwd
|
|
12500
|
+
);
|
|
12501
|
+
addFileToFilesToBeRenamed(
|
|
12502
|
+
rootDir,
|
|
12503
|
+
originalUrl,
|
|
12504
|
+
link.attribs["href"],
|
|
12505
|
+
fileRenames
|
|
12506
|
+
);
|
|
12507
|
+
} catch {
|
|
12508
|
+
console.log(
|
|
12509
|
+
`warning: could not hash css resource because it was not found at ${link.attribs["href"]}`
|
|
12510
|
+
);
|
|
12511
|
+
}
|
|
12512
|
+
}
|
|
12513
|
+
});
|
|
12514
|
+
const scripts = selectAll("script", dom);
|
|
12515
|
+
scripts.map((script) => script).forEach((script) => {
|
|
12516
|
+
if (script.attribs["src"] === "./index.js" && !(script.attribs["hash"]?.toLowerCase() === "false")) {
|
|
12517
|
+
try {
|
|
12518
|
+
const hashedFilename = addHashToUrl("index.js", rootDir, cwd);
|
|
12519
|
+
script.attribs["src"] = "./" + path.basename(hashedFilename);
|
|
12520
|
+
addFileToFilesToBeRenamed(
|
|
12521
|
+
rootDir,
|
|
12522
|
+
"index.js",
|
|
12523
|
+
hashedFilename,
|
|
12524
|
+
fileRenames
|
|
12525
|
+
);
|
|
12526
|
+
} catch {
|
|
12527
|
+
console.log(
|
|
12528
|
+
`warning: could not hash index.js because it was not found at ${indexJsFile}`
|
|
12529
|
+
);
|
|
12530
|
+
}
|
|
12531
|
+
}
|
|
12532
|
+
});
|
|
12533
|
+
await writeFile(indexHtmlFile, render(dom));
|
|
12534
|
+
fileRenames.forEach((fr) => {
|
|
12535
|
+
if (existsSync(path.join(cwd, fr.original))) {
|
|
12536
|
+
renameSync(path.join(cwd, fr.original), path.join(cwd, fr.new));
|
|
12537
|
+
}
|
|
12538
|
+
});
|
|
12539
|
+
await writeHashManifest(rootDir, fileRenames, cwd);
|
|
12540
|
+
}
|
|
12541
|
+
}
|
|
12542
|
+
};
|
|
12553
12543
|
}
|
|
12554
12544
|
const getFileHash = (filePath) => {
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12545
|
+
const buffer = readFileSync(filePath);
|
|
12546
|
+
const hash = createHash("md5").update(buffer).digest("hex");
|
|
12547
|
+
return hash.slice(0, HASH_CHARACTER_LENGTH);
|
|
12548
|
+
};
|
|
12549
|
+
const addHashToUrl = (url, rootDir, cwd = "") => {
|
|
12550
|
+
const ext = path.extname(url);
|
|
12551
|
+
const hash = getFileHash(path.join(cwd, rootDir, url));
|
|
12552
|
+
if (ext) {
|
|
12553
|
+
url = url.replace(ext, `.${hash}${ext}`);
|
|
12554
|
+
} else {
|
|
12555
|
+
url = url + `.${hash}`;
|
|
12556
|
+
}
|
|
12557
|
+
return url;
|
|
12558
12558
|
};
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12559
|
+
async function writeHashManifest(rootDir, fileRenames, cwd = "") {
|
|
12560
|
+
const manifestFilename = path.join(cwd, rootDir, "hash-manifest.json");
|
|
12561
|
+
const manifest = {};
|
|
12562
|
+
fileRenames.forEach((fr) => {
|
|
12563
|
+
let originalName = fr.original.replace(rootDir + path.sep, "");
|
|
12564
|
+
let hashedName = fr.new.replace(rootDir + path.sep, "");
|
|
12565
|
+
if (process.platform === "win32") {
|
|
12566
|
+
originalName = originalName.replace(/\\/g, "/");
|
|
12567
|
+
hashedName = hashedName.replace(/\\/g, "/");
|
|
12564
12568
|
}
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
};
|
|
12570
|
-
function writeHashManifest(rootDir, fileRenames) {
|
|
12571
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
12572
|
-
const manifestFilename = path.join(rootDir, "hash-manifest.json");
|
|
12573
|
-
const manifest = {};
|
|
12574
|
-
fileRenames.forEach((fr) => {
|
|
12575
|
-
let originalName = fr.original.replace(rootDir + path.sep, "");
|
|
12576
|
-
let hashedName = fr.new.replace(rootDir + path.sep, "");
|
|
12577
|
-
if (process.platform === "win32") {
|
|
12578
|
-
originalName = originalName.replace(/\\/g, "/");
|
|
12579
|
-
hashedName = hashedName.replace(/\\/g, "/");
|
|
12580
|
-
}
|
|
12581
|
-
manifest[originalName] = hashedName;
|
|
12582
|
-
});
|
|
12583
|
-
const manifestString = JSON.stringify(manifest, null, 2);
|
|
12584
|
-
yield writeFile(manifestFilename, manifestString);
|
|
12585
|
-
});
|
|
12569
|
+
manifest[originalName] = hashedName;
|
|
12570
|
+
});
|
|
12571
|
+
const manifestString = JSON.stringify(manifest, null, 2);
|
|
12572
|
+
await writeFile(manifestFilename, manifestString);
|
|
12586
12573
|
}
|
|
12587
12574
|
function addFileToFilesToBeRenamed(rootDir, originalUrlValue, hashedUrlValue, fileRenames) {
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12575
|
+
const filename = path.join(rootDir, originalUrlValue);
|
|
12576
|
+
const hashedFilename = path.join(rootDir, hashedUrlValue);
|
|
12577
|
+
fileRenames.push({
|
|
12578
|
+
original: filename,
|
|
12579
|
+
new: hashedFilename
|
|
12580
|
+
});
|
|
12594
12581
|
}
|
|
12595
12582
|
|
|
12596
12583
|
function makeM2c2kitServiceWorker(rootDir, additionalFiles) {
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
}
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
}
|
|
12584
|
+
let inputFile = "";
|
|
12585
|
+
return {
|
|
12586
|
+
name: "make-m2c2kit-serviceworker",
|
|
12587
|
+
buildStart: {
|
|
12588
|
+
handler(options) {
|
|
12589
|
+
if (options.input) {
|
|
12590
|
+
if (typeof options.input === "string") {
|
|
12591
|
+
inputFile = path.resolve(options.input);
|
|
12592
|
+
} else if (Array.isArray(options.input)) {
|
|
12593
|
+
inputFile = path.resolve(options.input[0]);
|
|
12594
|
+
} else {
|
|
12595
|
+
throw new Error(
|
|
12596
|
+
"Could not determine input file when trying to add service worker code."
|
|
12597
|
+
);
|
|
12598
|
+
}
|
|
12599
|
+
}
|
|
12600
|
+
}
|
|
12601
|
+
},
|
|
12602
|
+
transform: {
|
|
12603
|
+
handler(code, id) {
|
|
12604
|
+
if (id === inputFile) {
|
|
12605
|
+
if (code.includes("//# sourceMappingURL")) {
|
|
12606
|
+
code = code.replace(
|
|
12607
|
+
"//# sourceMappingURL",
|
|
12608
|
+
serviceWorkerRegistrationCode + "\n//# sourceMappingURL"
|
|
12609
|
+
);
|
|
12610
|
+
}
|
|
12611
|
+
}
|
|
12612
|
+
return code;
|
|
12613
|
+
}
|
|
12614
|
+
},
|
|
12615
|
+
closeBundle: {
|
|
12616
|
+
sequential: true,
|
|
12617
|
+
async handler() {
|
|
12618
|
+
const packageHomeFolderPath = path.dirname(
|
|
12619
|
+
fileURLToPath(import.meta.url)
|
|
12620
|
+
);
|
|
12621
|
+
let swContents = (await readFile(path.join(packageHomeFolderPath, "assets", "sw.js"))).toString();
|
|
12622
|
+
const manifestFilename = path.join(rootDir, "hash-manifest.json");
|
|
12623
|
+
const manifestContents = (await readFile(manifestFilename)).toString();
|
|
12624
|
+
const manifest = JSON.parse(manifestContents);
|
|
12625
|
+
const hashedFilenames = Object.values(manifest);
|
|
12626
|
+
let replacementString = hashedFilenames.map((f) => `"${f}"`).join(",");
|
|
12627
|
+
if (additionalFiles) {
|
|
12628
|
+
replacementString = replacementString + "," + additionalFiles.map((f) => `"${f}"`).join(",");
|
|
12629
|
+
}
|
|
12630
|
+
swContents = swContents.replace(
|
|
12631
|
+
'"_-_ADDITIONAL_RESOURCES_TO_CACHE_-_"',
|
|
12632
|
+
replacementString
|
|
12633
|
+
);
|
|
12634
|
+
const swDestinationFilename = path.join(rootDir, "sw.js");
|
|
12635
|
+
await writeFile(swDestinationFilename, swContents);
|
|
12636
|
+
}
|
|
12637
|
+
}
|
|
12638
|
+
};
|
|
12651
12639
|
}
|
|
12652
12640
|
const serviceWorkerRegistrationCode = `const registerServiceWorker = async () => {
|
|
12653
12641
|
if ("serviceWorker" in navigator) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m2c2kit/build-helpers",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -11,28 +11,29 @@
|
|
|
11
11
|
],
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@rollup/plugin-commonjs": "25.0.0",
|
|
14
|
-
"@rollup/plugin-node-resolve": "15.0
|
|
15
|
-
"@rollup/plugin-typescript": "11.1.1",
|
|
14
|
+
"@rollup/plugin-node-resolve": "15.1.0",
|
|
16
15
|
"@types/estree": "1.0.1",
|
|
17
16
|
"@types/findup-sync": "4.0.2",
|
|
17
|
+
"cpy": "10.1.0",
|
|
18
18
|
"cpy-cli": "4.2.0",
|
|
19
19
|
"findup-sync": "5.0.0",
|
|
20
20
|
"rimraf": "5.0.1",
|
|
21
21
|
"rollup": "3.21.0",
|
|
22
22
|
"rollup-plugin-copy": "^3.4.0",
|
|
23
23
|
"rollup-plugin-dts": "5.3.0",
|
|
24
|
-
"
|
|
24
|
+
"rollup-plugin-esbuild": "5.0.0",
|
|
25
|
+
"typescript": "5.1.3"
|
|
25
26
|
},
|
|
26
27
|
"scripts": {
|
|
27
|
-
"build": "npm run clean && rollup -c
|
|
28
|
+
"build": "npm run clean && tsc && rollup -c",
|
|
28
29
|
"clean": "rimraf build dist .rollup.cache tsconfig.tsbuildinfo",
|
|
29
|
-
"test": "
|
|
30
|
+
"test": "cd ../.. && npx env-cmd -f .env.jest jest --selectProjects @m2c2kit/build-helpers"
|
|
30
31
|
},
|
|
31
32
|
"license": "MIT",
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"acorn": "8.8.2",
|
|
34
35
|
"acorn-walk": "8.2.0",
|
|
35
|
-
"astring": "1.8.
|
|
36
|
+
"astring": "1.8.6",
|
|
36
37
|
"css-select": "5.1.0",
|
|
37
38
|
"dom-serializer": "2.0.0",
|
|
38
39
|
"domhandler": "5.0.3",
|