{"_id":"@alsadi/json_rpc_server","_rev":"4-4b86ea5652e68cd5323cae9df96f1861","name":"@alsadi/json_rpc_server","dist-tags":{"latest":"0.1.2"},"versions":{"0.0.1":{"name":"@alsadi/json_rpc_server","version":"0.0.1","description":"simple json rpc server and tools","exports":{".":"./index.js"},"types":"./index.d.ts","main":"index.js","type":"module","scripts":{"lint":"eslint -c .eslintrc.json *.js lib/**/*.js","lintfix":"eslint -c .eslintrc.json --fix *.js lib/**/*.js","test":"node --es-module-specifier-resolution=node --abort-on-uncaught-exception --unhandled-rejections=strict --trace-warnings ./test.js","types":"tsc *.js lib/**/*.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts","repl":"node -r esm","build":"rollup -c","dev":"rollup -c -w"},"dependencies":{"@alsadi/simple_http_server":"0.0.3"},"private":false,"author":{"name":"alsadi@gmail.com"},"license":"Apache-2.0","devDependencies":{"@rollup/plugin-commonjs":"^17.0.0","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^11.0.0","@rollup/plugin-replace":"^2.4.2","@typescript-eslint/parser":"^4.16.1","eslint":"^7.21.0","eslint-config-google":"^0.14.0","eslint-config-standard":"^16.0.2","eslint-plugin-compat":"^3.9.0","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1","eslint-plugin-security":"^1.4.0","esm":"^3.2.25","rollup":"^2.3.4","rollup-plugin-css-chunks":"^2.0.3","rollup-plugin-css-only":"^3.1.0","rollup-plugin-delete":"^2.0.0","rollup-plugin-extract-bundle-tree":"^1.2.0","rollup-plugin-import-assets":"^1.1.1","rollup-plugin-livereload":"^2.0.0","rollup-plugin-multi-input":"^1.3.1","rollup-plugin-svelte":"^7.0.0","rollup-plugin-terser":"^7.0.0","typescript":"^4.2.3"},"directories":{"lib":"lib"},"repository":{"type":"git","url":"git+https://github.com/muayyad-alsadi/node-json-rpc.git"},"keywords":["json-rpc","http","server"],"bugs":{"url":"https://github.com/muayyad-alsadi/node-json-rpc/issues"},"homepage":"https://github.com/muayyad-alsadi/node-json-rpc#readme","gitHead":"41285bef2902ad2e7bfbe7f99f2bb12547b86eae","_id":"@alsadi/json_rpc_server@0.0.1","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-57i4ai/QNCW0qUUDIfQemjnEXyeNv0X7Wj8AWIQsCoX6qrAga/4r/0QORSi5xBJbDi3aPq2OuKIs3y8vCdBdZw==","shasum":"84eefc32865ee84e5576c7d2cce854050e6b65ea","tarball":"https://registry.npmjs.org/@alsadi/json_rpc_server/-/json_rpc_server-0.0.1.tgz","fileCount":10,"unpackedSize":10781,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg3N5TCRA9TVsSAnZWagAAzBsP/jnYDovJ7lT3po5ETh4V\nqsTrZjr1T5cglbE7mC+2Y+tyamSS9fnuXnMRFRPPpXIFgQwoRR+yD+3hiILQ\ntNcI7iG7WF0QfPaMAWm5LSaW718hsqptp+P7nax0Irdyedww+4Ocmj0wB3tK\ne5hyRA9RggMFxupHeL7dyiY6y3vS4616Zf0OnKrvjQjICNqgEalt7tivEWI4\nZnezVM3LV7+YNAybSZfQgil1DgFlpVPzMcNEUfPhh4/jdxLzq+A0ipZ1YHiD\nNyEV1hVJ2iNeALxZn7yf0/K2LCaqAjVPPD5+NZUtA4yc8yb5ME6TVBrtrXtg\nXQBFtNz6yKWWH/LbvzXQLG0nmup3LIKo7TeXGM0lbdheas39OT3SKEjPCGTq\nK9+F8qQaDr1w/rVN8GBLPhXZQkWgtL4Zv0xZmPMguc8vddm85zo7fJqbWq7D\nUykLNISYIa2cVM8v+V1EQvm3KXu8YbPslB+7CYFkuWO7HBXO72eG5KwIXQmM\nDSxW1dPcu8wZFg4SGqvYrz9maDobjYKmO0e3FwchwWK0RpLPIC1kVevWJ/pc\nlAFdaP4uqJ2uiDmeFnTNjlzXOFWTZ2DGdfxXe9nJGR/6LVHDMij+Ldsdg3w/\nzIoAr4lzCsyR2IbffeIJjFlTAiac0QXx9ItHqLB9rrhPs1/ijb7bXm5WPZk2\nb/zH\r\n=kNgG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDGeWE05KTOKZTfHCOQN+I8jTtEn/cxZeNlnpBdW0XCywIhAMASgk6Oac+a+q+VgUfh3PDIG5TgMZJeJNrTVgTNtb5u"}]},"_npmUser":{"name":"alsadi","email":"alsadi@gmail.com"},"maintainers":[{"name":"alsadi","email":"alsadi@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/json_rpc_server_0.0.1_1625087571056_0.47469905862568873"},"_hasShrinkwrap":false},"0.1.0":{"name":"@alsadi/json_rpc_server","version":"0.1.0","description":"simple json rpc server and tools","exports":{".":"./index.js"},"types":"./index.d.ts","main":"index.js","type":"module","scripts":{"lint":"eslint -c .eslintrc.json *.js lib/**/*.js","lintfix":"eslint -c .eslintrc.json --fix *.js lib/**/*.js","demo":"node --es-module-specifier-resolution=node --abort-on-uncaught-exception --unhandled-rejections=strict --trace-warnings ./demo.js","types":"tsc *.js lib/**/*.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts","repl":"node -r esm","build":"rollup -c","dev":"rollup -c -w"},"dependencies":{"@alsadi/simple_http_server":"0.0.7","ws":"^7.5.2"},"private":false,"author":{"name":"alsadi@gmail.com"},"license":"Apache-2.0","devDependencies":{"@rollup/plugin-commonjs":"^17.0.0","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^11.0.0","@rollup/plugin-replace":"^2.4.2","@typescript-eslint/parser":"^4.16.1","eslint":"^7.21.0","eslint-config-google":"^0.14.0","eslint-config-standard":"^16.0.2","eslint-plugin-compat":"^3.9.0","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1","eslint-plugin-security":"^1.4.0","esm":"^3.2.25","rollup":"^2.3.4","rollup-plugin-css-chunks":"^2.0.3","rollup-plugin-css-only":"^3.1.0","rollup-plugin-delete":"^2.0.0","rollup-plugin-extract-bundle-tree":"^1.2.0","rollup-plugin-import-assets":"^1.1.1","rollup-plugin-livereload":"^2.0.0","rollup-plugin-multi-input":"^1.3.1","rollup-plugin-svelte":"^7.0.0","rollup-plugin-terser":"^7.0.0","typescript":"^4.2.3"},"directories":{"lib":"lib"},"repository":{"type":"git","url":"git+https://github.com/muayyad-alsadi/node-json-rpc.git"},"keywords":["json-rpc","http","server"],"bugs":{"url":"https://github.com/muayyad-alsadi/node-json-rpc/issues"},"homepage":"https://github.com/muayyad-alsadi/node-json-rpc#readme","gitHead":"9bfce5570ee962be39088516d8de8b25ad962c84","_id":"@alsadi/json_rpc_server@0.1.0","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-1+lJykqP1RGC/29gKwChTLEEoZTJbLbsVr/cPaVNhnPSf1E7pviidE+8kMUzGlhU0ckMIM7IPK2UbTM80DZnhw==","shasum":"ea2201c3e86e6a925f36a70fa8e15101beda802e","tarball":"https://registry.npmjs.org/@alsadi/json_rpc_server/-/json_rpc_server-0.1.0.tgz","fileCount":10,"unpackedSize":24768,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg6GU7CRA9TVsSAnZWagAAbaQQAKED/AoyznLCwrXFywtW\nvH5y8y+Cc+pSTxe0yhjy9z8SKY/8aNzYXeYbo8PGozjsix/6iFUWneN9VpU8\nqFeJk/2GoypbZX8dL9RjI8Zwpw0QJVKfwbJmuSd6u2El61e/Phy56wa8tyoD\nvp/8pTJTAkcWoQCWSUVOOTmOG1uy01fNwxU16FhzXac/JLZjGw01fPjZX8oh\n2Vta8aemRt3CNODQT+iijWpZNheTiS4r7cFWKVKhvB3buSawvW8i6nJ75bsn\nEMPRuqmQ7qIKDXfhVk55aaXSSS2mTc5NIf/8ZdF4EdRLCjexq4UVM+RifepU\nKn07wp2MXhqj99LxgvPb4dzcnE1L/BOq0H/6esiTwHh1+nyUEwvfUOVYOisO\nmSPinV2WvVOlAJgsQ1Vx9gQpimZWcThFyl2uVtaN0UWCXJQJlxDQmGuZVEbD\n8WfkUixy8t58J+IrHcHLN+J94RdT3Tqma4rw3CSnRLLrVFAKX9FprJS9k8uE\nVFy+9D5b1ZY5BJCIhHWuw8DCMnluHr9JwrrDIIKytvypJ+Ycm3IcJOzjb1u2\n3pOjpS/3isWK4VVk8/LsdQkjazDyBuyP/O/S/Z2PEAXmKnZRGFUZa/A64nBQ\nJB7cPlmiF4hRHJNI7cMOPwyK31BVXTajfmrBimf1nMz0pNFDkHdjT8EbTtgH\n32nH\r\n=7cbF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFWm0lT5eTGW0yONYTNzI2qBZpl0MpK02YkDOb/06O7tAiBLRNbftHOiJxDq4YJpfmybJX6oQz970+qw4Ny6tKIKRQ=="}]},"_npmUser":{"name":"alsadi","email":"alsadi@gmail.com"},"maintainers":[{"name":"alsadi","email":"alsadi@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/json_rpc_server_0.1.0_1625843003162_0.3929607560214765"},"_hasShrinkwrap":false},"0.1.1":{"name":"@alsadi/json_rpc_server","version":"0.1.1","description":"simple json rpc server and tools","exports":{".":"./index.js"},"types":"./index.d.ts","main":"index.js","type":"module","scripts":{"lint":"eslint -c .eslintrc.json *.js lib/**/*.js","lintfix":"eslint -c .eslintrc.json --fix *.js lib/**/*.js","demo":"node --es-module-specifier-resolution=node --abort-on-uncaught-exception --unhandled-rejections=strict --trace-warnings ./demo.js","types":"tsc *.js lib/**/*.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts","repl":"node -r esm","build":"rollup -c","dev":"rollup -c -w"},"dependencies":{"@alsadi/simple_http_server":"0.0.7"},"private":false,"author":{"name":"alsadi@gmail.com"},"license":"Apache-2.0","devDependencies":{"ws":"^7.5.2","@rollup/plugin-commonjs":"^17.0.0","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^11.0.0","@rollup/plugin-replace":"^2.4.2","@typescript-eslint/parser":"^4.16.1","eslint":"^7.21.0","eslint-config-google":"^0.14.0","eslint-config-standard":"^16.0.2","eslint-plugin-compat":"^3.9.0","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1","eslint-plugin-security":"^1.4.0","esm":"^3.2.25","rollup":"^2.3.4","rollup-plugin-css-chunks":"^2.0.3","rollup-plugin-css-only":"^3.1.0","rollup-plugin-delete":"^2.0.0","rollup-plugin-extract-bundle-tree":"^1.2.0","rollup-plugin-import-assets":"^1.1.1","rollup-plugin-livereload":"^2.0.0","rollup-plugin-multi-input":"^1.3.1","rollup-plugin-svelte":"^7.0.0","rollup-plugin-terser":"^7.0.0","typescript":"^4.2.3"},"directories":{"lib":"lib"},"repository":{"type":"git","url":"git+https://github.com/muayyad-alsadi/node-json-rpc.git"},"keywords":["json-rpc","http","server"],"bugs":{"url":"https://github.com/muayyad-alsadi/node-json-rpc/issues"},"homepage":"https://github.com/muayyad-alsadi/node-json-rpc#readme","gitHead":"840654211c82f54def598a3f3236cea3eb0a5336","_id":"@alsadi/json_rpc_server@0.1.1","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-24vfLaeX7UBMRQz6n/O3w1bO9T8EqjRULR7SRwYDFq9/y00sNyd3Okk4tnHA8pfzErcKbIeM9jTKVn9bAB94kA==","shasum":"fd4138b251045546efe422b89f24d80ebf1fb566","tarball":"https://registry.npmjs.org/@alsadi/json_rpc_server/-/json_rpc_server-0.1.1.tgz","fileCount":10,"unpackedSize":25031,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg6dgiCRA9TVsSAnZWagAA3LoQAI5i7dh0LI009nKsVRcZ\nCCnn2RVSMPonph6sJSFTMQoCOHuKtL818+0BeunrhUoC0QEy+M3PfkPQnWbT\nLWCMPEBpSqQwQbd1WBsl/Gjb61eQTZIm53Vs0OQGZ5n/Rfys5kG6RQBnXSNr\ncUYteLNxhhs8aZcRMDDhaDR25Dt5nYxRuKh2GLjDjUD0NFiKbmf9UIj2faSX\n+nejDc6Bf1H30EeUlvZuywAlWSEpH2UDh9JcjsotnEzWtqA+1Sb18SNTFiGp\ndTkVJUn80JAWO1t+/E3WxaM58clTAIa4PdTH/Ywuc09slL6TwBGddzd3IrzA\n6VO8Y7zgJ9eD9QvODIa8nsgyJcGq/s5J5kMjnL6AA0AW6HuLBKlQPcnKATdA\nJqMiiy95xl+jC9w/JlZ1WMyiOWRVCryyNFMPDz9ba+75OtI2AW+aL57nQWJx\nkR4m7Nsv+TxOyY4s4VO665isLyPr69q4BFAqEyV8HZRoYixi317t/3feoVh8\no73ZtNGtcEECBvKb78x4xv7VAYMIGwgpGKS9gxLEuzDZMPjmDs7Krro8eyOv\nwQP6pVHkc182INDphOlDeYuGQbTy421FTluoi709LblwPp1zEuXe+fRZmfP8\nid+xmetZ8s9bldtQfBE6lO3V/LIOln+TeRoE43ayqgE4bPxI4CQ1XW1pUoMX\nvD2b\r\n=wEsR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCHRxmto+GvUwghr7oo/k7UCs4x+UEgQH0SLl+OnF5iOgIhANrpLR0hk9nj3W+CCZiUxLNV8uaDZWbMPUT21NHzoftT"}]},"_npmUser":{"name":"alsadi","email":"alsadi@gmail.com"},"maintainers":[{"name":"alsadi","email":"alsadi@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/json_rpc_server_0.1.1_1625937954160_0.454857718813906"},"_hasShrinkwrap":false},"0.1.2":{"name":"@alsadi/json_rpc_server","version":"0.1.2","description":"simple json rpc server and tools","exports":{".":"./index.js"},"types":"./index.d.ts","main":"index.js","type":"module","scripts":{"lint":"eslint -c .eslintrc.json *.js lib/**/*.js","lintfix":"eslint -c .eslintrc.json --fix *.js lib/**/*.js","demo":"node --es-module-specifier-resolution=node --abort-on-uncaught-exception --unhandled-rejections=strict --trace-warnings ./demo.js","types":"tsc *.js lib/**/*.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts","repl":"node -r esm","build":"rollup -c","dev":"rollup -c -w"},"dependencies":{"@alsadi/simple_http_server":"0.0.7"},"private":false,"author":{"name":"alsadi@gmail.com"},"license":"Apache-2.0","devDependencies":{"ws":"^7.5.2","@rollup/plugin-commonjs":"^17.0.0","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^11.0.0","@rollup/plugin-replace":"^2.4.2","@typescript-eslint/parser":"^4.16.1","eslint":"^7.21.0","eslint-config-google":"^0.14.0","eslint-config-standard":"^16.0.2","eslint-plugin-compat":"^3.9.0","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1","eslint-plugin-security":"^1.4.0","esm":"^3.2.25","rollup":"^2.3.4","rollup-plugin-css-chunks":"^2.0.3","rollup-plugin-css-only":"^3.1.0","rollup-plugin-delete":"^2.0.0","rollup-plugin-extract-bundle-tree":"^1.2.0","rollup-plugin-import-assets":"^1.1.1","rollup-plugin-livereload":"^2.0.0","rollup-plugin-multi-input":"^1.3.1","rollup-plugin-svelte":"^7.0.0","rollup-plugin-terser":"^7.0.0","typescript":"^4.2.3"},"directories":{"lib":"lib"},"repository":{"type":"git","url":"git+https://github.com/muayyad-alsadi/node-json-rpc.git"},"keywords":["json-rpc","http","server"],"bugs":{"url":"https://github.com/muayyad-alsadi/node-json-rpc/issues"},"homepage":"https://github.com/muayyad-alsadi/node-json-rpc#readme","gitHead":"ab83f5e692e99983fb8e9c5234e340b5da9dd4a2","_id":"@alsadi/json_rpc_server@0.1.2","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-n0hQXl/76Osgbwh+KBcXq7BrWaR18iA+NsF4q7FFUOWmG1qJcKwCZAm3LPgkio0WF0LPtuqyz/kSbld4H068sw==","shasum":"36772d2e7fc45c73710eb95c63f0546d5b6a3b89","tarball":"https://registry.npmjs.org/@alsadi/json_rpc_server/-/json_rpc_server-0.1.2.tgz","fileCount":10,"unpackedSize":25037,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg6q1ZCRA9TVsSAnZWagAAlyYQAICaA5CmpN5vc2p6xj+W\nb14A4WeMNmiEboQKo7cbPeQXIzKxmMEoZ8UQ98UeowgEW+7UsaBMA6g8Rux7\nzgYnPxvHIdObTGkIXPNSV/tZi0sveUPnqs+jMG+QQmu4MgVsxM1Pkr4vUR6P\nN0867XMfh9P08rR50kn1UaBtGCuG6j/AFNr2LiGlpXC9b74goWohquiQajcR\nGnkRHCZ2EPGeP4536ew6qo4n5r2X8xTtEeE4WhM9acZu7ZXDir5r7H7ZldcK\nszhSqbByiDIWiJMz7OkZd11yluqZDuPhbmcPO28Hq9TlUqIJnWfjFtVv5/hc\n+9SSY33jCnJwc+hHD27a9VrLHth6hJZd09UXFuVuvlzV4AxHUli8LmFXpCLL\nnw/hBzEZS4SGFCL48VYyu20rC7V938vbXQj6bMTgv5hNq24vIXVSRHucQjgt\npq+Kh0TqbZ7p2sSIo695y7unrIPXhDP5a/JKpzJz/GnCsFuJPHlFBkh9Ba0K\n2YfzWdwzYWGNxIaxdKKd+CtLOpA6ECVJC3zT4uEnfRH5I2vTfOvCa/rc4FwJ\nuCBiNp8LI7V1S9djrTnLC2/W/brgkvpS9Y3pZlSfJkM95sO+BGRr6OWR1mJS\nJ0Xt6sb0NZf695/Wq+CpuSuBwDcqOGS48uwwHZm0c7tSnds0bfUgto7A9STc\n1PHi\r\n=WW+T\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDwAKW13/jj+tJflEtb/VAr7zrvZslLMSTuymn+dwQgwwIgAZc//L1zHQZehhhEt1RIItZTJYkeShdWY4mR9zvPEow="}]},"_npmUser":{"name":"alsadi","email":"alsadi@gmail.com"},"maintainers":[{"name":"alsadi","email":"alsadi@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/json_rpc_server_0.1.2_1625992537163_0.6509153104696477"},"_hasShrinkwrap":false}},"time":{"created":"2021-06-30T21:12:51.003Z","0.0.1":"2021-06-30T21:12:51.213Z","modified":"2022-04-04T13:38:55.860Z","0.1.0":"2021-07-09T15:03:23.297Z","0.1.1":"2021-07-10T17:25:54.361Z","0.1.2":"2021-07-11T08:35:37.339Z"},"maintainers":[{"name":"alsadi","email":"alsadi@gmail.com"}],"description":"simple json rpc server and tools","homepage":"https://github.com/muayyad-alsadi/node-json-rpc#readme","keywords":["json-rpc","http","server"],"repository":{"type":"git","url":"git+https://github.com/muayyad-alsadi/node-json-rpc.git"},"author":{"name":"alsadi@gmail.com"},"bugs":{"url":"https://github.com/muayyad-alsadi/node-json-rpc/issues"},"license":"Apache-2.0","readme":"# JsonRpcServer\n\nA simple JSON-RPC implementation for [Node.js](http://nodejs.org/) that works via HTTP or WebSockets. You can get it via [npm install](https://www.npmjs.com/package/@alsadi/json_rpc_server).\n\n[![NPM](https://nodei.co/npm/@alsadi/json_rpc_server.png?downloads=true&downloadRank=true)](https://nodei.co/npm/@alsadi/json_rpc_server)\n\n\n```shell\nnpm install --save '@alsadi/json_rpc_server'\n```\n\n```javascript\nimport {JsonRpcHttpServer} from \"@alsadi/json_rpc_server\";\n\nasync function books_list({page, per_page}) {\n    // simulate database lookup\n    per_page = per_page || 10;\n    const items = [];\n    for (let i=0, j=(page-1)*per_page; i<per_page; ++i, ++j) {\n        items.push({id: j, title: `book #${j} title goes here`});\n    }\n    return {items};\n} \n\n(async function() {\n    const server = new JsonRpcHttpServer(\"rpc\", [\"assets\", \"index.html\", \"favicon.ico\"], \"./public\");\n    server.add_method(\"books.list\", books_list);\n    server.listen(8080);\n})();\n```\n\nYou can use strict standard request like this\n\n```shell\ncurl -X POST -d '{\"jsonrpc\": \"2.0\", \"method\": \"books.list\", \"params\":{\"page\":1, \"per_page\":10}, \"id\":\"xyz\"}' 'http://localhost:8080/rpc' | jq\n```\n\nor simply, our extension\n\n```shell\ncurl -X POST -d '{\"params\":{\"page\":1, \"per_page\": 10}}' 'http://localhost:8080/rpc/books.list' | jq\n```\n\n## Included Demo\n\nType `npm run demo` which starts a server on port 8080 both HTTP and WebSocket.\n\n## Validation\n\nadjust the code above to pass validate method that throws exceptions\nor return false in case of invalid params, like this:\n\n```javascript\nfunction books_list_validate(params) {\n    const {page, per_page} = params;\n    if (!Number.isInteger(page)) {\n        throw new Error(\"page should be integer\");\n    }\n    if (!Number.isInteger(per_page)) {\n        const e = new Error(\"page should be integer\");\n        e.code = 'invalid-per-page-value';\n        e.field = \"per_page\";\n        throw e;\n    }\n    return true;\n}\nserver.add_method(\"books.list\", books_list, books_list_validate);\n```\n\nFor validation you can:\n\n* Throw a coded exception (an exception with code property)\n  * you can use short cut like `FieldValidationError(field, msg)` or `ValidationError(validations, msg)`\n* return false with reasons of key being the param with a list of problems like this\n\n```javascript\nthrow new FieldValidationError(\"field1\", \"reason 1\");\nthrow new ValidationError({\n    \"field1\":[\"reason 1\", \"reason 2\"],\n    \"field2\":[\"reason 3\"],\n});\nreturn [false, {\n    \"page\": [\"required field is missing\"],\n    \"per_page\": [\"should be in range 1-100\"],\n}];\n```\n\n## Automatic Validations\n\nYou don't need to write validation yourself as you can generate validators from your code (TS type-hints or JS-Doc):\n\n* generate [JSON-Schema](https://json-schema.org/) from JS-Doc comments using [jsdoc-api](https://www.npmjs.com/package/jsdoc-api).\n* or you can also use `TypeScript` to generate [`.d.ts` file](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html) from your code and then convert that to JSON-Schema and create run-time validators: [ts-to-json](https://github.com/ccpu/ts-to-json), [typescript-json-schema](https://github.com/YousefED/typescript-json-schema), [node-ts2json](https://github.com/jeremyfa/node-ts2json), ,[ts-json-object](https://github.com/moshegottlieb/ts-json-object), [ts-interface-checker](https://github.com/gristlabs/ts-interface-checker), [https://github.com/mizchi/dts-parser](https://github.com/mizchi/dts-parser), [io-ts](https://github.com/gcanti/io-ts), [parse-ts](https://github.com/jethrolarson/parse-ts).\n\nfor even use [TS compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API)\nusing\n\n```bash\ntsc lib/**/*.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts\n```\n\n\n```javascript\nconst ts = require(\"typescript\");\nlet r=ts.createSourceFile(\"index.d.ts\", fs.readFileSync(\"index.d.ts\", \"utf-8\"), ts.ScriptTarget.Latest)\nlet filename = \"web/books\"\nlet func = \"action_list\"\nconsole.log(JSON.stringify(r.statements.filter(i=>i.name.text==filename)[0].body.statements.filter(i=>i.name.text==func)[0].parameters[0].type.members, null, 2))\n```\n\n* use [ajv](https://ajv.js.org/) to validate input params.\n\nThe best part about the above approach that the expensive part is done at build-time not runtime.\n\n```javascript\nasync function() {\n    // ...\n    const method_name = \"books.list\";\n    const schema_name = `rpc.${name}`;\n    const fn = `${schema_name}.json`;\n    const schema_str = (await fs.promises.readFile(`./schemas/${fn}`)).toString();\n    const schema = JSON.parse(schema_str);\n    ajv.addSchema(schema, name);\n    // ...\n    const validate = proj.ajv.getSchema(schema_name);\n    server.add_method(method_name, callback, validate);\n}\n```\n\n## Interface Description Language (IDL)\n\nYou can use JSON-Schema above as Interface Description Language (IDL) and generate OpenAPI/Swagger Automatically.\nJust generate url: `./public/build/swagger.json` that contains all the JSON schemas like this\n\n```javascript\n{\n  \"openapi\": \"3.0.1\",\n  \"paths\": {\n    \"/books.list\": {\n      \"requestBody\": {\n        \"content\": {\n          \"application/json\": {\n            \"schema\": {\"$ref\": \"#/components/schemas/books.list\"}\n          }\n        }\n      },\n      \"responses\": {\n        \"200\": {\n          \"description\": \"JSON object\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\"$ref\": \"#/components/schemas/generic\"}\n            }\n          }\n        }\n      }\n    }\n  }\n},\n\"components\": {\n  \"schemas\": {\n      // ... GOES HERE\n  }\n}\n}\n```\nand use the generated file list this\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>JSON-RPC UI</title>\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"http://unpkg.com/swagger-ui-dist@3.20.7/swagger-ui.css\" >\n</head>\n<body>\n<div id=\"swagger-ui\"></div>\n<script src=\"http://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js\"></script>\n<script>\nvar ui = SwaggerUIBundle({\n    url: \"/build/swagger.json\",\n    dom_id: '#swagger-ui'\n})\n</script>\n</body>\n</html>\n```\n\n\n## Extensions to JSON-RPC\n\n* `\"jsonrpc\": \"2.0\"` is optional, it's is just ignored\n* `\"method\"` in HTTP is optional, if missing it will be read from HTTP URL like this `/rpc/<METHOD>`. This helps using Swagger/OpenAPI/Postman. In WS method is manadatory.\n* When called the function recieves a second optional parameter called `ctx` (for context) containing the object returned by auth method, for example auth might read session cookie or basic auth head and based on that returns `{\"user\":{id, name, avatar, ...}}`. \n* `\"error\"` object has the following properies beside `\"code\"` and `\"message\"`\n  * `level`: `string` optional defaults to `error` but can be set `warning` in case of non-code problem like validation errors.\n  * `trace`: `string`  which is the stack trace in non-production environment.\n  * `validations`: `Object<string, Array<string>>` in case of validation errors it contains a mapping of field names (properties) and their corresponding array of problems.\n\n","readmeFilename":"README.md"}