@afterpack/next 0.2.4 → 0.2.6
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/README.md +2 -1
- package/dist/index.cjs +4 -21
- package/dist/index.js +4 -21
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -95,7 +95,8 @@ Without a key, AfterPack runs on your machine with the full pipeline at any pres
|
|
|
95
95
|
[`AFTERPACK_KEY`](https://www.afterpack.dev/docs/config#key) in your environment and the same plugin
|
|
96
96
|
builds in AfterPack's cloud instead, which adds per-region
|
|
97
97
|
[directives](https://www.afterpack.dev/docs/directives) and two hardening transforms you can turn
|
|
98
|
-
on: self-integrity
|
|
98
|
+
on: self-integrity, which detects edits to its own check table only, not edits
|
|
99
|
+
elsewhere in your code, and comparison hardening. Keep the key out of `next.config.ts`: the
|
|
99
100
|
plugin rejects it there. See [AfterPack Pro](https://www.afterpack.dev/docs/pro).
|
|
100
101
|
|
|
101
102
|
## Links
|
package/dist/index.cjs
CHANGED
|
@@ -40,23 +40,6 @@ function readBuildIdFromManifest(distDir) {
|
|
|
40
40
|
return null;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
function detectBundler(distDir) {
|
|
44
|
-
if ((0, node_fs.existsSync)((0, node_path.join)(distDir, "turbopack"))) return "turbopack";
|
|
45
|
-
if ((0, node_fs.existsSync)((0, node_path.join)(distDir, "server", "webpack-runtime.js"))) return "webpack";
|
|
46
|
-
return "unknown";
|
|
47
|
-
}
|
|
48
|
-
const TURBOPACK_CHUNK_RE = /^(?:turbopack-)?([0-9a-z~._-]{13})\.(?:js|css)$/;
|
|
49
|
-
const WEBPACK_CHUNK_RE = /[-.]([0-9a-f]{16})\.js$/;
|
|
50
|
-
function nextChunkToken(bundler) {
|
|
51
|
-
const pattern = bundler === "turbopack" ? TURBOPACK_CHUNK_RE : bundler === "webpack" ? WEBPACK_CHUNK_RE : null;
|
|
52
|
-
return (relativePath) => {
|
|
53
|
-
if (pattern === null || !relativePath.startsWith("static/chunks/")) return null;
|
|
54
|
-
return pattern.exec((0, node_path.basename)(relativePath))?.[1] ?? null;
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function skipNextInternals(relativePath) {
|
|
58
|
-
return relativePath === "cache" || relativePath.startsWith("trace");
|
|
59
|
-
}
|
|
60
43
|
function stripTrailer(path) {
|
|
61
44
|
const code = (0, node_fs.readFileSync)(path, "utf8");
|
|
62
45
|
const stripped = (0, __afterpack_integration_utils.withSourceMappingURL)(code, null);
|
|
@@ -101,7 +84,7 @@ async function runAfterpackHook(input) {
|
|
|
101
84
|
const files = (0, __afterpack_integration_utils.collectJsFiles)(chunksDir, { include: settings.paths?.include });
|
|
102
85
|
if (files.length === 0) throw new Error(`[${LABEL}] no client JS found under ${chunksDir} — refusing to report a protected build for a tree nothing was obfuscated in.`);
|
|
103
86
|
const engine = input.engine ?? await loadEngineOnDemand();
|
|
104
|
-
const bundler =
|
|
87
|
+
const bundler = (0, __afterpack_integration_utils.detectNextBundler)(distDir);
|
|
105
88
|
if (bundler === "unknown") console.warn(`[${LABEL}] could not tell whether this build used Turbopack or webpack, so no content-hashed chunk name was changed. The obfuscated chunks keep the plain build's names, and an immutable cache may serve stale bytes. Report this with your Next.js version.`);
|
|
106
89
|
const buildId = readBuildIdFromManifest(distDir);
|
|
107
90
|
const result = await (0, __afterpack_integration_utils.runObfuscationPass)({
|
|
@@ -118,8 +101,8 @@ async function runAfterpackHook(input) {
|
|
|
118
101
|
postMinify: true,
|
|
119
102
|
hashedNames: {
|
|
120
103
|
root: distDir,
|
|
121
|
-
tokenOf: nextChunkToken(bundler),
|
|
122
|
-
skip: skipNextInternals
|
|
104
|
+
tokenOf: (0, __afterpack_integration_utils.nextChunkToken)(bundler),
|
|
105
|
+
skip: __afterpack_integration_utils.skipNextInternals
|
|
123
106
|
},
|
|
124
107
|
afterWrite: (written) => {
|
|
125
108
|
stripServedSourceMaps(written, (0, node_path.join)(distDir, "static"), settings.diagnostics?.level === "none" ? () => {} : (message) => console.log(message));
|
|
@@ -137,7 +120,7 @@ async function runAfterpackHook(input) {
|
|
|
137
120
|
}
|
|
138
121
|
function warnIfBuildIdPinned(buildId, diagnosticsLevel) {
|
|
139
122
|
if (diagnosticsLevel === "none") return;
|
|
140
|
-
if (!/^[0-9a-
|
|
123
|
+
if (!/^[0-9a-z_-]{16,}$/i.test(buildId)) console.warn(`[${LABEL}] this build's id "${buildId}" is not a random Next id, so \`static/${buildId}/_buildManifest.js\` and \`_ssgManifest.js\` keep one immutable URL across releases while their bytes change. AfterPack cannot rename the build id — Next writes into static/${buildId}/ after the build hook runs. Leave \`generateBuildId\` unset so Next randomizes it per build, or bump it every release.`);
|
|
141
124
|
}
|
|
142
125
|
|
|
143
126
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
3
|
-
import { collectJsFiles, collectSourceMaps, collectStylesheets, createTelemetryReporter, passSettings, removeSourceMaps, resolveClientIdentity, resolvePluginConfig, runObfuscationPass, stripCssSourceMappingURLs, withSourceMappingURL } from "@afterpack/integration-utils";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { collectJsFiles, collectSourceMaps, collectStylesheets, createTelemetryReporter, detectNextBundler, nextChunkToken, passSettings, removeSourceMaps, resolveClientIdentity, resolvePluginConfig, runObfuscationPass, skipNextInternals, stripCssSourceMappingURLs, withSourceMappingURL } from "@afterpack/integration-utils";
|
|
4
4
|
|
|
5
5
|
//#region src/hook.ts
|
|
6
6
|
const LABEL = "afterpack-next";
|
|
@@ -17,23 +17,6 @@ function readBuildIdFromManifest(distDir) {
|
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
function detectBundler(distDir) {
|
|
21
|
-
if (existsSync(join(distDir, "turbopack"))) return "turbopack";
|
|
22
|
-
if (existsSync(join(distDir, "server", "webpack-runtime.js"))) return "webpack";
|
|
23
|
-
return "unknown";
|
|
24
|
-
}
|
|
25
|
-
const TURBOPACK_CHUNK_RE = /^(?:turbopack-)?([0-9a-z~._-]{13})\.(?:js|css)$/;
|
|
26
|
-
const WEBPACK_CHUNK_RE = /[-.]([0-9a-f]{16})\.js$/;
|
|
27
|
-
function nextChunkToken(bundler) {
|
|
28
|
-
const pattern = bundler === "turbopack" ? TURBOPACK_CHUNK_RE : bundler === "webpack" ? WEBPACK_CHUNK_RE : null;
|
|
29
|
-
return (relativePath) => {
|
|
30
|
-
if (pattern === null || !relativePath.startsWith("static/chunks/")) return null;
|
|
31
|
-
return pattern.exec(basename(relativePath))?.[1] ?? null;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
function skipNextInternals(relativePath) {
|
|
35
|
-
return relativePath === "cache" || relativePath.startsWith("trace");
|
|
36
|
-
}
|
|
37
20
|
function stripTrailer(path) {
|
|
38
21
|
const code = readFileSync(path, "utf8");
|
|
39
22
|
const stripped = withSourceMappingURL(code, null);
|
|
@@ -78,7 +61,7 @@ async function runAfterpackHook(input) {
|
|
|
78
61
|
const files = collectJsFiles(chunksDir, { include: settings.paths?.include });
|
|
79
62
|
if (files.length === 0) throw new Error(`[${LABEL}] no client JS found under ${chunksDir} — refusing to report a protected build for a tree nothing was obfuscated in.`);
|
|
80
63
|
const engine = input.engine ?? await loadEngineOnDemand();
|
|
81
|
-
const bundler =
|
|
64
|
+
const bundler = detectNextBundler(distDir);
|
|
82
65
|
if (bundler === "unknown") console.warn(`[${LABEL}] could not tell whether this build used Turbopack or webpack, so no content-hashed chunk name was changed. The obfuscated chunks keep the plain build's names, and an immutable cache may serve stale bytes. Report this with your Next.js version.`);
|
|
83
66
|
const buildId = readBuildIdFromManifest(distDir);
|
|
84
67
|
const result = await runObfuscationPass({
|
|
@@ -114,7 +97,7 @@ async function runAfterpackHook(input) {
|
|
|
114
97
|
}
|
|
115
98
|
function warnIfBuildIdPinned(buildId, diagnosticsLevel) {
|
|
116
99
|
if (diagnosticsLevel === "none") return;
|
|
117
|
-
if (!/^[0-9a-
|
|
100
|
+
if (!/^[0-9a-z_-]{16,}$/i.test(buildId)) console.warn(`[${LABEL}] this build's id "${buildId}" is not a random Next id, so \`static/${buildId}/_buildManifest.js\` and \`_ssgManifest.js\` keep one immutable URL across releases while their bytes change. AfterPack cannot rename the build id — Next writes into static/${buildId}/ after the build hook runs. Leave \`generateBuildId\` unset so Next randomizes it per build, or bump it every release.`);
|
|
118
101
|
}
|
|
119
102
|
|
|
120
103
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@afterpack/next",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Next.js integration for AfterPack: obfuscate the client JavaScript of a Next.js build inside next build",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"next": ">=15.4.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@afterpack/core": "~0.2.
|
|
32
|
-
"@afterpack/integration-utils": "0.2.
|
|
31
|
+
"@afterpack/core": "~0.2.7",
|
|
32
|
+
"@afterpack/integration-utils": "0.2.6"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@biomejs/biome": "2.4.4",
|