@zudojs/rpc 0.1.0 → 1.1.0
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/LICENSE +21 -0
- package/README.md +104 -12
- package/dist/index.d.ts +8 -4
- package/dist/index.js +3 -4
- package/dist/rpc/client/index.d.ts +1 -1
- package/dist/rpc/client/rpcClient.core.d.ts +57 -3
- package/dist/rpc/client/rpcClient.core.js +189 -32
- package/dist/rpc/constants/index.d.ts +1 -1
- package/dist/rpc/constants/index.js +1 -1
- package/dist/rpc/constants/rpcConstants.core.d.ts +18 -0
- package/dist/rpc/constants/rpcConstants.core.js +18 -0
- package/dist/rpc/context/rpcContext.type.js +3 -1
- package/dist/rpc/dispatcher/index.d.ts +1 -0
- package/dist/rpc/dispatcher/rpcDispatcher.core.d.ts +49 -2
- package/dist/rpc/dispatcher/rpcDispatcher.core.js +109 -14
- package/dist/rpc/middleware/rpcMiddleware.core.d.ts +12 -0
- package/dist/rpc/middleware/rpcMiddleware.core.js +29 -6
- package/dist/rpc/procedure/rpcProcedure.type.d.ts +25 -3
- package/dist/rpc/procedure/rpcProcedure.type.js +9 -0
- package/dist/rpc/procedure/rpcProcedureRegistry.core.d.ts +15 -1
- package/dist/rpc/procedure/rpcProcedureRegistry.core.js +26 -1
- package/dist/rpc/procedure/rpcProcedureRouter.core.d.ts +1 -1
- package/dist/rpc/procedure/rpcProcedureRouter.core.js +5 -0
- package/dist/rpc/reliability/cancellation/rpcCancellation.helper.d.ts +30 -3
- package/dist/rpc/reliability/cancellation/rpcCancellation.helper.js +60 -4
- package/dist/rpc/reliability/deadline/rpcDeadline.helper.d.ts +14 -1
- package/dist/rpc/reliability/deadline/rpcDeadline.helper.js +23 -2
- package/dist/rpc/reliability/index.d.ts +5 -4
- package/dist/rpc/reliability/index.js +3 -3
- package/dist/rpc/reliability/retry/rpcRetry.helper.d.ts +22 -0
- package/dist/rpc/reliability/retry/rpcRetry.helper.js +80 -8
- package/dist/rpc/reliability/timeout/rpcTimeout.helper.d.ts +18 -2
- package/dist/rpc/reliability/timeout/rpcTimeout.helper.js +71 -7
- package/dist/rpc/server/index.d.ts +1 -0
- package/dist/rpc/server/rpcServer.core.d.ts +41 -2
- package/dist/rpc/server/rpcServer.core.js +117 -16
- package/dist/rpc/streaming/rpcStreaming.type.d.ts +9 -0
- package/dist/rpc/streaming/rpcStreaming.type.js +9 -0
- package/dist/rpc/transport/rpcTransport.type.d.ts +9 -1
- package/dist/rpc/validation/index.d.ts +3 -0
- package/dist/rpc/validation/index.js +2 -0
- package/dist/rpc/validation/rpcValidation.core.d.ts +86 -0
- package/dist/rpc/validation/rpcValidation.core.js +133 -0
- package/package.json +27 -16
- package/dist/.tsbuildinfo +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/rpc/client/index.d.ts.map +0 -1
- package/dist/rpc/client/index.js.map +0 -1
- package/dist/rpc/client/rpcClient.core.d.ts.map +0 -1
- package/dist/rpc/client/rpcClient.core.js.map +0 -1
- package/dist/rpc/constants/index.d.ts.map +0 -1
- package/dist/rpc/constants/index.js.map +0 -1
- package/dist/rpc/constants/rpcConstants.core.d.ts.map +0 -1
- package/dist/rpc/constants/rpcConstants.core.js.map +0 -1
- package/dist/rpc/context/index.d.ts.map +0 -1
- package/dist/rpc/context/index.js.map +0 -1
- package/dist/rpc/context/rpcContext.type.d.ts.map +0 -1
- package/dist/rpc/context/rpcContext.type.js.map +0 -1
- package/dist/rpc/dispatcher/index.d.ts.map +0 -1
- package/dist/rpc/dispatcher/index.js.map +0 -1
- package/dist/rpc/dispatcher/rpcDispatcher.core.d.ts.map +0 -1
- package/dist/rpc/dispatcher/rpcDispatcher.core.js.map +0 -1
- package/dist/rpc/errors/index.d.ts.map +0 -1
- package/dist/rpc/errors/index.js.map +0 -1
- package/dist/rpc/errors/rpc.errors.d.ts.map +0 -1
- package/dist/rpc/errors/rpc.errors.js.map +0 -1
- package/dist/rpc/interceptor/index.d.ts.map +0 -1
- package/dist/rpc/interceptor/index.js.map +0 -1
- package/dist/rpc/interceptor/rpcInterceptor.type.d.ts.map +0 -1
- package/dist/rpc/interceptor/rpcInterceptor.type.js.map +0 -1
- package/dist/rpc/middleware/index.d.ts.map +0 -1
- package/dist/rpc/middleware/index.js.map +0 -1
- package/dist/rpc/middleware/rpcMiddleware.core.d.ts.map +0 -1
- package/dist/rpc/middleware/rpcMiddleware.core.js.map +0 -1
- package/dist/rpc/procedure/index.d.ts.map +0 -1
- package/dist/rpc/procedure/index.js.map +0 -1
- package/dist/rpc/procedure/rpcProcedure.type.d.ts.map +0 -1
- package/dist/rpc/procedure/rpcProcedure.type.js.map +0 -1
- package/dist/rpc/procedure/rpcProcedureRegistry.core.d.ts.map +0 -1
- package/dist/rpc/procedure/rpcProcedureRegistry.core.js.map +0 -1
- package/dist/rpc/procedure/rpcProcedureRouter.core.d.ts.map +0 -1
- package/dist/rpc/procedure/rpcProcedureRouter.core.js.map +0 -1
- package/dist/rpc/reliability/cancellation/rpcCancellation.helper.d.ts.map +0 -1
- package/dist/rpc/reliability/cancellation/rpcCancellation.helper.js.map +0 -1
- package/dist/rpc/reliability/deadline/rpcDeadline.helper.d.ts.map +0 -1
- package/dist/rpc/reliability/deadline/rpcDeadline.helper.js.map +0 -1
- package/dist/rpc/reliability/index.d.ts.map +0 -1
- package/dist/rpc/reliability/index.js.map +0 -1
- package/dist/rpc/reliability/retry/rpcRetry.helper.d.ts.map +0 -1
- package/dist/rpc/reliability/retry/rpcRetry.helper.js.map +0 -1
- package/dist/rpc/reliability/timeout/rpcTimeout.helper.d.ts.map +0 -1
- package/dist/rpc/reliability/timeout/rpcTimeout.helper.js.map +0 -1
- package/dist/rpc/server/index.d.ts.map +0 -1
- package/dist/rpc/server/index.js.map +0 -1
- package/dist/rpc/server/rpcServer.core.d.ts.map +0 -1
- package/dist/rpc/server/rpcServer.core.js.map +0 -1
- package/dist/rpc/streaming/index.d.ts.map +0 -1
- package/dist/rpc/streaming/index.js.map +0 -1
- package/dist/rpc/streaming/rpcStreaming.type.d.ts.map +0 -1
- package/dist/rpc/streaming/rpcStreaming.type.js.map +0 -1
- package/dist/rpc/transport/index.d.ts.map +0 -1
- package/dist/rpc/transport/index.js.map +0 -1
- package/dist/rpc/transport/rpcTransport.type.d.ts.map +0 -1
- package/dist/rpc/transport/rpcTransport.type.js.map +0 -1
- package/dist/rpc/types/index.d.ts.map +0 -1
- package/dist/rpc/types/index.js.map +0 -1
- package/dist/rpc/types/rpcMetadata.type.d.ts.map +0 -1
- package/dist/rpc/types/rpcMetadata.type.js.map +0 -1
- package/dist/rpc/types/rpcProcedureName.type.d.ts.map +0 -1
- package/dist/rpc/types/rpcProcedureName.type.js.map +0 -1
- package/dist/rpc/types/rpcRequest.type.d.ts.map +0 -1
- package/dist/rpc/types/rpcRequest.type.js.map +0 -1
- package/dist/rpc/types/rpcResponse.type.d.ts.map +0 -1
- package/dist/rpc/types/rpcResponse.type.js.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js.map +0 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/rpc/validation
|
|
3
|
+
*
|
|
4
|
+
* Request-level checks applied before a payload reaches a handler.
|
|
5
|
+
*
|
|
6
|
+
* Requests arrive from an untrusted peer over a transport, so these are
|
|
7
|
+
* the first checks the server runs, not the last.
|
|
8
|
+
*/
|
|
9
|
+
import type { Schema, SchemaIssue } from "@zudojs/schema";
|
|
10
|
+
import type { RPCRequest } from "../types/rpcRequest.type.js";
|
|
11
|
+
/**
|
|
12
|
+
* Limits applied to an incoming request.
|
|
13
|
+
*/
|
|
14
|
+
export interface RPCRequestLimits {
|
|
15
|
+
/**
|
|
16
|
+
* Maximum encoded payload size in bytes. Defaults to
|
|
17
|
+
* {@link MAX_RPC_PAYLOAD_SIZE}. Set to `0` to skip the check when the
|
|
18
|
+
* transport already enforces a frame limit.
|
|
19
|
+
*/
|
|
20
|
+
readonly maxPayloadBytes?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Whether procedure names must match {@link PROCEDURE_NAME_PATTERN}.
|
|
23
|
+
* Defaults to `true`.
|
|
24
|
+
*/
|
|
25
|
+
readonly enforceProcedureNamePattern?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validates a procedure name.
|
|
29
|
+
*
|
|
30
|
+
* Length is checked before the pattern so a pathological name cannot
|
|
31
|
+
* drive regex backtracking.
|
|
32
|
+
*/
|
|
33
|
+
export declare function assertValidProcedureName(name: unknown): asserts name is string;
|
|
34
|
+
/**
|
|
35
|
+
* Measures the encoded size of a payload in bytes.
|
|
36
|
+
*
|
|
37
|
+
* Returns `undefined` for a payload that cannot be encoded, which the
|
|
38
|
+
* caller reports as an invalid request rather than passing on.
|
|
39
|
+
*/
|
|
40
|
+
export declare function measurePayloadBytes(payload: unknown): number | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Validates the shape and size of an incoming request.
|
|
43
|
+
*
|
|
44
|
+
* @throws {RPCInvalidRequestError} when the frame is malformed or the
|
|
45
|
+
* payload exceeds the configured limit.
|
|
46
|
+
*/
|
|
47
|
+
export declare function assertValidRequest(request: unknown, limits?: RPCRequestLimits): asserts request is RPCRequest;
|
|
48
|
+
/**
|
|
49
|
+
* Converts schema issues into metadata safe to return to a caller.
|
|
50
|
+
*
|
|
51
|
+
* Only the path, code and message travel; the received input is dropped
|
|
52
|
+
* so a validation response cannot echo back data the caller sent.
|
|
53
|
+
*/
|
|
54
|
+
export declare function toValidationIssues(issues: readonly SchemaIssue[]): readonly {
|
|
55
|
+
path: string;
|
|
56
|
+
code: string;
|
|
57
|
+
message: string;
|
|
58
|
+
}[];
|
|
59
|
+
/**
|
|
60
|
+
* The part of a `@zudojs/schema` Schema this package depends on.
|
|
61
|
+
*
|
|
62
|
+
* Structural so any schema-like validator can be supplied, and so the
|
|
63
|
+
* dependency stays to the parse contract rather than the class.
|
|
64
|
+
*/
|
|
65
|
+
export type RPCSchema<TOutput = unknown> = Pick<Schema<TOutput, never>, "safeParse">;
|
|
66
|
+
/**
|
|
67
|
+
* Parses caller input against a schema.
|
|
68
|
+
*
|
|
69
|
+
* @throws {RPCValidationError} carrying the issues, which are safe to
|
|
70
|
+
* return: they describe the caller's own input.
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseInput<T>(schema: RPCSchema<T>, value: unknown, procedureName: string): T;
|
|
73
|
+
/**
|
|
74
|
+
* Parses a handler's result against its output schema.
|
|
75
|
+
*
|
|
76
|
+
* An invalid output is a server defect rather than a caller mistake, so
|
|
77
|
+
* it is thrown as an `RPCInternalError` (`expose: false`): the server
|
|
78
|
+
* answers with the generic internal error and hands the detail — the
|
|
79
|
+
* failing paths and codes — to `onInternalError`. Throwing a validation
|
|
80
|
+
* error here told the caller *its* request was invalid, with an empty
|
|
81
|
+
* issue list, for a fault that is entirely the handler's.
|
|
82
|
+
*
|
|
83
|
+
* @throws {RPCInternalError}
|
|
84
|
+
*/
|
|
85
|
+
export declare function parseOutput<T>(schema: RPCSchema<T>, value: unknown, procedureName: string): T;
|
|
86
|
+
//# sourceMappingURL=rpcValidation.core.d.ts.map
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/rpc/validation
|
|
3
|
+
*
|
|
4
|
+
* Request-level checks applied before a payload reaches a handler.
|
|
5
|
+
*
|
|
6
|
+
* Requests arrive from an untrusted peer over a transport, so these are
|
|
7
|
+
* the first checks the server runs, not the last.
|
|
8
|
+
*/
|
|
9
|
+
import { RPCInternalError, RPCInvalidRequestError, RPCValidationError, } from "../errors/rpc.errors.js";
|
|
10
|
+
import { MAX_PROCEDURE_NAME_LENGTH, MAX_RPC_PAYLOAD_SIZE, PROCEDURE_NAME_PATTERN, } from "../constants/rpcConstants.core.js";
|
|
11
|
+
/**
|
|
12
|
+
* Validates a procedure name.
|
|
13
|
+
*
|
|
14
|
+
* Length is checked before the pattern so a pathological name cannot
|
|
15
|
+
* drive regex backtracking.
|
|
16
|
+
*/
|
|
17
|
+
export function assertValidProcedureName(name) {
|
|
18
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
19
|
+
throw new RPCInvalidRequestError("Procedure name must be a non-empty string.");
|
|
20
|
+
}
|
|
21
|
+
if (name.length > MAX_PROCEDURE_NAME_LENGTH) {
|
|
22
|
+
throw new RPCInvalidRequestError(`Procedure name exceeds ${MAX_PROCEDURE_NAME_LENGTH} characters.`);
|
|
23
|
+
}
|
|
24
|
+
if (!PROCEDURE_NAME_PATTERN.test(name)) {
|
|
25
|
+
throw new RPCInvalidRequestError(`Procedure name "${name}" must be dot-separated identifiers, e.g. "users.getUser".`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Measures the encoded size of a payload in bytes.
|
|
30
|
+
*
|
|
31
|
+
* Returns `undefined` for a payload that cannot be encoded, which the
|
|
32
|
+
* caller reports as an invalid request rather than passing on.
|
|
33
|
+
*/
|
|
34
|
+
export function measurePayloadBytes(payload) {
|
|
35
|
+
if (payload === undefined) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const encoded = JSON.stringify(payload);
|
|
40
|
+
if (encoded === undefined) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
return Buffer.byteLength(encoded, "utf8");
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validates the shape and size of an incoming request.
|
|
51
|
+
*
|
|
52
|
+
* @throws {RPCInvalidRequestError} when the frame is malformed or the
|
|
53
|
+
* payload exceeds the configured limit.
|
|
54
|
+
*/
|
|
55
|
+
export function assertValidRequest(request, limits = {}) {
|
|
56
|
+
if (typeof request !== "object" || request === null) {
|
|
57
|
+
throw new RPCInvalidRequestError("Request must be an object.");
|
|
58
|
+
}
|
|
59
|
+
const candidate = request;
|
|
60
|
+
if (typeof candidate.id !== "string" || candidate.id.length === 0) {
|
|
61
|
+
throw new RPCInvalidRequestError("Request id must be a non-empty string.");
|
|
62
|
+
}
|
|
63
|
+
if (limits.enforceProcedureNamePattern ?? true) {
|
|
64
|
+
assertValidProcedureName(candidate.procedure);
|
|
65
|
+
}
|
|
66
|
+
else if (typeof candidate.procedure !== "string" ||
|
|
67
|
+
candidate.procedure.length === 0) {
|
|
68
|
+
throw new RPCInvalidRequestError("Procedure name must be a non-empty string.", undefined);
|
|
69
|
+
}
|
|
70
|
+
if (candidate.metadata !== undefined &&
|
|
71
|
+
(typeof candidate.metadata !== "object" || candidate.metadata === null)) {
|
|
72
|
+
throw new RPCInvalidRequestError("Request metadata must be an object.", candidate.procedure);
|
|
73
|
+
}
|
|
74
|
+
const maxBytes = limits.maxPayloadBytes ?? MAX_RPC_PAYLOAD_SIZE;
|
|
75
|
+
if (maxBytes > 0) {
|
|
76
|
+
const size = measurePayloadBytes(candidate.payload);
|
|
77
|
+
if (size === undefined) {
|
|
78
|
+
throw new RPCInvalidRequestError("Request payload could not be encoded.", candidate.procedure);
|
|
79
|
+
}
|
|
80
|
+
if (size > maxBytes) {
|
|
81
|
+
throw new RPCInvalidRequestError(`Request payload of ${size} bytes exceeds the ${maxBytes} byte limit.`, candidate.procedure);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Converts schema issues into metadata safe to return to a caller.
|
|
87
|
+
*
|
|
88
|
+
* Only the path, code and message travel; the received input is dropped
|
|
89
|
+
* so a validation response cannot echo back data the caller sent.
|
|
90
|
+
*/
|
|
91
|
+
export function toValidationIssues(issues) {
|
|
92
|
+
return issues.map((issue) => ({
|
|
93
|
+
path: issue.path.map(String).join("."),
|
|
94
|
+
code: String(issue.code),
|
|
95
|
+
message: issue.message,
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Parses caller input against a schema.
|
|
100
|
+
*
|
|
101
|
+
* @throws {RPCValidationError} carrying the issues, which are safe to
|
|
102
|
+
* return: they describe the caller's own input.
|
|
103
|
+
*/
|
|
104
|
+
export function parseInput(schema, value, procedureName) {
|
|
105
|
+
const result = schema.safeParse(value);
|
|
106
|
+
if (result.success) {
|
|
107
|
+
return result.data;
|
|
108
|
+
}
|
|
109
|
+
throw new RPCValidationError(`Invalid input for procedure "${procedureName}".`, toValidationIssues(result.issues), procedureName);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Parses a handler's result against its output schema.
|
|
113
|
+
*
|
|
114
|
+
* An invalid output is a server defect rather than a caller mistake, so
|
|
115
|
+
* it is thrown as an `RPCInternalError` (`expose: false`): the server
|
|
116
|
+
* answers with the generic internal error and hands the detail — the
|
|
117
|
+
* failing paths and codes — to `onInternalError`. Throwing a validation
|
|
118
|
+
* error here told the caller *its* request was invalid, with an empty
|
|
119
|
+
* issue list, for a fault that is entirely the handler's.
|
|
120
|
+
*
|
|
121
|
+
* @throws {RPCInternalError}
|
|
122
|
+
*/
|
|
123
|
+
export function parseOutput(schema, value, procedureName) {
|
|
124
|
+
const result = schema.safeParse(value);
|
|
125
|
+
if (result.success) {
|
|
126
|
+
return result.data;
|
|
127
|
+
}
|
|
128
|
+
const where = toValidationIssues(result.issues)
|
|
129
|
+
.map((issue) => `${issue.path || "(root)"}: ${issue.code}`)
|
|
130
|
+
.join(", ");
|
|
131
|
+
throw new RPCInternalError(`Procedure "${procedureName}" produced a response that does not match its output schema at ${where}.`, procedureName);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=rpcValidation.core.js.map
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zudojs/rpc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Remote procedure call infrastructure for Zudojs applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Oluwayemi Oyinlola",
|
|
8
|
+
"url": "https://github.com/oyinlola-tech"
|
|
9
|
+
},
|
|
6
10
|
"type": "module",
|
|
7
11
|
"main": "./dist/index.js",
|
|
8
12
|
"module": "./dist/index.js",
|
|
@@ -14,26 +18,22 @@
|
|
|
14
18
|
}
|
|
15
19
|
},
|
|
16
20
|
"files": [
|
|
17
|
-
"dist"
|
|
21
|
+
"dist",
|
|
22
|
+
"!dist/**/*.map",
|
|
23
|
+
"!dist/**/*.tsbuildinfo",
|
|
24
|
+
"!dist/.tsbuildinfo"
|
|
18
25
|
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "tsc -p tsconfig.json",
|
|
21
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
22
|
-
"clean": "rm -rf dist",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest"
|
|
25
|
-
},
|
|
26
26
|
"engines": {
|
|
27
27
|
"node": ">=24.0.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@zudojs/errors": "0.1
|
|
31
|
-
"@zudojs/constants": "0.1
|
|
32
|
-
"@zudojs/types": "
|
|
33
|
-
"@zudojs/schema": "0.1
|
|
30
|
+
"@zudojs/errors": "1.0.1",
|
|
31
|
+
"@zudojs/constants": "1.0.1",
|
|
32
|
+
"@zudojs/types": "1.0.0",
|
|
33
|
+
"@zudojs/schema": "1.0.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"typescript": "
|
|
36
|
+
"typescript": "7.0.2",
|
|
37
37
|
"vitest": "^4.1.11"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
@@ -46,8 +46,19 @@
|
|
|
46
46
|
"procedure"
|
|
47
47
|
],
|
|
48
48
|
"homepage": "https://github.com/oyinlola-tech/zudo#readme",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/oyinlola-tech/zudo/issues"
|
|
51
|
+
},
|
|
49
52
|
"repository": {
|
|
50
53
|
"type": "git",
|
|
51
|
-
"url": "https://github.com/oyinlola-tech/zudo"
|
|
54
|
+
"url": "https://github.com/oyinlola-tech/zudo",
|
|
55
|
+
"directory": "packages/rpc"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsc -p tsconfig.json",
|
|
59
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
|
|
60
|
+
"clean": "rm -rf dist",
|
|
61
|
+
"test": "vitest run",
|
|
62
|
+
"test:watch": "vitest"
|
|
52
63
|
}
|
|
53
|
-
}
|
|
64
|
+
}
|