@ereo/rpc 0.1.28 → 0.1.31
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/client.js +33 -8
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/context-bridge.d.ts +5 -1
- package/dist/src/context-bridge.d.ts.map +1 -1
- package/dist/src/hooks.d.ts.map +1 -1
- package/dist/src/index.js +24 -7
- package/dist/src/server-fn-handler.d.ts +4 -0
- package/dist/src/server-fn-handler.d.ts.map +1 -1
- package/dist/src/server-fn.d.ts +3 -0
- package/dist/src/server-fn.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/client.js
CHANGED
|
@@ -25,7 +25,7 @@ function createClient(optionsOrEndpoint) {
|
|
|
25
25
|
const pendingSubscriptions = [];
|
|
26
26
|
const connectionQueue = [];
|
|
27
27
|
function getHeaders() {
|
|
28
|
-
const base = { "Content-Type": "application/json" };
|
|
28
|
+
const base = { "Content-Type": "application/json", "X-Ereo-RPC": "1" };
|
|
29
29
|
const custom = typeof options.headers === "function" ? options.headers() : options.headers;
|
|
30
30
|
return { ...base, ...custom };
|
|
31
31
|
}
|
|
@@ -248,6 +248,7 @@ function createClient(optionsOrEndpoint) {
|
|
|
248
248
|
subscriptions.delete(id);
|
|
249
249
|
sendUnsubscribe(id);
|
|
250
250
|
if (subscriptions.size === 0 && pendingSubscriptions.length === 0) {
|
|
251
|
+
stopHeartbeat();
|
|
251
252
|
if (reconnectTimeout) {
|
|
252
253
|
clearTimeout(reconnectTimeout);
|
|
253
254
|
reconnectTimeout = null;
|
|
@@ -255,6 +256,7 @@ function createClient(optionsOrEndpoint) {
|
|
|
255
256
|
ws?.close();
|
|
256
257
|
ws = null;
|
|
257
258
|
wsConnected = false;
|
|
259
|
+
wsConnecting = false;
|
|
258
260
|
}
|
|
259
261
|
};
|
|
260
262
|
};
|
|
@@ -266,13 +268,30 @@ function createClient(optionsOrEndpoint) {
|
|
|
266
268
|
return createProxy([]);
|
|
267
269
|
}
|
|
268
270
|
async function handleHttpResponse(response, path) {
|
|
269
|
-
|
|
271
|
+
let result;
|
|
272
|
+
try {
|
|
273
|
+
result = await response.json();
|
|
274
|
+
} catch {
|
|
275
|
+
const error = new Error(`RPC call to ${path.join(".")} returned invalid JSON (status ${response.status})`);
|
|
276
|
+
error.name = "RPCClientError";
|
|
277
|
+
error.code = "PARSE_ERROR";
|
|
278
|
+
error.path = path.join(".");
|
|
279
|
+
throw error;
|
|
280
|
+
}
|
|
281
|
+
if (!result || !("ok" in result)) {
|
|
282
|
+
const error = new Error(`RPC call to ${path.join(".")} returned unexpected response format`);
|
|
283
|
+
error.name = "RPCClientError";
|
|
284
|
+
error.code = "INVALID_RESPONSE";
|
|
285
|
+
error.path = path.join(".");
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
270
288
|
if (!result.ok) {
|
|
271
|
-
const
|
|
289
|
+
const errMsg = result.error?.message || "Unknown RPC error";
|
|
290
|
+
const error = new Error(errMsg);
|
|
272
291
|
error.name = "RPCClientError";
|
|
273
|
-
error.code = result.error
|
|
292
|
+
error.code = result.error?.code || "UNKNOWN";
|
|
274
293
|
error.path = path.join(".");
|
|
275
|
-
error.details = result.error
|
|
294
|
+
error.details = result.error?.details;
|
|
276
295
|
throw error;
|
|
277
296
|
}
|
|
278
297
|
return result.data;
|
|
@@ -382,7 +401,10 @@ function useSubscription(procedure, options = {}) {
|
|
|
382
401
|
onData: (value) => {
|
|
383
402
|
setStatus("connected");
|
|
384
403
|
setData(value);
|
|
385
|
-
setHistory((prev) =>
|
|
404
|
+
setHistory((prev) => {
|
|
405
|
+
const next = [...prev, value];
|
|
406
|
+
return next.length > 1000 ? next.slice(-1000) : next;
|
|
407
|
+
});
|
|
386
408
|
onData?.(value);
|
|
387
409
|
},
|
|
388
410
|
onError: (err) => {
|
|
@@ -465,7 +487,7 @@ function createClientProxy(id) {
|
|
|
465
487
|
const fn = async (input) => {
|
|
466
488
|
const response = await fetch(url, {
|
|
467
489
|
method: "POST",
|
|
468
|
-
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
490
|
+
headers: { "Content-Type": "application/json", Accept: "application/json", "X-Ereo-RPC": "1" },
|
|
469
491
|
body: JSON.stringify({ input })
|
|
470
492
|
});
|
|
471
493
|
const result = await response.json();
|
|
@@ -491,6 +513,7 @@ function createServerFn(idOrOptions, maybeHandler) {
|
|
|
491
513
|
let handler;
|
|
492
514
|
let middleware = [];
|
|
493
515
|
let inputSchema;
|
|
516
|
+
let allowPublic;
|
|
494
517
|
if (typeof idOrOptions === "string") {
|
|
495
518
|
id = idOrOptions;
|
|
496
519
|
handler = maybeHandler;
|
|
@@ -499,13 +522,15 @@ function createServerFn(idOrOptions, maybeHandler) {
|
|
|
499
522
|
handler = idOrOptions.handler;
|
|
500
523
|
middleware = idOrOptions.middleware ?? [];
|
|
501
524
|
inputSchema = idOrOptions.input;
|
|
525
|
+
allowPublic = idOrOptions.allowPublic;
|
|
502
526
|
}
|
|
503
527
|
if (isServer) {
|
|
504
528
|
registerServerFn({
|
|
505
529
|
id,
|
|
506
530
|
handler,
|
|
507
531
|
middleware,
|
|
508
|
-
inputSchema
|
|
532
|
+
inputSchema,
|
|
533
|
+
allowPublic
|
|
509
534
|
});
|
|
510
535
|
const fn = async (input) => {
|
|
511
536
|
const ctx = {
|
package/dist/src/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EACV,MAAM,EACN,SAAS,EACT,WAAW,EAMZ,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,kCAAkC;IAClC,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAQD;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,SAAS,CAAC,EACtD,iBAAiB,EAAE,MAAM,GAAG,gBAAgB,GAC3C,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EACV,MAAM,EACN,SAAS,EACT,WAAW,EAMZ,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,kCAAkC;IAClC,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAQD;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,SAAS,CAAC,EACtD,iBAAiB,EAAE,MAAM,GAAG,gBAAgB,GAC3C,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAqWxB;AAmCD,MAAM,WAAW,cAAe,SAAQ,KAAK;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -12,7 +12,11 @@ import type { BaseContext } from './types';
|
|
|
12
12
|
*/
|
|
13
13
|
export type ContextProvider<TContext = any> = (request: Request) => TContext | Promise<TContext>;
|
|
14
14
|
/**
|
|
15
|
-
* Set the global context provider that will be used by both RPC and loaders
|
|
15
|
+
* Set the global context provider that will be used by both RPC and loaders.
|
|
16
|
+
*
|
|
17
|
+
* **Important:** The provider must be a stateless factory function that creates
|
|
18
|
+
* a fresh context object for each request. Do not return shared/mutable objects
|
|
19
|
+
* across requests, as this can lead to cross-request data leakage.
|
|
16
20
|
*
|
|
17
21
|
* Usage in your app setup:
|
|
18
22
|
* import { setContextProvider } from '@ereo/rpc';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-bridge.d.ts","sourceRoot":"","sources":["../../src/context-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,QAAQ,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAOjG
|
|
1
|
+
{"version":3,"file":"context-bridge.d.ts","sourceRoot":"","sources":["../../src/context-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,QAAQ,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAOjG;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,GAAG,IAAI,CAEtF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAKD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAuBxE;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB,CAAC,QAAQ;IAChD,uCAAuC;IACvC,OAAO,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB,CAAC,QAAQ;IAC3C,iDAAiD;IACjD,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAC5C,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,GAClC,eAAe,CAAC,QAAQ,CAAC,CAE3B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,CAAC,IAAI,EAAE;IAC1C,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,CAAC,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;CACvE,KAAK,OAAO,CAAC,GAAG,CAAC,CAMjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAQ9C"}
|
package/dist/src/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -415,9 +415,17 @@ function getContextProvider() {
|
|
|
415
415
|
function clearContextProvider() {
|
|
416
416
|
globalContextProvider = null;
|
|
417
417
|
}
|
|
418
|
+
var _lastContextRef = null;
|
|
418
419
|
async function createSharedContext(request) {
|
|
419
420
|
if (globalContextProvider) {
|
|
420
|
-
|
|
421
|
+
const ctx = await globalContextProvider(request);
|
|
422
|
+
if (typeof ctx === "object" && ctx !== null && typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
|
|
423
|
+
if (_lastContextRef && _lastContextRef.deref() === ctx) {
|
|
424
|
+
console.warn("[@ereo/rpc] Context provider returned the same object reference for consecutive calls. " + "This may cause cross-request data leakage. Providers should return a fresh object per request.");
|
|
425
|
+
}
|
|
426
|
+
_lastContextRef = new WeakRef(ctx);
|
|
427
|
+
}
|
|
428
|
+
return ctx;
|
|
421
429
|
}
|
|
422
430
|
return {};
|
|
423
431
|
}
|
|
@@ -627,7 +635,7 @@ function createClientProxy(id) {
|
|
|
627
635
|
const fn = async (input) => {
|
|
628
636
|
const response = await fetch(url, {
|
|
629
637
|
method: "POST",
|
|
630
|
-
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
638
|
+
headers: { "Content-Type": "application/json", Accept: "application/json", "X-Ereo-RPC": "1" },
|
|
631
639
|
body: JSON.stringify({ input })
|
|
632
640
|
});
|
|
633
641
|
const result = await response.json();
|
|
@@ -653,6 +661,7 @@ function createServerFn(idOrOptions, maybeHandler) {
|
|
|
653
661
|
let handler;
|
|
654
662
|
let middleware = [];
|
|
655
663
|
let inputSchema;
|
|
664
|
+
let allowPublic;
|
|
656
665
|
if (typeof idOrOptions === "string") {
|
|
657
666
|
id = idOrOptions;
|
|
658
667
|
handler = maybeHandler;
|
|
@@ -661,13 +670,15 @@ function createServerFn(idOrOptions, maybeHandler) {
|
|
|
661
670
|
handler = idOrOptions.handler;
|
|
662
671
|
middleware = idOrOptions.middleware ?? [];
|
|
663
672
|
inputSchema = idOrOptions.input;
|
|
673
|
+
allowPublic = idOrOptions.allowPublic;
|
|
664
674
|
}
|
|
665
675
|
if (isServer) {
|
|
666
676
|
registerServerFn({
|
|
667
677
|
id,
|
|
668
678
|
handler,
|
|
669
679
|
middleware,
|
|
670
|
-
inputSchema
|
|
680
|
+
inputSchema,
|
|
681
|
+
allowPublic
|
|
671
682
|
});
|
|
672
683
|
const fn = async (input) => {
|
|
673
684
|
const ctx = {
|
|
@@ -706,7 +717,9 @@ function createServerFnHandler(options = {}) {
|
|
|
706
717
|
basePath = SERVER_FN_BASE,
|
|
707
718
|
middleware: globalMiddleware = [],
|
|
708
719
|
onError,
|
|
709
|
-
createContext
|
|
720
|
+
createContext,
|
|
721
|
+
disableCsrfProtection = false,
|
|
722
|
+
defaultMiddleware = []
|
|
710
723
|
} = options;
|
|
711
724
|
const prefix = basePath.endsWith("/") ? basePath : basePath + "/";
|
|
712
725
|
return async (request, appContext) => {
|
|
@@ -717,9 +730,12 @@ function createServerFnHandler(options = {}) {
|
|
|
717
730
|
if (request.method !== "POST") {
|
|
718
731
|
return jsonResponse2({ ok: false, error: { code: "METHOD_NOT_ALLOWED", message: "Server functions only accept POST requests" } }, 405);
|
|
719
732
|
}
|
|
733
|
+
if (!disableCsrfProtection && !request.headers.get("X-Ereo-RPC")) {
|
|
734
|
+
return jsonResponse2({ ok: false, error: { code: "CSRF_ERROR", message: "Missing X-Ereo-RPC header" } }, 403);
|
|
735
|
+
}
|
|
720
736
|
const fnId = decodeURIComponent(url.pathname.slice(prefix.length));
|
|
721
|
-
if (!fnId) {
|
|
722
|
-
return jsonResponse2({ ok: false, error: { code: "BAD_REQUEST", message: "
|
|
737
|
+
if (!fnId || fnId.includes("..") || fnId.includes("\x00")) {
|
|
738
|
+
return jsonResponse2({ ok: false, error: { code: "BAD_REQUEST", message: "Invalid function ID" } }, 400);
|
|
723
739
|
}
|
|
724
740
|
const fn = getServerFn(fnId);
|
|
725
741
|
if (!fn) {
|
|
@@ -753,7 +769,8 @@ function createServerFnHandler(options = {}) {
|
|
|
753
769
|
return jsonResponse2({ ok: false, error: { code: "VALIDATION_ERROR", message: "Input validation failed", details } }, 400);
|
|
754
770
|
}
|
|
755
771
|
}
|
|
756
|
-
const
|
|
772
|
+
const fnDefaultMiddleware = fn.allowPublic ? [] : defaultMiddleware;
|
|
773
|
+
const allMiddleware = [...globalMiddleware, ...fnDefaultMiddleware, ...fn.middleware];
|
|
757
774
|
const runChain = async (index) => {
|
|
758
775
|
if (index < allMiddleware.length) {
|
|
759
776
|
return allMiddleware[index](ctx, () => runChain(index + 1));
|
|
@@ -26,6 +26,10 @@ export interface ServerFnHandlerOptions {
|
|
|
26
26
|
onError?: (error: unknown, fnId: string) => void;
|
|
27
27
|
/** Context provider — creates app context from the request */
|
|
28
28
|
createContext?: (request: Request) => unknown | Promise<unknown>;
|
|
29
|
+
/** Disable CSRF header check (not recommended) */
|
|
30
|
+
disableCsrfProtection?: boolean;
|
|
31
|
+
/** Default middleware prepended to all server functions unless allowPublic is true */
|
|
32
|
+
defaultMiddleware?: ServerFnMiddleware[];
|
|
29
33
|
}
|
|
30
34
|
export type ServerFnRequestHandler = (request: Request, appContext?: unknown) => Promise<Response | null>;
|
|
31
35
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-fn-handler.d.ts","sourceRoot":"","sources":["../../src/server-fn-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,gDAAgD;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,8DAA8D;IAC9D,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"server-fn-handler.d.ts","sourceRoot":"","sources":["../../src/server-fn-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,gDAAgD;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,8DAA8D;IAC9D,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,kDAAkD;IAClD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,OAAO,KACjB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAM9B;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,sBAA2B,GACnC,sBAAsB,CA6JxB"}
|
package/dist/src/server-fn.d.ts
CHANGED
|
@@ -47,6 +47,8 @@ export interface ServerFnOptions<TInput, TOutput> {
|
|
|
47
47
|
middleware?: ServerFnMiddleware[];
|
|
48
48
|
/** The function implementation */
|
|
49
49
|
handler: (input: TInput, ctx: ServerFnContext) => Promise<TOutput> | TOutput;
|
|
50
|
+
/** Skip defaultMiddleware (marks this function as publicly accessible) */
|
|
51
|
+
allowPublic?: boolean;
|
|
50
52
|
}
|
|
51
53
|
/** A callable server function with metadata */
|
|
52
54
|
export interface ServerFn<TInput, TOutput> {
|
|
@@ -69,6 +71,7 @@ export interface RegisteredServerFn {
|
|
|
69
71
|
handler: (input: unknown, ctx: ServerFnContext) => Promise<unknown>;
|
|
70
72
|
middleware: ServerFnMiddleware[];
|
|
71
73
|
inputSchema?: Schema<unknown>;
|
|
74
|
+
allowPublic?: boolean;
|
|
72
75
|
}
|
|
73
76
|
/** Error thrown by server functions with structured error data */
|
|
74
77
|
export declare class ServerFnError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-fn.d.ts","sourceRoot":"","sources":["../../src/server-fn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAA8B,MAAM,SAAS,CAAC;AAMlE,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,eAAe,EAAE,OAAO,CAAC;IACzB,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,oDAAoD;AACpD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KACzB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,yDAAyD;AACzD,MAAM,WAAW,eAAe,CAAC,MAAM,EAAE,OAAO;IAC9C,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,kCAAkC;IAClC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"server-fn.d.ts","sourceRoot":"","sources":["../../src/server-fn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAA8B,MAAM,SAAS,CAAC;AAMlE,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,eAAe,EAAE,OAAO,CAAC;IACzB,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,oDAAoD;AACpD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KACzB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,yDAAyD;AACzD,MAAM,WAAW,eAAe,CAAC,MAAM,EAAE,OAAO;IAC9C,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,kCAAkC;IAClC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7E,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,+CAA+C;AAC/C,MAAM,WAAW,QAAQ,CAAC,MAAM,EAAE,OAAO;IACvC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,yBAAyB;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,kDAAkD;AAClD,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEjF,mDAAmD;AACnD,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAElF,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAMD,kEAAkE;AAClE,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGhD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;CAQvE;AAED,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAQD,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAOhE;AAED,6CAA6C;AAC7C,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEtE;AAED,0CAA0C;AAC1C,wBAAgB,eAAe,IAAI,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAEzE;AAED,mCAAmC;AACnC,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,0DAA0D;AAC1D,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAUD,yCAAyC;AACzC,eAAO,MAAM,cAAc,gBAAgB,CAAC;AA+C5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAG,IAAI,EAAE,OAAO,GAAG,OAAO,EAC7D,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAC3E,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAC5C,OAAO,EAAE,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,GACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ereo/rpc",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Ereo Team",
|
|
6
6
|
"homepage": "https://ereo.dev",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"typecheck": "tsc --noEmit"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@ereo/core": "^0.1.
|
|
39
|
+
"@ereo/core": "^0.1.31"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"react": ">=18.0.0"
|