diff --git a/examples/example.jrpc b/examples/example.jrpc index cecfccf..f555267 100644 --- a/examples/example.jrpc +++ b/examples/example.jrpc @@ -1,6 +1,7 @@ import "./import"; define csharp_namespace Example; +define rust_crate example; enum TestEnum { VAL1, @@ -14,17 +15,17 @@ type Test { atom: TestAtom; array: TestAtom[]; enumValue: TestEnum; - map: {number, TestAtom}; + map: {int, TestAtom}; } type AddValueRequest { - value1: number; - value2: number; + value1: float; + value2: float; } type AddValueResponse { - value: number; + value: float; } service TestService { @@ -36,11 +37,11 @@ service TestService { @Description("Add two numbers") @Param("value1", "The first value") @Param("value2", "The second value") - AddValuesMultipleParams(value1: number, value2: number): number; + AddValuesMultipleParams(value1: float, value2: float): float; @Description("Does literaly nothing") @Param("param1", "Some number") - ReturningVoid(param1: number): void; + ReturningVoid(param1: float): void; @Description("Just sends an Event with a String") @Param("param1", "Parameter with some string for event") @@ -49,5 +50,5 @@ service TestService { ThrowingError(): void; - FunctionWithArrayAsParamAndReturn(values1: number[], values2: number[]): number[]; + FunctionWithArrayAsParamAndReturn(values1: float[], values2: float[]): float[]; } diff --git a/examples/import.jrpc b/examples/import.jrpc index 58196ff..e44c177 100644 --- a/examples/import.jrpc +++ b/examples/import.jrpc @@ -1,5 +1,5 @@ type TestAtom { - val_number: number; + val_number: float; val_boolean: boolean; val_string: string; } diff --git a/lib/jrpc.js b/lib/jrpc.js index 99aa043..455fa1a 100755 --- a/lib/jrpc.js +++ b/lib/jrpc.js @@ -9876,7 +9876,7 @@ function parse(tokens, file) { // src/ir.ts var import_debug = __toESM(require_src()); var log = (0, import_debug.default)("app"); -var BUILTIN = ["number", "string", "boolean"]; +var BUILTIN = ["float", "int", "string", "boolean"]; var IRError = class extends Error { constructor(statement, message) { super("Error building IR: " + message); @@ -9912,7 +9912,7 @@ function get_ir(parsed) { if (depends.indexOf(field.fieldtype) < 0) depends.push(field.fieldtype); } - if (field.map && field.map !== "number" && field.map !== "string") { + if (field.map && field.map !== "int" && field.map !== "string") { throw new IRError(field, `Type ${field.map} is not valid as map key!`); } return { @@ -10047,6 +10047,7 @@ function get_ir(parsed) { } else if (statement.type == "define") { options[statement.key] = statement.value; if ((statement.key == "use_messagepack" || statement.key == "allow_bytes") && statement.value == "true") { + options["allow_bytes"] = true; builtin.push("bytes"); } } else { @@ -10074,10 +10075,14 @@ var CompileTarget = class { } } writeFile(name, content) { + let resPath = Path.join(this.outputFolder, name); + let resDir = Path.dirname(resPath); + if (!FS.existsSync(resDir)) + FS.mkdirSync(resDir, { recursive: true }); if (content instanceof Promise) { - content.then((res) => FS.writeFileSync(Path.join(this.outputFolder, name), res)); + content.then((res) => FS.writeFileSync(resPath, res)); } else { - FS.writeFileSync(Path.join(this.outputFolder, name), content); + FS.writeFileSync(resPath, content); } } getTemplate(name) { @@ -10120,7 +10125,8 @@ function compile(ir, target) { // src/targets/typescript.ts var conversion = { boolean: "boolean", - number: "number", + int: "number", + float: "number", string: "string", void: "void", bytes: "Uint8Array" @@ -10139,7 +10145,7 @@ var TypescriptTarget = class extends CompileTarget { `; } generateImports(a, def) { - a(0, this.generateImport(`{ VerificationError, apply_number, apply_string, apply_boolean, apply_void }`, `./ts_base`)); + a(0, this.generateImport(`{ VerificationError, apply_int, apply_float, apply_string, apply_boolean, apply_void }`, `./ts_base`)); a(0, def.depends.map((dep) => this.generateImport(`${dep}, { apply_${dep} }`, "./" + dep))); } getFileName(typename) { @@ -10440,7 +10446,8 @@ var NodeJSTypescriptTarget = class extends TypescriptTarget { // src/targets/csharp.ts var conversion2 = { boolean: "bool", - number: "double", + int: "long", + float: "double", string: "string", void: "void", bytes: "" @@ -10454,8 +10461,8 @@ var CSharpTarget = class extends CompileTarget { return this.options.csharp_namespace || "JRPC"; } start() { - if (this.options.use_messagepack == true) { - throw new Error("C# has no support for MessagePack yet!"); + if (this.options.allow_bytes == true) { + throw new Error("C# has no support for 'bytes' yet!"); } this.writeFile(this.namespace + ".csproj", this.getTemplate("CSharp/CSharp.csproj")); const fixNS = (input) => input.replace("__NAMESPACE__", this.namespace); diff --git a/package.json b/package.json index 2a2108d..2bf5aa8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hibas123/jrpcgen", - "version": "1.0.31", + "version": "1.1.1", "main": "lib/index.js", "license": "MIT", "packageManager": "yarn@3.1.1", @@ -19,7 +19,7 @@ "files": [ "lib/jrpc.js", "templates/**", - "examples/**", + "examples/*.jrpc", "src/**", "tsconfig.json" ], diff --git a/src/compile.ts b/src/compile.ts index 76193a9..07f0be3 100644 --- a/src/compile.ts +++ b/src/compile.ts @@ -1,5 +1,5 @@ import * as FS from "fs"; -import * as FSE from "fs-extra" +import * as FSE from "fs-extra"; import * as Path from "path"; import { EnumDefinition, @@ -11,7 +11,10 @@ import { export abstract class CompileTarget { abstract name: string; - constructor(private outputFolder: string, protected options: T & { use_messagepack: boolean }) { + constructor( + private outputFolder: string, + protected options: T & { allow_bytes: boolean } + ) { if (!FS.existsSync(outputFolder)) { FS.mkdirSync(outputFolder, { recursive: true, @@ -30,12 +33,13 @@ export abstract class CompileTarget { abstract finalize(steps: Step[]): void; protected writeFile(name: string, content: string | Promise) { + let resPath = Path.join(this.outputFolder, name); + let resDir = Path.dirname(resPath); + if (!FS.existsSync(resDir)) FS.mkdirSync(resDir, { recursive: true }); if (content instanceof Promise) { - content.then((res) => - FS.writeFileSync(Path.join(this.outputFolder, name), res) - ); + content.then((res) => FS.writeFileSync(resPath, res)); } else { - FS.writeFileSync(Path.join(this.outputFolder, name), content); + FS.writeFileSync(resPath, content); } } @@ -59,12 +63,10 @@ export abstract class CompileTarget { return res.join("\n"); } - protected loadTemplateFolder(name:string) { + protected loadTemplateFolder(name: string) { let root = Path.join(__dirname, "../templates/", name); - - FSE.copySync(root, this.outputFolder, { - }); + FSE.copySync(root, this.outputFolder, {}); } } diff --git a/src/ir.ts b/src/ir.ts index 3fccf48..b360796 100644 --- a/src/ir.ts +++ b/src/ir.ts @@ -2,7 +2,7 @@ import type { Parsed, StatementNode } from "./parser"; import dbg from "debug"; const log = dbg("app"); -const BUILTIN = ["number", "string", "boolean"]; +const BUILTIN = ["float", "int", "string", "boolean"]; export class IRError extends Error { constructor(public statement: StatementNode, message: string) { @@ -115,7 +115,7 @@ export default function get_ir(parsed: Parsed): IR { depends.push(field.fieldtype); } - if (field.map && field.map !== "number" && field.map !== "string") { + if (field.map && field.map !== "int" && field.map !== "string") { throw new IRError( field, `Type ${field.map} is not valid as map key!` @@ -312,6 +312,7 @@ export default function get_ir(parsed: Parsed): IR { statement.key == "allow_bytes") && statement.value == "true" ) { + options["allow_bytes"] = true; builtin.push("bytes"); } } else { diff --git a/src/process.ts b/src/process.ts index d8cc255..3140445 100644 --- a/src/process.ts +++ b/src/process.ts @@ -22,7 +22,6 @@ Targets.set("ts-esm", ESMTypescriptTarget); Targets.set("ts-node", NodeJSTypescriptTarget); Targets.set("c#", CSharpTarget as typeof CompileTarget); - function indexToLineAndCol(src: string, index: number) { let line = 1; let col = 1; diff --git a/src/targets/csharp.ts b/src/targets/csharp.ts index c30b154..82e75ae 100644 --- a/src/targets/csharp.ts +++ b/src/targets/csharp.ts @@ -12,10 +12,11 @@ type lineAppender = (ind: number, line: string | string[]) => void; const conversion = { boolean: "bool", - number: "double", + int: "long", + float: "double", string: "string", void: "void", - bytes: "" + bytes: "", }; function toCSharpType(type: string): string { @@ -30,8 +31,8 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> { } start(): void { - if(this.options.use_messagepack == true) { - throw new Error("C# has no support for MessagePack yet!"); + if (this.options.allow_bytes == true) { + throw new Error("C# has no support for 'bytes' yet!"); } this.writeFile( this.namespace + ".csproj", diff --git a/src/targets/typescript.ts b/src/targets/typescript.ts index a8103d0..9dbcb71 100644 --- a/src/targets/typescript.ts +++ b/src/targets/typescript.ts @@ -13,7 +13,8 @@ type lineAppender = (ind: number, line: string | string[]) => void; const conversion = { boolean: "boolean", - number: "number", + int: "number", + float: "number", string: "string", void: "void", bytes: "Uint8Array", @@ -45,7 +46,7 @@ export class TypescriptTarget extends CompileTarget { a( 0, this.generateImport( - `{ VerificationError, apply_number, apply_string, apply_boolean, apply_void }`, + `{ VerificationError, apply_int, apply_float, apply_string, apply_boolean, apply_void }`, `./ts_base` ) ); diff --git a/templates/ts_base.ts b/templates/ts_base.ts index e94ca58..7c27aa2 100644 --- a/templates/ts_base.ts +++ b/templates/ts_base.ts @@ -4,13 +4,24 @@ export class VerificationError extends Error { public readonly field?: string, public readonly value?: any ) { - super("Parameter verification failed! " +(type ? "Expected " + type + "! " :"") + (field ? "At: " + field + "! " : "")); + super( + "Parameter verification failed! " + + (type ? "Expected " + type + "! " : "") + + (field ? "At: " + field + "! " : "") + ); } } -export function apply_number(data: any) { +export function apply_int(data: any) { + data = Math.floor(Number(data)); + if (Number.isNaN(data)) throw new VerificationError("int", undefined, data); + return data; +} + +export function apply_float(data: any) { data = Number(data); - if(Number.isNaN(data)) throw new VerificationError("number", undefined, data); + if (Number.isNaN(data)) + throw new VerificationError("float", undefined, data); return data; }