surrge 0.4.8 → 0.5.0
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/auth/config.d.ts +6 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/passkey.d.ts +15 -0
- package/dist/auth/passkey.d.ts.map +1 -0
- package/dist/auth/session.d.ts +3 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/setup.d.ts +8 -0
- package/dist/auth/setup.d.ts.map +1 -0
- package/dist/dashboard/html.d.ts.map +1 -1
- package/dist/dashboard/index.d.ts +7 -1
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/index.js +69 -2
- package/dist/loader.js +69 -2
- package/dist/register.js +69 -2
- package/dist/scripts/postinstall.js +38 -0
- package/dist/src/cli.js +53 -0
- package/dist/src/hooks.js +148 -0
- package/dist/src/index.js +26073 -0
- package/dist/src/loader.js +26194 -0
- package/dist/src/register.js +26068 -0
- package/dist/storage/config.d.ts +4 -0
- package/dist/storage/config.d.ts.map +1 -0
- package/dist/storage/db.d.ts +5 -0
- package/dist/storage/db.d.ts.map +1 -1
- package/dist/storage/schema.d.ts +1 -1
- package/dist/storage/schema.d.ts.map +1 -1
- package/dist/storage/user.d.ts +17 -0
- package/dist/storage/user.d.ts.map +1 -0
- package/package.json +6 -3
- package/scripts/postinstall.ts +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,qBAA4B,CAAC;AAGpD,eAAO,MAAM,MAAM,EAAE,MAAiB,CAAC;AACvC,eAAO,MAAM,IAAI,EAAE,MAAgD,CAAC;AACpE,eAAO,MAAM,MAAM,EAAE,MAA6D,CAAC;AAGnF,eAAO,MAAM,MAAM,EAAE,MAAkD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { generateAuthenticationOptions, generateRegistrationOptions, type VerifyAuthenticationResponseOpts, type VerifyRegistrationResponseOpts } from "@simplewebauthn/server";
|
|
2
|
+
import type * as User from "../storage/user.js";
|
|
3
|
+
export type Registration = {
|
|
4
|
+
credential_id: string;
|
|
5
|
+
public_key: Uint8Array;
|
|
6
|
+
counter: number;
|
|
7
|
+
};
|
|
8
|
+
export type Authentication = {
|
|
9
|
+
counter: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const challenge: (username: string) => Promise<Awaited<ReturnType<typeof generateRegistrationOptions>>>;
|
|
12
|
+
export declare const register: (username: string, response: VerifyRegistrationResponseOpts["response"], expectedChallenge: string) => Promise<Registration>;
|
|
13
|
+
export declare const discover: () => Promise<Awaited<ReturnType<typeof generateAuthenticationOptions>>>;
|
|
14
|
+
export declare const authenticate: (user: User.Record, response: VerifyAuthenticationResponseOpts["response"], expectedChallenge: string) => Promise<Authentication>;
|
|
15
|
+
//# sourceMappingURL=passkey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey.d.ts","sourceRoot":"","sources":["../../src/auth/passkey.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,2BAA2B,EAK3B,KAAK,gCAAgC,EACrC,KAAK,8BAA8B,EACpC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAEhD,MAAM,MAAM,YAAY,GAAG;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC,CAgBjE,CAAC;AAEF,eAAO,MAAM,QAAQ,GACnB,UAAU,MAAM,EAChB,UAAU,8BAA8B,CAAC,UAAU,CAAC,EACpD,mBAAmB,MAAM,KACxB,OAAO,CAAC,YAAY,CAmBtB,CAAC;AAGF,eAAO,MAAM,QAAQ,QAAa,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,6BAA6B,CAAC,CAAC,CASlG,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,MAAM,IAAI,CAAC,MAAM,EACjB,UAAU,gCAAgC,CAAC,UAAU,CAAC,EACtD,mBAAmB,MAAM,KACxB,OAAO,CAAC,cAAc,CAkBxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,MAAM,GAAI,UAAU,MAAM,KAAG,MAMzC,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,IAkB7D,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const hash: () => string | null;
|
|
2
|
+
export declare const verify: (code: string, stored: string) => boolean;
|
|
3
|
+
export declare const clear: () => void;
|
|
4
|
+
export declare const generate: () => {
|
|
5
|
+
code: string;
|
|
6
|
+
hash: string;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/auth/setup.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI,QAAO,MAAM,GAAG,IAWhC,CAAC;AAGF,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,OAYrD,CAAC;AAGF,eAAO,MAAM,KAAK,QAAO,IAiBxB,CAAC;AAGF,eAAO,MAAM,QAAQ,QAAO;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAMvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,QAAO,
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,QAAO,MAA4ttvB,CAAC"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
|
|
2
|
+
type Variables = {
|
|
3
|
+
username: string | null;
|
|
4
|
+
};
|
|
5
|
+
export declare const createDashboard: (basePath: string) => Hono<{
|
|
6
|
+
Variables: Variables;
|
|
7
|
+
}>;
|
|
8
|
+
export {};
|
|
3
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,KAAK,SAAS,GAAG;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,KAAG,IAAI,CAAC;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,CAiU/E,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3598,7 +3598,7 @@ var require_promise_limit = __commonJS((exports, module) => {
|
|
|
3598
3598
|
// package.json
|
|
3599
3599
|
var package_default = {
|
|
3600
3600
|
name: "surrge",
|
|
3601
|
-
version: "0.4.
|
|
3601
|
+
version: "0.4.10",
|
|
3602
3602
|
description: "One-line observability + analytics for Node.js/Bun",
|
|
3603
3603
|
type: "module",
|
|
3604
3604
|
exports: {
|
|
@@ -3700,22 +3700,28 @@ __export(exports_collector, {
|
|
|
3700
3700
|
// src/storage/db.ts
|
|
3701
3701
|
var exports_db = {};
|
|
3702
3702
|
__export(exports_db, {
|
|
3703
|
+
warnIfEphemeral: () => warnIfEphemeral,
|
|
3703
3704
|
reset: () => reset,
|
|
3704
3705
|
recentRequests: () => recentRequests,
|
|
3705
3706
|
recentPageViews: () => recentPageViews,
|
|
3706
3707
|
recentMetrics: () => recentMetrics,
|
|
3707
3708
|
recentLogs: () => recentLogs,
|
|
3708
3709
|
recentErrors: () => recentErrors,
|
|
3710
|
+
parseVolume: () => parseVolume,
|
|
3711
|
+
isWritable: () => isWritable,
|
|
3709
3712
|
insertRequest: () => insertRequest,
|
|
3710
3713
|
insertPageView: () => insertPageView,
|
|
3711
3714
|
insertMetric: () => insertMetric,
|
|
3712
3715
|
insertLog: () => insertLog,
|
|
3713
3716
|
insertError: () => insertError,
|
|
3714
3717
|
init: () => init,
|
|
3718
|
+
inDocker: () => inDocker,
|
|
3719
|
+
findVolume: () => findVolume,
|
|
3715
3720
|
db: () => db,
|
|
3716
3721
|
cleanup: () => cleanup,
|
|
3717
3722
|
analytics: () => analytics
|
|
3718
3723
|
});
|
|
3724
|
+
import { accessSync, constants, existsSync, readFileSync, statSync } from "node:fs";
|
|
3719
3725
|
|
|
3720
3726
|
// node_modules/@libsql/core/lib-esm/api.js
|
|
3721
3727
|
class LibsqlError extends Error {
|
|
@@ -8494,8 +8500,68 @@ CREATE INDEX IF NOT EXISTS idx_server_metrics_timestamp ON server_metrics(timest
|
|
|
8494
8500
|
var RETENTION_DAYS = 7;
|
|
8495
8501
|
|
|
8496
8502
|
// src/storage/db.ts
|
|
8503
|
+
var SYSTEM_PATHS = ["/proc", "/sys", "/dev", "/run", "/tmp", "/etc", "/bin", "/lib", "/usr", "/sbin", "/boot"];
|
|
8504
|
+
var inDocker = () => {
|
|
8505
|
+
return existsSync("/.dockerenv");
|
|
8506
|
+
};
|
|
8507
|
+
var isWritable = (path) => {
|
|
8508
|
+
try {
|
|
8509
|
+
accessSync(path, constants.W_OK);
|
|
8510
|
+
return true;
|
|
8511
|
+
} catch {
|
|
8512
|
+
return false;
|
|
8513
|
+
}
|
|
8514
|
+
};
|
|
8515
|
+
var parseVolume = (mountsContent, rootDev) => {
|
|
8516
|
+
for (const line of mountsContent.split(`
|
|
8517
|
+
`)) {
|
|
8518
|
+
const parts = line.split(" ");
|
|
8519
|
+
if (parts.length < 2)
|
|
8520
|
+
continue;
|
|
8521
|
+
const mountPoint = parts[1];
|
|
8522
|
+
if (mountPoint === "/")
|
|
8523
|
+
continue;
|
|
8524
|
+
if (SYSTEM_PATHS.some((sys) => mountPoint === sys || mountPoint.startsWith(`${sys}/`)))
|
|
8525
|
+
continue;
|
|
8526
|
+
if (!existsSync(mountPoint))
|
|
8527
|
+
continue;
|
|
8528
|
+
try {
|
|
8529
|
+
const mountDev = statSync(mountPoint).dev;
|
|
8530
|
+
if (mountDev !== rootDev && isWritable(mountPoint)) {
|
|
8531
|
+
return mountPoint;
|
|
8532
|
+
}
|
|
8533
|
+
} catch {
|
|
8534
|
+
continue;
|
|
8535
|
+
}
|
|
8536
|
+
}
|
|
8537
|
+
return null;
|
|
8538
|
+
};
|
|
8539
|
+
var findVolume = () => {
|
|
8540
|
+
if (!existsSync("/proc/mounts"))
|
|
8541
|
+
return null;
|
|
8542
|
+
try {
|
|
8543
|
+
const rootDev = statSync("/").dev;
|
|
8544
|
+
const mounts = readFileSync("/proc/mounts", "utf-8");
|
|
8545
|
+
return parseVolume(mounts, rootDev);
|
|
8546
|
+
} catch {
|
|
8547
|
+
return null;
|
|
8548
|
+
}
|
|
8549
|
+
};
|
|
8550
|
+
var resolvePath = () => {
|
|
8551
|
+
if (process.env.SURRGE_DB_PATH)
|
|
8552
|
+
return process.env.SURRGE_DB_PATH;
|
|
8553
|
+
const volume = findVolume();
|
|
8554
|
+
if (volume)
|
|
8555
|
+
return `${volume}/surrge.db`;
|
|
8556
|
+
return "surrge.db";
|
|
8557
|
+
};
|
|
8558
|
+
var warnIfEphemeral = () => {
|
|
8559
|
+
if (inDocker() && !findVolume() && !process.env.SURRGE_DB_PATH) {
|
|
8560
|
+
console.warn("[surrge] Running in Docker without persistent storage. Mount a volume at /data to persist data.");
|
|
8561
|
+
}
|
|
8562
|
+
};
|
|
8497
8563
|
var client = null;
|
|
8498
|
-
var init = (path =
|
|
8564
|
+
var init = (path = resolvePath()) => {
|
|
8499
8565
|
if (client)
|
|
8500
8566
|
return client;
|
|
8501
8567
|
const url = path === ":memory:" ? ":memory:" : `file:${path}`;
|
|
@@ -10866,6 +10932,7 @@ var handleDashboard = async (req, res) => {
|
|
|
10866
10932
|
|
|
10867
10933
|
// src/register.ts
|
|
10868
10934
|
init();
|
|
10935
|
+
warnIfEphemeral();
|
|
10869
10936
|
start();
|
|
10870
10937
|
start2();
|
|
10871
10938
|
start3();
|
package/dist/loader.js
CHANGED
|
@@ -3598,7 +3598,7 @@ var require_promise_limit = __commonJS((exports, module) => {
|
|
|
3598
3598
|
// package.json
|
|
3599
3599
|
var package_default = {
|
|
3600
3600
|
name: "surrge",
|
|
3601
|
-
version: "0.4.
|
|
3601
|
+
version: "0.4.10",
|
|
3602
3602
|
description: "One-line observability + analytics for Node.js/Bun",
|
|
3603
3603
|
type: "module",
|
|
3604
3604
|
exports: {
|
|
@@ -3700,22 +3700,28 @@ __export(exports_collector, {
|
|
|
3700
3700
|
// src/storage/db.ts
|
|
3701
3701
|
var exports_db = {};
|
|
3702
3702
|
__export(exports_db, {
|
|
3703
|
+
warnIfEphemeral: () => warnIfEphemeral,
|
|
3703
3704
|
reset: () => reset,
|
|
3704
3705
|
recentRequests: () => recentRequests,
|
|
3705
3706
|
recentPageViews: () => recentPageViews,
|
|
3706
3707
|
recentMetrics: () => recentMetrics,
|
|
3707
3708
|
recentLogs: () => recentLogs,
|
|
3708
3709
|
recentErrors: () => recentErrors,
|
|
3710
|
+
parseVolume: () => parseVolume,
|
|
3711
|
+
isWritable: () => isWritable,
|
|
3709
3712
|
insertRequest: () => insertRequest,
|
|
3710
3713
|
insertPageView: () => insertPageView,
|
|
3711
3714
|
insertMetric: () => insertMetric,
|
|
3712
3715
|
insertLog: () => insertLog,
|
|
3713
3716
|
insertError: () => insertError,
|
|
3714
3717
|
init: () => init,
|
|
3718
|
+
inDocker: () => inDocker,
|
|
3719
|
+
findVolume: () => findVolume,
|
|
3715
3720
|
db: () => db,
|
|
3716
3721
|
cleanup: () => cleanup,
|
|
3717
3722
|
analytics: () => analytics
|
|
3718
3723
|
});
|
|
3724
|
+
import { accessSync, constants, existsSync, readFileSync, statSync } from "node:fs";
|
|
3719
3725
|
|
|
3720
3726
|
// node_modules/@libsql/core/lib-esm/api.js
|
|
3721
3727
|
class LibsqlError extends Error {
|
|
@@ -8494,8 +8500,68 @@ CREATE INDEX IF NOT EXISTS idx_server_metrics_timestamp ON server_metrics(timest
|
|
|
8494
8500
|
var RETENTION_DAYS = 7;
|
|
8495
8501
|
|
|
8496
8502
|
// src/storage/db.ts
|
|
8503
|
+
var SYSTEM_PATHS = ["/proc", "/sys", "/dev", "/run", "/tmp", "/etc", "/bin", "/lib", "/usr", "/sbin", "/boot"];
|
|
8504
|
+
var inDocker = () => {
|
|
8505
|
+
return existsSync("/.dockerenv");
|
|
8506
|
+
};
|
|
8507
|
+
var isWritable = (path) => {
|
|
8508
|
+
try {
|
|
8509
|
+
accessSync(path, constants.W_OK);
|
|
8510
|
+
return true;
|
|
8511
|
+
} catch {
|
|
8512
|
+
return false;
|
|
8513
|
+
}
|
|
8514
|
+
};
|
|
8515
|
+
var parseVolume = (mountsContent, rootDev) => {
|
|
8516
|
+
for (const line of mountsContent.split(`
|
|
8517
|
+
`)) {
|
|
8518
|
+
const parts = line.split(" ");
|
|
8519
|
+
if (parts.length < 2)
|
|
8520
|
+
continue;
|
|
8521
|
+
const mountPoint = parts[1];
|
|
8522
|
+
if (mountPoint === "/")
|
|
8523
|
+
continue;
|
|
8524
|
+
if (SYSTEM_PATHS.some((sys) => mountPoint === sys || mountPoint.startsWith(`${sys}/`)))
|
|
8525
|
+
continue;
|
|
8526
|
+
if (!existsSync(mountPoint))
|
|
8527
|
+
continue;
|
|
8528
|
+
try {
|
|
8529
|
+
const mountDev = statSync(mountPoint).dev;
|
|
8530
|
+
if (mountDev !== rootDev && isWritable(mountPoint)) {
|
|
8531
|
+
return mountPoint;
|
|
8532
|
+
}
|
|
8533
|
+
} catch {
|
|
8534
|
+
continue;
|
|
8535
|
+
}
|
|
8536
|
+
}
|
|
8537
|
+
return null;
|
|
8538
|
+
};
|
|
8539
|
+
var findVolume = () => {
|
|
8540
|
+
if (!existsSync("/proc/mounts"))
|
|
8541
|
+
return null;
|
|
8542
|
+
try {
|
|
8543
|
+
const rootDev = statSync("/").dev;
|
|
8544
|
+
const mounts = readFileSync("/proc/mounts", "utf-8");
|
|
8545
|
+
return parseVolume(mounts, rootDev);
|
|
8546
|
+
} catch {
|
|
8547
|
+
return null;
|
|
8548
|
+
}
|
|
8549
|
+
};
|
|
8550
|
+
var resolvePath = () => {
|
|
8551
|
+
if (process.env.SURRGE_DB_PATH)
|
|
8552
|
+
return process.env.SURRGE_DB_PATH;
|
|
8553
|
+
const volume = findVolume();
|
|
8554
|
+
if (volume)
|
|
8555
|
+
return `${volume}/surrge.db`;
|
|
8556
|
+
return "surrge.db";
|
|
8557
|
+
};
|
|
8558
|
+
var warnIfEphemeral = () => {
|
|
8559
|
+
if (inDocker() && !findVolume() && !process.env.SURRGE_DB_PATH) {
|
|
8560
|
+
console.warn("[surrge] Running in Docker without persistent storage. Mount a volume at /data to persist data.");
|
|
8561
|
+
}
|
|
8562
|
+
};
|
|
8497
8563
|
var client = null;
|
|
8498
|
-
var init = (path =
|
|
8564
|
+
var init = (path = resolvePath()) => {
|
|
8499
8565
|
if (client)
|
|
8500
8566
|
return client;
|
|
8501
8567
|
const url = path === ":memory:" ? ":memory:" : `file:${path}`;
|
|
@@ -10866,6 +10932,7 @@ var handleDashboard = async (req, res) => {
|
|
|
10866
10932
|
|
|
10867
10933
|
// src/register.ts
|
|
10868
10934
|
init();
|
|
10935
|
+
warnIfEphemeral();
|
|
10869
10936
|
start();
|
|
10870
10937
|
start2();
|
|
10871
10938
|
start3();
|
package/dist/register.js
CHANGED
|
@@ -3598,7 +3598,7 @@ var require_promise_limit = __commonJS((exports, module) => {
|
|
|
3598
3598
|
// package.json
|
|
3599
3599
|
var package_default = {
|
|
3600
3600
|
name: "surrge",
|
|
3601
|
-
version: "0.4.
|
|
3601
|
+
version: "0.4.10",
|
|
3602
3602
|
description: "One-line observability + analytics for Node.js/Bun",
|
|
3603
3603
|
type: "module",
|
|
3604
3604
|
exports: {
|
|
@@ -3700,22 +3700,28 @@ __export(exports_collector, {
|
|
|
3700
3700
|
// src/storage/db.ts
|
|
3701
3701
|
var exports_db = {};
|
|
3702
3702
|
__export(exports_db, {
|
|
3703
|
+
warnIfEphemeral: () => warnIfEphemeral,
|
|
3703
3704
|
reset: () => reset,
|
|
3704
3705
|
recentRequests: () => recentRequests,
|
|
3705
3706
|
recentPageViews: () => recentPageViews,
|
|
3706
3707
|
recentMetrics: () => recentMetrics,
|
|
3707
3708
|
recentLogs: () => recentLogs,
|
|
3708
3709
|
recentErrors: () => recentErrors,
|
|
3710
|
+
parseVolume: () => parseVolume,
|
|
3711
|
+
isWritable: () => isWritable,
|
|
3709
3712
|
insertRequest: () => insertRequest,
|
|
3710
3713
|
insertPageView: () => insertPageView,
|
|
3711
3714
|
insertMetric: () => insertMetric,
|
|
3712
3715
|
insertLog: () => insertLog,
|
|
3713
3716
|
insertError: () => insertError,
|
|
3714
3717
|
init: () => init,
|
|
3718
|
+
inDocker: () => inDocker,
|
|
3719
|
+
findVolume: () => findVolume,
|
|
3715
3720
|
db: () => db,
|
|
3716
3721
|
cleanup: () => cleanup,
|
|
3717
3722
|
analytics: () => analytics
|
|
3718
3723
|
});
|
|
3724
|
+
import { accessSync, constants, existsSync, readFileSync, statSync } from "node:fs";
|
|
3719
3725
|
|
|
3720
3726
|
// node_modules/@libsql/core/lib-esm/api.js
|
|
3721
3727
|
class LibsqlError extends Error {
|
|
@@ -8494,8 +8500,68 @@ CREATE INDEX IF NOT EXISTS idx_server_metrics_timestamp ON server_metrics(timest
|
|
|
8494
8500
|
var RETENTION_DAYS = 7;
|
|
8495
8501
|
|
|
8496
8502
|
// src/storage/db.ts
|
|
8503
|
+
var SYSTEM_PATHS = ["/proc", "/sys", "/dev", "/run", "/tmp", "/etc", "/bin", "/lib", "/usr", "/sbin", "/boot"];
|
|
8504
|
+
var inDocker = () => {
|
|
8505
|
+
return existsSync("/.dockerenv");
|
|
8506
|
+
};
|
|
8507
|
+
var isWritable = (path) => {
|
|
8508
|
+
try {
|
|
8509
|
+
accessSync(path, constants.W_OK);
|
|
8510
|
+
return true;
|
|
8511
|
+
} catch {
|
|
8512
|
+
return false;
|
|
8513
|
+
}
|
|
8514
|
+
};
|
|
8515
|
+
var parseVolume = (mountsContent, rootDev) => {
|
|
8516
|
+
for (const line of mountsContent.split(`
|
|
8517
|
+
`)) {
|
|
8518
|
+
const parts = line.split(" ");
|
|
8519
|
+
if (parts.length < 2)
|
|
8520
|
+
continue;
|
|
8521
|
+
const mountPoint = parts[1];
|
|
8522
|
+
if (mountPoint === "/")
|
|
8523
|
+
continue;
|
|
8524
|
+
if (SYSTEM_PATHS.some((sys) => mountPoint === sys || mountPoint.startsWith(`${sys}/`)))
|
|
8525
|
+
continue;
|
|
8526
|
+
if (!existsSync(mountPoint))
|
|
8527
|
+
continue;
|
|
8528
|
+
try {
|
|
8529
|
+
const mountDev = statSync(mountPoint).dev;
|
|
8530
|
+
if (mountDev !== rootDev && isWritable(mountPoint)) {
|
|
8531
|
+
return mountPoint;
|
|
8532
|
+
}
|
|
8533
|
+
} catch {
|
|
8534
|
+
continue;
|
|
8535
|
+
}
|
|
8536
|
+
}
|
|
8537
|
+
return null;
|
|
8538
|
+
};
|
|
8539
|
+
var findVolume = () => {
|
|
8540
|
+
if (!existsSync("/proc/mounts"))
|
|
8541
|
+
return null;
|
|
8542
|
+
try {
|
|
8543
|
+
const rootDev = statSync("/").dev;
|
|
8544
|
+
const mounts = readFileSync("/proc/mounts", "utf-8");
|
|
8545
|
+
return parseVolume(mounts, rootDev);
|
|
8546
|
+
} catch {
|
|
8547
|
+
return null;
|
|
8548
|
+
}
|
|
8549
|
+
};
|
|
8550
|
+
var resolvePath = () => {
|
|
8551
|
+
if (process.env.SURRGE_DB_PATH)
|
|
8552
|
+
return process.env.SURRGE_DB_PATH;
|
|
8553
|
+
const volume = findVolume();
|
|
8554
|
+
if (volume)
|
|
8555
|
+
return `${volume}/surrge.db`;
|
|
8556
|
+
return "surrge.db";
|
|
8557
|
+
};
|
|
8558
|
+
var warnIfEphemeral = () => {
|
|
8559
|
+
if (inDocker() && !findVolume() && !process.env.SURRGE_DB_PATH) {
|
|
8560
|
+
console.warn("[surrge] Running in Docker without persistent storage. Mount a volume at /data to persist data.");
|
|
8561
|
+
}
|
|
8562
|
+
};
|
|
8497
8563
|
var client = null;
|
|
8498
|
-
var init = (path =
|
|
8564
|
+
var init = (path = resolvePath()) => {
|
|
8499
8565
|
if (client)
|
|
8500
8566
|
return client;
|
|
8501
8567
|
const url = path === ":memory:" ? ":memory:" : `file:${path}`;
|
|
@@ -10866,6 +10932,7 @@ var handleDashboard = async (req, res) => {
|
|
|
10866
10932
|
|
|
10867
10933
|
// src/register.ts
|
|
10868
10934
|
init();
|
|
10935
|
+
warnIfEphemeral();
|
|
10869
10936
|
start();
|
|
10870
10937
|
start2();
|
|
10871
10938
|
start3();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// scripts/postinstall.ts
|
|
2
|
+
import { scryptSync, randomBytes } from "node:crypto";
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
var projectRoot = process.env.INIT_CWD;
|
|
6
|
+
if (!projectRoot) {
|
|
7
|
+
process.exit(0);
|
|
8
|
+
}
|
|
9
|
+
var pkgPath = join(projectRoot, "package.json");
|
|
10
|
+
if (!existsSync(pkgPath)) {
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
var pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
14
|
+
if (pkg.surrge?.setup) {
|
|
15
|
+
console.log("[surrge] Setup code already exists in package.json");
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
var code = String(Math.floor(1e5 + Math.random() * 900000));
|
|
19
|
+
var salt = randomBytes(16).toString("hex");
|
|
20
|
+
var hash = scryptSync(code, salt, 64).toString("hex");
|
|
21
|
+
var stored = `${salt}:${hash}`;
|
|
22
|
+
pkg.surrge = { ...pkg.surrge, setup: stored };
|
|
23
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + `
|
|
24
|
+
`);
|
|
25
|
+
console.log(`
|
|
26
|
+
┌───────────────────────────────────────┐
|
|
27
|
+
│ SURRGE SETUP CODE │
|
|
28
|
+
├───────────────────────────────────────┤
|
|
29
|
+
│ │
|
|
30
|
+
│ ${code} │
|
|
31
|
+
│ │
|
|
32
|
+
│ Save this 6-digit code! │
|
|
33
|
+
│ You'll need it to create your │
|
|
34
|
+
│ admin account on first login. │
|
|
35
|
+
│ │
|
|
36
|
+
│ This code will not be shown again. │
|
|
37
|
+
└───────────────────────────────────────┘
|
|
38
|
+
`);
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
5
|
+
import { dirname, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
var args = process.argv.slice(2);
|
|
8
|
+
if (args.length === 0) {
|
|
9
|
+
console.log("Usage: surrge [options] <script> [args...]");
|
|
10
|
+
console.log(" surrge node [options] <script> [args...]");
|
|
11
|
+
console.log(" surrge bun [options] <script> [args...]");
|
|
12
|
+
console.log("");
|
|
13
|
+
console.log("Options are passed through to the runtime (e.g., --hot, --watch)");
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
var loaderPath = resolve(dirname(fileURLToPath(import.meta.url)), "loader.js");
|
|
17
|
+
var hasBun = () => {
|
|
18
|
+
const result = spawnSync("bun", ["--version"], { stdio: "ignore" });
|
|
19
|
+
return result.status === 0;
|
|
20
|
+
};
|
|
21
|
+
var runtime;
|
|
22
|
+
var remaining;
|
|
23
|
+
if (args[0] === "node" || args[0] === "bun") {
|
|
24
|
+
runtime = args[0];
|
|
25
|
+
remaining = args.slice(1);
|
|
26
|
+
} else {
|
|
27
|
+
runtime = hasBun() ? "bun" : "node";
|
|
28
|
+
remaining = args;
|
|
29
|
+
}
|
|
30
|
+
var runtimeFlags = [];
|
|
31
|
+
var scriptIndex = 0;
|
|
32
|
+
for (let i = 0;i < remaining.length; i++) {
|
|
33
|
+
if (remaining[i].startsWith("-")) {
|
|
34
|
+
runtimeFlags.push(remaining[i]);
|
|
35
|
+
} else {
|
|
36
|
+
scriptIndex = i;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
var scriptArgs = remaining.slice(scriptIndex);
|
|
41
|
+
if (scriptArgs.length === 0) {
|
|
42
|
+
console.log("Error: No script specified");
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
var flag = runtime === "bun" ? "--preload" : "--import";
|
|
46
|
+
var child = spawn(runtime, [flag, loaderPath, ...runtimeFlags, ...scriptArgs], {
|
|
47
|
+
stdio: "inherit",
|
|
48
|
+
cwd: process.cwd(),
|
|
49
|
+
env: process.env
|
|
50
|
+
});
|
|
51
|
+
child.on("close", (code) => {
|
|
52
|
+
process.exit(code ?? 0);
|
|
53
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
29
|
+
|
|
30
|
+
// src/hooks.ts
|
|
31
|
+
import fs from "node:fs";
|
|
32
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
33
|
+
var STDOUT_FD = 1;
|
|
34
|
+
var buffer = "";
|
|
35
|
+
var originalWriteSync = fs.writeSync;
|
|
36
|
+
var originalWrite = fs.write;
|
|
37
|
+
var logQueue = [];
|
|
38
|
+
globalThis.__surrge_log_queue = logQueue;
|
|
39
|
+
var normalizeLevel = (level) => {
|
|
40
|
+
if (typeof level === "number") {
|
|
41
|
+
if (level >= 50)
|
|
42
|
+
return "error";
|
|
43
|
+
if (level >= 40)
|
|
44
|
+
return "warn";
|
|
45
|
+
if (level >= 30)
|
|
46
|
+
return "info";
|
|
47
|
+
return "debug";
|
|
48
|
+
}
|
|
49
|
+
if (typeof level === "string") {
|
|
50
|
+
const lower = level.toLowerCase();
|
|
51
|
+
if (["error", "err"].includes(lower))
|
|
52
|
+
return "error";
|
|
53
|
+
if (["warn", "warning"].includes(lower))
|
|
54
|
+
return "warn";
|
|
55
|
+
return lower;
|
|
56
|
+
}
|
|
57
|
+
return "info";
|
|
58
|
+
};
|
|
59
|
+
var captureOutput = (chunk) => {
|
|
60
|
+
const text = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString() : new TextDecoder().decode(chunk);
|
|
61
|
+
buffer += text;
|
|
62
|
+
const lines = buffer.split(`
|
|
63
|
+
`);
|
|
64
|
+
buffer = lines.pop() ?? "";
|
|
65
|
+
for (const line of lines) {
|
|
66
|
+
if (!line.trim() || !line.startsWith("{"))
|
|
67
|
+
continue;
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(line);
|
|
70
|
+
const level = normalizeLevel(parsed.level ?? parsed.severity ?? "info");
|
|
71
|
+
const message = String(parsed.msg ?? parsed.message ?? line);
|
|
72
|
+
const { level: _, msg: __, message: ___, ...metadata } = parsed;
|
|
73
|
+
logQueue.push({
|
|
74
|
+
level,
|
|
75
|
+
message,
|
|
76
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined
|
|
77
|
+
});
|
|
78
|
+
} catch {}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var require2 = createRequire2(import.meta.url);
|
|
82
|
+
var cjsFs = require2("node:fs");
|
|
83
|
+
fs.writeSync = (fd, data, ...args) => {
|
|
84
|
+
if (fd === STDOUT_FD && (typeof data === "string" || Buffer.isBuffer(data))) {
|
|
85
|
+
captureOutput(data);
|
|
86
|
+
}
|
|
87
|
+
return originalWriteSync(fd, data, ...args);
|
|
88
|
+
};
|
|
89
|
+
fs.write = (fd, data, ...args) => {
|
|
90
|
+
if (fd === STDOUT_FD && (typeof data === "string" || Buffer.isBuffer(data))) {
|
|
91
|
+
captureOutput(data);
|
|
92
|
+
}
|
|
93
|
+
return originalWrite(fd, data, ...args);
|
|
94
|
+
};
|
|
95
|
+
var cjsOriginalWriteSync = cjsFs.writeSync;
|
|
96
|
+
var cjsOriginalWrite = cjsFs.write;
|
|
97
|
+
cjsFs.writeSync = (fd, data, ...args) => {
|
|
98
|
+
if (fd === STDOUT_FD && (typeof data === "string" || Buffer.isBuffer(data))) {
|
|
99
|
+
captureOutput(data);
|
|
100
|
+
}
|
|
101
|
+
return cjsOriginalWriteSync(fd, data, ...args);
|
|
102
|
+
};
|
|
103
|
+
cjsFs.write = (fd, data, ...args) => {
|
|
104
|
+
if (fd === STDOUT_FD && (typeof data === "string" || Buffer.isBuffer(data))) {
|
|
105
|
+
captureOutput(data);
|
|
106
|
+
}
|
|
107
|
+
return cjsOriginalWrite(fd, data, ...args);
|
|
108
|
+
};
|
|
109
|
+
var originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
110
|
+
process.stdout.write = (chunk, encodingOrCallback, callback) => {
|
|
111
|
+
if (typeof chunk === "string" || chunk instanceof Uint8Array) {
|
|
112
|
+
captureOutput(chunk);
|
|
113
|
+
}
|
|
114
|
+
if (typeof encodingOrCallback === "function") {
|
|
115
|
+
return originalStdoutWrite(chunk, encodingOrCallback);
|
|
116
|
+
}
|
|
117
|
+
return originalStdoutWrite(chunk, encodingOrCallback, callback);
|
|
118
|
+
};
|
|
119
|
+
var Bun = globalThis.Bun;
|
|
120
|
+
var BunStdout = Bun?.stdout;
|
|
121
|
+
if (Bun?.write) {
|
|
122
|
+
const originalBunWrite = Bun.write;
|
|
123
|
+
Bun.write = (dest, data, ...args) => {
|
|
124
|
+
const isStdout = dest === STDOUT_FD || dest === process.stdout || dest === BunStdout;
|
|
125
|
+
if (isStdout && (typeof data === "string" || data instanceof Uint8Array)) {
|
|
126
|
+
captureOutput(data);
|
|
127
|
+
}
|
|
128
|
+
return originalBunWrite(dest, data, ...args);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
var bunStdout = BunStdout;
|
|
132
|
+
if (bunStdout?.write) {
|
|
133
|
+
const originalBunStdoutWrite = bunStdout.write.bind(bunStdout);
|
|
134
|
+
bunStdout.write = (data) => {
|
|
135
|
+
captureOutput(data);
|
|
136
|
+
return originalBunStdoutWrite(data);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
var resolve = async (specifier, context, nextResolve) => {
|
|
140
|
+
return nextResolve(specifier, context);
|
|
141
|
+
};
|
|
142
|
+
var load = async (url, context, nextLoad) => {
|
|
143
|
+
return nextLoad(url, context);
|
|
144
|
+
};
|
|
145
|
+
export {
|
|
146
|
+
resolve,
|
|
147
|
+
load
|
|
148
|
+
};
|