@patchstack/connect 0.2.9 → 0.2.11
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 +107 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +92 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -1
- package/dist/index.d.ts +42 -1
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -1
- package/dist/protect/templates/guard.ts +3 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1108,6 +1108,94 @@ 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
|
|
1111
1199
|
var MARKER_ATTR = "data-patchstack-build";
|
|
1112
1200
|
var BUILD_DIR_CANDIDATES = ["dist", "build", "out", ".output/public"];
|
|
1113
1201
|
function resolveBuildDir(cwd, override) {
|
|
@@ -1138,11 +1226,14 @@ function findHtmlFiles(dir) {
|
|
|
1138
1226
|
walk2(dir);
|
|
1139
1227
|
return out;
|
|
1140
1228
|
}
|
|
1141
|
-
function buildInjectionSnippet(checksum) {
|
|
1229
|
+
function buildInjectionSnippet(checksum, stack) {
|
|
1142
1230
|
const statements = ["window.__PATCHSTACK_PROD__=true;"];
|
|
1143
1231
|
if (checksum !== null && checksum !== "") {
|
|
1144
1232
|
statements.push(`window.__PATCHSTACK_BUILD__=${JSON.stringify(checksum)};`);
|
|
1145
1233
|
}
|
|
1234
|
+
if (stack != null && !isEmptyStack(stack)) {
|
|
1235
|
+
statements.push(`window.__PATCHSTACK_STACK__=${JSON.stringify(stack)};`);
|
|
1236
|
+
}
|
|
1146
1237
|
return `<script ${MARKER_ATTR}>${statements.join("")}</script>`;
|
|
1147
1238
|
}
|
|
1148
1239
|
function injectMarker(html, snippet) {
|
|
@@ -1301,7 +1392,7 @@ function runProtect(cwd, opts = {}) {
|
|
|
1301
1392
|
patchStart(cwd);
|
|
1302
1393
|
generateManifest(cwd);
|
|
1303
1394
|
wirePrebuild(cwd);
|
|
1304
|
-
log("done \u2014 guard wired
|
|
1395
|
+
log("done \u2014 guard wired and always-on (blocks by default). Set PATCHSTACK_MODE=dry-run for log-only.");
|
|
1305
1396
|
}
|
|
1306
1397
|
|
|
1307
1398
|
// src/cli.ts
|
|
@@ -1479,9 +1570,19 @@ async function runStatus(args) {
|
|
|
1479
1570
|
}
|
|
1480
1571
|
return 0;
|
|
1481
1572
|
}
|
|
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
|
+
}
|
|
1482
1582
|
async function runMarkBuild(args) {
|
|
1483
1583
|
const cwd = process.cwd();
|
|
1484
1584
|
let checksum = null;
|
|
1585
|
+
let stack = null;
|
|
1485
1586
|
try {
|
|
1486
1587
|
const manifest = await scanLockfile(cwd);
|
|
1487
1588
|
for (const warning of manifest.warnings ?? []) {
|
|
@@ -1489,6 +1590,7 @@ async function runMarkBuild(args) {
|
|
|
1489
1590
|
}
|
|
1490
1591
|
const { payload } = buildWirePayload(manifest);
|
|
1491
1592
|
checksum = computeManifestChecksum(payload.packages);
|
|
1593
|
+
stack = detectStack(payload.packages);
|
|
1492
1594
|
} catch (err) {
|
|
1493
1595
|
console.warn(
|
|
1494
1596
|
`mark-build: could not compute the build fingerprint (${err.message}). Stamping the production flag only.`
|
|
@@ -1506,7 +1608,7 @@ async function runMarkBuild(args) {
|
|
|
1506
1608
|
console.warn(`mark-build: no HTML files found under ${dir}. Nothing to mark.`);
|
|
1507
1609
|
return 0;
|
|
1508
1610
|
}
|
|
1509
|
-
const snippet = buildInjectionSnippet(checksum);
|
|
1611
|
+
const snippet = buildInjectionSnippet(checksum, stack);
|
|
1510
1612
|
let marked = 0;
|
|
1511
1613
|
for (const file of files) {
|
|
1512
1614
|
const before = readFileSync2(file, "utf8");
|
|
@@ -1516,8 +1618,9 @@ async function runMarkBuild(args) {
|
|
|
1516
1618
|
marked += 1;
|
|
1517
1619
|
}
|
|
1518
1620
|
}
|
|
1621
|
+
const stackSummary = stack !== null ? describeStack(stack) : null;
|
|
1519
1622
|
console.log(
|
|
1520
|
-
`mark-build: marked ${marked} HTML file(s) in ${dir}${checksum !== null ? ` (build ${checksum})` : ""}.`
|
|
1623
|
+
`mark-build: marked ${marked} HTML file(s) in ${dir}${checksum !== null ? ` (build ${checksum})` : ""}${stackSummary !== null ? ` [${stackSummary}]` : ""}.`
|
|
1521
1624
|
);
|
|
1522
1625
|
return 0;
|
|
1523
1626
|
}
|