Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
A minimalist NodeJS client for 신경 written in TypeScript. Requires Node 18+
뉴런
- neuron
Neuron
/ˈnjʊəɹɒn/ • noun
- (cytology) A cell of the nervous system, which conducts nerve impulses; consisting of an axon and several dendrites. Neurons are connected by synapses.
This client only does very little abstraction over the 신경 connection and protocol, while still providing QoL helpers and a user-friendly API.
The small amount of abstractions makes it plugin-friendly: it can deal with arbitrary events and routes easily.
Warning: 신경 is alpha software, so is 뉴런. Because breaking changes may happen at any time in 신경, it means this library may also receive breaking changes that will reflect the upstream changes.
pnpm add nyuleon
# or
yarn add nyuleon
# or
npm i nyuleon
import SingyeongClient from 'nyuleon'
const client = new SingyeongClient('singyeong://my-fancy-app@localhost:4000/', { options... })
clientId: string
: ID this client should have. Must be unique. If unset, a random UUID will be used.authentication: string
: Authentication token to use. If set, will override the password part of the DSN.ip: string
: IP used for HTTP proxying. Despite the name, this field accepts a protocol (http:// or https://) and a port.
http://<Connecting IP>:80
will be used to send requests to your client.namespace: string
: Namespace of the app. Useful for routing via namespace
metadata key.receiveClientUpdates: boolean
: Whether the client wants to receive events when a client dis/connects to/from the server.dispatcher: Dispatcher
: Undici dispatcher to use for all HTTP requests.
restOnly: boolean
: When set to true, the client will not connect and you will only be able to use the REST API.
updateMetadata(metadata: MetadataData): void
metadata: MetadataData
: Metadata object. Must be complete, partial updates won't work! Can be made type safe.send({ query, payload, nonce }: MessageParams): void
query: Query
: Routing query. Can be made type safe.payload: any
: Payload to send.nonce?: string
: String that'll be sent along with the message. Can be used for req-res messaging.broadcast({ query, payload, nonce }: MessageParams): void
send
for the parameters documentation.queue({ queue, query, payload, nonce }: QueueMessageParams): void
queue: string
: Name of the queue to push into.send
for the other parameters documentation.queueSubscribe(queue: string): void
queue: string
: Name of the queue to subscribe to.queueUnsubscribe(queue: string): void
queue: string
: Name of the queue to unsubscribe from.queueAck(queue: string, id: string): void
queue: string
: Name of the queue.id: string
: ID sent by singyeong along with the message you want to acknowledge.dispatch(event: string, payload: any): void
event: string
: Name of the event to dispatch.payload: any
: Payload to send as dispatch data.close(code?: number, reason?: string): void
code?: number
: WebSocket close codereason?: number
: WebSocket close reason messageproxy(query: Query, request: RequestParams): Promise<ResponseData>
query: Query
: Routing query to find the application to request. Can be made type safe.request: RequestParams
: Request to send to the target client.
request.method: HttpMethod
: HTTP method.request.route: string
: HTTP path to send the request to.request.headers?: Record<string, string>
: HTTP headers to send along with the request.request.body?: any
: Request body to send. Cannot be set if method
is GET.findClients(query: Query): Promise<Client[]>
query: Query
: Routing query you want to search for. Can be made type safe.request(request: RequestOptions): Promise<ResponseData>
request: RequestOptions
: An Undici RequestOptions object.ready
: Emitted when singyeong sent the READY
payload.
restricted: boolean
: Whether the socket is considered "restricted".message
: Emitted when a message has been received.
message: Message<T = any>
: The message you received
message.payload: T
: The payload.message.nonce?: string
: The nonce of the payload, if set by the emitter.broadcast: boolean
: Whether the message was a BROADCAST
or a SEND
.queueMessage
: Emitted when a message from a queue has been received.
message: QueueMessage<T = any>
: The message you received
message.queue: string
: The name of the queue this message is from.message.id: string
: ID to send to singyeong to acknowledge this message.message.payload: T
: The payload.message.nonce?: string
: The nonce of the payload, if set by the emitter.message.ack: Function
: Acks the message. Alias to client.queueAck(msg.queue, msg.id)
.queueConfirm
: Emitted by singyeong to confirm a message has been queued.
queue: string
: Name of the queue.clientConnected
: Emitted when a new client connected to the singyeong server.
applicationId: string
: ID of the application that connected.clientDisconnected
: Emitted when a client disconnected from the singyeong server.
applicationId: string
: ID of the application that disconnected.pluginDispatch
: Emitted when a non-standard (plugin) dispatch was received.
event: string
: Name of the dispatch event received.payload: any
: Raw payload data sent.reconnect
: Emitted when the connection was closed and the client is reconnecting.
code: number
: WebSocket close code.reason: string
: WebSocket close reason.wasClean: boolean
: Whether the close was clean or not.close
: Emitted when the connection was closed.
code: number
: WebSocket close code.reason: string
: WebSocket close reason.wasClean: boolean
: Whether the close was clean or not.zombie
: Emitted when the server stopped responding to heartbeat. The client will disconnect and reconnect.
error
: Emitted when an error occurred.
e: SingyeongError
: The error.뉴런 has first-class support for type safe queries and metadata support. By default, the only type checking enforced is "whatever that is valid". However, you can specify via generics the shape of metadata objects you are dealing with, and strong type checking will be applied. This ensures your queries are always valid, and it gives amazing autocompletion capability.
type MyMeta = { someString: string, someNumber: number, someOtherString: string };
const client = new SingyeongClient<MyMeta>('singyeong://meow@localhost:4000')
client.updateMetadata({
someString: { type: 'string', value: '1' },
someNumber: { type: 'integer', value: 1337 },
// this will cause a type error:
someOtherString: { type: 'boolean', value: false },
// this will cause a type error:
anUnknownMetadataProperty: { type: 'string', value: 'who am i??' },
})
type TargetMetadata = { key1: string, key2: { subkey1: string } };
client.send<TargetMetadata>({
query: {
ops: [
{
path: '/key1',
op: '$eq',
// this will cause a type error
to: { value: 1 },
},
{
// this will cause a type error
path: '/unknownKey',
op: '$eq',
to: { value: 1 },
},
],
},
})
신경 named itself after the Korean word for "nerve", so the name 뉴런 ("neuron") was picked to stay in the same naming scheme: Korean word around the nervous system.
FAQs
NodeJS client for singyeong
We found that nyuleon demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.