100 lines
2.8 KiB
Markdown
100 lines
2.8 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)
|
||
|
|
||
|
TypeScrip port of the python library [irctokens](https://github.com/jesopo/irctokens)
|
||
|
|
||
|
## 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
|