tina4-nodejs 3.13.140 → 3.13.142
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/CLAUDE.md +2 -2
- package/package.json +1 -1
- package/packages/cli/dist/bin.js +438 -453
- package/packages/cli/src/bin.ts +4 -14
- package/packages/cli/src/commands/build.ts +2 -18
- package/packages/cli/src/commands/generate.ts +2 -22
- package/packages/cli/src/commands/lint.ts +3 -13
- package/packages/cli/src/commands/migrate.ts +2 -6
- package/packages/cli/src/commands/migrateRollback.ts +2 -6
- package/packages/cli/src/commands/migrateStatus.ts +2 -6
- package/packages/cli/src/commands/queue.ts +2 -30
- package/packages/cli/src/util.ts +90 -0
- package/packages/core/dist/index.js +215 -184
- package/packages/core/gallery/queue/src/lib/queueDb.ts +11 -0
- package/packages/core/gallery/queue/src/routes/api/gallery/queue/consume/post.ts +2 -5
- package/packages/core/gallery/queue/src/routes/api/gallery/queue/fail/post.ts +2 -5
- package/packages/core/src/devAdmin.ts +3 -12
- package/packages/core/src/dispatchPipeline.ts +2 -18
- package/packages/core/src/etag.ts +24 -0
- package/packages/core/src/feedback.ts +2 -11
- package/packages/core/src/session.ts +22 -66
- package/packages/core/src/sessionHandlers/respSessionHandler.ts +94 -0
- package/packages/core/src/sessionHandlers/valkeyHandler.ts +22 -73
- package/packages/core/src/static.ts +1 -13
- package/packages/core/src/upstreamResponse.ts +31 -0
- package/packages/core/src/websocket.ts +48 -7
- package/packages/orm/dist/index.js +215 -184
- package/packages/orm/src/graph/adapters/bolt.ts +8 -29
- package/packages/orm/src/graph/adapters/rowMapping.ts +57 -0
- package/packages/orm/src/graph/adapters/ultipa.ts +8 -30
- package/types/cli/src/util.d.ts +28 -0
- package/types/core/src/etag.d.ts +9 -0
- package/types/core/src/session.d.ts +2 -19
- package/types/core/src/sessionHandlers/respSessionHandler.d.ts +52 -0
- package/types/core/src/sessionHandlers/valkeyHandler.d.ts +2 -26
- package/types/core/src/upstreamResponse.d.ts +10 -0
- package/types/core/src/websocket.d.ts +21 -0
- package/types/orm/src/graph/adapters/rowMapping.d.ts +26 -0
|
@@ -13695,6 +13695,36 @@ var init_shapes = __esm({
|
|
|
13695
13695
|
}
|
|
13696
13696
|
});
|
|
13697
13697
|
|
|
13698
|
+
// ../orm/src/graph/adapters/rowMapping.ts
|
|
13699
|
+
function errorMessage(exc) {
|
|
13700
|
+
if (exc instanceof Error) return exc.message;
|
|
13701
|
+
return String(exc);
|
|
13702
|
+
}
|
|
13703
|
+
function nodeFromRow(row) {
|
|
13704
|
+
if (row === null || row === void 0) return null;
|
|
13705
|
+
return new GraphNode(
|
|
13706
|
+
String(row.id),
|
|
13707
|
+
row.labels ?? [],
|
|
13708
|
+
row.props ?? {}
|
|
13709
|
+
);
|
|
13710
|
+
}
|
|
13711
|
+
function edgeFromRow(row) {
|
|
13712
|
+
if (row === null || row === void 0) return null;
|
|
13713
|
+
return new GraphEdge(
|
|
13714
|
+
String(row.id),
|
|
13715
|
+
String(row.type),
|
|
13716
|
+
String(row.f),
|
|
13717
|
+
String(row.t),
|
|
13718
|
+
row.props ?? {}
|
|
13719
|
+
);
|
|
13720
|
+
}
|
|
13721
|
+
var init_rowMapping = __esm({
|
|
13722
|
+
"../orm/src/graph/adapters/rowMapping.ts"() {
|
|
13723
|
+
"use strict";
|
|
13724
|
+
init_shapes();
|
|
13725
|
+
}
|
|
13726
|
+
});
|
|
13727
|
+
|
|
13698
13728
|
// ../orm/src/graph/connectTimeout.ts
|
|
13699
13729
|
function resolveGraphConnectTimeout() {
|
|
13700
13730
|
const raw = (process.env[GRAPH_CONNECT_TIMEOUT_VARIABLE] ?? "").trim();
|
|
@@ -13734,15 +13764,12 @@ function propClause(properties) {
|
|
|
13734
13764
|
for (const key of keys) params[`p_${key}`] = props[key];
|
|
13735
13765
|
return { clause: `{${pairs}}`, params };
|
|
13736
13766
|
}
|
|
13737
|
-
function errorMessage(exc) {
|
|
13738
|
-
if (exc instanceof Error) return exc.message;
|
|
13739
|
-
return String(exc);
|
|
13740
|
-
}
|
|
13741
13767
|
var DRIVER_PACKAGE, driver, UltipaClient, UltipaConnectError, UNBOUNDED_CONNECT_SECONDS, UltipaGraphAdapter;
|
|
13742
13768
|
var init_ultipa = __esm({
|
|
13743
13769
|
async "../orm/src/graph/adapters/ultipa.ts"() {
|
|
13744
13770
|
"use strict";
|
|
13745
13771
|
init_shapes();
|
|
13772
|
+
init_rowMapping();
|
|
13746
13773
|
init_errors();
|
|
13747
13774
|
init_connectTimeout2();
|
|
13748
13775
|
DRIVER_PACKAGE = "tina4-ultipa";
|
|
@@ -13800,12 +13827,7 @@ var init_ultipa = __esm({
|
|
|
13800
13827
|
}
|
|
13801
13828
|
// -- portable node/edge/traverse core (GQL) ----------------------------
|
|
13802
13829
|
nodeFromRow(row) {
|
|
13803
|
-
|
|
13804
|
-
return new GraphNode(
|
|
13805
|
-
String(row.id),
|
|
13806
|
-
row.labels ?? [],
|
|
13807
|
-
row.props ?? {}
|
|
13808
|
-
);
|
|
13830
|
+
return nodeFromRow(row);
|
|
13809
13831
|
}
|
|
13810
13832
|
async addNode(label, properties = null) {
|
|
13811
13833
|
const { clause, params } = propClause(properties);
|
|
@@ -13819,15 +13841,7 @@ var init_ultipa = __esm({
|
|
|
13819
13841
|
params.to_id = toId;
|
|
13820
13842
|
const gql = `MATCH (a), (b) WHERE id(a) = $from_id AND id(b) = $to_id INSERT (a)-[e:\`${type2}\` ${clause}]->(b) RETURN id(e) AS id, type(e) AS type, id(a) AS f, id(b) AS t, properties(e) AS props`;
|
|
13821
13843
|
const rows = (await this.run(gql, params, false)).dicts();
|
|
13822
|
-
|
|
13823
|
-
const row = rows[0];
|
|
13824
|
-
return new GraphEdge(
|
|
13825
|
-
String(row.id),
|
|
13826
|
-
String(row.type),
|
|
13827
|
-
String(row.f),
|
|
13828
|
-
String(row.t),
|
|
13829
|
-
row.props ?? {}
|
|
13830
|
-
);
|
|
13844
|
+
return edgeFromRow(rows[0]);
|
|
13831
13845
|
}
|
|
13832
13846
|
async getNode(nodeId) {
|
|
13833
13847
|
const gql = `MATCH (n) WHERE id(n) = $id RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
@@ -13892,10 +13906,6 @@ var bolt_exports = {};
|
|
|
13892
13906
|
__export(bolt_exports, {
|
|
13893
13907
|
BoltGraphAdapter: () => BoltGraphAdapter
|
|
13894
13908
|
});
|
|
13895
|
-
function errorMessage2(exc) {
|
|
13896
|
-
if (exc instanceof Error) return exc.message;
|
|
13897
|
-
return String(exc);
|
|
13898
|
-
}
|
|
13899
13909
|
function boltId(id) {
|
|
13900
13910
|
const value = Number(id);
|
|
13901
13911
|
return Number.isNaN(value) ? -1 : value;
|
|
@@ -13905,6 +13915,7 @@ var init_bolt = __esm({
|
|
|
13905
13915
|
async "../orm/src/graph/adapters/bolt.ts"() {
|
|
13906
13916
|
"use strict";
|
|
13907
13917
|
init_shapes();
|
|
13918
|
+
init_rowMapping();
|
|
13908
13919
|
init_errors();
|
|
13909
13920
|
init_connectTimeout2();
|
|
13910
13921
|
DRIVER_PACKAGE2 = "neo4j-driver";
|
|
@@ -13940,7 +13951,7 @@ var init_bolt = __esm({
|
|
|
13940
13951
|
const result = await session.run(cypher, params ?? {});
|
|
13941
13952
|
return result.records.map((record) => record.toObject());
|
|
13942
13953
|
} catch (exc) {
|
|
13943
|
-
this.lastError =
|
|
13954
|
+
this.lastError = errorMessage(exc);
|
|
13944
13955
|
const code = exc?.code ?? "";
|
|
13945
13956
|
const message = this.lastError.toLowerCase();
|
|
13946
13957
|
if (code === "ServiceUnavailable" || code === neo4j.error?.SERVICE_UNAVAILABLE || message.includes("timed out") || message.includes("timeout")) {
|
|
@@ -13964,12 +13975,7 @@ var init_bolt = __esm({
|
|
|
13964
13975
|
}
|
|
13965
13976
|
// -- portable node/edge/traverse core (Cypher) -------------------------
|
|
13966
13977
|
nodeFromRow(row) {
|
|
13967
|
-
|
|
13968
|
-
return new GraphNode(
|
|
13969
|
-
String(row.id),
|
|
13970
|
-
row.labels ?? [],
|
|
13971
|
-
row.props ?? {}
|
|
13972
|
-
);
|
|
13978
|
+
return nodeFromRow(row);
|
|
13973
13979
|
}
|
|
13974
13980
|
async addNode(label, properties = null) {
|
|
13975
13981
|
const cypher = `CREATE (n:\`${label}\` $props) RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
@@ -13983,15 +13989,7 @@ var init_bolt = __esm({
|
|
|
13983
13989
|
to_id: boltId(toId),
|
|
13984
13990
|
props: properties ?? {}
|
|
13985
13991
|
});
|
|
13986
|
-
|
|
13987
|
-
const row = rows[0];
|
|
13988
|
-
return new GraphEdge(
|
|
13989
|
-
String(row.id),
|
|
13990
|
-
String(row.type),
|
|
13991
|
-
String(row.f),
|
|
13992
|
-
String(row.t),
|
|
13993
|
-
row.props ?? {}
|
|
13994
|
-
);
|
|
13992
|
+
return edgeFromRow(rows[0]);
|
|
13995
13993
|
}
|
|
13996
13994
|
async getNode(nodeId) {
|
|
13997
13995
|
const cypher = `MATCH (n) WHERE id(n) = $id RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
@@ -14057,7 +14055,7 @@ function cleanProps(doc) {
|
|
|
14057
14055
|
}
|
|
14058
14056
|
return props;
|
|
14059
14057
|
}
|
|
14060
|
-
function
|
|
14058
|
+
function errorMessage2(exc) {
|
|
14061
14059
|
if (exc instanceof Error) return exc.message;
|
|
14062
14060
|
return String(exc);
|
|
14063
14061
|
}
|
|
@@ -14096,14 +14094,14 @@ var init_arango = __esm({
|
|
|
14096
14094
|
this.db = new ArangoDatabase(config);
|
|
14097
14095
|
}
|
|
14098
14096
|
connectOrError(exc) {
|
|
14099
|
-
const text =
|
|
14097
|
+
const text = errorMessage2(exc).toLowerCase();
|
|
14100
14098
|
if (text.includes("timed out") || text.includes("timeout") || text.includes("connection") || text.includes("econnrefused") || text.includes("etimedout") || text.includes("max retries")) {
|
|
14101
14099
|
return new GraphConnectTimeout(
|
|
14102
14100
|
`Graph connect to ${this.url.host}:${this.url.port} timed out (${GRAPH_CONNECT_TIMEOUT_VARIABLE}). Raise ${GRAPH_CONNECT_TIMEOUT_VARIABLE} if the server is simply slow, or set it to 0 to wait indefinitely.`,
|
|
14103
14101
|
exc
|
|
14104
14102
|
);
|
|
14105
14103
|
}
|
|
14106
|
-
return new GraphError(
|
|
14104
|
+
return new GraphError(errorMessage2(exc), exc);
|
|
14107
14105
|
}
|
|
14108
14106
|
async ensureCollections() {
|
|
14109
14107
|
if (this.ensured) return;
|
|
@@ -14114,7 +14112,7 @@ var init_arango = __esm({
|
|
|
14114
14112
|
if (!await edges.exists()) await this.db.createEdgeCollection(EDGE_COLLECTION);
|
|
14115
14113
|
this.ensured = true;
|
|
14116
14114
|
} catch (exc) {
|
|
14117
|
-
this.lastError =
|
|
14115
|
+
this.lastError = errorMessage2(exc);
|
|
14118
14116
|
throw this.connectOrError(exc);
|
|
14119
14117
|
}
|
|
14120
14118
|
}
|
|
@@ -14124,7 +14122,7 @@ var init_arango = __esm({
|
|
|
14124
14122
|
const cursor = await this.db.query({ query, bindVars: bind2 ?? {} });
|
|
14125
14123
|
return await cursor.all();
|
|
14126
14124
|
} catch (exc) {
|
|
14127
|
-
this.lastError =
|
|
14125
|
+
this.lastError = errorMessage2(exc);
|
|
14128
14126
|
throw this.connectOrError(exc);
|
|
14129
14127
|
}
|
|
14130
14128
|
}
|
|
@@ -22387,6 +22385,21 @@ var init_portTakeover = __esm({
|
|
|
22387
22385
|
}
|
|
22388
22386
|
});
|
|
22389
22387
|
|
|
22388
|
+
// src/etag.ts
|
|
22389
|
+
function etagMatches(ifNoneMatch, etag) {
|
|
22390
|
+
const strip = (tag) => tag.trim().replace(/^W\//, "");
|
|
22391
|
+
const target = strip(etag);
|
|
22392
|
+
return ifNoneMatch.split(",").some((candidate) => {
|
|
22393
|
+
const trimmed = candidate.trim();
|
|
22394
|
+
return trimmed === "*" || strip(trimmed) === target;
|
|
22395
|
+
});
|
|
22396
|
+
}
|
|
22397
|
+
var init_etag = __esm({
|
|
22398
|
+
"src/etag.ts"() {
|
|
22399
|
+
"use strict";
|
|
22400
|
+
}
|
|
22401
|
+
});
|
|
22402
|
+
|
|
22390
22403
|
// src/sessionHandlers/syncBridge.ts
|
|
22391
22404
|
import { Worker } from "node:worker_threads";
|
|
22392
22405
|
function getBridge(key, workerSource, workerData) {
|
|
@@ -22668,42 +22681,35 @@ var init_respClient = __esm({
|
|
|
22668
22681
|
}
|
|
22669
22682
|
});
|
|
22670
22683
|
|
|
22671
|
-
// src/sessionHandlers/
|
|
22672
|
-
var
|
|
22673
|
-
var
|
|
22674
|
-
"src/sessionHandlers/
|
|
22684
|
+
// src/sessionHandlers/respSessionHandler.ts
|
|
22685
|
+
var RespSessionHandler;
|
|
22686
|
+
var init_respSessionHandler = __esm({
|
|
22687
|
+
"src/sessionHandlers/respSessionHandler.ts"() {
|
|
22675
22688
|
"use strict";
|
|
22676
22689
|
init_respClient();
|
|
22677
|
-
|
|
22678
|
-
|
|
22679
|
-
|
|
22680
|
-
|
|
22681
|
-
prefix;
|
|
22682
|
-
db;
|
|
22683
|
-
constructor(config) {
|
|
22684
|
-
this.host = config?.host ?? process.env.TINA4_SESSION_VALKEY_HOST ?? "127.0.0.1";
|
|
22685
|
-
this.port = config?.port ?? (process.env.TINA4_SESSION_VALKEY_PORT ? parseInt(process.env.TINA4_SESSION_VALKEY_PORT, 10) : 6379);
|
|
22686
|
-
this.password = config?.password ?? process.env.TINA4_SESSION_VALKEY_PASSWORD ?? "";
|
|
22687
|
-
this.prefix = config?.prefix ?? process.env.TINA4_SESSION_VALKEY_PREFIX ?? "tina4:session:";
|
|
22688
|
-
this.db = config?.db ?? (process.env.TINA4_SESSION_VALKEY_DB ? parseInt(process.env.TINA4_SESSION_VALKEY_DB, 10) : 0);
|
|
22690
|
+
RespSessionHandler = class {
|
|
22691
|
+
constructor(conn, label) {
|
|
22692
|
+
this.conn = conn;
|
|
22693
|
+
this.label = label;
|
|
22689
22694
|
}
|
|
22695
|
+
conn;
|
|
22696
|
+
label;
|
|
22690
22697
|
/**
|
|
22691
|
-
* Execute a RESP command synchronously against the live
|
|
22698
|
+
* Execute a RESP command synchronously against the live server.
|
|
22692
22699
|
*
|
|
22693
|
-
* Delegates to the shared {@link respCommandSync} transport: a genuine key
|
|
22694
|
-
* yields `""`, and a transport/connection FAILURE
|
|
22695
|
-
*
|
|
22696
|
-
* (silent) from "backend failed" (log-loud + degrade). Backend-failure parity.
|
|
22700
|
+
* Delegates to the shared {@link respCommandSync} transport: a genuine key
|
|
22701
|
+
* miss yields `""`, and a transport/connection FAILURE THROWS so the caller
|
|
22702
|
+
* can distinguish "not found" from "backend failed". Backend-failure parity.
|
|
22697
22703
|
*/
|
|
22698
22704
|
execSync(args) {
|
|
22699
22705
|
return respCommandSync(
|
|
22700
|
-
{ host: this.host, port: this.port, password: this.password, db: this.db },
|
|
22706
|
+
{ host: this.conn.host, port: this.conn.port, password: this.conn.password, db: this.conn.db },
|
|
22701
22707
|
args,
|
|
22702
|
-
|
|
22708
|
+
this.label
|
|
22703
22709
|
);
|
|
22704
22710
|
}
|
|
22705
22711
|
key(sessionId) {
|
|
22706
|
-
return `${this.prefix}${sessionId}`;
|
|
22712
|
+
return `${this.conn.prefix}${sessionId}`;
|
|
22707
22713
|
}
|
|
22708
22714
|
read(sessionId) {
|
|
22709
22715
|
const raw = this.execSync(["GET", this.key(sessionId)]);
|
|
@@ -22714,7 +22720,7 @@ var init_valkeyHandler = __esm({
|
|
|
22714
22720
|
return null;
|
|
22715
22721
|
}
|
|
22716
22722
|
}
|
|
22717
|
-
write(sessionId, data, ttl) {
|
|
22723
|
+
write(sessionId, data, ttl = 0) {
|
|
22718
22724
|
const json = JSON.stringify(data);
|
|
22719
22725
|
if (ttl > 0) {
|
|
22720
22726
|
this.execSync(["SETEX", this.key(sessionId), String(ttl), json]);
|
|
@@ -22729,6 +22735,29 @@ var init_valkeyHandler = __esm({
|
|
|
22729
22735
|
}
|
|
22730
22736
|
});
|
|
22731
22737
|
|
|
22738
|
+
// src/sessionHandlers/valkeyHandler.ts
|
|
22739
|
+
var ValkeySessionHandler;
|
|
22740
|
+
var init_valkeyHandler = __esm({
|
|
22741
|
+
"src/sessionHandlers/valkeyHandler.ts"() {
|
|
22742
|
+
"use strict";
|
|
22743
|
+
init_respSessionHandler();
|
|
22744
|
+
ValkeySessionHandler = class extends RespSessionHandler {
|
|
22745
|
+
constructor(config) {
|
|
22746
|
+
super(
|
|
22747
|
+
{
|
|
22748
|
+
host: config?.host ?? process.env.TINA4_SESSION_VALKEY_HOST ?? "127.0.0.1",
|
|
22749
|
+
port: config?.port ?? (process.env.TINA4_SESSION_VALKEY_PORT ? parseInt(process.env.TINA4_SESSION_VALKEY_PORT, 10) : 6379),
|
|
22750
|
+
password: config?.password ?? process.env.TINA4_SESSION_VALKEY_PASSWORD ?? "",
|
|
22751
|
+
prefix: config?.prefix ?? process.env.TINA4_SESSION_VALKEY_PREFIX ?? "tina4:session:",
|
|
22752
|
+
db: config?.db ?? (process.env.TINA4_SESSION_VALKEY_DB ? parseInt(process.env.TINA4_SESSION_VALKEY_DB, 10) : 0)
|
|
22753
|
+
},
|
|
22754
|
+
"Valkey"
|
|
22755
|
+
);
|
|
22756
|
+
}
|
|
22757
|
+
};
|
|
22758
|
+
}
|
|
22759
|
+
});
|
|
22760
|
+
|
|
22732
22761
|
// src/sessionHandlers/memcachedHandler.ts
|
|
22733
22762
|
import { createHash as createHash4 } from "node:crypto";
|
|
22734
22763
|
var MAX_KEY_BYTES, MAX_RELATIVE_EXPTIME, MemcachedSessionHandler;
|
|
@@ -23794,7 +23823,7 @@ var init_session = __esm({
|
|
|
23794
23823
|
"use strict";
|
|
23795
23824
|
init_logger();
|
|
23796
23825
|
init_dotenv();
|
|
23797
|
-
|
|
23826
|
+
init_respSessionHandler();
|
|
23798
23827
|
init_valkeyHandler();
|
|
23799
23828
|
init_memcachedHandler();
|
|
23800
23829
|
init_mongoHandler();
|
|
@@ -23920,57 +23949,19 @@ var init_session = __esm({
|
|
|
23920
23949
|
}
|
|
23921
23950
|
}
|
|
23922
23951
|
};
|
|
23923
|
-
RedisSessionHandler = class {
|
|
23924
|
-
host;
|
|
23925
|
-
port;
|
|
23926
|
-
password;
|
|
23927
|
-
prefix;
|
|
23928
|
-
db;
|
|
23952
|
+
RedisSessionHandler = class extends RespSessionHandler {
|
|
23929
23953
|
constructor(config) {
|
|
23930
|
-
|
|
23931
|
-
|
|
23932
|
-
|
|
23933
|
-
|
|
23934
|
-
|
|
23935
|
-
|
|
23936
|
-
|
|
23937
|
-
|
|
23938
|
-
*
|
|
23939
|
-
* Delegates to the shared {@link respCommandSync} transport: a genuine key miss
|
|
23940
|
-
* yields `""`, and a transport/connection FAILURE (server unreachable, rejected
|
|
23941
|
-
* AUTH, timeout) THROWS so the Session boundary can distinguish "not found"
|
|
23942
|
-
* (silent) from "backend failed" (log-loud + degrade). Backend-failure parity.
|
|
23943
|
-
*/
|
|
23944
|
-
execSync(args) {
|
|
23945
|
-
return respCommandSync(
|
|
23946
|
-
{ host: this.host, port: this.port, password: this.password, db: this.db },
|
|
23947
|
-
args,
|
|
23954
|
+
super(
|
|
23955
|
+
{
|
|
23956
|
+
host: config?.redisHost ?? process.env.TINA4_SESSION_REDIS_HOST ?? "127.0.0.1",
|
|
23957
|
+
port: config?.redisPort ?? (process.env.TINA4_SESSION_REDIS_PORT ? parseInt(process.env.TINA4_SESSION_REDIS_PORT, 10) : 6379),
|
|
23958
|
+
password: config?.redisPassword ?? process.env.TINA4_SESSION_REDIS_PASSWORD ?? "",
|
|
23959
|
+
prefix: config?.redisPrefix ?? process.env.TINA4_SESSION_REDIS_PREFIX ?? "tina4:session:",
|
|
23960
|
+
db: config?.redisDb ?? (process.env.TINA4_SESSION_REDIS_DB ? parseInt(process.env.TINA4_SESSION_REDIS_DB, 10) : 0)
|
|
23961
|
+
},
|
|
23948
23962
|
"Redis"
|
|
23949
23963
|
);
|
|
23950
23964
|
}
|
|
23951
|
-
key(sessionId) {
|
|
23952
|
-
return `${this.prefix}${sessionId}`;
|
|
23953
|
-
}
|
|
23954
|
-
read(sessionId) {
|
|
23955
|
-
const raw = this.execSync(["GET", this.key(sessionId)]);
|
|
23956
|
-
if (!raw) return null;
|
|
23957
|
-
try {
|
|
23958
|
-
return JSON.parse(raw);
|
|
23959
|
-
} catch {
|
|
23960
|
-
return null;
|
|
23961
|
-
}
|
|
23962
|
-
}
|
|
23963
|
-
write(sessionId, data, ttl = 0) {
|
|
23964
|
-
const json = JSON.stringify(data);
|
|
23965
|
-
if (ttl > 0) {
|
|
23966
|
-
this.execSync(["SETEX", this.key(sessionId), String(ttl), json]);
|
|
23967
|
-
} else {
|
|
23968
|
-
this.execSync(["SET", this.key(sessionId), json]);
|
|
23969
|
-
}
|
|
23970
|
-
}
|
|
23971
|
-
destroy(sessionId) {
|
|
23972
|
-
this.execSync(["DEL", this.key(sessionId)]);
|
|
23973
|
-
}
|
|
23974
23965
|
};
|
|
23975
23966
|
FLASH_PREFIX = "_flash_";
|
|
23976
23967
|
Session = class {
|
|
@@ -24380,14 +24371,6 @@ function headStripIntercept(rawReq, rawRes) {
|
|
|
24380
24371
|
function isCompressibleContentType(contentType) {
|
|
24381
24372
|
return COMPRESSIBLE_PREFIXES.some((prefix) => contentType.includes(prefix));
|
|
24382
24373
|
}
|
|
24383
|
-
function etagMatchesInm(ifNoneMatch, etag) {
|
|
24384
|
-
const strip = (tag) => tag.trim().replace(/^W\//, "");
|
|
24385
|
-
const target = strip(etag);
|
|
24386
|
-
return ifNoneMatch.split(",").some((candidate) => {
|
|
24387
|
-
const trimmed = candidate.trim();
|
|
24388
|
-
return trimmed === "*" || strip(trimmed) === target;
|
|
24389
|
-
});
|
|
24390
|
-
}
|
|
24391
24374
|
function maybeCompressResponse(body, rawReq, rawRes) {
|
|
24392
24375
|
const acceptEncoding = String(rawReq.headers["accept-encoding"] ?? "");
|
|
24393
24376
|
const contentTypeHeader = rawRes.getHeader("content-type");
|
|
@@ -24403,7 +24386,7 @@ function maybeCompressResponse(body, rawReq, rawRes) {
|
|
|
24403
24386
|
}
|
|
24404
24387
|
function responseIsNotModified(rawReq, rawRes, etag) {
|
|
24405
24388
|
const ifNoneMatch = String(rawReq.headers["if-none-match"] ?? "");
|
|
24406
|
-
if (ifNoneMatch) return
|
|
24389
|
+
if (ifNoneMatch) return etagMatches(ifNoneMatch, etag);
|
|
24407
24390
|
const lastModifiedHeader = rawRes.getHeader("last-modified");
|
|
24408
24391
|
if (typeof lastModifiedHeader !== "string") return false;
|
|
24409
24392
|
const ifModifiedSince = String(rawReq.headers["if-modified-since"] ?? "");
|
|
@@ -24531,6 +24514,7 @@ var init_dispatchPipeline = __esm({
|
|
|
24531
24514
|
"src/dispatchPipeline.ts"() {
|
|
24532
24515
|
"use strict";
|
|
24533
24516
|
init_logger();
|
|
24517
|
+
init_etag();
|
|
24534
24518
|
COMPRESSIBLE_PREFIXES = [
|
|
24535
24519
|
"text/",
|
|
24536
24520
|
"application/json",
|
|
@@ -24626,18 +24610,11 @@ function isNotModified(req2, etag, stat) {
|
|
|
24626
24610
|
}
|
|
24627
24611
|
return false;
|
|
24628
24612
|
}
|
|
24629
|
-
function etagMatches(ifNoneMatch, etag) {
|
|
24630
|
-
const strip = (tag) => tag.trim().replace(/^W\//, "");
|
|
24631
|
-
const target = strip(etag);
|
|
24632
|
-
return ifNoneMatch.split(",").some((candidate) => {
|
|
24633
|
-
const trimmed = candidate.trim();
|
|
24634
|
-
return trimmed === "*" || strip(trimmed) === target;
|
|
24635
|
-
});
|
|
24636
|
-
}
|
|
24637
24613
|
var COMPRESSIBLE_PREFIXES2, MIME_TYPES;
|
|
24638
24614
|
var init_static = __esm({
|
|
24639
24615
|
"src/static.ts"() {
|
|
24640
24616
|
"use strict";
|
|
24617
|
+
init_etag();
|
|
24641
24618
|
COMPRESSIBLE_PREFIXES2 = [
|
|
24642
24619
|
"text/",
|
|
24643
24620
|
"application/json",
|
|
@@ -25214,6 +25191,25 @@ Generated by DevMailbox.seed() for development purposes.`,
|
|
|
25214
25191
|
}
|
|
25215
25192
|
});
|
|
25216
25193
|
|
|
25194
|
+
// src/upstreamResponse.ts
|
|
25195
|
+
async function relayUpstreamResponse(res, upstream) {
|
|
25196
|
+
const raw = await upstream.text();
|
|
25197
|
+
const status2 = upstream.status || 200;
|
|
25198
|
+
try {
|
|
25199
|
+
res.json(JSON.parse(raw), status2);
|
|
25200
|
+
} catch {
|
|
25201
|
+
res.raw.writeHead(status2, {
|
|
25202
|
+
"Content-Type": upstream.headers.get("content-type") ?? "text/plain; charset=utf-8"
|
|
25203
|
+
});
|
|
25204
|
+
res.raw.end(raw);
|
|
25205
|
+
}
|
|
25206
|
+
}
|
|
25207
|
+
var init_upstreamResponse = __esm({
|
|
25208
|
+
"src/upstreamResponse.ts"() {
|
|
25209
|
+
"use strict";
|
|
25210
|
+
}
|
|
25211
|
+
});
|
|
25212
|
+
|
|
25217
25213
|
// src/metrics.ts
|
|
25218
25214
|
import * as fs3 from "node:fs";
|
|
25219
25215
|
import * as path2 from "node:path";
|
|
@@ -25429,6 +25425,7 @@ var init_feedback = __esm({
|
|
|
25429
25425
|
"use strict";
|
|
25430
25426
|
init_auth();
|
|
25431
25427
|
init_devAdmin();
|
|
25428
|
+
init_upstreamResponse();
|
|
25432
25429
|
RATE_LIMIT_WINDOW_SEC = 3600;
|
|
25433
25430
|
RATE_LIMIT_MAX = 5;
|
|
25434
25431
|
_rateLimitHits = /* @__PURE__ */ new Map();
|
|
@@ -25475,16 +25472,7 @@ var init_feedback = __esm({
|
|
|
25475
25472
|
return;
|
|
25476
25473
|
}
|
|
25477
25474
|
clearTimeout(timer);
|
|
25478
|
-
|
|
25479
|
-
const status2 = upstream.status || 200;
|
|
25480
|
-
try {
|
|
25481
|
-
res.json(JSON.parse(raw), status2);
|
|
25482
|
-
} catch {
|
|
25483
|
-
res.raw.writeHead(status2, {
|
|
25484
|
-
"Content-Type": upstream.headers.get("content-type") ?? "text/plain; charset=utf-8"
|
|
25485
|
-
});
|
|
25486
|
-
res.raw.end(raw);
|
|
25487
|
-
}
|
|
25475
|
+
await relayUpstreamResponse(res, upstream);
|
|
25488
25476
|
};
|
|
25489
25477
|
__feedbackDirname = dirname7(fileURLToPath2(import.meta.url));
|
|
25490
25478
|
WIDGET_BUNDLE_PATH = resolve9(__feedbackDirname, "__feedback", "widget.js");
|
|
@@ -25534,6 +25522,38 @@ var init_version = __esm({
|
|
|
25534
25522
|
}
|
|
25535
25523
|
});
|
|
25536
25524
|
|
|
25525
|
+
// ../cli/src/util.ts
|
|
25526
|
+
function parseFlags(args, booleanFlags) {
|
|
25527
|
+
const flags = {};
|
|
25528
|
+
const positional = [];
|
|
25529
|
+
let i = 0;
|
|
25530
|
+
while (i < args.length) {
|
|
25531
|
+
const arg = args[i];
|
|
25532
|
+
if (arg.startsWith("--")) {
|
|
25533
|
+
const key = arg.slice(2);
|
|
25534
|
+
if (booleanFlags?.has(key)) {
|
|
25535
|
+
flags[key] = true;
|
|
25536
|
+
i += 1;
|
|
25537
|
+
} else if (i + 1 < args.length && !args[i + 1].startsWith("--")) {
|
|
25538
|
+
flags[key] = args[i + 1];
|
|
25539
|
+
i += 2;
|
|
25540
|
+
} else {
|
|
25541
|
+
flags[key] = true;
|
|
25542
|
+
i += 1;
|
|
25543
|
+
}
|
|
25544
|
+
} else {
|
|
25545
|
+
positional.push(arg);
|
|
25546
|
+
i += 1;
|
|
25547
|
+
}
|
|
25548
|
+
}
|
|
25549
|
+
return { flags, positional };
|
|
25550
|
+
}
|
|
25551
|
+
var init_util = __esm({
|
|
25552
|
+
"../cli/src/util.ts"() {
|
|
25553
|
+
"use strict";
|
|
25554
|
+
}
|
|
25555
|
+
});
|
|
25556
|
+
|
|
25537
25557
|
// ../cli/src/commands/generate.ts
|
|
25538
25558
|
var generate_exports = {};
|
|
25539
25559
|
__export(generate_exports, {
|
|
@@ -25798,28 +25818,7 @@ function parseCliArgs(args) {
|
|
|
25798
25818
|
"json",
|
|
25799
25819
|
"dry-run"
|
|
25800
25820
|
]);
|
|
25801
|
-
|
|
25802
|
-
const positional = [];
|
|
25803
|
-
let i = 0;
|
|
25804
|
-
while (i < args.length) {
|
|
25805
|
-
if (args[i].startsWith("--")) {
|
|
25806
|
-
const key = args[i].slice(2);
|
|
25807
|
-
if (booleanFlags.has(key)) {
|
|
25808
|
-
flags[key] = true;
|
|
25809
|
-
i += 1;
|
|
25810
|
-
} else if (i + 1 < args.length && !args[i + 1].startsWith("--")) {
|
|
25811
|
-
flags[key] = args[i + 1];
|
|
25812
|
-
i += 2;
|
|
25813
|
-
} else {
|
|
25814
|
-
flags[key] = true;
|
|
25815
|
-
i += 1;
|
|
25816
|
-
}
|
|
25817
|
-
} else {
|
|
25818
|
-
positional.push(args[i]);
|
|
25819
|
-
i += 1;
|
|
25820
|
-
}
|
|
25821
|
-
}
|
|
25822
|
-
return { flags, positional };
|
|
25821
|
+
return parseFlags(args, booleanFlags);
|
|
25823
25822
|
}
|
|
25824
25823
|
function parseEvery(every) {
|
|
25825
25824
|
if (!every || every === true) return 60;
|
|
@@ -27380,6 +27379,7 @@ var FIELD_TYPE_MAP, SQL_RESERVED_TABLE_NAMES, RESOLUTION_ENVELOPE_VERSION, __res
|
|
|
27380
27379
|
var init_generate = __esm({
|
|
27381
27380
|
"../cli/src/commands/generate.ts"() {
|
|
27382
27381
|
"use strict";
|
|
27382
|
+
init_util();
|
|
27383
27383
|
FIELD_TYPE_MAP = {
|
|
27384
27384
|
string: { orm: '"string"', sql: "VARCHAR(255)", defaultVal: "''" },
|
|
27385
27385
|
str: { orm: '"string"', sql: "VARCHAR(255)", defaultVal: "''" },
|
|
@@ -30998,6 +30998,7 @@ __export(websocket_exports, {
|
|
|
30998
30998
|
CLOSE_NORMAL: () => CLOSE_NORMAL,
|
|
30999
30999
|
CLOSE_POLICY_VIOLATION: () => CLOSE_POLICY_VIOLATION,
|
|
31000
31000
|
CLOSE_PROTOCOL_ERROR: () => CLOSE_PROTOCOL_ERROR,
|
|
31001
|
+
MessageAssembler: () => MessageAssembler,
|
|
31001
31002
|
OP_BINARY: () => OP_BINARY,
|
|
31002
31003
|
OP_CLOSE: () => OP_CLOSE,
|
|
31003
31004
|
OP_CONTINUATION: () => OP_CONTINUATION,
|
|
@@ -31255,21 +31256,24 @@ function serveWebSocketRoute(req2, socket, head) {
|
|
|
31255
31256
|
state.closed = true;
|
|
31256
31257
|
void Promise.resolve().then(() => conn._onClose ? conn._onClose() : handler(conn, "close", "")).catch((e) => Log.error(`WebSocket close handler error: ${e.message}`)).finally(() => wsRouteManager.remove(conn.id));
|
|
31257
31258
|
};
|
|
31259
|
+
const assembler = new MessageAssembler();
|
|
31258
31260
|
socket.on("data", (chunk) => {
|
|
31259
31261
|
buffer = Buffer.concat([buffer, chunk]);
|
|
31260
31262
|
while (buffer.length > 0) {
|
|
31261
31263
|
const frame = parseFrame(buffer);
|
|
31262
31264
|
if (!frame) break;
|
|
31263
31265
|
buffer = buffer.subarray(frame.bytesConsumed);
|
|
31264
|
-
|
|
31266
|
+
const whole = assembler.push(frame);
|
|
31267
|
+
if (!whole) continue;
|
|
31268
|
+
switch (whole.opcode) {
|
|
31265
31269
|
case OP_TEXT: {
|
|
31266
|
-
const text =
|
|
31270
|
+
const text = whole.payload.toString("utf-8");
|
|
31267
31271
|
void Promise.resolve().then(() => conn._onMessage ? conn._onMessage(text) : handler(conn, "message", text)).catch((e) => Log.error(`WebSocket message handler error: ${e.message}`));
|
|
31268
31272
|
break;
|
|
31269
31273
|
}
|
|
31270
31274
|
case OP_PING:
|
|
31271
31275
|
try {
|
|
31272
|
-
socket.write(buildFrame(OP_PONG,
|
|
31276
|
+
socket.write(buildFrame(OP_PONG, whole.payload));
|
|
31273
31277
|
} catch {
|
|
31274
31278
|
}
|
|
31275
31279
|
break;
|
|
@@ -31288,7 +31292,7 @@ function serveWebSocketRoute(req2, socket, head) {
|
|
|
31288
31292
|
socket.on("error", fireClose);
|
|
31289
31293
|
return true;
|
|
31290
31294
|
}
|
|
31291
|
-
var MAGIC_STRING, OP_CONTINUATION, OP_TEXT, OP_BINARY, OP_CLOSE, OP_PING, OP_PONG, CLOSE_NORMAL, CLOSE_GOING_AWAY, CLOSE_PROTOCOL_ERROR, CLOSE_POLICY_VIOLATION, WebSocketServer, WsRouteManager, wsRouteManager, DevReloadWsManager, devReloadWs;
|
|
31295
|
+
var MAGIC_STRING, OP_CONTINUATION, OP_TEXT, OP_BINARY, OP_CLOSE, OP_PING, OP_PONG, CLOSE_NORMAL, CLOSE_GOING_AWAY, CLOSE_PROTOCOL_ERROR, CLOSE_POLICY_VIOLATION, MessageAssembler, WebSocketServer, WsRouteManager, wsRouteManager, DevReloadWsManager, devReloadWs;
|
|
31292
31296
|
var init_websocket = __esm({
|
|
31293
31297
|
"src/websocket.ts"() {
|
|
31294
31298
|
"use strict";
|
|
@@ -31307,6 +31311,30 @@ var init_websocket = __esm({
|
|
|
31307
31311
|
CLOSE_GOING_AWAY = 1001;
|
|
31308
31312
|
CLOSE_PROTOCOL_ERROR = 1002;
|
|
31309
31313
|
CLOSE_POLICY_VIOLATION = 1008;
|
|
31314
|
+
MessageAssembler = class {
|
|
31315
|
+
parts = [];
|
|
31316
|
+
opcode = 0;
|
|
31317
|
+
push(frame) {
|
|
31318
|
+
if (frame.opcode >= 8) return { opcode: frame.opcode, payload: frame.payload };
|
|
31319
|
+
if (frame.opcode === OP_CONTINUATION) {
|
|
31320
|
+
if (!this.opcode) return null;
|
|
31321
|
+
this.parts.push(frame.payload);
|
|
31322
|
+
if (!frame.fin) return null;
|
|
31323
|
+
const whole = { opcode: this.opcode, payload: Buffer.concat(this.parts) };
|
|
31324
|
+
this.parts = [];
|
|
31325
|
+
this.opcode = 0;
|
|
31326
|
+
return whole;
|
|
31327
|
+
}
|
|
31328
|
+
if (frame.fin) {
|
|
31329
|
+
this.parts = [];
|
|
31330
|
+
this.opcode = 0;
|
|
31331
|
+
return { opcode: frame.opcode, payload: frame.payload };
|
|
31332
|
+
}
|
|
31333
|
+
this.opcode = frame.opcode;
|
|
31334
|
+
this.parts = [frame.payload];
|
|
31335
|
+
return null;
|
|
31336
|
+
}
|
|
31337
|
+
};
|
|
31310
31338
|
WebSocketServer = class {
|
|
31311
31339
|
port;
|
|
31312
31340
|
server = null;
|
|
@@ -31749,6 +31777,15 @@ var init_websocket = __esm({
|
|
|
31749
31777
|
this.emit("error", err, client);
|
|
31750
31778
|
});
|
|
31751
31779
|
}
|
|
31780
|
+
assemblers = /* @__PURE__ */ new WeakMap();
|
|
31781
|
+
assemblerFor(client) {
|
|
31782
|
+
let a = this.assemblers.get(client);
|
|
31783
|
+
if (!a) {
|
|
31784
|
+
a = new MessageAssembler();
|
|
31785
|
+
this.assemblers.set(client, a);
|
|
31786
|
+
}
|
|
31787
|
+
return a;
|
|
31788
|
+
}
|
|
31752
31789
|
processBuffer(client, buffer, setBuffer) {
|
|
31753
31790
|
let remaining = buffer;
|
|
31754
31791
|
while (remaining.length > 0) {
|
|
@@ -31756,15 +31793,17 @@ var init_websocket = __esm({
|
|
|
31756
31793
|
if (!frame) break;
|
|
31757
31794
|
remaining = remaining.subarray(frame.bytesConsumed);
|
|
31758
31795
|
client.lastActivity = Date.now();
|
|
31759
|
-
|
|
31796
|
+
const whole = this.assemblerFor(client).push(frame);
|
|
31797
|
+
if (!whole) continue;
|
|
31798
|
+
switch (whole.opcode) {
|
|
31760
31799
|
case OP_TEXT:
|
|
31761
|
-
this.emit("message", client,
|
|
31800
|
+
this.emit("message", client, whole.payload.toString("utf-8"));
|
|
31762
31801
|
break;
|
|
31763
31802
|
case OP_BINARY:
|
|
31764
|
-
this.emit("message", client,
|
|
31803
|
+
this.emit("message", client, whole.payload);
|
|
31765
31804
|
break;
|
|
31766
31805
|
case OP_PING: {
|
|
31767
|
-
const pongFrame = buildFrame(OP_PONG,
|
|
31806
|
+
const pongFrame = buildFrame(OP_PONG, whole.payload);
|
|
31768
31807
|
try {
|
|
31769
31808
|
client.socket.write(pongFrame);
|
|
31770
31809
|
} catch {
|
|
@@ -36142,16 +36181,7 @@ async function proxyToSupervisor(req2, res, downstreamPath) {
|
|
|
36142
36181
|
return;
|
|
36143
36182
|
}
|
|
36144
36183
|
clearTimeout(timer);
|
|
36145
|
-
|
|
36146
|
-
const status2 = upstream.status || 200;
|
|
36147
|
-
try {
|
|
36148
|
-
res.json(JSON.parse(raw), status2);
|
|
36149
|
-
} catch {
|
|
36150
|
-
res.raw.writeHead(status2, {
|
|
36151
|
-
"Content-Type": upstream.headers.get("content-type") ?? "text/plain; charset=utf-8"
|
|
36152
|
-
});
|
|
36153
|
-
res.raw.end(raw);
|
|
36154
|
-
}
|
|
36184
|
+
await relayUpstreamResponse(res, upstream);
|
|
36155
36185
|
}
|
|
36156
36186
|
function resolveDevEnvVar(key) {
|
|
36157
36187
|
const live = process.env[key];
|
|
@@ -36593,6 +36623,7 @@ var init_devAdmin = __esm({
|
|
|
36593
36623
|
"src/devAdmin.ts"() {
|
|
36594
36624
|
"use strict";
|
|
36595
36625
|
init_devMailbox();
|
|
36626
|
+
init_upstreamResponse();
|
|
36596
36627
|
init_dotenv();
|
|
36597
36628
|
init_metrics();
|
|
36598
36629
|
init_feedback();
|