Compare commits

...

27 Commits

Author SHA1 Message Date
Leifer Mendez
eda8a67718 refactor(provider): twilio + hook 2022-12-07 18:06:27 +01:00
Leifer Mendez
73caf090ba fix(bot): added delay promises 2022-12-07 16:20:56 +01:00
Leifer Mendez
8dd3be909b feat(provider): added twilio provider 2022-12-06 21:28:52 +01:00
Leifer Mendez
24ac9fbf48 fix(bot): fix sensitive case 2022-12-06 19:35:21 +01:00
Leifer Mendez
4350dff22a feat(provider): 🔥 add twilii (weoking) 2022-12-05 20:45:05 +01:00
github-actions[bot]
30e3d443bb docs(contributor): contrib-readme-action has updated readme 2022-12-05 15:47:15 +00:00
Leifer Mendez
f5ea7fe2c4 Merge branch 'dev' of github.com:leifermendez/bot-whatsapp into dev 2022-12-05 16:46:47 +01:00
Leifer Mendez
94d139e484 ci(contributors): add username avatar 2022-12-05 16:46:29 +01:00
github-actions[bot]
8049241f3f docs(contributor): contrib-readme-action has updated readme 2022-12-05 15:45:01 +00:00
Leifer Mendez
28d308ed4b ci(contributors): add username avatar 2022-12-05 16:44:36 +01:00
Leifer Mendez
e0862053d0 Merge branch 'feature/fallback' into dev 2022-12-05 16:35:05 +01:00
Leifer Mendez
e0e76d3a56 ci(contributors): add username avatar 2022-12-05 16:33:22 +01:00
Leifer Mendez
242e44315b Merge pull request #139 from leifermendez/feature/fallback
Feature/fallback
2022-12-05 16:32:02 +01:00
Leifer Mendez
6b53ed13e2 docs(contributors): add username avatar 2022-12-05 16:15:21 +01:00
Leifer Mendez
fafccbcecc Merge commit 'f2533f1ed5c0078be59938720f2ecf96c616b843' into feature/fallback 2022-12-05 16:05:49 +01:00
Leifer Mendez
49698bfda9 fix(bot): update 2022-12-05 16:02:23 +01:00
Leifer Mendez
4154cc2230 feat(bot): 🔥 improvement provider handler 2022-12-05 14:49:23 +01:00
Leifer Mendez
ce8a96b958 feat(bot): add send image function 2022-12-05 13:01:32 +01:00
Leifer Mendez
f373a3abc7 chore(bot): fallback done 2022-12-05 09:59:40 +01:00
Leifer Mendez
371ee0a780 chore(bot): update fallback function 2022-12-04 16:01:52 +01:00
Leifer Mendez
aa2417af12 chore(bot): added new fallback option 2022-12-02 15:22:13 +01:00
Leifer Mendez
f2533f1ed5 Merge pull request #136 from leifermendez/feature/monorepo
docs(contributing):  update
2022-12-01 21:34:54 +01:00
Leifer Mendez
f9ccfef8e0 Merge pull request #135 from leifermendez/feature/monorepo
chore(cli): 🔥 fix
2022-12-01 21:07:48 +01:00
Leifer Mendez
08dbdcf4ae Merge pull request #134 from leifermendez/feature/monorepo
chore(cli): 🎨 remove uneccesary steps
2022-12-01 20:59:57 +01:00
Leifer Mendez
d7ed9ff592 Merge pull request #133 from leifermendez/feature/monorepo
chore(cli):  added new function
2022-12-01 20:45:34 +01:00
Leifer Mendez
a99f424901 Merge pull request #132 from leifermendez/feature/monorepo
Feature/monorepo
2022-12-01 18:43:03 +01:00
Leifer Mendez
f29ed6e29b Merge pull request #131 from leifermendez/feature/monorepo
Merge pull request #130 from leifermendez/dev
2022-12-01 18:38:03 +01:00
35 changed files with 1023 additions and 213 deletions

View File

@@ -2,7 +2,7 @@ name: Test / Coverage
on:
push:
branches: [feature/monorepo]
branches: [dev]
pull_request:
branches: [main]

20
.github/workflows/contributors.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Add contributors
on:
schedule:
- cron: '20 20 * * *'
push:
branches: [dev]
pull_request:
branches: [main, dev]
jobs:
contrib-readme-job:
runs-on: ubuntu-latest
name: A job to automate contrib in readme
steps:
- name: Contribute List
uses: akhilmhdh/contributors-readme-action@v2.3.6
with:
image_size: 50
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

2
.gitignore vendored
View File

@@ -18,6 +18,8 @@ config.json
coverage/
*.lcov
log
log/*
*.log
lib
tmp/
.yarn/*

View File

@@ -1,3 +1,9 @@
{
"conventionalCommits.scopes": ["hook", "contributing", "cli"]
"conventionalCommits.scopes": [
"hook",
"contributing",
"cli",
"bot",
"provider"
]
}

2
GLOSSARY.md Normal file
View File

@@ -0,0 +1,2 @@
CTX: Es el objeto que representa un mensaje, con opciones, id, ref
messageInComming: Objeto entrante del provider {body, from,...}

View File

@@ -8,6 +8,75 @@ Video como hacer PR: https://youtu.be/Lxt8Acob6aU
**Comunidad**
<!-- readme: collaborators,contributors -start -->
<table>
<tr>
<td align="center">
<a href="https://github.com/leifermendez">
<img src="https://avatars.githubusercontent.com/u/15802366?v=4" width="50;" alt="leifermendez"/>
<br />
<sub><b>Leifer Mendez</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/aurik3">
<img src="https://avatars.githubusercontent.com/u/37228512?v=4" width="50;" alt="aurik3"/>
<br />
<sub><b>Null</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/vicente1992">
<img src="https://avatars.githubusercontent.com/u/57806030?v=4" width="50;" alt="vicente1992"/>
<br />
<sub><b>Manuel Vicente Ortiz</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/leifermendezfroged">
<img src="https://avatars.githubusercontent.com/u/97020486?v=4" width="50;" alt="leifermendezfroged"/>
<br />
<sub><b>Leifer Mendez</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Gonzalito87">
<img src="https://avatars.githubusercontent.com/u/100331586?v=4" width="50;" alt="Gonzalito87"/>
<br />
<sub><b>Null</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/tonyvazgar">
<img src="https://avatars.githubusercontent.com/u/21047090?v=4" width="50;" alt="tonyvazgar"/>
<br />
<sub><b>Luis Antonio Vázquez García</b></sub>
</a>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/ulisesvina">
<img src="https://avatars.githubusercontent.com/u/20508563?v=4" width="50;" alt="ulisesvina"/>
<br />
<sub><b>Ulises Viña</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/rrruuuyyy">
<img src="https://avatars.githubusercontent.com/u/33061671?v=4" width="50;" alt="rrruuuyyy"/>
<br />
<sub><b>Rodrigo Mendoza Cabrera</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/yond1994">
<img src="https://avatars.githubusercontent.com/u/47557263?v=4" width="50;" alt="yond1994"/>
<br />
<sub><b>Yonathan Suarez</b></sub>
</a>
</td></tr>
</table>
<!-- readme: collaborators,contributors -end -->
> Forma parte de este proyecto.
@@ -15,6 +84,3 @@ Video como hacer PR: https://youtu.be/Lxt8Acob6aU
- [Twitter](https://twitter.com/leifermendez)
- [Youtube](https://www.youtube.com/watch?v=5lEMCeWEJ8o&list=PL_WGMLcL4jzWPhdhcUyhbFU6bC0oJd2BR)
- [Telegram](https://t.me/leifermendez)

33
TODO.md
View File

@@ -2,31 +2,50 @@
- [X] __(doc)__ Video de como colaborar PR
- [ ] __(doc)__ Video implementación de test y cobertura
- [ ] __(doc)__ Video explicacion de github action
- [ ] Crear packages list externas
### @bot-whatsapp/bot
- [ ] agregar export package
- [X] agregar export package
- [X] Posibilidad de en el capture meter todo un nuevo CTX de FLOW .addAnswer('Marca la opcion',{capture:true, join:CTX})
- [X] .addKeyword('1') no funciona con 1 caracter
- [X] sensitivy viene activado por defecto
- [ ] fallback respuesta en hijo: Se puede colocar en option el ref de la answer fallback
- [X] fallback respuesta en hijo: Se puede colocar en option el ref de la answer fallback
- [X] Cuando Envian Sticket devuelve mensaje raro
- [x] addAnswer agregar delay
- [ ] colocar mensaje esperando conectando whatsapp (provider)
- [ ] Cuando Envian Sticket devuelve mensaje raro
- [ ] createDatabase validar implementacion de funciones
- [ ] limitar caracteres de mensajes 4000
- [X] cuando envias numeros (5 o 1) se dispara el flujo
### @bot-whatsapp/database
- [X] agregar export package
- [X] __(doc):__ Video para explicar como implementar nuevos database
- [X] Mongo adapter
- [ ] MySQL adapter
- [X] MySQL adapter
- [ ] JsonFile adapter
### @bot-whatsapp/provider
- [X] agregar export package
- [ ] __(doc):__ Video para explicar como implementar nuevos providers
- [ ] WhatsappWeb provider enviar imagenes
- [ ] WhatsappWeb provider enviar audio
- [X] WhatsappWeb provider enviar imagenes
- [X] WhatsappWeb provider enviar audio
- [X] WhatsappWeb botones (Tiene truco) github:leifermendez/whatsapp-web.js
- [ ] Twilio adapter
- [ ] Meta adapter
### @bot-whatsapp/cli
- [ ] Hacer comando para crear `example-app`
- [X] Hacer comando para crear `example-app`
### @bot-whatsapp/create-bot
- [ ]
### Starters
- [X] Base
- [X] Basico
- [ ] Enviando Imagen
- [ ] Enviando Botones
- [ ] Mezclando flujos hijos
### Extra
- [X] Crear CI mantener fork update https://stackoverflow.com/questions/23793062/can-forks-be-synced-automatically-in-github

View File

@@ -7,6 +7,7 @@
"scripts": {
"commit": "git-cz",
"cli:rollup": "rollup --config ./packages/cli/rollup-cli.config.js ",
"create-bot:rollup": "rollup --config ./packages/create-bot-whatsapp/rollup-create.config.js ",
"bot:rollup": "rollup --config ./packages/bot/rollup-bot.config.js",
"provider:rollup": "rollup --config ./packages/provider/rollup-provider.config.js ",
"database:rollup": "rollup --config ./packages/database/rollup-database.config.js",
@@ -16,12 +17,12 @@
"lint:check": "eslint ./packages",
"lint:fix": "eslint --fix ./packages",
"build": "yarn run cli:rollup && yarn run bot:rollup && yarn run provider:rollup && yarn run database:rollup",
"link.dist": "cd packages/bot && npm link && cd ../provider && npm link && cd ../cli && npm link && cd ../database && npm link && cd ../provider && npm link",
"copy.lib": "node ./scripts/move.js",
"test.unit": "node ./node_modules/uvu/bin.js packages test",
"test.coverage": "node ./node_modules/c8/bin/c8.js npm run test.unit",
"test": "npm run test.coverage",
"cli": "node ./packages/cli/bin/cli.js",
"create": "node ./packages/create-bot-whatsapp/bin/create.js",
"dev:debug": "node --inspect ./example-app/app.js",
"dev": "node ./example-app/app.js",
"prepare": "npx husky install",
@@ -30,6 +31,7 @@
"release": "standard-version"
},
"workspaces": [
"packages/create-bot-whatsapp",
"packages/bot",
"packages/cli",
"packages/database",

View File

@@ -1,6 +1,13 @@
const { toCtx } = require('../io/methods')
const { printer } = require('../utils/interactive')
const { delay } = require('../utils/delay')
const Queue = require('../utils/queue')
const { Console } = require('console')
const { createWriteStream } = require('fs')
const logger = new Console({
stdout: createWriteStream(`${process.cwd()}/core.class.log`),
})
/**
* [ ] Escuchar eventos del provider asegurarte que los provider emitan eventos
* [ ] Guardar historial en db
@@ -21,7 +28,14 @@ class CoreClass {
}
}
/**
* Manejador de eventos
*/
listenerBusEvents = () => [
{
event: 'preinit',
func: () => printer('Iniciando provider espere...'),
},
{
event: 'require_action',
func: ({ instructions, title = '⚡⚡ ACCION REQUERIDA ⚡⚡' }) =>
@@ -44,16 +58,19 @@ class CoreClass {
]
/**
* @private
* @param {*} ctxMessage
*
* @param {*} messageInComming
* @returns
*/
handleMsg = async (messageInComming) => {
logger.log(`[handleMsg]: `, messageInComming)
const { body, from } = messageInComming
let msgToSend = []
let fallBackFlag = false
if (!body.length) return
//Consultamos mensaje previo en DB
const prevMsg = await this.databaseClass.getPrevByNumber(from)
//Consultamos for refSerializada en el flow actual
const refToContinue = this.flowClass.findBySerialize(
prevMsg?.refSerialize
)
@@ -67,14 +84,24 @@ class CoreClass {
this.databaseClass.save(ctxByNumber)
}
//Si se tiene un callback se ejecuta
if (refToContinue && prevMsg?.options?.callback) {
const indexFlow = this.flowClass.findIndexByRef(refToContinue?.ref)
this.flowClass.allCallbacks[indexFlow].callback(messageInComming)
// 📄 [options: fallback]: esta funcion se encarga de repetir el ultimo mensaje
const fallBack = () => {
fallBackFlag = true
msgToSend = this.flowClass.find(refToContinue?.keyword, true) || []
this.sendFlow(msgToSend, from)
return refToContinue
}
//Si se tiene anidaciones de flows, si tienes anidados obligatoriamente capture:true
if (prevMsg?.options?.nested?.length) {
// 📄 [options: callback]: Si se tiene un callback se ejecuta
if (!fallBackFlag && refToContinue && prevMsg?.options?.callback) {
const indexFlow = this.flowClass.findIndexByRef(refToContinue?.ref)
this.flowClass.allCallbacks[indexFlow].callback(messageInComming, {
fallBack,
})
}
// 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa
if (!fallBackFlag && prevMsg?.options?.nested?.length) {
const nestedRef = prevMsg.options.nested
const flowStandalone = nestedRef.map((f) => ({
...nestedRef.find((r) => r.refSerialize === f.refSerialize),
@@ -85,28 +112,44 @@ class CoreClass {
return
}
//Consultamos si se espera respuesta por parte de cliente "Ejemplo: Dime tu nombre"
if (!prevMsg?.options?.nested?.length && prevMsg?.options?.capture) {
// 📄🤘(tiene return) [options: capture (boolean)]: Si se tiene option boolean
if (!fallBackFlag && !prevMsg?.options?.nested?.length) {
const typeCapture = typeof prevMsg?.options?.capture
const valueCapture = prevMsg?.options?.capture
if (['string', 'boolean'].includes(typeCapture) && valueCapture) {
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
} else {
msgToSend = this.flowClass.find(body) || []
this.sendFlow(msgToSend, from)
return
}
}
msgToSend = this.flowClass.find(body) || []
this.sendFlow(msgToSend, from)
}
/**
* Enviar mensaje con contexto atraves del proveedor de whatsapp
* @param {*} numberOrId
* @param {*} ctxMessage ver más en GLOSSARY.md
* @returns
*/
sendProviderAndSave = (numberOrId, ctxMessage) => {
const { answer } = ctxMessage
return Promise.all([
this.providerClass.sendMessage(numberOrId, answer),
this.providerClass.sendMessage(numberOrId, answer, ctxMessage),
this.databaseClass.save({ ...ctxMessage, from: numberOrId }),
])
}
sendFlow = (messageToSend, numberOrId) => {
sendFlow = async (messageToSend, numberOrId) => {
const queue = []
for (const ctxMessage of messageToSend) {
queue.push(this.sendProviderAndSave(numberOrId, ctxMessage))
const delayMs = ctxMessage?.options?.delay || 0
if (delayMs) await delay(delayMs)
Queue.enqueue(() =>
this.sendProviderAndSave(numberOrId, ctxMessage)
)
}
return Promise.all(queue)
}

View File

@@ -22,11 +22,13 @@ const createFlow = (args) => {
/**
* Crear instancia de clase Provider
* Depdendiendo del Provider puedes pasar argumentos
* Ver Documentacion
* @param {*} args
* @returns
*/
const createProvider = (providerClass = class {}) => {
const providerInstance = new providerClass()
const createProvider = (providerClass = class {}, args = null) => {
const providerInstance = new providerClass(args)
if (!providerClass.prototype instanceof ProviderClass)
throw new Error('El provider no implementa ProviderClass')
return providerInstance

View File

@@ -21,29 +21,25 @@ class FlowClass {
}
find = (keyOrWord, symbol = false, overFlow = null) => {
keyOrWord = `${keyOrWord}`
let capture = false
let messages = []
let refSymbol = null
overFlow = overFlow ?? this.flowSerialize
const mapSensitiveString = (str, flag = false) => {
if (!flag && Array.isArray(str)) {
return str.map((c) => c.toLowerCase())
/** Retornar expresion regular para buscar coincidencia */
const mapSensitive = (str, flag = false) => {
const regexSensitive = flag ? 'g' : 'i'
if (Array.isArray(str)) {
return new RegExp(str.join('|'), regexSensitive)
}
if (!flag && typeof str === 'string') {
return str.toLowerCase()
}
return str
return new RegExp(str, regexSensitive)
}
const findIn = (keyOrWord, symbol = false, flow = overFlow) => {
const sensitive = refSymbol?.options?.sensitive || false
capture = refSymbol?.options?.capture || false
keyOrWord = mapSensitiveString(keyOrWord, sensitive)
if (capture) return messages
if (symbol) {
@@ -51,9 +47,9 @@ class FlowClass {
if (refSymbol?.answer) messages.push(refSymbol)
if (refSymbol?.ref) findIn(refSymbol.ref, true)
} else {
refSymbol = flow.find((c) =>
mapSensitiveString(c.keyword, sensitive).includes(keyOrWord)
)
refSymbol = flow.find((c) => {
return mapSensitive(c.keyword, sensitive).test(keyOrWord)
})
if (refSymbol?.ref) findIn(refSymbol.ref, true)
return messages
}

View File

@@ -1,10 +1,9 @@
const { generateRef } = require('../../utils/hash')
const { toJson } = require('./toJson')
const { toSerialize } = require('./toSerialize')
/**
*
* @param answer string
* @param options {media:string, buttons:[], capture:true default false}
* @param options {media:string, buttons:[{"body":"😎 Cursos"}], delay:ms, capture:true default false}
* @returns
*/
const addAnswer =
@@ -25,6 +24,7 @@ const addAnswer =
: false,
child:
typeof options?.child === 'string' ? `${options?.child}` : null,
delay: typeof options?.delay === 'number' ? options?.delay : 0,
})
const getNested = () => ({
@@ -79,6 +79,7 @@ const addAnswer =
}
}
/// Retornar contexto no colocar nada más abajo de esto
const ctx = ctxAnswer()
return {

View File

@@ -19,7 +19,7 @@ class ProviderClass extends EventEmitter {
*
*/
sendMessage = async (userId, message) => {
sendMessage = async (userId, message, sendMessage) => {
if (NODE_ENV !== 'production')
console.log('[sendMessage]', { userId, message })
return message

View File

@@ -0,0 +1,4 @@
const delay = (miliseconds) =>
new Promise((res) => setTimeout(res, miliseconds))
module.exports = { delay }

View File

@@ -0,0 +1,46 @@
class Queue {
static queue = []
static pendingPromise = false
static enqueue(promise) {
return new Promise((resolve, reject) => {
this.queue.push({
promise,
resolve,
reject,
})
this.dequeue()
})
}
static dequeue() {
if (this.workingOnPromise) {
return false
}
const item = this.queue.shift()
if (!item) {
return false
}
try {
this.workingOnPromise = true
item.promise()
.then((value) => {
this.workingOnPromise = false
item.resolve(value)
this.dequeue()
})
.catch((err) => {
this.workingOnPromise = false
item.reject(err)
this.dequeue()
})
} catch (err) {
this.workingOnPromise = false
item.reject(err)
this.dequeue()
}
return true
}
}
module.exports = Queue

View File

@@ -0,0 +1,3 @@
#!/usr/bin/env node
const main = require('../lib/bin/bundle.create.cjs')
main()

View File

@@ -0,0 +1,12 @@
/**
* Main function
*/
const main = () => {
console.clear()
console.log(``)
console.log(`[PostInstall]: Este es el main function.`)
console.log(`[PostInstall]: 👌 Aqui podrias instalar cosas`)
console.log(``)
}
module.exports = main

View File

@@ -0,0 +1,13 @@
{
"name": "create-bot-whatsapp",
"version": "0.0.1",
"description": "",
"main": "./lib/bin/bundle.create.cjs",
"private": true,
"dependencies": {
"@bot-whatsapp/cli": "*"
},
"bin": {
"bot": "./lib/bin/bundle.create.cjs"
}
}

View File

@@ -0,0 +1,16 @@
const banner = require('../../config/banner.rollup.json')
const commonjs = require('@rollup/plugin-commonjs')
const { nodeResolve } = require('@rollup/plugin-node-resolve')
const { join } = require('path')
const PATH = join(__dirname, 'lib', 'bin', 'bundle.create.cjs')
module.exports = {
input: join(__dirname, 'index.js'),
output: {
banner: banner['banner.output'].join(''),
file: PATH,
format: 'cjs',
},
plugins: [commonjs(), nodeResolve()],
}

View File

@@ -1,24 +1,17 @@
require('dotenv').config()
const mysql = require('mysql2')
const DB_NAME = process.env.DB_NAME || 'db_bot'
const DB_HOST = process.env.DB_HOST || 'localhost'
const DB_USER = process.env.DB_USER || 'root'
class MyslAdapter {
db
listHistory = []
credentials = { host: null, user: null, database: null }
constructor() {
constructor(_credentials) {
this.credentials = _credentials
this.init().then()
}
async init() {
this.db = mysql.createConnection({
host: DB_HOST,
user: DB_USER,
database: DB_NAME,
})
this.db = mysql.createConnection(this.credentials)
await this.db.connect((error) => {
if (!error) {

View File

@@ -29,10 +29,13 @@
"@types/node": "latest",
"@typescript-eslint/eslint-plugin": "5.43.0",
"@typescript-eslint/parser": "5.43.0",
"autoprefixer": "10.4.11",
"eslint": "8.28.0",
"eslint-plugin-qwik": "0.14.1",
"node-fetch": "3.3.0",
"postcss": "^8.4.16",
"prettier": "2.7.1",
"tailwindcss": "^3.1.8",
"typescript": "4.9.3",
"vite": "3.2.4",
"vite-tsconfig-paths": "3.5.0",

View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@@ -0,0 +1,21 @@
/** @type {import('tailwindcss').Config} */
const defaultTheme = require("tailwindcss/defaultTheme");
const colors = require("tailwindcss/colors");
module.exports = {
content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
theme: {
extend: {
colors: {
primary: colors.purple,
secondary: colors.sky,
},
fontFamily: {
sans: ["'Inter'", ...defaultTheme.fontFamily.sans],
},
},
},
plugins: [],
darkMode: "class",
};

View File

@@ -1,13 +0,0 @@
# @bot-whatsapp/provider
```js
// bootstrap.js Como iniciar el provider
const { inout, provider, database } = require('@bot-whatsapp')
provider.start()
provider.close()
```
- [ ] whatsapp-web.js _verificar update_
- [ ] Meta _verificar tokens_
- [ ] Twilio _verificar tokens_

View File

@@ -1,19 +1,59 @@
const twilio = require('twilio')
const { ProviderClass } = require('@bot-whatsapp/bot')
const TwilioVendor = new twilio(accountSid, authToken)
const TwilioWebHookServer = require('./server')
const { parseNumber } = require('./utils')
/**
* { accountSid, authToken, vendorNumber }
*/
class TwilioProvider extends ProviderClass {
constructor() {
super(TwilioVendor)
twilioHook
vendor
vendorNumber
constructor({ accountSid, authToken, vendorNumber }, _port = 3000) {
super()
this.vendor = new twilio(accountSid, authToken)
this.twilioHook = new TwilioWebHookServer(_port)
this.vendorNumber = vendorNumber
this.twilioHook.start()
const listEvents = this.busEvents()
for (const { event, func } of listEvents) {
this.twilioHook.on(event, func)
}
}
sendMessage = (message) =>
this.vendor.messages.create({
sendMessage = async (number, message) => {
return this.vendor.messages.create({
body: message,
to: '+12345678901', // Text this number
from: '+12345678901', // From a valid Twilio number
from: ['whatsapp:+', parseNumber(this.vendorNumber)].join(''),
to: ['whatsapp:+', parseNumber(number)].join(''),
})
}
/**
* Mapeamos los eventos nativos de whatsapp-web.js a los que la clase Provider espera
* para tener un standar de eventos
* @returns
*/
busEvents = () => [
{
event: 'auth_failure',
func: (payload) => this.emit('error', payload),
},
{
event: 'ready',
func: () => this.emit('ready', true),
},
{
event: 'message',
func: (payload) => {
this.emit('message', payload)
},
},
]
}
module.exports = TwilioProvider

View File

@@ -0,0 +1,63 @@
const { EventEmitter } = require('node:events')
const polka = require('polka')
const { urlencoded } = require('body-parser')
const { parseNumber } = require('./utils')
/**
* Encargado de levantar un servidor HTTP con una hook url
* [POST] /twilio-hook
*/
class TwilioWebHookServer extends EventEmitter {
twilioServer
twilioPort
constructor(_twilioPort) {
this.twilioServer = this.buildHTTPServer()
this.twilioPort = _twilioPort
}
/**
* Mensaje entrante
* emit: 'message'
* @param {*} req
* @param {*} res
*/
incomingMsg = (req, res) => {
const { body } = req
this.emit('message', {
from: parseNumber(body.From),
to: parseNumber(body.To),
body: body.Body,
})
const json = JSON.stringify({ body })
res.end(json)
}
/**
* Contruir HTTP Server
* @returns
*/
buildHTTPServer = () => {
return polka()
.use(urlencoded({ extended: true }))
.post('/twilio-hook', this.incomingMsg)
}
/**
* Puerto del HTTP
* @param {*} port default 3000
*/
start = () => {
this.twilioServer.listen(this.twilioPort, () => {
console.log(``)
console.log(`[Twilio]: Agregar esta url "WHEN A MESSAGE COMES IN"`)
console.log(
`[Twilio]: http://localhost:${this.twilioPort}/twilio-hook`
)
console.log(`[Twilio]: Más información en la documentacion`)
console.log(``)
})
this.emit('ready')
}
}
module.exports = TwilioWebHookServer

View File

@@ -0,0 +1,5 @@
const parseNumber = (number) => {
return `${number}`.replace('whatsapp:', '').replace('+', '')
}
module.exports = { parseNumber }

View File

@@ -1,13 +1,24 @@
const { Client, LocalAuth } = require('whatsapp-web.js')
const {
Client,
LocalAuth,
MessageMedia,
Buttons,
List,
} = require('whatsapp-web.js')
const { ProviderClass } = require('@bot-whatsapp/bot')
const { Console } = require('console')
const { createWriteStream } = require('fs')
const { createWriteStream, existsSync } = require('fs')
const { cleanNumber, generateImage, isValidNumber } = require('./utils')
const logger = new Console({
stdout: createWriteStream('./log'),
})
/**
* WebWhatsappProvider: Es una clase tipo adaptor
* que extiende clases de ProviderClass (la cual es como interfaz para sber que funciones rqueridas)
* https://github.com/pedroslopez/whatsapp-web.js
*/
class WebWhatsappProvider extends ProviderClass {
vendor
constructor() {
@@ -21,13 +32,14 @@ class WebWhatsappProvider extends ProviderClass {
for (const { event, func } of listEvents) {
this.vendor.on(event, func)
}
this.vendor.emit('preinit')
this.vendor.initialize().catch((e) => {
logger.log(e)
this.emit('require_action', {
instructions: [
`Debes eliminar la carpeta .wwebjs_auth`,
`y reiniciar nuevamente el bot `,
`(Opcion 1): Debes eliminar la carpeta .wwebjs_auth y reiniciar nuevamente el bot. `,
`(Opcion 2): Intenta actualizar el paquete [npm install whatsapp-web.js] `,
`(Opcion 3): Ir FORO de discord https://link.codigoencasa.com/DISCORD `,
],
})
})
@@ -60,10 +72,6 @@ class WebWhatsappProvider extends ProviderClass {
event: 'ready',
func: () => this.emit('ready', true),
},
{
event: 'authenticated',
func: () => this.emit('ready', true),
},
{
event: 'message',
func: (payload) => {
@@ -80,10 +88,87 @@ class WebWhatsappProvider extends ProviderClass {
},
]
sendMessage = async (userId, message) => {
const number = cleanNumber(userId)
/**
* Enviar un archivo multimedia
* https://docs.wwebjs.dev/MessageMedia.html
* @private
* @param {*} number
* @param {*} mediaInput
* @returns
*/
sendMedia = async (number, mediaInput = null) => {
if (!existsSync(mediaInput))
throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
const media = MessageMedia.fromFilePath(mediaInput)
return this.vendor.sendMessage(number, media, {
sendAudioAsVoice: true,
})
}
/**
* Enviar botones
* https://docs.wwebjs.dev/Buttons.html
* @private
* @param {*} number
* @param {*} message
* @param {*} buttons []
* @returns
*/
sendButtons = async (number, message, buttons = []) => {
const buttonMessage = new Buttons(message, buttons, '', '')
return this.vendor.sendMessage(number, buttonMessage)
}
/**
* Enviar lista
* https://docs.wwebjs.dev/List.html
* @private
* @alpha No funciona en whatsapp bussines
* @param {*} number
* @param {*} message
* @param {*} buttons []
* @returns
*/
sendList = async (number, message, listInput = []) => {
let sections = [
{
title: 'sectionTitle',
rows: [
{ title: 'ListItem1', description: 'desc' },
{ title: 'ListItem2' },
],
},
]
let list = new List('List body', 'btnText', sections, 'Title', 'footer')
return this.vendor.sendMessage(number, list)
}
/**
* Enviar un mensaje solo texto
* https://docs.wwebjs.dev/Message.html
* @private
* @param {*} number
* @param {*} message
* @returns
*/
sendText = async (number, message) => {
return this.vendor.sendMessage(number, message)
}
/**
*
* @param {*} userId
* @param {*} message
* @param {*} param2
* @returns
*/
sendMessage = async (userId, message, { options }) => {
const number = cleanNumber(userId)
if (options?.media) return this.sendMedia(number, options.media)
if (options?.buttons?.length)
return this.sendButtons(number, message, options.buttons)
return this.sendText(number, message)
}
}
module.exports = WebWhatsappProvider

View File

@@ -11,6 +11,7 @@ const copyLibPkg = async (pkgName, to) => {
}
Promise.all([
copyLibPkg('create-bot-whatsapp', appDir),
copyLibPkg('bot', appDir),
copyLibPkg('database', appDir),
copyLibPkg('provider', appDir),

View File

@@ -5,11 +5,6 @@ const {
addKeyword,
} = require('@bot-whatsapp/bot')
/**
* ATENCION: Si vas a usar el provider whatsapp-web.js
* recuerda ejecutar npm i whatsapp-web.js@latest
*/
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
const MockAdapter = require('@bot-whatsapp/database/mock')

View File

@@ -6,11 +6,6 @@ const {
addChild,
} = require('@bot-whatsapp/bot')
/**
* ATENCION: Si vas a usar el provider whatsapp-web.js
* recuerda ejecutar npm i whatsapp-web.js@latest
*/
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
const MockAdapter = require('@bot-whatsapp/database/mock')

579
yarn.lock
View File

@@ -1257,16 +1257,16 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/android-arm@npm:0.15.16":
version: 0.15.16
resolution: "@esbuild/android-arm@npm:0.15.16"
"@esbuild/android-arm@npm:0.15.18":
version: 0.15.18
resolution: "@esbuild/android-arm@npm:0.15.18"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
"@esbuild/linux-loong64@npm:0.15.16":
version: 0.15.16
resolution: "@esbuild/linux-loong64@npm:0.15.16"
"@esbuild/linux-loong64@npm:0.15.18":
version: 0.15.18
resolution: "@esbuild/linux-loong64@npm:0.15.18"
conditions: os=linux & cpu=loong64
languageName: node
linkType: hard
@@ -2126,6 +2126,24 @@ __metadata:
languageName: node
linkType: hard
"acorn-node@npm:^1.8.2":
version: 1.8.2
resolution: "acorn-node@npm:1.8.2"
dependencies:
acorn: ^7.0.0
acorn-walk: ^7.0.0
xtend: ^4.0.2
checksum: 02e1564a1ccf8bd1fcefcd01235398af4a9effaf032c5397994ddd275590a72894cb3e26e4b82579ccdda1e48ade7486aef61e771ddae3563ca452b927f443d8
languageName: node
linkType: hard
"acorn-walk@npm:^7.0.0":
version: 7.2.0
resolution: "acorn-walk@npm:7.2.0"
checksum: 9252158a79b9d92f1bc0dd6acc0fcfb87a67339e84bcc301bb33d6078936d27e35d606b4d35626d2962cd43c256d6f27717e70cbe15c04fff999ab0b2260b21f
languageName: node
linkType: hard
"acorn-walk@npm:^8.1.1":
version: 8.2.0
resolution: "acorn-walk@npm:8.2.0"
@@ -2133,6 +2151,15 @@ __metadata:
languageName: node
linkType: hard
"acorn@npm:^7.0.0":
version: 7.4.1
resolution: "acorn@npm:7.4.1"
bin:
acorn: bin/acorn
checksum: 1860f23c2107c910c6177b7b7be71be350db9e1080d814493fae143ae37605189504152d1ba8743ba3178d0b37269ce1ffc42b101547fdc1827078f82671e407
languageName: node
linkType: hard
"acorn@npm:^8.0.0, acorn@npm:^8.4.1, acorn@npm:^8.8.0":
version: 8.8.1
resolution: "acorn@npm:8.8.1"
@@ -2278,6 +2305,13 @@ __metadata:
languageName: node
linkType: hard
"arg@npm:^5.0.2":
version: 5.0.2
resolution: "arg@npm:5.0.2"
checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078
languageName: node
linkType: hard
"argparse@npm:^2.0.1":
version: 2.0.1
resolution: "argparse@npm:2.0.1"
@@ -2329,6 +2363,24 @@ __metadata:
languageName: node
linkType: hard
"autoprefixer@npm:10.4.11":
version: 10.4.11
resolution: "autoprefixer@npm:10.4.11"
dependencies:
browserslist: ^4.21.3
caniuse-lite: ^1.0.30001399
fraction.js: ^4.2.0
normalize-range: ^0.1.2
picocolors: ^1.0.0
postcss-value-parser: ^4.2.0
peerDependencies:
postcss: ^8.1.0
bin:
autoprefixer: bin/autoprefixer
checksum: fb8b2abbb0ce5e3c6bc957ffb714b84aa2e6a9f24cf9c139bcfec33ba5e3334f61a132c606a621e04097d026c1f653fe1bda2d1c3dc47b87c9f6b00d90732daa
languageName: node
linkType: hard
"bail@npm:^2.0.0":
version: 2.0.2
resolution: "bail@npm:2.0.2"
@@ -2374,10 +2426,13 @@ __metadata:
"@types/node": latest
"@typescript-eslint/eslint-plugin": 5.43.0
"@typescript-eslint/parser": 5.43.0
autoprefixer: 10.4.11
eslint: 8.28.0
eslint-plugin-qwik: 0.14.1
node-fetch: 3.3.0
postcss: ^8.4.16
prettier: 2.7.1
tailwindcss: ^3.1.8
typescript: 4.9.3
vite: 3.2.4
vite-tsconfig-paths: 3.5.0
@@ -2436,6 +2491,20 @@ __metadata:
languageName: node
linkType: hard
"browserslist@npm:^4.21.3":
version: 4.21.4
resolution: "browserslist@npm:4.21.4"
dependencies:
caniuse-lite: ^1.0.30001400
electron-to-chromium: ^1.4.251
node-releases: ^2.0.6
update-browserslist-db: ^1.0.9
bin:
browserslist: cli.js
checksum: 4af3793704dbb4615bcd29059ab472344dc7961c8680aa6c4bb84f05340e14038d06a5aead58724eae69455b8fade8b8c69f1638016e87e5578969d74c078b79
languageName: node
linkType: hard
"bson@npm:^4.7.0":
version: 4.7.0
resolution: "bson@npm:4.7.0"
@@ -2542,6 +2611,13 @@ __metadata:
languageName: node
linkType: hard
"camelcase-css@npm:^2.0.1":
version: 2.0.1
resolution: "camelcase-css@npm:2.0.1"
checksum: 1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1
languageName: node
linkType: hard
"camelcase-keys@npm:^6.2.2":
version: 6.2.2
resolution: "camelcase-keys@npm:6.2.2"
@@ -2560,6 +2636,13 @@ __metadata:
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001399, caniuse-lite@npm:^1.0.30001400":
version: 1.0.30001436
resolution: "caniuse-lite@npm:1.0.30001436"
checksum: 7928ac7d93741a81b3005ca4623b133e7d790828be70b26ee55e4860facc59bc344f4092e20034981070a4714f70814c8be4929be4b22728031784f267f69099
languageName: node
linkType: hard
"ccount@npm:^2.0.0":
version: 2.0.1
resolution: "ccount@npm:2.0.1"
@@ -2713,7 +2796,7 @@ __metadata:
languageName: node
linkType: hard
"color-name@npm:~1.1.4":
"color-name@npm:^1.1.4, color-name@npm:~1.1.4":
version: 1.1.4
resolution: "color-name@npm:1.1.4"
checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610
@@ -3053,6 +3136,16 @@ __metadata:
languageName: node
linkType: hard
"create-bot-whatsapp@workspace:packages/create-bot-whatsapp":
version: 0.0.0-use.local
resolution: "create-bot-whatsapp@workspace:packages/create-bot-whatsapp"
dependencies:
"@bot-whatsapp/cli": "*"
bin:
bot: ./lib/bin/bundle.create.cjs
languageName: unknown
linkType: soft
"create-require@npm:^1.1.0":
version: 1.1.1
resolution: "create-require@npm:1.1.1"
@@ -3090,6 +3183,15 @@ __metadata:
languageName: node
linkType: hard
"cssesc@npm:^3.0.0":
version: 3.0.0
resolution: "cssesc@npm:3.0.0"
bin:
cssesc: bin/cssesc
checksum: f8c4ababffbc5e2ddf2fa9957dda1ee4af6048e22aeda1869d0d00843223c1b13ad3f5d88b51caa46c994225eacb636b764eb807a8883e2fb6f99b4f4e8c48b2
languageName: node
linkType: hard
"dargs@npm:^7.0.0":
version: 7.0.0
resolution: "dargs@npm:7.0.0"
@@ -3163,6 +3265,13 @@ __metadata:
languageName: node
linkType: hard
"defined@npm:^1.0.0":
version: 1.0.1
resolution: "defined@npm:1.0.1"
checksum: b1a852300bdb57f297289b55eafdd0c517afaa3ec8190e78fce91b9d8d0c0369d4505ecbdacfd3d98372e664f4a267d9bd793938d4a8c76209c9d9516fbe2101
languageName: node
linkType: hard
"delegates@npm:^1.0.0":
version: 1.0.0
resolution: "delegates@npm:1.0.0"
@@ -3214,6 +3323,26 @@ __metadata:
languageName: node
linkType: hard
"detective@npm:^5.2.1":
version: 5.2.1
resolution: "detective@npm:5.2.1"
dependencies:
acorn-node: ^1.8.2
defined: ^1.0.0
minimist: ^1.2.6
bin:
detective: bin/detective.js
checksum: dc4601bbc6be850edb3c2dab7a0eaf5a6169a15ad201679c66d40ea1986df816eeaecd590047f15b0780285f3eeea13b82dca0d4c52a47e744a571e326a72dc9
languageName: node
linkType: hard
"didyoumean@npm:^1.2.2":
version: 1.2.2
resolution: "didyoumean@npm:1.2.2"
checksum: d5d98719d58b3c2fa59663c4c42ba9716f1fd01245c31d5fce31915bd3aa26e6aac149788e007358f778ebbd68a2256eb5973e8ca6f221df221ba060115acf2e
languageName: node
linkType: hard
"diff@npm:^4.0.1":
version: 4.0.2
resolution: "diff@npm:4.0.2"
@@ -3237,6 +3366,13 @@ __metadata:
languageName: node
linkType: hard
"dlv@npm:^1.1.3":
version: 1.1.3
resolution: "dlv@npm:1.1.3"
checksum: d7381bca22ed11933a1ccf376db7a94bee2c57aa61e490f680124fa2d1cd27e94eba641d9f45be57caab4f9a6579de0983466f620a2cd6230d7ec93312105ae7
languageName: node
linkType: hard
"doctrine@npm:^3.0.0":
version: 3.0.0
resolution: "doctrine@npm:3.0.0"
@@ -3279,6 +3415,13 @@ __metadata:
languageName: node
linkType: hard
"electron-to-chromium@npm:^1.4.251":
version: 1.4.284
resolution: "electron-to-chromium@npm:1.4.284"
checksum: be496e9dca6509dbdbb54dc32146fc99f8eb716d28a7ee8ccd3eba0066561df36fc51418d8bd7cf5a5891810bf56c0def3418e74248f51ea4a843d423603d10a
languageName: node
linkType: hard
"emoji-regex@npm:^8.0.0":
version: 8.0.0
resolution: "emoji-regex@npm:8.0.0"
@@ -3334,9 +3477,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-android-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-android-64@npm:0.15.16"
"esbuild-android-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-android-64@npm:0.15.18"
conditions: os=android & cpu=x64
languageName: node
linkType: hard
@@ -3348,9 +3491,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-android-arm64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-android-arm64@npm:0.15.16"
"esbuild-android-arm64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-android-arm64@npm:0.15.18"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
@@ -3362,9 +3505,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-darwin-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-darwin-64@npm:0.15.16"
"esbuild-darwin-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-darwin-64@npm:0.15.18"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
@@ -3376,9 +3519,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-darwin-arm64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-darwin-arm64@npm:0.15.16"
"esbuild-darwin-arm64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-darwin-arm64@npm:0.15.18"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
@@ -3390,9 +3533,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-freebsd-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-freebsd-64@npm:0.15.16"
"esbuild-freebsd-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-freebsd-64@npm:0.15.18"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
@@ -3404,9 +3547,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-freebsd-arm64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-freebsd-arm64@npm:0.15.16"
"esbuild-freebsd-arm64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-freebsd-arm64@npm:0.15.18"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
@@ -3418,9 +3561,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-32@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-32@npm:0.15.16"
"esbuild-linux-32@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-32@npm:0.15.18"
conditions: os=linux & cpu=ia32
languageName: node
linkType: hard
@@ -3432,9 +3575,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-64@npm:0.15.16"
"esbuild-linux-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-64@npm:0.15.18"
conditions: os=linux & cpu=x64
languageName: node
linkType: hard
@@ -3446,9 +3589,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-arm64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-arm64@npm:0.15.16"
"esbuild-linux-arm64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-arm64@npm:0.15.18"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
@@ -3460,9 +3603,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-arm@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-arm@npm:0.15.16"
"esbuild-linux-arm@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-arm@npm:0.15.18"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
@@ -3474,9 +3617,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-mips64le@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-mips64le@npm:0.15.16"
"esbuild-linux-mips64le@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-mips64le@npm:0.15.18"
conditions: os=linux & cpu=mips64el
languageName: node
linkType: hard
@@ -3488,9 +3631,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-ppc64le@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-ppc64le@npm:0.15.16"
"esbuild-linux-ppc64le@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-ppc64le@npm:0.15.18"
conditions: os=linux & cpu=ppc64
languageName: node
linkType: hard
@@ -3502,9 +3645,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-riscv64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-riscv64@npm:0.15.16"
"esbuild-linux-riscv64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-riscv64@npm:0.15.18"
conditions: os=linux & cpu=riscv64
languageName: node
linkType: hard
@@ -3516,9 +3659,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-linux-s390x@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-linux-s390x@npm:0.15.16"
"esbuild-linux-s390x@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-linux-s390x@npm:0.15.18"
conditions: os=linux & cpu=s390x
languageName: node
linkType: hard
@@ -3530,9 +3673,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-netbsd-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-netbsd-64@npm:0.15.16"
"esbuild-netbsd-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-netbsd-64@npm:0.15.18"
conditions: os=netbsd & cpu=x64
languageName: node
linkType: hard
@@ -3544,9 +3687,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-openbsd-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-openbsd-64@npm:0.15.16"
"esbuild-openbsd-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-openbsd-64@npm:0.15.18"
conditions: os=openbsd & cpu=x64
languageName: node
linkType: hard
@@ -3558,9 +3701,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-sunos-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-sunos-64@npm:0.15.16"
"esbuild-sunos-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-sunos-64@npm:0.15.18"
conditions: os=sunos & cpu=x64
languageName: node
linkType: hard
@@ -3572,9 +3715,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-windows-32@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-windows-32@npm:0.15.16"
"esbuild-windows-32@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-windows-32@npm:0.15.18"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
@@ -3586,9 +3729,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-windows-64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-windows-64@npm:0.15.16"
"esbuild-windows-64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-windows-64@npm:0.15.18"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
@@ -3600,9 +3743,9 @@ __metadata:
languageName: node
linkType: hard
"esbuild-windows-arm64@npm:0.15.16":
version: 0.15.16
resolution: "esbuild-windows-arm64@npm:0.15.16"
"esbuild-windows-arm64@npm:0.15.18":
version: 0.15.18
resolution: "esbuild-windows-arm64@npm:0.15.18"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
@@ -3679,31 +3822,31 @@ __metadata:
linkType: hard
"esbuild@npm:^0.15.9":
version: 0.15.16
resolution: "esbuild@npm:0.15.16"
version: 0.15.18
resolution: "esbuild@npm:0.15.18"
dependencies:
"@esbuild/android-arm": 0.15.16
"@esbuild/linux-loong64": 0.15.16
esbuild-android-64: 0.15.16
esbuild-android-arm64: 0.15.16
esbuild-darwin-64: 0.15.16
esbuild-darwin-arm64: 0.15.16
esbuild-freebsd-64: 0.15.16
esbuild-freebsd-arm64: 0.15.16
esbuild-linux-32: 0.15.16
esbuild-linux-64: 0.15.16
esbuild-linux-arm: 0.15.16
esbuild-linux-arm64: 0.15.16
esbuild-linux-mips64le: 0.15.16
esbuild-linux-ppc64le: 0.15.16
esbuild-linux-riscv64: 0.15.16
esbuild-linux-s390x: 0.15.16
esbuild-netbsd-64: 0.15.16
esbuild-openbsd-64: 0.15.16
esbuild-sunos-64: 0.15.16
esbuild-windows-32: 0.15.16
esbuild-windows-64: 0.15.16
esbuild-windows-arm64: 0.15.16
"@esbuild/android-arm": 0.15.18
"@esbuild/linux-loong64": 0.15.18
esbuild-android-64: 0.15.18
esbuild-android-arm64: 0.15.18
esbuild-darwin-64: 0.15.18
esbuild-darwin-arm64: 0.15.18
esbuild-freebsd-64: 0.15.18
esbuild-freebsd-arm64: 0.15.18
esbuild-linux-32: 0.15.18
esbuild-linux-64: 0.15.18
esbuild-linux-arm: 0.15.18
esbuild-linux-arm64: 0.15.18
esbuild-linux-mips64le: 0.15.18
esbuild-linux-ppc64le: 0.15.18
esbuild-linux-riscv64: 0.15.18
esbuild-linux-s390x: 0.15.18
esbuild-netbsd-64: 0.15.18
esbuild-openbsd-64: 0.15.18
esbuild-sunos-64: 0.15.18
esbuild-windows-32: 0.15.18
esbuild-windows-64: 0.15.18
esbuild-windows-arm64: 0.15.18
dependenciesMeta:
"@esbuild/android-arm":
optional: true
@@ -3751,7 +3894,7 @@ __metadata:
optional: true
bin:
esbuild: bin/esbuild
checksum: 6f9262784b115363290cc9aa54692b3b646cd0508364333a609cc7be5ede4d93f91561ae8da48125e077da2e7add5368105486233ac2258f7169b171e8d78564
checksum: ec12682b2cb2d4f0669d0e555028b87a9284ca7f6a1b26e35e69a8697165b35cc682ad598abc70f0bbcfdc12ca84ef888caf5ceee389237862e8f8c17da85f89
languageName: node
linkType: hard
@@ -3841,7 +3984,7 @@ __metadata:
languageName: node
linkType: hard
"eslint@npm:8.28.0, eslint@npm:^8.26.0":
"eslint@npm:8.28.0":
version: 8.28.0
resolution: "eslint@npm:8.28.0"
dependencies:
@@ -3890,6 +4033,55 @@ __metadata:
languageName: node
linkType: hard
"eslint@npm:^8.26.0":
version: 8.29.0
resolution: "eslint@npm:8.29.0"
dependencies:
"@eslint/eslintrc": ^1.3.3
"@humanwhocodes/config-array": ^0.11.6
"@humanwhocodes/module-importer": ^1.0.1
"@nodelib/fs.walk": ^1.2.8
ajv: ^6.10.0
chalk: ^4.0.0
cross-spawn: ^7.0.2
debug: ^4.3.2
doctrine: ^3.0.0
escape-string-regexp: ^4.0.0
eslint-scope: ^7.1.1
eslint-utils: ^3.0.0
eslint-visitor-keys: ^3.3.0
espree: ^9.4.0
esquery: ^1.4.0
esutils: ^2.0.2
fast-deep-equal: ^3.1.3
file-entry-cache: ^6.0.1
find-up: ^5.0.0
glob-parent: ^6.0.2
globals: ^13.15.0
grapheme-splitter: ^1.0.4
ignore: ^5.2.0
import-fresh: ^3.0.0
imurmurhash: ^0.1.4
is-glob: ^4.0.0
is-path-inside: ^3.0.3
js-sdsl: ^4.1.4
js-yaml: ^4.1.0
json-stable-stringify-without-jsonify: ^1.0.1
levn: ^0.4.1
lodash.merge: ^4.6.2
minimatch: ^3.1.2
natural-compare: ^1.4.0
optionator: ^0.9.1
regexpp: ^3.2.0
strip-ansi: ^6.0.1
strip-json-comments: ^3.1.0
text-table: ^0.2.0
bin:
eslint: bin/eslint.js
checksum: e05204b05907b82d910983995cb946e0ba62ca514eb2b6791c43f623333b143564a2eee0139909d31c10935c21877d815b1f76dd674a59cb91c471064325c4ab
languageName: node
linkType: hard
"espree@npm:^9.4.0":
version: 9.4.1
resolution: "espree@npm:9.4.1"
@@ -4074,7 +4266,7 @@ __metadata:
languageName: node
linkType: hard
"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9":
"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.9":
version: 3.2.12
resolution: "fast-glob@npm:3.2.12"
dependencies:
@@ -4113,11 +4305,11 @@ __metadata:
linkType: hard
"fastq@npm:^1.6.0":
version: 1.13.0
resolution: "fastq@npm:1.13.0"
version: 1.14.0
resolution: "fastq@npm:1.14.0"
dependencies:
reusify: ^1.0.4
checksum: 32cf15c29afe622af187d12fc9cd93e160a0cb7c31a3bb6ace86b7dea3b28e7b72acde89c882663f307b2184e14782c6c664fa315973c03626c7d4bff070bb0b
checksum: da2c05ec1446ef77b8ba2b76619c90d483404f5087e71e77469fbee797280a1f4ef26a63be15b2377198bc20d09fdf25c7d6e1e492a1e568a29dfdd9bcb7538c
languageName: node
linkType: hard
@@ -4232,6 +4424,13 @@ __metadata:
languageName: node
linkType: hard
"fraction.js@npm:^4.2.0":
version: 4.2.0
resolution: "fraction.js@npm:4.2.0"
checksum: 8c76a6e21dedea87109d6171a0ac77afa14205794a565d71cb10d2925f629a3922da61bf45ea52dbc30bce4d8636dc0a27213a88cbd600eab047d82f9a3a94c5
languageName: node
linkType: hard
"fs-extra@npm:^10.0.0":
version: 10.1.0
resolution: "fs-extra@npm:10.1.0"
@@ -5225,6 +5424,13 @@ __metadata:
languageName: node
linkType: hard
"lilconfig@npm:^2.0.5, lilconfig@npm:^2.0.6":
version: 2.0.6
resolution: "lilconfig@npm:2.0.6"
checksum: 40a3cd72f103b1be5975f2ac1850810b61d4053e20ab09be8d3aeddfe042187e1ba70b4651a7e70f95efa1642e7dc8b2ae395b317b7d7753b241b43cef7c0f7d
languageName: node
linkType: hard
"lines-and-columns@npm:^1.1.6":
version: 1.2.4
resolution: "lines-and-columns@npm:1.2.4"
@@ -5991,7 +6197,7 @@ __metadata:
languageName: node
linkType: hard
"micromatch@npm:^4.0.4":
"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
version: 4.0.5
resolution: "micromatch@npm:4.0.5"
dependencies:
@@ -6384,6 +6590,13 @@ __metadata:
languageName: node
linkType: hard
"node-releases@npm:^2.0.6":
version: 2.0.6
resolution: "node-releases@npm:2.0.6"
checksum: e86a926dc9fbb3b41b4c4a89d998afdf140e20a4e8dbe6c0a807f7b2948b42ea97d7fd3ad4868041487b6e9ee98409829c6e4d84a734a4215dff060a7fbeb4bf
languageName: node
linkType: hard
"nopt@npm:^6.0.0":
version: 6.0.0
resolution: "nopt@npm:6.0.0"
@@ -6426,6 +6639,13 @@ __metadata:
languageName: node
linkType: hard
"normalize-range@npm:^0.1.2":
version: 0.1.2
resolution: "normalize-range@npm:0.1.2"
checksum: 9b2f14f093593f367a7a0834267c24f3cb3e887a2d9809c77d8a7e5fd08738bcd15af46f0ab01cc3a3d660386f015816b5c922cea8bf2ee79777f40874063184
languageName: node
linkType: hard
"npm-run-path@npm:^4.0.0, npm-run-path@npm:^4.0.1":
version: 4.0.1
resolution: "npm-run-path@npm:4.0.1"
@@ -6475,6 +6695,13 @@ __metadata:
languageName: node
linkType: hard
"object-hash@npm:^3.0.0":
version: 3.0.0
resolution: "object-hash@npm:3.0.0"
checksum: 80b4904bb3857c52cc1bfd0b52c0352532ca12ed3b8a6ff06a90cd209dfda1b95cee059a7625eb9da29537027f68ac4619363491eedb2f5d3dddbba97494fd6c
languageName: node
linkType: hard
"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
version: 1.4.0
resolution: "once@npm:1.4.0"
@@ -6785,7 +7012,77 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:^8.4.18":
"postcss-import@npm:^14.1.0":
version: 14.1.0
resolution: "postcss-import@npm:14.1.0"
dependencies:
postcss-value-parser: ^4.0.0
read-cache: ^1.0.0
resolve: ^1.1.7
peerDependencies:
postcss: ^8.0.0
checksum: cd45d406e90f67cdab9524352e573cc6b4462b790934a05954e929a6653ebd31288ceebc8ce3c3ed7117ae672d9ebbec57df0bceec0a56e9b259c2e71d47ca86
languageName: node
linkType: hard
"postcss-js@npm:^4.0.0":
version: 4.0.0
resolution: "postcss-js@npm:4.0.0"
dependencies:
camelcase-css: ^2.0.1
peerDependencies:
postcss: ^8.3.3
checksum: 14be8a58670b4c5d037d40f179240a4f736d53530db727e2635638fa296bc4bff18149ca860928398aace422e55d07c9f5729eeccd395340944985199cdc82a5
languageName: node
linkType: hard
"postcss-load-config@npm:^3.1.4":
version: 3.1.4
resolution: "postcss-load-config@npm:3.1.4"
dependencies:
lilconfig: ^2.0.5
yaml: ^1.10.2
peerDependencies:
postcss: ">=8.0.9"
ts-node: ">=9.0.0"
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
checksum: 1c589504c2d90b1568aecae8238ab993c17dba2c44f848a8f13619ba556d26a1c09644d5e6361b5784e721e94af37b604992f9f3dc0483e687a0cc1cc5029a34
languageName: node
linkType: hard
"postcss-nested@npm:6.0.0":
version: 6.0.0
resolution: "postcss-nested@npm:6.0.0"
dependencies:
postcss-selector-parser: ^6.0.10
peerDependencies:
postcss: ^8.2.14
checksum: 2105dc52cd19747058f1a46862c9e454b5a365ac2e7135fc1015d67a8fe98ada2a8d9ee578e90f7a093bd55d3994dd913ba5ff1d5e945b4ed9a8a2992ecc8f10
languageName: node
linkType: hard
"postcss-selector-parser@npm:^6.0.10":
version: 6.0.11
resolution: "postcss-selector-parser@npm:6.0.11"
dependencies:
cssesc: ^3.0.0
util-deprecate: ^1.0.2
checksum: 0b01aa9c2d2c8dbeb51e9b204796b678284be9823abc8d6d40a8b16d4149514e922c264a8ed4deb4d6dbced564b9be390f5942c058582d8656351516d6c49cde
languageName: node
linkType: hard
"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.2.0":
version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0"
checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f
languageName: node
linkType: hard
"postcss@npm:^8.4.16, postcss@npm:^8.4.18":
version: 8.4.19
resolution: "postcss@npm:8.4.19"
dependencies:
@@ -6932,6 +7229,22 @@ __metadata:
languageName: node
linkType: hard
"quick-lru@npm:^5.1.1":
version: 5.1.1
resolution: "quick-lru@npm:5.1.1"
checksum: a516faa25574be7947969883e6068dbe4aa19e8ef8e8e0fd96cddd6d36485e9106d85c0041a27153286b0770b381328f4072aa40d3b18a19f5f7d2b78b94b5ed
languageName: node
linkType: hard
"read-cache@npm:^1.0.0":
version: 1.0.0
resolution: "read-cache@npm:1.0.0"
dependencies:
pify: ^2.3.0
checksum: cffc728b9ede1e0667399903f9ecaf3789888b041c46ca53382fa3a06303e5132774dc0a96d0c16aa702dbac1ea0833d5a868d414f5ab2af1e1438e19e6657c6
languageName: node
linkType: hard
"read-pkg-up@npm:^3.0.0":
version: 3.0.0
resolution: "read-pkg-up@npm:3.0.0"
@@ -7111,7 +7424,7 @@ __metadata:
languageName: node
linkType: hard
"resolve@npm:^1.10.0, resolve@npm:^1.22.1":
"resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.22.1":
version: 1.22.1
resolution: "resolve@npm:1.22.1"
dependencies:
@@ -7124,7 +7437,7 @@ __metadata:
languageName: node
linkType: hard
"resolve@patch:resolve@^1.10.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.1#~builtin<compat/resolve>":
"resolve@patch:resolve@^1.1.7#~builtin<compat/resolve>, resolve@patch:resolve@^1.10.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.1#~builtin<compat/resolve>":
version: 1.22.1
resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin<compat/resolve>::version=1.22.1&hash=c3c19d"
dependencies:
@@ -7231,8 +7544,8 @@ __metadata:
linkType: hard
"rollup@npm:^3.2.3":
version: 3.5.1
resolution: "rollup@npm:3.5.1"
version: 3.6.0
resolution: "rollup@npm:3.6.0"
dependencies:
fsevents: ~2.3.2
dependenciesMeta:
@@ -7240,7 +7553,7 @@ __metadata:
optional: true
bin:
rollup: dist/bin/rollup
checksum: 9206af1fca3c05a519adf6cd81fa9c86d3262370256c2480b480e11f19dda212aac388d1893da6193d660071c54e57ae5981f54e0e52fe27e45245b991fbf6d3
checksum: 9aefeddf54623cefdbf9d3f75ac4c3e68f08a4e7f0685ac70c49acbc7963307eb80492c519c76010e15af429d40086ab3b3301add09cb8da892bdf89c605cd52
languageName: node
linkType: hard
@@ -7751,6 +8064,42 @@ __metadata:
languageName: node
linkType: hard
"tailwindcss@npm:^3.1.8":
version: 3.2.4
resolution: "tailwindcss@npm:3.2.4"
dependencies:
arg: ^5.0.2
chokidar: ^3.5.3
color-name: ^1.1.4
detective: ^5.2.1
didyoumean: ^1.2.2
dlv: ^1.1.3
fast-glob: ^3.2.12
glob-parent: ^6.0.2
is-glob: ^4.0.3
lilconfig: ^2.0.6
micromatch: ^4.0.5
normalize-path: ^3.0.0
object-hash: ^3.0.0
picocolors: ^1.0.0
postcss: ^8.4.18
postcss-import: ^14.1.0
postcss-js: ^4.0.0
postcss-load-config: ^3.1.4
postcss-nested: 6.0.0
postcss-selector-parser: ^6.0.10
postcss-value-parser: ^4.2.0
quick-lru: ^5.1.1
resolve: ^1.22.1
peerDependencies:
postcss: ^8.0.9
bin:
tailwind: lib/cli.js
tailwindcss: lib/cli.js
checksum: ec187d180c722ec4f57537f2216c7b21269b525f12aaf353cea464d939c3e6286a1221eb3e1206e45d1f015f296171309ad4d9952899b0245cd07d9500a9401f
languageName: node
linkType: hard
"tar@npm:^6.1.11, tar@npm:^6.1.2":
version: 6.1.12
resolution: "tar@npm:6.1.12"
@@ -8169,6 +8518,20 @@ __metadata:
languageName: node
linkType: hard
"update-browserslist-db@npm:^1.0.9":
version: 1.0.10
resolution: "update-browserslist-db@npm:1.0.10"
dependencies:
escalade: ^3.1.1
picocolors: ^1.0.0
peerDependencies:
browserslist: ">= 4.21.0"
bin:
browserslist-lint: cli.js
checksum: 12db73b4f63029ac407b153732e7cd69a1ea8206c9100b482b7d12859cd3cd0bc59c602d7ae31e652706189f1acb90d42c53ab24a5ba563ed13aebdddc5561a0
languageName: node
linkType: hard
"uri-js@npm:^4.2.2":
version: 4.4.1
resolution: "uri-js@npm:4.4.1"
@@ -8185,7 +8548,7 @@ __metadata:
languageName: node
linkType: hard
"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1":
"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1":
version: 1.0.2
resolution: "util-deprecate@npm:1.0.2"
checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
@@ -8410,7 +8773,7 @@ __metadata:
languageName: node
linkType: hard
"wrangler@npm:latest":
wrangler@latest:
version: 2.5.0
resolution: "wrangler@npm:2.5.0"
dependencies:
@@ -8473,7 +8836,7 @@ __metadata:
languageName: node
linkType: hard
"xtend@npm:~4.0.1":
"xtend@npm:^4.0.2, xtend@npm:~4.0.1":
version: 4.0.2
resolution: "xtend@npm:4.0.2"
checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a
@@ -8508,7 +8871,7 @@ __metadata:
languageName: node
linkType: hard
"yaml@npm:^1.10.0":
"yaml@npm:^1.10.0, yaml@npm:^1.10.2":
version: 1.10.2
resolution: "yaml@npm:1.10.2"
checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f