begin switch to deno runtime

This commit is contained in:
qpismont 2024-01-04 21:20:47 +01:00
parent 30ff9c1cbb
commit 489a5874da
22 changed files with 420 additions and 5303 deletions

View file

@ -1,5 +0,0 @@
dist/
jest.config.js
tests/
.eslintrc.cjs
coverage/

View file

@ -1,11 +0,0 @@
/* eslint-env node */
module.exports = {
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
root: true,
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
};

3
.gitignore vendored
View file

@ -1,3 +1,2 @@
node_modules/ node_modules/
dist/ npm/
coverage/

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}

12
deno.json Normal file
View file

@ -0,0 +1,12 @@
{
"imports": {
"nats": "npm:nats",
"zod": "npm:zod",
"std/": "https://deno.land/std@0.210.0/",
"dnt": "https://deno.land/x/dnt@0.39.0/mod.ts"
},
"tasks": {
"test": "deno test --allow-net --parallel",
"build": "deno run -A scripts/build_npm.ts 0.1.0"
}
}

144
deno.lock Normal file
View file

@ -0,0 +1,144 @@
{
"version": "3",
"packages": {
"specifiers": {
"npm:nats": "npm:nats@2.18.0",
"npm:zod": "npm:zod@3.22.4"
},
"npm": {
"nats@2.18.0": {
"integrity": "sha512-zZF004ejzf67Za0Tva+xphxoxBMNc5IMLqbZ7Ho0j9TMuisjpo+qCd1EktXRCLNxmrZ8O6Tbm1dBsZYNF6yR1A==",
"dependencies": {
"nkeys.js": "nkeys.js@1.0.5"
}
},
"nkeys.js@1.0.5": {
"integrity": "sha512-u25YnRPHiGVsNzwyHnn+PT90sgAhnS8jUJ1nxmkHMFYCJ6+Ic0lv291w7uhRBpJVJ3PH2GWbYqA151lGCRrB5g==",
"dependencies": {
"tweetnacl": "tweetnacl@1.0.3"
}
},
"tweetnacl@1.0.3": {
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
"dependencies": {}
},
"zod@3.22.4": {
"integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==",
"dependencies": {}
}
}
},
"redirects": {
"https://deno.land/x/dnt/mod.ts": "https://deno.land/x/dnt@0.39.0/mod.ts"
},
"remote": {
"https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
"https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
"https://deno.land/std@0.140.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d",
"https://deno.land/std@0.140.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9",
"https://deno.land/std@0.140.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf",
"https://deno.land/std@0.140.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37",
"https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f",
"https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d",
"https://deno.land/std@0.140.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b",
"https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
"https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
"https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d",
"https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44",
"https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757",
"https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21",
"https://deno.land/std@0.181.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
"https://deno.land/std@0.181.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
"https://deno.land/std@0.181.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e",
"https://deno.land/std@0.181.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32",
"https://deno.land/std@0.181.0/fs/empty_dir.ts": "c3d2da4c7352fab1cf144a1ecfef58090769e8af633678e0f3fabaef98594688",
"https://deno.land/std@0.181.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40",
"https://deno.land/std@0.181.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a",
"https://deno.land/std@0.181.0/fs/walk.ts": "ea95ffa6500c1eda6b365be488c056edc7c883a1db41ef46ec3bf057b1c0fe32",
"https://deno.land/std@0.181.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.181.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
"https://deno.land/std@0.181.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0",
"https://deno.land/std@0.181.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
"https://deno.land/std@0.181.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
"https://deno.land/std@0.181.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c",
"https://deno.land/std@0.181.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
"https://deno.land/std@0.181.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
"https://deno.land/std@0.181.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
"https://deno.land/std@0.210.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9",
"https://deno.land/std@0.210.0/assert/_diff.ts": "2c9371f17cf08cbb843c924bc31ca77af422ec4fe162f73d42c651d547573fa8",
"https://deno.land/std@0.210.0/assert/_format.ts": "335ce8e15c65b679ad142dbc9e5e97e5d58602c39dd3c9175cef6c85fe22d6d5",
"https://deno.land/std@0.210.0/assert/assert.ts": "e265ad50a9341f3b40e51dd4cb41ab253d976943ba78a977106950e52e0302ab",
"https://deno.land/std@0.210.0/assert/assert_almost_equals.ts": "a70d637856e1c6128dc733346d32aa73c67058489495116ca85091c39a60c767",
"https://deno.land/std@0.210.0/assert/assert_array_includes.ts": "59d005d8897c1fbcbd5792170833f13a867f6a5ecd5a6b34a3d86b4b430de63c",
"https://deno.land/std@0.210.0/assert/assert_equals.ts": "991b0c2b437a015d623654f758e48bfd931068211a52e8131b397cdf005c595f",
"https://deno.land/std@0.210.0/assert/assert_exists.ts": "f24ecb0d3febad358a6cee235f012551077e07692517ebfe0630a561ba40a703",
"https://deno.land/std@0.210.0/assert/assert_false.ts": "99cf237fe374cabf57072d2fb41b3eaff389029f850fbb96f643c875792f10ce",
"https://deno.land/std@0.210.0/assert/assert_greater.ts": "e0bba9ac76a780573a864ab6eeb8b9fd71435b750bdd36d56a270e22ab9a79d9",
"https://deno.land/std@0.210.0/assert/assert_greater_or_equal.ts": "aea1c7dc868926ba55f1e59f8c3560bb44706b5e3b6b009453ee4064eecf6746",
"https://deno.land/std@0.210.0/assert/assert_instance_of.ts": "7c093d36b1a86666d5a60a8c290c91a51a627153b821a5a4dc40b24cab69f1e7",
"https://deno.land/std@0.210.0/assert/assert_is_error.ts": "a8a758581661edec514c453910bee2f9c91b1346a515c58404963b130d81cd80",
"https://deno.land/std@0.210.0/assert/assert_less.ts": "855aa58e49afa6a9e825f1abcd5947dc789c5878fc1b6f48b8a08115d48da32b",
"https://deno.land/std@0.210.0/assert/assert_less_or_equal.ts": "2ae5246bd0e83da26e5c8e2815d1493252f71f7dc02afb83dc2fc0e0fb0bd894",
"https://deno.land/std@0.210.0/assert/assert_match.ts": "e541a9769cf5726312ff9e15031e2faa2df3c59fbdc5573c8758b1f4668ccc62",
"https://deno.land/std@0.210.0/assert/assert_not_equals.ts": "6bce4b28f3316029c0aef107f8390796798835c382d31c1004160baef0b80db0",
"https://deno.land/std@0.210.0/assert/assert_not_instance_of.ts": "866243fd28bc6665e2ffcc027a9df1d2a69cb644aef1e9b8d1ce34377c6b8a84",
"https://deno.land/std@0.210.0/assert/assert_not_match.ts": "59707eceb0d2b16d6892fbf92ec86f92fd76fcfc55f8b61508299db7d2972cab",
"https://deno.land/std@0.210.0/assert/assert_not_strict_equals.ts": "c84b8e229450e8dfc44b9910d602788313ff7333d67d5bd8528371567b6a3632",
"https://deno.land/std@0.210.0/assert/assert_object_match.ts": "ebeff248d48e5810f787e8742ae4f6b39904f4640edc2f69796596ceb6dbcdf8",
"https://deno.land/std@0.210.0/assert/assert_rejects.ts": "f7e83272d816e1b39710012a0597ed950db2de6b193adcc5e50ddbcd9e177767",
"https://deno.land/std@0.210.0/assert/assert_strict_equals.ts": "4007dabef1c2e9d6f1bb0e948ba7ba99ec9b1bee97ba34d67f7c10e7e5d794f7",
"https://deno.land/std@0.210.0/assert/assert_string_includes.ts": "108a30d9348e5ff7a8b0b7cc836cf0a8cff27d5b33e861b8c56b52cc60b8219a",
"https://deno.land/std@0.210.0/assert/assert_throws.ts": "a8767e6a06e94bac42ca9eebdad5d4e2decbc0c48bc892da7e06aa1fe0b388ba",
"https://deno.land/std@0.210.0/assert/assertion_error.ts": "26ed1863d905005f00785c89750c001c3522c5417e4f58f95044b8143cfc1593",
"https://deno.land/std@0.210.0/assert/equal.ts": "6f81c8a3b12c08bdc3510c8a1293b4db1c083692219d7e3828d2234b448d3d3d",
"https://deno.land/std@0.210.0/assert/fail.ts": "f56fc64f9a141f98c1be5ff1005ddf158db888b7b206510e955bb3fedc69021c",
"https://deno.land/std@0.210.0/assert/mod.ts": "37c49a26aae2b254bbe25723434dc28cd7532e444cf0b481a97c045d110ec085",
"https://deno.land/std@0.210.0/assert/unimplemented.ts": "4e3e504792c87c485dbc5f4020489d8806ef697741403af2008dfa7b5a4711e8",
"https://deno.land/std@0.210.0/assert/unreachable.ts": "1af8c99421cc5fb7332454b2b9eca074a4e394895a180bc837750dedcca75338",
"https://deno.land/std@0.210.0/fmt/colors.ts": "2685c524bef9b16b3059a417daf6860c754eb755e19e812762ef5dff62f24481",
"https://deno.land/std@0.210.0/testing/_test_suite.ts": "30f018feeb3835f12ab198d8a518f9089b1bcb2e8c838a8b615ab10d5005465c",
"https://deno.land/std@0.210.0/testing/bdd.ts": "c41f019786c4a9112aadb7e5a7bbcc711f58429ac5904b3855fa248ba5fa0ba6",
"https://deno.land/x/code_block_writer@12.0.0/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5",
"https://deno.land/x/code_block_writer@12.0.0/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff",
"https://deno.land/x/deno_cache@0.6.2/auth_tokens.ts": "5d1d56474c54a9d152e44d43ea17c2e6a398dd1e9682c69811a313567c01ee1e",
"https://deno.land/x/deno_cache@0.6.2/cache.ts": "58b53c128b742757efcad10af9a3871f23b4e200674cb5b0ddf61164fb9b2fe7",
"https://deno.land/x/deno_cache@0.6.2/deno_dir.ts": "1ea355b8ba11c630d076b222b197cfc937dd81e5a4a260938997da99e8ff93a0",
"https://deno.land/x/deno_cache@0.6.2/deps.ts": "12cca94516cf2d3ed42fccd4b721ecd8060679253f077d83057511045b0081aa",
"https://deno.land/x/deno_cache@0.6.2/dirs.ts": "009c6f54e0b610914d6ce9f72f6f6ccfffd2d47a79a19061e0a9eb4253836069",
"https://deno.land/x/deno_cache@0.6.2/disk_cache.ts": "66a1e604a8d564b6dd0500326cac33d08b561d331036bf7272def80f2f7952aa",
"https://deno.land/x/deno_cache@0.6.2/file_fetcher.ts": "4f3e4a2c78a5ca1e4812099e5083f815a8525ab20d389b560b3517f6b1161dd6",
"https://deno.land/x/deno_cache@0.6.2/http_cache.ts": "407135eaf2802809ed373c230d57da7ef8dff923c4abf205410b9b99886491fd",
"https://deno.land/x/deno_cache@0.6.2/lib/deno_cache_dir.generated.js": "59f8defac32e8ebf2a30f7bc77e9d88f0e60098463fb1b75e00b9791a4bbd733",
"https://deno.land/x/deno_cache@0.6.2/lib/snippets/deno_cache_dir-a2aecaa9536c9402/fs.js": "cbe3a976ed63c72c7cb34ef845c27013033a3b11f9d8d3e2c4aa5dda2c0c7af6",
"https://deno.land/x/deno_cache@0.6.2/mod.ts": "b4004287e1c6123d7f07fe9b5b3e94ce6d990c4102949a89c527c68b19627867",
"https://deno.land/x/deno_cache@0.6.2/util.ts": "f3f5a0cfc60051f09162942fb0ee87a0e27b11a12aec4c22076e3006be4cc1e2",
"https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66",
"https://deno.land/x/dnt@0.39.0/lib/compiler.ts": "7f4447531581896348b8a379ab94730856b42ae50d99043f2468328360293cb1",
"https://deno.land/x/dnt@0.39.0/lib/compiler_transforms.ts": "f21aba052f5dcf0b0595c734450842855c7f572e96165d3d34f8fed2fc1f7ba1",
"https://deno.land/x/dnt@0.39.0/lib/mod.deps.ts": "8d6123c8e1162037e58aa8126686a03d1e2cffb250a8757bf715f80242097597",
"https://deno.land/x/dnt@0.39.0/lib/npm_ignore.ts": "57fbb7e7b935417d225eec586c6aa240288905eb095847d3f6a88e290209df4e",
"https://deno.land/x/dnt@0.39.0/lib/package_json.ts": "607b0a4f44acad071a4c8533b312a27d6671eac8e6a23625c8350ce29eadb2ba",
"https://deno.land/x/dnt@0.39.0/lib/pkg/dnt_wasm.generated.js": "4f9c59b3ca6c875adabb10df256e273fff1129fca3a1557eb8936bddd7da7b18",
"https://deno.land/x/dnt@0.39.0/lib/pkg/snippets/dnt-wasm-a15ef721fa5290c5/helpers.js": "aba69a019a6da6f084898a6c7b903b8b583bc0dbd82bfb338449cf0b5bce58fd",
"https://deno.land/x/dnt@0.39.0/lib/shims.ts": "60fd285ad433c6944544595e7b885eab3eab09253252891380654f4cd3addaaa",
"https://deno.land/x/dnt@0.39.0/lib/test_runner/get_test_runner_code.ts": "4dc7a73a13b027341c0688df2b29a4ef102f287c126f134c33f69f0339b46968",
"https://deno.land/x/dnt@0.39.0/lib/test_runner/test_runner.ts": "4d0da0500ec427d5f390d9a8d42fb882fbeccc92c92d66b6f2e758606dbd40e6",
"https://deno.land/x/dnt@0.39.0/lib/transform.deps.ts": "2e159661e1c5c650de9a573babe0e319349fe493105157307ec2ad2f6a52c94e",
"https://deno.land/x/dnt@0.39.0/lib/types.ts": "b8e228b2fac44c2ae902fbb73b1689f6ab889915bd66486c8a85c0c24255f5fb",
"https://deno.land/x/dnt@0.39.0/lib/utils.ts": "224f15f33e7226a2fd991e438d0291d7ed8c7889807efa2e1ecb67d2d1db6720",
"https://deno.land/x/dnt@0.39.0/mod.ts": "9df36a862161d9eb376472b699f6cb08ba0ad1704e0826fbe13be766bd3c01da",
"https://deno.land/x/dnt@0.39.0/transform.ts": "f68743a14cf9bf53bfc9c81073871d69d447a7f9e3453e0447ca2fb78926bb1d",
"https://deno.land/x/ts_morph@20.0.0/bootstrap/mod.ts": "b53aad517f106c4079971fcd4a81ab79fadc40b50061a3ab2b741a09119d51e9",
"https://deno.land/x/ts_morph@20.0.0/bootstrap/ts_morph_bootstrap.js": "6645ac03c5e6687dfa8c78109dc5df0250b811ecb3aea2d97c504c35e8401c06",
"https://deno.land/x/ts_morph@20.0.0/common/DenoRuntime.ts": "6a7180f0c6e90dcf23ccffc86aa8271c20b1c4f34c570588d08a45880b7e172d",
"https://deno.land/x/ts_morph@20.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed",
"https://deno.land/x/ts_morph@20.0.0/common/ts_morph_common.js": "2325f94f61dc5f3f98a1dab366dc93048d11b1433d718b10cfc6ee5a1cfebe8f",
"https://deno.land/x/ts_morph@20.0.0/common/typescript.js": "b9edf0a451685d13e0467a7ed4351d112b74bd1e256b915a2b941054e31c1736",
"https://deno.land/x/wasmbuild@0.15.1/cache.ts": "9d01b5cb24e7f2a942bbd8d14b093751fa690a6cde8e21709ddc97667e6669ed",
"https://deno.land/x/wasmbuild@0.15.1/loader.ts": "8c2fc10e21678e42f84c5135d8ab6ab7dc92424c3f05d2354896a29ccfd02a63"
}
}

View file

@ -1,5 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};

2
mod.ts Normal file
View file

@ -0,0 +1,2 @@
export * from "./src/service.ts";
export * from "./src/adaptors/nats.ts";

4966
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,33 +0,0 @@
{
"name": "nano-service",
"version": "0.0.1",
"description": "typescript library for making micro service",
"main": "dist/lib.js",
"types": "dist/lib.d.ts",
"files": [
"/dist"
],
"scripts": {
"lint": "eslint .",
"test": "jest",
"build": "tsc -p tsconfig.build.json"
},
"repository": {
"type": "git",
"url": "https://gitea.qpismont.fr/qpismont/nano-service"
},
"author": "qpismont",
"license": "MIT",
"devDependencies": {
"@types/jest": "^29.5.6",
"@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.8.0",
"eslint": "^8.51.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"dependencies": {
"nats": "^2.17.0"
}
}

30
scripts/build_npm.ts Normal file
View file

@ -0,0 +1,30 @@
import { build, emptyDir } from "dnt";
await emptyDir("./npm");
await build({
entryPoints: ["./mod.ts"],
outDir: "./npm",
shims: {
deno: true,
},
test: false,
importMap: "deno.json",
package: {
name: "nano-service",
version: Deno.args[0],
description: "Your package.",
license: "MIT",
repository: {
type: "git",
url: "git+https://github.com/username/repo.git",
},
bugs: {
url: "https://github.com/username/repo/issues",
},
},
postBuild() {
Deno.copyFileSync("LICENSE", "npm/LICENSE");
Deno.copyFileSync("README.md", "npm/README.md");
},
});

View file

@ -1,4 +1,4 @@
import { AdaptorSubscribeTypeFn } from "../types"; import { AdaptorSubscribeTypeFn } from "../types.ts";
export default interface Adaptor { export default interface Adaptor {
subscribe(subject: string, fn: AdaptorSubscribeTypeFn): void; subscribe(subject: string, fn: AdaptorSubscribeTypeFn): void;

View file

@ -1,9 +1,15 @@
import { AdaptorSubscribeTypeFn } from "../types"; import { AdaptorSubscribeTypeFn } from "../types.ts";
import Adaptor from "./adaptor"; import Adaptor from "./adaptor.ts";
import { NatsConnection, connect, ConnectionOptions, StringCodec, Codec, Subscription } from "nats"; import {
Codec,
connect,
ConnectionOptions,
NatsConnection,
StringCodec,
Subscription,
} from "nats";
export default class NatsAdaptor implements Adaptor { export default class NatsAdaptor implements Adaptor {
private options: ConnectionOptions; private options: ConnectionOptions;
private nc?: NatsConnection; private nc?: NatsConnection;
@ -37,12 +43,12 @@ export default class NatsAdaptor implements Adaptor {
} }
async request(subject: string, req: string): Promise<string> { async request(subject: string, req: string): Promise<string> {
if(this.nc) { if (this.nc) {
const msg = await this.nc.request(subject, this.sc.encode(req)); const msg = await this.nc.request(subject, this.sc.encode(req));
return this.sc.decode(msg.data); return this.sc.decode(msg.data);
} else {
throw new Error("nats connection is not initialized");
} }
throw new Error("nats connection is not initialized");
} }
async stop(): Promise<void> { async stop(): Promise<void> {

View file

@ -1,5 +1,4 @@
export class RequestError extends Error { export class RequestError extends Error {
public statusCode: number; public statusCode: number;
constructor(msg: string, statusCode: number) { constructor(msg: string, statusCode: number) {

View file

@ -1,2 +0,0 @@
export * from "./service";
export * from "./adaptors/nats";

View file

@ -1,15 +1,15 @@
export interface Request<T> { export interface Request<T> {
service: string; service: string;
subject: string; subject: string;
data: T data?: T;
} }
export interface Message<T> { export interface Message<T> {
from: string; from: string;
data: T; data?: T;
} }
export interface Response<T> { export interface Response<T> {
data?: T, data?: T;
statusCode: number statusCode: number;
} }

View file

@ -1,10 +1,11 @@
import Adaptor from "./adaptors/adaptor"; import { ServiceError } from "nats";
import { RequestError } from "./error"; import Adaptor from "./adaptors/adaptor.ts";
import { Request, Response } from "./messages"; import { RequestError } from "./error.ts";
import { RouteSubscribeTypeFn } from "./types"; import { Message, Request, Response } from "./messages.ts";
import { RouteSubscribeTypeFn } from "./types.ts";
import { z } from "zod";
export default class Service { export default class Service {
private name: string; private name: string;
private adaptors: Record<string, Adaptor>; private adaptors: Record<string, Adaptor>;
@ -18,48 +19,88 @@ export default class Service {
this.adaptors[name] = adaptor; this.adaptors[name] = adaptor;
} }
public async subscribe<T, U>(adaptor: string, subject: string, fn: RouteSubscribeTypeFn<T, U>) { public subscribe<T extends z.ZodType<O>, O, U>(
this.adaptors[adaptor].subscribe(`${this.name}.${subject}`, async (rawReq) => { adaptor: string,
subject: string,
fn: RouteSubscribeTypeFn<z.infer<T>, U>,
schema: T | undefined = undefined,
) {
this.adaptors[adaptor].subscribe(
`${this.name}.${subject}`,
async (rawReq) => {
const msg: Request<T> = JSON.parse(rawReq); const msg: Request<T> = JSON.parse(rawReq);
const res = await fn({ data: msg.data, from: this.name });
return JSON.stringify(res); const message: Message<z.infer<T>> = { from: this.name };
});
if (msg.data && schema) {
const validate = schema.safeParse(msg.data);
if (!validate.success) {
return JSON.stringify(
new ServiceError(400, validate.error.toString()),
);
} else {
message.data = validate.data;
}
} }
public async request<T, U>(adaptor: string, req: Request<T>): Promise<Response<U>> { const res = await fn(message);
if(!this.adaptors[adaptor]) {
return JSON.stringify(res);
},
);
}
public async request<T, O, U extends z.ZodType<O>>(
adaptor: string,
req: Request<T>,
schema?: z.ZodType<O>,
): Promise<Response<z.infer<U>>> {
if (!this.adaptors[adaptor]) {
throw new Error(`${adaptor} adaptor not exist`); throw new Error(`${adaptor} adaptor not exist`);
} }
const rawReq = JSON.stringify(req); const rawReq = JSON.stringify(req);
try { try {
const rawRes = await this.adaptors[adaptor].request(`${req.service}.${req.subject}`, rawReq); const rawRes = await this.adaptors[adaptor].request(
const res: Response<U> = JSON.parse(rawRes); `${req.service}.${req.subject}`,
rawReq,
);
const res: Response<z.infer<U>> = JSON.parse(rawRes);
if(res.statusCode < 200 || res.statusCode >= 299) { if (res.statusCode < 200 || res.statusCode >= 299) {
throw new RequestError("error while request", res.statusCode); throw new RequestError("error while request", res.statusCode);
} }
return res; if (res.data && schema) {
} catch(err) { const validate = schema.safeParse(res.data);
if(err instanceof RequestError) {
throw err; if (!validate.success) {
throw new ServiceError(400, validate.error.toString());
} else { } else {
throw new RequestError("unexpected error", 500); res.data = validate.data;
} }
} }
return res;
} catch (err) {
if (err instanceof RequestError) {
throw err;
}
throw new RequestError("unexpected error", 500);
}
} }
public async listen() { public async listen() {
for(const index in this.adaptors) { for (const index in this.adaptors) {
await this.adaptors[index].listen(this.name); await this.adaptors[index].listen(this.name);
} }
} }
public async stop() { public async stop() {
for(const index in this.adaptors) { for (const index in this.adaptors) {
await this.adaptors[index].stop(); await this.adaptors[index].stop();
} }
} }

View file

@ -1,4 +1,6 @@
import { Message, Response } from "./messages"; import { Message, Response } from "./messages.ts";
export type AdaptorSubscribeTypeFn = (msg: string) => Promise<string>; export type AdaptorSubscribeTypeFn = (msg: string) => Promise<string>;
export type RouteSubscribeTypeFn<T, U> = (msg: Message<T>) => Promise<Response<U>>; export type RouteSubscribeTypeFn<T, U> = (
msg: Message<T>,
) => Promise<Response<U>>;

View file

@ -1,11 +1,12 @@
import { RequestError } from "../src/error"; import { RequestError } from "../src/error.ts";
import { assertEquals } from "std/assert/mod.ts";
test('request error', () => { Deno.test("request error", () => {
const expectedMsg = "This is my err"; const expectedMsg = "This is my err";
const expectedStatusCode = 500; const expectedStatusCode = 500;
const err = new RequestError(expectedMsg, expectedStatusCode); const err = new RequestError(expectedMsg, expectedStatusCode);
expect(err.message).toBe(expectedMsg); assertEquals(err.message, expectedMsg);
expect(err.statusCode).toBe(expectedStatusCode); assertEquals(err.statusCode, expectedStatusCode);
}); });

View file

@ -1,16 +1,17 @@
import NatsAdaptor from "../src/adaptors/nats"; import { z } from "zod";
import { RequestError } from "../src/error"; import NatsAdaptor from "../src/adaptors/nats.ts";
import { Message } from "../src/messages"; import { Message } from "../src/messages.ts";
import Service from "../src/service"; import Service from "../src/service.ts";
import { assertEquals, assertThrows } from "std/assert/mod.ts";
import { afterEach, beforeEach, it } from "std/testing/bdd.ts";
let srv!: Service; let srv!: Service;
const natsServer = '127.0.0.1:4222'; const natsServer = "127.0.0.1:4222";
const serviceName = "test-service"; const serviceName = "test-service";
const adaptorName = "nats"; const adaptorName = "nats";
const subject = "test"; const subject = "test";
beforeEach(() => { beforeEach(() => {
srv = new Service(serviceName); srv = new Service(serviceName);
}); });
@ -19,46 +20,61 @@ afterEach(async () => {
await srv.stop(); await srv.stop();
}); });
test('request success', async () => { it("request success", async () => {
const dataExpected = "hello success"; const dataExpected = "hello success";
const statusCodeExpected = 200; const statusCodeExpected = 200;
srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] })); srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] }));
srv.subscribe(adaptorName, subject, async (msg: Message<string>) => { srv.subscribe(adaptorName, subject, async (msg) => {
return {data: msg.data, statusCode: statusCodeExpected}; return { data: msg.data, statusCode: statusCodeExpected };
}); }, z.string());
await srv.listen(); await srv.listen();
const res = await srv.request(adaptorName, {service: serviceName, subject: subject, data: dataExpected}); const res = await srv.request(adaptorName, {
service: serviceName,
subject: subject,
data: dataExpected,
}, z.string());
expect(res.data).toBe(dataExpected); assertEquals(res.data, dataExpected);
expect(res.statusCode).toBe(statusCodeExpected); assertEquals(res.statusCode, statusCodeExpected);
}); });
test('request error', async () => { it("request error", async () => {
const dataExpected = "hello error"; const dataExpected = "hello error";
const statusCodeExpected = 500; const statusCodeExpected = 500;
srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] })); srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] }));
srv.subscribe(adaptorName, subject, async (msg: Message<string>) => { srv.subscribe(adaptorName, subject, async (msg) => {
return {data: msg.data, statusCode: statusCodeExpected}; return { data: msg.data, statusCode: statusCodeExpected };
}); }, z.string());
await srv.listen(); await srv.listen();
expect(srv.request(adaptorName, {service: serviceName, subject: subject, data: dataExpected})).rejects.toThrow(RequestError); assertThrows(async () => {
await srv.request(adaptorName, {
service: serviceName,
subject: subject,
data: dataExpected,
});
});
}); });
test('request adaptor not found', async () => { it("request adaptor not found", async () => {
const dataExpected = "hello success"; const dataExpected = "hello success";
const statusCodeExpected = 200; const statusCodeExpected = 200;
srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] })); srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] }));
srv.subscribe(adaptorName, subject, async (msg: Message<string>) => { srv.subscribe(adaptorName, subject, async (msg) => {
return {data: msg.data, statusCode: statusCodeExpected}; return { data: msg.data, statusCode: statusCodeExpected };
}); });
await srv.listen(); await srv.listen();
expect(srv.request("bad adaptor", {service: serviceName, subject: subject, data: dataExpected})).rejects.toThrow(Error); assertThrows(async () => {
await srv.request("bad adaptor", {
service: serviceName,
subject: subject,
data: dataExpected,
});
});
}); });

View file

@ -1,6 +0,0 @@
{
"extends": "./tsconfig.json",
"exclude": [
"tests/**/*"
]
}

View file

@ -1,110 +0,0 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "NodeNext", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
//"moduleResolution": "NodeNext", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
"allowSyntheticDefaultImports": false, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["./src/**/*", "./tests/**/*"]
}