tina4-nodejs 3.13.110 → 3.13.111
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 +787 -3
- package/packages/core/dist/index.js +787 -3
- package/packages/orm/dist/index.js +794 -0
- package/packages/orm/src/graph/adapters/arango.ts +256 -0
- package/packages/orm/src/graph/adapters/bolt.ts +259 -0
- package/packages/orm/src/graph/adapters/ultipa.ts +271 -0
- package/packages/orm/src/graph/connectTimeout.ts +39 -0
- package/packages/orm/src/graph/errors.ts +29 -0
- package/packages/orm/src/graph/graphAdapter.ts +53 -0
- package/packages/orm/src/graph/graphDatabase.ts +114 -0
- package/packages/orm/src/graph/graphUrl.ts +98 -0
- package/packages/orm/src/graph/shapes.ts +95 -0
- package/packages/orm/src/index.ts +137 -115
- package/types/orm/src/graph/adapters/arango.d.ts +42 -0
- package/types/orm/src/graph/adapters/bolt.d.ts +43 -0
- package/types/orm/src/graph/adapters/ultipa.d.ts +39 -0
- package/types/orm/src/graph/connectTimeout.d.ts +12 -0
- package/types/orm/src/graph/errors.d.ts +21 -0
- package/types/orm/src/graph/graphAdapter.d.ts +38 -0
- package/types/orm/src/graph/graphDatabase.d.ts +44 -0
- package/types/orm/src/graph/graphUrl.d.ts +28 -0
- package/types/orm/src/graph/shapes.d.ts +37 -0
- package/types/orm/src/index.d.ts +8 -0
package/packages/cli/dist/bin.js
CHANGED
|
@@ -16918,6 +16918,775 @@ var init_docstore = __esm({
|
|
|
16918
16918
|
}
|
|
16919
16919
|
});
|
|
16920
16920
|
|
|
16921
|
+
// ../orm/src/graph/graphUrl.ts
|
|
16922
|
+
var SCHEME_ENGINE, ENGINE_DEFAULT_PORT, GraphUrl;
|
|
16923
|
+
var init_graphUrl = __esm({
|
|
16924
|
+
"../orm/src/graph/graphUrl.ts"() {
|
|
16925
|
+
"use strict";
|
|
16926
|
+
SCHEME_ENGINE = {
|
|
16927
|
+
ultipa: "ultipa",
|
|
16928
|
+
ultipas: "ultipa",
|
|
16929
|
+
// TLS variant
|
|
16930
|
+
neo4j: "bolt",
|
|
16931
|
+
"neo4j+s": "bolt",
|
|
16932
|
+
bolt: "bolt",
|
|
16933
|
+
"bolt+s": "bolt",
|
|
16934
|
+
memgraph: "bolt",
|
|
16935
|
+
arango: "arango",
|
|
16936
|
+
arangodb: "arango"
|
|
16937
|
+
};
|
|
16938
|
+
ENGINE_DEFAULT_PORT = {
|
|
16939
|
+
ultipa: 60061,
|
|
16940
|
+
bolt: 7687,
|
|
16941
|
+
arango: 8529
|
|
16942
|
+
};
|
|
16943
|
+
GraphUrl = class _GraphUrl {
|
|
16944
|
+
raw;
|
|
16945
|
+
scheme;
|
|
16946
|
+
engine;
|
|
16947
|
+
host;
|
|
16948
|
+
port;
|
|
16949
|
+
/** The graph/database name (leading slash stripped), or null when absent. */
|
|
16950
|
+
graph;
|
|
16951
|
+
username;
|
|
16952
|
+
password;
|
|
16953
|
+
params;
|
|
16954
|
+
useTls;
|
|
16955
|
+
constructor(url) {
|
|
16956
|
+
this.raw = url;
|
|
16957
|
+
let parsed;
|
|
16958
|
+
try {
|
|
16959
|
+
parsed = new URL(url);
|
|
16960
|
+
} catch {
|
|
16961
|
+
throw new Error(
|
|
16962
|
+
`Unsupported graph URL '${url}' \u2014 expected scheme://[user[:password]@]host[:port]/graph (e.g. ultipa://host:60061/mygraph).`
|
|
16963
|
+
);
|
|
16964
|
+
}
|
|
16965
|
+
const scheme = parsed.protocol.replace(/:$/, "").toLowerCase();
|
|
16966
|
+
const engine = SCHEME_ENGINE[scheme];
|
|
16967
|
+
if (engine === void 0) {
|
|
16968
|
+
throw new Error(
|
|
16969
|
+
`Unsupported graph URL scheme '${scheme}'. Supported: ${Object.keys(SCHEME_ENGINE).sort().join(", ")} (e.g. ultipa://host:60061/mygraph).`
|
|
16970
|
+
);
|
|
16971
|
+
}
|
|
16972
|
+
this.scheme = scheme;
|
|
16973
|
+
this.engine = engine;
|
|
16974
|
+
this.host = parsed.hostname || "localhost";
|
|
16975
|
+
this.port = parsed.port ? parseInt(parsed.port, 10) : ENGINE_DEFAULT_PORT[engine];
|
|
16976
|
+
const path8 = (parsed.pathname || "").replace(/^\//, "");
|
|
16977
|
+
this.graph = path8 === "" ? null : path8;
|
|
16978
|
+
this.username = parsed.username ? decodeURIComponent(parsed.username) : null;
|
|
16979
|
+
this.password = parsed.password ? decodeURIComponent(parsed.password) : null;
|
|
16980
|
+
this.params = {};
|
|
16981
|
+
for (const [key, value] of parsed.searchParams) {
|
|
16982
|
+
if (!(key in this.params)) this.params[key] = value;
|
|
16983
|
+
}
|
|
16984
|
+
this.useTls = scheme.endsWith("s") || this.params.tls === "1" || this.params.tls === "true";
|
|
16985
|
+
}
|
|
16986
|
+
/** host:port/graph — for messages, never carrying credentials. */
|
|
16987
|
+
getDsn() {
|
|
16988
|
+
const target = this.port ? `${this.host}:${this.port}` : this.host;
|
|
16989
|
+
return this.graph ? `${target}/${this.graph}` : target;
|
|
16990
|
+
}
|
|
16991
|
+
static fromEnv(envKey = "TINA4_GRAPH_URL") {
|
|
16992
|
+
const url = (process.env[envKey] ?? "").trim();
|
|
16993
|
+
return url === "" ? null : new _GraphUrl(url);
|
|
16994
|
+
}
|
|
16995
|
+
};
|
|
16996
|
+
}
|
|
16997
|
+
});
|
|
16998
|
+
|
|
16999
|
+
// ../orm/src/graph/errors.ts
|
|
17000
|
+
var GraphError, GraphConnectTimeout;
|
|
17001
|
+
var init_errors = __esm({
|
|
17002
|
+
"../orm/src/graph/errors.ts"() {
|
|
17003
|
+
"use strict";
|
|
17004
|
+
GraphError = class extends Error {
|
|
17005
|
+
constructor(message, cause) {
|
|
17006
|
+
super(message, cause === void 0 ? void 0 : { cause });
|
|
17007
|
+
this.name = "GraphError";
|
|
17008
|
+
}
|
|
17009
|
+
};
|
|
17010
|
+
GraphConnectTimeout = class extends GraphError {
|
|
17011
|
+
constructor(message, cause) {
|
|
17012
|
+
super(message, cause);
|
|
17013
|
+
this.name = "GraphConnectTimeout";
|
|
17014
|
+
}
|
|
17015
|
+
};
|
|
17016
|
+
}
|
|
17017
|
+
});
|
|
17018
|
+
|
|
17019
|
+
// ../orm/src/graph/shapes.ts
|
|
17020
|
+
var GraphNode, GraphEdge, GraphResult;
|
|
17021
|
+
var init_shapes = __esm({
|
|
17022
|
+
"../orm/src/graph/shapes.ts"() {
|
|
17023
|
+
"use strict";
|
|
17024
|
+
GraphNode = class {
|
|
17025
|
+
id;
|
|
17026
|
+
labels;
|
|
17027
|
+
properties;
|
|
17028
|
+
constructor(id, labels = null, properties = null) {
|
|
17029
|
+
this.id = id;
|
|
17030
|
+
this.labels = [...labels ?? []];
|
|
17031
|
+
this.properties = { ...properties ?? {} };
|
|
17032
|
+
}
|
|
17033
|
+
toDict() {
|
|
17034
|
+
return { id: this.id, labels: this.labels, properties: this.properties };
|
|
17035
|
+
}
|
|
17036
|
+
};
|
|
17037
|
+
GraphEdge = class {
|
|
17038
|
+
id;
|
|
17039
|
+
type;
|
|
17040
|
+
from;
|
|
17041
|
+
to;
|
|
17042
|
+
properties;
|
|
17043
|
+
constructor(id, type2, from, to, properties = null) {
|
|
17044
|
+
this.id = id;
|
|
17045
|
+
this.type = type2;
|
|
17046
|
+
this.from = from;
|
|
17047
|
+
this.to = to;
|
|
17048
|
+
this.properties = { ...properties ?? {} };
|
|
17049
|
+
}
|
|
17050
|
+
toDict() {
|
|
17051
|
+
return {
|
|
17052
|
+
id: this.id,
|
|
17053
|
+
type: this.type,
|
|
17054
|
+
from: this.from,
|
|
17055
|
+
to: this.to,
|
|
17056
|
+
properties: this.properties
|
|
17057
|
+
};
|
|
17058
|
+
}
|
|
17059
|
+
};
|
|
17060
|
+
GraphResult = class {
|
|
17061
|
+
records;
|
|
17062
|
+
columns;
|
|
17063
|
+
constructor(records = null, columns = null) {
|
|
17064
|
+
this.records = [...records ?? []];
|
|
17065
|
+
this.columns = [...columns ?? []];
|
|
17066
|
+
}
|
|
17067
|
+
toArray() {
|
|
17068
|
+
return this.records;
|
|
17069
|
+
}
|
|
17070
|
+
/** The first value of the first record, or null. */
|
|
17071
|
+
scalar() {
|
|
17072
|
+
if (this.records.length === 0) return null;
|
|
17073
|
+
const values = Object.values(this.records[0]);
|
|
17074
|
+
return values.length ? values[0] : null;
|
|
17075
|
+
}
|
|
17076
|
+
[Symbol.iterator]() {
|
|
17077
|
+
return this.records[Symbol.iterator]();
|
|
17078
|
+
}
|
|
17079
|
+
get length() {
|
|
17080
|
+
return this.records.length;
|
|
17081
|
+
}
|
|
17082
|
+
};
|
|
17083
|
+
}
|
|
17084
|
+
});
|
|
17085
|
+
|
|
17086
|
+
// ../orm/src/graph/connectTimeout.ts
|
|
17087
|
+
function resolveGraphConnectTimeout() {
|
|
17088
|
+
const raw = (process.env[GRAPH_CONNECT_TIMEOUT_VARIABLE] ?? "").trim();
|
|
17089
|
+
if (raw === "") {
|
|
17090
|
+
return DEFAULT_GRAPH_CONNECT_TIMEOUT_SECONDS;
|
|
17091
|
+
}
|
|
17092
|
+
const seconds = Number(raw);
|
|
17093
|
+
if (!Number.isFinite(seconds)) {
|
|
17094
|
+
Log.warning(
|
|
17095
|
+
`${GRAPH_CONNECT_TIMEOUT_VARIABLE}="${raw}" is not a number of seconds \u2014 bounding graph connects at the ${DEFAULT_GRAPH_CONNECT_TIMEOUT_SECONDS}s default instead`
|
|
17096
|
+
);
|
|
17097
|
+
return DEFAULT_GRAPH_CONNECT_TIMEOUT_SECONDS;
|
|
17098
|
+
}
|
|
17099
|
+
return seconds <= 0 ? null : seconds;
|
|
17100
|
+
}
|
|
17101
|
+
var GRAPH_CONNECT_TIMEOUT_VARIABLE, DEFAULT_GRAPH_CONNECT_TIMEOUT_SECONDS;
|
|
17102
|
+
var init_connectTimeout2 = __esm({
|
|
17103
|
+
"../orm/src/graph/connectTimeout.ts"() {
|
|
17104
|
+
"use strict";
|
|
17105
|
+
init_src3();
|
|
17106
|
+
GRAPH_CONNECT_TIMEOUT_VARIABLE = "TINA4_GRAPH_CONNECT_TIMEOUT";
|
|
17107
|
+
DEFAULT_GRAPH_CONNECT_TIMEOUT_SECONDS = 10;
|
|
17108
|
+
}
|
|
17109
|
+
});
|
|
17110
|
+
|
|
17111
|
+
// ../orm/src/graph/adapters/ultipa.ts
|
|
17112
|
+
var ultipa_exports = {};
|
|
17113
|
+
__export(ultipa_exports, {
|
|
17114
|
+
UltipaGraphAdapter: () => UltipaGraphAdapter
|
|
17115
|
+
});
|
|
17116
|
+
function propClause(properties) {
|
|
17117
|
+
const props = properties ?? {};
|
|
17118
|
+
const keys = Object.keys(props);
|
|
17119
|
+
if (keys.length === 0) return { clause: "{}", params: {} };
|
|
17120
|
+
const pairs = keys.map((key) => `${key}: $p_${key}`).join(", ");
|
|
17121
|
+
const params = {};
|
|
17122
|
+
for (const key of keys) params[`p_${key}`] = props[key];
|
|
17123
|
+
return { clause: `{${pairs}}`, params };
|
|
17124
|
+
}
|
|
17125
|
+
function errorMessage(exc) {
|
|
17126
|
+
if (exc instanceof Error) return exc.message;
|
|
17127
|
+
return String(exc);
|
|
17128
|
+
}
|
|
17129
|
+
var DRIVER_PACKAGE, driver, UltipaClient, UltipaConnectError, UNBOUNDED_CONNECT_SECONDS, UltipaGraphAdapter;
|
|
17130
|
+
var init_ultipa = __esm({
|
|
17131
|
+
async "../orm/src/graph/adapters/ultipa.ts"() {
|
|
17132
|
+
"use strict";
|
|
17133
|
+
init_shapes();
|
|
17134
|
+
init_errors();
|
|
17135
|
+
init_connectTimeout2();
|
|
17136
|
+
DRIVER_PACKAGE = "tina4-ultipa";
|
|
17137
|
+
driver = await import(DRIVER_PACKAGE);
|
|
17138
|
+
UltipaClient = driver.UltipaClient;
|
|
17139
|
+
UltipaConnectError = driver.UltipaConnectError;
|
|
17140
|
+
UNBOUNDED_CONNECT_SECONDS = 31536e4;
|
|
17141
|
+
UltipaGraphAdapter = class {
|
|
17142
|
+
url;
|
|
17143
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17144
|
+
client;
|
|
17145
|
+
lastError = null;
|
|
17146
|
+
constructor(graphUrl, credentials = {}) {
|
|
17147
|
+
this.url = graphUrl;
|
|
17148
|
+
const timeout = resolveGraphConnectTimeout();
|
|
17149
|
+
this.client = new UltipaClient({
|
|
17150
|
+
host: graphUrl.host,
|
|
17151
|
+
port: graphUrl.port,
|
|
17152
|
+
username: graphUrl.username || credentials.username || null,
|
|
17153
|
+
password: graphUrl.password || credentials.password || null,
|
|
17154
|
+
graph: graphUrl.graph,
|
|
17155
|
+
connectTimeout: timeout ?? UNBOUNDED_CONNECT_SECONDS,
|
|
17156
|
+
useTls: graphUrl.useTls
|
|
17157
|
+
});
|
|
17158
|
+
}
|
|
17159
|
+
// -- connection + raw pass-through -------------------------------------
|
|
17160
|
+
async run(gql, params = null, readOnly = true) {
|
|
17161
|
+
try {
|
|
17162
|
+
await this.client.connect();
|
|
17163
|
+
} catch (exc) {
|
|
17164
|
+
this.lastError = errorMessage(exc);
|
|
17165
|
+
if (exc instanceof UltipaConnectError || exc?.name === "UltipaConnectError") {
|
|
17166
|
+
const elapsed = typeof exc?.elapsed === "number" ? exc.elapsed : 0;
|
|
17167
|
+
throw new GraphConnectTimeout(
|
|
17168
|
+
`Graph connect to ${this.url.host}:${this.url.port} timed out after ${elapsed.toFixed(1)}s (${GRAPH_CONNECT_TIMEOUT_VARIABLE}). Raise ${GRAPH_CONNECT_TIMEOUT_VARIABLE} if the server is simply slow, or set it to 0 to wait indefinitely.`,
|
|
17169
|
+
exc
|
|
17170
|
+
);
|
|
17171
|
+
}
|
|
17172
|
+
throw new GraphError(this.lastError, exc);
|
|
17173
|
+
}
|
|
17174
|
+
try {
|
|
17175
|
+
return await this.client.query(gql, { params: params ?? null, readOnly });
|
|
17176
|
+
} catch (exc) {
|
|
17177
|
+
this.lastError = errorMessage(exc);
|
|
17178
|
+
throw new GraphError(this.lastError, exc);
|
|
17179
|
+
}
|
|
17180
|
+
}
|
|
17181
|
+
async query(text, params = null) {
|
|
17182
|
+
const result = await this.run(text, params, true);
|
|
17183
|
+
return new GraphResult(result.dicts(), result.columns);
|
|
17184
|
+
}
|
|
17185
|
+
async execute(text, params = null) {
|
|
17186
|
+
const result = await this.run(text, params, false);
|
|
17187
|
+
return new GraphResult(result.dicts(), result.columns);
|
|
17188
|
+
}
|
|
17189
|
+
// -- portable node/edge/traverse core (GQL) ----------------------------
|
|
17190
|
+
nodeFromRow(row) {
|
|
17191
|
+
if (row === null || row === void 0) return null;
|
|
17192
|
+
return new GraphNode(
|
|
17193
|
+
String(row.id),
|
|
17194
|
+
row.labels ?? [],
|
|
17195
|
+
row.props ?? {}
|
|
17196
|
+
);
|
|
17197
|
+
}
|
|
17198
|
+
async addNode(label, properties = null) {
|
|
17199
|
+
const { clause, params } = propClause(properties);
|
|
17200
|
+
const gql = `INSERT (n:\`${label}\` ${clause}) RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
17201
|
+
const rows = (await this.run(gql, params, false)).dicts();
|
|
17202
|
+
return rows.length ? this.nodeFromRow(rows[0]) : null;
|
|
17203
|
+
}
|
|
17204
|
+
async addEdge(fromId, toId, type2, properties = null) {
|
|
17205
|
+
const { clause, params } = propClause(properties);
|
|
17206
|
+
params.from_id = fromId;
|
|
17207
|
+
params.to_id = toId;
|
|
17208
|
+
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`;
|
|
17209
|
+
const rows = (await this.run(gql, params, false)).dicts();
|
|
17210
|
+
if (rows.length === 0) return null;
|
|
17211
|
+
const row = rows[0];
|
|
17212
|
+
return new GraphEdge(
|
|
17213
|
+
String(row.id),
|
|
17214
|
+
String(row.type),
|
|
17215
|
+
String(row.f),
|
|
17216
|
+
String(row.t),
|
|
17217
|
+
row.props ?? {}
|
|
17218
|
+
);
|
|
17219
|
+
}
|
|
17220
|
+
async getNode(nodeId) {
|
|
17221
|
+
const gql = `MATCH (n) WHERE id(n) = $id RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
17222
|
+
const rows = (await this.run(gql, { id: nodeId }, true)).dicts();
|
|
17223
|
+
return rows.length ? this.nodeFromRow(rows[0]) : null;
|
|
17224
|
+
}
|
|
17225
|
+
async updateNode(nodeId, properties) {
|
|
17226
|
+
const props = properties ?? {};
|
|
17227
|
+
const keys = Object.keys(props);
|
|
17228
|
+
const sets = keys.map((key) => `n.${key} = $p_${key}`).join(", ");
|
|
17229
|
+
const params = { id: nodeId };
|
|
17230
|
+
for (const key of keys) params[`p_${key}`] = props[key];
|
|
17231
|
+
const gql = `MATCH (n) WHERE id(n) = $id SET ${sets} RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
17232
|
+
const rows = (await this.run(gql, params, false)).dicts();
|
|
17233
|
+
return rows.length ? this.nodeFromRow(rows[0]) : null;
|
|
17234
|
+
}
|
|
17235
|
+
async deleteNode(nodeId) {
|
|
17236
|
+
const gql = "MATCH (n) WHERE id(n) = $id DETACH DELETE n";
|
|
17237
|
+
await this.run(gql, { id: nodeId }, false);
|
|
17238
|
+
return true;
|
|
17239
|
+
}
|
|
17240
|
+
async neighbors(nodeId, options = {}) {
|
|
17241
|
+
const direction = options.direction ?? "both";
|
|
17242
|
+
const limit = options.limit ?? 100;
|
|
17243
|
+
const edge = options.edgeType ? `:\`${options.edgeType}\`` : "";
|
|
17244
|
+
const pattern = {
|
|
17245
|
+
out: `(n)-[${edge}]->(m)`,
|
|
17246
|
+
in: `(n)<-[${edge}]-(m)`,
|
|
17247
|
+
both: `(n)-[${edge}]-(m)`
|
|
17248
|
+
}[direction];
|
|
17249
|
+
const gql = `MATCH ${pattern} WHERE id(n) = $id RETURN DISTINCT id(m) AS id, labels(m) AS labels, properties(m) AS props LIMIT ${Math.trunc(limit)}`;
|
|
17250
|
+
const rows = (await this.run(gql, { id: nodeId }, true)).dicts();
|
|
17251
|
+
return rows.map((row) => this.nodeFromRow(row)).filter((node) => node !== null);
|
|
17252
|
+
}
|
|
17253
|
+
async traverse(startId, options = {}) {
|
|
17254
|
+
const depth = options.depth ?? 1;
|
|
17255
|
+
const direction = options.direction ?? "both";
|
|
17256
|
+
const limit = options.limit ?? 1e3;
|
|
17257
|
+
const edge = options.edgeType ? `:\`${options.edgeType}\`` : "";
|
|
17258
|
+
const quant = `{1,${Math.trunc(depth)}}`;
|
|
17259
|
+
const pattern = {
|
|
17260
|
+
out: `(n)-[${edge}]->${quant}(m)`,
|
|
17261
|
+
in: `(n)<-[${edge}]-${quant}(m)`,
|
|
17262
|
+
both: `(n)-[${edge}]-${quant}(m)`
|
|
17263
|
+
}[direction];
|
|
17264
|
+
const gql = `MATCH ${pattern} WHERE id(n) = $start RETURN DISTINCT id(m) AS id, labels(m) AS labels, properties(m) AS props LIMIT ${Math.trunc(limit)}`;
|
|
17265
|
+
const rows = (await this.run(gql, { start: startId }, true)).dicts();
|
|
17266
|
+
return rows.map((row) => this.nodeFromRow(row)).filter((node) => node !== null);
|
|
17267
|
+
}
|
|
17268
|
+
close() {
|
|
17269
|
+
this.client.close();
|
|
17270
|
+
}
|
|
17271
|
+
getError() {
|
|
17272
|
+
return this.lastError;
|
|
17273
|
+
}
|
|
17274
|
+
};
|
|
17275
|
+
}
|
|
17276
|
+
});
|
|
17277
|
+
|
|
17278
|
+
// ../orm/src/graph/adapters/bolt.ts
|
|
17279
|
+
var bolt_exports = {};
|
|
17280
|
+
__export(bolt_exports, {
|
|
17281
|
+
BoltGraphAdapter: () => BoltGraphAdapter
|
|
17282
|
+
});
|
|
17283
|
+
function errorMessage2(exc) {
|
|
17284
|
+
if (exc instanceof Error) return exc.message;
|
|
17285
|
+
return String(exc);
|
|
17286
|
+
}
|
|
17287
|
+
function boltId(id) {
|
|
17288
|
+
const value = Number(id);
|
|
17289
|
+
return Number.isNaN(value) ? -1 : value;
|
|
17290
|
+
}
|
|
17291
|
+
var DRIVER_PACKAGE2, driverModule, neo4j, BoltGraphAdapter;
|
|
17292
|
+
var init_bolt = __esm({
|
|
17293
|
+
async "../orm/src/graph/adapters/bolt.ts"() {
|
|
17294
|
+
"use strict";
|
|
17295
|
+
init_shapes();
|
|
17296
|
+
init_errors();
|
|
17297
|
+
init_connectTimeout2();
|
|
17298
|
+
DRIVER_PACKAGE2 = "neo4j-driver";
|
|
17299
|
+
driverModule = await import(DRIVER_PACKAGE2);
|
|
17300
|
+
neo4j = driverModule.default ?? driverModule;
|
|
17301
|
+
BoltGraphAdapter = class {
|
|
17302
|
+
url;
|
|
17303
|
+
database;
|
|
17304
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17305
|
+
driver;
|
|
17306
|
+
lastError = null;
|
|
17307
|
+
constructor(graphUrl, credentials = {}) {
|
|
17308
|
+
this.url = graphUrl;
|
|
17309
|
+
this.database = graphUrl.graph || null;
|
|
17310
|
+
const user = graphUrl.username || credentials.username || "neo4j";
|
|
17311
|
+
const pwd = graphUrl.password || credentials.password || "";
|
|
17312
|
+
const scheme = graphUrl.useTls ? "bolt+s" : "bolt";
|
|
17313
|
+
const uri = `${scheme}://${graphUrl.host}:${graphUrl.port}`;
|
|
17314
|
+
const timeout = resolveGraphConnectTimeout();
|
|
17315
|
+
const config = { disableLosslessIntegers: true };
|
|
17316
|
+
if (timeout !== null) {
|
|
17317
|
+
const ms = Math.max(1, Math.ceil(timeout * 1e3));
|
|
17318
|
+
config.connectionTimeout = ms;
|
|
17319
|
+
config.connectionAcquisitionTimeout = ms;
|
|
17320
|
+
config.maxTransactionRetryTime = ms;
|
|
17321
|
+
}
|
|
17322
|
+
this.driver = neo4j.driver(uri, neo4j.auth.basic(user, pwd), config);
|
|
17323
|
+
}
|
|
17324
|
+
// -- connection + raw pass-through -------------------------------------
|
|
17325
|
+
async run(cypher, params = null) {
|
|
17326
|
+
const session = this.database ? this.driver.session({ database: this.database }) : this.driver.session();
|
|
17327
|
+
try {
|
|
17328
|
+
const result = await session.run(cypher, params ?? {});
|
|
17329
|
+
return result.records.map((record) => record.toObject());
|
|
17330
|
+
} catch (exc) {
|
|
17331
|
+
this.lastError = errorMessage2(exc);
|
|
17332
|
+
const code = exc?.code ?? "";
|
|
17333
|
+
const message = this.lastError.toLowerCase();
|
|
17334
|
+
if (code === "ServiceUnavailable" || code === neo4j.error?.SERVICE_UNAVAILABLE || message.includes("timed out") || message.includes("timeout")) {
|
|
17335
|
+
throw new GraphConnectTimeout(
|
|
17336
|
+
`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.`,
|
|
17337
|
+
exc
|
|
17338
|
+
);
|
|
17339
|
+
}
|
|
17340
|
+
throw new GraphError(this.lastError, exc);
|
|
17341
|
+
} finally {
|
|
17342
|
+
await session.close();
|
|
17343
|
+
}
|
|
17344
|
+
}
|
|
17345
|
+
async query(text, params = null) {
|
|
17346
|
+
const rows = await this.run(text, params);
|
|
17347
|
+
const columns = rows.length ? Object.keys(rows[0]) : [];
|
|
17348
|
+
return new GraphResult(rows, columns);
|
|
17349
|
+
}
|
|
17350
|
+
async execute(text, params = null) {
|
|
17351
|
+
return this.query(text, params);
|
|
17352
|
+
}
|
|
17353
|
+
// -- portable node/edge/traverse core (Cypher) -------------------------
|
|
17354
|
+
nodeFromRow(row) {
|
|
17355
|
+
if (row === null || row === void 0) return null;
|
|
17356
|
+
return new GraphNode(
|
|
17357
|
+
String(row.id),
|
|
17358
|
+
row.labels ?? [],
|
|
17359
|
+
row.props ?? {}
|
|
17360
|
+
);
|
|
17361
|
+
}
|
|
17362
|
+
async addNode(label, properties = null) {
|
|
17363
|
+
const cypher = `CREATE (n:\`${label}\` $props) RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
17364
|
+
const rows = await this.run(cypher, { props: properties ?? {} });
|
|
17365
|
+
return rows.length ? this.nodeFromRow(rows[0]) : null;
|
|
17366
|
+
}
|
|
17367
|
+
async addEdge(fromId, toId, type2, properties = null) {
|
|
17368
|
+
const cypher = `MATCH (a), (b) WHERE id(a) = $from_id AND id(b) = $to_id CREATE (a)-[e:\`${type2}\` $props]->(b) RETURN id(e) AS id, type(e) AS type, id(a) AS f, id(b) AS t, properties(e) AS props`;
|
|
17369
|
+
const rows = await this.run(cypher, {
|
|
17370
|
+
from_id: boltId(fromId),
|
|
17371
|
+
to_id: boltId(toId),
|
|
17372
|
+
props: properties ?? {}
|
|
17373
|
+
});
|
|
17374
|
+
if (rows.length === 0) return null;
|
|
17375
|
+
const row = rows[0];
|
|
17376
|
+
return new GraphEdge(
|
|
17377
|
+
String(row.id),
|
|
17378
|
+
String(row.type),
|
|
17379
|
+
String(row.f),
|
|
17380
|
+
String(row.t),
|
|
17381
|
+
row.props ?? {}
|
|
17382
|
+
);
|
|
17383
|
+
}
|
|
17384
|
+
async getNode(nodeId) {
|
|
17385
|
+
const cypher = `MATCH (n) WHERE id(n) = $id RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
17386
|
+
const rows = await this.run(cypher, { id: boltId(nodeId) });
|
|
17387
|
+
return rows.length ? this.nodeFromRow(rows[0]) : null;
|
|
17388
|
+
}
|
|
17389
|
+
async updateNode(nodeId, properties) {
|
|
17390
|
+
const cypher = `MATCH (n) WHERE id(n) = $id SET n += $props RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props`;
|
|
17391
|
+
const rows = await this.run(cypher, { id: boltId(nodeId), props: properties ?? {} });
|
|
17392
|
+
return rows.length ? this.nodeFromRow(rows[0]) : null;
|
|
17393
|
+
}
|
|
17394
|
+
async deleteNode(nodeId) {
|
|
17395
|
+
await this.run("MATCH (n) WHERE id(n) = $id DETACH DELETE n", { id: boltId(nodeId) });
|
|
17396
|
+
return true;
|
|
17397
|
+
}
|
|
17398
|
+
async neighbors(nodeId, options = {}) {
|
|
17399
|
+
const direction = options.direction ?? "both";
|
|
17400
|
+
const limit = options.limit ?? 100;
|
|
17401
|
+
const edge = options.edgeType ? `:\`${options.edgeType}\`` : "";
|
|
17402
|
+
const pattern = {
|
|
17403
|
+
out: `(n)-[${edge}]->(m)`,
|
|
17404
|
+
in: `(n)<-[${edge}]-(m)`,
|
|
17405
|
+
both: `(n)-[${edge}]-(m)`
|
|
17406
|
+
}[direction];
|
|
17407
|
+
const cypher = `MATCH ${pattern} WHERE id(n) = $id RETURN DISTINCT id(m) AS id, labels(m) AS labels, properties(m) AS props LIMIT ${Math.trunc(limit)}`;
|
|
17408
|
+
const rows = await this.run(cypher, { id: boltId(nodeId) });
|
|
17409
|
+
return rows.map((row) => this.nodeFromRow(row)).filter((node) => node !== null);
|
|
17410
|
+
}
|
|
17411
|
+
async traverse(startId, options = {}) {
|
|
17412
|
+
const depth = options.depth ?? 1;
|
|
17413
|
+
const direction = options.direction ?? "both";
|
|
17414
|
+
const limit = options.limit ?? 1e3;
|
|
17415
|
+
const edge = options.edgeType ? `:\`${options.edgeType}\`` : "";
|
|
17416
|
+
const range = `*1..${Math.trunc(depth)}`;
|
|
17417
|
+
const arrow = {
|
|
17418
|
+
out: `-[${edge}${range}]->`,
|
|
17419
|
+
in: `<-[${edge}${range}]-`,
|
|
17420
|
+
both: `-[${edge}${range}]-`
|
|
17421
|
+
}[direction];
|
|
17422
|
+
const cypher = `MATCH (n)${arrow}(m) WHERE id(n) = $start RETURN DISTINCT id(m) AS id, labels(m) AS labels, properties(m) AS props LIMIT ${Math.trunc(limit)}`;
|
|
17423
|
+
const rows = await this.run(cypher, { start: boltId(startId) });
|
|
17424
|
+
return rows.map((row) => this.nodeFromRow(row)).filter((node) => node !== null);
|
|
17425
|
+
}
|
|
17426
|
+
async close() {
|
|
17427
|
+
await this.driver.close();
|
|
17428
|
+
}
|
|
17429
|
+
getError() {
|
|
17430
|
+
return this.lastError;
|
|
17431
|
+
}
|
|
17432
|
+
};
|
|
17433
|
+
}
|
|
17434
|
+
});
|
|
17435
|
+
|
|
17436
|
+
// ../orm/src/graph/adapters/arango.ts
|
|
17437
|
+
var arango_exports = {};
|
|
17438
|
+
__export(arango_exports, {
|
|
17439
|
+
ArangoGraphAdapter: () => ArangoGraphAdapter
|
|
17440
|
+
});
|
|
17441
|
+
function cleanProps(doc) {
|
|
17442
|
+
const props = {};
|
|
17443
|
+
for (const [key, value] of Object.entries(doc)) {
|
|
17444
|
+
if (!RESERVED.has(key)) props[key] = value;
|
|
17445
|
+
}
|
|
17446
|
+
return props;
|
|
17447
|
+
}
|
|
17448
|
+
function errorMessage3(exc) {
|
|
17449
|
+
if (exc instanceof Error) return exc.message;
|
|
17450
|
+
return String(exc);
|
|
17451
|
+
}
|
|
17452
|
+
var DRIVER_PACKAGE3, driverModule2, ArangoDatabase, VERTEX_COLLECTION, EDGE_COLLECTION, RESERVED, ArangoGraphAdapter;
|
|
17453
|
+
var init_arango = __esm({
|
|
17454
|
+
async "../orm/src/graph/adapters/arango.ts"() {
|
|
17455
|
+
"use strict";
|
|
17456
|
+
init_shapes();
|
|
17457
|
+
init_errors();
|
|
17458
|
+
init_connectTimeout2();
|
|
17459
|
+
DRIVER_PACKAGE3 = "arangojs";
|
|
17460
|
+
driverModule2 = await import(DRIVER_PACKAGE3);
|
|
17461
|
+
ArangoDatabase = driverModule2.Database ?? driverModule2.default?.Database;
|
|
17462
|
+
VERTEX_COLLECTION = "tina4_nodes";
|
|
17463
|
+
EDGE_COLLECTION = "tina4_edges";
|
|
17464
|
+
RESERVED = /* @__PURE__ */ new Set(["_id", "_key", "_rev", "_from", "_to", "_labels", "_type"]);
|
|
17465
|
+
ArangoGraphAdapter = class {
|
|
17466
|
+
url;
|
|
17467
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17468
|
+
db;
|
|
17469
|
+
ensured = false;
|
|
17470
|
+
lastError = null;
|
|
17471
|
+
constructor(graphUrl, credentials = {}) {
|
|
17472
|
+
this.url = graphUrl;
|
|
17473
|
+
const scheme = graphUrl.useTls ? "https" : "http";
|
|
17474
|
+
const user = graphUrl.username || credentials.username || "root";
|
|
17475
|
+
const pwd = graphUrl.password || credentials.password || "";
|
|
17476
|
+
const database = graphUrl.graph || "_system";
|
|
17477
|
+
const timeout = resolveGraphConnectTimeout();
|
|
17478
|
+
const config = {
|
|
17479
|
+
url: `${scheme}://${graphUrl.host}:${graphUrl.port}`,
|
|
17480
|
+
databaseName: database,
|
|
17481
|
+
auth: { username: user, password: pwd }
|
|
17482
|
+
};
|
|
17483
|
+
if (timeout !== null) config.timeout = Math.max(1, Math.ceil(timeout * 1e3));
|
|
17484
|
+
this.db = new ArangoDatabase(config);
|
|
17485
|
+
}
|
|
17486
|
+
connectOrError(exc) {
|
|
17487
|
+
const text = errorMessage3(exc).toLowerCase();
|
|
17488
|
+
if (text.includes("timed out") || text.includes("timeout") || text.includes("connection") || text.includes("econnrefused") || text.includes("etimedout") || text.includes("max retries")) {
|
|
17489
|
+
return new GraphConnectTimeout(
|
|
17490
|
+
`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.`,
|
|
17491
|
+
exc
|
|
17492
|
+
);
|
|
17493
|
+
}
|
|
17494
|
+
return new GraphError(errorMessage3(exc), exc);
|
|
17495
|
+
}
|
|
17496
|
+
async ensureCollections() {
|
|
17497
|
+
if (this.ensured) return;
|
|
17498
|
+
try {
|
|
17499
|
+
const nodes = this.db.collection(VERTEX_COLLECTION);
|
|
17500
|
+
if (!await nodes.exists()) await this.db.createCollection(VERTEX_COLLECTION);
|
|
17501
|
+
const edges = this.db.collection(EDGE_COLLECTION);
|
|
17502
|
+
if (!await edges.exists()) await this.db.createEdgeCollection(EDGE_COLLECTION);
|
|
17503
|
+
this.ensured = true;
|
|
17504
|
+
} catch (exc) {
|
|
17505
|
+
this.lastError = errorMessage3(exc);
|
|
17506
|
+
throw this.connectOrError(exc);
|
|
17507
|
+
}
|
|
17508
|
+
}
|
|
17509
|
+
async aql(query, bind2 = null) {
|
|
17510
|
+
await this.ensureCollections();
|
|
17511
|
+
try {
|
|
17512
|
+
const cursor = await this.db.query({ query, bindVars: bind2 ?? {} });
|
|
17513
|
+
return await cursor.all();
|
|
17514
|
+
} catch (exc) {
|
|
17515
|
+
this.lastError = errorMessage3(exc);
|
|
17516
|
+
throw this.connectOrError(exc);
|
|
17517
|
+
}
|
|
17518
|
+
}
|
|
17519
|
+
async query(text, params = null) {
|
|
17520
|
+
const rows = await this.aql(text, params);
|
|
17521
|
+
const first = rows[0];
|
|
17522
|
+
const columns = rows.length && first && typeof first === "object" ? Object.keys(first) : [];
|
|
17523
|
+
return new GraphResult(rows, columns);
|
|
17524
|
+
}
|
|
17525
|
+
async execute(text, params = null) {
|
|
17526
|
+
return this.query(text, params);
|
|
17527
|
+
}
|
|
17528
|
+
// -- portable node/edge/traverse core (AQL) ----------------------------
|
|
17529
|
+
nodeFromDoc(doc) {
|
|
17530
|
+
if (doc === null || doc === void 0) return null;
|
|
17531
|
+
return new GraphNode(
|
|
17532
|
+
String(doc._id),
|
|
17533
|
+
doc._labels ?? [],
|
|
17534
|
+
cleanProps(doc)
|
|
17535
|
+
);
|
|
17536
|
+
}
|
|
17537
|
+
async addNode(label, properties = null) {
|
|
17538
|
+
const doc = { ...properties ?? {}, _labels: [label] };
|
|
17539
|
+
const rows = await this.aql(`INSERT @doc INTO ${VERTEX_COLLECTION} RETURN NEW`, { doc });
|
|
17540
|
+
return rows.length ? this.nodeFromDoc(rows[0]) : null;
|
|
17541
|
+
}
|
|
17542
|
+
async addEdge(fromId, toId, type2, properties = null) {
|
|
17543
|
+
const doc = { ...properties ?? {}, _from: fromId, _to: toId, _type: type2 };
|
|
17544
|
+
const rows = await this.aql(`INSERT @doc INTO ${EDGE_COLLECTION} RETURN NEW`, { doc });
|
|
17545
|
+
if (rows.length === 0) return null;
|
|
17546
|
+
const row = rows[0];
|
|
17547
|
+
return new GraphEdge(
|
|
17548
|
+
String(row._id),
|
|
17549
|
+
String(row._type),
|
|
17550
|
+
String(row._from),
|
|
17551
|
+
String(row._to),
|
|
17552
|
+
cleanProps(row)
|
|
17553
|
+
);
|
|
17554
|
+
}
|
|
17555
|
+
async getNode(nodeId) {
|
|
17556
|
+
const rows = await this.aql("RETURN DOCUMENT(@id)", { id: nodeId });
|
|
17557
|
+
return rows.length && rows[0] ? this.nodeFromDoc(rows[0]) : null;
|
|
17558
|
+
}
|
|
17559
|
+
async updateNode(nodeId, properties) {
|
|
17560
|
+
const rows = await this.aql(
|
|
17561
|
+
`UPDATE PARSE_IDENTIFIER(@id).key WITH @props IN ${VERTEX_COLLECTION} RETURN NEW`,
|
|
17562
|
+
{ id: nodeId, props: properties ?? {} }
|
|
17563
|
+
);
|
|
17564
|
+
return rows.length ? this.nodeFromDoc(rows[0]) : null;
|
|
17565
|
+
}
|
|
17566
|
+
async deleteNode(nodeId) {
|
|
17567
|
+
await this.aql(
|
|
17568
|
+
`FOR e IN ${EDGE_COLLECTION} FILTER e._from == @id OR e._to == @id REMOVE e IN ${EDGE_COLLECTION}`,
|
|
17569
|
+
{ id: nodeId }
|
|
17570
|
+
);
|
|
17571
|
+
await this.aql(
|
|
17572
|
+
`REMOVE PARSE_IDENTIFIER(@id).key IN ${VERTEX_COLLECTION}`,
|
|
17573
|
+
{ id: nodeId }
|
|
17574
|
+
);
|
|
17575
|
+
return true;
|
|
17576
|
+
}
|
|
17577
|
+
async neighbors(nodeId, options = {}) {
|
|
17578
|
+
const direction = options.direction ?? "both";
|
|
17579
|
+
const limit = options.limit ?? 100;
|
|
17580
|
+
const arangoDir = { out: "OUTBOUND", in: "INBOUND", both: "ANY" }[direction];
|
|
17581
|
+
const typeFilter = options.edgeType ? "FILTER e._type == @etype " : "";
|
|
17582
|
+
const bind2 = { start: nodeId, limit: Math.trunc(limit) };
|
|
17583
|
+
if (options.edgeType) bind2.etype = options.edgeType;
|
|
17584
|
+
const rows = await this.aql(
|
|
17585
|
+
`FOR v, e IN 1..1 ${arangoDir} @start ${EDGE_COLLECTION} ${typeFilter}LIMIT @limit RETURN DISTINCT v`,
|
|
17586
|
+
bind2
|
|
17587
|
+
);
|
|
17588
|
+
return rows.map((doc) => this.nodeFromDoc(doc)).filter((node) => node !== null);
|
|
17589
|
+
}
|
|
17590
|
+
async traverse(startId, options = {}) {
|
|
17591
|
+
const depth = options.depth ?? 1;
|
|
17592
|
+
const direction = options.direction ?? "both";
|
|
17593
|
+
const limit = options.limit ?? 1e3;
|
|
17594
|
+
const arangoDir = { out: "OUTBOUND", in: "INBOUND", both: "ANY" }[direction];
|
|
17595
|
+
const typeFilter = options.edgeType ? "FILTER e._type == @etype " : "";
|
|
17596
|
+
const bind2 = { start: startId, limit: Math.trunc(limit) };
|
|
17597
|
+
if (options.edgeType) bind2.etype = options.edgeType;
|
|
17598
|
+
const rows = await this.aql(
|
|
17599
|
+
`FOR v, e IN 1..${Math.trunc(depth)} ${arangoDir} @start ${EDGE_COLLECTION} ${typeFilter}LIMIT @limit RETURN DISTINCT v`,
|
|
17600
|
+
bind2
|
|
17601
|
+
);
|
|
17602
|
+
return rows.map((doc) => this.nodeFromDoc(doc)).filter((node) => node !== null);
|
|
17603
|
+
}
|
|
17604
|
+
async close() {
|
|
17605
|
+
if (typeof this.db.close === "function") this.db.close();
|
|
17606
|
+
}
|
|
17607
|
+
getError() {
|
|
17608
|
+
return this.lastError;
|
|
17609
|
+
}
|
|
17610
|
+
};
|
|
17611
|
+
}
|
|
17612
|
+
});
|
|
17613
|
+
|
|
17614
|
+
// ../orm/src/graph/graphDatabase.ts
|
|
17615
|
+
var ENGINE_ADAPTERS, GraphDatabase;
|
|
17616
|
+
var init_graphDatabase = __esm({
|
|
17617
|
+
"../orm/src/graph/graphDatabase.ts"() {
|
|
17618
|
+
"use strict";
|
|
17619
|
+
init_graphUrl();
|
|
17620
|
+
init_errors();
|
|
17621
|
+
ENGINE_ADAPTERS = {
|
|
17622
|
+
ultipa: {
|
|
17623
|
+
load: () => init_ultipa().then(() => ultipa_exports),
|
|
17624
|
+
className: "UltipaGraphAdapter",
|
|
17625
|
+
package: "tina4-ultipa",
|
|
17626
|
+
installCommand: "npm install tina4-ultipa"
|
|
17627
|
+
},
|
|
17628
|
+
bolt: {
|
|
17629
|
+
// Neo4j AND Memgraph — both speak Bolt/Cypher over the neo4j-driver package.
|
|
17630
|
+
load: () => init_bolt().then(() => bolt_exports),
|
|
17631
|
+
className: "BoltGraphAdapter",
|
|
17632
|
+
package: "neo4j-driver",
|
|
17633
|
+
installCommand: "npm install neo4j-driver"
|
|
17634
|
+
},
|
|
17635
|
+
arango: {
|
|
17636
|
+
load: () => init_arango().then(() => arango_exports),
|
|
17637
|
+
className: "ArangoGraphAdapter",
|
|
17638
|
+
package: "arangojs",
|
|
17639
|
+
installCommand: "npm install arangojs"
|
|
17640
|
+
}
|
|
17641
|
+
};
|
|
17642
|
+
GraphDatabase = class _GraphDatabase {
|
|
17643
|
+
/**
|
|
17644
|
+
* Parse the URL, pick the engine adapter, connect lazily.
|
|
17645
|
+
*
|
|
17646
|
+
* The engine driver is imported only here (first use of that engine); if it is
|
|
17647
|
+
* absent the error names the package and the install command. Async because the
|
|
17648
|
+
* driver import is dynamic — the connect itself still happens lazily on first
|
|
17649
|
+
* operation (mirroring the relational adapters).
|
|
17650
|
+
*/
|
|
17651
|
+
static async create(url, credentials = {}) {
|
|
17652
|
+
const graphUrl = new GraphUrl(url);
|
|
17653
|
+
const registration = ENGINE_ADAPTERS[graphUrl.engine];
|
|
17654
|
+
if (registration === void 0) {
|
|
17655
|
+
throw new GraphError(
|
|
17656
|
+
`No graph adapter for engine '${graphUrl.engine}' yet (scheme '${graphUrl.scheme}'). Available: ${Object.keys(ENGINE_ADAPTERS).sort().join(", ")}.`
|
|
17657
|
+
);
|
|
17658
|
+
}
|
|
17659
|
+
let module;
|
|
17660
|
+
try {
|
|
17661
|
+
module = await registration.load();
|
|
17662
|
+
} catch (cause) {
|
|
17663
|
+
throw new GraphError(
|
|
17664
|
+
`The graph driver for '${graphUrl.engine}' is not installed (${registration.package}). Install it with:
|
|
17665
|
+
${registration.installCommand}`,
|
|
17666
|
+
cause
|
|
17667
|
+
);
|
|
17668
|
+
}
|
|
17669
|
+
const AdapterClass = module[registration.className];
|
|
17670
|
+
if (AdapterClass === void 0) {
|
|
17671
|
+
throw new GraphError(
|
|
17672
|
+
`The graph adapter '${registration.className}' is missing from its module for engine '${graphUrl.engine}'.`
|
|
17673
|
+
);
|
|
17674
|
+
}
|
|
17675
|
+
return new AdapterClass(graphUrl, credentials);
|
|
17676
|
+
}
|
|
17677
|
+
/** Build from TINA4_GRAPH_URL (+ TINA4_GRAPH_USERNAME/_PASSWORD). */
|
|
17678
|
+
static async fromEnv(envKey = "TINA4_GRAPH_URL") {
|
|
17679
|
+
const url = (process.env[envKey] ?? "").trim();
|
|
17680
|
+
if (url === "") return null;
|
|
17681
|
+
return _GraphDatabase.create(url, {
|
|
17682
|
+
username: process.env.TINA4_GRAPH_USERNAME,
|
|
17683
|
+
password: process.env.TINA4_GRAPH_PASSWORD
|
|
17684
|
+
});
|
|
17685
|
+
}
|
|
17686
|
+
};
|
|
17687
|
+
}
|
|
17688
|
+
});
|
|
17689
|
+
|
|
16921
17690
|
// ../orm/src/realtime/models/workspace.ts
|
|
16922
17691
|
var Workspace;
|
|
16923
17692
|
var init_workspace = __esm({
|
|
@@ -17476,6 +18245,7 @@ __export(src_exports, {
|
|
|
17476
18245
|
CachedDatabaseAdapter: () => CachedDatabaseAdapter,
|
|
17477
18246
|
Cursor: () => Cursor,
|
|
17478
18247
|
DEFAULT_DATABASE_CONNECT_TIMEOUT_SECONDS: () => DEFAULT_DATABASE_CONNECT_TIMEOUT_SECONDS,
|
|
18248
|
+
DEFAULT_GRAPH_CONNECT_TIMEOUT_SECONDS: () => DEFAULT_GRAPH_CONNECT_TIMEOUT_SECONDS,
|
|
17479
18249
|
DEFAULT_SRID: () => DEFAULT_SRID,
|
|
17480
18250
|
Database: () => Database,
|
|
17481
18251
|
DatabaseResult: () => DatabaseResult,
|
|
@@ -17483,6 +18253,14 @@ __export(src_exports, {
|
|
|
17483
18253
|
DocStoreDriverMissing: () => DocStoreDriverMissing,
|
|
17484
18254
|
FakeData: () => FakeData2,
|
|
17485
18255
|
FirebirdAdapter: () => FirebirdAdapter,
|
|
18256
|
+
GRAPH_CONNECT_TIMEOUT_VARIABLE: () => GRAPH_CONNECT_TIMEOUT_VARIABLE,
|
|
18257
|
+
GraphConnectTimeout: () => GraphConnectTimeout,
|
|
18258
|
+
GraphDatabase: () => GraphDatabase,
|
|
18259
|
+
GraphEdge: () => GraphEdge,
|
|
18260
|
+
GraphError: () => GraphError,
|
|
18261
|
+
GraphNode: () => GraphNode,
|
|
18262
|
+
GraphResult: () => GraphResult,
|
|
18263
|
+
GraphUrl: () => GraphUrl,
|
|
17486
18264
|
InvalidId: () => InvalidId,
|
|
17487
18265
|
LocalStorage: () => LocalStorage,
|
|
17488
18266
|
Migration: () => Migration,
|
|
@@ -17564,6 +18342,7 @@ __export(src_exports, {
|
|
|
17564
18342
|
resetRequestCaches: () => resetRequestCaches,
|
|
17565
18343
|
resolveDbPool: () => resolveDbPool,
|
|
17566
18344
|
resolveFirebirdCharset: () => resolveFirebirdCharset,
|
|
18345
|
+
resolveGraphConnectTimeout: () => resolveGraphConnectTimeout,
|
|
17567
18346
|
rollback: () => rollback,
|
|
17568
18347
|
seedModels: () => seedModels,
|
|
17569
18348
|
seedOrm: () => seedOrm,
|
|
@@ -17613,6 +18392,11 @@ var init_src = __esm({
|
|
|
17613
18392
|
init_firebird();
|
|
17614
18393
|
init_mongodb();
|
|
17615
18394
|
init_odbc();
|
|
18395
|
+
init_graphDatabase();
|
|
18396
|
+
init_graphUrl();
|
|
18397
|
+
init_shapes();
|
|
18398
|
+
init_errors();
|
|
18399
|
+
init_connectTimeout2();
|
|
17616
18400
|
init_realtime2();
|
|
17617
18401
|
}
|
|
17618
18402
|
});
|
|
@@ -21308,7 +22092,7 @@ var init_mongoHandler = __esm({
|
|
|
21308
22092
|
// ../core/src/sessionHandlers/sqlClient.ts
|
|
21309
22093
|
import { createRequire as createRequire7 } from "node:module";
|
|
21310
22094
|
function driverPath(engine) {
|
|
21311
|
-
const packageName =
|
|
22095
|
+
const packageName = DRIVER_PACKAGE4[engine];
|
|
21312
22096
|
try {
|
|
21313
22097
|
return requireFromHere.resolve(packageName);
|
|
21314
22098
|
} catch {
|
|
@@ -21332,14 +22116,14 @@ function sqlCommandSync(target, sql, params = [], label = "Database session") {
|
|
|
21332
22116
|
return [];
|
|
21333
22117
|
}
|
|
21334
22118
|
}
|
|
21335
|
-
var SQL_SESSION_ENGINES, CONNECT_TIMEOUT_MS2,
|
|
22119
|
+
var SQL_SESSION_ENGINES, CONNECT_TIMEOUT_MS2, DRIVER_PACKAGE4, requireFromHere, SQL_WORKER;
|
|
21336
22120
|
var init_sqlClient = __esm({
|
|
21337
22121
|
"../core/src/sessionHandlers/sqlClient.ts"() {
|
|
21338
22122
|
"use strict";
|
|
21339
22123
|
init_syncBridge();
|
|
21340
22124
|
SQL_SESSION_ENGINES = ["sqlite", "postgres", "mysql", "mssql", "firebird"];
|
|
21341
22125
|
CONNECT_TIMEOUT_MS2 = 3e3;
|
|
21342
|
-
|
|
22126
|
+
DRIVER_PACKAGE4 = {
|
|
21343
22127
|
postgres: "pg",
|
|
21344
22128
|
mysql: "mysql2",
|
|
21345
22129
|
mssql: "tedious",
|