@patchstack/connect 0.2.11 → 0.3.1
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/cli.js +45 -191
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +0 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -42
- package/dist/index.d.ts +1 -42
- package/dist/index.js +0 -89
- package/dist/index.js.map +1 -1
- package/dist/protect/templates/guard.ts +52 -95
- package/dist/protect/templates/rules.json +4 -7
- package/dist/protect.cjs +1240 -0
- package/dist/protect.cjs.map +1 -0
- package/dist/protect.d.ts +51 -0
- package/dist/protect.js +1210 -0
- package/dist/protect.js.map +1 -0
- package/package.json +6 -1
- package/dist/protect/templates/engine.d.ts +0 -57
- package/dist/protect/templates/engine.js +0 -137
- package/dist/protect/templates/manifest.d.ts +0 -1
package/dist/cli.js
CHANGED
|
@@ -1108,94 +1108,6 @@ function isEnvironment(value) {
|
|
|
1108
1108
|
// src/mark-build.ts
|
|
1109
1109
|
import { existsSync, readdirSync, statSync } from "fs";
|
|
1110
1110
|
import path7 from "path";
|
|
1111
|
-
|
|
1112
|
-
// src/stack.ts
|
|
1113
|
-
var STACK_RULES = [
|
|
1114
|
-
// Meta-frameworks (most specific first).
|
|
1115
|
-
{ category: "framework", pkg: "@tanstack/react-start", label: "tanstack-start" },
|
|
1116
|
-
{ category: "framework", pkg: "@tanstack/start", label: "tanstack-start" },
|
|
1117
|
-
{ category: "framework", pkg: "next", label: "next" },
|
|
1118
|
-
{ category: "framework", pkg: "nuxt", label: "nuxt" },
|
|
1119
|
-
{ category: "framework", pkg: "@remix-run/react", label: "remix" },
|
|
1120
|
-
{ category: "framework", pkg: "@remix-run/node", label: "remix" },
|
|
1121
|
-
{ category: "framework", pkg: "react-router", label: "react-router" },
|
|
1122
|
-
{ category: "framework", pkg: "astro", label: "astro" },
|
|
1123
|
-
{ category: "framework", pkg: "@sveltejs/kit", label: "sveltekit" },
|
|
1124
|
-
{ category: "framework", pkg: "@builder.io/qwik-city", label: "qwik-city" },
|
|
1125
|
-
{ category: "framework", pkg: "gatsby", label: "gatsby" },
|
|
1126
|
-
{ category: "framework", pkg: "express", label: "express" },
|
|
1127
|
-
{ category: "framework", pkg: "fastify", label: "fastify" },
|
|
1128
|
-
// UI runtimes.
|
|
1129
|
-
{ category: "ui", pkg: "@angular/core", label: "angular" },
|
|
1130
|
-
{ category: "ui", pkg: "react-dom", label: "react" },
|
|
1131
|
-
{ category: "ui", pkg: "react", label: "react" },
|
|
1132
|
-
{ category: "ui", pkg: "vue", label: "vue" },
|
|
1133
|
-
{ category: "ui", pkg: "svelte", label: "svelte" },
|
|
1134
|
-
{ category: "ui", pkg: "solid-js", label: "solid" },
|
|
1135
|
-
{ category: "ui", pkg: "preact", label: "preact" },
|
|
1136
|
-
// Bundlers / build tools.
|
|
1137
|
-
{ category: "bundler", pkg: "vite", label: "vite" },
|
|
1138
|
-
{ category: "bundler", pkg: "@rspack/core", label: "rspack" },
|
|
1139
|
-
{ category: "bundler", pkg: "webpack", label: "webpack" },
|
|
1140
|
-
{ category: "bundler", pkg: "parcel", label: "parcel" },
|
|
1141
|
-
{ category: "bundler", pkg: "rollup", label: "rollup" },
|
|
1142
|
-
{ category: "bundler", pkg: "esbuild", label: "esbuild" },
|
|
1143
|
-
// Deployment-runtime hints from build deps.
|
|
1144
|
-
{ category: "runtime", pkg: "wrangler", label: "cloudflare-workers" },
|
|
1145
|
-
{ category: "runtime", pkg: "@cloudflare/workers-types", label: "cloudflare-workers" },
|
|
1146
|
-
{ category: "runtime", pkg: "@cloudflare/vite-plugin", label: "cloudflare-workers" },
|
|
1147
|
-
{ category: "runtime", pkg: "@vercel/node", label: "vercel" },
|
|
1148
|
-
{ category: "runtime", pkg: "@netlify/functions", label: "netlify" },
|
|
1149
|
-
{ category: "runtime", pkg: "@netlify/blobs", label: "netlify" },
|
|
1150
|
-
// Vibe / builder platforms — the "learn from each platform" signal.
|
|
1151
|
-
{ category: "builder", pkg: "lovable-tagger", label: "lovable" },
|
|
1152
|
-
{ category: "builder", pkg: "@replit/vite-plugin-runtime-error-modal", label: "replit" },
|
|
1153
|
-
{ category: "builder", pkg: "@replit/vite-plugin-cartographer", label: "replit" }
|
|
1154
|
-
];
|
|
1155
|
-
var HOSTING_ENV_PATTERNS = [
|
|
1156
|
-
/^CF_/,
|
|
1157
|
-
/^CLOUDFLARE_/,
|
|
1158
|
-
/^VERCEL/,
|
|
1159
|
-
/^NETLIFY/,
|
|
1160
|
-
/^AWS_(LAMBDA|REGION|EXECUTION)/,
|
|
1161
|
-
/^FLY_/,
|
|
1162
|
-
/^RENDER/,
|
|
1163
|
-
/^RAILWAY_/,
|
|
1164
|
-
/^DENO_/,
|
|
1165
|
-
/^EDGE_RUNTIME/,
|
|
1166
|
-
/^DYNO$/,
|
|
1167
|
-
/^K_SERVICE$/,
|
|
1168
|
-
/^GAE_/,
|
|
1169
|
-
/^FUNCTION_/
|
|
1170
|
-
];
|
|
1171
|
-
function collectHostingEnvKeys(env = process.env) {
|
|
1172
|
-
return Object.keys(env).filter((key) => HOSTING_ENV_PATTERNS.some((pattern) => pattern.test(key))).sort();
|
|
1173
|
-
}
|
|
1174
|
-
function detectStack(packages, env = process.env) {
|
|
1175
|
-
const present = new Set(packages.map((pkg) => pkg.name));
|
|
1176
|
-
const firstMatch = (category) => {
|
|
1177
|
-
for (const rule of STACK_RULES) {
|
|
1178
|
-
if (rule.category === category && present.has(rule.pkg)) {
|
|
1179
|
-
return rule.label;
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
return null;
|
|
1183
|
-
};
|
|
1184
|
-
return {
|
|
1185
|
-
framework: firstMatch("framework"),
|
|
1186
|
-
ui: firstMatch("ui"),
|
|
1187
|
-
bundler: firstMatch("bundler"),
|
|
1188
|
-
runtime: firstMatch("runtime"),
|
|
1189
|
-
builder: firstMatch("builder"),
|
|
1190
|
-
ecosystem: "npm",
|
|
1191
|
-
hostingEnvKeys: collectHostingEnvKeys(env)
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
function isEmptyStack(stack) {
|
|
1195
|
-
return stack.framework === null && stack.ui === null && stack.bundler === null && stack.runtime === null && stack.builder === null && stack.hostingEnvKeys.length === 0;
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
// src/mark-build.ts
|
|
1199
1111
|
var MARKER_ATTR = "data-patchstack-build";
|
|
1200
1112
|
var BUILD_DIR_CANDIDATES = ["dist", "build", "out", ".output/public"];
|
|
1201
1113
|
function resolveBuildDir(cwd, override) {
|
|
@@ -1226,14 +1138,11 @@ function findHtmlFiles(dir) {
|
|
|
1226
1138
|
walk2(dir);
|
|
1227
1139
|
return out;
|
|
1228
1140
|
}
|
|
1229
|
-
function buildInjectionSnippet(checksum
|
|
1141
|
+
function buildInjectionSnippet(checksum) {
|
|
1230
1142
|
const statements = ["window.__PATCHSTACK_PROD__=true;"];
|
|
1231
1143
|
if (checksum !== null && checksum !== "") {
|
|
1232
1144
|
statements.push(`window.__PATCHSTACK_BUILD__=${JSON.stringify(checksum)};`);
|
|
1233
1145
|
}
|
|
1234
|
-
if (stack != null && !isEmptyStack(stack)) {
|
|
1235
|
-
statements.push(`window.__PATCHSTACK_STACK__=${JSON.stringify(stack)};`);
|
|
1236
|
-
}
|
|
1237
1146
|
return `<script ${MARKER_ATTR}>${statements.join("")}</script>`;
|
|
1238
1147
|
}
|
|
1239
1148
|
function injectMarker(html, snippet) {
|
|
@@ -1252,13 +1161,17 @@ function injectMarker(html, snippet) {
|
|
|
1252
1161
|
|
|
1253
1162
|
// src/protect/install.ts
|
|
1254
1163
|
import { readFileSync, writeFileSync, existsSync as existsSync2, mkdirSync, copyFileSync } from "fs";
|
|
1255
|
-
import { join } from "path";
|
|
1164
|
+
import { join, dirname } from "path";
|
|
1256
1165
|
import { fileURLToPath } from "url";
|
|
1257
|
-
var TEMPLATES = fileURLToPath(
|
|
1166
|
+
var TEMPLATES = join(dirname(fileURLToPath(import.meta.url)), "protect", "templates");
|
|
1167
|
+
var APP = process.cwd();
|
|
1168
|
+
var PS_DIR = join(APP, "src/integrations/patchstack");
|
|
1169
|
+
var read = (p) => readFileSync(p, "utf8");
|
|
1170
|
+
var log = (msg) => console.log(`patchstack protect: ${msg}`);
|
|
1258
1171
|
var CLIENT_TUNNEL = [
|
|
1259
1172
|
"",
|
|
1260
|
-
" // PATCHSTACK
|
|
1261
|
-
" //
|
|
1173
|
+
" // PATCHSTACK: in the browser, tunnel Supabase traffic through the app's own server guard",
|
|
1174
|
+
" // (same-origin) so payloads are inspected before they reach Supabase.",
|
|
1262
1175
|
" if (typeof window !== 'undefined') {",
|
|
1263
1176
|
" const target = typeof input === 'string' ? input : input instanceof Request ? input.url : String(input);",
|
|
1264
1177
|
" const method = init?.method ?? (input instanceof Request ? input.method : 'GET');",
|
|
@@ -1270,11 +1183,11 @@ var CLIENT_TUNNEL = [
|
|
|
1270
1183
|
].join("\n");
|
|
1271
1184
|
var START_IMPORTS = [
|
|
1272
1185
|
'import { getRequest } from "@tanstack/react-start/server";',
|
|
1273
|
-
'import { GUARD_PATH, handleGuardRequest } from "@/integrations/patchstack/guard";'
|
|
1186
|
+
'import { GUARD_PATH, handleGuardRequest, inspectServerFn } from "@/integrations/patchstack/guard";'
|
|
1274
1187
|
].join("\n");
|
|
1275
1188
|
var START_MIDDLEWARE = [
|
|
1276
1189
|
"",
|
|
1277
|
-
"// Patchstack
|
|
1190
|
+
"// Patchstack guard (browser tunnel): intercept tunneled Supabase traffic before anything else.",
|
|
1278
1191
|
"const patchstackGuard = createMiddleware().server(async ({ next }) => {",
|
|
1279
1192
|
" const request = getRequest();",
|
|
1280
1193
|
" if (request) {",
|
|
@@ -1283,115 +1196,69 @@ var START_MIDDLEWARE = [
|
|
|
1283
1196
|
" }",
|
|
1284
1197
|
" return next();",
|
|
1285
1198
|
"});",
|
|
1199
|
+
"",
|
|
1200
|
+
"// Patchstack guard (server functions): inspect server-fn args before they reach the database,",
|
|
1201
|
+
"// covering apps that mutate via TanStack server functions (which bypass the browser tunnel).",
|
|
1202
|
+
'const patchstackFunctionGuard = createMiddleware({ type: "function" }).server(async ({ next, data }) => {',
|
|
1203
|
+
" const blocked = await inspectServerFn(data);",
|
|
1204
|
+
" if (blocked) throw new Error(blocked.message);",
|
|
1205
|
+
" return next();",
|
|
1206
|
+
"});",
|
|
1286
1207
|
""
|
|
1287
1208
|
].join("\n");
|
|
1288
|
-
var PS_DIR_REL = "src/integrations/patchstack";
|
|
1289
|
-
function log(msg) {
|
|
1290
|
-
console.log(`patchstack protect: ${msg}`);
|
|
1291
|
-
}
|
|
1292
1209
|
function detectSupportedStack(cwd) {
|
|
1293
1210
|
const pkgPath = join(cwd, "package.json");
|
|
1294
1211
|
if (!existsSync2(pkgPath)) return false;
|
|
1295
|
-
const pkg = JSON.parse(
|
|
1212
|
+
const pkg = JSON.parse(read(pkgPath));
|
|
1296
1213
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1297
1214
|
return Boolean(deps["@tanstack/react-start"]) && existsSync2(join(cwd, "src/start.ts")) && existsSync2(join(cwd, "src/integrations/supabase/client.ts"));
|
|
1298
1215
|
}
|
|
1299
|
-
function generateManifest(cwd) {
|
|
1300
|
-
const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
|
|
1301
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1302
|
-
const packages = {};
|
|
1303
|
-
for (const name of Object.keys(deps)) {
|
|
1304
|
-
let version = String(deps[name]).replace(/^[^\d]*/, "");
|
|
1305
|
-
const installed = join(cwd, "node_modules", name, "package.json");
|
|
1306
|
-
if (existsSync2(installed)) {
|
|
1307
|
-
try {
|
|
1308
|
-
version = JSON.parse(readFileSync(installed, "utf8")).version;
|
|
1309
|
-
} catch {
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
packages[name] = version;
|
|
1313
|
-
}
|
|
1314
|
-
mkdirSync(join(cwd, PS_DIR_REL), { recursive: true });
|
|
1315
|
-
const body = "// Patchstack auto-guard manifest \u2014 generated from the lockfile.\n// Do not edit; regenerated by `patchstack-connect protect --manifest` (wired into prebuild).\nexport const manifest = " + JSON.stringify({ packages }, null, 2) + ";\n";
|
|
1316
|
-
writeFileSync(join(cwd, PS_DIR_REL, "manifest.js"), body);
|
|
1317
|
-
log(`wrote manifest.js (${Object.keys(packages).length} packages)`);
|
|
1318
|
-
}
|
|
1319
1216
|
function scaffold(cwd) {
|
|
1320
|
-
const dst = join(cwd,
|
|
1217
|
+
const dst = join(cwd, "src/integrations/patchstack");
|
|
1321
1218
|
mkdirSync(dst, { recursive: true });
|
|
1322
|
-
copyFileSync(join(TEMPLATES, "engine.js"), join(dst, "engine.js"));
|
|
1323
|
-
copyFileSync(join(TEMPLATES, "engine.d.ts"), join(dst, "engine.d.ts"));
|
|
1324
|
-
copyFileSync(join(TEMPLATES, "manifest.d.ts"), join(dst, "manifest.d.ts"));
|
|
1325
|
-
copyFileSync(join(TEMPLATES, "rules.json"), join(dst, "rules.json"));
|
|
1326
1219
|
copyFileSync(join(TEMPLATES, "guard.ts"), join(dst, "guard.ts"));
|
|
1327
|
-
|
|
1220
|
+
copyFileSync(join(TEMPLATES, "rules.json"), join(dst, "rules.json"));
|
|
1221
|
+
log("scaffolded guard.ts + rules.json");
|
|
1328
1222
|
}
|
|
1329
1223
|
function patchClient(cwd) {
|
|
1330
1224
|
const p = join(cwd, "src/integrations/supabase/client.ts");
|
|
1331
|
-
let s =
|
|
1332
|
-
if (s.includes("x-ps-target"))
|
|
1333
|
-
log("client.ts already wired");
|
|
1334
|
-
return;
|
|
1335
|
-
}
|
|
1225
|
+
let s = read(p);
|
|
1226
|
+
if (s.includes("x-ps-target")) return log("client.ts already wired");
|
|
1336
1227
|
const anchor = "headers.set('apikey', supabaseKey);";
|
|
1337
|
-
if (!s.includes(anchor))
|
|
1338
|
-
|
|
1339
|
-
return;
|
|
1340
|
-
}
|
|
1341
|
-
s = s.replace(anchor, anchor + "\n" + CLIENT_TUNNEL);
|
|
1342
|
-
writeFileSync(p, s);
|
|
1228
|
+
if (!s.includes(anchor)) return log("client.ts anchor not found \u2014 skipping (template changed?)");
|
|
1229
|
+
writeFileSync(p, s.replace(anchor, anchor + "\n" + CLIENT_TUNNEL));
|
|
1343
1230
|
log("patched client.ts (tunnel Supabase through the guard)");
|
|
1344
1231
|
}
|
|
1345
1232
|
function patchStart(cwd) {
|
|
1346
1233
|
const p = join(cwd, "src/start.ts");
|
|
1347
|
-
let s =
|
|
1348
|
-
if (s.includes("patchstackGuard"))
|
|
1349
|
-
log("start.ts already wired");
|
|
1350
|
-
return;
|
|
1351
|
-
}
|
|
1234
|
+
let s = read(p);
|
|
1235
|
+
if (s.includes("patchstackGuard")) return log("start.ts already wired");
|
|
1352
1236
|
const importAnchor = 'import { createStart, createMiddleware } from "@tanstack/react-start";';
|
|
1353
1237
|
const exportAnchor = "export const startInstance";
|
|
1354
1238
|
const rmAnchor = "requestMiddleware: [";
|
|
1355
1239
|
if (!s.includes(importAnchor) || !s.includes(exportAnchor) || !s.includes(rmAnchor)) {
|
|
1356
|
-
log("start.ts anchors not found (template changed?)
|
|
1357
|
-
return;
|
|
1240
|
+
return log("start.ts anchors not found \u2014 skipping (template changed?)");
|
|
1358
1241
|
}
|
|
1359
1242
|
s = s.replace(importAnchor, importAnchor + "\n" + START_IMPORTS);
|
|
1360
1243
|
s = s.replace(exportAnchor, START_MIDDLEWARE + "\n" + exportAnchor);
|
|
1361
1244
|
s = s.replace(rmAnchor, rmAnchor + "patchstackGuard, ");
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
const pkg = JSON.parse(readFileSync(p, "utf8"));
|
|
1368
|
-
pkg.scripts = pkg.scripts || {};
|
|
1369
|
-
const step = "patchstack-connect protect --manifest";
|
|
1370
|
-
const prebuild = pkg.scripts.prebuild || "";
|
|
1371
|
-
if (prebuild.includes(step)) {
|
|
1372
|
-
log("prebuild already refreshes the manifest");
|
|
1373
|
-
return;
|
|
1245
|
+
const fmAnchor = "functionMiddleware: [";
|
|
1246
|
+
if (s.includes(fmAnchor)) {
|
|
1247
|
+
s = s.replace(fmAnchor, fmAnchor + "patchstackFunctionGuard, ");
|
|
1248
|
+
} else {
|
|
1249
|
+
s = s.replace(rmAnchor, "functionMiddleware: [patchstackFunctionGuard],\n " + rmAnchor);
|
|
1374
1250
|
}
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
log("wired manifest refresh into prebuild");
|
|
1251
|
+
writeFileSync(p, s);
|
|
1252
|
+
log("patched start.ts (guard registered as request + function middleware)");
|
|
1378
1253
|
}
|
|
1379
|
-
function runProtect(cwd
|
|
1380
|
-
if (opts.manifestOnly) {
|
|
1381
|
-
generateManifest(cwd);
|
|
1382
|
-
return;
|
|
1383
|
-
}
|
|
1254
|
+
function runProtect(cwd) {
|
|
1384
1255
|
if (!detectSupportedStack(cwd)) {
|
|
1385
|
-
log(
|
|
1386
|
-
"runtime protection currently supports TanStack Start + Supabase apps; stack not detected \u2014 skipping."
|
|
1387
|
-
);
|
|
1256
|
+
log("runtime protection currently supports TanStack Start + Supabase apps; stack not detected \u2014 skipping.");
|
|
1388
1257
|
return;
|
|
1389
1258
|
}
|
|
1390
1259
|
scaffold(cwd);
|
|
1391
1260
|
patchClient(cwd);
|
|
1392
1261
|
patchStart(cwd);
|
|
1393
|
-
generateManifest(cwd);
|
|
1394
|
-
wirePrebuild(cwd);
|
|
1395
1262
|
log("done \u2014 guard wired and always-on (blocks by default). Set PATCHSTACK_MODE=dry-run for log-only.");
|
|
1396
1263
|
}
|
|
1397
1264
|
|
|
@@ -1407,9 +1274,8 @@ Usage:
|
|
|
1407
1274
|
patchstack-connect status [options] Show current configuration
|
|
1408
1275
|
patchstack-connect mark-build [options] Stamp built HTML with a production flag +
|
|
1409
1276
|
build fingerprint (run as a postbuild step)
|
|
1410
|
-
patchstack-connect protect
|
|
1411
|
-
a
|
|
1412
|
-
regenerates the package manifest (prebuild).
|
|
1277
|
+
patchstack-connect protect Install always-on runtime protection (the
|
|
1278
|
+
guard) into a TanStack Start + Supabase app.
|
|
1413
1279
|
patchstack-connect help Print this message
|
|
1414
1280
|
|
|
1415
1281
|
Options (for scan and status):
|
|
@@ -1547,9 +1413,9 @@ async function runScan(args) {
|
|
|
1547
1413
|
}
|
|
1548
1414
|
return 0;
|
|
1549
1415
|
}
|
|
1550
|
-
async function runProtectCommand(
|
|
1416
|
+
async function runProtectCommand(_args) {
|
|
1551
1417
|
try {
|
|
1552
|
-
runProtect(process.cwd()
|
|
1418
|
+
runProtect(process.cwd());
|
|
1553
1419
|
} catch (err) {
|
|
1554
1420
|
console.warn(`patchstack protect: skipped (${err.message}).`);
|
|
1555
1421
|
}
|
|
@@ -1570,19 +1436,9 @@ async function runStatus(args) {
|
|
|
1570
1436
|
}
|
|
1571
1437
|
return 0;
|
|
1572
1438
|
}
|
|
1573
|
-
function describeStack(stack) {
|
|
1574
|
-
const parts = [stack.builder, stack.framework, stack.ui, stack.runtime].filter(
|
|
1575
|
-
(part) => part !== null
|
|
1576
|
-
);
|
|
1577
|
-
if (stack.hostingEnvKeys.length > 0) {
|
|
1578
|
-
parts.push(`${stack.hostingEnvKeys.length} hosting env key(s)`);
|
|
1579
|
-
}
|
|
1580
|
-
return parts.length > 0 ? parts.join(" \xB7 ") : null;
|
|
1581
|
-
}
|
|
1582
1439
|
async function runMarkBuild(args) {
|
|
1583
1440
|
const cwd = process.cwd();
|
|
1584
1441
|
let checksum = null;
|
|
1585
|
-
let stack = null;
|
|
1586
1442
|
try {
|
|
1587
1443
|
const manifest = await scanLockfile(cwd);
|
|
1588
1444
|
for (const warning of manifest.warnings ?? []) {
|
|
@@ -1590,7 +1446,6 @@ async function runMarkBuild(args) {
|
|
|
1590
1446
|
}
|
|
1591
1447
|
const { payload } = buildWirePayload(manifest);
|
|
1592
1448
|
checksum = computeManifestChecksum(payload.packages);
|
|
1593
|
-
stack = detectStack(payload.packages);
|
|
1594
1449
|
} catch (err) {
|
|
1595
1450
|
console.warn(
|
|
1596
1451
|
`mark-build: could not compute the build fingerprint (${err.message}). Stamping the production flag only.`
|
|
@@ -1608,7 +1463,7 @@ async function runMarkBuild(args) {
|
|
|
1608
1463
|
console.warn(`mark-build: no HTML files found under ${dir}. Nothing to mark.`);
|
|
1609
1464
|
return 0;
|
|
1610
1465
|
}
|
|
1611
|
-
const snippet = buildInjectionSnippet(checksum
|
|
1466
|
+
const snippet = buildInjectionSnippet(checksum);
|
|
1612
1467
|
let marked = 0;
|
|
1613
1468
|
for (const file of files) {
|
|
1614
1469
|
const before = readFileSync2(file, "utf8");
|
|
@@ -1618,9 +1473,8 @@ async function runMarkBuild(args) {
|
|
|
1618
1473
|
marked += 1;
|
|
1619
1474
|
}
|
|
1620
1475
|
}
|
|
1621
|
-
const stackSummary = stack !== null ? describeStack(stack) : null;
|
|
1622
1476
|
console.log(
|
|
1623
|
-
`mark-build: marked ${marked} HTML file(s) in ${dir}${checksum !== null ? ` (build ${checksum})` : ""}
|
|
1477
|
+
`mark-build: marked ${marked} HTML file(s) in ${dir}${checksum !== null ? ` (build ${checksum})` : ""}.`
|
|
1624
1478
|
);
|
|
1625
1479
|
return 0;
|
|
1626
1480
|
}
|