@patchstack/connect 0.3.22 → 0.3.24
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/AGENT-INSTALL.md +16 -7
- package/README.md +22 -2
- package/dist/chunk-MJOTFUDE.js +87 -0
- package/dist/chunk-MJOTFUDE.js.map +1 -0
- package/dist/cli.js +2868 -129
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +105 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -2
- package/dist/index.d.ts +37 -2
- package/dist/index.js +103 -1
- package/dist/index.js.map +1 -1
- package/dist/protect.cjs +1182 -217
- package/dist/protect.cjs.map +1 -1
- package/dist/protect.d.ts +27 -1
- package/dist/protect.edge.js +3530 -0
- package/dist/protect.edge.js.map +7 -0
- package/dist/protect.js +1066 -193
- package/dist/protect.js.map +1 -1
- package/dist/{refresh-manifest-OW7WT5A6.js → refresh-manifest-MUWVIPFR.js} +12 -2
- package/dist/refresh-manifest-MUWVIPFR.js.map +1 -0
- package/package.json +11 -3
- package/dist/refresh-manifest-OW7WT5A6.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,8 @@ __export(src_exports, {
|
|
|
46
46
|
ensureWidgetInHtml: () => ensureWidgetInHtml,
|
|
47
47
|
findSourceShell: () => findSourceShell,
|
|
48
48
|
isEmptyStack: () => isEmptyStack,
|
|
49
|
+
persistApiKey: () => persistApiKey,
|
|
50
|
+
persistPulseAuth: () => persistPulseAuth,
|
|
49
51
|
persistSiteUuid: () => persistSiteUuid,
|
|
50
52
|
postManifest: () => postManifest,
|
|
51
53
|
resolveConfig: () => resolveConfig,
|
|
@@ -964,6 +966,88 @@ function compareSegments(a, b) {
|
|
|
964
966
|
return 0;
|
|
965
967
|
}
|
|
966
968
|
|
|
969
|
+
// src/pulse-token.ts
|
|
970
|
+
var TOKEN_SKEW_MS = 6e4;
|
|
971
|
+
function buildTokenUrl(manifestEndpoint) {
|
|
972
|
+
const url = new URL(manifestEndpoint);
|
|
973
|
+
const path8 = url.pathname.replace(/\/$/, "");
|
|
974
|
+
url.pathname = path8.endsWith("/manifest") ? `${path8.slice(0, -"/manifest".length)}/token` : "/monitor/pulse/token";
|
|
975
|
+
url.search = "";
|
|
976
|
+
url.hash = "";
|
|
977
|
+
return url.toString();
|
|
978
|
+
}
|
|
979
|
+
function parsePulseAuth(credential) {
|
|
980
|
+
const index = credential.lastIndexOf("-");
|
|
981
|
+
if (index <= 0 || index === credential.length - 1) return null;
|
|
982
|
+
const clientId = credential.slice(index + 1);
|
|
983
|
+
if (!/^\d+$/.test(clientId)) return null;
|
|
984
|
+
return { clientId, clientSecret: credential.slice(0, index) };
|
|
985
|
+
}
|
|
986
|
+
var cached = null;
|
|
987
|
+
var inflight = null;
|
|
988
|
+
function clearPulseToken() {
|
|
989
|
+
cached = null;
|
|
990
|
+
}
|
|
991
|
+
async function getPulseToken(config, fetchImpl = fetch) {
|
|
992
|
+
if (typeof config.pulseAuth !== "string" || config.pulseAuth.length === 0) return null;
|
|
993
|
+
if (cached !== null && Date.now() < cached.expiresAt - TOKEN_SKEW_MS) {
|
|
994
|
+
return cached.token;
|
|
995
|
+
}
|
|
996
|
+
if (inflight !== null) return inflight;
|
|
997
|
+
const credentials = parsePulseAuth(config.pulseAuth);
|
|
998
|
+
if (credentials === null) return null;
|
|
999
|
+
inflight = (async () => {
|
|
1000
|
+
try {
|
|
1001
|
+
const response = await fetchImpl(buildTokenUrl(config.endpoint), {
|
|
1002
|
+
method: "POST",
|
|
1003
|
+
headers: {
|
|
1004
|
+
"Content-Type": "application/json",
|
|
1005
|
+
Accept: "application/json",
|
|
1006
|
+
"User-Agent": "@patchstack/connect"
|
|
1007
|
+
},
|
|
1008
|
+
body: JSON.stringify({
|
|
1009
|
+
grant_type: "client_credentials",
|
|
1010
|
+
client_id: credentials.clientId,
|
|
1011
|
+
client_secret: credentials.clientSecret
|
|
1012
|
+
}),
|
|
1013
|
+
signal: AbortSignal.timeout(config.timeoutMs)
|
|
1014
|
+
});
|
|
1015
|
+
if (!response.ok) return null;
|
|
1016
|
+
const body = await response.json();
|
|
1017
|
+
if (typeof body.access_token !== "string" || body.access_token.length === 0) return null;
|
|
1018
|
+
const expiresIn = Number(body.expires_in);
|
|
1019
|
+
const ttlMs = Number.isFinite(expiresIn) && expiresIn > 0 ? expiresIn * 1e3 : 36e5;
|
|
1020
|
+
cached = { token: body.access_token, expiresAt: Date.now() + ttlMs };
|
|
1021
|
+
return body.access_token;
|
|
1022
|
+
} catch {
|
|
1023
|
+
return null;
|
|
1024
|
+
} finally {
|
|
1025
|
+
inflight = null;
|
|
1026
|
+
}
|
|
1027
|
+
})();
|
|
1028
|
+
return inflight;
|
|
1029
|
+
}
|
|
1030
|
+
async function pulseAuthHeader(config, fetchImpl = fetch) {
|
|
1031
|
+
const token = await getPulseToken(config, fetchImpl);
|
|
1032
|
+
return token === null ? {} : { Authorization: `Bearer ${token}` };
|
|
1033
|
+
}
|
|
1034
|
+
async function pulseFetch(config, url, init, fetchImpl = fetch) {
|
|
1035
|
+
const send = async () => {
|
|
1036
|
+
const auth = await pulseAuthHeader(config, fetchImpl);
|
|
1037
|
+
const response = await fetchImpl(url, {
|
|
1038
|
+
...init,
|
|
1039
|
+
headers: { ...init.headers, ...auth }
|
|
1040
|
+
});
|
|
1041
|
+
return { response, authenticated: auth.Authorization !== void 0 };
|
|
1042
|
+
};
|
|
1043
|
+
const first = await send();
|
|
1044
|
+
if (first.response.status === 401 && first.authenticated) {
|
|
1045
|
+
clearPulseToken();
|
|
1046
|
+
return (await send()).response;
|
|
1047
|
+
}
|
|
1048
|
+
return first.response;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
967
1051
|
// src/client.ts
|
|
968
1052
|
var DEFAULT_ENDPOINT = "https://api.patchstack.com/monitor/pulse/manifest";
|
|
969
1053
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
@@ -980,7 +1064,7 @@ async function postManifest(config, payload) {
|
|
|
980
1064
|
const timeoutMs = config.timeoutMs;
|
|
981
1065
|
let response;
|
|
982
1066
|
try {
|
|
983
|
-
response = await
|
|
1067
|
+
response = await pulseFetch(config, url, {
|
|
984
1068
|
method: "POST",
|
|
985
1069
|
headers: {
|
|
986
1070
|
"Content-Type": "application/json",
|
|
@@ -1072,8 +1156,12 @@ async function resolveConfig(options) {
|
|
|
1072
1156
|
"CONFIG_MISSING"
|
|
1073
1157
|
);
|
|
1074
1158
|
}
|
|
1159
|
+
const apiKeyRaw = fromEnv.apiKey ?? fromFile.apiKey ?? null;
|
|
1160
|
+
const pulseAuthRaw = fromEnv.pulseAuth ?? fromFile.pulseAuth ?? apiKeyRaw;
|
|
1075
1161
|
return {
|
|
1076
1162
|
siteUuid: siteUuid === null || siteUuid.length === 0 ? null : siteUuid,
|
|
1163
|
+
apiKey: apiKeyRaw === null || apiKeyRaw.length === 0 ? null : apiKeyRaw,
|
|
1164
|
+
pulseAuth: pulseAuthRaw === null || pulseAuthRaw.length === 0 ? null : pulseAuthRaw,
|
|
1077
1165
|
endpoint,
|
|
1078
1166
|
timeoutMs,
|
|
1079
1167
|
environment,
|
|
@@ -1090,6 +1178,14 @@ async function persistSiteUuid(cwd, siteUuid) {
|
|
|
1090
1178
|
const existing = await readConfigFile(cwd);
|
|
1091
1179
|
return writeConfigFile(cwd, { ...existing, siteUuid });
|
|
1092
1180
|
}
|
|
1181
|
+
async function persistApiKey(cwd, apiKey) {
|
|
1182
|
+
const existing = await readConfigFile(cwd);
|
|
1183
|
+
return writeConfigFile(cwd, { ...existing, apiKey });
|
|
1184
|
+
}
|
|
1185
|
+
async function persistPulseAuth(cwd, pulseAuth) {
|
|
1186
|
+
const existing = await readConfigFile(cwd);
|
|
1187
|
+
return writeConfigFile(cwd, { ...existing, pulseAuth });
|
|
1188
|
+
}
|
|
1093
1189
|
async function readConfigFile(cwd) {
|
|
1094
1190
|
const target = import_node_path6.default.join(cwd, CONFIG_FILENAME);
|
|
1095
1191
|
let raw;
|
|
@@ -1131,6 +1227,8 @@ function readEnv() {
|
|
|
1131
1227
|
const environmentRaw = process.env.PATCHSTACK_ENVIRONMENT;
|
|
1132
1228
|
return {
|
|
1133
1229
|
siteUuid: process.env.PATCHSTACK_SITE_UUID ?? void 0,
|
|
1230
|
+
apiKey: process.env.PATCHSTACK_API_KEY ?? void 0,
|
|
1231
|
+
pulseAuth: process.env.PATCHSTACK_PULSE_AUTH ?? void 0,
|
|
1134
1232
|
endpoint: process.env.PATCHSTACK_ENDPOINT ?? void 0,
|
|
1135
1233
|
timeoutMs,
|
|
1136
1234
|
environment: environmentRaw !== void 0 && environmentRaw.length > 0 ? environmentRaw : void 0
|
|
@@ -1299,6 +1397,10 @@ async function scanAndReport(options = {}) {
|
|
|
1299
1397
|
if (config.siteUuid === null && response.uuid !== void 0 && response.uuid.length > 0) {
|
|
1300
1398
|
await persistSiteUuid(cwd, response.uuid);
|
|
1301
1399
|
}
|
|
1400
|
+
if (typeof response.api_key === "string" && response.api_key.length > 0) {
|
|
1401
|
+
await persistApiKey(cwd, response.api_key);
|
|
1402
|
+
await persistPulseAuth(cwd, response.api_key);
|
|
1403
|
+
}
|
|
1302
1404
|
return {
|
|
1303
1405
|
manifest,
|
|
1304
1406
|
response,
|
|
@@ -1325,6 +1427,8 @@ async function scanAndReport(options = {}) {
|
|
|
1325
1427
|
ensureWidgetInHtml,
|
|
1326
1428
|
findSourceShell,
|
|
1327
1429
|
isEmptyStack,
|
|
1430
|
+
persistApiKey,
|
|
1431
|
+
persistPulseAuth,
|
|
1328
1432
|
persistSiteUuid,
|
|
1329
1433
|
postManifest,
|
|
1330
1434
|
resolveConfig,
|