arri 0.19.4 → 0.20.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/dist/cli.cjs CHANGED
@@ -12,7 +12,7 @@ const esbuild = require('esbuild');
12
12
  const esbuildPluginReplace = require('esbuild-plugin-replace');
13
13
  const path = require('pathe');
14
14
  const prettier = require('prettier');
15
- const config = require('./shared/arri.6b7e8945.cjs');
15
+ const config = require('./shared/arri.b90bc113.cjs');
16
16
  const globby = require('globby');
17
17
  const scule = require('scule');
18
18
  const arriCodegenDart = require('arri-codegen-dart');
package/dist/cli.mjs CHANGED
@@ -11,7 +11,7 @@ import { build as build$1 } from 'esbuild';
11
11
  import { replace } from 'esbuild-plugin-replace';
12
12
  import path from 'pathe';
13
13
  import prettier from 'prettier';
14
- import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.ea72d98f.mjs';
14
+ import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.f69ab093.mjs';
15
15
  import { globby } from 'globby';
16
16
  import { camelCase, kebabCase } from 'scule';
17
17
  import { dartClientGenerator } from 'arri-codegen-dart';
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const config = require('./shared/arri.6b7e8945.cjs');
3
+ const config = require('./shared/arri.b90bc113.cjs');
4
4
  const h3 = require('h3');
5
5
  require('arri-validate');
6
6
  require('node:process');
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
- import { AObjectSchema, ASchema, InferType, a, ValidationError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
2
+ import { AObjectSchema, ASchema, InferType, a, ValidationError, ValueError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
3
3
  import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
4
4
  export * from 'h3';
5
5
  import { BuildOptions } from 'esbuild';
@@ -73,6 +73,8 @@ interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends R
73
73
  connection: EventStreamConnection<TResponse>;
74
74
  }
75
75
  interface EventStreamConnectionOptions<TData> {
76
+ validator: (input: unknown) => input is TData;
77
+ validationErrors: (input: unknown) => ValueError[];
76
78
  serializer: (input: TData) => string;
77
79
  pingInterval?: number;
78
80
  }
@@ -93,6 +95,8 @@ declare class EventStreamConnection<TData> {
93
95
  private readonly writer;
94
96
  private writerIsClosed;
95
97
  private readonly encoder;
98
+ private readonly validationErrors;
99
+ private readonly validator;
96
100
  private readonly serializer;
97
101
  private readonly h3Event;
98
102
  private pingInterval;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
- import { AObjectSchema, ASchema, InferType, a, ValidationError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
2
+ import { AObjectSchema, ASchema, InferType, a, ValidationError, ValueError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
3
3
  import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
4
4
  export * from 'h3';
5
5
  import { BuildOptions } from 'esbuild';
@@ -73,6 +73,8 @@ interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends R
73
73
  connection: EventStreamConnection<TResponse>;
74
74
  }
75
75
  interface EventStreamConnectionOptions<TData> {
76
+ validator: (input: unknown) => input is TData;
77
+ validationErrors: (input: unknown) => ValueError[];
76
78
  serializer: (input: TData) => string;
77
79
  pingInterval?: number;
78
80
  }
@@ -93,6 +95,8 @@ declare class EventStreamConnection<TData> {
93
95
  private readonly writer;
94
96
  private writerIsClosed;
95
97
  private readonly encoder;
98
+ private readonly validationErrors;
99
+ private readonly validator;
96
100
  private readonly serializer;
97
101
  private readonly h3Event;
98
102
  private pingInterval;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
- import { AObjectSchema, ASchema, InferType, a, ValidationError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
2
+ import { AObjectSchema, ASchema, InferType, a, ValidationError, ValueError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
3
3
  import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
4
4
  export * from 'h3';
5
5
  import { BuildOptions } from 'esbuild';
@@ -73,6 +73,8 @@ interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends R
73
73
  connection: EventStreamConnection<TResponse>;
74
74
  }
75
75
  interface EventStreamConnectionOptions<TData> {
76
+ validator: (input: unknown) => input is TData;
77
+ validationErrors: (input: unknown) => ValueError[];
76
78
  serializer: (input: TData) => string;
77
79
  pingInterval?: number;
78
80
  }
@@ -93,6 +95,8 @@ declare class EventStreamConnection<TData> {
93
95
  private readonly writer;
94
96
  private writerIsClosed;
95
97
  private readonly encoder;
98
+ private readonly validationErrors;
99
+ private readonly validator;
96
100
  private readonly serializer;
97
101
  private readonly h3Event;
98
102
  private pingInterval;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ArriApp, p as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse, B as EventStreamConnection, c as createRpcDefinition, n as defaultConfig, o as defineConfig, h as defineError, w as defineEventStreamRpc, q as defineRoute, d as defineRpc, j as errorResponseFromValidationErrors, y as formatSse, z as formatSseList, e as getRpcParamName, g as getRpcPath, f as getRpcResponseName, k as handleH3Error, t as handleRoute, l as isArriConfig, x as isEventStreamRpc, m as isResolvedArriConfig, b as isRpc, i as isRpcParamSchema, C as registerEventStreamRpc, s as registerRoute, r as registerRpc, u as setSseHeaders, v as validateRpcRequestInput } from './shared/arri.ea72d98f.mjs';
1
+ export { A as ArriApp, p as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse, B as EventStreamConnection, c as createRpcDefinition, n as defaultConfig, o as defineConfig, h as defineError, w as defineEventStreamRpc, q as defineRoute, d as defineRpc, j as errorResponseFromValidationErrors, y as formatSse, z as formatSseList, e as getRpcParamName, g as getRpcPath, f as getRpcResponseName, k as handleH3Error, t as handleRoute, l as isArriConfig, x as isEventStreamRpc, m as isResolvedArriConfig, b as isRpc, i as isRpcParamSchema, C as registerEventStreamRpc, s as registerRoute, r as registerRpc, u as setSseHeaders, v as validateRpcRequestInput } from './shared/arri.f69ab093.mjs';
2
2
  export * from 'h3';
3
3
  import 'arri-validate';
4
4
  import 'node:process';
@@ -312,6 +312,13 @@ function registerRpc(router, path, procedure, opts) {
312
312
  await opts.onBeforeResponse(event);
313
313
  }
314
314
  if (typeof response === "object") {
315
+ if (!responseValidator?.validate(response)) {
316
+ const errors = arriValidate.a.errors(procedure.response, response);
317
+ throw defineError(500, {
318
+ statusMessage: "Failed to serialize response. Response does not match specified schema",
319
+ data: errors
320
+ });
321
+ }
315
322
  h3.setResponseHeader(event, "Content-Type", "application/json");
316
323
  await h3.send(
317
324
  event,
@@ -423,13 +430,17 @@ var __publicField$2 = (obj, key, value) => {
423
430
  return value;
424
431
  };
425
432
  function setSseHeaders(event) {
426
- h3.setHeaders(event, {
433
+ const isHttp2 = event._http2 === true;
434
+ const input = {
427
435
  "Content-Type": "text/event-stream",
428
436
  "Cache-Control": "private, no-cache, no-store, no-transform, must-revalidate, max-age=0",
429
- Connection: "keep-alive",
430
437
  Pragma: "no-cache",
431
438
  "X-Accel-Buffering": "no"
432
- });
439
+ };
440
+ if (!isHttp2) {
441
+ input.Connection = "keep-alive";
442
+ }
443
+ h3.setResponseHeaders(event, input);
433
444
  }
434
445
  function defineEventStreamRpc(config) {
435
446
  return {
@@ -470,6 +481,8 @@ class EventStreamConnection {
470
481
  __publicField$2(this, "writer");
471
482
  __publicField$2(this, "writerIsClosed", false);
472
483
  __publicField$2(this, "encoder");
484
+ __publicField$2(this, "validationErrors");
485
+ __publicField$2(this, "validator");
473
486
  __publicField$2(this, "serializer");
474
487
  __publicField$2(this, "h3Event");
475
488
  __publicField$2(this, "pingInterval");
@@ -484,6 +497,8 @@ class EventStreamConnection {
484
497
  this.encoder = new TextEncoder();
485
498
  this.pingIntervalMs = opts.pingInterval ?? 6e4;
486
499
  this.serializer = opts.serializer;
500
+ this.validator = opts.validator;
501
+ this.validationErrors = opts.validationErrors;
487
502
  void this.writer.closed.then(() => {
488
503
  this.writerIsClosed = true;
489
504
  });
@@ -508,19 +523,47 @@ class EventStreamConnection {
508
523
  if (Array.isArray(data)) {
509
524
  const events = [];
510
525
  for (const item of data) {
526
+ if (this.validator(item)) {
527
+ events.push({
528
+ id: eventId,
529
+ event: "message",
530
+ data: this.serializer(item)
531
+ });
532
+ continue;
533
+ }
534
+ const errors2 = this.validationErrors(item);
535
+ const errorResponse2 = {
536
+ statusCode: 500,
537
+ statusMessage: "Failed to serialize response. Response does not match specified schema.",
538
+ data: errors2
539
+ };
511
540
  events.push({
512
541
  id: eventId,
513
- event: "message",
514
- data: this.serializer(item)
542
+ event: "error",
543
+ data: JSON.stringify(errorResponse2)
515
544
  });
516
545
  }
517
546
  await this.publishEvents(events);
518
547
  return;
519
548
  }
549
+ if (this.validator(data)) {
550
+ await this.publishEvent({
551
+ id: eventId,
552
+ event: "message",
553
+ data: this.serializer(data)
554
+ });
555
+ return;
556
+ }
557
+ const errors = this.validationErrors(data);
558
+ const errorResponse = {
559
+ statusCode: 500,
560
+ statusMessage: "Failed to serialize response. Response does not match specified schema.",
561
+ data: errors
562
+ };
520
563
  await this.publishEvent({
521
564
  id: eventId,
522
- event: "message",
523
- data: this.serializer(data)
565
+ event: "error",
566
+ data: JSON.stringify(errorResponse)
524
567
  });
525
568
  }
526
569
  // /**
@@ -651,8 +694,17 @@ function registerEventStreamRpc(router, path, procedure, opts) {
651
694
  }
652
695
  const connection = new EventStreamConnection(event, {
653
696
  pingInterval: procedure.pingInterval,
697
+ validator: responseValidator?.validate ?? function() {
698
+ return true;
699
+ },
654
700
  serializer: responseValidator?.serialize ?? function(_) {
655
701
  return "";
702
+ },
703
+ validationErrors(input) {
704
+ if (procedure.response) {
705
+ return arriValidate.a.errors(procedure.response, input);
706
+ }
707
+ return [];
656
708
  }
657
709
  });
658
710
  event.context.connection = connection;
@@ -1,4 +1,4 @@
1
- import { createError, isError, setResponseStatus, send, eventHandler, isPreflightRequest, setResponseHeader, readRawBody, getValidatedQuery, setHeaders, getHeader, sendStream, defineEventHandler, getQuery, setHeader, createRouter, createApp, sendError } from 'h3';
1
+ import { createError, isError, setResponseStatus, send, eventHandler, isPreflightRequest, setResponseHeader, readRawBody, getValidatedQuery, setResponseHeaders, getHeader, sendStream, defineEventHandler, getQuery, setHeader, createRouter, createApp, sendError } from 'h3';
2
2
  import { a, isAObjectSchema, isARecordSchema, isADiscriminatorSchema } from 'arri-validate';
3
3
  import { nextTick } from 'node:process';
4
4
  import { isRpcHttpMethod, removeDisallowedChars } from 'arri-codegen-utils';
@@ -310,6 +310,13 @@ function registerRpc(router, path, procedure, opts) {
310
310
  await opts.onBeforeResponse(event);
311
311
  }
312
312
  if (typeof response === "object") {
313
+ if (!responseValidator?.validate(response)) {
314
+ const errors = a.errors(procedure.response, response);
315
+ throw defineError(500, {
316
+ statusMessage: "Failed to serialize response. Response does not match specified schema",
317
+ data: errors
318
+ });
319
+ }
313
320
  setResponseHeader(event, "Content-Type", "application/json");
314
321
  await send(
315
322
  event,
@@ -421,13 +428,17 @@ var __publicField$2 = (obj, key, value) => {
421
428
  return value;
422
429
  };
423
430
  function setSseHeaders(event) {
424
- setHeaders(event, {
431
+ const isHttp2 = event._http2 === true;
432
+ const input = {
425
433
  "Content-Type": "text/event-stream",
426
434
  "Cache-Control": "private, no-cache, no-store, no-transform, must-revalidate, max-age=0",
427
- Connection: "keep-alive",
428
435
  Pragma: "no-cache",
429
436
  "X-Accel-Buffering": "no"
430
- });
437
+ };
438
+ if (!isHttp2) {
439
+ input.Connection = "keep-alive";
440
+ }
441
+ setResponseHeaders(event, input);
431
442
  }
432
443
  function defineEventStreamRpc(config) {
433
444
  return {
@@ -468,6 +479,8 @@ class EventStreamConnection {
468
479
  __publicField$2(this, "writer");
469
480
  __publicField$2(this, "writerIsClosed", false);
470
481
  __publicField$2(this, "encoder");
482
+ __publicField$2(this, "validationErrors");
483
+ __publicField$2(this, "validator");
471
484
  __publicField$2(this, "serializer");
472
485
  __publicField$2(this, "h3Event");
473
486
  __publicField$2(this, "pingInterval");
@@ -482,6 +495,8 @@ class EventStreamConnection {
482
495
  this.encoder = new TextEncoder();
483
496
  this.pingIntervalMs = opts.pingInterval ?? 6e4;
484
497
  this.serializer = opts.serializer;
498
+ this.validator = opts.validator;
499
+ this.validationErrors = opts.validationErrors;
485
500
  void this.writer.closed.then(() => {
486
501
  this.writerIsClosed = true;
487
502
  });
@@ -506,19 +521,47 @@ class EventStreamConnection {
506
521
  if (Array.isArray(data)) {
507
522
  const events = [];
508
523
  for (const item of data) {
524
+ if (this.validator(item)) {
525
+ events.push({
526
+ id: eventId,
527
+ event: "message",
528
+ data: this.serializer(item)
529
+ });
530
+ continue;
531
+ }
532
+ const errors2 = this.validationErrors(item);
533
+ const errorResponse2 = {
534
+ statusCode: 500,
535
+ statusMessage: "Failed to serialize response. Response does not match specified schema.",
536
+ data: errors2
537
+ };
509
538
  events.push({
510
539
  id: eventId,
511
- event: "message",
512
- data: this.serializer(item)
540
+ event: "error",
541
+ data: JSON.stringify(errorResponse2)
513
542
  });
514
543
  }
515
544
  await this.publishEvents(events);
516
545
  return;
517
546
  }
547
+ if (this.validator(data)) {
548
+ await this.publishEvent({
549
+ id: eventId,
550
+ event: "message",
551
+ data: this.serializer(data)
552
+ });
553
+ return;
554
+ }
555
+ const errors = this.validationErrors(data);
556
+ const errorResponse = {
557
+ statusCode: 500,
558
+ statusMessage: "Failed to serialize response. Response does not match specified schema.",
559
+ data: errors
560
+ };
518
561
  await this.publishEvent({
519
562
  id: eventId,
520
- event: "message",
521
- data: this.serializer(data)
563
+ event: "error",
564
+ data: JSON.stringify(errorResponse)
522
565
  });
523
566
  }
524
567
  // /**
@@ -649,8 +692,17 @@ function registerEventStreamRpc(router, path, procedure, opts) {
649
692
  }
650
693
  const connection = new EventStreamConnection(event, {
651
694
  pingInterval: procedure.pingInterval,
695
+ validator: responseValidator?.validate ?? function() {
696
+ return true;
697
+ },
652
698
  serializer: responseValidator?.serialize ?? function(_) {
653
699
  return "";
700
+ },
701
+ validationErrors(input) {
702
+ if (procedure.response) {
703
+ return a.errors(procedure.response, input);
704
+ }
705
+ return [];
654
706
  }
655
707
  });
656
708
  event.context.connection = connection;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arri",
3
- "version": "0.19.4",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -37,17 +37,17 @@
37
37
  "h3": "^1.10.0",
38
38
  "jiti": "^1.21.0",
39
39
  "ofetch": "^1.3.3",
40
- "pathe": "^1.1.1",
41
- "prettier": "^3.1.1",
42
- "scule": "^1.1.1",
40
+ "pathe": "^1.1.2",
41
+ "prettier": "^3.2.2",
42
+ "scule": "^1.2.0",
43
43
  "uncrypto": "^0.1.3",
44
- "arri-codegen-dart": "0.19.4",
45
- "arri-codegen-ts": "0.19.4",
46
- "arri-codegen-utils": "0.19.4",
47
- "arri-validate": "0.19.4"
44
+ "arri-codegen-dart": "0.20.0",
45
+ "arri-validate": "0.20.0",
46
+ "arri-codegen-utils": "0.20.0",
47
+ "arri-codegen-ts": "0.20.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/degit": "^2.8.6",
51
- "bun-types": "^1.0.21"
51
+ "bun-types": "^1.0.22"
52
52
  }
53
53
  }