Compare commits
19 commits
upgrade-de
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
765af2700d | ||
da965206f6 | |||
|
226bf76e1c | ||
|
2a6fa5195a | ||
|
330e47d477 | ||
354405a253 | |||
|
fb7cd0bf34 | ||
|
ab29b28125 | ||
bf7037eb15 | |||
|
d936a34a2e | ||
|
aae70c59c0 | ||
|
3bdb12b2a9 | ||
16eb073aaa | |||
|
487a48406f | ||
|
96f8b57564 | ||
955b3ded7e | |||
|
00d45d670b | ||
|
d8c98adeff | ||
|
8283e05c02 |
24 changed files with 568 additions and 428 deletions
177
.gitignore
vendored
177
.gitignore
vendored
|
@ -1,2 +1,177 @@
|
|||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Caches
|
||||
|
||||
.cache
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
npm/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
|
||||
.npmrc
|
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
@ -1,3 +1,8 @@
|
|||
{
|
||||
"editor.formatOnSave": true
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "biomejs.biome",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports.biome": "explicit"
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
|
@ -1,16 +1,9 @@
|
|||
when:
|
||||
event: [push]
|
||||
|
||||
steps:
|
||||
build:
|
||||
image: denoland/deno:${DENO_VERSION}
|
||||
image: oven/bun:1.1.10-slim
|
||||
commands:
|
||||
- apt update
|
||||
- apt install curl -y
|
||||
- curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && apt-get install -y nodejs
|
||||
- deno task build
|
||||
|
||||
matrix:
|
||||
DENO_VERSION:
|
||||
- 1.39.2
|
||||
- 1.39.3
|
||||
- 1.39.4
|
||||
- 1.40.0
|
||||
- 1.40.1
|
||||
- bun install
|
||||
- bun run build
|
|
@ -1,5 +1,10 @@
|
|||
when:
|
||||
event: [push]
|
||||
|
||||
steps:
|
||||
lint:
|
||||
image: denoland/deno:1.40.1
|
||||
image: oven/bun:1.1.10-slim
|
||||
commands:
|
||||
- deno lint
|
||||
- bun install
|
||||
- bun run ci
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ when:
|
|||
|
||||
steps:
|
||||
publish:
|
||||
image: denoland/deno:1.40.1
|
||||
image: denoland/deno:1.39.2
|
||||
commands:
|
||||
- apt update
|
||||
- apt install curl -y
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
when:
|
||||
event: [push]
|
||||
|
||||
steps:
|
||||
test:
|
||||
image: denoland/deno:${DENO_VERSION}
|
||||
image: oven/bun:${BUN_VERSION}-slim
|
||||
environment:
|
||||
- NATS_HOST=nats:4222
|
||||
commands:
|
||||
- deno task test
|
||||
- bun install
|
||||
- bun run test
|
||||
|
||||
matrix:
|
||||
DENO_VERSION:
|
||||
- 1.39.2
|
||||
- 1.39.3
|
||||
- 1.39.4
|
||||
- 1.40.0
|
||||
- 1.40.1
|
||||
BUN_VERSION:
|
||||
- 1.1.8
|
||||
- 1.1.9
|
||||
- 1.1.10
|
||||
|
||||
services:
|
||||
nats:
|
||||
image: nats
|
||||
image: nats:2-alpine
|
20
biome.json
Normal file
20
biome.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true
|
||||
}
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true
|
||||
},
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": true
|
||||
}
|
||||
}
|
BIN
bun.lockb
Executable file
BIN
bun.lockb
Executable file
Binary file not shown.
16
deno.json
16
deno.json
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"imports": {
|
||||
"nats": "npm:nats",
|
||||
"zod": "npm:zod",
|
||||
"std/": "https://deno.land/std@0.213.0/",
|
||||
"dnt": "https://deno.land/x/dnt@0.39.0/mod.ts"
|
||||
},
|
||||
"tasks": {
|
||||
"test": "deno test --allow-net --allow-env --parallel",
|
||||
"build": "deno run -A scripts/build_npm.ts 0.1.0",
|
||||
"publish": "cd npm && npm publish"
|
||||
},
|
||||
"lint": {
|
||||
"include": ["src/"]
|
||||
}
|
||||
}
|
73
deno.lock
73
deno.lock
|
@ -1,73 +0,0 @@
|
|||
{
|
||||
"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": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remote": {
|
||||
"https://deno.land/std@0.211.0/assert/_constants.ts": "a271e8ef5a573f1df8e822a6eb9d09df064ad66a4390f21b3e31f820a38e0975",
|
||||
"https://deno.land/std@0.211.0/assert/_diff.ts": "6a2d68f2c42d73a1e31818a4195f40598d672c7f02ac75c7f1b1e6789852c2bc",
|
||||
"https://deno.land/std@0.211.0/assert/_format.ts": "0ba808961bf678437fb486b56405b6fefad2cf87b5809667c781ddee8c32aff4",
|
||||
"https://deno.land/std@0.211.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5",
|
||||
"https://deno.land/std@0.211.0/assert/assert_almost_equals.ts": "648ea72678296a5ad86d3bbb66904335fa97de3133223f44ca4596b225cdcbef",
|
||||
"https://deno.land/std@0.211.0/assert/assert_array_includes.ts": "dbb461c20681807a884ad84d873f9e4daead380859531b1e7f27fa4e8f8bf431",
|
||||
"https://deno.land/std@0.211.0/assert/assert_equals.ts": "b3b33ae8a85ae22a0754c61a7486d4ae870e8938830a94f5cacecba3a9b0442a",
|
||||
"https://deno.land/std@0.211.0/assert/assert_exists.ts": "24a7bf965e634f909242cd09fbaf38bde6b791128ece08e33ab08586a7cc55c9",
|
||||
"https://deno.land/std@0.211.0/assert/assert_false.ts": "6f382568e5128c0f855e5f7dbda8624c1ed9af4fcc33ef4a9afeeedcdce99769",
|
||||
"https://deno.land/std@0.211.0/assert/assert_greater.ts": "8dfcf082d2bcffcaab3bd0dab48d41e41c26266529567246de47bd6864936f6d",
|
||||
"https://deno.land/std@0.211.0/assert/assert_greater_or_equal.ts": "9e02ef89f32563f539f7e66556930033418728847aefcca4e3806a735b5f122e",
|
||||
"https://deno.land/std@0.211.0/assert/assert_instance_of.ts": "72dc1faff1e248692d873c89382fa1579dd7b53b56d52f37f9874a75b11ba444",
|
||||
"https://deno.land/std@0.211.0/assert/assert_is_error.ts": "6596f2b5ba89ba2fe9b074f75e9318cda97a2381e59d476812e30077fbdb6ed2",
|
||||
"https://deno.land/std@0.211.0/assert/assert_less.ts": "91a6fed705f9c39bbd683b62aa9dfc42547bc886c29f696997e681cafb886b16",
|
||||
"https://deno.land/std@0.211.0/assert/assert_less_or_equal.ts": "7a3c2e554eb20aa6af9dd4a410e550bcee9e8a28102d51f5f40cb1b8d141e4e1",
|
||||
"https://deno.land/std@0.211.0/assert/assert_match.ts": "ec2d9680ed3e7b9746ec57ec923a17eef6d476202f339ad91d22277d7f1d16e1",
|
||||
"https://deno.land/std@0.211.0/assert/assert_not_equals.ts": "cb78bf9a4357d69673c87b634491bc6b840412c8b55efe472af9877ef6f0a29b",
|
||||
"https://deno.land/std@0.211.0/assert/assert_not_instance_of.ts": "8f720d92d83775c40b2542a8d76c60c2d4aeddaf8713c8d11df8984af2604931",
|
||||
"https://deno.land/std@0.211.0/assert/assert_not_match.ts": "b4b7c77f146963e2b673c1ce4846473703409eb93f5ab0eb60f6e6f8aeffe39f",
|
||||
"https://deno.land/std@0.211.0/assert/assert_not_strict_equals.ts": "89ba25e1da5233404ac4c01651c088759b7977c51034eefc6050fe3fc2d10c46",
|
||||
"https://deno.land/std@0.211.0/assert/assert_object_match.ts": "e85e5eef62a56ce364c3afdd27978ccab979288a3e772e6855c270a7b118fa49",
|
||||
"https://deno.land/std@0.211.0/assert/assert_rejects.ts": "e9e0c8d9c3e164c7ac962c37b3be50577c5a2010db107ed272c4c1afb1269f54",
|
||||
"https://deno.land/std@0.211.0/assert/assert_strict_equals.ts": "0425a98f70badccb151644c902384c12771a93e65f8ff610244b8147b03a2366",
|
||||
"https://deno.land/std@0.211.0/assert/assert_string_includes.ts": "dfb072a890167146f8e5bdd6fde887ce4657098e9f71f12716ef37f35fb6f4a7",
|
||||
"https://deno.land/std@0.211.0/assert/assert_throws.ts": "edddd86b39606c342164b49ad88dd39a26e72a26655e07545d172f164b617fa7",
|
||||
"https://deno.land/std@0.211.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8",
|
||||
"https://deno.land/std@0.211.0/assert/equal.ts": "fae5e8a52a11d3ac694bbe1a53e13a7969e3f60791262312e91a3e741ae519e2",
|
||||
"https://deno.land/std@0.211.0/assert/fail.ts": "f310e51992bac8e54f5fd8e44d098638434b2edb802383690e0d7a9be1979f1c",
|
||||
"https://deno.land/std@0.211.0/assert/mod.ts": "325df8c0683ad83a873b9691aa66b812d6275fc9fec0b2d180ac68a2c5efed3b",
|
||||
"https://deno.land/std@0.211.0/assert/unimplemented.ts": "47ca67d1c6dc53abd0bd729b71a31e0825fc452dbcd4fde4ca06789d5644e7fd",
|
||||
"https://deno.land/std@0.211.0/assert/unreachable.ts": "38cfecb95d8b06906022d2f9474794fca4161a994f83354fd079cac9032b5145",
|
||||
"https://deno.land/std@0.211.0/fmt/colors.ts": "be082d6a6bbb2980ae7b2bf8c23c6bb2811ba90a06a9bcb861344a71784c5a99",
|
||||
"https://deno.land/std@0.211.0/testing/_test_suite.ts": "f10a8a6338b60c403f07a76f3f46bdc9f1e1a820c0a1decddeb2949f7a8a0546",
|
||||
"https://deno.land/std@0.211.0/testing/bdd.ts": "3cbd17bd35f629a76ce63446238dfb4632240dd46b3b205027c45fa3dd67e554"
|
||||
},
|
||||
"workspace": {
|
||||
"dependencies": [
|
||||
"npm:nats",
|
||||
"npm:zod"
|
||||
]
|
||||
}
|
||||
}
|
4
mod.ts
4
mod.ts
|
@ -1,4 +0,0 @@
|
|||
export * from "./src/service.ts";
|
||||
export * from "./src/adaptors/nats.ts";
|
||||
export * from "./src/error.ts";
|
||||
export type { Request, Response } from "./src/messages.ts";
|
26
package.json
Normal file
26
package.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "@qpismont/nano-service",
|
||||
"version": "0.0.3",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": ["/dist"],
|
||||
"scripts": {
|
||||
"ci": "biome ci . --error-on-warnings",
|
||||
"test": "bun test",
|
||||
"build": "tsc --project tsconfig.build.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.3.3",
|
||||
"@types/bun": "latest",
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"nats": "^2.28.2",
|
||||
"zod": "^3.23.8"
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
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: "@qpismont/nano-service",
|
||||
version: Deno.args[0],
|
||||
description: "Your package.",
|
||||
license: "MIT",
|
||||
repository: {
|
||||
"type": "git",
|
||||
"url": "https://gitea.qpismont.fr/qpismont/nano-service",
|
||||
},
|
||||
},
|
||||
postBuild() {
|
||||
Deno.copyFileSync("LICENSE", "npm/LICENSE");
|
||||
Deno.copyFileSync("README.md", "npm/README.md");
|
||||
},
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import { AdaptorSubscribeTypeFn } from "../types.ts";
|
||||
import type { AdaptorSubscribeTypeFn } from "../types.ts";
|
||||
|
||||
export default interface Adaptor {
|
||||
subscribe(subject: string, fn: AdaptorSubscribeTypeFn): void;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { AdaptorSubscribeTypeFn } from "../types.ts";
|
||||
import Adaptor from "./adaptor.ts";
|
||||
import {
|
||||
Codec,
|
||||
connect,
|
||||
ConnectionOptions,
|
||||
NatsConnection,
|
||||
type Codec,
|
||||
type ConnectionOptions,
|
||||
type NatsConnection,
|
||||
StringCodec,
|
||||
Subscription,
|
||||
type Subscription,
|
||||
connect,
|
||||
} from "nats";
|
||||
import type { AdaptorSubscribeTypeFn } from "../types.ts";
|
||||
import type Adaptor from "./adaptor.ts";
|
||||
|
||||
export default class NatsAdaptor implements Adaptor {
|
||||
private options: ConnectionOptions;
|
||||
|
@ -52,6 +52,7 @@ export default class NatsAdaptor implements Adaptor {
|
|||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
this.sub?.unsubscribe();
|
||||
await this.nc?.drain();
|
||||
}
|
||||
}
|
||||
|
|
4
src/index.ts
Normal file
4
src/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export * from "./service";
|
||||
export * from "./adaptors/nats";
|
||||
export * from "./error";
|
||||
export type { Request, Response } from "./messages";
|
|
@ -1,15 +1,15 @@
|
|||
import Adaptor from "./adaptors/adaptor.ts";
|
||||
import { RequestError } from "./error.ts";
|
||||
import type { z } from "zod";
|
||||
import type Adaptor from "./adaptors/adaptor";
|
||||
import { RequestError } from "./error";
|
||||
import {
|
||||
InternalRequest,
|
||||
type InternalRequest,
|
||||
InternalRequestSchema,
|
||||
InternalResponse,
|
||||
type InternalResponse,
|
||||
InternalResponseSchema,
|
||||
Request,
|
||||
Response,
|
||||
} from "./messages.ts";
|
||||
import { RouteSubscribeTypeFn } from "./types.ts";
|
||||
import { z } from "zod";
|
||||
type Request,
|
||||
type Response,
|
||||
} from "./messages";
|
||||
import type { RouteSubscribeTypeFn } from "./types";
|
||||
|
||||
export default class Service {
|
||||
private name: string;
|
||||
|
@ -29,20 +29,19 @@ export default class Service {
|
|||
adaptor: string,
|
||||
subject: string,
|
||||
fn: RouteSubscribeTypeFn<z.infer<T>, U>,
|
||||
schema: T | undefined = undefined,
|
||||
schema?: T,
|
||||
) {
|
||||
this.adaptors[adaptor].subscribe(
|
||||
`${this.name}.${subject}`,
|
||||
async (rawReq) => {
|
||||
const rawReqJson = JSON.parse(rawReq);
|
||||
const internalRequestJson = InternalRequestSchema.safeParse(rawReqJson);
|
||||
|
||||
if (!internalRequestJson.success) {
|
||||
return JSON.stringify(
|
||||
{
|
||||
return JSON.stringify({
|
||||
statusCode: 400,
|
||||
data: "bad request structure",
|
||||
} satisfies InternalResponse,
|
||||
);
|
||||
} satisfies InternalResponse);
|
||||
}
|
||||
|
||||
const internalRequest = internalRequestJson.data;
|
||||
|
@ -53,20 +52,19 @@ export default class Service {
|
|||
|
||||
if (internalRequest.data && schema) {
|
||||
const validate = schema.safeParse(internalRequest.data);
|
||||
|
||||
if (!validate.success) {
|
||||
return JSON.stringify(
|
||||
{
|
||||
return JSON.stringify({
|
||||
statusCode: 400,
|
||||
data: validate.error,
|
||||
} satisfies InternalResponse,
|
||||
);
|
||||
} else {
|
||||
req.data = validate.data;
|
||||
} satisfies InternalResponse);
|
||||
}
|
||||
|
||||
req.data = validate.data;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fn(req);
|
||||
const res = await fn(this, req);
|
||||
const internalResponse = {
|
||||
statusCode: res.statusCode,
|
||||
data: res.data,
|
||||
|
@ -75,20 +73,16 @@ export default class Service {
|
|||
return JSON.stringify(internalResponse);
|
||||
} catch (err) {
|
||||
if (err instanceof RequestError) {
|
||||
return JSON.stringify(
|
||||
{
|
||||
return JSON.stringify({
|
||||
statusCode: err.statusCode,
|
||||
data: err.message,
|
||||
} satisfies InternalResponse,
|
||||
);
|
||||
} else {
|
||||
return JSON.stringify(
|
||||
{
|
||||
statusCode: 500,
|
||||
data: err?.message || "unknow error apend",
|
||||
} satisfies InternalResponse,
|
||||
);
|
||||
} satisfies InternalResponse);
|
||||
}
|
||||
|
||||
return JSON.stringify({
|
||||
statusCode: 500,
|
||||
data: "unknow error apend",
|
||||
} satisfies InternalResponse);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -122,7 +116,8 @@ export default class Service {
|
|||
|
||||
const internalResponse = internalResponseJson.data;
|
||||
if (
|
||||
internalResponse.statusCode < 200 || internalResponse.statusCode >= 299
|
||||
internalResponse.statusCode < 200 ||
|
||||
internalResponse.statusCode >= 299
|
||||
) {
|
||||
throw new RequestError(
|
||||
internalResponse.data,
|
||||
|
@ -137,9 +132,8 @@ export default class Service {
|
|||
|
||||
if (!validate.success) {
|
||||
throw new RequestError(validate.error.message, 400);
|
||||
} else {
|
||||
res.data = validate.data;
|
||||
}
|
||||
res.data = validate.data;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { Request, Response } from "./messages.ts";
|
||||
import type { Request, Response } from "./messages.ts";
|
||||
import type Service from "./service.ts";
|
||||
|
||||
export type AdaptorSubscribeTypeFn = (msg: string) => Promise<string>;
|
||||
export type RouteSubscribeTypeFn<T, U> = (
|
||||
srv: Service,
|
||||
msg: Request<T>,
|
||||
) => Promise<Response<U>>;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { RequestError } from "../src/error.ts";
|
||||
import { assertEquals } from "std/assert/mod.ts";
|
||||
import { expect, test } from "bun:test";
|
||||
import { RequestError } from "../src/error";
|
||||
|
||||
Deno.test("request error", () => {
|
||||
test("request error", () => {
|
||||
const expectedMsg = "This is my err";
|
||||
const expectedStatusCode = 500;
|
||||
|
||||
const err = new RequestError(expectedMsg, expectedStatusCode);
|
||||
|
||||
assertEquals(err.message, expectedMsg);
|
||||
assertEquals(err.statusCode, expectedStatusCode);
|
||||
expect(err.message).toBe(expectedMsg);
|
||||
expect(err.statusCode).toBe(expectedStatusCode);
|
||||
});
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { afterEach, beforeEach, expect, test } from "bun:test";
|
||||
import { z } from "zod";
|
||||
import NatsAdaptor from "../src/adaptors/nats.ts";
|
||||
import Service from "../src/service.ts";
|
||||
import { assertEquals, assertRejects, assertThrows } from "std/assert/mod.ts";
|
||||
import { afterEach, beforeEach, it } from "std/testing/bdd.ts";
|
||||
import { RequestError } from "../src/error.ts";
|
||||
import NatsAdaptor from "../src/adaptors/nats";
|
||||
import { RequestError } from "../src/error";
|
||||
import Service from "../src/service";
|
||||
|
||||
let srv!: Service;
|
||||
|
||||
const natsServer = Deno.env.get("NATS_HOST") || "127.0.0.1:4222";
|
||||
const natsServer = Bun.env.NATS_HOST || "127.0.0.1:4222";
|
||||
const serviceName = "test-service";
|
||||
const adaptorName = "nats";
|
||||
const subject = "test";
|
||||
|
@ -20,73 +19,74 @@ afterEach(async () => {
|
|||
await srv.stop();
|
||||
});
|
||||
|
||||
it("request success", {
|
||||
sanitizeExit: false,
|
||||
sanitizeOps: false,
|
||||
sanitizeResources: false,
|
||||
}, async () => {
|
||||
test("request success", async () => {
|
||||
const dataExpected = "hello success";
|
||||
const statusCodeExpected = 200;
|
||||
|
||||
srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] }));
|
||||
srv.subscribe(adaptorName, subject, async (msg) => {
|
||||
srv.subscribe(
|
||||
adaptorName,
|
||||
subject,
|
||||
async (srv, msg) => {
|
||||
return { data: msg.data, statusCode: statusCodeExpected };
|
||||
}, z.string());
|
||||
},
|
||||
z.string(),
|
||||
);
|
||||
|
||||
await srv.listen();
|
||||
|
||||
const res = await srv.request(adaptorName, {
|
||||
const res = await srv.request(
|
||||
adaptorName,
|
||||
{
|
||||
service: serviceName,
|
||||
subject: subject,
|
||||
data: dataExpected,
|
||||
}, z.string());
|
||||
},
|
||||
z.string(),
|
||||
);
|
||||
|
||||
assertEquals(res.data, dataExpected);
|
||||
assertEquals(res.statusCode, statusCodeExpected);
|
||||
expect(res.data).toBe(dataExpected);
|
||||
expect(res.statusCode).toBe(statusCodeExpected);
|
||||
});
|
||||
|
||||
it("request error", {
|
||||
sanitizeExit: false,
|
||||
sanitizeOps: false,
|
||||
sanitizeResources: false,
|
||||
}, async () => {
|
||||
test("request error", async () => {
|
||||
const dataExpected = "hello error";
|
||||
const statusCodeExpected = 500;
|
||||
|
||||
srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] }));
|
||||
srv.subscribe(adaptorName, subject, async (msg) => {
|
||||
srv.subscribe(adaptorName, subject, async (srv, msg) => {
|
||||
throw new RequestError("request error", 500);
|
||||
}, z.string());
|
||||
});
|
||||
|
||||
await srv.listen();
|
||||
assertRejects(() => {
|
||||
return srv.request(adaptorName, {
|
||||
expect(() => {
|
||||
return srv.request(
|
||||
adaptorName,
|
||||
{
|
||||
service: serviceName,
|
||||
subject: subject,
|
||||
data: dataExpected,
|
||||
}, z.string());
|
||||
});
|
||||
},
|
||||
z.string(),
|
||||
);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("request adaptor not found", {
|
||||
sanitizeExit: false,
|
||||
sanitizeOps: false,
|
||||
sanitizeResources: false,
|
||||
}, async () => {
|
||||
test("request adaptor not found", async () => {
|
||||
const dataExpected = "hello success";
|
||||
const statusCodeExpected = 200;
|
||||
|
||||
srv.addAdaptor(adaptorName, new NatsAdaptor({ servers: [natsServer] }));
|
||||
srv.subscribe(adaptorName, subject, async (msg) => {
|
||||
srv.subscribe(adaptorName, subject, async (srv, msg) => {
|
||||
return { data: msg.data, statusCode: statusCodeExpected };
|
||||
});
|
||||
|
||||
await srv.listen();
|
||||
assertRejects(() => {
|
||||
expect(() => {
|
||||
return srv.request("bad adaptor", {
|
||||
service: serviceName,
|
||||
subject: subject,
|
||||
data: dataExpected,
|
||||
});
|
||||
});
|
||||
}).toThrow();
|
||||
});
|
||||
|
|
11
tsconfig.build.json
Normal file
11
tsconfig.build.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false,
|
||||
"noEmitOnError": true,
|
||||
"outDir": "dist/",
|
||||
"allowImportingTsExtensions": false,
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
}
|
22
tsconfig.json
Normal file
22
tsconfig.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue