irctokens-js/README.md

102 lines
2.9 KiB
Markdown

# irctokens
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![QA](https://github.com/swantzter/irctokens-js/actions/workflows/qa.yml/badge.svg)](https://github.com/swantzter/irctokens-js/actions/workflows/qa.yml)
[![Publish to NPM and GCR](https://github.com/swantzter/irctokens-js/actions/workflows/publish.yml/badge.svg)](https://github.com/swantzter/irctokens-js/actions/workflows/publish.yml)
[![codecov](https://codecov.io/gh/swantzter/irctokens-js/branch/main/graph/badge.svg)](https://codecov.io/gh/swantzter/irctokens-js)
TypeScript port of the python library [irctokens](https://github.com/jesopo/irctokens).
The major and minor version of this library will aim to follow upstream, patch
will be increased independently.
## rationale
there's far too many IRC client implementations out in the world that do not
tokenise data correctly and thus fall victim to things like colons either being
where you don't expect them or not being where you expect them.
## usage
### installation
`$ npm install irctokens`
### tokenisation
```typescript
import { tokenise } from 'irctokens'
const line = tokenise('@id=123 :Swant!~swant@hostname PRIVMSG #chat :hello there!')
console.log(line.tags)
// { id: '123' }
console.log(line.source)
// 'Swant!~swant@hostname'
console.log(line.hostmask)
// Hostmask { nickname: 'Swant', username: '~swant', hostname: 'hostname' }
console.log(line.command)
// 'PRIVMSG'
console.log(line.params)
// ['#chat', 'hello there!']
```
### formatting
```typescript
import { Line } from 'irctokens'
const line = new Line({ command: 'USER', params: ['user', '0', '*', 'real name'] })
console.log(line.format())
// 'USER user 0 * :real name'
```
### stateful
below is an example of a fully socket-wise safe IRC client connection that will
connect and join a channel. both protocol sending and receiving are handled by
irctokens.
```typescript
import { Socket } from 'net'
import { Line, StatefulEncoder, StatefulDecoder } from 'irctokens'
const NICK = 'nickname'
const CHAN = '#channel'
const d = new StatefulDecoder()
const e = new StatefulEncoder()
const s = new Socket()
s.connect(6667, '127.0.0.1')
function send (line: Line) {
console.log(`> ${line.format()}`)
e.push(line)
const pending = e.pending()
s.write(pending)
e.pop(pending.length)
}
s.once('connect', () => {
send(new Line({ command: 'USER', params: ['username', '0', '*', 'real name'] }))
send(new Line({ command: 'NICK', params: [NICK] }))
})
s.on('data', data => {
const lines = d.push(Uint8Array.from(data))
if (!lines) return
for (const line of lines) {
console.log(`< ${line.format()}`)
if (line.command === 'PING') send(new Line({ command: 'PONG', params: [line.params[0]] }))
else if (line.command === '001') send(new Line({ command: 'JOIN', params: [CHAN] }))
}
})
```
## contact
Come say hi at `#irctokens` on irc.libera.chat