diff --git a/examples/minimal-react/CHANGELOG.md b/examples/minimal-react/CHANGELOG.md index 643236b5..22149ff5 100644 --- a/examples/minimal-react/CHANGELOG.md +++ b/examples/minimal-react/CHANGELOG.md @@ -1,5 +1,15 @@ # @examples/minimal-react +## 10.38.5 + +### Patch Changes + +- Updated dependencies + - @beff/client@0.0.8 + - @beff/hono@0.0.8 + - @beff/cli@0.0.8 + - @beff/react@0.0.8 + ## 10.38.4 ### Patch Changes diff --git a/examples/minimal-react/package.json b/examples/minimal-react/package.json index 688b06d8..28f0d0fd 100644 --- a/examples/minimal-react/package.json +++ b/examples/minimal-react/package.json @@ -1,7 +1,7 @@ { "name": "@examples/minimal-react", "private": true, - "version": "10.38.4", + "version": "10.38.5", "workspaces": [ "client", "server" @@ -26,10 +26,10 @@ "wait-port": "^1.0.1" }, "dependencies": { - "@beff/cli": "workspace:^0.0.7", - "@beff/client": "workspace:^0.0.7", - "@beff/hono": "workspace:^0.0.7", - "@beff/react": "workspace:^0.0.7", + "@beff/cli": "workspace:^0.0.8", + "@beff/client": "workspace:^0.0.8", + "@beff/hono": "workspace:^0.0.8", + "@beff/react": "workspace:^0.0.8", "@hono/node-server": "^1.1.1", "@tanstack/react-query": "^4.33.0", "@types/node": "^20.5.7", diff --git a/examples/node-server/CHANGELOG.md b/examples/node-server/CHANGELOG.md index d98ad376..015be89f 100644 --- a/examples/node-server/CHANGELOG.md +++ b/examples/node-server/CHANGELOG.md @@ -1,5 +1,13 @@ # node-server +## 1.0.4 + +### Patch Changes + +- Updated dependencies + - @beff/hono@0.0.8 + - @beff/cli@0.0.8 + ## 1.0.3 ### Patch Changes diff --git a/examples/node-server/package.json b/examples/node-server/package.json index a89d75f8..b6435009 100644 --- a/examples/node-server/package.json +++ b/examples/node-server/package.json @@ -1,6 +1,6 @@ { "name": "node-server", - "version": "1.0.3", + "version": "1.0.4", "description": "", "main": "index.js", "scripts": { @@ -12,8 +12,8 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/cli": "workspace:^0.0.7", - "@beff/hono": "workspace:^0.0.7", + "@beff/cli": "workspace:^0.0.8", + "@beff/hono": "workspace:^0.0.8", "@hono/node-server": "^1.1.1", "esbuild": "^0.19.2", "vitest": "^0.34.3" diff --git a/examples/standalone-parser/CHANGELOG.md b/examples/standalone-parser/CHANGELOG.md index 9d89d213..41c7d883 100644 --- a/examples/standalone-parser/CHANGELOG.md +++ b/examples/standalone-parser/CHANGELOG.md @@ -1,5 +1,12 @@ # node-server +## 1.0.5 + +### Patch Changes + +- Updated dependencies + - @beff/cli@0.0.8 + ## 1.0.4 ### Patch Changes diff --git a/examples/standalone-parser/package.json b/examples/standalone-parser/package.json index 93ed679a..45170037 100644 --- a/examples/standalone-parser/package.json +++ b/examples/standalone-parser/package.json @@ -1,6 +1,6 @@ { "name": "standalone-parser", - "version": "1.0.4", + "version": "1.0.5", "description": "", "main": "index.js", "scripts": { @@ -11,7 +11,7 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/cli": "workspace:^0.0.7", + "@beff/cli": "workspace:^0.0.8", "vitest": "^0.34.3" } } \ No newline at end of file diff --git a/packages/beff-cli/CHANGELOG.md b/packages/beff-cli/CHANGELOG.md index 0bfe22ce..ab6f2566 100644 --- a/packages/beff-cli/CHANGELOG.md +++ b/packages/beff-cli/CHANGELOG.md @@ -1,5 +1,11 @@ # @beff/cli +## 0.0.8 + +### Patch Changes + +- Support for optional parameters + ## 0.0.7 ### Patch Changes diff --git a/packages/beff-cli/package.json b/packages/beff-cli/package.json index 0a3d5e95..70076df6 100644 --- a/packages/beff-cli/package.json +++ b/packages/beff-cli/package.json @@ -1,6 +1,6 @@ { "name": "@beff/cli", - "version": "0.0.7", + "version": "0.0.8", "description": "", "bin": { "beff": "./bin/index.js" diff --git a/packages/beff-client/CHANGELOG.md b/packages/beff-client/CHANGELOG.md index e4b62943..7522264c 100644 --- a/packages/beff-client/CHANGELOG.md +++ b/packages/beff-client/CHANGELOG.md @@ -1,5 +1,13 @@ # @beff/client +## 0.0.8 + +### Patch Changes + +- Support for optional parameters +- Updated dependencies + - @beff/cli@0.0.8 + ## 0.0.7 ### Patch Changes diff --git a/packages/beff-client/package.json b/packages/beff-client/package.json index 63063b9f..cf2a2ce9 100644 --- a/packages/beff-client/package.json +++ b/packages/beff-client/package.json @@ -1,6 +1,6 @@ { "name": "@beff/client", - "version": "0.0.7", + "version": "0.0.8", "description": "", "main": "dist/cjs/index.js", "scripts": { @@ -18,7 +18,7 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/cli": "workspace:^0.0.7" + "@beff/cli": "workspace:^0.0.8" }, "devDependencies": { "typescript": "^5.2.2" diff --git a/packages/beff-client/src/index.ts b/packages/beff-client/src/index.ts index 5b51ea02..f99eb739 100644 --- a/packages/beff-client/src/index.ts +++ b/packages/beff-client/src/index.ts @@ -72,17 +72,25 @@ export class BffRequest { break; } case "query": { - if (!hasAddedQueryParams) { - path += "?"; - hasAddedQueryParams = true; - path += `${metadata.name}=${param}`; + if (!metadata.required && param == null) { + // skip optional query params } else { - path += `&${metadata.name}=${param}`; + if (!hasAddedQueryParams) { + path += "?"; + hasAddedQueryParams = true; + path += `${metadata.name}=${param}`; + } else { + path += `&${metadata.name}=${param}`; + } } break; } case "header": { - init.headers[metadata.name] = String(param); + if (!metadata.required && param == null) { + // skip optional headers + } else { + init.headers[metadata.name] = String(param); + } break; } case "body": { diff --git a/packages/beff-core/src/api_extractor.rs b/packages/beff-core/src/api_extractor.rs index c63e658b..fc350d6f 100644 --- a/packages/beff-core/src/api_extractor.rs +++ b/packages/beff-core/src/api_extractor.rs @@ -61,6 +61,36 @@ pub enum HandlerParameter { Context(Span), } +impl HandlerParameter { + pub fn make_optional(self: HandlerParameter) -> HandlerParameter { + match self { + HandlerParameter::PathOrQueryOrBody { + schema, + description, + span, + .. + } => HandlerParameter::PathOrQueryOrBody { + schema, + required: false, + description, + span, + }, + HandlerParameter::Header { + span, + schema, + description, + .. + } => HandlerParameter::Header { + span, + schema, + required: false, + description, + }, + HandlerParameter::Context(_) => self, + } + } +} + #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum MethodKind { Get(Span), @@ -477,7 +507,7 @@ impl<'a, R: FileManager> ExtractExportDefaultVisitor<'a, R> { &mut self, param: &Pat, parent_span: &Span, - ) -> Result> { + ) -> Result<(String, HandlerParameter)> { match param { Pat::Ident(BindingIdent { id, type_ann }) => { if type_ann.is_none() { @@ -492,12 +522,15 @@ impl<'a, R: FileManager> ExtractExportDefaultVisitor<'a, R> { comments.and_then(|it| self.parse_description_comment(it, &id.span)); let ty = self.assert_and_extract_type_from_ann(type_ann, &id.span); let param = self.parse_parameter_type(&ty, !id.optional, description, &id.span)?; - Ok(vec![(id.sym.to_string(), param)]) + Ok((id.sym.to_string(), param)) + } + Pat::Assign(AssignPat { span, left, .. }) => { + let (name, ty) = self.parse_arrow_parameter(left, span)?; + Ok((name, ty.make_optional())) } Pat::Rest(RestPat { span, .. }) | Pat::Array(ArrayPat { span, .. }) | Pat::Object(ObjectPat { span, .. }) - | Pat::Assign(AssignPat { span, .. }) | Pat::Invalid(Invalid { span, .. }) => { self.error(span, DiagnosticInfoMessage::ParameterPatternNotSupported) } @@ -557,7 +590,6 @@ impl<'a, R: FileManager> ExtractExportDefaultVisitor<'a, R> { .iter() .map(|it| self.parse_arrow_parameter(&it.pat, parent_span)) .collect::>>()?; - let parameters = parameters.into_iter().flatten().collect(); let e = FnHandler { method_kind: self.parse_method_kind(key)?, parameters, @@ -625,7 +657,6 @@ impl<'a, R: FileManager> ExtractExportDefaultVisitor<'a, R> { .map(|it| self.parse_arrow_parameter(it, parent_span)) .collect::>>()? .into_iter() - .flatten() .collect(), summary: endpoint_comments.summary, description: endpoint_comments.description, diff --git a/packages/beff-core/src/print/coercer.rs b/packages/beff-core/src/print/coercer.rs index 74ce3470..4ee68c7e 100644 --- a/packages/beff-core/src/print/coercer.rs +++ b/packages/beff-core/src/print/coercer.rs @@ -1,4 +1,4 @@ -use crate::{swc_builder::SwcBuilder, ast::json_schema::JsonSchema}; +use crate::{ast::json_schema::JsonSchema, swc_builder::SwcBuilder}; use swc_common::DUMMY_SP; use swc_ecma_ast::{ BindingIdent, BlockStmt, CallExpr, Callee, Expr, ExprOrSpread, FnExpr, Function, Ident, Param, @@ -25,11 +25,31 @@ fn coerce_primitive(value: Expr, p: &str) -> Expr { }) } +fn coercion_noop(value: Expr) -> Expr { + let decoder_ref_fn = Ident { + span: DUMMY_SP, + sym: format!("CoercionNoop").into(), + optional: false, + }; + let callee = Callee::Expr(Expr::Ident(decoder_ref_fn).into()); + Expr::Call(CallExpr { + span: DUMMY_SP, + callee: callee, + args: vec![ExprOrSpread { + spread: None, + expr: value.into(), + }], + type_args: None, + }) +} + struct CoercerFnGenerator {} impl CoercerFnGenerator { fn coerce_schema(&mut self, schema: &JsonSchema, value_ref: &Expr, depth: usize) -> Expr { match schema { - JsonSchema::Null | JsonSchema::Const(_) | JsonSchema::Any => value_ref.clone(), + JsonSchema::Null | JsonSchema::Const(_) | JsonSchema::Any => { + coercion_noop(value_ref.clone()) + } JsonSchema::Boolean => coerce_primitive(value_ref.clone(), "boolean"), JsonSchema::String => coerce_primitive(value_ref.clone(), "string"), JsonSchema::StringWithFormat(_) => coerce_primitive(value_ref.clone(), "string"), @@ -90,7 +110,7 @@ impl CoercerFnGenerator { let input = SwcBuilder::input_expr(); let stmts = vec![Stmt::Return(ReturnStmt { span: DUMMY_SP, - arg: Some(Box::new(self.coerce_schema(schema, &input, depth))), + arg: Some(self.coerce_schema(schema, &input, depth).into()), })]; Function { diff --git a/packages/beff-hono/CHANGELOG.md b/packages/beff-hono/CHANGELOG.md index 89a00041..f8455326 100644 --- a/packages/beff-hono/CHANGELOG.md +++ b/packages/beff-hono/CHANGELOG.md @@ -1,5 +1,14 @@ # @beff/hono +## 0.0.8 + +### Patch Changes + +- Support for optional parameters +- Updated dependencies + - @beff/client@0.0.8 + - @beff/cli@0.0.8 + ## 0.0.7 ### Patch Changes diff --git a/packages/beff-hono/package.json b/packages/beff-hono/package.json index ff61e06d..cb4bf1d9 100644 --- a/packages/beff-hono/package.json +++ b/packages/beff-hono/package.json @@ -1,6 +1,6 @@ { "name": "@beff/hono", - "version": "0.0.7", + "version": "0.0.8", "description": "", "main": "dist/cjs/index.js", "scripts": { @@ -18,8 +18,8 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/cli": "workspace:^0.0.7", - "@beff/client": "workspace:^0.0.7", + "@beff/cli": "workspace:^0.0.8", + "@beff/client": "workspace:^0.0.8", "hono": "^3.5.6", "vitest": "^0.34.3" }, diff --git a/packages/beff-hono/src/index.ts b/packages/beff-hono/src/index.ts index 0e120bc0..1a95a704 100644 --- a/packages/beff-hono/src/index.ts +++ b/packages/beff-hono/src/index.ts @@ -76,7 +76,7 @@ const redocTemplate = (baseUrl: string) => ` `; const coerce = (coercer: any, value: any): any => { - return coercer(value); + return coercer(value).data; }; const toHonoPattern = (pattern: string): string => { @@ -115,23 +115,7 @@ const prettyPrintErrorMessage = (it: DecodeError): string => { } }; -type CoercionFailure = { - __isCoercionFailure: true; - original: unknown; -}; - -const isCoercionFailure = (it: unknown): it is CoercionFailure => { - return ( - typeof it === "object" && - it != null && - "__isCoercionFailure" in it && - Boolean(it?.__isCoercionFailure) - ); -}; const prettyPrintValue = (it: unknown): string => { - if (isCoercionFailure(it)) { - return prettyPrintValue(it.original); - } if (typeof it === "string") { return `"${it}"`; } diff --git a/packages/beff-react/CHANGELOG.md b/packages/beff-react/CHANGELOG.md index 5381dae4..50ff22da 100644 --- a/packages/beff-react/CHANGELOG.md +++ b/packages/beff-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @beff/react +## 0.0.8 + +### Patch Changes + +- Support for optional parameters +- Updated dependencies + - @beff/client@0.0.8 + ## 0.0.7 ### Patch Changes diff --git a/packages/beff-react/package.json b/packages/beff-react/package.json index 3b30a75d..d8c485fb 100644 --- a/packages/beff-react/package.json +++ b/packages/beff-react/package.json @@ -1,6 +1,6 @@ { "name": "@beff/react", - "version": "0.0.7", + "version": "0.0.8", "description": "", "main": "dist/cjs/index.js", "scripts": { @@ -18,7 +18,7 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/client": "workspace:^0.0.7", + "@beff/client": "workspace:^0.0.8", "@tanstack/react-query": "^4.33.0", "react": "^18.2.0", "typescript": "^5.2.2" diff --git a/packages/beff-wasm/CHANGELOG.md b/packages/beff-wasm/CHANGELOG.md index 388f1b43..cb7d3d49 100644 --- a/packages/beff-wasm/CHANGELOG.md +++ b/packages/beff-wasm/CHANGELOG.md @@ -1,5 +1,11 @@ # beff-vscode +## 0.0.8 + +### Patch Changes + +- Support for optional parameters + ## 0.0.7 ### Patch Changes diff --git a/packages/beff-wasm/fixtures/codegen-snaps/decoder/bff-generated/router.js b/packages/beff-wasm/fixtures/codegen-snaps/decoder/bff-generated/router.js index 63827b3a..51331160 100644 --- a/packages/beff-wasm/fixtures/codegen-snaps/decoder/bff-generated/router.js +++ b/packages/beff-wasm/fixtures/codegen-snaps/decoder/bff-generated/router.js @@ -1,44 +1,63 @@ import vals from "./validators.js"; const { validators, add_path_to_errors, registerStringFormat, isCustomFormatInvalid } = vals; -class CoercionFailure { - constructor(original) { - this.__isCoercionFailure = true; - this.original = original + +function CoercionOk(data) { + return { + ok: true, + data, } } + +function CoercionNoop(data) { + return { + ok: false, + data, + } +} + + function coerce_string(input) { - return input; + if (typeof input === "string") { + return CoercionOk(input) + } + return CoercionNoop(input); } const isNumeric = (num) => (typeof num === "number" || (typeof num === "string" && num.trim() !== "")) && !isNaN(num ); function coerce_number(input) { + if (input == null) { + return CoercionNoop(input); + } if (isNumeric(input)) { - return Number(input); + return CoercionOk(Number(input)); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_boolean(input) { + if (input == null) { + return CoercionNoop(input); + } if (input === "true" || input === "false") { - return input === "true"; + return CoercionOk(input === "true"); } if (input === "1" || input === "0") { - return input === "1"; + return CoercionOk(input === "1"); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_union(input, ...cases) { + if (input == null) { + return CoercionNoop(input); + } for (const c of cases) { - const r = coerce(c, input); - if (!(r instanceof CoercionFailure)) { + const r = c(input); + if (r.ok) { return r; } } - return new CoercionFailure(input); -} -function coerce(coercer, value) { - return coercer(value); + return CoercionNoop(input); } const meta = [ diff --git a/packages/beff-wasm/fixtures/codegen-snaps/export-decoder/bff-generated/router.js b/packages/beff-wasm/fixtures/codegen-snaps/export-decoder/bff-generated/router.js index e42168bc..4daf2ac8 100644 --- a/packages/beff-wasm/fixtures/codegen-snaps/export-decoder/bff-generated/router.js +++ b/packages/beff-wasm/fixtures/codegen-snaps/export-decoder/bff-generated/router.js @@ -1,44 +1,63 @@ import vals from "./validators.js"; const { validators, add_path_to_errors, registerStringFormat, isCustomFormatInvalid } = vals; -class CoercionFailure { - constructor(original) { - this.__isCoercionFailure = true; - this.original = original + +function CoercionOk(data) { + return { + ok: true, + data, } } + +function CoercionNoop(data) { + return { + ok: false, + data, + } +} + + function coerce_string(input) { - return input; + if (typeof input === "string") { + return CoercionOk(input) + } + return CoercionNoop(input); } const isNumeric = (num) => (typeof num === "number" || (typeof num === "string" && num.trim() !== "")) && !isNaN(num ); function coerce_number(input) { + if (input == null) { + return CoercionNoop(input); + } if (isNumeric(input)) { - return Number(input); + return CoercionOk(Number(input)); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_boolean(input) { + if (input == null) { + return CoercionNoop(input); + } if (input === "true" || input === "false") { - return input === "true"; + return CoercionOk(input === "true"); } if (input === "1" || input === "0") { - return input === "1"; + return CoercionOk(input === "1"); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_union(input, ...cases) { + if (input == null) { + return CoercionNoop(input); + } for (const c of cases) { - const r = coerce(c, input); - if (!(r instanceof CoercionFailure)) { + const r = c(input); + if (r.ok) { return r; } } - return new CoercionFailure(input); -} -function coerce(coercer, value) { - return coercer(value); + return CoercionNoop(input); } const meta = [ diff --git a/packages/beff-wasm/fixtures/codegen-snaps/hello-server/bff-generated/router.js b/packages/beff-wasm/fixtures/codegen-snaps/hello-server/bff-generated/router.js index 7471a7f4..8d42b939 100644 --- a/packages/beff-wasm/fixtures/codegen-snaps/hello-server/bff-generated/router.js +++ b/packages/beff-wasm/fixtures/codegen-snaps/hello-server/bff-generated/router.js @@ -1,44 +1,63 @@ import vals from "./validators.js"; const { validators, add_path_to_errors, registerStringFormat, isCustomFormatInvalid } = vals; -class CoercionFailure { - constructor(original) { - this.__isCoercionFailure = true; - this.original = original + +function CoercionOk(data) { + return { + ok: true, + data, } } + +function CoercionNoop(data) { + return { + ok: false, + data, + } +} + + function coerce_string(input) { - return input; + if (typeof input === "string") { + return CoercionOk(input) + } + return CoercionNoop(input); } const isNumeric = (num) => (typeof num === "number" || (typeof num === "string" && num.trim() !== "")) && !isNaN(num ); function coerce_number(input) { + if (input == null) { + return CoercionNoop(input); + } if (isNumeric(input)) { - return Number(input); + return CoercionOk(Number(input)); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_boolean(input) { + if (input == null) { + return CoercionNoop(input); + } if (input === "true" || input === "false") { - return input === "true"; + return CoercionOk(input === "true"); } if (input === "1" || input === "0") { - return input === "1"; + return CoercionOk(input === "1"); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_union(input, ...cases) { + if (input == null) { + return CoercionNoop(input); + } for (const c of cases) { - const r = coerce(c, input); - if (!(r instanceof CoercionFailure)) { + const r = c(input); + if (r.ok) { return r; } } - return new CoercionFailure(input); -} -function coerce(coercer, value) { - return coercer(value); + return CoercionNoop(input); } const meta = [ diff --git a/packages/beff-wasm/fixtures/codegen-snaps/hono-context/bff-generated/router.js b/packages/beff-wasm/fixtures/codegen-snaps/hono-context/bff-generated/router.js index 231fd360..138d62cb 100644 --- a/packages/beff-wasm/fixtures/codegen-snaps/hono-context/bff-generated/router.js +++ b/packages/beff-wasm/fixtures/codegen-snaps/hono-context/bff-generated/router.js @@ -1,44 +1,63 @@ import vals from "./validators.js"; const { validators, add_path_to_errors, registerStringFormat, isCustomFormatInvalid } = vals; -class CoercionFailure { - constructor(original) { - this.__isCoercionFailure = true; - this.original = original + +function CoercionOk(data) { + return { + ok: true, + data, } } + +function CoercionNoop(data) { + return { + ok: false, + data, + } +} + + function coerce_string(input) { - return input; + if (typeof input === "string") { + return CoercionOk(input) + } + return CoercionNoop(input); } const isNumeric = (num) => (typeof num === "number" || (typeof num === "string" && num.trim() !== "")) && !isNaN(num ); function coerce_number(input) { + if (input == null) { + return CoercionNoop(input); + } if (isNumeric(input)) { - return Number(input); + return CoercionOk(Number(input)); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_boolean(input) { + if (input == null) { + return CoercionNoop(input); + } if (input === "true" || input === "false") { - return input === "true"; + return CoercionOk(input === "true"); } if (input === "1" || input === "0") { - return input === "1"; + return CoercionOk(input === "1"); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_union(input, ...cases) { + if (input == null) { + return CoercionNoop(input); + } for (const c of cases) { - const r = coerce(c, input); - if (!(r instanceof CoercionFailure)) { + const r = c(input); + if (r.ok) { return r; } } - return new CoercionFailure(input); -} -function coerce(coercer, value) { - return coercer(value); + return CoercionNoop(input); } const meta = [ diff --git a/packages/beff-wasm/fixtures/codegen-snaps/qualified-nested/bff-generated/router.js b/packages/beff-wasm/fixtures/codegen-snaps/qualified-nested/bff-generated/router.js index f416f212..53c25c58 100644 --- a/packages/beff-wasm/fixtures/codegen-snaps/qualified-nested/bff-generated/router.js +++ b/packages/beff-wasm/fixtures/codegen-snaps/qualified-nested/bff-generated/router.js @@ -1,44 +1,63 @@ import vals from "./validators.js"; const { validators, add_path_to_errors, registerStringFormat, isCustomFormatInvalid } = vals; -class CoercionFailure { - constructor(original) { - this.__isCoercionFailure = true; - this.original = original + +function CoercionOk(data) { + return { + ok: true, + data, } } + +function CoercionNoop(data) { + return { + ok: false, + data, + } +} + + function coerce_string(input) { - return input; + if (typeof input === "string") { + return CoercionOk(input) + } + return CoercionNoop(input); } const isNumeric = (num) => (typeof num === "number" || (typeof num === "string" && num.trim() !== "")) && !isNaN(num ); function coerce_number(input) { + if (input == null) { + return CoercionNoop(input); + } if (isNumeric(input)) { - return Number(input); + return CoercionOk(Number(input)); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_boolean(input) { + if (input == null) { + return CoercionNoop(input); + } if (input === "true" || input === "false") { - return input === "true"; + return CoercionOk(input === "true"); } if (input === "1" || input === "0") { - return input === "1"; + return CoercionOk(input === "1"); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_union(input, ...cases) { + if (input == null) { + return CoercionNoop(input); + } for (const c of cases) { - const r = coerce(c, input); - if (!(r instanceof CoercionFailure)) { + const r = c(input); + if (r.ok) { return r; } } - return new CoercionFailure(input); -} -function coerce(coercer, value) { - return coercer(value); + return CoercionNoop(input); } const meta = [ diff --git a/packages/beff-wasm/fixtures/codegen-snaps/qualified-types/bff-generated/router.js b/packages/beff-wasm/fixtures/codegen-snaps/qualified-types/bff-generated/router.js index 675872cf..3f4f9419 100644 --- a/packages/beff-wasm/fixtures/codegen-snaps/qualified-types/bff-generated/router.js +++ b/packages/beff-wasm/fixtures/codegen-snaps/qualified-types/bff-generated/router.js @@ -1,44 +1,63 @@ import vals from "./validators.js"; const { validators, add_path_to_errors, registerStringFormat, isCustomFormatInvalid } = vals; -class CoercionFailure { - constructor(original) { - this.__isCoercionFailure = true; - this.original = original + +function CoercionOk(data) { + return { + ok: true, + data, } } + +function CoercionNoop(data) { + return { + ok: false, + data, + } +} + + function coerce_string(input) { - return input; + if (typeof input === "string") { + return CoercionOk(input) + } + return CoercionNoop(input); } const isNumeric = (num) => (typeof num === "number" || (typeof num === "string" && num.trim() !== "")) && !isNaN(num ); function coerce_number(input) { + if (input == null) { + return CoercionNoop(input); + } if (isNumeric(input)) { - return Number(input); + return CoercionOk(Number(input)); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_boolean(input) { + if (input == null) { + return CoercionNoop(input); + } if (input === "true" || input === "false") { - return input === "true"; + return CoercionOk(input === "true"); } if (input === "1" || input === "0") { - return input === "1"; + return CoercionOk(input === "1"); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_union(input, ...cases) { + if (input == null) { + return CoercionNoop(input); + } for (const c of cases) { - const r = coerce(c, input); - if (!(r instanceof CoercionFailure)) { + const r = c(input); + if (r.ok) { return r; } } - return new CoercionFailure(input); -} -function coerce(coercer, value) { - return coercer(value); + return CoercionNoop(input); } const meta = [ diff --git a/packages/beff-wasm/fixtures/errors/pattern-args/stderr.log b/packages/beff-wasm/fixtures/errors/pattern-args/stderr.log index 3c3c0735..bd5482e8 100644 --- a/packages/beff-wasm/fixtures/errors/pattern-args/stderr.log +++ b/packages/beff-wasm/fixtures/errors/pattern-args/stderr.log @@ -18,12 +18,12 @@ Error: Parameter pattern is not supported 16 | }, 17 | }, -Error: Parameter pattern is not supported +Error: Invalid context usage /errors/pattern-args/app.ts:19:17 17 | }, 18 | [`/user2`]: { > 19 | get: async (a: string[] = []): Promise => { - | ^^^^^^^^^^^^^^^^ Parameter pattern is not supported + | ^^^^^^^^^^^ Context must be the first parameter 20 | return todo(); 21 | }, 22 | }, diff --git a/packages/beff-wasm/package.json b/packages/beff-wasm/package.json index 05e62f06..03f7f631 100644 --- a/packages/beff-wasm/package.json +++ b/packages/beff-wasm/package.json @@ -1,7 +1,7 @@ { "name": "beff-vscode", "publisher": "beff", - "version": "0.0.7", + "version": "0.0.8", "description": "", "engines": { "vscode": "^1.73.0" @@ -40,8 +40,8 @@ }, "devDependencies": { "@babel/code-frame": "^7.22.13", - "@beff/cli": "workspace:^0.0.7", - "@beff/hono": "workspace:^0.0.7", + "@beff/cli": "workspace:^0.0.8", + "@beff/hono": "workspace:^0.0.8", "@types/babel__code-frame": "^7.0.3", "@types/node": "^20.5.7", "@types/vscode": "^1.73.0", diff --git a/packages/beff-wasm/ts-node/bundle-to-disk.ts b/packages/beff-wasm/ts-node/bundle-to-disk.ts index 97dc6bbe..23277de9 100644 --- a/packages/beff-wasm/ts-node/bundle-to-disk.ts +++ b/packages/beff-wasm/ts-node/bundle-to-disk.ts @@ -39,44 +39,63 @@ declare const _exports: { meta: HandlerMetaClient[] }; export default _exports; `; const coercerCode = ` -class CoercionFailure { - constructor(original) { - this.__isCoercionFailure = true; - this.original = original + +function CoercionOk(data) { + return { + ok: true, + data, } } + +function CoercionNoop(data) { + return { + ok: false, + data, + } +} + + function coerce_string(input) { - return input; + if (typeof input === "string") { + return CoercionOk(input) + } + return CoercionNoop(input); } const isNumeric = (num) => (typeof num === "number" || (typeof num === "string" && num.trim() !== "")) && !isNaN(num ); function coerce_number(input) { + if (input == null) { + return CoercionNoop(input); + } if (isNumeric(input)) { - return Number(input); + return CoercionOk(Number(input)); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_boolean(input) { + if (input == null) { + return CoercionNoop(input); + } if (input === "true" || input === "false") { - return input === "true"; + return CoercionOk(input === "true"); } if (input === "1" || input === "0") { - return input === "1"; + return CoercionOk(input === "1"); } - return new CoercionFailure(input); + return CoercionNoop(input); } function coerce_union(input, ...cases) { + if (input == null) { + return CoercionNoop(input); + } for (const c of cases) { - const r = coerce(c, input); - if (!(r instanceof CoercionFailure)) { + const r = c(input); + if (r.ok) { return r; } } - return new CoercionFailure(input); -} -function coerce(coercer, value) { - return coercer(value); + return CoercionNoop(input); } `; diff --git a/packages/beff-wasm/vitest/params/__tests__/router.test.ts b/packages/beff-wasm/vitest/params/__tests__/router.test.ts index a5f50b61..3b174ef6 100644 --- a/packages/beff-wasm/vitest/params/__tests__/router.test.ts +++ b/packages/beff-wasm/vitest/params/__tests__/router.test.ts @@ -97,3 +97,11 @@ it("coerce", async () => { '"456"' ); }); + +it("default param", async () => { + expect(await beff["/with-default"].get()).toMatchInlineSnapshot("1"); + expect(await beff["/with-default"].post()).toMatchInlineSnapshot("1"); + + expect(await beff["/with-default"].get(5)).toMatchInlineSnapshot("5"); + expect(await beff["/with-default"].post(5)).toMatchInlineSnapshot("5"); +}); diff --git a/packages/beff-wasm/vitest/params/router.ts b/packages/beff-wasm/vitest/params/router.ts index 72af6c71..6e2d1a98 100644 --- a/packages/beff-wasm/vitest/params/router.ts +++ b/packages/beff-wasm/vitest/params/router.ts @@ -60,5 +60,13 @@ export default { return id; }, }, + "/with-default": { + get: async (c: Ctx, page: number = 1) => { + return page; + }, + post: async (c: Ctx, page: number | undefined = 1) => { + return page; + }, + }, }; type ValidIds = 123 | 456; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 004f55df..d48e9a61 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,16 +19,16 @@ importers: examples/minimal-react: dependencies: '@beff/cli': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-cli '@beff/client': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-client '@beff/hono': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-hono '@beff/react': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-react '@hono/node-server': specifier: ^1.1.1 @@ -80,10 +80,10 @@ importers: examples/node-server: dependencies: '@beff/cli': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-cli '@beff/hono': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-hono '@hono/node-server': specifier: ^1.1.1 @@ -98,7 +98,7 @@ importers: examples/standalone-parser: dependencies: '@beff/cli': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-cli vitest: specifier: ^0.34.3 @@ -109,7 +109,7 @@ importers: packages/beff-client: dependencies: '@beff/cli': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../beff-cli devDependencies: typescript: @@ -121,10 +121,10 @@ importers: packages/beff-hono: dependencies: '@beff/cli': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../beff-cli '@beff/client': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../beff-client hono: specifier: ^3.5.6 @@ -140,7 +140,7 @@ importers: packages/beff-react: dependencies: '@beff/client': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../beff-client '@tanstack/react-query': specifier: ^4.33.0 @@ -162,10 +162,10 @@ importers: specifier: ^7.22.13 version: 7.22.13 '@beff/cli': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../beff-cli '@beff/hono': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../beff-hono '@types/babel__code-frame': specifier: ^7.0.3 @@ -201,10 +201,10 @@ importers: tests/node-docs: dependencies: '@beff/cli': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-cli '@beff/hono': - specifier: workspace:^0.0.7 + specifier: workspace:^0.0.8 version: link:../../packages/beff-hono '@hono/node-server': specifier: ^1.1.1 diff --git a/tests/node-docs/CHANGELOG.md b/tests/node-docs/CHANGELOG.md index 08637c43..fc24beda 100644 --- a/tests/node-docs/CHANGELOG.md +++ b/tests/node-docs/CHANGELOG.md @@ -1,5 +1,13 @@ # node-docs +## 1.0.5 + +### Patch Changes + +- Updated dependencies + - @beff/hono@0.0.8 + - @beff/cli@0.0.8 + ## 1.0.4 ### Patch Changes diff --git a/tests/node-docs/package.json b/tests/node-docs/package.json index 89ccbb8c..40d9d6a1 100644 --- a/tests/node-docs/package.json +++ b/tests/node-docs/package.json @@ -1,6 +1,6 @@ { "name": "node-docs", - "version": "1.0.4", + "version": "1.0.5", "description": "", "main": "index.js", "scripts": { @@ -13,8 +13,8 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/cli": "workspace:^0.0.7", - "@beff/hono": "workspace:^0.0.7", + "@beff/cli": "workspace:^0.0.8", + "@beff/hono": "workspace:^0.0.8", "@hono/node-server": "^1.1.1", "esbuild": "^0.19.2", "vitest": "^0.34.3"