diff --git a/__tests__/invalid-request.test.ts b/__tests__/invalid-request.test.ts index 96dc3f87..fd324e16 100644 --- a/__tests__/invalid-request.test.ts +++ b/__tests__/invalid-request.test.ts @@ -396,7 +396,10 @@ describe('cancels invalid request', () => { totalErrors: 2, // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment firstValidationErrors: expect.arrayContaining([ - { path: '/mustSendThings', message: 'Required property' }, + { + path: '/mustSendThings', + message: 'Expected required property', + }, { path: '/mustSendThings', message: 'Expected string' }, ]), }, @@ -595,7 +598,10 @@ describe('cancels invalid request', () => { totalErrors: 2, // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment firstValidationErrors: expect.arrayContaining([ - { path: '/newRequiredField', message: 'Required property' }, + { + path: '/newRequiredField', + message: 'Expected required property', + }, { path: '/newRequiredField', message: 'Expected string' }, ]), }, diff --git a/package-lock.json b/package-lock.json index fb4e64f5..76f7e78d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@replit/river", - "version": "0.208.2", + "version": "0.208.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@replit/river", - "version": "0.208.2", + "version": "0.208.3", "license": "MIT", "dependencies": { "@msgpack/msgpack": "^3.0.0-beta2", @@ -14,9 +14,11 @@ "ws": "^8.17.0" }, "devDependencies": { + "@opentelemetry/api": "^1.7.0", "@opentelemetry/context-async-hooks": "^1.26.0", "@opentelemetry/core": "^1.7.0", "@opentelemetry/sdk-trace-base": "^1.24.1", + "@sinclair/typebox": "~0.34.0", "@stylistic/eslint-plugin": "^2.6.4", "@types/ws": "^8.5.5", "@typescript-eslint/eslint-plugin": "^7.8.0", @@ -35,7 +37,7 @@ }, "peerDependencies": { "@opentelemetry/api": "^1.7.0", - "@sinclair/typebox": "~0.32.8 || ~0.34.0" + "@sinclair/typebox": "~0.34.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -708,7 +710,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", - "peer": true, + "dev": true, "engines": { "node": ">=8.0.0" } @@ -1079,10 +1081,10 @@ ] }, "node_modules/@sinclair/typebox": { - "version": "0.32.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.32.8.tgz", - "integrity": "sha512-ifqNG6GBr0QRao2Vy+2P2WzxkOnpGmHfZCFXWwuR/0elH4h79mGXN8mEYwnJ2qGEr7MGgfqvf8Njwj4dBGFMBA==", - "peer": true + "version": "0.34.33", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.33.tgz", + "integrity": "sha512-5HAV9exOMcXRUxo+9iYB5n09XxzCXnfy4VTNW4xnDv+FgjzAGY989C28BIdljKqmF+ZltUwujE3aossvcVtq6g==", + "dev": true }, "node_modules/@stylistic/eslint-plugin": { "version": "2.6.4", @@ -4723,7 +4725,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", - "peer": true + "dev": true }, "@opentelemetry/context-async-hooks": { "version": "1.26.0", @@ -4921,10 +4923,10 @@ "optional": true }, "@sinclair/typebox": { - "version": "0.32.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.32.8.tgz", - "integrity": "sha512-ifqNG6GBr0QRao2Vy+2P2WzxkOnpGmHfZCFXWwuR/0elH4h79mGXN8mEYwnJ2qGEr7MGgfqvf8Njwj4dBGFMBA==", - "peer": true + "version": "0.34.33", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.33.tgz", + "integrity": "sha512-5HAV9exOMcXRUxo+9iYB5n09XxzCXnfy4VTNW4xnDv+FgjzAGY989C28BIdljKqmF+ZltUwujE3aossvcVtq6g==", + "dev": true }, "@stylistic/eslint-plugin": { "version": "2.6.4", diff --git a/package.json b/package.json index 696faa5b..8e446816 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@replit/river", "description": "It's like tRPC but... with JSON Schema Support, duplex streaming and support for service multiplexing. Transport agnostic!", - "version": "0.208.2", + "version": "0.208.3", "type": "module", "exports": { ".": { @@ -54,12 +54,14 @@ }, "peerDependencies": { "@opentelemetry/api": "^1.7.0", - "@sinclair/typebox": "~0.32.8 || ~0.34.0" + "@sinclair/typebox": "~0.34.0" }, "devDependencies": { + "@opentelemetry/api": "^1.7.0", "@opentelemetry/context-async-hooks": "^1.26.0", "@opentelemetry/core": "^1.7.0", "@opentelemetry/sdk-trace-base": "^1.24.1", + "@sinclair/typebox": "~0.34.0", "@stylistic/eslint-plugin": "^2.6.4", "@types/ws": "^8.5.5", "@typescript-eslint/eslint-plugin": "^7.8.0", diff --git a/router/services.ts b/router/services.ts index e2eaec1d..e575ef0b 100644 --- a/router/services.ts +++ b/router/services.ts @@ -160,6 +160,15 @@ export interface SerializedServerSchemaProtocolv1 { services: Record; } +/** + * Omits compositing symbols from this schema. + * The same approach that was previously used in the deprecated Type.Strict function. + * https://github.com/sinclairzx81/typebox/blob/master/changelog/0.34.0.md#strict + */ +export function Strict(schema: T): T { + return JSON.parse(JSON.stringify(schema)) as T; +} + // TODO remove once clients migrate to v2 /** * Same as {@link serializeSchema} but with a format that is compatible with @@ -183,7 +192,7 @@ export function serializeSchemaV1Compat( }; if (handshakeSchema) { - schema.handshakeSchema = Type.Strict(handshakeSchema); + schema.handshakeSchema = Strict(handshakeSchema); } return schema; @@ -226,7 +235,7 @@ export function serializeSchema( }; if (handshakeSchema) { - schema.handshakeSchema = Type.Strict(handshakeSchema); + schema.handshakeSchema = Strict(handshakeSchema); } return schema; @@ -439,8 +448,8 @@ export class ServiceSchema< Object.entries(this.procedures).map(([procName, procDef]) => [ procName, { - init: Type.Strict(procDef.requestInit), - output: Type.Strict(procDef.responseData), + init: Strict(procDef.requestInit), + output: Strict(procDef.responseData), errors: getSerializedProcErrors(procDef), // Only add `description` field if the type declares it. ...('description' in procDef @@ -450,7 +459,7 @@ export class ServiceSchema< // Only add the `input` field if the type declares it. ...('requestData' in procDef ? { - input: Type.Strict(procDef.requestData), + input: Strict(procDef.requestData), } : {}), }, @@ -479,8 +488,8 @@ export class ServiceSchema< { // BACKWARDS COMPAT: map init to input for protocolv1 // this is the only change needed to make it compatible. - input: Type.Strict(procDef.requestInit), - output: Type.Strict(procDef.responseData), + input: Strict(procDef.requestInit), + output: Strict(procDef.responseData), errors: getSerializedProcErrors(procDef), // Only add `description` field if the type declares it. ...('description' in procDef @@ -496,15 +505,15 @@ export class ServiceSchema< return [ procName, { - init: Type.Strict(procDef.requestInit), - output: Type.Strict(procDef.responseData), + init: Strict(procDef.requestInit), + output: Strict(procDef.responseData), errors: getSerializedProcErrors(procDef), // Only add `description` field if the type declares it. ...('description' in procDef ? { description: procDef.description } : {}), type: procDef.type, - input: Type.Strict(procDef.requestData), + input: Strict(procDef.requestData), }, ]; }, @@ -541,14 +550,14 @@ function getSerializedProcErrors( !('responseError' in procDef) || procDef.responseError[Kind] === 'Never' ) { - return Type.Strict(ReaderErrorSchema); + return Strict(ReaderErrorSchema); } const withProtocolErrors = flattenErrorType( Type.Union([procDef.responseError, ReaderErrorSchema]), ); - return Type.Strict(withProtocolErrors); + return Strict(withProtocolErrors); } /**