diff --git a/e2e-tests/standalone-parser/CHANGELOG.md b/e2e-tests/standalone-parser/CHANGELOG.md index 6a0769ea..35738689 100644 --- a/e2e-tests/standalone-parser/CHANGELOG.md +++ b/e2e-tests/standalone-parser/CHANGELOG.md @@ -1,5 +1,13 @@ # node-server +## 1.0.55 + +### Patch Changes + +- Updated dependencies + - @beff/cli@0.0.58 + - @beff/client@0.0.58 + ## 1.0.54 ### Patch Changes diff --git a/e2e-tests/standalone-parser/package.json b/e2e-tests/standalone-parser/package.json index bdba93fa..26b07a53 100644 --- a/e2e-tests/standalone-parser/package.json +++ b/e2e-tests/standalone-parser/package.json @@ -1,6 +1,6 @@ { "name": "standalone-parser", - "version": "1.0.54", + "version": "1.0.55", "description": "", "main": "index.js", "scripts": { @@ -11,7 +11,7 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/cli": "workspace:^0.0.57", + "@beff/cli": "workspace:^0.0.58", "@beff/client": "workspace:^", "vitest": "^0.34.4", "zod": "^3.23.5" diff --git a/packages/beff-cli/CHANGELOG.md b/packages/beff-cli/CHANGELOG.md index 7becf385..5f05eed4 100644 --- a/packages/beff-cli/CHANGELOG.md +++ b/packages/beff-cli/CHANGELOG.md @@ -1,5 +1,11 @@ # @beff/cli +## 0.0.58 + +### Patch Changes + +- typeof enum + ## 0.0.57 ### Patch Changes diff --git a/packages/beff-cli/package.json b/packages/beff-cli/package.json index 7824b52e..eef3c826 100644 --- a/packages/beff-cli/package.json +++ b/packages/beff-cli/package.json @@ -1,6 +1,6 @@ { "name": "@beff/cli", - "version": "0.0.57", + "version": "0.0.58", "description": "", "bin": { "beff": "./bin/index.js" diff --git a/packages/beff-client/CHANGELOG.md b/packages/beff-client/CHANGELOG.md index b21b9437..146ace65 100644 --- a/packages/beff-client/CHANGELOG.md +++ b/packages/beff-client/CHANGELOG.md @@ -1,5 +1,13 @@ # @beff/client +## 0.0.58 + +### Patch Changes + +- typeof enum +- Updated dependencies + - @beff/cli@0.0.58 + ## 0.0.57 ### Patch Changes diff --git a/packages/beff-client/package.json b/packages/beff-client/package.json index 276cabc1..93ba9779 100644 --- a/packages/beff-client/package.json +++ b/packages/beff-client/package.json @@ -1,6 +1,6 @@ { "name": "@beff/client", - "version": "0.0.57", + "version": "0.0.58", "description": "", "main": "dist/cjs/index.js", "scripts": { @@ -20,7 +20,7 @@ "author": "", "license": "ISC", "dependencies": { - "@beff/cli": "workspace:^0.0.57", + "@beff/cli": "workspace:^0.0.58", "zod": "^3.23.5" }, "devDependencies": { diff --git a/packages/beff-core/src/diag.rs b/packages/beff-core/src/diag.rs index 4d6c8343..93184503 100644 --- a/packages/beff-core/src/diag.rs +++ b/packages/beff-core/src/diag.rs @@ -7,6 +7,7 @@ use crate::{BffFileName, ParsedModule}; #[derive(Debug, Clone)] pub enum DiagnosticInfoMessage { + EnumMemberNotFound, TplLitTypeUnsupported, TwoCallsToBuildSchemas, CannotResolveRefInJsonSchemaToTplLit, @@ -459,6 +460,7 @@ impl DiagnosticInfoMessage { DiagnosticInfoMessage::TplLitTypeUnsupported => { "Template literal type is not supported".to_string() } + DiagnosticInfoMessage::EnumMemberNotFound => "Enum member not found".to_string(), } } } diff --git a/packages/beff-core/src/sym_reference.rs b/packages/beff-core/src/sym_reference.rs index d1d009f6..4bf92c2a 100644 --- a/packages/beff-core/src/sym_reference.rs +++ b/packages/beff-core/src/sym_reference.rs @@ -249,6 +249,10 @@ impl<'a, R: FileManager> TypeResolver<'a, R> { return Ok(ResolvedLocalSymbol::Expr(alias.clone())); } + if let Some(enum_) = self.get_current_file().locals.enums.get(k) { + return Ok(ResolvedLocalSymbol::TsEnumDecl(enum_.clone())); + } + if let Some(exported) = self .get_current_file() .symbol_exports diff --git a/packages/beff-core/src/type_to_schema.rs b/packages/beff-core/src/type_to_schema.rs index ec6af8f5..d5956c31 100644 --- a/packages/beff-core/src/type_to_schema.rs +++ b/packages/beff-core/src/type_to_schema.rs @@ -1327,6 +1327,38 @@ impl<'a, 'b, R: FileManager> TypeToSchema<'a, 'b, R> { Expr::TsSatisfies(c) => self.typeof_expr(&c.expr, as_const), Expr::Member(m) => { let mut ctx = SemTypeContext::new(); + if let Expr::Ident(i) = &m.obj.as_ref() { + let s = + TypeResolver::new(self.files, &self.current_file).resolve_local_value(i)?; + if let ResolvedLocalSymbol::TsEnumDecl(decl) = s { + // check if enum contains the member + let prop = match &m.prop { + MemberProp::Ident(i) => Some(i.sym.to_string()), + MemberProp::Computed(c) => match self.typeof_expr(&c.expr, as_const)? { + JsonSchema::Const(JsonSchemaConst::String(s)) => Some(s.clone()), + _ => None, + }, + MemberProp::PrivateName(_) => None, + }; + let prop_str = prop.unwrap_or("".to_string()); + let found = decl.members.iter().find(|it| { + // + match &it.id { + TsEnumMemberId::Ident(i2) => { + i2.sym.to_string() == prop_str.as_str() + } + TsEnumMemberId::Str(_) => unreachable!(), + } + }); + + if let Some(_found) = found { + // return the enum's type + return self.convert_enum_decl(&decl); + } + return self + .error(&m.prop.span(), DiagnosticInfoMessage::EnumMemberNotFound); + } + } let obj = self.typeof_expr(&m.obj, as_const)?; if let JsonSchema::Object { vs, rest: _ } = &obj { // try to do it syntatically to preserve aliases @@ -1507,9 +1539,7 @@ impl<'a, 'b, R: FileManager> TypeToSchema<'a, 'b, R> { self.collect_value_exports(&file_name, &mut acc)?; Ok(JsonSchema::object(acc, None)) } - ResolvedLocalSymbol::TsEnumDecl(_) => { - self.error(span, DiagnosticInfoMessage::TypeofTsEnumNotSupported) - } + ResolvedLocalSymbol::TsEnumDecl(enum_decl) => self.convert_enum_decl(&enum_decl), ResolvedLocalSymbol::TsBuiltin(_) => { self.error(span, DiagnosticInfoMessage::TypeOfTsBuiltinNotSupported) } diff --git a/packages/beff-core/tests/print_parser.rs b/packages/beff-core/tests/print_parser.rs index fd1d6cb0..3a140a76 100644 --- a/packages/beff-core/tests/print_parser.rs +++ b/packages/beff-core/tests/print_parser.rs @@ -549,6 +549,32 @@ mod tests { "#)); } #[test] + fn ok_repro10() { + insta::assert_snapshot!(ok(r#" + enum E { + A="A", + B="B" + }; + export const ABC = {a: E.B, } as const satisfies Record; + export type AllTs = (keyof typeof ABC); + + parse.buildParsers<{ AllTs: AllTs }>(); + "#)); + } + #[test] + fn ok_repro11() { + insta::assert_snapshot!(ok(r#" + enum E { + A="A", + B="B" + }; + const val = E.B as const; + export type AllTs = typeof val; + + parse.buildParsers<{ AllTs: AllTs }>(); + "#)); + } + #[test] fn ok_void() { insta::assert_snapshot!(ok(r#" export type IX = void diff --git a/packages/beff-core/tests/snapshots/print_parser__tests__ok_repro10.snap b/packages/beff-core/tests/snapshots/print_parser__tests__ok_repro10.snap new file mode 100644 index 00000000..dd149c64 --- /dev/null +++ b/packages/beff-core/tests/snapshots/print_parser__tests__ok_repro10.snap @@ -0,0 +1,6 @@ +--- +source: packages/beff-core/tests/print_parser.rs +expression: "ok(r#\"\n enum E {\n A=\"A\",\n B=\"B\"\n };\n export const ABC = {a: E.B, } as const satisfies Record;\n export type AllTs = (keyof typeof ABC);\n\n parse.buildParsers<{ AllTs: AllTs }>();\n \"#)" +--- +type AllTs = "a"; +type AllTs = AllTs; diff --git a/packages/beff-core/tests/snapshots/print_parser__tests__ok_repro11.snap b/packages/beff-core/tests/snapshots/print_parser__tests__ok_repro11.snap new file mode 100644 index 00000000..538f278a --- /dev/null +++ b/packages/beff-core/tests/snapshots/print_parser__tests__ok_repro11.snap @@ -0,0 +1,6 @@ +--- +source: packages/beff-core/tests/print_parser.rs +expression: "ok(r#\"\n enum E {\n A=\"A\",\n B=\"B\"\n };\n const val = E.B as const;\n export type AllTs = typeof val;\n\n parse.buildParsers<{ AllTs: AllTs }>();\n \"#)" +--- +type AllTs = "A" | "B"; +type AllTs = AllTs; diff --git a/packages/beff-wasm/package.json b/packages/beff-wasm/package.json index 995967d1..2e293de7 100644 --- a/packages/beff-wasm/package.json +++ b/packages/beff-wasm/package.json @@ -41,7 +41,7 @@ }, "devDependencies": { "@babel/code-frame": "^7.22.13", - "@beff/cli": "workspace:^0.0.57", + "@beff/cli": "workspace:^0.0.58", "@types/babel__code-frame": "^7.0.4", "@types/node": "^20.6.2", "@types/vscode": "^1.73.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c5ce949..0534a61e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,7 +34,7 @@ importers: e2e-tests/standalone-parser: dependencies: '@beff/cli': - specifier: workspace:^0.0.57 + specifier: workspace:^0.0.58 version: link:../../packages/beff-cli '@beff/client': specifier: workspace:^ @@ -55,7 +55,7 @@ importers: packages/beff-client: dependencies: '@beff/cli': - specifier: workspace:^0.0.57 + specifier: workspace:^0.0.58 version: link:../beff-cli zod: specifier: ^3.23.5 @@ -89,7 +89,7 @@ importers: specifier: ^7.22.13 version: 7.22.13 '@beff/cli': - specifier: workspace:^0.0.57 + specifier: workspace:^0.0.58 version: link:../beff-cli '@types/babel__code-frame': specifier: ^7.0.4