@forwardimpact/librpc 0.1.102 → 0.1.104
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/bin/fit-unary.js +16 -10
- package/package.json +1 -1
- package/src/base.js +6 -2
- package/src/server.js +13 -5
package/bin/fit-unary.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "@forwardimpact/libpreflight/node22";
|
|
3
3
|
|
|
4
|
-
import { readFileSync } from "node:fs";
|
|
5
4
|
import { createCli } from "@forwardimpact/libcli";
|
|
6
5
|
import { createClient, createTracer } from "@forwardimpact/librpc";
|
|
7
6
|
import { createLogger } from "@forwardimpact/libtelemetry";
|
|
7
|
+
import { createDefaultRuntime } from "@forwardimpact/libutil/runtime";
|
|
8
|
+
|
|
9
|
+
const runtime = createDefaultRuntime();
|
|
8
10
|
|
|
9
11
|
// `bun build --compile` injects FIT_UNARY_VERSION via --define, eliminating
|
|
10
12
|
// the readFileSync branch in the compiled binary (which would ENOENT against
|
|
11
13
|
// the bunfs virtual mount). Source execution falls through to package.json.
|
|
12
14
|
const VERSION =
|
|
13
|
-
|
|
14
|
-
JSON.parse(
|
|
15
|
-
.
|
|
15
|
+
runtime.proc.env.FIT_UNARY_VERSION ||
|
|
16
|
+
JSON.parse(
|
|
17
|
+
runtime.fsSync.readFileSync(
|
|
18
|
+
new URL("../package.json", import.meta.url),
|
|
19
|
+
"utf8",
|
|
20
|
+
),
|
|
21
|
+
).version;
|
|
16
22
|
|
|
17
23
|
const definition = {
|
|
18
24
|
name: "fit-unary",
|
|
@@ -27,7 +33,7 @@ const definition = {
|
|
|
27
33
|
examples: ['fit-unary memory GetWindow \'{"resource_id":"..."}\''],
|
|
28
34
|
};
|
|
29
35
|
|
|
30
|
-
const cli = createCli(definition);
|
|
36
|
+
const cli = createCli(definition, { runtime });
|
|
31
37
|
const logger = createLogger("cli");
|
|
32
38
|
|
|
33
39
|
/**
|
|
@@ -35,13 +41,13 @@ const logger = createLogger("cli");
|
|
|
35
41
|
* @returns {Promise<void>}
|
|
36
42
|
*/
|
|
37
43
|
async function main() {
|
|
38
|
-
const parsed = cli.parse(
|
|
39
|
-
if (!parsed)
|
|
44
|
+
const parsed = cli.parse(runtime.proc.argv.slice(2));
|
|
45
|
+
if (!parsed) return runtime.proc.exit(0);
|
|
40
46
|
|
|
41
47
|
const [service, method, requestJson] = parsed.positionals;
|
|
42
48
|
if (!service || !method) {
|
|
43
49
|
cli.usageError("expected arguments: <service> <method> [json-request]");
|
|
44
|
-
|
|
50
|
+
return runtime.proc.exit(2);
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
const request = requestJson ? JSON.parse(requestJson) : {};
|
|
@@ -49,11 +55,11 @@ async function main() {
|
|
|
49
55
|
const client = await createClient(service, logger, tracer);
|
|
50
56
|
|
|
51
57
|
const response = await client.callUnary(method, request);
|
|
52
|
-
|
|
58
|
+
runtime.proc.stdout.write(JSON.stringify(response, null, 2) + "\n");
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
main().catch((error) => {
|
|
56
62
|
logger.exception("main", error);
|
|
57
63
|
cli.error(error.message);
|
|
58
|
-
|
|
64
|
+
runtime.proc.exit(1);
|
|
59
65
|
});
|
package/package.json
CHANGED
package/src/base.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import grpc from "@grpc/grpc-js";
|
|
2
2
|
|
|
3
3
|
import { createObserver } from "@forwardimpact/libtelemetry";
|
|
4
|
+
import { createDefaultProc } from "@forwardimpact/libutil/runtime";
|
|
4
5
|
|
|
5
6
|
import { Interceptor, HmacAuth } from "./auth.js";
|
|
6
7
|
import { definitions } from "./generated/definitions/exports.js";
|
|
@@ -23,12 +24,15 @@ export function createGrpc() {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
|
-
* Default auth factory that creates authentication interceptor
|
|
27
|
+
* Default auth factory that creates authentication interceptor.
|
|
28
|
+
* Reads `SERVICE_SECRET` through `createDefaultProc().env` (a late-binding
|
|
29
|
+
* Proxy over `process.env`) rather than touching the `process` global
|
|
30
|
+
* directly — same read semantics as before, no ambient-dep smell.
|
|
27
31
|
* @param {string} serviceName - Name of the service for the interceptor
|
|
28
32
|
* @returns {Interceptor} Configured interceptor instance
|
|
29
33
|
*/
|
|
30
34
|
export function createAuth(serviceName) {
|
|
31
|
-
const secret =
|
|
35
|
+
const secret = createDefaultProc().env.SERVICE_SECRET;
|
|
32
36
|
if (!secret) {
|
|
33
37
|
throw new Error(
|
|
34
38
|
`SERVICE_SECRET environment variable is required for service ${serviceName}`,
|
package/src/server.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
capitalizeFirstLetter,
|
|
7
7
|
} from "./base.js";
|
|
8
8
|
import { healthDefinition, createHealthHandlers } from "./health.js";
|
|
9
|
+
import { createDefaultRuntime } from "@forwardimpact/libutil/runtime";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* gRPC Server class using pre-compiled service definitions
|
|
@@ -14,6 +15,7 @@ import { healthDefinition, createHealthHandlers } from "./health.js";
|
|
|
14
15
|
export class Server extends Rpc {
|
|
15
16
|
#server;
|
|
16
17
|
#service;
|
|
18
|
+
#runtime;
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Creates a gRPC server for a service
|
|
@@ -24,6 +26,8 @@ export class Server extends Rpc {
|
|
|
24
26
|
* @param {(serviceName: string, logger: object, tracer: object) => object} observerFn - Observer factory
|
|
25
27
|
* @param {() => {grpc: object}} grpcFn - gRPC factory
|
|
26
28
|
* @param {(serviceName: string) => object} authFn - Auth factory
|
|
29
|
+
* @param {import("@forwardimpact/libutil/runtime").Runtime} [runtime] - Optional runtime bag;
|
|
30
|
+
* falls back to `createDefaultRuntime()` so existing service callers keep working.
|
|
27
31
|
*/
|
|
28
32
|
constructor(
|
|
29
33
|
service,
|
|
@@ -33,11 +37,13 @@ export class Server extends Rpc {
|
|
|
33
37
|
observerFn = createObserver,
|
|
34
38
|
grpcFn = createGrpc,
|
|
35
39
|
authFn = createAuth,
|
|
40
|
+
runtime = null,
|
|
36
41
|
) {
|
|
37
42
|
if (!service) throw new Error("service is required");
|
|
38
43
|
|
|
39
44
|
super(config, logger, tracer, observerFn, grpcFn, authFn);
|
|
40
45
|
this.#service = service;
|
|
46
|
+
this.#runtime = runtime ?? createDefaultRuntime();
|
|
41
47
|
}
|
|
42
48
|
|
|
43
49
|
/** Starts the gRPC server */
|
|
@@ -170,10 +176,11 @@ export class Server extends Rpc {
|
|
|
170
176
|
);
|
|
171
177
|
callback(null, response);
|
|
172
178
|
} catch (error) {
|
|
173
|
-
|
|
174
|
-
code
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
const code =
|
|
180
|
+
typeof error?.code === "number"
|
|
181
|
+
? error.code
|
|
182
|
+
: this.grpc().status.INTERNAL;
|
|
183
|
+
callback({ code, message: error?.message || String(error) });
|
|
177
184
|
}
|
|
178
185
|
};
|
|
179
186
|
}
|
|
@@ -203,6 +210,7 @@ export class Server extends Rpc {
|
|
|
203
210
|
|
|
204
211
|
/** Sets up graceful shutdown handlers */
|
|
205
212
|
#setupShutdown() {
|
|
213
|
+
const runtime = this.#runtime;
|
|
206
214
|
const shutdown = async () => {
|
|
207
215
|
this.observer().logger()?.info("Server", "Shutting down...");
|
|
208
216
|
|
|
@@ -211,7 +219,7 @@ export class Server extends Rpc {
|
|
|
211
219
|
await this.#service.shutdown();
|
|
212
220
|
}
|
|
213
221
|
|
|
214
|
-
this.#server.tryShutdown(() =>
|
|
222
|
+
this.#server.tryShutdown(() => runtime.proc.exit(0));
|
|
215
223
|
};
|
|
216
224
|
process.on("SIGINT", shutdown);
|
|
217
225
|
process.on("SIGTERM", shutdown);
|