tina4-nodejs 3.12.0 → 3.12.2
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
CHANGED
package/package.json
CHANGED
|
@@ -23,6 +23,66 @@ function requireFirebird(): any {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// Detects a Windows drive-letter prefix like "C:/" or "C:\". The leading-slash
|
|
27
|
+
// variant ("/C:/...") shows up after URL parsing strips one slash off
|
|
28
|
+
// "firebird://host:port/C:/...".
|
|
29
|
+
const WIN_DRIVE_RE = /^\/?[A-Za-z]:[/\\]/;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Turn a URL path component into a Firebird database identifier.
|
|
33
|
+
*
|
|
34
|
+
* Firebird is the awkward one — it needs either an absolute file path on the
|
|
35
|
+
* server, a Windows drive-letter path, or an alias name. The classic URI form
|
|
36
|
+
* uses a double-slash to keep the leading "/" of an absolute path through
|
|
37
|
+
* URL parsing:
|
|
38
|
+
*
|
|
39
|
+
* firebird://host:port//firebird/data/app.fdb -> /firebird/data/app.fdb
|
|
40
|
+
*
|
|
41
|
+
* But that double slash is unintuitive to anyone used to the way
|
|
42
|
+
* postgres / mysql / mssql encode the database name. We accept five
|
|
43
|
+
* equivalent forms and normalise all of them:
|
|
44
|
+
*
|
|
45
|
+
* - `//abs/path/db.fdb` -> `/abs/path/db.fdb` (classic double-slash)
|
|
46
|
+
* - `/abs/path/db.fdb` -> `/abs/path/db.fdb` (single-slash, what most people type)
|
|
47
|
+
* - `/C:/Data/db.fdb` -> `C:/Data/db.fdb` (Windows, leading URL slash dropped)
|
|
48
|
+
* - `/C%3A/Data/db.fdb` -> `C:/Data/db.fdb` (Windows with URL-encoded colon)
|
|
49
|
+
* - `/employee` -> `employee` (alias — single token)
|
|
50
|
+
*
|
|
51
|
+
* Aliases are detected as the leftover case: a single token with no
|
|
52
|
+
* slashes. Anything path-like is kept as a path.
|
|
53
|
+
*/
|
|
54
|
+
export function normalizeFirebirdDbIdentifier(rawPath: string): string {
|
|
55
|
+
let decoded = decodeURIComponent(rawPath);
|
|
56
|
+
|
|
57
|
+
// Classic double-slash form: //abs/path -> /abs/path
|
|
58
|
+
if (decoded.startsWith("//")) {
|
|
59
|
+
decoded = decoded.slice(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Windows drive-letter — drop the URL-introduced leading slash.
|
|
63
|
+
// /C:/Data/db.fdb -> C:/Data/db.fdb
|
|
64
|
+
if (WIN_DRIVE_RE.test(decoded)) {
|
|
65
|
+
if (decoded.startsWith("/")) {
|
|
66
|
+
decoded = decoded.slice(1);
|
|
67
|
+
}
|
|
68
|
+
return decoded;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Look at the content after stripping the leading slash. If it's a single
|
|
72
|
+
// token with no separators, it's a Firebird alias — return WITHOUT the
|
|
73
|
+
// leading slash (the alias name itself is the identifier).
|
|
74
|
+
const body = decoded.startsWith("/") ? decoded.slice(1) : decoded;
|
|
75
|
+
if (body && !body.includes("/") && !body.includes("\\")) {
|
|
76
|
+
return body;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Otherwise it's a file path. If it already has a leading slash, keep it.
|
|
80
|
+
// If it's a relative-looking path (slash-separated but no leading "/")
|
|
81
|
+
// promote it to absolute — Firebird needs absolute paths and we don't know
|
|
82
|
+
// the server's CWD anyway.
|
|
83
|
+
return decoded.startsWith("/") ? decoded : "/" + decoded;
|
|
84
|
+
}
|
|
85
|
+
|
|
26
86
|
export interface FirebirdConfig {
|
|
27
87
|
host?: string;
|
|
28
88
|
port?: number;
|
|
@@ -69,6 +129,21 @@ export class FirebirdAdapter implements DatabaseAdapter {
|
|
|
69
129
|
};
|
|
70
130
|
}
|
|
71
131
|
|
|
132
|
+
// Firebird database identifier resolution — two layers:
|
|
133
|
+
//
|
|
134
|
+
// 1. `TINA4_DATABASE_FIREBIRD_PATH` env override wins if set. Useful for
|
|
135
|
+
// Windows users with raw backslash paths (no URL encoding required)
|
|
136
|
+
// and for ops setups that keep server URL and DB location in separate
|
|
137
|
+
// config layers.
|
|
138
|
+
// 2. Otherwise normalise whatever the URL or config supplied — accepts
|
|
139
|
+
// every sensible variant (single/double slash, drive letter, alias).
|
|
140
|
+
const envOverride = process.env.TINA4_DATABASE_FIREBIRD_PATH;
|
|
141
|
+
if (envOverride && envOverride.length > 0) {
|
|
142
|
+
fbConfig.database = envOverride;
|
|
143
|
+
} else if (typeof fbConfig.database === "string" && fbConfig.database.length > 0) {
|
|
144
|
+
fbConfig.database = normalizeFirebirdDbIdentifier(fbConfig.database);
|
|
145
|
+
}
|
|
146
|
+
|
|
72
147
|
await new Promise<void>((resolve, reject) => {
|
|
73
148
|
fb.attach(fbConfig, (err: Error | null, db: any) => {
|
|
74
149
|
if (err) reject(err);
|
|
@@ -82,6 +157,8 @@ export class FirebirdAdapter implements DatabaseAdapter {
|
|
|
82
157
|
|
|
83
158
|
private parseUrl(url: string): { host?: string; port?: number; user?: string; password?: string; database?: string } {
|
|
84
159
|
// firebird://user:pass@host:port/path/to/db.fdb
|
|
160
|
+
// The path part after the host is normalised by normalizeFirebirdDbIdentifier()
|
|
161
|
+
// in connect(); here we just preserve it (with the leading "/" the regex strips).
|
|
85
162
|
const match = url.match(/firebird:\/\/(?:([^:]+):([^@]+)@)?([^:/]+)(?::(\d+))?\/(.*)/);
|
|
86
163
|
if (match) {
|
|
87
164
|
return {
|
|
@@ -54,7 +54,7 @@ export { MysqlAdapter } from "./adapters/mysql.js";
|
|
|
54
54
|
export type { MysqlConfig } from "./adapters/mysql.js";
|
|
55
55
|
export { MssqlAdapter } from "./adapters/mssql.js";
|
|
56
56
|
export type { MssqlConfig } from "./adapters/mssql.js";
|
|
57
|
-
export { FirebirdAdapter } from "./adapters/firebird.js";
|
|
57
|
+
export { FirebirdAdapter, normalizeFirebirdDbIdentifier } from "./adapters/firebird.js";
|
|
58
58
|
export type { FirebirdConfig } from "./adapters/firebird.js";
|
|
59
59
|
export { MongodbAdapter } from "./adapters/mongodb.js";
|
|
60
60
|
export type { MongoConfig } from "./adapters/mongodb.js";
|