@zintrust/redis-rpc 2.4.2 → 2.4.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/README.md CHANGED
@@ -56,6 +56,43 @@ The server and client read these variables:
56
56
  | `REDIS_RPC_RETRY_MAX` | `2` | Client-side retry count used by integrations. |
57
57
  | `REDIS_RPC_RETRY_DELAY_MS` | `500` | Client-side retry delay used by integrations. |
58
58
 
59
+ ### Custom request headers
60
+
61
+ The client supports injecting extra HTTP headers into every outgoing RPC request. This uses the same environment-variable convention as all other ZinTrust proxy adapters (`REDIS_PROXY_HEADERS_*` for the redis-proxy, `MYSQL_PROXY_HEADERS_*` for MySQL, and so on).
62
+
63
+ **Pattern:** `REDIS_RPC_PROXY_HEADERS_{HEADER_NAME}=value`
64
+
65
+ Underscores in `HEADER_NAME` are converted to hyphens to form the actual header name.
66
+
67
+ | Environment variable | HTTP header sent |
68
+ | --- | --- |
69
+ | `REDIS_RPC_PROXY_HEADERS_X_Tenant_Id=abc` | `x-tenant-id: abc` |
70
+ | `REDIS_RPC_PROXY_HEADERS_Authorization=Bearer t` | `authorization: Bearer t` |
71
+ | `REDIS_RPC_PROXY_HEADERS_X_Trace_Id=xyz` | `x-trace-id: xyz` |
72
+ | `REDIS_RPC_PROXY_HEADERS_X_Custom_Header=foo` | `x-custom-header: foo` |
73
+
74
+ These headers are read once when `createRedisRpcClient()` is called and are sent on every request. They are merged after `x-redis-rpc-secret`, so they cannot accidentally overwrite authentication.
75
+
76
+ You can also pass headers directly in code. Programmatic headers take priority over env-sourced ones when a key collides:
77
+
78
+ ```ts
79
+ const client = createRedisRpcClient({
80
+ baseUrl: process.env.REDIS_RPC_URL,
81
+ secret: process.env.REDIS_RPC_SECRET,
82
+ headers: {
83
+ 'x-tenant-id': 'abc',
84
+ 'x-trace-id': '123',
85
+ },
86
+ });
87
+ ```
88
+
89
+ Both sources are combined: `{ ...rpcClientHeaders(), ...options.headers }`. To inspect what headers were auto-detected from env, call the exported helper directly:
90
+
91
+ ```ts
92
+ import { rpcClientHeaders } from '@zintrust/redis-rpc';
93
+ console.log(rpcClientHeaders()); // { 'x-tenant-id': 'abc', ... } or undefined
94
+ ```
95
+
59
96
  Set both `USE_REDIS_PROXY=true` and `REDIS_RPC_URL` to make supported ZinTrust packages select Redis RPC automatically. `USE_REDIS_PROXY=true` by itself does not enable Redis RPC; it only says the process is allowed to use a Redis proxy transport.
60
97
 
61
98
  ## Running the server
package/dist/client.js CHANGED
@@ -2,7 +2,7 @@ import { ErrorFactory, isUndefinedOrNull } from '@zintrust/core/runtime';
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import http from 'node:http';
4
4
  import https from 'node:https';
5
- import { rpcServerOptions } from './env.js';
5
+ import { rpcClientHeaders, rpcServerOptions } from './env.js';
6
6
  const requestJson = (url, body, headers) => {
7
7
  return new Promise((resolve, reject) => {
8
8
  const transport = url.protocol === 'https:' ? https : http;
@@ -48,6 +48,8 @@ export const createRedisRpcClient = (options = {}) => {
48
48
  const settings = rpcServerOptions();
49
49
  const baseUrl = options.baseUrl || `http://${settings.host}:${settings.port}`;
50
50
  const secret = options.secret ?? settings.secret;
51
+ // Env-sourced headers are the baseline; options.headers merges on top (wins on collision).
52
+ const resolvedHeaders = { ...rpcClientHeaders(), ...options.headers };
51
53
  const client = Object.freeze({
52
54
  call: async (service, method, payload = {}) => {
53
55
  const url = new URL('/rpc', baseUrl);
@@ -61,6 +63,7 @@ export const createRedisRpcClient = (options = {}) => {
61
63
  'content-type': 'application/json',
62
64
  connection: 'close',
63
65
  ...(secret ? { 'x-redis-rpc-secret': secret } : {}),
66
+ ...resolvedHeaders,
64
67
  });
65
68
  const parsed = response.body;
66
69
  if (!response.ok || parsed.ok !== true) {
package/dist/env.d.ts CHANGED
@@ -15,3 +15,18 @@ export declare const readString: (key: string, fallback?: string) => string;
15
15
  export declare const readInt: (key: string, fallback: number) => number;
16
16
  export declare const redisConnectionOptions: () => RedisRpcRedisOptions;
17
17
  export declare const rpcServerOptions: () => RedisRpcServerOptions;
18
+ /**
19
+ * Reads custom HTTP headers from environment variables using the same convention
20
+ * as all other ZinTrust proxies (SqlProxyAdapterUtils.parseCustomHeadersFromEnv).
21
+ *
22
+ * Pattern: REDIS_RPC_PROXY_HEADERS_{HEADER_NAME}=value
23
+ * Underscores in HEADER_NAME are converted to hyphens.
24
+ *
25
+ * Examples:
26
+ * REDIS_RPC_PROXY_HEADERS_X_Tenant_Id=abc → x-tenant-id: abc
27
+ * REDIS_RPC_PROXY_HEADERS_Authorization=Bearer t → authorization: Bearer t
28
+ * REDIS_RPC_PROXY_HEADERS_X_Trace_Id=xyz → x-trace-id: xyz
29
+ *
30
+ * Returns undefined when no matching env vars are set (no overhead).
31
+ */
32
+ export declare const rpcClientHeaders: () => Record<string, string> | undefined;
package/dist/env.js CHANGED
@@ -1,9 +1,12 @@
1
- import { isNull } from '@zintrust/core/helper';
2
1
  import { config as loadDotenv } from 'dotenv';
3
2
  loadDotenv({ path: process.env.REDIS_RPC_ENV_FILE || '.env' });
4
3
  export const readString = (key, fallback = '') => {
5
4
  const value = process.env[key];
6
- return typeof value === 'string' && !isNull(value.trim()) ? value.trim() : fallback;
5
+ if (typeof value !== 'string') {
6
+ return fallback;
7
+ }
8
+ const trimmed = value.trim();
9
+ return trimmed === '' ? fallback : trimmed;
7
10
  };
8
11
  export const readInt = (key, fallback) => {
9
12
  const parsed = Number.parseInt(readString(key, String(fallback)), 10);
@@ -22,3 +25,27 @@ export const rpcServerOptions = () => ({
22
25
  secret: readString('REDIS_RPC_SECRET', readString('REDIS_PROXY_SECRET', readString('APP_KEY', ''))),
23
26
  prefix: readString('REDIS_RPC_BULLMQ_PREFIX', readString('BULLMQ_PREFIX', 'bull')),
24
27
  });
28
+ /**
29
+ * Reads custom HTTP headers from environment variables using the same convention
30
+ * as all other ZinTrust proxies (SqlProxyAdapterUtils.parseCustomHeadersFromEnv).
31
+ *
32
+ * Pattern: REDIS_RPC_PROXY_HEADERS_{HEADER_NAME}=value
33
+ * Underscores in HEADER_NAME are converted to hyphens.
34
+ *
35
+ * Examples:
36
+ * REDIS_RPC_PROXY_HEADERS_X_Tenant_Id=abc → x-tenant-id: abc
37
+ * REDIS_RPC_PROXY_HEADERS_Authorization=Bearer t → authorization: Bearer t
38
+ * REDIS_RPC_PROXY_HEADERS_X_Trace_Id=xyz → x-trace-id: xyz
39
+ *
40
+ * Returns undefined when no matching env vars are set (no overhead).
41
+ */
42
+ export const rpcClientHeaders = () => {
43
+ const PREFIX = 'REDIS_RPC_PROXY_HEADERS_';
44
+ const headers = {};
45
+ for (const [key, value] of Object.entries(process.env)) {
46
+ if (key.startsWith(PREFIX) && typeof value === 'string' && value.trim() !== '') {
47
+ headers[key.slice(PREFIX.length).replaceAll('_', '-')] = value.trim();
48
+ }
49
+ }
50
+ return Object.keys(headers).length > 0 ? headers : undefined;
51
+ };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createRedisRpcServer, listenRedisRpcServer } from './server';
2
2
  export { createRedisRpcClient } from './client';
3
+ export { rpcClientHeaders, rpcServerOptions, redisConnectionOptions } from './env';
3
4
  export { createBullMqRpcQueue, createWorkerRpcRuntime, createQueueMonitorRpcDriver, createRedisRpcService, } from './adapters';
4
5
  export { createRedisRpcBackend } from './backend';
5
6
  export type { RpcPayload, RpcRequest, RpcErrorBody, RpcSuccessBody, RedisRpcBackendState, RedisRpcServiceHandler, RedisRpcBackend, CreateRedisRpcBackendOptions, RedisRpcClientOptions, RedisRpcClient, RedisRpcServerInstance, } from './types';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createRedisRpcServer, listenRedisRpcServer } from './server.js';
2
2
  export { createRedisRpcClient } from './client.js';
3
+ export { rpcClientHeaders, rpcServerOptions, redisConnectionOptions } from './env.js';
3
4
  export { createBullMqRpcQueue, createWorkerRpcRuntime, createQueueMonitorRpcDriver, createRedisRpcService, } from './adapters.js';
4
5
  export { createRedisRpcBackend } from './backend.js';
5
6
  /**
package/dist/types.d.ts CHANGED
@@ -49,6 +49,8 @@ export type CreateRedisRpcBackendOptions = Partial<RedisRpcServerOptions> & Read
49
49
  export type RedisRpcClientOptions = Partial<RedisRpcServerOptions> & Readonly<{
50
50
  baseUrl?: string;
51
51
  secret?: string;
52
+ /** Extra HTTP headers merged into every request (same pattern as redis-proxy customHeaders). */
53
+ headers?: Record<string, string>;
52
54
  }>;
53
55
  export type RedisRpcClient = Readonly<{
54
56
  call: <T = unknown>(service: string, method: string, payload?: RpcPayload) => Promise<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/redis-rpc",
3
- "version": "2.4.2",
3
+ "version": "2.4.3",
4
4
  "description": "Redis RPC backend for BullMQ queue operations in ZinTrust.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -1,98 +0,0 @@
1
- {
2
- "name": "@zintrust/redis-rpc",
3
- "version": "2.4.1",
4
- "buildDate": "2026-05-31T11:45:34.243Z",
5
- "buildEnvironment": {
6
- "node": "v22.22.1",
7
- "platform": "darwin",
8
- "arch": "arm64"
9
- },
10
- "git": {
11
- "commit": "e97b7b3d",
12
- "branch": "release"
13
- },
14
- "package": {
15
- "engines": {
16
- "node": ">=20.0.0"
17
- },
18
- "dependencies": [
19
- "@zintrust/core",
20
- "bullmq",
21
- "dotenv",
22
- "ioredis"
23
- ],
24
- "peerDependencies": [
25
- "@zintrust/core"
26
- ]
27
- },
28
- "files": {
29
- "adapters.d.ts": {
30
- "size": 2331,
31
- "sha256": "4080a5f54655beac7aa22f271aae61e03611230abf75491cd269d83278ea07c7"
32
- },
33
- "adapters.js": {
34
- "size": 2817,
35
- "sha256": "f7a732072fa8b1c0a288cdea9e6304f0e884179ed924eb1530a2dbd57e5bb087"
36
- },
37
- "backend.d.ts": {
38
- "size": 183,
39
- "sha256": "c2f1dd71fe2c5a1dc73a7fba855b5e8f8b1700c9f05baeab2c5d9aa8f31f4c60"
40
- },
41
- "backend.js": {
42
- "size": 21160,
43
- "sha256": "85777d42545d97624a0973fccc33b91a0f8e6a6345c940a8581845a4670cce2e"
44
- },
45
- "build-manifest.json": {
46
- "size": 2714,
47
- "sha256": "7b981cbb55c59a29db94c6f110f360299e33e36ed26d54a5f4aef9af54e3a324"
48
- },
49
- "client.d.ts": {
50
- "size": 166,
51
- "sha256": "f58e91ca403a526864cca16eba5caa34a947835d403a20fe9e02e7cdd7ec55ca"
52
- },
53
- "client.js": {
54
- "size": 3528,
55
- "sha256": "79322c1c1265d34a02260f0d51b99e0e549e02978a40208faaf4e6fdf56e92e3"
56
- },
57
- "env.d.ts": {
58
- "size": 575,
59
- "sha256": "640907189918c080ac4bdce3f9a09771ab417ab266d9d5096071ce03e95f36a0"
60
- },
61
- "env.js": {
62
- "size": 1282,
63
- "sha256": "4612b16a360e9a0644718f533c94dd80f2f4e1134c396348cf86814f54387ba7"
64
- },
65
- "errors.d.ts": {
66
- "size": 484,
67
- "sha256": "178c171224b78c62b2347f58922906fa6903cdff27731db14b4f9c88af4e86d1"
68
- },
69
- "errors.js": {
70
- "size": 1202,
71
- "sha256": "eea48bcb9a1fe0f4f065835b9ce517087a5216bd9f78816378c17fac432d7dce"
72
- },
73
- "index.d.ts": {
74
- "size": 775,
75
- "sha256": "69ade1c65e33274c5a4aef0ddddd02a2ad4b8436da40fdb918e352f17a038230"
76
- },
77
- "index.js": {
78
- "size": 745,
79
- "sha256": "554f195a0480b8fddb7778d656aae9d528398b15b1f95748d5ccf77c58884dc4"
80
- },
81
- "server.d.ts": {
82
- "size": 276,
83
- "sha256": "3f9453082da4e8bdef61c904a4e6a8f2c5c24ef6ae8c785ec6671ee57739256c"
84
- },
85
- "server.js": {
86
- "size": 3027,
87
- "sha256": "843b4cb91e438003d474d1f145d30cdc0627f8e099fb90bfe02597eb469be192"
88
- },
89
- "types.d.ts": {
90
- "size": 2348,
91
- "sha256": "90ab4f7122923b219e51cd333688e90a1152def08b6e86891dd066c36f185157"
92
- },
93
- "types.js": {
94
- "size": 11,
95
- "sha256": "8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"
96
- }
97
- }
98
- }