Add Mattermost bot for stand-up
parent
81a5c737d0
commit
b9db70f590
1
Procfile
1
Procfile
|
@ -1 +1,2 @@
|
|||
web: node -v ; yarn -v ; echo "$PORT" ; yarn workspace api run start:prod
|
||||
bot: node -v ; yarn -v ; echo "$PORT" ; yarn workspace standup-mattermost-bot run start:prod
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
"modele-social",
|
||||
"exoneration-covid",
|
||||
"api",
|
||||
"site"
|
||||
"site",
|
||||
"standup-mattermost-bot"
|
||||
],
|
||||
"scripts": {
|
||||
"scalingo-postbuild": "CI=true ; yarn test:type && yarn workspaces focus api && yarn workspace api run build && yarn workspaces focus --all && yarn test && yarn workspaces focus api --production",
|
||||
"scalingo-postbuild": "CI=true ; yarn test:type && yarn build:api && yarn build:standup-mattermost-bot && yarn workspaces focus --all && yarn test && yarn workspaces focus standup-mattermost-bot api --production",
|
||||
"build:api": "yarn workspaces focus api && yarn workspace api run build",
|
||||
"build:standup-mattermost-bot": "yarn workspaces focus standup-mattermost-bot && yarn workspace standup-mattermost-bot run build",
|
||||
"lint:eslintrc": "npx eslint-config-prettier .eslintrc.cjs",
|
||||
"lint:eslint": "NODE_OPTIONS='--max-old-space-size=4096' eslint .",
|
||||
"lint:eslint:fix": "yarn lint:eslint --fix",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
MONGO_URL=mongodb://root:example@localhost:27017/
|
|
@ -0,0 +1,12 @@
|
|||
# Bot Mattermost pour stand-up asynchrone
|
||||
|
||||
Ce bot envoie une notification périodique sur un canal Mattermost dédié afin que chaque membre de l'équipe puisse écrire en réponse où il en est dans ses tâches.
|
||||
|
||||
Il désigne également qui sera l'animateur pour chaque jour de la semaine à venir.
|
||||
|
||||
Et peut-être plus à venir...
|
||||
|
||||
# Détail technique
|
||||
|
||||
Le bot peut être installé facilement sur Scalingo, vous pouvez aller dans le `Procfile` à la racine du projet.
|
||||
Il nécessite une base de données Mongodb pour stocker les token d'authentification et la liste des animateurs de la semaine.
|
|
@ -0,0 +1,21 @@
|
|||
version: '3.7'
|
||||
|
||||
services:
|
||||
mongo:
|
||||
image: mongo
|
||||
restart: always
|
||||
ports:
|
||||
- 27017:27017
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
MONGO_INITDB_ROOT_PASSWORD: example
|
||||
|
||||
mongo-express:
|
||||
image: mongo-express
|
||||
restart: always
|
||||
ports:
|
||||
- 8081:8081
|
||||
environment:
|
||||
ME_CONFIG_MONGODB_ADMINUSERNAME: root
|
||||
ME_CONFIG_MONGODB_ADMINPASSWORD: example
|
||||
ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "standup-mattermost-bot",
|
||||
"license": "MIT",
|
||||
"version": "2.0.0",
|
||||
"description": "Code source du standup-mattermost-bot",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/betagouv/mon-entreprise.git",
|
||||
"directory": "standup-mattermost-bot"
|
||||
},
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "^16"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "yarn tsc",
|
||||
"start": "nodemon -e \"js,ts\" -x 'NODE_OPTIONS=\"--loader ts-node/esm\" node ./source/index.ts'",
|
||||
"start:prod": "NODE_ENV=production nodemon -d 500ms -w ./dist/index.js -x 'node ./dist/index.js || touch ./dist/index.js'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@breejs/later": "^4.1.0",
|
||||
"@koa/cors": "^3.4.1",
|
||||
"@koa/router": "^12.0.0",
|
||||
"bree": "^9.1.2",
|
||||
"dotenv": "^16.0.3",
|
||||
"got": "^12.5.1",
|
||||
"koa": "^2.13.4",
|
||||
"mongodb": "^4.10.0",
|
||||
"nodemon": "^2.0.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/koa": "^2.13.5",
|
||||
"@types/koa__cors": "^3.3.0",
|
||||
"@types/koa__router": "^12.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import type { MattermostSendMessage } from './mattermost.js'
|
||||
|
||||
export const PORT = process.env.PORT || 4000
|
||||
export const ORIGIN = process.env.ORIGIN || 'http://localhost:4000'
|
||||
export const MONGO_URL = process.env.MONGO_URL
|
||||
export const NODE_ENV = process.env.NODE_ENV
|
||||
|
||||
export const serverUrl = 'https://mattermost.incubateur.net'
|
||||
export const clientSecret = 'pgnch7w643yfdkdjnnjcxhpsoe'
|
||||
export const clientId = 'wbkot91tjbd6byn4fbmrtu8h6o'
|
||||
export const redirectUri = `${ORIGIN}/oauth`
|
||||
|
||||
const days = [
|
||||
'Lundi',
|
||||
'Mardi',
|
||||
'Mercredi',
|
||||
'Jeudi',
|
||||
'Vendredi',
|
||||
'Samedi',
|
||||
'Dimanche',
|
||||
]
|
||||
|
||||
interface BotConfig {
|
||||
channelName: string
|
||||
standupDays: string[]
|
||||
messageProps: MattermostSendMessage['props']
|
||||
}
|
||||
|
||||
export const botConfig: BotConfig = {
|
||||
channelName:
|
||||
NODE_ENV !== 'production'
|
||||
? 'startup-monentreprise-dev-bot-stand-up'
|
||||
: 'startup-monentreprise-stand-up',
|
||||
standupDays: days.slice(0, 4),
|
||||
messageProps: {
|
||||
from_webhook: 'true',
|
||||
override_username: 'L’URSSAF est votre amie',
|
||||
override_icon_url:
|
||||
'https://mon-entreprise.urssaf.fr/favicon/favicon-32x32.png?v=2.0',
|
||||
},
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
import './server.js'
|
||||
import './jobs.js'
|
|
@ -0,0 +1,41 @@
|
|||
import later from '@breejs/later'
|
||||
import Bree, { BreeOptions } from 'bree'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { NODE_ENV } from './config.js'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const jobs: BreeOptions['jobs'] = [
|
||||
{
|
||||
name: 'refresh-token',
|
||||
interval: 'at 2:00',
|
||||
},
|
||||
{
|
||||
name: 'daily-stand-up',
|
||||
interval: 'every weekday at 16:42',
|
||||
},
|
||||
{
|
||||
name: 'weekly-randomizer',
|
||||
interval: 'on Thursday at 17:42',
|
||||
},
|
||||
]
|
||||
|
||||
const badJob = jobs.findIndex(
|
||||
(job) =>
|
||||
typeof job === 'object' &&
|
||||
'interval' in job &&
|
||||
// eslint-disable-next-line
|
||||
later.parse.text(job.interval).error >= 0
|
||||
)
|
||||
if (badJob >= 0) {
|
||||
throw new Error(`Bad interval in job n°${badJob}`)
|
||||
}
|
||||
|
||||
const bree = new Bree({
|
||||
root: join(__dirname, 'jobs'),
|
||||
defaultExtension: NODE_ENV === 'production' ? 'js' : 'ts',
|
||||
jobs,
|
||||
})
|
||||
|
||||
await bree.start()
|
|
@ -0,0 +1,50 @@
|
|||
import { botConfig, serverUrl } from '../config.js'
|
||||
import { getUserChannels, sendMessage } from '../mattermost.js'
|
||||
import { initMongodb } from '../mongodb.js'
|
||||
|
||||
const mongo = await initMongodb()
|
||||
|
||||
const oauth = await mongo.getOAuth()
|
||||
|
||||
if (!oauth) {
|
||||
throw new Error('No OAuth in database')
|
||||
}
|
||||
|
||||
const { accessToken } = oauth
|
||||
|
||||
const standupChannel = (
|
||||
await getUserChannels({ serverUrl, accessToken, userId: 'me' })
|
||||
).body.find(({ name }) => name === botConfig.channelName)
|
||||
|
||||
if (!standupChannel) {
|
||||
throw new Error('Standup channel not found')
|
||||
}
|
||||
|
||||
const index = new Date().getDay() - 1
|
||||
const nextDayMember = (await mongo.getWeeklyTeamOrder())?.memberIds[index]
|
||||
const nextDayStandup = nextDayMember
|
||||
? `:arrow_forward: Demain, c'est ${nextDayMember} qui anime le stand-up.`
|
||||
: ''
|
||||
|
||||
const now = new Date()
|
||||
.toLocaleTimeString('fr', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
})
|
||||
.replace(':', 'h')
|
||||
|
||||
await sendMessage({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
channelId: standupChannel.id,
|
||||
message: `
|
||||
Coucou tout le monde :wave:
|
||||
Il est ${now}, l'heure des champion·ne·s, ou plutôt celle d'indiquer nos sujets pour le stand-up de demain.
|
||||
_(Rappel : Je note ici ce dont je suis fier·e, ce sur quoi je bloque, ce que je veux montrer, ce dont j'ai besoin – aide, outillage… )_
|
||||
|
||||
${nextDayStandup}
|
||||
`,
|
||||
props: botConfig.messageProps,
|
||||
})
|
||||
|
||||
await mongo.close()
|
|
@ -0,0 +1,26 @@
|
|||
import { clientId, clientSecret, redirectUri, serverUrl } from '../config.js'
|
||||
import { initMongodb } from '../mongodb.js'
|
||||
import { refreshAccessToken } from '../oauth.js'
|
||||
import { snakeToCamelCaseKeys } from '../utils.js'
|
||||
|
||||
const mongo = await initMongodb()
|
||||
|
||||
const oauth = await mongo.getOAuth()
|
||||
|
||||
if (!oauth) {
|
||||
throw new Error('No OAuth in database')
|
||||
}
|
||||
|
||||
const { refreshToken } = oauth
|
||||
|
||||
const newToken = await refreshAccessToken({
|
||||
serverUrl,
|
||||
refreshToken,
|
||||
redirectUri,
|
||||
clientId,
|
||||
clientSecret,
|
||||
})
|
||||
|
||||
await mongo.saveOAuth(snakeToCamelCaseKeys(newToken.body))
|
||||
|
||||
await mongo.close()
|
|
@ -0,0 +1,76 @@
|
|||
import { botConfig, serverUrl } from '../config.js'
|
||||
import {
|
||||
getChannelMembers,
|
||||
getUser,
|
||||
getUserChannels,
|
||||
sendMessage,
|
||||
} from '../mattermost.js'
|
||||
import { initMongodb } from '../mongodb.js'
|
||||
import { shuffleArray, snakeToCamelCaseKeys } from '../utils.js'
|
||||
|
||||
const mongo = await initMongodb()
|
||||
|
||||
const oauth = await mongo.getOAuth()
|
||||
|
||||
if (!oauth) {
|
||||
throw new Error('No OAuth in database')
|
||||
}
|
||||
|
||||
const { accessToken } = oauth
|
||||
|
||||
const standupChannel = (
|
||||
await getUserChannels({ serverUrl, accessToken, userId: 'me' })
|
||||
).body.find(({ name }) => name === botConfig.channelName)
|
||||
|
||||
if (!standupChannel) {
|
||||
throw new Error('Standup channel not found')
|
||||
}
|
||||
|
||||
const standupChannelMembers = (
|
||||
await getChannelMembers({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
channelId: standupChannel.id,
|
||||
})
|
||||
).body.map((x) => snakeToCamelCaseKeys(x))
|
||||
|
||||
const standupMembers = await Promise.all(
|
||||
standupChannelMembers.map(({ userId }) =>
|
||||
getUser({ serverUrl, accessToken, userId }).then(({ body }) =>
|
||||
snakeToCamelCaseKeys(body)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
const shuffleMembers = shuffleArray(standupMembers)
|
||||
|
||||
await mongo.setWeeklyTeamOrder(shuffleMembers.map(({ id }) => id))
|
||||
|
||||
const nextStandupOrder = botConfig.standupDays
|
||||
.map((day, i) =>
|
||||
shuffleMembers[i] ? `- ${day} : @${shuffleMembers[i].username}` : ''
|
||||
)
|
||||
.filter(<T>(x: T | null): x is T => x !== null)
|
||||
.join('\n')
|
||||
|
||||
const now = new Date()
|
||||
.toLocaleTimeString('fr', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
})
|
||||
.replace(':', 'h')
|
||||
|
||||
await sendMessage({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
channelId: standupChannel.id,
|
||||
message: `
|
||||
Il est ${now}, c'est déja la fin de semaine (ou presque pour certain :smile:) !
|
||||
|
||||
Voici l'ordre des animateurs proposé pour le stand-up de la semaine prochaine :
|
||||
${nextStandupOrder}
|
||||
`,
|
||||
props: botConfig.messageProps,
|
||||
})
|
||||
|
||||
await mongo.close()
|
|
@ -0,0 +1,179 @@
|
|||
import got from 'got'
|
||||
|
||||
interface MattermostInput {
|
||||
serverUrl: string
|
||||
accessToken: string
|
||||
}
|
||||
|
||||
interface MattermostGetUser extends MattermostInput {
|
||||
userId: string
|
||||
}
|
||||
|
||||
interface MattermostUser {
|
||||
id: string
|
||||
create_at: number
|
||||
update_at: number
|
||||
delete_at: number
|
||||
username: string
|
||||
email: string
|
||||
email_verified: boolean
|
||||
nickname: string
|
||||
first_name: string
|
||||
last_name: string
|
||||
roles: string
|
||||
}
|
||||
|
||||
export const getUser = ({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
userId,
|
||||
}: MattermostGetUser) =>
|
||||
got.get<MattermostUser>(`${serverUrl}/api/v4/users/${userId}`, {
|
||||
responseType: 'json',
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
})
|
||||
|
||||
interface MattermostGetUserChannels extends MattermostInput {
|
||||
userId: string
|
||||
}
|
||||
|
||||
interface MattermostChannel {
|
||||
id: string
|
||||
create_at: number
|
||||
update_at: number
|
||||
delete_at: number
|
||||
team_id: string
|
||||
type: string
|
||||
display_name: string
|
||||
name: string
|
||||
header: string
|
||||
purpose: string
|
||||
last_post_at: number
|
||||
total_msg_count: number
|
||||
extra_update_at: number
|
||||
creator_id: string
|
||||
total_msg_count_root: number
|
||||
last_root_post_at: number
|
||||
}
|
||||
|
||||
export const getUserChannels = ({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
userId,
|
||||
}: MattermostGetUserChannels) =>
|
||||
got.get<MattermostChannel[]>(`${serverUrl}/api/v4/users/${userId}/channels`, {
|
||||
responseType: 'json',
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
})
|
||||
|
||||
interface MattermostGetChannelMembers extends MattermostInput {
|
||||
channelId: string
|
||||
}
|
||||
|
||||
interface MattermostChannelMember {
|
||||
channel_id: string
|
||||
user_id: string
|
||||
roles: string
|
||||
last_viewed_at: number
|
||||
msg_count: number
|
||||
mention_count: number
|
||||
mention_count_root: number
|
||||
msg_count_root: number
|
||||
notify_props: unknown
|
||||
last_update_at: number
|
||||
scheme_guest: false
|
||||
scheme_user: boolean
|
||||
scheme_admin: boolean
|
||||
explicit_roles: string
|
||||
}
|
||||
|
||||
export const getChannelMembers = ({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
channelId,
|
||||
}: MattermostGetChannelMembers) =>
|
||||
got.get<MattermostChannelMember[]>(
|
||||
`${serverUrl}/api/v4/channels/${channelId}/members`,
|
||||
{
|
||||
responseType: 'json',
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
}
|
||||
)
|
||||
|
||||
interface MattermostPost {
|
||||
id: string
|
||||
create_at: number
|
||||
update_at: number
|
||||
delete_at: number
|
||||
is_pinned: false
|
||||
user_id: string
|
||||
channel_id: string
|
||||
root_id: string
|
||||
original_id: string
|
||||
message: string
|
||||
type: string
|
||||
props: unknown
|
||||
hashtags: string
|
||||
pending_post_id: string
|
||||
reply_count: number
|
||||
last_reply_at: number
|
||||
metadata: unknown
|
||||
}
|
||||
|
||||
/* get posts from a channel
|
||||
|
||||
interface MattermostGetChannelPosts extends MattermostInput {
|
||||
channelId: string
|
||||
}
|
||||
|
||||
interface MattermostChannelPost {
|
||||
order: string[]
|
||||
posts: { [id: string]: MattermostPost }
|
||||
next_post_id: string
|
||||
prev_post_id: string
|
||||
}
|
||||
|
||||
export const getChannelPosts = ({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
channelId,
|
||||
}: MattermostGetChannelPosts) =>
|
||||
got.get<MattermostChannelPost>(
|
||||
`${serverUrl}/api/v4/channels/${channelId}/posts`,
|
||||
{
|
||||
responseType: 'json',
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
}
|
||||
)
|
||||
|
||||
*/
|
||||
|
||||
export interface MattermostSendMessage extends MattermostInput {
|
||||
channelId: string
|
||||
message: string
|
||||
props?: {
|
||||
from_webhook?: 'true'
|
||||
override_icon_url?: string
|
||||
override_username?: string
|
||||
}
|
||||
rootId?: string
|
||||
}
|
||||
|
||||
export const sendMessage = ({
|
||||
serverUrl,
|
||||
accessToken,
|
||||
channelId,
|
||||
message,
|
||||
props,
|
||||
rootId,
|
||||
}: MattermostSendMessage) =>
|
||||
got.post<MattermostPost>(`${serverUrl}/api/v4/posts`, {
|
||||
json: {
|
||||
channel_id: channelId,
|
||||
message,
|
||||
props,
|
||||
root_id: rootId,
|
||||
},
|
||||
responseType: 'json',
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
})
|
|
@ -0,0 +1,53 @@
|
|||
import { MongoClient } from 'mongodb'
|
||||
import { MONGO_URL } from './config.js'
|
||||
|
||||
interface OAuthCollection {
|
||||
accessToken: string
|
||||
refreshToken: string
|
||||
}
|
||||
interface MemberIds {
|
||||
memberIds: string[]
|
||||
}
|
||||
|
||||
export const initMongodb = async () => {
|
||||
if (!MONGO_URL) {
|
||||
throw new Error('MONGO_URL env var is empty')
|
||||
}
|
||||
|
||||
const client = new MongoClient(MONGO_URL)
|
||||
await client.connect()
|
||||
|
||||
const db = client.db('bot')
|
||||
|
||||
return {
|
||||
saveOAuth: ({ accessToken, refreshToken }: OAuthCollection) => {
|
||||
const collection = db.collection<OAuthCollection>('oauth')
|
||||
|
||||
return collection.findOneAndReplace(
|
||||
{},
|
||||
{ accessToken, refreshToken },
|
||||
{ upsert: true }
|
||||
)
|
||||
},
|
||||
|
||||
getOAuth: () => {
|
||||
const collection = db.collection<OAuthCollection>('oauth')
|
||||
|
||||
return collection.findOne()
|
||||
},
|
||||
|
||||
setWeeklyTeamOrder: (memberIds: string[]) => {
|
||||
const collection = db.collection<MemberIds>('weeklyTeamOrder')
|
||||
|
||||
return collection.findOneAndReplace({}, { memberIds }, { upsert: true })
|
||||
},
|
||||
|
||||
getWeeklyTeamOrder: () => {
|
||||
const collection = db.collection<MemberIds>('weeklyTeamOrder')
|
||||
|
||||
return collection.findOne()
|
||||
},
|
||||
|
||||
close: () => client.close(),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
import got from 'got'
|
||||
|
||||
export interface OAuthResponse {
|
||||
access_token: string
|
||||
token_type: string
|
||||
expires_in: number
|
||||
scope: string
|
||||
refresh_token: string
|
||||
id_token: string
|
||||
}
|
||||
|
||||
interface OAuthParams {
|
||||
serverUrl: string
|
||||
clientSecret: string
|
||||
clientId: string
|
||||
redirectUri: string
|
||||
}
|
||||
|
||||
interface GetOAuthParams extends OAuthParams {
|
||||
code: string
|
||||
}
|
||||
|
||||
export const getAccessToken = ({
|
||||
serverUrl,
|
||||
clientSecret,
|
||||
clientId,
|
||||
redirectUri,
|
||||
code,
|
||||
}: GetOAuthParams) =>
|
||||
got.post<OAuthResponse>(`${serverUrl}/oauth/access_token`, {
|
||||
form: {
|
||||
client_secret: clientSecret,
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
grant_type: 'authorization_code',
|
||||
code,
|
||||
},
|
||||
responseType: 'json',
|
||||
throwHttpErrors: true,
|
||||
})
|
||||
|
||||
interface RefreshOAuthParams extends OAuthParams {
|
||||
serverUrl: string
|
||||
clientSecret: string
|
||||
clientId: string
|
||||
redirectUri: string
|
||||
refreshToken: string
|
||||
}
|
||||
|
||||
export const refreshAccessToken = ({
|
||||
serverUrl,
|
||||
clientSecret,
|
||||
clientId,
|
||||
redirectUri,
|
||||
refreshToken,
|
||||
}: RefreshOAuthParams) =>
|
||||
got.post<OAuthResponse>(`${serverUrl}/oauth/access_token`, {
|
||||
form: {
|
||||
client_secret: clientSecret,
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: refreshToken,
|
||||
},
|
||||
responseType: 'json',
|
||||
throwHttpErrors: true,
|
||||
})
|
|
@ -0,0 +1,81 @@
|
|||
import cors from '@koa/cors'
|
||||
import Router from '@koa/router'
|
||||
import 'dotenv/config'
|
||||
import Koa from 'koa'
|
||||
import {
|
||||
clientId,
|
||||
clientSecret,
|
||||
PORT,
|
||||
redirectUri,
|
||||
serverUrl,
|
||||
} from './config.js'
|
||||
import { initMongodb } from './mongodb.js'
|
||||
import { getAccessToken } from './oauth.js'
|
||||
import { snakeToCamelCaseKeys } from './utils.js'
|
||||
|
||||
const mongo = await initMongodb()
|
||||
|
||||
type KoaState = Koa.DefaultState
|
||||
type KoaContext = Koa.DefaultContext
|
||||
|
||||
const app = new Koa<KoaState, KoaContext>()
|
||||
const router = new Router<KoaState, KoaContext>()
|
||||
|
||||
app.use(cors())
|
||||
|
||||
router.get('/connect', (ctx) => {
|
||||
const url =
|
||||
`${serverUrl}/oauth/authorize?` +
|
||||
[
|
||||
`client_id=${clientId}`,
|
||||
`redirect_uri=${redirectUri}`,
|
||||
`response_type=code`,
|
||||
`state=`,
|
||||
].join('&')
|
||||
|
||||
ctx.redirect(url)
|
||||
})
|
||||
|
||||
router.get('/oauth', async (ctx) => {
|
||||
const { code, error } = ctx.query
|
||||
|
||||
if (error) {
|
||||
ctx.status = 400
|
||||
ctx.body = error
|
||||
|
||||
return
|
||||
}
|
||||
if (typeof code !== 'string') {
|
||||
ctx.status = 400
|
||||
ctx.body = 'Bad code'
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const { body } = await getAccessToken({
|
||||
serverUrl,
|
||||
clientSecret,
|
||||
clientId,
|
||||
redirectUri,
|
||||
code,
|
||||
})
|
||||
|
||||
await mongo.saveOAuth(snakeToCamelCaseKeys(body))
|
||||
|
||||
ctx.status = 200
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err)
|
||||
|
||||
ctx.status = 400
|
||||
}
|
||||
})
|
||||
|
||||
app.use(router.routes())
|
||||
app.use(router.allowedMethods())
|
||||
|
||||
app.listen(PORT, () => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`app listening on port ${PORT}`)
|
||||
})
|
|
@ -0,0 +1,35 @@
|
|||
type CamelCase<S extends string> =
|
||||
S extends `${infer P1}_${infer P2}${infer P3}`
|
||||
? `${Lowercase<P1>}${Uppercase<P2>}${CamelCase<P3>}`
|
||||
: Lowercase<S>
|
||||
|
||||
const snakeToCamelCase = <T extends string>(str: T) =>
|
||||
str
|
||||
.replace(/_/g, ' ')
|
||||
.replace(/(?<!\p{L})\p{L}|\s+/gu, (m) => (+m === 0 ? '' : m.toUpperCase()))
|
||||
.replace(/^./, (m) => m?.toLowerCase()) as CamelCase<T>
|
||||
|
||||
export type KeysToCamelCase<T> = {
|
||||
[K in keyof T as CamelCase<string & K>]: T[K]
|
||||
}
|
||||
|
||||
export const snakeToCamelCaseKeys = <T extends object>(object: T) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(object).map(
|
||||
([key, value]) => [snakeToCamelCase(key), value],
|
||||
{}
|
||||
)
|
||||
) as KeysToCamelCase<T>
|
||||
|
||||
export const shuffleArray = <T>(array: T[]) => {
|
||||
const shuffle = [...array]
|
||||
|
||||
for (let i = shuffle.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1))
|
||||
const [shuffleI, shuffleJ] = [shuffle[i], shuffle[j]]
|
||||
shuffle[i] = shuffleJ
|
||||
shuffle[j] = shuffleI
|
||||
}
|
||||
|
||||
return shuffle
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"incremental": true,
|
||||
"target": "ES2020",
|
||||
"module": "NodeNext",
|
||||
"outDir": "dist",
|
||||
"declaration": true,
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
|
||||
/* Additional Checks */
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
/* Module Resolution Options */
|
||||
"moduleResolution": "NodeNext",
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
|
||||
/* Advanced Options */
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
||||
// temporary disable lib check waiting a fix for https://github.com/sindresorhus/got/issues/2051
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"ts-node": {
|
||||
"esm": true,
|
||||
"files": true
|
||||
},
|
||||
"include": ["source", "types/**/*.d.ts"],
|
||||
"exclude": ["**/node_modules", "**/dist", "vitest.config.ts"]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
declare module '@breejs/later'
|
531
yarn.lock
531
yarn.lock
|
@ -2909,7 +2909,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.18.9":
|
||||
"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.10.5, @babel/runtime@npm:^7.18.9":
|
||||
version: 7.19.0
|
||||
resolution: "@babel/runtime@npm:7.19.0"
|
||||
dependencies:
|
||||
|
@ -3068,6 +3068,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@breejs/later@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "@breejs/later@npm:4.1.0"
|
||||
checksum: 0d1c2e06b8b20266ec1aaa09ce96f1b24504d6248a62ac3455a0f46fb9189bae0a5960f962c02cd21dbf9794dd11566e970a8204f02af12f6d6815b32b2d2f1e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@bugsnag/browser@npm:^7.17.0":
|
||||
version: 7.17.0
|
||||
resolution: "@bugsnag/browser@npm:7.17.0"
|
||||
|
@ -3752,6 +3759,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@koa/cors@npm:^3.4.1":
|
||||
version: 3.4.1
|
||||
resolution: "@koa/cors@npm:3.4.1"
|
||||
dependencies:
|
||||
vary: ^1.1.2
|
||||
checksum: 8359f19e156f36016ae3f174ef374bd377eee271b29b9106d595f53fb8c80b63d6b8db7471a466fdc68f62f06286722c5351b5463ed2d46fe88256a568045af6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@koa/router@npm:^10.1.1":
|
||||
version: 10.1.1
|
||||
resolution: "@koa/router@npm:10.1.1"
|
||||
|
@ -3765,6 +3781,18 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@koa/router@npm:^12.0.0":
|
||||
version: 12.0.0
|
||||
resolution: "@koa/router@npm:12.0.0"
|
||||
dependencies:
|
||||
http-errors: ^2.0.0
|
||||
koa-compose: ^4.1.0
|
||||
methods: ^1.1.2
|
||||
path-to-regexp: ^6.2.1
|
||||
checksum: 5529629f7517dba20319cf70b66c5a6111673019f6d196cd500a7b90e6663c99848c188f1bce17415d46c7b20b06566d432299a53affe0a15d05b9213917b9f6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@mapbox/node-pre-gyp@npm:^1.0.5":
|
||||
version: 1.0.9
|
||||
resolution: "@mapbox/node-pre-gyp@npm:1.0.9"
|
||||
|
@ -8309,7 +8337,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/http-cache-semantics@npm:*":
|
||||
"@types/http-cache-semantics@npm:*, @types/http-cache-semantics@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "@types/http-cache-semantics@npm:4.0.1"
|
||||
checksum: 1048aacf627829f0d5f00184e16548205cd9f964bf0841c29b36bc504509230c40bc57c39778703a1c965a6f5b416ae2cbf4c1d4589c889d2838dd9dbfccf6e9
|
||||
|
@ -8455,6 +8483,22 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/koa@npm:^2.13.5":
|
||||
version: 2.13.5
|
||||
resolution: "@types/koa@npm:2.13.5"
|
||||
dependencies:
|
||||
"@types/accepts": "*"
|
||||
"@types/content-disposition": "*"
|
||||
"@types/cookies": "*"
|
||||
"@types/http-assert": "*"
|
||||
"@types/http-errors": "*"
|
||||
"@types/keygrip": "*"
|
||||
"@types/koa-compose": "*"
|
||||
"@types/node": "*"
|
||||
checksum: e3b634d934b79ce8f394bf4130511596081f9c073dbfb4309aa32e4c421c47049a002b65111f8d9687eabec55d5a27b1b9ae0699afa83894cb7032c3536bfa17
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/koa__cors@npm:^3.3.0":
|
||||
version: 3.3.0
|
||||
resolution: "@types/koa__cors@npm:3.3.0"
|
||||
|
@ -8464,6 +8508,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/koa__router@npm:^12.0.0":
|
||||
version: 12.0.0
|
||||
resolution: "@types/koa__router@npm:12.0.0"
|
||||
dependencies:
|
||||
"@types/koa": "*"
|
||||
checksum: ebfee772f7a9c5ff5e296a24443eb2c288fa2e5b8c60afbb460b41f0bd0d68c8a722fff5984eef7b7d90d057fe6f556171695ea83e2cdbeef3e2462f73c362b7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/koa__router@npm:^8.0.11":
|
||||
version: 8.0.11
|
||||
resolution: "@types/koa__router@npm:8.0.11"
|
||||
|
@ -8473,6 +8526,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/lodash@npm:^4.14.165":
|
||||
version: 4.14.186
|
||||
resolution: "@types/lodash@npm:4.14.186"
|
||||
checksum: ee0c1368a8100bb6efb88335107473a41928fc307ff1ef4ff1278868ccddba9c04c68c36d1ffe3a0392ef4a956e1955f7de3203ec09df4f1655dd1b88485c549
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/lodash@npm:^4.14.167":
|
||||
version: 4.14.181
|
||||
resolution: "@types/lodash@npm:4.14.181"
|
||||
|
@ -8838,6 +8898,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/webidl-conversions@npm:*":
|
||||
version: 7.0.0
|
||||
resolution: "@types/webidl-conversions@npm:7.0.0"
|
||||
checksum: 60142c7ddd9eb6f907d232d6b3a81ecf990f73b5a62a004eba8bd0f54809a42ece68ce512e7e3e1d98af8b6393d66cddb96f3622d2fb223c4e9c8937c61bfed7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/webpack-env@npm:^1.16.0":
|
||||
version: 1.16.3
|
||||
resolution: "@types/webpack-env@npm:1.16.3"
|
||||
|
@ -8870,6 +8937,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/whatwg-url@npm:^8.2.1":
|
||||
version: 8.2.2
|
||||
resolution: "@types/whatwg-url@npm:8.2.2"
|
||||
dependencies:
|
||||
"@types/node": "*"
|
||||
"@types/webidl-conversions": "*"
|
||||
checksum: 5dc5afe078dfa1a8a266745586fa3db9baa8ce7cc904789211d1dca1d34d7f3dd17d0b7423c36bc9beab9d98aa99338f1fc60798c0af6cbb8356f20e20d9f243
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/yargs-parser@npm:*":
|
||||
version: 21.0.0
|
||||
resolution: "@types/yargs-parser@npm:21.0.0"
|
||||
|
@ -10977,6 +11054,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"boolean@npm:^3.2.0":
|
||||
version: 3.2.0
|
||||
resolution: "boolean@npm:3.2.0"
|
||||
checksum: fb29535b8bf710ef45279677a86d14f5185d604557204abd2ca5fa3fb2a5c80e04d695c8dbf13ab269991977a79bb6c04b048220a6b2a3849853faa94f4a7d77
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"boxen@npm:^5.0.0, boxen@npm:^5.1.2":
|
||||
version: 5.1.2
|
||||
resolution: "boxen@npm:5.1.2"
|
||||
|
@ -11048,6 +11132,24 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bree@npm:^9.1.2":
|
||||
version: 9.1.2
|
||||
resolution: "bree@npm:9.1.2"
|
||||
dependencies:
|
||||
"@breejs/later": ^4.1.0
|
||||
boolean: ^3.2.0
|
||||
combine-errors: ^3.0.3
|
||||
cron-validate: ^1.4.3
|
||||
human-interval: ^2.0.1
|
||||
is-string-and-not-blank: ^0.0.2
|
||||
is-valid-path: ^0.1.1
|
||||
ms: ^2.1.3
|
||||
p-wait-for: 3
|
||||
safe-timers: ^1.1.0
|
||||
checksum: c23c6f1fc3aa27b33c0649668534806140f8fa0d80991d322304d669993ab1188b097c431b633735cd11ca0a49eff2a8b464d8eb781fcaa8e976b2c1098fc4ed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"broccoli-node-api@npm:^1.7.0":
|
||||
version: 1.7.0
|
||||
resolution: "broccoli-node-api@npm:1.7.0"
|
||||
|
@ -11220,6 +11322,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bson@npm:^4.7.0":
|
||||
version: 4.7.0
|
||||
resolution: "bson@npm:4.7.0"
|
||||
dependencies:
|
||||
buffer: ^5.6.0
|
||||
checksum: 83e7b64afdad5a505073a7e6206e7b345f59e7888fbcb1948fba72b6101a1baf58b7499314f8e24b650567665f7973eda048aabbb1ddcfbadfba7d6c6b0f5e83
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"buffer-alloc-unsafe@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "buffer-alloc-unsafe@npm:1.1.0"
|
||||
|
@ -11495,6 +11606,28 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cacheable-lookup@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "cacheable-lookup@npm:7.0.0"
|
||||
checksum: 9e2856763fc0a7347ab34d704c010440b819d4bb5e3593b664381b7433e942dd22e67ee5581f12256f908e79b82d30b86ebbacf40a081bfe10ee93fbfbc2d6a9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cacheable-request@npm:^10.2.1":
|
||||
version: 10.2.1
|
||||
resolution: "cacheable-request@npm:10.2.1"
|
||||
dependencies:
|
||||
"@types/http-cache-semantics": ^4.0.1
|
||||
get-stream: ^6.0.1
|
||||
http-cache-semantics: ^4.1.0
|
||||
keyv: ^4.5.0
|
||||
mimic-response: ^4.0.0
|
||||
normalize-url: ^7.1.0
|
||||
responselike: ^3.0.0
|
||||
checksum: 11bcee52d676623fbfe4b02b9f30930457796a7320a5db25392238a92a98185ffa7e87619d82a472c411c7f48eada5ec182bab41e6d849a038e84774dcdbba7d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cacheable-request@npm:^2.1.1":
|
||||
version: 2.1.4
|
||||
resolution: "cacheable-request@npm:2.1.4"
|
||||
|
@ -12330,6 +12463,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"combine-errors@npm:^3.0.3":
|
||||
version: 3.0.3
|
||||
resolution: "combine-errors@npm:3.0.3"
|
||||
dependencies:
|
||||
custom-error-instance: 2.1.1
|
||||
lodash.uniqby: 4.5.0
|
||||
checksum: bd0b0d2a4020f9976b8fe8eb7d5aa855b43ecacdcb61ee1fc5664d73ff8c1d7d0bbe4dd948bea7ba1870518bfc5688b89941de7a4967659418b4664cdb02884f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6":
|
||||
version: 1.0.8
|
||||
resolution: "combined-stream@npm:1.0.8"
|
||||
|
@ -12829,6 +12972,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cron-validate@npm:^1.4.3":
|
||||
version: 1.4.3
|
||||
resolution: "cron-validate@npm:1.4.3"
|
||||
dependencies:
|
||||
yup: 0.32.9
|
||||
checksum: beb4ef6ee7a0f07ee815866a621fbb01dd27e090da0ec5ac41c2ce845469af4e0e130adde967dd310839ad9e93db6de4c3c00617baa2fb80fdf78c773977f554
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-fetch@npm:^3.1.5":
|
||||
version: 3.1.5
|
||||
resolution: "cross-fetch@npm:3.1.5"
|
||||
|
@ -13022,6 +13174,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"custom-error-instance@npm:2.1.1":
|
||||
version: 2.1.1
|
||||
resolution: "custom-error-instance@npm:2.1.1"
|
||||
checksum: db01483864c9f4356b720b443a1f9b374758745a75199187a0ccc12505cf822bc801a0d8e3f96d727559880024f40e09667d5c08e5de0bff243c6b5ae0bd303c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cyclist@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "cyclist@npm:1.0.1"
|
||||
|
@ -13576,7 +13735,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"denque@npm:^2.0.1":
|
||||
"denque@npm:^2.0.1, denque@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "denque@npm:2.1.0"
|
||||
checksum: 1d4ae1d05e59ac3a3481e7b478293f4b4c813819342273f3d5b826c7ffa9753c520919ba264f377e09108d24ec6cf0ec0ac729a5686cbb8f32d797126c5dae74
|
||||
|
@ -13988,6 +14147,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv@npm:^16.0.3":
|
||||
version: 16.0.3
|
||||
resolution: "dotenv@npm:16.0.3"
|
||||
checksum: afcf03f373d7a6d62c7e9afea6328e62851d627a4e73f2e12d0a8deae1cd375892004f3021883f8aec85932cd2834b091f568ced92b4774625b321db83b827f8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv@npm:^8.0.0":
|
||||
version: 8.6.0
|
||||
resolution: "dotenv@npm:8.6.0"
|
||||
|
@ -16408,7 +16574,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"form-data-encoder@npm:^2.1.0":
|
||||
"form-data-encoder@npm:^2.1.0, form-data-encoder@npm:^2.1.2":
|
||||
version: 2.1.2
|
||||
resolution: "form-data-encoder@npm:2.1.2"
|
||||
checksum: 5c6401e3ebd2ba2adfa151c9fbd1df5adae8b1dd7bca5b18ab25ad1f9b83e20ddffb6b9ff77f5006b93d7ec2032e22828c9543c0bd4b2bc5b05335c31a3ba5b9
|
||||
|
@ -17212,6 +17378,25 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"got@npm:^12.5.1":
|
||||
version: 12.5.1
|
||||
resolution: "got@npm:12.5.1"
|
||||
dependencies:
|
||||
"@sindresorhus/is": ^5.2.0
|
||||
"@szmarczak/http-timer": ^5.0.1
|
||||
cacheable-lookup: ^7.0.0
|
||||
cacheable-request: ^10.2.1
|
||||
decompress-response: ^6.0.0
|
||||
form-data-encoder: ^2.1.2
|
||||
get-stream: ^6.0.1
|
||||
http2-wrapper: ^2.1.10
|
||||
lowercase-keys: ^3.0.0
|
||||
p-cancelable: ^3.0.0
|
||||
responselike: ^3.0.0
|
||||
checksum: 479a279e8f0ba39270d500e8998dda897c850a9f43eef716c58fcaa7b5049e74ca3fd8ab70be1e2a59a5c8b59a83b9deab16d4e523423bb1e2dfe17401750efa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"got@npm:^8.3.1":
|
||||
version: 8.3.2
|
||||
resolution: "got@npm:8.3.2"
|
||||
|
@ -17796,7 +17981,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-errors@npm:2.0.0":
|
||||
"http-errors@npm:2.0.0, http-errors@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "http-errors@npm:2.0.0"
|
||||
dependencies:
|
||||
|
@ -17912,6 +18097,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"human-interval@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "human-interval@npm:2.0.1"
|
||||
dependencies:
|
||||
numbered: ^1.1.0
|
||||
checksum: 8f1b37485f554d1f7a3fa2cefdbd9cee2df3ff2cfb86ae1db9f58f2db9d524d44863c2d291f04c810317f2fa7ceeda2188281985c7d65b3774d53c9e835ed55c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"human-signals@npm:^1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "human-signals@npm:1.1.1"
|
||||
|
@ -18319,6 +18513,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ip@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "ip@npm:2.0.0"
|
||||
checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ipaddr.js@npm:1.9.1":
|
||||
version: 1.9.1
|
||||
resolution: "ipaddr.js@npm:1.9.1"
|
||||
|
@ -18976,6 +19177,22 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-string-and-not-blank@npm:^0.0.2":
|
||||
version: 0.0.2
|
||||
resolution: "is-string-and-not-blank@npm:0.0.2"
|
||||
dependencies:
|
||||
is-string-blank: ^1.0.1
|
||||
checksum: 9b0fff4f0974ffaceb382dcf012587d1ad5d5013d7260a4e85621b67fbcb29ca906bcd607fe71bdd72c642f7b56b5b9e779f9d54224b826da9aa48b2003b6113
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-string-blank@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "is-string-blank@npm:1.0.1"
|
||||
checksum: 00a0955c2bac08cc84f9f878d2a3fdba86997ac23c0b661e50f39efba635444d9cec84237337200be9a4e07234069318498592817614525cd959ae0d43df2151
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-string@npm:^1.0.5, is-string@npm:^1.0.7":
|
||||
version: 1.0.7
|
||||
resolution: "is-string@npm:1.0.7"
|
||||
|
@ -19772,6 +19989,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"keyv@npm:^4.5.0":
|
||||
version: 4.5.0
|
||||
resolution: "keyv@npm:4.5.0"
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
checksum: d294873cf88ec8f691e5edeb7b4b884f886c5f021a01902a0e243c362449db2b55419d7fb7187d059add747b7398321e39e44d391b65f94935174ce13452714d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"kind-of@npm:^3.0.2, kind-of@npm:^3.0.3, kind-of@npm:^3.2.0":
|
||||
version: 3.2.2
|
||||
resolution: "kind-of@npm:3.2.2"
|
||||
|
@ -20218,6 +20444,62 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash-es@npm:^4.17.15":
|
||||
version: 4.17.21
|
||||
resolution: "lodash-es@npm:4.17.21"
|
||||
checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash._baseiteratee@npm:~4.7.0":
|
||||
version: 4.7.0
|
||||
resolution: "lodash._baseiteratee@npm:4.7.0"
|
||||
dependencies:
|
||||
lodash._stringtopath: ~4.8.0
|
||||
checksum: 814a7125b9e2fa7e436c4402eae842a200189e2839b56bd6cde7cd0a3628b60842f5d39a9f5dceaf8766669b2e4a17a36ce2a213d1d6a891c1bef8a6bda36ea9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash._basetostring@npm:~4.12.0":
|
||||
version: 4.12.0
|
||||
resolution: "lodash._basetostring@npm:4.12.0"
|
||||
checksum: ccaf83827f86be5c9daeb7b939f761d6a43f0de0781bc3b6772fcb8568fbcbfa1e1082c66e5e12dd23e00ac40a18349c5a793a6a552e3574cbbcb3e1545fcb4c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash._baseuniq@npm:~4.6.0":
|
||||
version: 4.6.0
|
||||
resolution: "lodash._baseuniq@npm:4.6.0"
|
||||
dependencies:
|
||||
lodash._createset: ~4.0.0
|
||||
lodash._root: ~3.0.0
|
||||
checksum: 8c16fe2e80716b18c2f28bbcc902768141d432b0b98e03b30a2fba6a097377fabdc8753da232568375d2aa9502dc6b3a390200aa1467d2f685a582a46a271936
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash._createset@npm:~4.0.0":
|
||||
version: 4.0.3
|
||||
resolution: "lodash._createset@npm:4.0.3"
|
||||
checksum: fb4450fbf4846aa7b420837ee44400b88664e28499388b7e04b4db38adca1305915f68a245fb2a87e031e7f440b997de4f360de6dea2712952520e97c7898de1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash._root@npm:~3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "lodash._root@npm:3.0.1"
|
||||
checksum: 3e12c6f409ae13164a8db358f44a691f1e038dad4e25463802980d0ed641ed118c147b65657501c51778c885422b913264dfbe33ec0c5d676443dd630a7e685a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash._stringtopath@npm:~4.8.0":
|
||||
version: 4.8.0
|
||||
resolution: "lodash._stringtopath@npm:4.8.0"
|
||||
dependencies:
|
||||
lodash._basetostring: ~4.12.0
|
||||
checksum: 00663b317796333e6315ebb4e8b590e68845de10d5d25c7585751fd9d28adf3e60e1ce85a6fbb6a0d440447c841465b91877e761239e358231eed2f52f0a5472
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.camelcase@npm:^4.3.0":
|
||||
version: 4.3.0
|
||||
resolution: "lodash.camelcase@npm:4.3.0"
|
||||
|
@ -20372,6 +20654,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.uniqby@npm:4.5.0":
|
||||
version: 4.5.0
|
||||
resolution: "lodash.uniqby@npm:4.5.0"
|
||||
dependencies:
|
||||
lodash._baseiteratee: ~4.7.0
|
||||
lodash._baseuniq: ~4.6.0
|
||||
checksum: 40a4fdd4c31323fcb6db91ec3124020333212ca1f13e75cc9939decdd33e8b176d204fb277be36a51a855c2c90e14d67932b3b130b2f0eedc729e4cb9cdcaed1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash@npm:^4.17.11, lodash@npm:^4.17.12, lodash@npm:^4.17.13, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21":
|
||||
version: 4.17.21
|
||||
resolution: "lodash@npm:4.17.21"
|
||||
|
@ -20897,6 +21189,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"memory-pager@npm:^1.0.2":
|
||||
version: 1.5.0
|
||||
resolution: "memory-pager@npm:1.5.0"
|
||||
checksum: d1a2e684583ef55c61cd3a49101da645b11ad57014dfc565e0b43baa9004b743f7e4ab81493d8fff2ab24e9950987cc3209c94bcc4fc8d7e30a475489a1f15e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"meow@npm:^3.1.0":
|
||||
version: 3.7.0
|
||||
resolution: "meow@npm:3.7.0"
|
||||
|
@ -21092,6 +21391,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mimic-response@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "mimic-response@npm:4.0.0"
|
||||
checksum: 33b804cc961efe206efdb1fca6a22540decdcfce6c14eb5c0c50e5ae9022267ab22ce8f5568b1f7247ba67500fe20d523d81e0e9f009b321ccd9d472e78d1850
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"min-document@npm:^2.19.0":
|
||||
version: 2.19.0
|
||||
resolution: "min-document@npm:2.19.0"
|
||||
|
@ -21306,6 +21612,32 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mongodb-connection-string-url@npm:^2.5.3":
|
||||
version: 2.5.4
|
||||
resolution: "mongodb-connection-string-url@npm:2.5.4"
|
||||
dependencies:
|
||||
"@types/whatwg-url": ^8.2.1
|
||||
whatwg-url: ^11.0.0
|
||||
checksum: 9f431826b229488808e4a8a9e6bdde0162be3e6d5cad40867b69b2199ce009f568b67dc1bf587a43367904d8184f1c68689f7ea6574ed40b396726abde9485e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mongodb@npm:^4.10.0":
|
||||
version: 4.10.0
|
||||
resolution: "mongodb@npm:4.10.0"
|
||||
dependencies:
|
||||
bson: ^4.7.0
|
||||
denque: ^2.1.0
|
||||
mongodb-connection-string-url: ^2.5.3
|
||||
saslprep: ^1.0.3
|
||||
socks: ^2.7.0
|
||||
dependenciesMeta:
|
||||
saslprep:
|
||||
optional: true
|
||||
checksum: 4847fe69b6d3baddc440936d306b4d00fa40a1dafabd387f9fb6f3ecd63b27c41f11b2cc46774ac2bf17e9b508d35908ebe21f47badf3449fb7afcbde2733951
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"moo@npm:^0.5.0, moo@npm:^0.5.1":
|
||||
version: 0.5.1
|
||||
resolution: "moo@npm:0.5.1"
|
||||
|
@ -21357,7 +21689,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.1":
|
||||
"ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.1, ms@npm:^2.1.3":
|
||||
version: 2.1.3
|
||||
resolution: "ms@npm:2.1.3"
|
||||
checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d
|
||||
|
@ -21398,6 +21730,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nanoclone@npm:^0.2.1":
|
||||
version: 0.2.1
|
||||
resolution: "nanoclone@npm:0.2.1"
|
||||
checksum: 96b2954e22f70561f41e20d69856266c65583c2a441dae108f1dc71b716785d2c8038dac5f1d5e92b117aed3825f526b53139e2e5d6e6db8a77cfa35b3b8bf40
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nanoid@npm:^3.3.4":
|
||||
version: 3.3.4
|
||||
resolution: "nanoid@npm:3.3.4"
|
||||
|
@ -21852,6 +22191,26 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nodemon@npm:^2.0.20":
|
||||
version: 2.0.20
|
||||
resolution: "nodemon@npm:2.0.20"
|
||||
dependencies:
|
||||
chokidar: ^3.5.2
|
||||
debug: ^3.2.7
|
||||
ignore-by-default: ^1.0.1
|
||||
minimatch: ^3.1.2
|
||||
pstree.remy: ^1.1.8
|
||||
semver: ^5.7.1
|
||||
simple-update-notifier: ^1.0.7
|
||||
supports-color: ^5.5.0
|
||||
touch: ^3.1.0
|
||||
undefsafe: ^2.0.5
|
||||
bin:
|
||||
nodemon: bin/nodemon.js
|
||||
checksum: 9fe858682414fe703179f4fe36c86e71f40d2693b5345c09803d7b191816a6589c5df8f1f9873bffee92893880183b95a031c86340e46b364ef1b0b7f619edbf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"noop2@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "noop2@npm:2.0.0"
|
||||
|
@ -21974,6 +22333,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"normalize-url@npm:^7.1.0":
|
||||
version: 7.2.0
|
||||
resolution: "normalize-url@npm:7.2.0"
|
||||
checksum: 7753f081ee997520c9cd855f06975d7ac24b1ef58002e310d5058c831b9a6165ec2ec9fc0c5bc9e886e1257affaffa7c36731ae39073fcf74af07197997d4fb6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"now-and-later@npm:^2.0.0":
|
||||
version: 2.0.1
|
||||
resolution: "now-and-later@npm:2.0.1"
|
||||
|
@ -22064,6 +22430,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"numbered@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "numbered@npm:1.1.0"
|
||||
checksum: cdc238990fe29818cb603ac8d4050ff82a05b63e10d8848d1ff1e315231e94813c48b405e651b22d32edc8ccf1f323920d1182ea02c081f11d94ea22b1f8c17a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1":
|
||||
version: 4.1.1
|
||||
resolution: "object-assign@npm:4.1.1"
|
||||
|
@ -22725,7 +23098,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"p-wait-for@npm:^3.0.0":
|
||||
"p-wait-for@npm:3, p-wait-for@npm:^3.0.0":
|
||||
version: 3.2.0
|
||||
resolution: "p-wait-for@npm:3.2.0"
|
||||
dependencies:
|
||||
|
@ -23027,7 +23400,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-to-regexp@npm:^6.1.0":
|
||||
"path-to-regexp@npm:^6.1.0, path-to-regexp@npm:^6.2.1":
|
||||
version: 6.2.1
|
||||
resolution: "path-to-regexp@npm:6.2.1"
|
||||
checksum: f0227af8284ea13300f4293ba111e3635142f976d4197f14d5ad1f124aebd9118783dd2e5f1fe16f7273743cc3dbeddfb7493f237bb27c10fdae07020cc9b698
|
||||
|
@ -23597,6 +23970,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"property-expr@npm:^2.0.4":
|
||||
version: 2.0.5
|
||||
resolution: "property-expr@npm:2.0.5"
|
||||
checksum: 4ebe82ce45aaf1527e96e2ab84d75d25217167ec3ff6378cf83a84fb4abc746e7c65768a79d275881602ae82f168f9a6dfaa7f5e331d0fcc83d692770bcce5f1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"property-information@npm:^5.0.0, property-information@npm:^5.3.0":
|
||||
version: 5.6.0
|
||||
resolution: "property-information@npm:5.6.0"
|
||||
|
@ -25346,6 +25726,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"safe-timers@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "safe-timers@npm:1.1.0"
|
||||
checksum: 6387c1e09fae12c4b96fb62e2575ace9ec6b1f73ad73d937e0ecc79de92cb64e56dbbfa60a8d5d7c54c035960457fa59cffd5d6b396fe0d82ed8042c889a7f1a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0":
|
||||
version: 2.1.2
|
||||
resolution: "safer-buffer@npm:2.1.2"
|
||||
|
@ -25372,6 +25759,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"saslprep@npm:^1.0.3":
|
||||
version: 1.0.3
|
||||
resolution: "saslprep@npm:1.0.3"
|
||||
dependencies:
|
||||
sparse-bitfield: ^3.0.3
|
||||
checksum: 4fdc0b70fb5e523f977de405e12cca111f1f10dd68a0cfae0ca52c1a7919a94d1556598ba2d35f447655c3b32879846c77f9274c90806f6673248ae3cea6ee43
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sax@npm:>=0.6.0":
|
||||
version: 1.2.4
|
||||
resolution: "sax@npm:1.2.4"
|
||||
|
@ -25473,7 +25869,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:7.0.0":
|
||||
"semver@npm:7.0.0, semver@npm:~7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "semver@npm:7.0.0"
|
||||
bin:
|
||||
|
@ -25709,6 +26105,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-update-notifier@npm:^1.0.7":
|
||||
version: 1.0.7
|
||||
resolution: "simple-update-notifier@npm:1.0.7"
|
||||
dependencies:
|
||||
semver: ~7.0.0
|
||||
checksum: aaadc1f158ad5101b363d1c7aed1f30fc1cac59a760aa31702633e0e6fe423348f07d0e78185aef0aad29130a7b7f0f188c21c7bc7353f897a0ea3682e051a70
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sisteransi@npm:^1.0.5":
|
||||
version: 1.0.5
|
||||
resolution: "sisteransi@npm:1.0.5"
|
||||
|
@ -25948,6 +26353,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socks@npm:^2.7.0":
|
||||
version: 2.7.1
|
||||
resolution: "socks@npm:2.7.1"
|
||||
dependencies:
|
||||
ip: ^2.0.0
|
||||
smart-buffer: ^4.2.0
|
||||
checksum: 259d9e3e8e1c9809a7f5c32238c3d4d2a36b39b83851d0f573bfde5f21c4b1288417ce1af06af1452569cd1eb0841169afd4998f0e04ba04656f6b7f0e46d748
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sort-keys-length@npm:^1.0.0":
|
||||
version: 1.0.1
|
||||
resolution: "sort-keys-length@npm:1.0.1"
|
||||
|
@ -26081,6 +26496,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sparse-bitfield@npm:^3.0.3":
|
||||
version: 3.0.3
|
||||
resolution: "sparse-bitfield@npm:3.0.3"
|
||||
dependencies:
|
||||
memory-pager: ^1.0.2
|
||||
checksum: 174da88dbbcc783d5dbd26921931cc83830280b8055fb05333786ebe6fc015b9601b24972b3d55920dd2d9f5fb120576fbfa2469b08e5222c9cadf3f05210aab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"spdx-correct@npm:^3.0.0":
|
||||
version: 3.1.1
|
||||
resolution: "spdx-correct@npm:3.1.1"
|
||||
|
@ -26232,6 +26656,27 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"standup-mattermost-bot@workspace:standup-mattermost-bot":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "standup-mattermost-bot@workspace:standup-mattermost-bot"
|
||||
dependencies:
|
||||
"@breejs/later": ^4.1.0
|
||||
"@koa/cors": ^3.4.1
|
||||
"@koa/router": ^12.0.0
|
||||
"@types/koa": ^2.13.5
|
||||
"@types/koa__cors": ^3.3.0
|
||||
"@types/koa__router": ^12.0.0
|
||||
bree: ^9.1.2
|
||||
dotenv: ^16.0.3
|
||||
got: ^12.5.1
|
||||
koa: ^2.13.4
|
||||
mongodb: ^4.10.0
|
||||
nodemon: ^2.0.20
|
||||
ts-node: ^10.9.1
|
||||
typescript: ^4.8.4
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"state-toggle@npm:^1.0.0":
|
||||
version: 1.0.3
|
||||
resolution: "state-toggle@npm:1.0.3"
|
||||
|
@ -27379,6 +27824,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"toposort@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "toposort@npm:2.0.2"
|
||||
checksum: d64c74b570391c9432873f48e231b439ee56bc49f7cb9780b505cfdf5cb832f808d0bae072515d93834dd6bceca5bb34448b5b4b408335e4d4716eaf68195dcb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tosource@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "tosource@npm:1.0.0"
|
||||
|
@ -27416,6 +27868,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tr46@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "tr46@npm:3.0.0"
|
||||
dependencies:
|
||||
punycode: ^2.1.1
|
||||
checksum: 44c3cc6767fb800490e6e9fd64fd49041aa4e49e1f6a012b34a75de739cc9ed3a6405296072c1df8b6389ae139c5e7c6496f659cfe13a04a4bff3a1422981270
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tr46@npm:~0.0.3":
|
||||
version: 0.0.3
|
||||
resolution: "tr46@npm:0.0.3"
|
||||
|
@ -27787,6 +28248,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^4.8.4":
|
||||
version: 4.8.4
|
||||
resolution: "typescript@npm:4.8.4"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 3e4f061658e0c8f36c820802fa809e0fd812b85687a9a2f5430bc3d0368e37d1c9605c3ce9b39df9a05af2ece67b1d844f9f6ea8ff42819f13bcb80f85629af0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@^4.2.4#~builtin<compat/typescript>, typescript@patch:typescript@^4.5.4#~builtin<compat/typescript>, typescript@patch:typescript@^4.5.5#~builtin<compat/typescript>":
|
||||
version: 4.7.4
|
||||
resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin<compat/typescript>::version=4.7.4&hash=a1c5e5"
|
||||
|
@ -27807,6 +28278,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@^4.8.4#~builtin<compat/typescript>":
|
||||
version: 4.8.4
|
||||
resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin<compat/typescript>::version=4.8.4&hash=a1c5e5"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 563a0ef47abae6df27a9a3ab38f75fc681f633ccf1a3502b1108e252e187787893de689220f4544aaf95a371a4eb3141e4a337deb9895de5ac3c1ca76430e5f0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uglify-js@npm:^3.1.4":
|
||||
version: 3.16.2
|
||||
resolution: "uglify-js@npm:3.16.2"
|
||||
|
@ -28854,6 +29335,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webidl-conversions@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "webidl-conversions@npm:7.0.0"
|
||||
checksum: f05588567a2a76428515333eff87200fae6c83c3948a7482ebb109562971e77ef6dc49749afa58abb993391227c5697b3ecca52018793e0cb4620a48f10bd21b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webpack-dev-middleware@npm:^3.7.3":
|
||||
version: 3.7.3
|
||||
resolution: "webpack-dev-middleware@npm:3.7.3"
|
||||
|
@ -29015,6 +29503,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"whatwg-url@npm:^11.0.0":
|
||||
version: 11.0.0
|
||||
resolution: "whatwg-url@npm:11.0.0"
|
||||
dependencies:
|
||||
tr46: ^3.0.0
|
||||
webidl-conversions: ^7.0.0
|
||||
checksum: ed4826aaa57e66bb3488a4b25c9cd476c46ba96052747388b5801f137dd740b73fde91ad207d96baf9f17fbcc80fc1a477ad65181b5eb5fa718d27c69501d7af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"whatwg-url@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "whatwg-url@npm:5.0.0"
|
||||
|
@ -29655,6 +30153,21 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yup@npm:0.32.9":
|
||||
version: 0.32.9
|
||||
resolution: "yup@npm:0.32.9"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.10.5
|
||||
"@types/lodash": ^4.14.165
|
||||
lodash: ^4.17.20
|
||||
lodash-es: ^4.17.15
|
||||
nanoclone: ^0.2.1
|
||||
property-expr: ^2.0.4
|
||||
toposort: ^2.0.2
|
||||
checksum: 3f33850913a237fb7e59b0b5c71d2cc6bdb1d6b2b01fc24c53ec68b35ad2b95cd49f735532117136495cb57f0ec58f0a7e1f1c55fad685555c7114155170f1ea
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"z-schema@npm:^5.0.1, z-schema@npm:~5.0.2":
|
||||
version: 5.0.3
|
||||
resolution: "z-schema@npm:5.0.3"
|
||||
|
|
Loading…
Reference in New Issue