xrootd 1.0.0-beta.1 → 1.0.0-beta.3

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/index.d.mts CHANGED
@@ -393,6 +393,47 @@ declare class File {
393
393
  truncate(size: number): Promise<void>;
394
394
  }
395
395
  //#endregion
396
+ //#region src/config/sec-env.d.ts
397
+ interface SecEnvOptions {
398
+ /** Environment variable source. Defaults to process.env. */
399
+ env?: Record<string, string | undefined>;
400
+ /** Protocol whitelist (equivalent to XrdSecPROTOCOL). */
401
+ protocolFilter?: string[];
402
+ /** Whether to read GSI variables (X509_*, XrdSecGSI*). Defaults to true. */
403
+ gsi?: boolean;
404
+ /** Whether to read SSS variables (XrdSecSSSKT). Defaults to true. */
405
+ sss?: boolean;
406
+ /** Whether to read KRB5 variables (XrdSecKRB5INITTKN). Defaults to true. */
407
+ krb5?: boolean;
408
+ /** Whether to read PWD variables (XrdSecPWDSRVPUK etc). Defaults to true. */
409
+ pwd?: boolean;
410
+ }
411
+ /**
412
+ * xrootd security environment variable configuration.
413
+ *
414
+ * Maps C++ xrootd's XrdSec* / X509_* environment variables to a structured
415
+ * config object. Does NOT read process.env directly — the caller provides
416
+ * the env source via constructor options.
417
+ */
418
+ declare class SecEnv {
419
+ readonly protocolFilter: string[];
420
+ readonly proxyMode: boolean;
421
+ readonly proxyCreds: boolean;
422
+ readonly sssKeytab: string | undefined;
423
+ readonly krb5InitToken: boolean;
424
+ readonly gsiCaDir: string;
425
+ readonly gsiCrlDir: string;
426
+ readonly gsiUserCert: string;
427
+ readonly gsiUserKey: string;
428
+ readonly gsiUserProxy: string;
429
+ readonly pwdServerPubkey: string | undefined;
430
+ readonly username: string | undefined;
431
+ readonly password: string | undefined;
432
+ constructor(options?: SecEnvOptions);
433
+ static fromEnv(env?: Record<string, string | undefined>, options?: Omit<SecEnvOptions, "env">): SecEnv;
434
+ private parseProtocolFilter;
435
+ }
436
+ //#endregion
396
437
  //#region src/client.d.ts
397
438
  interface XRootDClientOptions {
398
439
  credentials?: {
@@ -401,6 +442,8 @@ interface XRootDClientOptions {
401
442
  };
402
443
  timeout?: number;
403
444
  maxRedirects?: number;
445
+ /** Security environment configuration. Enables credential auto-discovery and protocol filtering. */
446
+ secEnv?: SecEnv;
404
447
  }
405
448
  declare class XRootDClient {
406
449
  private readonly url;
@@ -431,6 +474,31 @@ declare class XRootDClient {
431
474
  private ensureFileSystem;
432
475
  }
433
476
  //#endregion
477
+ //#region src/config/loader.d.ts
478
+ interface ResolvedAuthConfig {
479
+ username?: string;
480
+ password?: string;
481
+ sssKey?: Buffer;
482
+ }
483
+ /**
484
+ * Resolve authentication credentials from multiple sources.
485
+ *
486
+ * Priority (high → low):
487
+ * 1. options.credentials (explicit)
488
+ * 2. URL userinfo (root://user:pass@host)
489
+ * 3. SecEnv XrdSecUSER / XrdSecCREDS
490
+ *
491
+ * Also reads the SSS keytab file specified by SecEnv if available.
492
+ */
493
+ declare function loadAuthConfig(options: {
494
+ url?: XRootDUrl;
495
+ credentials?: {
496
+ username: string;
497
+ password?: string;
498
+ };
499
+ secEnv?: SecEnv;
500
+ }): ResolvedAuthConfig;
501
+ //#endregion
434
502
  //#region src/api/filesystem.d.ts
435
503
  declare class FileSystem {
436
504
  private mux;
@@ -659,5 +727,5 @@ declare function putBytes(buf: Buffer, offset: number, data: Uint8Array): number
659
727
  /** Slice `length` bytes from `buf` at `offset`, return `[slice, newOffset]`. */
660
728
  declare function getBytes(buf: Buffer, offset: number, length: number): [Buffer, number];
661
729
  //#endregion
662
- export { type AuthConfig, BODY_SIZE, CRED_TYPE, type ChunkInfo, ClientError, DEFAULT_PORT, type DirectoryEntry, type DirectoryList, DirlistOptions, type ErrorResponse, FHANDLE_SIZE, File, FileSystem, type Frame, Framer, HANDSHAKE_FIFTH, HANDSHAKE_FIRST, HANDSHAKE_FOURTH, HANDSHAKE_SECOND, HANDSHAKE_THIRD, type ITransport, type Location, type LocationInfo, type LoginResponse, Message, Multiplexer, OpenFlags, type OpenOptions, type OpenResponse, PROTOCOL_VERSION, type ProtocolInfo, type ProtocolResponse, REQUEST_HDR_SIZE, REQUEST_OFFSET_BODY, REQUEST_OFFSET_DLEN, REQUEST_OFFSET_REQUEST_ID, REQUEST_OFFSET_STREAM_ID, RESPONSE_HDR_SIZE, RESPONSE_OFFSET_BODY, RESPONSE_OFFSET_DLEN, RESPONSE_OFFSET_STATUS, RESPONSE_OFFSET_STREAM_ID, type RedirectResponse, RequestId, ResponseStatus, SESS_ID_SIZE, S_IFDIR, S_IFLNK, ServerError, type Session, StatFlags, type StatInfo, Transport, type WaitResponse, XRootDClient, type XRootDClientOptions, XRootDError, XRootDUrl, buildCloseRequest, buildHandshakeAndProtocol, buildLoginRequest, buildOpenRequest, buildReadRequest, buildStatRequest, buildWriteRequest, createStatInfo, get16, get32, getBytes, getString, handshake, kXR_ExpBind, kXR_ExpLogin, kXR_ableTLS, kXR_bifreqs, kXR_secreqs, kXR_wantTLS, parseErrorResponse, parseLoginResponse, parseOpenResponse, parseProtocolResponse, parseRedirectResponse, parseWaitResponse, put16, put32, putBytes, putString };
730
+ export { type AuthConfig, BODY_SIZE, CRED_TYPE, type ChunkInfo, ClientError, DEFAULT_PORT, type DirectoryEntry, type DirectoryList, DirlistOptions, type ErrorResponse, FHANDLE_SIZE, File, FileSystem, type Frame, Framer, HANDSHAKE_FIFTH, HANDSHAKE_FIRST, HANDSHAKE_FOURTH, HANDSHAKE_SECOND, HANDSHAKE_THIRD, type ITransport, type Location, type LocationInfo, type LoginResponse, Message, Multiplexer, OpenFlags, type OpenOptions, type OpenResponse, PROTOCOL_VERSION, type ProtocolInfo, type ProtocolResponse, REQUEST_HDR_SIZE, REQUEST_OFFSET_BODY, REQUEST_OFFSET_DLEN, REQUEST_OFFSET_REQUEST_ID, REQUEST_OFFSET_STREAM_ID, RESPONSE_HDR_SIZE, RESPONSE_OFFSET_BODY, RESPONSE_OFFSET_DLEN, RESPONSE_OFFSET_STATUS, RESPONSE_OFFSET_STREAM_ID, type RedirectResponse, RequestId, type ResolvedAuthConfig, ResponseStatus, SESS_ID_SIZE, S_IFDIR, S_IFLNK, SecEnv, type SecEnvOptions, ServerError, type Session, StatFlags, type StatInfo, Transport, type WaitResponse, XRootDClient, type XRootDClientOptions, XRootDError, XRootDUrl, buildCloseRequest, buildHandshakeAndProtocol, buildLoginRequest, buildOpenRequest, buildReadRequest, buildStatRequest, buildWriteRequest, createStatInfo, get16, get32, getBytes, getString, handshake, kXR_ExpBind, kXR_ExpLogin, kXR_ableTLS, kXR_bifreqs, kXR_secreqs, kXR_wantTLS, loadAuthConfig, parseErrorResponse, parseLoginResponse, parseOpenResponse, parseProtocolResponse, parseRedirectResponse, parseWaitResponse, put16, put32, putBytes, putString };
663
731
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,5 +1,8 @@
1
1
  import net from "node:net";
2
2
  import tls from "node:tls";
3
+ import { createCipheriv } from "node:crypto";
4
+ import { readFileSync } from "node:fs";
5
+ import { homedir } from "node:os";
3
6
  //#region src/protocol/constants.ts
4
7
  const RequestId = {
5
8
  Auth: 3e3,
@@ -637,13 +640,15 @@ function buildRmRequest(streamId, path) {
637
640
  function buildMvRequest(streamId, source, target) {
638
641
  const srcBytes = strToBytes(source);
639
642
  const tgtBytes = strToBytes(target);
640
- const msg = new Message(24 + srcBytes.length + tgtBytes.length);
643
+ const spaceSep = new Uint8Array([32]);
644
+ const msg = new Message(24 + srcBytes.length + 1 + tgtBytes.length);
641
645
  msg.writeBytes(streamIdToBytes(streamId));
642
646
  msg.writeInt16BE(RequestId.Mv);
643
647
  msg.writeBytes(/* @__PURE__ */ new Uint8Array(14));
644
648
  msg.writeInt16BE(srcBytes.length & 65535);
645
- msg.writeInt32BE(srcBytes.length + tgtBytes.length);
649
+ msg.writeInt32BE(srcBytes.length + 1 + tgtBytes.length);
646
650
  msg.writeBytes(srcBytes);
651
+ msg.writeBytes(spaceSep);
647
652
  msg.writeBytes(tgtBytes);
648
653
  return msg.getBuffer();
649
654
  }
@@ -1189,19 +1194,21 @@ const authProtocols = /* @__PURE__ */ new Map();
1189
1194
  function registerAuthProtocol(name, factory) {
1190
1195
  authProtocols.set(name, factory);
1191
1196
  }
1192
- async function doAuthentication(mux, secReqs, params) {
1197
+ async function doAuthentication(mux, secReqs, params, options) {
1193
1198
  if (!secReqs || secReqs.trim().length === 0) return {
1194
1199
  prot: "",
1195
1200
  uid: 0,
1196
1201
  gid: 0
1197
1202
  };
1198
1203
  const supportedProtocols = secReqs.split(",").map((s) => s.trim());
1199
- for (const protoName of supportedProtocols) {
1204
+ const filter = options?.protocolFilter;
1205
+ const candidates = filter?.length ? supportedProtocols.filter((p) => filter.includes(p)) : supportedProtocols;
1206
+ for (const protoName of candidates) {
1200
1207
  const factory = authProtocols.get(protoName);
1201
1208
  if (!factory) continue;
1202
1209
  return await executeAuth(mux, factory(), params);
1203
1210
  }
1204
- throw new XRootDError(ServerError.AuthFailed, `No supported authentication protocol. Server requires: ${secReqs}`);
1211
+ throw new XRootDError(ServerError.AuthFailed, `No supported authentication protocol. Server requires: ${secReqs}` + (filter ? `. Allowed: ${filter.join(",")}` : ""));
1205
1212
  }
1206
1213
  async function executeAuth(mux, protocol, params) {
1207
1214
  const creds = await protocol.getCredentials(params);
@@ -1254,6 +1261,79 @@ var HostAuth = class {
1254
1261
  }
1255
1262
  };
1256
1263
  //#endregion
1264
+ //#region src/utils/crc32.ts
1265
+ function crc32(data) {
1266
+ let crc = 4294967295;
1267
+ for (let i = 0; i < data.length; i++) {
1268
+ crc ^= data[i];
1269
+ for (let j = 0; j < 8; j++) crc = crc >>> 1 ^ (crc & 1 ? 3988292384 : 0);
1270
+ }
1271
+ return (crc ^ 4294967295) >>> 0;
1272
+ }
1273
+ //#endregion
1274
+ //#region src/security/sss.ts
1275
+ function pkcs5Pad(data, blockSize) {
1276
+ const padLen = blockSize - data.length % blockSize;
1277
+ const padded = Buffer.alloc(data.length + padLen);
1278
+ data.copy(padded);
1279
+ padded.fill(padLen, data.length);
1280
+ return padded;
1281
+ }
1282
+ /**
1283
+ * SSS (Simple Shared Secret) authentication protocol.
1284
+ *
1285
+ * Uses Blowfish-ECB encryption + CRC32 checksum.
1286
+ * Note: Requires Node.js with legacy OpenSSL provider for Blowfish support.
1287
+ * Run with: NODE_OPTIONS=--openssl-legacy-provider
1288
+ *
1289
+ * Or use the static create() method which checks if Blowfish is available.
1290
+ */
1291
+ var SSSAuth = class {
1292
+ name = "sss";
1293
+ entity = {
1294
+ prot: "sss",
1295
+ uid: 0,
1296
+ gid: 0
1297
+ };
1298
+ complete = false;
1299
+ key;
1300
+ constructor(key) {
1301
+ if (key.length !== 8) throw new Error("SSS key must be 8 bytes");
1302
+ this.key = key;
1303
+ }
1304
+ static isSupported() {
1305
+ try {
1306
+ createCipheriv("bf-ecb", Buffer.alloc(8), null).final();
1307
+ return true;
1308
+ } catch {
1309
+ return false;
1310
+ }
1311
+ }
1312
+ async getCredentials(params) {
1313
+ const password = params.password || "";
1314
+ const passwordBytes = new TextEncoder().encode(password);
1315
+ const crc = crc32(passwordBytes);
1316
+ const payload = Buffer.alloc(passwordBytes.length + 4);
1317
+ Buffer.from(passwordBytes).copy(payload, 0);
1318
+ payload.writeUInt32BE(crc, passwordBytes.length);
1319
+ const cipher = createCipheriv("bf-ecb", this.key, null);
1320
+ const padded = pkcs5Pad(payload, 8);
1321
+ const encrypted = Buffer.concat([cipher.update(padded), cipher.final()]);
1322
+ this.entity.name = params.username;
1323
+ return new Uint8Array(encrypted);
1324
+ }
1325
+ async processChallenge(_challenge) {
1326
+ this.complete = true;
1327
+ return /* @__PURE__ */ new Uint8Array(0);
1328
+ }
1329
+ isComplete() {
1330
+ return this.complete;
1331
+ }
1332
+ getEntity() {
1333
+ return this.entity;
1334
+ }
1335
+ };
1336
+ //#endregion
1257
1337
  //#region src/api/types.ts
1258
1338
  const StatFlags = {
1259
1339
  XBitSet: 1,
@@ -1383,7 +1463,7 @@ var File = class {
1383
1463
  const { errnum, errmsg } = parseErrorResponse(frame.body);
1384
1464
  throw new XRootDError(errnum, errmsg);
1385
1465
  }
1386
- if (frame.status === ResponseStatus.Ok) return new Uint8Array(frame.body);
1466
+ if (frame.status === ResponseStatus.Ok || frame.status === ResponseStatus.Oksofar) return new Uint8Array(frame.body);
1387
1467
  throw new XRootDError(ServerError.ServerError, `Unexpected read response status: ${frame.status}`);
1388
1468
  }
1389
1469
  async write(offset, data) {
@@ -1394,7 +1474,7 @@ var File = class {
1394
1474
  const { errnum, errmsg } = parseErrorResponse(frame.body);
1395
1475
  throw new XRootDError(errnum, errmsg);
1396
1476
  }
1397
- if (frame.status === ResponseStatus.Ok) return frame.dlen;
1477
+ if (frame.status === ResponseStatus.Ok) return frame.dlen > 0 ? frame.dlen : data.length;
1398
1478
  throw new XRootDError(ServerError.ServerError, `Unexpected write response status: ${frame.status}`);
1399
1479
  }
1400
1480
  async close() {
@@ -1492,6 +1572,32 @@ var FileSystem = class {
1492
1572
  }
1493
1573
  };
1494
1574
  //#endregion
1575
+ //#region src/config/loader.ts
1576
+ /**
1577
+ * Resolve authentication credentials from multiple sources.
1578
+ *
1579
+ * Priority (high → low):
1580
+ * 1. options.credentials (explicit)
1581
+ * 2. URL userinfo (root://user:pass@host)
1582
+ * 3. SecEnv XrdSecUSER / XrdSecCREDS
1583
+ *
1584
+ * Also reads the SSS keytab file specified by SecEnv if available.
1585
+ */
1586
+ function loadAuthConfig(options) {
1587
+ const { url, credentials, secEnv } = options;
1588
+ const username = credentials?.username ?? url?.user ?? secEnv?.username;
1589
+ const password = credentials?.password ?? url?.password ?? secEnv?.password;
1590
+ let sssKey;
1591
+ if (secEnv?.sssKeytab) try {
1592
+ sssKey = readFileSync(secEnv.sssKeytab);
1593
+ } catch {}
1594
+ return {
1595
+ username,
1596
+ password,
1597
+ sssKey
1598
+ };
1599
+ }
1600
+ //#endregion
1495
1601
  //#region src/client.ts
1496
1602
  var XRootDClient = class {
1497
1603
  url;
@@ -1516,15 +1622,22 @@ var XRootDClient = class {
1516
1622
  });
1517
1623
  if (this.options.timeout) this.mux.setTimeout(this.options.timeout);
1518
1624
  this.session = await handshake(this.mux, url, { username: this.options.credentials?.username });
1625
+ const secEnv = this.options.secEnv;
1626
+ const authConfig = loadAuthConfig({
1627
+ url,
1628
+ credentials: this.options.credentials,
1629
+ secEnv
1630
+ });
1519
1631
  registerAuthProtocol("host", () => new HostAuth());
1520
- if (this.session.secReqs && this.options.credentials) {
1632
+ if (authConfig.sssKey && SSSAuth.isSupported()) registerAuthProtocol("sss", () => new SSSAuth(authConfig.sssKey));
1633
+ if (this.session.secReqs && (authConfig.username || authConfig.password)) {
1521
1634
  const secEntity = await doAuthentication(this.mux, this.session.secReqs, {
1522
1635
  host: url.host,
1523
1636
  port: url.port,
1524
- username: this.options.credentials.username,
1525
- password: this.options.credentials.password,
1637
+ username: authConfig.username,
1638
+ password: authConfig.password,
1526
1639
  sessid: this.session.sessid
1527
- });
1640
+ }, { protocolFilter: secEnv?.protocolFilter });
1528
1641
  this.session.secEntity = secEntity;
1529
1642
  }
1530
1643
  this.fs = new FileSystem(this.mux);
@@ -1611,6 +1724,69 @@ var XRootDClient = class {
1611
1724
  }
1612
1725
  };
1613
1726
  //#endregion
1614
- export { BODY_SIZE, CRED_TYPE, ClientError, DEFAULT_PORT, DirlistOptions, FHANDLE_SIZE, File, FileSystem, Framer, HANDSHAKE_FIFTH, HANDSHAKE_FIRST, HANDSHAKE_FOURTH, HANDSHAKE_SECOND, HANDSHAKE_THIRD, Message, Multiplexer, OpenFlags, PROTOCOL_VERSION, REQUEST_HDR_SIZE, REQUEST_OFFSET_BODY, REQUEST_OFFSET_DLEN, REQUEST_OFFSET_REQUEST_ID, REQUEST_OFFSET_STREAM_ID, RESPONSE_HDR_SIZE, RESPONSE_OFFSET_BODY, RESPONSE_OFFSET_DLEN, RESPONSE_OFFSET_STATUS, RESPONSE_OFFSET_STREAM_ID, RequestId, ResponseStatus, SESS_ID_SIZE, S_IFDIR, S_IFLNK, ServerError, StatFlags, Transport, XRootDClient, XRootDError, XRootDUrl, buildCloseRequest, buildHandshakeAndProtocol, buildLoginRequest, buildOpenRequest, buildReadRequest, buildStatRequest, buildWriteRequest, createStatInfo, get16, get32, getBytes, getString, handshake, kXR_ExpBind, kXR_ExpLogin, kXR_ableTLS, kXR_bifreqs, kXR_secreqs, kXR_wantTLS, parseErrorResponse, parseLoginResponse, parseOpenResponse, parseProtocolResponse, parseRedirectResponse, parseWaitResponse, put16, put32, putBytes, putString };
1727
+ //#region src/config/sec-env.ts
1728
+ /**
1729
+ * xrootd security environment variable configuration.
1730
+ *
1731
+ * Maps C++ xrootd's XrdSec* / X509_* environment variables to a structured
1732
+ * config object. Does NOT read process.env directly — the caller provides
1733
+ * the env source via constructor options.
1734
+ */
1735
+ var SecEnv = class SecEnv {
1736
+ protocolFilter;
1737
+ proxyMode;
1738
+ proxyCreds;
1739
+ sssKeytab;
1740
+ krb5InitToken;
1741
+ gsiCaDir;
1742
+ gsiCrlDir;
1743
+ gsiUserCert;
1744
+ gsiUserKey;
1745
+ gsiUserProxy;
1746
+ pwdServerPubkey;
1747
+ username;
1748
+ password;
1749
+ constructor(options = {}) {
1750
+ const env = options.env ?? process.env;
1751
+ this.protocolFilter = options.protocolFilter ?? this.parseProtocolFilter(env);
1752
+ this.proxyMode = truthy(env["XrdSecPROXY"]);
1753
+ this.proxyCreds = truthy(env["XrdSecPROXYCREDS"]);
1754
+ this.sssKeytab = options.sss !== false ? env["XrdSecSSSKT"] ?? env["XrdSecsssKT"] : void 0;
1755
+ this.krb5InitToken = options.krb5 !== false ? truthy(env["XrdSecKRB5INITTKN"]) : false;
1756
+ if (options.gsi !== false) {
1757
+ const home = homedir();
1758
+ this.gsiCaDir = env["XrdSecGSICADIR"] ?? env["X509_CERT_DIR"] ?? "/etc/grid-security/certificates";
1759
+ this.gsiCrlDir = env["XrdSecGSICRLDIR"] ?? env["X509_CERT_DIR"] ?? "/etc/grid-security/certificates";
1760
+ this.gsiUserCert = env["XrdSecGSIUSERCERT"] ?? env["X509_USER_CERT"] ?? `${home}/.globus/usercert.pem`;
1761
+ this.gsiUserKey = env["XrdSecGSIUSERKEY"] ?? env["X509_USER_KEY"] ?? `${home}/.globus/userkey.pem`;
1762
+ this.gsiUserProxy = env["XrdSecGSIUSERPROXY"] ?? env["X509_USER_PROXY"] ?? `/tmp/x509up_u${process.getuid?.() ?? 0}`;
1763
+ } else {
1764
+ this.gsiCaDir = "";
1765
+ this.gsiCrlDir = "";
1766
+ this.gsiUserCert = "";
1767
+ this.gsiUserKey = "";
1768
+ this.gsiUserProxy = "";
1769
+ }
1770
+ this.pwdServerPubkey = options.pwd !== false ? env["XrdSecPWDSRVPUK"] : void 0;
1771
+ this.username = env["XrdSecUSER"];
1772
+ this.password = env["XrdSecCREDS"];
1773
+ }
1774
+ static fromEnv(env, options) {
1775
+ return new SecEnv({
1776
+ ...options,
1777
+ env: env ?? process.env
1778
+ });
1779
+ }
1780
+ parseProtocolFilter(env) {
1781
+ const raw = env["XrdSecPROTOCOL"];
1782
+ if (!raw) return [];
1783
+ return raw.split(",").map((s) => s.trim()).filter(Boolean);
1784
+ }
1785
+ };
1786
+ function truthy(val) {
1787
+ return val !== void 0 && val !== "0" && val !== "";
1788
+ }
1789
+ //#endregion
1790
+ export { BODY_SIZE, CRED_TYPE, ClientError, DEFAULT_PORT, DirlistOptions, FHANDLE_SIZE, File, FileSystem, Framer, HANDSHAKE_FIFTH, HANDSHAKE_FIRST, HANDSHAKE_FOURTH, HANDSHAKE_SECOND, HANDSHAKE_THIRD, Message, Multiplexer, OpenFlags, PROTOCOL_VERSION, REQUEST_HDR_SIZE, REQUEST_OFFSET_BODY, REQUEST_OFFSET_DLEN, REQUEST_OFFSET_REQUEST_ID, REQUEST_OFFSET_STREAM_ID, RESPONSE_HDR_SIZE, RESPONSE_OFFSET_BODY, RESPONSE_OFFSET_DLEN, RESPONSE_OFFSET_STATUS, RESPONSE_OFFSET_STREAM_ID, RequestId, ResponseStatus, SESS_ID_SIZE, S_IFDIR, S_IFLNK, SecEnv, ServerError, StatFlags, Transport, XRootDClient, XRootDError, XRootDUrl, buildCloseRequest, buildHandshakeAndProtocol, buildLoginRequest, buildOpenRequest, buildReadRequest, buildStatRequest, buildWriteRequest, createStatInfo, get16, get32, getBytes, getString, handshake, kXR_ExpBind, kXR_ExpLogin, kXR_ableTLS, kXR_bifreqs, kXR_secreqs, kXR_wantTLS, loadAuthConfig, parseErrorResponse, parseLoginResponse, parseOpenResponse, parseProtocolResponse, parseRedirectResponse, parseWaitResponse, put16, put32, putBytes, putString };
1615
1791
 
1616
1792
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xrootd",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.3",
4
4
  "description": "A TypeScript client library for the XRootD protocol",
5
5
  "main": "dist/index.mjs",
6
6
  "types": "dist/index.d.mts",
@@ -11,7 +11,6 @@
11
11
  }
12
12
  },
13
13
  "scripts": {
14
- "preinstall": "npx only-allow pnpm",
15
14
  "build": "tsdown",
16
15
  "dev": "tsdown --watch",
17
16
  "typecheck": "tsc --noEmit",