yedra 0.20.0 → 0.20.2

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/lib.d.ts CHANGED
@@ -1,25 +1,10 @@
1
1
  export { BadRequestError, ConflictError, ForbiddenError, HttpError, NotFoundError, PaymentRequiredError, UnauthorizedError, } from './routing/errors.js';
2
2
  export { Log } from './routing/log.js';
3
+ export * from './schema-lib.js';
3
4
  export declare const validatePath: (path: string) => void;
4
5
  export { parseEnv } from './routing/env.js';
5
6
  export { SecurityScheme } from './util/security.js';
6
- export { BodyType, type Typeof } from './validation/body.js';
7
- export { boolean } from './validation/boolean.js';
8
- export { date } from './validation/date.js';
9
7
  export { either } from './validation/either.js';
10
- export { _enum as enum } from './validation/enum.js';
11
- export { ValidationError } from './validation/error.js';
12
- export { integer } from './validation/integer.js';
13
8
  export { json } from './validation/json.js';
14
- export { array } from './validation/modifiable.js';
15
- export { _null as null } from './validation/null.js';
16
- export { number } from './validation/number.js';
17
- export { laxObject, object } from './validation/object.js';
18
9
  export { raw } from './validation/raw.js';
19
- export { record } from './validation/record.js';
20
- export { Schema } from './validation/schema.js';
21
10
  export { stream } from './validation/stream.js';
22
- export { string } from './validation/string.js';
23
- export { union } from './validation/union.js';
24
- export { unknown } from './validation/unknown.js';
25
- export { uuid } from './validation/uuid.js';
package/dist/lib.js CHANGED
@@ -2,29 +2,15 @@ import { Path } from './routing/path.js';
2
2
  // routing
3
3
  export { BadRequestError, ConflictError, ForbiddenError, HttpError, NotFoundError, PaymentRequiredError, UnauthorizedError, } from './routing/errors.js';
4
4
  export { Log } from './routing/log.js';
5
+ // validation (browser-safe, shared with yedra/schema)
6
+ export * from './schema-lib.js';
5
7
  export const validatePath = (path) => {
6
8
  new Path(path);
7
9
  };
8
10
  export { parseEnv } from './routing/env.js';
9
11
  export { SecurityScheme } from './util/security.js';
10
- export { BodyType } from './validation/body.js';
11
- export { boolean } from './validation/boolean.js';
12
- export { date } from './validation/date.js';
12
+ // Node-only body types
13
13
  export { either } from './validation/either.js';
14
- export { _enum as enum } from './validation/enum.js';
15
- export { ValidationError } from './validation/error.js';
16
- export { integer } from './validation/integer.js';
17
14
  export { json } from './validation/json.js';
18
- // validation
19
- export { array } from './validation/modifiable.js';
20
- export { _null as null } from './validation/null.js';
21
- export { number } from './validation/number.js';
22
- export { laxObject, object } from './validation/object.js';
23
15
  export { raw } from './validation/raw.js';
24
- export { record } from './validation/record.js';
25
- export { Schema } from './validation/schema.js';
26
16
  export { stream } from './validation/stream.js';
27
- export { string } from './validation/string.js';
28
- export { union } from './validation/union.js';
29
- export { unknown } from './validation/unknown.js';
30
- export { uuid } from './validation/uuid.js';
@@ -73,8 +73,17 @@ class BuiltApp {
73
73
  const status = response.status ?? 200;
74
74
  if (response.body instanceof ReadableStream) {
75
75
  res.writeHead(status, response.headers);
76
- for await (const chunk of response.body) {
77
- res.write(chunk);
76
+ try {
77
+ for await (const chunk of response.body) {
78
+ const canContinue = res.write(chunk);
79
+ if (!canContinue) {
80
+ // Buffer full - wait for drain before continuing
81
+ await new Promise((resolve) => res.once('drain', resolve));
82
+ }
83
+ }
84
+ }
85
+ catch (_error) {
86
+ res.destroy();
78
87
  }
79
88
  }
80
89
  else if (response.body instanceof Uint8Array) {
@@ -0,0 +1,16 @@
1
+ export { BodyType, type Typeof } from './validation/body.js';
2
+ export { boolean } from './validation/boolean.js';
3
+ export { date } from './validation/date.js';
4
+ export { _enum as enum } from './validation/enum.js';
5
+ export { ValidationError } from './validation/error.js';
6
+ export { integer } from './validation/integer.js';
7
+ export { array } from './validation/modifiable.js';
8
+ export { _null as null } from './validation/null.js';
9
+ export { number } from './validation/number.js';
10
+ export { laxObject, object } from './validation/object.js';
11
+ export { record } from './validation/record.js';
12
+ export { Schema } from './validation/schema.js';
13
+ export { string } from './validation/string.js';
14
+ export { union } from './validation/union.js';
15
+ export { unknown } from './validation/unknown.js';
16
+ export { uuid } from './validation/uuid.js';
@@ -0,0 +1,19 @@
1
+ // Browser-safe schema-only exports.
2
+ // This module excludes all Node.js-specific code (HTTP server,
3
+ // WebSocket, streams, etc.) so it can be safely bundled for the browser.
4
+ export { BodyType } from './validation/body.js';
5
+ export { boolean } from './validation/boolean.js';
6
+ export { date } from './validation/date.js';
7
+ export { _enum as enum } from './validation/enum.js';
8
+ export { ValidationError } from './validation/error.js';
9
+ export { integer } from './validation/integer.js';
10
+ export { array } from './validation/modifiable.js';
11
+ export { _null as null } from './validation/null.js';
12
+ export { number } from './validation/number.js';
13
+ export { laxObject, object } from './validation/object.js';
14
+ export { record } from './validation/record.js';
15
+ export { Schema } from './validation/schema.js';
16
+ export { string } from './validation/string.js';
17
+ export { union } from './validation/union.js';
18
+ export { unknown } from './validation/unknown.js';
19
+ export { uuid } from './validation/uuid.js';
@@ -0,0 +1,2 @@
1
+ import * as y from './schema-lib.js';
2
+ export { y };
package/dist/schema.js ADDED
@@ -0,0 +1,4 @@
1
+ // Browser-safe entry point for frontend use.
2
+ // Usage: import { y } from 'yedra/schema'
3
+ import * as y from './schema-lib.js';
4
+ export { y };
@@ -1,9 +1,8 @@
1
- import { isDate } from 'node:util/types';
2
1
  import { Issue, ValidationError } from './error.js';
3
2
  import { ModifiableSchema } from './modifiable.js';
4
3
  class DateSchema extends ModifiableSchema {
5
4
  parse(obj) {
6
- if (isDate(obj)) {
5
+ if (obj instanceof Date) {
7
6
  return obj;
8
7
  }
9
8
  if (typeof obj === 'string' || typeof obj === 'number') {
@@ -1,9 +1,10 @@
1
1
  import type { Readable } from 'node:stream';
2
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
3
  import { BodyType } from './body.js';
3
4
  /**
4
5
  * The base class for all schemas.
5
6
  */
6
- export declare abstract class Schema<T> extends BodyType<T, T> {
7
+ export declare abstract class Schema<T> extends BodyType<T, T> implements StandardSchemaV1<unknown, T> {
7
8
  deserialize(stream: Readable, contentType: string): Promise<T>;
8
9
  bodyDocs(): object;
9
10
  /**
@@ -20,4 +21,15 @@ export declare abstract class Schema<T> extends BodyType<T, T> {
20
21
  * Whether the schema is allowed to be optional.
21
22
  */
22
23
  isOptional(): boolean;
24
+ /**
25
+ * Standard Schema V1 compliance. This allows yedra schemas to be used
26
+ * directly with libraries that accept Standard Schema validators
27
+ * (e.g. TanStack Form, TanStack Router, tRPC).
28
+ *
29
+ * This is a non-breaking addition — it does not affect `parse()` or any
30
+ * existing behavior. All subclasses inherit this automatically.
31
+ *
32
+ * @see https://standardschema.dev/
33
+ */
34
+ get '~standard'(): StandardSchemaV1.Props<unknown, T>;
23
35
  }
@@ -1,4 +1,3 @@
1
- import { readableToBuffer } from '../util/stream.js';
2
1
  import { BodyType } from './body.js';
3
2
  import { Issue, ValidationError } from './error.js';
4
3
  /**
@@ -6,6 +5,10 @@ import { Issue, ValidationError } from './error.js';
6
5
  */
7
6
  export class Schema extends BodyType {
8
7
  async deserialize(stream, contentType) {
8
+ // Lazy import to keep this module browser-safe for yedra/schema.
9
+ // deserialize() is only called server-side, so the Node-specific
10
+ // stream utility is never resolved when bundled for the frontend.
11
+ const { readableToBuffer } = await import('../util/stream.js');
9
12
  const buffer = await readableToBuffer(stream);
10
13
  if (buffer.length === 0) {
11
14
  return this.parse({});
@@ -31,4 +34,42 @@ export class Schema extends BodyType {
31
34
  isOptional() {
32
35
  return false;
33
36
  }
37
+ /**
38
+ * Standard Schema V1 compliance. This allows yedra schemas to be used
39
+ * directly with libraries that accept Standard Schema validators
40
+ * (e.g. TanStack Form, TanStack Router, tRPC).
41
+ *
42
+ * This is a non-breaking addition — it does not affect `parse()` or any
43
+ * existing behavior. All subclasses inherit this automatically.
44
+ *
45
+ * @see https://standardschema.dev/
46
+ */
47
+ get '~standard'() {
48
+ return {
49
+ version: 1,
50
+ vendor: 'yedra',
51
+ // Wraps parse() to match Standard Schema's non-throwing convention:
52
+ // returns { value } on success, { issues } on failure.
53
+ validate: (value) => {
54
+ try {
55
+ return { value: this.parse(value) };
56
+ }
57
+ catch (error) {
58
+ if (error instanceof ValidationError) {
59
+ return {
60
+ issues: error.issues.map((issue) => ({
61
+ message: issue.message,
62
+ // Convert array index strings ("0", "1") to numbers
63
+ path: issue.path.map((segment) => {
64
+ const num = Number(segment);
65
+ return Number.isInteger(num) && num >= 0 ? num : segment;
66
+ }),
67
+ })),
68
+ };
69
+ }
70
+ throw error;
71
+ }
72
+ },
73
+ };
74
+ }
34
75
  }
package/package.json CHANGED
@@ -1,42 +1,53 @@
1
1
  {
2
- "name": "yedra",
3
- "version": "0.20.0",
4
- "repository": "github:0codekit/yedra",
5
- "main": "dist/index.js",
6
- "devDependencies": {
7
- "@biomejs/biome": "^2.3.12",
8
- "@types/bun": "^1.3.6",
9
- "@types/node": "^25.0.10",
10
- "@types/uuid": "^11.0.0",
11
- "@types/ws": "^8.18.1",
12
- "typescript": "^5.9.3"
13
- },
14
- "bugs": "https://github.com/0codekit/yedra/issues",
15
- "contributors": [
16
- "Justus Zorn <jzorn@wemakefuture.com>"
17
- ],
18
- "description": "A TypeScript web framework with OpenAPI generation.",
19
- "keywords": [
20
- "typescript",
21
- "web",
22
- "http",
23
- "schema",
24
- "validation",
25
- "openapi"
26
- ],
27
- "license": "MIT",
28
- "files": [
29
- "./dist/**"
30
- ],
31
- "scripts": {
32
- "check": "biome check src/*"
33
- },
34
- "types": "dist/index.d.ts",
35
- "type": "module",
36
- "dependencies": {
37
- "@opentelemetry/api": "^1.9.0",
38
- "mime": "^4.1.0",
39
- "uuid": "^13.0.0",
40
- "ws": "^8.19.0"
41
- }
2
+ "name": "yedra",
3
+ "version": "0.20.2",
4
+ "repository": "github:0codekit/yedra",
5
+ "main": "dist/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "default": "./dist/index.js"
10
+ },
11
+ "./schema": {
12
+ "types": "./dist/schema.d.ts",
13
+ "default": "./dist/schema.js"
14
+ }
15
+ },
16
+ "devDependencies": {
17
+ "@biomejs/biome": "^2.3.14",
18
+ "@types/bun": "^1.3.9",
19
+ "@types/node": "^25.2.3",
20
+ "@types/uuid": "^11.0.0",
21
+ "@types/ws": "^8.18.1",
22
+ "typescript": "^5.9.3"
23
+ },
24
+ "bugs": "https://github.com/0codekit/yedra/issues",
25
+ "contributors": [
26
+ "Justus Zorn <jzorn@wemakefuture.com>"
27
+ ],
28
+ "description": "A TypeScript web framework with OpenAPI generation.",
29
+ "keywords": [
30
+ "typescript",
31
+ "web",
32
+ "http",
33
+ "schema",
34
+ "validation",
35
+ "openapi"
36
+ ],
37
+ "license": "MIT",
38
+ "files": [
39
+ "./dist/**"
40
+ ],
41
+ "scripts": {
42
+ "check": "biome check src/*"
43
+ },
44
+ "types": "dist/index.d.ts",
45
+ "type": "module",
46
+ "dependencies": {
47
+ "@opentelemetry/api": "^1.9.0",
48
+ "@standard-schema/spec": "^1.1.0",
49
+ "mime": "^4.1.0",
50
+ "uuid": "^13.0.0",
51
+ "ws": "^8.19.0"
52
+ }
42
53
  }