summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--assets/schemas.json4197
-rw-r--r--package-lock.json15
-rw-r--r--package.json1
-rw-r--r--pnpm-lock.yaml5745
-rw-r--r--src/api/Server.ts5
-rw-r--r--src/api/middlewares/Authentication.ts2
-rw-r--r--src/api/routes/connections/#connection_name/#connection_id/refresh.ts11
-rw-r--r--src/api/routes/connections/#connection_name/authorize.ts34
-rw-r--r--src/api/routes/connections/#connection_name/callback.ts53
-rw-r--r--src/api/routes/policies/instance/domains.ts2
-rw-r--r--src/api/routes/users/#id/profile.ts4
-rw-r--r--src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts81
-rw-r--r--src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts85
-rw-r--r--src/api/routes/users/@me/connections/index.ts (renamed from src/api/routes/users/@me/connections.ts)22
-rw-r--r--src/connections/BattleNet/BattleNetSettings.ts5
-rw-r--r--src/connections/BattleNet/index.ts116
-rw-r--r--src/connections/Discord/DiscordSettings.ts5
-rw-r--r--src/connections/Discord/index.ts115
-rw-r--r--src/connections/EpicGames/EpicGamesSettings.ts5
-rw-r--r--src/connections/EpicGames/index.ts128
-rw-r--r--src/connections/Facebook/FacebookSettings.ts5
-rw-r--r--src/connections/Facebook/index.ts119
-rw-r--r--src/connections/GitHub/GitHubSettings.ts5
-rw-r--r--src/connections/GitHub/index.ts106
-rw-r--r--src/connections/Reddit/RedditSettings.ts5
-rw-r--r--src/connections/Reddit/index.ts128
-rw-r--r--src/connections/Spotify/SpotifySettings.ts5
-rw-r--r--src/connections/Spotify/index.ts171
-rw-r--r--src/connections/Twitch/TwitchSettings.ts5
-rw-r--r--src/connections/Twitch/index.ts163
-rw-r--r--src/connections/Twitter/TwitterSettings.ts5
-rw-r--r--src/connections/Twitter/index.ts165
-rw-r--r--src/connections/Xbox/XboxSettings.ts5
-rw-r--r--src/connections/Xbox/index.ts180
-rw-r--r--src/connections/Youtube/YoutubeSettings.ts5
-rw-r--r--src/connections/Youtube/index.ts133
-rw-r--r--src/gateway/opcodes/Identify.ts103
-rw-r--r--src/util/config/types/ApiConfiguration.ts2
-rw-r--r--src/util/connections/Connection.ts100
-rw-r--r--src/util/connections/ConnectionConfig.ts79
-rw-r--r--src/util/connections/ConnectionLoader.ts67
-rw-r--r--src/util/connections/ConnectionStore.ts7
-rw-r--r--src/util/connections/RefreshableConnection.ts30
-rw-r--r--src/util/connections/index.ts5
-rw-r--r--src/util/dtos/ConnectedAccountDTO.ts43
-rw-r--r--src/util/dtos/index.ts1
-rw-r--r--src/util/entities/ConnectedAccount.ts38
-rw-r--r--src/util/entities/ConnectionConfigEntity.ts11
-rw-r--r--src/util/entities/index.ts1
-rw-r--r--src/util/index.ts1
-rw-r--r--src/util/interfaces/ConnectedAccount.ts17
-rw-r--r--src/util/interfaces/Event.ts7
-rw-r--r--src/util/interfaces/index.ts5
-rw-r--r--src/util/schemas/ConnectedAccountSchema.ts18
-rw-r--r--src/util/schemas/ConnectionCallbackSchema.ts7
-rw-r--r--src/util/schemas/ConnectionUpdateSchema.ts4
-rw-r--r--src/util/schemas/index.ts3
-rw-r--r--src/util/util/Constants.ts6
58 files changed, 12070 insertions, 321 deletions
diff --git a/assets/schemas.json b/assets/schemas.json

index 3c7e60a8..8ec8adcc 100644 --- a/assets/schemas.json +++ b/assets/schemas.json
@@ -36,6 +36,33 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, + "ConnectedAccountCommonOAuthTokenResponse": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "scope", + "token_type" + ], + "$schema": "http://json-schema.org/draft-07/schema#" + }, "SMTPConnection.CustomAuthenticationResponse": { "type": "object", "properties": { @@ -419,6 +446,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -1107,6 +1165,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -1795,6 +1884,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -2478,6 +2598,2213 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 14, + 15, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "string" + ] + }, + "bitrate": { + "type": "integer" + }, + "user_limit": { + "type": "integer" + }, + "rate_limit_per_user": { + "type": "integer" + }, + "position": { + "type": "integer" + }, + "permission_overwrites": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "allow", + "deny", + "id", + "type" + ] + } + }, + "parent_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nsfw": { + "type": "boolean" + }, + "rtc_region": { + "type": "string" + }, + "default_auto_archive_duration": { + "type": "integer" + }, + "default_reaction_emoji": { + "type": [ + "null", + "string" + ] + }, + "flags": { + "type": "integer" + }, + "default_thread_rate_limit_per_user": { + "type": "integer" + }, + "video_quality_mode": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ActivitySchema": { + "type": "object", + "properties": { + "afk": { + "type": "boolean" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "activities": { + "type": "array", + "items": { + "$ref": "#/definitions/Activity" + } + }, + "since": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "status" + ] + }, + "Status": { + "enum": [ + "dnd", + "idle", + "invisible", + "offline", + "online" + ], + "type": "string" + }, + "Activity": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ActivityType" + }, + "url": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "timestamps": { + "type": "object", + "properties": { + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "end", + "start" + ] + }, + "application_id": { + "type": "string" + }, + "details": { + "type": "string" + }, + "state": { + "type": "string" + }, + "emoji": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "animated": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "animated", + "name" + ] + }, + "party": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "size": { + "type": "array", + "items": [ + { + "type": "integer" + } + ], + "minItems": 1, + "maxItems": 1 + } + }, + "additionalProperties": false + }, + "assets": { + "type": "object", + "properties": { + "large_image": { + "type": "string" + }, + "large_text": { + "type": "string" + }, + "small_image": { + "type": "string" + }, + "small_text": { + "type": "string" + } + }, + "additionalProperties": false + }, + "secrets": { + "type": "object", + "properties": { + "join": { + "type": "string" + }, + "spectate": { + "type": "string" + }, + "match": { + "type": "string" + } + }, + "additionalProperties": false + }, + "instance": { + "type": "boolean" + }, + "flags": { + "type": "string" + }, + "id": { + "type": "string" + }, + "sync_id": { + "type": "string" + }, + "metadata": { + "type": "object", + "properties": { + "context_uri": { + "type": "string" + }, + "album_id": { + "type": "string" + }, + "artist_ids": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "required": [ + "album_id", + "artist_ids" + ] + }, + "session_id": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "flags", + "name", + "session_id", + "type" + ] + }, + "ActivityType": { + "enum": [ + 0, + 1, + 2, + 4, + 5 + ], + "type": "number" + }, + "Record<string,[number,number][]>": { + "type": "object", + "additionalProperties": false + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "color": { + "type": "integer" + }, + "footer": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "icon_url": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "text" + ] + }, + "image": { + "$ref": "#/definitions/EmbedImage" + }, + "thumbnail": { + "$ref": "#/definitions/EmbedImage" + }, + "video": { + "$ref": "#/definitions/EmbedImage" + }, + "provider": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "author": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "icon_url": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "inline": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "value" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "Partial<ChannelOverride>": { + "type": "object", + "properties": { + "message_notifications": { + "type": "integer" + }, + "mute_config": { + "$ref": "#/definitions/MuteConfig" + }, + "muted": { + "type": "boolean" + }, + "channel_id": { + "type": [ + "null", + "string" + ] + } + }, + "additionalProperties": false + }, + "MuteConfig": { + "type": "object", + "properties": { + "end_time": { + "type": "integer" + }, + "selected_time_window": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "end_time", + "selected_time_window" + ] + }, + "CustomStatus": { + "type": "object", + "properties": { + "emoji_id": { + "type": "string" + }, + "emoji_name": { + "type": "string" + }, + "expires_at": { + "type": "integer" + }, + "text": { + "type": "string" + } + }, + "additionalProperties": false + }, + "FriendSourceFlags": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "all" + ] + }, + "GuildFolder": { + "type": "object", + "properties": { + "color": { + "type": "integer" + }, + "guild_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "color", + "guild_ids", + "id", + "name" + ] + }, + "Partial<GenerateWebAuthnCredentialsSchema>": { + "type": "object", + "properties": { + "password": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Partial<CreateWebAuthnCredentialSchema>": { + "type": "object", + "properties": { + "credential": { + "type": "string" + }, + "name": { + "type": "string" + }, + "ticket": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UserPublic": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "premium_since": { + "type": "string", + "format": "date-time" + }, + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_type": { + "type": "integer" + }, + "theme_colors": { + "type": "array", + "items": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "minItems": 2, + "maxItems": 2 + }, + "pronouns": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "premium_type", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "ConnectedAccountSchema": { + "type": "object", + "properties": { + "external_id": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "token_data": { + "$ref": "#/definitions/ConnectedAccountTokenData" + }, + "friend_sync": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "revoked": { + "type": "boolean" + }, + "show_activity": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + }, + "visibility": { + "type": "integer" + }, + "integrations": { + "type": "array", + "items": { + "type": "string" + } + }, + "metadata_": {}, + "metadata_visibility": { + "type": "integer" + }, + "two_way_link": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "external_id", + "name", + "type", + "user_id" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 14, + 15, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "string" + ] + }, + "bitrate": { + "type": "integer" + }, + "user_limit": { + "type": "integer" + }, + "rate_limit_per_user": { + "type": "integer" + }, + "position": { + "type": "integer" + }, + "permission_overwrites": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "allow", + "deny", + "id", + "type" + ] + } + }, + "parent_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nsfw": { + "type": "boolean" + }, + "rtc_region": { + "type": "string" + }, + "default_auto_archive_duration": { + "type": "integer" + }, + "default_reaction_emoji": { + "type": [ + "null", + "string" + ] + }, + "flags": { + "type": "integer" + }, + "default_thread_rate_limit_per_user": { + "type": "integer" + }, + "video_quality_mode": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ActivitySchema": { + "type": "object", + "properties": { + "afk": { + "type": "boolean" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "activities": { + "type": "array", + "items": { + "$ref": "#/definitions/Activity" + } + }, + "since": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "status" + ] + }, + "Status": { + "enum": [ + "dnd", + "idle", + "invisible", + "offline", + "online" + ], + "type": "string" + }, + "Activity": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ActivityType" + }, + "url": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "timestamps": { + "type": "object", + "properties": { + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "end", + "start" + ] + }, + "application_id": { + "type": "string" + }, + "details": { + "type": "string" + }, + "state": { + "type": "string" + }, + "emoji": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "animated": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "animated", + "name" + ] + }, + "party": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "size": { + "type": "array", + "items": [ + { + "type": "integer" + } + ], + "minItems": 1, + "maxItems": 1 + } + }, + "additionalProperties": false + }, + "assets": { + "type": "object", + "properties": { + "large_image": { + "type": "string" + }, + "large_text": { + "type": "string" + }, + "small_image": { + "type": "string" + }, + "small_text": { + "type": "string" + } + }, + "additionalProperties": false + }, + "secrets": { + "type": "object", + "properties": { + "join": { + "type": "string" + }, + "spectate": { + "type": "string" + }, + "match": { + "type": "string" + } + }, + "additionalProperties": false + }, + "instance": { + "type": "boolean" + }, + "flags": { + "type": "string" + }, + "id": { + "type": "string" + }, + "sync_id": { + "type": "string" + }, + "metadata": { + "type": "object", + "properties": { + "context_uri": { + "type": "string" + }, + "album_id": { + "type": "string" + }, + "artist_ids": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "required": [ + "album_id", + "artist_ids" + ] + }, + "session_id": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "flags", + "name", + "session_id", + "type" + ] + }, + "ActivityType": { + "enum": [ + 0, + 1, + 2, + 4, + 5 + ], + "type": "number" + }, + "Record<string,[number,number][]>": { + "type": "object", + "additionalProperties": false + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "color": { + "type": "integer" + }, + "footer": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "icon_url": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "text" + ] + }, + "image": { + "$ref": "#/definitions/EmbedImage" + }, + "thumbnail": { + "$ref": "#/definitions/EmbedImage" + }, + "video": { + "$ref": "#/definitions/EmbedImage" + }, + "provider": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "author": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "icon_url": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "inline": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "value" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "Partial<ChannelOverride>": { + "type": "object", + "properties": { + "message_notifications": { + "type": "integer" + }, + "mute_config": { + "$ref": "#/definitions/MuteConfig" + }, + "muted": { + "type": "boolean" + }, + "channel_id": { + "type": [ + "null", + "string" + ] + } + }, + "additionalProperties": false + }, + "MuteConfig": { + "type": "object", + "properties": { + "end_time": { + "type": "integer" + }, + "selected_time_window": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "end_time", + "selected_time_window" + ] + }, + "CustomStatus": { + "type": "object", + "properties": { + "emoji_id": { + "type": "string" + }, + "emoji_name": { + "type": "string" + }, + "expires_at": { + "type": "integer" + }, + "text": { + "type": "string" + } + }, + "additionalProperties": false + }, + "FriendSourceFlags": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "all" + ] + }, + "GuildFolder": { + "type": "object", + "properties": { + "color": { + "type": "integer" + }, + "guild_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "color", + "guild_ids", + "id", + "name" + ] + }, + "Partial<GenerateWebAuthnCredentialsSchema>": { + "type": "object", + "properties": { + "password": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Partial<CreateWebAuthnCredentialSchema>": { + "type": "object", + "properties": { + "credential": { + "type": "string" + }, + "name": { + "type": "string" + }, + "ticket": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UserPublic": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "premium_since": { + "type": "string", + "format": "date-time" + }, + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_type": { + "type": "integer" + }, + "theme_colors": { + "type": "array", + "items": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "minItems": 2, + "maxItems": 2 + }, + "pronouns": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "premium_type", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "ConnectionCallbackSchema": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "state": { + "type": "string" + }, + "insecure": { + "type": "boolean" + }, + "friend_sync": { + "type": "boolean" + }, + "openid_params": {} + }, + "additionalProperties": false, + "required": [ + "friend_sync", + "insecure", + "state" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 14, + 15, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "string" + ] + }, + "bitrate": { + "type": "integer" + }, + "user_limit": { + "type": "integer" + }, + "rate_limit_per_user": { + "type": "integer" + }, + "position": { + "type": "integer" + }, + "permission_overwrites": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "allow", + "deny", + "id", + "type" + ] + } + }, + "parent_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nsfw": { + "type": "boolean" + }, + "rtc_region": { + "type": "string" + }, + "default_auto_archive_duration": { + "type": "integer" + }, + "default_reaction_emoji": { + "type": [ + "null", + "string" + ] + }, + "flags": { + "type": "integer" + }, + "default_thread_rate_limit_per_user": { + "type": "integer" + }, + "video_quality_mode": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ActivitySchema": { + "type": "object", + "properties": { + "afk": { + "type": "boolean" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "activities": { + "type": "array", + "items": { + "$ref": "#/definitions/Activity" + } + }, + "since": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "status" + ] + }, + "Status": { + "enum": [ + "dnd", + "idle", + "invisible", + "offline", + "online" + ], + "type": "string" + }, + "Activity": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ActivityType" + }, + "url": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "timestamps": { + "type": "object", + "properties": { + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "end", + "start" + ] + }, + "application_id": { + "type": "string" + }, + "details": { + "type": "string" + }, + "state": { + "type": "string" + }, + "emoji": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "animated": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "animated", + "name" + ] + }, + "party": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "size": { + "type": "array", + "items": [ + { + "type": "integer" + } + ], + "minItems": 1, + "maxItems": 1 + } + }, + "additionalProperties": false + }, + "assets": { + "type": "object", + "properties": { + "large_image": { + "type": "string" + }, + "large_text": { + "type": "string" + }, + "small_image": { + "type": "string" + }, + "small_text": { + "type": "string" + } + }, + "additionalProperties": false + }, + "secrets": { + "type": "object", + "properties": { + "join": { + "type": "string" + }, + "spectate": { + "type": "string" + }, + "match": { + "type": "string" + } + }, + "additionalProperties": false + }, + "instance": { + "type": "boolean" + }, + "flags": { + "type": "string" + }, + "id": { + "type": "string" + }, + "sync_id": { + "type": "string" + }, + "metadata": { + "type": "object", + "properties": { + "context_uri": { + "type": "string" + }, + "album_id": { + "type": "string" + }, + "artist_ids": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "required": [ + "album_id", + "artist_ids" + ] + }, + "session_id": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "flags", + "name", + "session_id", + "type" + ] + }, + "ActivityType": { + "enum": [ + 0, + 1, + 2, + 4, + 5 + ], + "type": "number" + }, + "Record<string,[number,number][]>": { + "type": "object", + "additionalProperties": false + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "color": { + "type": "integer" + }, + "footer": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "icon_url": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "text" + ] + }, + "image": { + "$ref": "#/definitions/EmbedImage" + }, + "thumbnail": { + "$ref": "#/definitions/EmbedImage" + }, + "video": { + "$ref": "#/definitions/EmbedImage" + }, + "provider": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "author": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "icon_url": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "inline": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "value" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "Partial<ChannelOverride>": { + "type": "object", + "properties": { + "message_notifications": { + "type": "integer" + }, + "mute_config": { + "$ref": "#/definitions/MuteConfig" + }, + "muted": { + "type": "boolean" + }, + "channel_id": { + "type": [ + "null", + "string" + ] + } + }, + "additionalProperties": false + }, + "MuteConfig": { + "type": "object", + "properties": { + "end_time": { + "type": "integer" + }, + "selected_time_window": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "end_time", + "selected_time_window" + ] + }, + "CustomStatus": { + "type": "object", + "properties": { + "emoji_id": { + "type": "string" + }, + "emoji_name": { + "type": "string" + }, + "expires_at": { + "type": "integer" + }, + "text": { + "type": "string" + } + }, + "additionalProperties": false + }, + "FriendSourceFlags": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "all" + ] + }, + "GuildFolder": { + "type": "object", + "properties": { + "color": { + "type": "integer" + }, + "guild_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "color", + "guild_ids", + "id", + "name" + ] + }, + "Partial<GenerateWebAuthnCredentialsSchema>": { + "type": "object", + "properties": { + "password": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Partial<CreateWebAuthnCredentialSchema>": { + "type": "object", + "properties": { + "credential": { + "type": "string" + }, + "name": { + "type": "string" + }, + "ticket": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UserPublic": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "premium_since": { + "type": "string", + "format": "date-time" + }, + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_type": { + "type": "integer" + }, + "theme_colors": { + "type": "array", + "items": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "minItems": 2, + "maxItems": 2 + }, + "pronouns": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "premium_type", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "ConnectionUpdateSchema": { + "type": "object", + "properties": { + "visibility": { + "type": "boolean" + }, + "show_activity": { + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -3160,6 +5487,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -3851,6 +6209,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -4530,6 +6919,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -5209,6 +7629,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -5907,6 +8358,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -6589,6 +9071,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -7331,6 +9844,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -8032,6 +10576,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -8873,6 +11448,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -9439,92 +12045,6 @@ } }, "additionalProperties": false - }, - "UserPublic": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "premium_since": { - "type": "string", - "format": "date-time" - }, - "username": { - "type": "string" - }, - "discriminator": { - "type": "string" - }, - "public_flags": { - "type": "integer" - }, - "avatar": { - "type": "string" - }, - "accent_color": { - "type": "integer" - }, - "banner": { - "type": "string" - }, - "bio": { - "type": "string" - }, - "bot": { - "type": "boolean" - }, - "premium_type": { - "type": "integer" - }, - "theme_colors": { - "type": "array", - "items": [ - { - "type": "integer" - }, - { - "type": "integer" - } - ], - "minItems": 2, - "maxItems": 2 - }, - "pronouns": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "bio", - "bot", - "discriminator", - "id", - "premium_since", - "premium_type", - "public_flags", - "username" - ] - }, - "PublicConnectedAccount": { - "type": "object", - "properties": { - "type": { - "type": "string" - }, - "name": { - "type": "string" - }, - "verified": { - "type": "boolean" - } - }, - "additionalProperties": false, - "required": [ - "name", - "type", - "verified" - ] } }, "$schema": "http://json-schema.org/draft-07/schema#" @@ -9570,6 +12090,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -10136,92 +12687,6 @@ } }, "additionalProperties": false - }, - "UserPublic": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "premium_since": { - "type": "string", - "format": "date-time" - }, - "username": { - "type": "string" - }, - "discriminator": { - "type": "string" - }, - "public_flags": { - "type": "integer" - }, - "avatar": { - "type": "string" - }, - "accent_color": { - "type": "integer" - }, - "banner": { - "type": "string" - }, - "bio": { - "type": "string" - }, - "bot": { - "type": "boolean" - }, - "premium_type": { - "type": "integer" - }, - "theme_colors": { - "type": "array", - "items": [ - { - "type": "integer" - }, - { - "type": "integer" - } - ], - "minItems": 2, - "maxItems": 2 - }, - "pronouns": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "bio", - "bot", - "discriminator", - "id", - "premium_since", - "premium_type", - "public_flags", - "username" - ] - }, - "PublicConnectedAccount": { - "type": "object", - "properties": { - "type": { - "type": "string" - }, - "name": { - "type": "string" - }, - "verified": { - "type": "boolean" - } - }, - "additionalProperties": false, - "required": [ - "name", - "type", - "verified" - ] } }, "$schema": "http://json-schema.org/draft-07/schema#" @@ -10271,6 +12736,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -10837,92 +13333,6 @@ } }, "additionalProperties": false - }, - "UserPublic": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "premium_since": { - "type": "string", - "format": "date-time" - }, - "username": { - "type": "string" - }, - "discriminator": { - "type": "string" - }, - "public_flags": { - "type": "integer" - }, - "avatar": { - "type": "string" - }, - "accent_color": { - "type": "integer" - }, - "banner": { - "type": "string" - }, - "bio": { - "type": "string" - }, - "bot": { - "type": "boolean" - }, - "premium_type": { - "type": "integer" - }, - "theme_colors": { - "type": "array", - "items": [ - { - "type": "integer" - }, - { - "type": "integer" - } - ], - "minItems": 2, - "maxItems": 2 - }, - "pronouns": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "bio", - "bot", - "discriminator", - "id", - "premium_since", - "premium_type", - "public_flags", - "username" - ] - }, - "PublicConnectedAccount": { - "type": "object", - "properties": { - "type": { - "type": "string" - }, - "name": { - "type": "string" - }, - "verified": { - "type": "boolean" - } - }, - "additionalProperties": false, - "required": [ - "name", - "type", - "verified" - ] } }, "$schema": "http://json-schema.org/draft-07/schema#" @@ -10963,6 +13373,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -11661,6 +14102,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -12349,6 +14821,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -13025,6 +15528,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -13812,6 +16346,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -14596,6 +17161,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -15275,6 +17871,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -15962,6 +18589,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -16642,6 +19300,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -17322,6 +20011,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -18031,6 +20751,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -18711,6 +21462,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -19390,6 +22172,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -20084,6 +22897,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -20767,6 +23611,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -21524,6 +24399,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -22203,6 +25109,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -22882,6 +25819,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -23558,6 +26526,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -24240,6 +27239,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -24932,6 +27962,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -25608,6 +28669,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -26333,6 +29425,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -27044,6 +30167,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -27745,6 +30899,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -28535,6 +31720,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -29210,6 +32426,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -29924,6 +33171,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -30623,6 +33901,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -31377,6 +34686,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -32053,6 +35393,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -32737,6 +36108,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -33411,6 +36813,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -34091,6 +37524,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -34771,6 +38235,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -35451,6 +38946,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -36145,6 +39671,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -36821,6 +40378,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -37526,6 +41114,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -38214,6 +41833,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { @@ -41594,6 +45244,37 @@ ], "type": "number" }, + "ConnectedAccountTokenData": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "expires_at": { + "type": "integer" + }, + "fetched_at": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "access_token", + "fetched_at" + ] + }, "ChannelModifySchema": { "type": "object", "properties": { diff --git a/package-lock.json b/package-lock.json
index 8f9d26f6..f7a81eb0 100644 --- a/package-lock.json +++ b/package-lock.json
@@ -46,11 +46,11 @@ "probe-image-size": "^7.2.3", "proxy-agent": "^5.0.0", "reflect-metadata": "^0.1.13", - "sqlite3": "^5.1.5", "ts-node": "^10.9.1", "tslib": "^2.4.1", "typeorm": "^0.3.10", "typescript-json-schema": "^0.50.1", + "wretch": "^2.3.2", "ws": "^8.9.0" }, "devDependencies": { @@ -7989,6 +7989,14 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/wretch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/wretch/-/wretch-2.3.2.tgz", + "integrity": "sha512-brN97Z2Mwed+w5z+keYI1u5OwWhPIaW0sJi9CxtKBVxLc3aqP6j1+2FCoIskM7WJq6SUHdxTFx20ox0iDLa0mQ==", + "engines": { + "node": ">=14" + } + }, "node_modules/ws": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", @@ -14170,6 +14178,11 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "wretch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/wretch/-/wretch-2.3.2.tgz", + "integrity": "sha512-brN97Z2Mwed+w5z+keYI1u5OwWhPIaW0sJi9CxtKBVxLc3aqP6j1+2FCoIskM7WJq6SUHdxTFx20ox0iDLa0mQ==" + }, "ws": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", diff --git a/package.json b/package.json
index 3780b2bb..16f3c87f 100644 --- a/package.json +++ b/package.json
@@ -105,6 +105,7 @@ "tslib": "^2.4.1", "typeorm": "^0.3.10", "typescript-json-schema": "^0.50.1", + "wretch": "^2.3.2", "ws": "^8.9.0" }, "_moduleAliases": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644
index 00000000..f5fbb88d --- /dev/null +++ b/pnpm-lock.yaml
@@ -0,0 +1,5745 @@ +lockfileVersion: 5.4 + +specifiers: + "@aws-sdk/client-s3": ^3.178.0 + "@sentry/integrations": ^7.17.2 + "@sentry/node": ^7.17.2 + "@sentry/tracing": ^7.17.2 + "@types/amqplib": ^0.8.2 + "@types/bcrypt": ^5.0.0 + "@types/body-parser": ^1.19.2 + "@types/cookie-parser": ^1.4.3 + "@types/express": ^4.17.15 + "@types/i18next-node-fs-backend": ^2.1.1 + "@types/json-bigint": ^1.0.1 + "@types/jsonwebtoken": ^8.5.9 + "@types/morgan": ^1.9.3 + "@types/multer": ^1.4.7 + "@types/node": ^18.7.20 + "@types/node-fetch": ^2.6.2 + "@types/node-os-utils": ^1.3.0 + "@types/probe-image-size": ^7.2.0 + "@types/sharp": ^0.31.0 + "@types/ws": ^8.5.3 + "@yukikaze-bot/erlpack": ^1.0.1 + ajv: 8.6.2 + ajv-formats: 2.1.1 + amqplib: ^0.10.3 + bcrypt: ^5.0.1 + body-parser: 1.20.1 + cheerio: ^1.0.0-rc.12 + cookie-parser: ^1.4.6 + dotenv: ^16.0.2 + exif-be-gone: ^1.3.1 + express: ^4.18.1 + fast-zlib: ^2.0.1 + file-type: "16.5" + form-data: ^4.0.0 + husky: ^8.0.0 + i18next: ^21.9.2 + i18next-http-middleware: ^3.2.1 + i18next-node-fs-backend: ^2.1.3 + image-size: ^1.0.2 + json-bigint: ^1.0.0 + jsonwebtoken: ^8.5.1 + lambert-server: ^1.2.12 + missing-native-js-functions: ^1.2.18 + module-alias: ^2.2.2 + morgan: ^1.10.0 + multer: ^1.4.5-lts.1 + node-2fa: ^2.0.3 + node-fetch: ^2.6.7 + node-os-utils: ^1.3.7 + picocolors: ^1.0.0 + prettier: ^2.7.1 + pretty-quick: ^3.1.3 + probe-image-size: ^7.2.3 + proxy-agent: ^5.0.0 + reflect-metadata: ^0.1.13 + sqlite3: ^5.1.4 + ts-node: ^10.9.1 + tslib: ^2.4.1 + typeorm: ^0.3.10 + typescript: ^4.8.3 + typescript-json-schema: ^0.50.1 + wretch: ^2.3.2 + ws: ^8.9.0 + +dependencies: + "@aws-sdk/client-s3": 3.245.0 + "@sentry/integrations": 7.30.0 + "@sentry/node": 7.30.0 + "@sentry/tracing": 7.30.0 + ajv: 8.6.2 + ajv-formats: 2.1.1_ajv@8.6.2 + amqplib: 0.10.3 + bcrypt: 5.1.0 + body-parser: 1.20.1 + cheerio: 1.0.0-rc.12 + cookie-parser: 1.4.6 + dotenv: 16.0.3 + exif-be-gone: 1.3.2 + fast-zlib: 2.0.1 + file-type: 16.5.4 + form-data: 4.0.0 + i18next: 21.10.0 + i18next-http-middleware: 3.2.1 + i18next-node-fs-backend: 2.1.3 + image-size: 1.0.2 + json-bigint: 1.0.0 + jsonwebtoken: 8.5.1 + lambert-server: 1.2.12 + missing-native-js-functions: 1.3.1 + module-alias: 2.2.2 + morgan: 1.10.0 + multer: 1.4.5-lts.1 + node-2fa: 2.0.3 + node-fetch: 2.6.7 + node-os-utils: 1.3.7 + picocolors: 1.0.0 + probe-image-size: 7.2.3 + proxy-agent: 5.0.0 + reflect-metadata: 0.1.13 + sqlite3: 5.1.4 + ts-node: 10.9.1_awa2wsr5thmg3i7jqycphctjfq + tslib: 2.4.1 + typeorm: 0.3.11_h3l5zcb3i6sggvllyfknv6gs44 + typescript-json-schema: 0.50.1 + wretch: 2.3.2 + ws: 8.12.0 + +optionalDependencies: + "@yukikaze-bot/erlpack": 1.0.1 + +devDependencies: + "@types/amqplib": 0.8.2 + "@types/bcrypt": 5.0.0 + "@types/body-parser": 1.19.2 + "@types/cookie-parser": 1.4.3 + "@types/express": 4.17.15 + "@types/i18next-node-fs-backend": 2.1.1 + "@types/json-bigint": 1.0.1 + "@types/jsonwebtoken": 8.5.9 + "@types/morgan": 1.9.4 + "@types/multer": 1.4.7 + "@types/node": 18.11.18 + "@types/node-fetch": 2.6.2 + "@types/node-os-utils": 1.3.0 + "@types/probe-image-size": 7.2.0 + "@types/sharp": 0.31.1 + "@types/ws": 8.5.4 + express: 4.18.2 + husky: 8.0.3 + prettier: 2.8.2 + pretty-quick: 3.1.3_prettier@2.8.2 + typescript: 4.9.4 + +packages: + /@acuminous/bitsyntax/0.1.2: + resolution: + { + integrity: sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==, + } + engines: { node: ">=0.8" } + dependencies: + buffer-more-ints: 1.0.0 + debug: 4.3.4 + safe-buffer: 5.1.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@aws-crypto/crc32/2.0.0: + resolution: + { + integrity: sha512-TvE1r2CUueyXOuHdEigYjIZVesInd9KN+K/TFFNfkkxRThiNxO6i4ZqqAVMoEjAamZZ1AA8WXJkjCz7YShHPQA==, + } + dependencies: + "@aws-crypto/util": 2.0.2 + "@aws-sdk/types": 3.226.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/crc32c/2.0.0: + resolution: + { + integrity: sha512-vF0eMdMHx3O3MoOXUfBZry8Y4ZDtcuskjjKgJz8YfIDjLStxTZrYXk+kZqtl6A0uCmmiN/Eb/JbC/CndTV1MHg==, + } + dependencies: + "@aws-crypto/util": 2.0.2 + "@aws-sdk/types": 3.226.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/ie11-detection/2.0.2: + resolution: + { + integrity: sha512-5XDMQY98gMAf/WRTic5G++jfmS/VLM0rwpiOpaainKi4L0nqWMSB1SzsrEG5rjFZGYN6ZAefO+/Yta2dFM0kMw==, + } + dependencies: + tslib: 1.14.1 + dev: false + + /@aws-crypto/sha1-browser/2.0.0: + resolution: + { + integrity: sha512-3fIVRjPFY8EG5HWXR+ZJZMdWNRpwbxGzJ9IH9q93FpbgCH8u8GHRi46mZXp3cYD7gealmyqpm3ThZwLKJjWJhA==, + } + dependencies: + "@aws-crypto/ie11-detection": 2.0.2 + "@aws-crypto/supports-web-crypto": 2.0.2 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-locate-window": 3.208.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/sha256-browser/2.0.0: + resolution: + { + integrity: sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==, + } + dependencies: + "@aws-crypto/ie11-detection": 2.0.2 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-crypto/supports-web-crypto": 2.0.2 + "@aws-crypto/util": 2.0.2 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-locate-window": 3.208.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/sha256-js/2.0.0: + resolution: + { + integrity: sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==, + } + dependencies: + "@aws-crypto/util": 2.0.2 + "@aws-sdk/types": 3.226.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/supports-web-crypto/2.0.2: + resolution: + { + integrity: sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==, + } + dependencies: + tslib: 1.14.1 + dev: false + + /@aws-crypto/util/2.0.2: + resolution: + { + integrity: sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==, + } + dependencies: + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + tslib: 1.14.1 + dev: false + + /@aws-sdk/abort-controller/3.226.0: + resolution: + { + integrity: sha512-cJVzr1xxPBd08voknXvR0RLgtZKGKt6WyDpH/BaPCu3rfSqWCDZKzwqe940eqosjmKrxC6pUZNKASIqHOQ8xxQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/chunked-blob-reader-native/3.208.0: + resolution: + { + integrity: sha512-JeOZ95PW+fJ6bbuqPySYqLqHk1n4+4ueEEraJsiUrPBV0S1ZtyvOGHcnGztKUjr2PYNaiexmpWuvUve9K12HRA==, + } + dependencies: + "@aws-sdk/util-base64": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/chunked-blob-reader/3.188.0: + resolution: + { + integrity: sha512-zkPRFZZPL3eH+kH86LDYYXImiClA1/sW60zYOjse9Pgka+eDJlvBN6hcYxwDEKjcwATYiSRR1aVQHcfCinlGXg==, + } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/client-s3/3.245.0: + resolution: + { + integrity: sha512-wdCrEiqIfwtWebrK7A1giRggwO64S6I2iPXTwRmat4AR6sFlMO02jVFaIDyA8TTiVnBMz7ekT1QFmIjFAKc4uQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-crypto/sha1-browser": 2.0.0 + "@aws-crypto/sha256-browser": 2.0.0 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-sdk/client-sts": 3.245.0 + "@aws-sdk/config-resolver": 3.234.0 + "@aws-sdk/credential-provider-node": 3.245.0 + "@aws-sdk/eventstream-serde-browser": 3.226.0 + "@aws-sdk/eventstream-serde-config-resolver": 3.226.0 + "@aws-sdk/eventstream-serde-node": 3.226.0 + "@aws-sdk/fetch-http-handler": 3.226.0 + "@aws-sdk/hash-blob-browser": 3.226.0 + "@aws-sdk/hash-node": 3.226.0 + "@aws-sdk/hash-stream-node": 3.226.0 + "@aws-sdk/invalid-dependency": 3.226.0 + "@aws-sdk/md5-js": 3.226.0 + "@aws-sdk/middleware-bucket-endpoint": 3.226.0 + "@aws-sdk/middleware-content-length": 3.226.0 + "@aws-sdk/middleware-endpoint": 3.226.0 + "@aws-sdk/middleware-expect-continue": 3.226.0 + "@aws-sdk/middleware-flexible-checksums": 3.226.0 + "@aws-sdk/middleware-host-header": 3.226.0 + "@aws-sdk/middleware-location-constraint": 3.226.0 + "@aws-sdk/middleware-logger": 3.226.0 + "@aws-sdk/middleware-recursion-detection": 3.226.0 + "@aws-sdk/middleware-retry": 3.235.0 + "@aws-sdk/middleware-sdk-s3": 3.231.0 + "@aws-sdk/middleware-serde": 3.226.0 + "@aws-sdk/middleware-signing": 3.226.0 + "@aws-sdk/middleware-ssec": 3.226.0 + "@aws-sdk/middleware-stack": 3.226.0 + "@aws-sdk/middleware-user-agent": 3.226.0 + "@aws-sdk/node-config-provider": 3.226.0 + "@aws-sdk/node-http-handler": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/signature-v4-multi-region": 3.226.0 + "@aws-sdk/smithy-client": 3.234.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/url-parser": 3.226.0 + "@aws-sdk/util-base64": 3.208.0 + "@aws-sdk/util-body-length-browser": 3.188.0 + "@aws-sdk/util-body-length-node": 3.208.0 + "@aws-sdk/util-defaults-mode-browser": 3.234.0 + "@aws-sdk/util-defaults-mode-node": 3.234.0 + "@aws-sdk/util-endpoints": 3.245.0 + "@aws-sdk/util-retry": 3.229.0 + "@aws-sdk/util-stream-browser": 3.226.0 + "@aws-sdk/util-stream-node": 3.226.0 + "@aws-sdk/util-user-agent-browser": 3.226.0 + "@aws-sdk/util-user-agent-node": 3.226.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + "@aws-sdk/util-utf8-node": 3.208.0 + "@aws-sdk/util-waiter": 3.226.0 + "@aws-sdk/xml-builder": 3.201.0 + fast-xml-parser: 4.0.11 + tslib: 2.4.1 + transitivePeerDependencies: + - "@aws-sdk/signature-v4-crt" + - aws-crt + dev: false + + /@aws-sdk/client-sso-oidc/3.245.0: + resolution: + { + integrity: sha512-0pGPA00kEsu2Yq1Ul+OwftHxws5YVllm4iZrPtGnqmXr7wmf6B9lOtrMQF44y7Tfw53po6+bKz08OKTEWkkjUA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-crypto/sha256-browser": 2.0.0 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-sdk/config-resolver": 3.234.0 + "@aws-sdk/fetch-http-handler": 3.226.0 + "@aws-sdk/hash-node": 3.226.0 + "@aws-sdk/invalid-dependency": 3.226.0 + "@aws-sdk/middleware-content-length": 3.226.0 + "@aws-sdk/middleware-endpoint": 3.226.0 + "@aws-sdk/middleware-host-header": 3.226.0 + "@aws-sdk/middleware-logger": 3.226.0 + "@aws-sdk/middleware-recursion-detection": 3.226.0 + "@aws-sdk/middleware-retry": 3.235.0 + "@aws-sdk/middleware-serde": 3.226.0 + "@aws-sdk/middleware-stack": 3.226.0 + "@aws-sdk/middleware-user-agent": 3.226.0 + "@aws-sdk/node-config-provider": 3.226.0 + "@aws-sdk/node-http-handler": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/smithy-client": 3.234.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/url-parser": 3.226.0 + "@aws-sdk/util-base64": 3.208.0 + "@aws-sdk/util-body-length-browser": 3.188.0 + "@aws-sdk/util-body-length-node": 3.208.0 + "@aws-sdk/util-defaults-mode-browser": 3.234.0 + "@aws-sdk/util-defaults-mode-node": 3.234.0 + "@aws-sdk/util-endpoints": 3.245.0 + "@aws-sdk/util-retry": 3.229.0 + "@aws-sdk/util-user-agent-browser": 3.226.0 + "@aws-sdk/util-user-agent-node": 3.226.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + "@aws-sdk/util-utf8-node": 3.208.0 + tslib: 2.4.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sso/3.245.0: + resolution: + { + integrity: sha512-dxzRwRo55ZNQ4hQigC+cishxLSWlBrbr3iszG0FLviavLDOlnVG5UUxWpOIGvwr8pYiSfM4jnfMxiwYwiCLg1g==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-crypto/sha256-browser": 2.0.0 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-sdk/config-resolver": 3.234.0 + "@aws-sdk/fetch-http-handler": 3.226.0 + "@aws-sdk/hash-node": 3.226.0 + "@aws-sdk/invalid-dependency": 3.226.0 + "@aws-sdk/middleware-content-length": 3.226.0 + "@aws-sdk/middleware-endpoint": 3.226.0 + "@aws-sdk/middleware-host-header": 3.226.0 + "@aws-sdk/middleware-logger": 3.226.0 + "@aws-sdk/middleware-recursion-detection": 3.226.0 + "@aws-sdk/middleware-retry": 3.235.0 + "@aws-sdk/middleware-serde": 3.226.0 + "@aws-sdk/middleware-stack": 3.226.0 + "@aws-sdk/middleware-user-agent": 3.226.0 + "@aws-sdk/node-config-provider": 3.226.0 + "@aws-sdk/node-http-handler": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/smithy-client": 3.234.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/url-parser": 3.226.0 + "@aws-sdk/util-base64": 3.208.0 + "@aws-sdk/util-body-length-browser": 3.188.0 + "@aws-sdk/util-body-length-node": 3.208.0 + "@aws-sdk/util-defaults-mode-browser": 3.234.0 + "@aws-sdk/util-defaults-mode-node": 3.234.0 + "@aws-sdk/util-endpoints": 3.245.0 + "@aws-sdk/util-retry": 3.229.0 + "@aws-sdk/util-user-agent-browser": 3.226.0 + "@aws-sdk/util-user-agent-node": 3.226.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + "@aws-sdk/util-utf8-node": 3.208.0 + tslib: 2.4.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sts/3.245.0: + resolution: + { + integrity: sha512-E+7v2sy34TLni/Dmz6bTU20NWvbHYH9sVUHKQ9kHhmFopUWrs4Nt77f85PbuiKJz/irjUh9ppT5q1odJNRKRVQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-crypto/sha256-browser": 2.0.0 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-sdk/config-resolver": 3.234.0 + "@aws-sdk/credential-provider-node": 3.245.0 + "@aws-sdk/fetch-http-handler": 3.226.0 + "@aws-sdk/hash-node": 3.226.0 + "@aws-sdk/invalid-dependency": 3.226.0 + "@aws-sdk/middleware-content-length": 3.226.0 + "@aws-sdk/middleware-endpoint": 3.226.0 + "@aws-sdk/middleware-host-header": 3.226.0 + "@aws-sdk/middleware-logger": 3.226.0 + "@aws-sdk/middleware-recursion-detection": 3.226.0 + "@aws-sdk/middleware-retry": 3.235.0 + "@aws-sdk/middleware-sdk-sts": 3.226.0 + "@aws-sdk/middleware-serde": 3.226.0 + "@aws-sdk/middleware-signing": 3.226.0 + "@aws-sdk/middleware-stack": 3.226.0 + "@aws-sdk/middleware-user-agent": 3.226.0 + "@aws-sdk/node-config-provider": 3.226.0 + "@aws-sdk/node-http-handler": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/smithy-client": 3.234.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/url-parser": 3.226.0 + "@aws-sdk/util-base64": 3.208.0 + "@aws-sdk/util-body-length-browser": 3.188.0 + "@aws-sdk/util-body-length-node": 3.208.0 + "@aws-sdk/util-defaults-mode-browser": 3.234.0 + "@aws-sdk/util-defaults-mode-node": 3.234.0 + "@aws-sdk/util-endpoints": 3.245.0 + "@aws-sdk/util-retry": 3.229.0 + "@aws-sdk/util-user-agent-browser": 3.226.0 + "@aws-sdk/util-user-agent-node": 3.226.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + "@aws-sdk/util-utf8-node": 3.208.0 + fast-xml-parser: 4.0.11 + tslib: 2.4.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/config-resolver/3.234.0: + resolution: + { + integrity: sha512-uZxy4wzllfvgCQxVc+Iqhde0NGAnfmV2hWR6ejadJaAFTuYNvQiRg9IqJy3pkyDPqXySiJ8Bom5PoJfgn55J/A==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/signature-v4": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-config-provider": 3.208.0 + "@aws-sdk/util-middleware": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/credential-provider-env/3.226.0: + resolution: + { + integrity: sha512-sd8uK1ojbXxaZXlthzw/VXZwCPUtU3PjObOfr3Evj7MPIM2IH8h29foOlggx939MdLQGboJf9gKvLlvKDWtJRA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/credential-provider-imds/3.226.0: + resolution: + { + integrity: sha512-//z/COQm2AjYFI1Lb0wKHTQSrvLFTyuKLFQGPJsKS7DPoxGOCKB7hmYerlbl01IDoCxTdyL//TyyPxbZEOQD5Q==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/node-config-provider": 3.226.0 + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/url-parser": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/credential-provider-ini/3.245.0: + resolution: + { + integrity: sha512-1SjfVc5Wg0lLRUvwMrfjGgFkl+zfxn74gnkPr6by1QyMAoTzmeUkalPLAIqd+uHtFom9e3K633BQtX7zVPZ5XQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/credential-provider-env": 3.226.0 + "@aws-sdk/credential-provider-imds": 3.226.0 + "@aws-sdk/credential-provider-process": 3.226.0 + "@aws-sdk/credential-provider-sso": 3.245.0 + "@aws-sdk/credential-provider-web-identity": 3.226.0 + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/shared-ini-file-loader": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-node/3.245.0: + resolution: + { + integrity: sha512-Dwv8zmRLTDLeEkGrK/sLNFZSC+ahXZxr07CuID054QKACIdUEvkqYlnalRiTeXngiHGQ54u8wU7f0D32R2oL0g==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/credential-provider-env": 3.226.0 + "@aws-sdk/credential-provider-imds": 3.226.0 + "@aws-sdk/credential-provider-ini": 3.245.0 + "@aws-sdk/credential-provider-process": 3.226.0 + "@aws-sdk/credential-provider-sso": 3.245.0 + "@aws-sdk/credential-provider-web-identity": 3.226.0 + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/shared-ini-file-loader": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-process/3.226.0: + resolution: + { + integrity: sha512-iUDMdnrTvbvaCFhWwqyXrhvQ9+ojPqPqXhwZtY1X/Qaz+73S9gXBPJHZaZb2Ke0yKE1Ql3bJbKvmmxC/qLQMng==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/shared-ini-file-loader": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/credential-provider-sso/3.245.0: + resolution: + { + integrity: sha512-txWrJc0WNBhXMi7q+twjx7cs/qzgTfbQ+vbag5idRmdoUeiR8rfLvihCab2NaGg50xhh+TaoUCXrgJp3E/XjYQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/client-sso": 3.245.0 + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/shared-ini-file-loader": 3.226.0 + "@aws-sdk/token-providers": 3.245.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-web-identity/3.226.0: + resolution: + { + integrity: sha512-CCpv847rLB0SFOHz2igvUMFAzeT2fD3YnY4C8jltuJoEkn0ITn1Hlgt13nTJ5BUuvyti2mvyXZHmNzhMIMrIlw==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/eventstream-codec/3.226.0: + resolution: + { + integrity: sha512-6uPtR8vSwz3fqoZk9hrb6qBYdp3PJ22+JxV5Wimdesvow4kJXSgDQXIxEkxbv6SxB9tNRB4uJHD84RetHEi15Q==, + } + dependencies: + "@aws-crypto/crc32": 2.0.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-hex-encoding": 3.201.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/eventstream-serde-browser/3.226.0: + resolution: + { + integrity: sha512-otYC5aZE9eJUqAlKpy8w0rPDQ1eKGvZPtgxWXmFYSO2lDVGfI1nBBNmdZ4MdHqNuQ7ucsKMQYF8BFJ65K2tYPA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/eventstream-serde-universal": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/eventstream-serde-config-resolver/3.226.0: + resolution: + { + integrity: sha512-A56Gypg+lyEfA5cna+EUH9XTrj0SvRG1gwNW7lrUzviN36SeA/LFTUIOEjxVML3Lowy+EPAcrSZ67h6aepoAig==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/eventstream-serde-node/3.226.0: + resolution: + { + integrity: sha512-KWLnKkKDzI9RNkiK6OiSYpG/XjZfue6Bsp/vRG+H5z3fbXdHv4X2+iW+Efu2Kvn7jsUyUv82TCl57DyJ/HKYhQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/eventstream-serde-universal": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/eventstream-serde-universal/3.226.0: + resolution: + { + integrity: sha512-Q8viYM1Sv90/yIUqyWNeG1GEvyVlAI3GIrInQcCMC+xT59jS+IKGy2y7ojCvSWXnhf5/HMXKcmG092QsqeKy0Q==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/eventstream-codec": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/fetch-http-handler/3.226.0: + resolution: + { + integrity: sha512-JewZPMNEBXfi1xVnRa7pVtK/zgZD8/lQ/YnD8pq79WuMa2cwyhDtr8oqCoqsPW+WJT5ScXoMtuHxN78l8eKWgg==, + } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/querystring-builder": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-base64": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/hash-blob-browser/3.226.0: + resolution: + { + integrity: sha512-5DCvWE6L4xGoViEHyjcPFuUe1G2EtNx8TqswWaoaKgyasP/yuRm4H99Ra7rqIrjCcSTAGD9NVsUQvVVw1bGt9w==, + } + dependencies: + "@aws-sdk/chunked-blob-reader": 3.188.0 + "@aws-sdk/chunked-blob-reader-native": 3.208.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/hash-node/3.226.0: + resolution: + { + integrity: sha512-MdlJhJ9/Espwd0+gUXdZRsHuostB2WxEVAszWxobP0FTT9PnicqnfK7ExmW+DUAc0ywxtEbR3e0UND65rlSTVw==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-buffer-from": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/hash-stream-node/3.226.0: + resolution: + { + integrity: sha512-cgNTGlF8SdHaQXtjEmuLXz2U8SLM2JDKtIVPku/lHTMsUsEn+fuv2C+h1f/hvd4aNw5t1zggym7sO1/h/rv56Q==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/invalid-dependency/3.226.0: + resolution: + { + integrity: sha512-QXOYFmap8g9QzRjumcRCIo2GEZkdCwd7ePQW0OABWPhKHzlJ74vvBxywjU3s39EEBEluWXtZ7Iufg6GxZM4ifw==, + } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/is-array-buffer/3.201.0: + resolution: + { + integrity: sha512-UPez5qLh3dNgt0DYnPD/q0mVJY84rA17QE26hVNOW3fAji8W2wrwrxdacWOxyXvlxWsVRcKmr+lay1MDqpAMfg==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/md5-js/3.226.0: + resolution: + { + integrity: sha512-ENigJRNudqyh6xsch166SZ4gggHd3XzZJ8gkCU4CWPne04HcR3BkWSO774IuWooCHt8zkaEHKecPurRz6qR+Vw==, + } + dependencies: + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + "@aws-sdk/util-utf8-node": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-bucket-endpoint/3.226.0: + resolution: + { + integrity: sha512-A1Vq5W2X7jgTfjqcKPmjoHohF0poP+9fxwL97fQMvzcwmjhtoCV3bLEpo6CGYx0pKPiSlRJXZkRwRPj2hDHDmA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-arn-parser": 3.208.0 + "@aws-sdk/util-config-provider": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-content-length/3.226.0: + resolution: + { + integrity: sha512-ksUzlHJN2JMuyavjA46a4sctvnrnITqt2tbGGWWrAuXY1mel2j+VbgnmJUiwHKUO6bTFBBeft5Vd1TSOb4JmiA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-endpoint/3.226.0: + resolution: + { + integrity: sha512-EvLFafjtUxTT0AC9p3aBQu1/fjhWdIeK58jIXaNFONfZ3F8QbEYUPuF/SqZvJM6cWfOO9qwYKkRDbCSTYhprIg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/middleware-serde": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/signature-v4": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/url-parser": 3.226.0 + "@aws-sdk/util-config-provider": 3.208.0 + "@aws-sdk/util-middleware": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-expect-continue/3.226.0: + resolution: + { + integrity: sha512-YxvQKTV/eA9P8AgW0hXOgj5Qa+TSnNFfyOkfeP089aP3f6p92b1cESf33TEOKsddive2mHT5LRCN6MuPcgWWrA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-flexible-checksums/3.226.0: + resolution: + { + integrity: sha512-8A9Ot9A7794UP5tMGl2MnfTW/UM/jYy1wRWF9YkR/hPIcPb7OmE0hmlwIQGzb/7grxpYw66ETKf0WeH/41YfeQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-crypto/crc32": 2.0.0 + "@aws-crypto/crc32c": 2.0.0 + "@aws-sdk/is-array-buffer": 3.201.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-host-header/3.226.0: + resolution: + { + integrity: sha512-haVkWVh6BUPwKgWwkL6sDvTkcZWvJjv8AgC8jiQuSl8GLZdzHTB8Qhi3IsfFta9HAuoLjxheWBE5Z/L0UrfhLA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-location-constraint/3.226.0: + resolution: + { + integrity: sha512-qHiYaBYPc2R37KxG2uqsUUwh4usrQMHfGkrpTUnx5d4rGzM3mC+muPsTpSHnAL63K2/yJOHQJFjss3GGwV4SSA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-logger/3.226.0: + resolution: + { + integrity: sha512-m9gtLrrYnpN6yckcQ09rV7ExWOLMuq8mMPF/K3DbL/YL0TuILu9i2T1W+JuxSX+K9FMG2HrLAKivE/kMLr55xA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-recursion-detection/3.226.0: + resolution: + { + integrity: sha512-mwRbdKEUeuNH5TEkyZ5FWxp6bL2UC1WbY+LDv6YjHxmSMKpAoOueEdtU34PqDOLrpXXxIGHDFmjeGeMfktyEcA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-retry/3.235.0: + resolution: + { + integrity: sha512-50WHbJGpD3SNp9763MAlHqIhXil++JdQbKejNpHg7HsJne/ao3ub+fDOfx//mMBjpzBV25BGd5UlfL6blrClSg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/service-error-classification": 3.229.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-middleware": 3.226.0 + "@aws-sdk/util-retry": 3.229.0 + tslib: 2.4.1 + uuid: 8.3.2 + dev: false + + /@aws-sdk/middleware-sdk-s3/3.231.0: + resolution: + { + integrity: sha512-UGaSvevd2TanfKgStF46dDSHkh4bxOr1gdUkyHm9i+1pF5lx4KdbnBZv/5SKnn7XifhHRXrs1M3lTzemXREhTA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-arn-parser": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-sdk-sts/3.226.0: + resolution: + { + integrity: sha512-NN9T/qoSD1kZvAT+VLny3NnlqgylYQcsgV3rvi/8lYzw/G/2s8VS6sm/VTWGGZhx08wZRv20MWzYu3bftcyqUg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/middleware-signing": 3.226.0 + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/signature-v4": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-serde/3.226.0: + resolution: + { + integrity: sha512-nPuOOAkSfx9TxzdKFx0X2bDlinOxGrqD7iof926K/AEflxGD1DBdcaDdjlYlPDW2CVE8LV/rAgbYuLxh/E/1VA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-signing/3.226.0: + resolution: + { + integrity: sha512-E6HmtPcl+IjYDDzi1xI2HpCbBq2avNWcjvCriMZWuTAtRVpnA6XDDGW5GY85IfS3A8G8vuWqEVPr8JcYUcjfew==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/signature-v4": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-middleware": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-ssec/3.226.0: + resolution: + { + integrity: sha512-DR97oWoLHiMdaUP/wu99HtzG7/ijvCrjZGDH37WBO1rxFtEti6L7T09wgHzwxMN8gtL8FJA7dU8IrffGSC9VmA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-stack/3.226.0: + resolution: + { + integrity: sha512-85wF29LvPvpoed60fZGDYLwv1Zpd/cM0C22WSSFPw1SSJeqO4gtFYyCg2squfT3KI6kF43IIkOCJ+L7GtryPug==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/middleware-user-agent/3.226.0: + resolution: + { + integrity: sha512-N1WnfzCW1Y5yWhVAphf8OPGTe8Df3vmV7/LdsoQfmpkCZgLZeK2o0xITkUQhRj1mbw7yp8tVFLFV3R2lMurdAQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/node-config-provider/3.226.0: + resolution: + { + integrity: sha512-B8lQDqiRk7X5izFEUMXmi8CZLOKCTWQJU9HQf3ako+sF0gexo4nHN3jhoRWyLtcgC5S3on/2jxpAcqtm7kuY3w==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/shared-ini-file-loader": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/node-http-handler/3.226.0: + resolution: + { + integrity: sha512-xQCddnZNMiPmjr3W7HYM+f5ir4VfxgJh37eqZwX6EZmyItFpNNeVzKUgA920ka1VPz/ZUYB+2OFGiX3LCLkkaA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/abort-controller": 3.226.0 + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/querystring-builder": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/property-provider/3.226.0: + resolution: + { + integrity: sha512-TsljjG+Sg0LmdgfiAlWohluWKnxB/k8xenjeozZfzOr5bHmNHtdbWv6BtNvD/R83hw7SFXxbJHlD5H4u9p2NFg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/protocol-http/3.226.0: + resolution: + { + integrity: sha512-zWkVqiTA9RXL6y0hhfZc9bcU4DX2NI6Hw9IhQmSPeM59mdbPjJlY4bLlMr5YxywqO3yQ/ylNoAfrEzrDjlOSRg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/querystring-builder/3.226.0: + resolution: + { + integrity: sha512-LVurypuNeotO4lmirKXRC4NYrZRAyMJXuwO0f2a5ZAUJCjauwYrifKue6yCfU7bls7gut7nfcR6B99WBYpHs3g==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-uri-escape": 3.201.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/querystring-parser/3.226.0: + resolution: + { + integrity: sha512-FzB+VrQ47KAFxiPt2YXrKZ8AOLZQqGTLCKHzx4bjxGmwgsjV8yIbtJiJhZLMcUQV4LtGeIY9ixIqQhGvnZHE4A==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/service-error-classification/3.229.0: + resolution: + { + integrity: sha512-dnzWWQ0/NoWMUZ5C0DW3dPm0wC1O76Y/SpKbuJzWPkx1EYy6r8p32Ly4D9vUzrKDbRGf48YHIF2kOkBmu21CLg==, + } + engines: { node: ">=14.0.0" } + dev: false + + /@aws-sdk/shared-ini-file-loader/3.226.0: + resolution: + { + integrity: sha512-661VQefsARxVyyV2FX9V61V+nNgImk7aN2hYlFKla6BCwZfMng+dEtD0xVGyg1PfRw0qvEv5LQyxMVgHcUSevA==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/signature-v4-multi-region/3.226.0: + resolution: + { + integrity: sha512-QHxNuf9ynK208v7Y3imdsa3Cz8ynYV7ZOf3sBJdItuEtHN6uy/KxaOrtvpF8I5Hyn48Hc8z5miTSMujFKT7GEw==, + } + engines: { node: ">=14.0.0" } + peerDependencies: + "@aws-sdk/signature-v4-crt": ^3.118.0 + peerDependenciesMeta: + "@aws-sdk/signature-v4-crt": + optional: true + dependencies: + "@aws-sdk/protocol-http": 3.226.0 + "@aws-sdk/signature-v4": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-arn-parser": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/signature-v4/3.226.0: + resolution: + { + integrity: sha512-/R5q5agdPd7HJB68XMzpxrNPk158EHUvkFkuRu5Qf3kkkHebEzWEBlWoVpUe6ss4rP9Tqcue6xPuaftEmhjpYw==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/is-array-buffer": 3.201.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-hex-encoding": 3.201.0 + "@aws-sdk/util-middleware": 3.226.0 + "@aws-sdk/util-uri-escape": 3.201.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/smithy-client/3.234.0: + resolution: + { + integrity: sha512-8AtR/k4vsFvjXeQbIzq/Wy7Nbk48Ou0wUEeVYPHWHPSU8QamFWORkOwmKtKMfHAyZvmqiAPeQqHFkq+UJhWyyQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/middleware-stack": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/token-providers/3.245.0: + resolution: + { + integrity: sha512-m/spXR/vEXGb+zMqRUMQYVMwFZSTdK5RkddYqamYkNhIoLm60EYeRu57JsMMs5djKi8dBRSKiXwVHx0l2rXMjg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/client-sso-oidc": 3.245.0 + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/shared-ini-file-loader": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/types/3.226.0: + resolution: + { + integrity: sha512-MmmNHrWeO4man7wpOwrAhXlevqtOV9ZLcH4RhnG5LmRce0RFOApx24HoKENfFCcOyCm5LQBlsXCqi0dZWDWU0A==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/url-parser/3.226.0: + resolution: + { + integrity: sha512-p5RLE0QWyP0OcTOLmFcLdVgUcUEzmEfmdrnOxyNzomcYb0p3vUagA5zfa1HVK2azsQJFBv28GfvMnba9bGhObg==, + } + dependencies: + "@aws-sdk/querystring-parser": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-arn-parser/3.208.0: + resolution: + { + integrity: sha512-QV4af+kscova9dv4VuHOgH8wEr/IIYHDGcnyVtkUEqahCejWr1Kuk+SBK0xMwnZY5LSycOtQ8aeqHOn9qOjZtA==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-base64/3.208.0: + resolution: + { + integrity: sha512-PQniZph5A6N7uuEOQi+1hnMz/FSOK/8kMFyFO+4DgA1dZ5pcKcn5wiFwHkcTb/BsgVqQa3Jx0VHNnvhlS8JyTg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/util-buffer-from": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-body-length-browser/3.188.0: + resolution: + { + integrity: sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg==, + } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-body-length-node/3.208.0: + resolution: + { + integrity: sha512-3zj50e5g7t/MQf53SsuuSf0hEELzMtD8RX8C76f12OSRo2Bca4FLLYHe0TZbxcfQHom8/hOaeZEyTyMogMglqg==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-buffer-from/3.208.0: + resolution: + { + integrity: sha512-7L0XUixNEFcLUGPeBF35enCvB9Xl+K6SQsmbrPk1P3mlV9mguWSDQqbOBwY1Ir0OVbD6H/ZOQU7hI/9RtRI0Zw==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/is-array-buffer": 3.201.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-config-provider/3.208.0: + resolution: + { + integrity: sha512-DSRqwrERUsT34ug+anlMBIFooBEGwM8GejC7q00Y/9IPrQy50KnG5PW2NiTjuLKNi7pdEOlwTSEocJE15eDZIg==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-defaults-mode-browser/3.234.0: + resolution: + { + integrity: sha512-IHMKXjTbOD8XMz5+2oCOsVP94BYb9YyjXdns0aAXr2NAo7k2+RCzXQ2DebJXppGda1F6opFutoKwyVSN0cmbMw==, + } + engines: { node: ">= 10.0.0" } + dependencies: + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/types": 3.226.0 + bowser: 2.11.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-defaults-mode-node/3.234.0: + resolution: + { + integrity: sha512-UGjQ+OjBYYhxFVtUY+jtr0ZZgzZh6OHtYwRhFt8IHewJXFCfZTyfsbX20szBj5y1S4HRIUJ7cwBLIytTqMbI5w==, + } + engines: { node: ">= 10.0.0" } + dependencies: + "@aws-sdk/config-resolver": 3.234.0 + "@aws-sdk/credential-provider-imds": 3.226.0 + "@aws-sdk/node-config-provider": 3.226.0 + "@aws-sdk/property-provider": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-endpoints/3.245.0: + resolution: + { + integrity: sha512-UNOFquB1tKx+8RT8n82Zb5tIwDyZHVPBg/m0LB0RsLETjr6krien5ASpqWezsXKIR1hftN9uaxN4bvf2dZrWHg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-hex-encoding/3.201.0: + resolution: + { + integrity: sha512-7t1vR1pVxKx0motd3X9rI3m/xNp78p3sHtP5yo4NP4ARpxyJ0fokBomY8ScaH2D/B+U5o9ARxldJUdMqyBlJcA==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-locate-window/3.208.0: + resolution: + { + integrity: sha512-iua1A2+P7JJEDHVgvXrRJSvsnzG7stYSGQnBVphIUlemwl6nN5D+QrgbjECtrbxRz8asYFHSzhdhECqN+tFiBg==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-middleware/3.226.0: + resolution: + { + integrity: sha512-B96CQnwX4gRvQdaQkdUtqvDPkrptV5+va6FVeJOocU/DbSYMAScLxtR3peMS8cnlOT6nL1Eoa42OI9AfZz1VwQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-retry/3.229.0: + resolution: + { + integrity: sha512-0zKTqi0P1inD0LzIMuXRIYYQ/8c1lWMg/cfiqUcIAF1TpatlpZuN7umU0ierpBFud7S+zDgg0oemh+Nj8xliJw==, + } + engines: { node: ">= 14.0.0" } + dependencies: + "@aws-sdk/service-error-classification": 3.229.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-stream-browser/3.226.0: + resolution: + { + integrity: sha512-ZvjlA1ySaLd0DqUWTKmL7LsxfPhroAONpzsinaHmw9aZVL40s2cADU9eWgBdHTuAOeFklL7NP0cc6UiTFHKe8g==, + } + dependencies: + "@aws-sdk/fetch-http-handler": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-base64": 3.208.0 + "@aws-sdk/util-hex-encoding": 3.201.0 + "@aws-sdk/util-utf8-browser": 3.188.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-stream-node/3.226.0: + resolution: + { + integrity: sha512-HADXiIgDGoXcCLSKuPnjCLENf0iC0lzqqnymZu9H2FoACZhJB7DvJ9LnP51Pvw9lfCu+yvLzbMqSPdbXtMbRWg==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/node-http-handler": 3.226.0 + "@aws-sdk/types": 3.226.0 + "@aws-sdk/util-buffer-from": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-uri-escape/3.201.0: + resolution: + { + integrity: sha512-TeTWbGx4LU2c5rx0obHeDFeO9HvwYwQtMh1yniBz00pQb6Qt6YVOETVQikRZ+XRQwEyCg/dA375UplIpiy54mA==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-user-agent-browser/3.226.0: + resolution: + { + integrity: sha512-PhBIu2h6sPJPcv2I7ELfFizdl5pNiL4LfxrasMCYXQkJvVnoXztHA1x+CQbXIdtZOIlpjC+6BjDcE0uhnpvfcA==, + } + dependencies: + "@aws-sdk/types": 3.226.0 + bowser: 2.11.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-user-agent-node/3.226.0: + resolution: + { + integrity: sha512-othPc5Dz/pkYkxH+nZPhc1Al0HndQT8zHD4e9h+EZ+8lkd8n+IsnLfTS/mSJWrfiC6UlNRVw55cItstmJyMe/A==, + } + engines: { node: ">=14.0.0" } + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + dependencies: + "@aws-sdk/node-config-provider": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-utf8-browser/3.188.0: + resolution: + { + integrity: sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q==, + } + dependencies: + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-utf8-node/3.208.0: + resolution: + { + integrity: sha512-jKY87Acv0yWBdFxx6bveagy5FYjz+dtV8IPT7ay1E2WPWH1czoIdMAkc8tSInK31T6CRnHWkLZ1qYwCbgRfERQ==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/util-buffer-from": 3.208.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/util-waiter/3.226.0: + resolution: + { + integrity: sha512-qYQMRxnu5k8qQihJXoIWMkBOj0+XkHHj/drLdbRnwL6ni6NcG8++cs9M3DSjIcxmxgF/7SLpDjn1H3sC7cYo4g==, + } + engines: { node: ">=14.0.0" } + dependencies: + "@aws-sdk/abort-controller": 3.226.0 + "@aws-sdk/types": 3.226.0 + tslib: 2.4.1 + dev: false + + /@aws-sdk/xml-builder/3.201.0: + resolution: + { + integrity: sha512-brRdB1wwMgjWEnOQsv7zSUhIQuh7DEicrfslAqHop4S4FtSI3GQAShpQqgOpMTNFYcpaWKmE/Y1MJmNY7xLCnw==, + } + engines: { node: ">=14.0.0" } + dependencies: + tslib: 2.4.1 + dev: false + + /@babel/runtime/7.20.7: + resolution: + { + integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==, + } + engines: { node: ">=6.9.0" } + dependencies: + regenerator-runtime: 0.13.11 + + /@cspotcode/source-map-support/0.8.1: + resolution: + { + integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, + } + engines: { node: ">=12" } + dependencies: + "@jridgewell/trace-mapping": 0.3.9 + dev: false + + /@gar/promisify/1.1.3: + resolution: + { + integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==, + } + dev: false + optional: true + + /@jridgewell/resolve-uri/3.1.0: + resolution: + { + integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==, + } + engines: { node: ">=6.0.0" } + dev: false + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: + { + integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==, + } + dev: false + + /@jridgewell/trace-mapping/0.3.9: + resolution: + { + integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, + } + dependencies: + "@jridgewell/resolve-uri": 3.1.0 + "@jridgewell/sourcemap-codec": 1.4.14 + dev: false + + /@mapbox/node-pre-gyp/1.0.10: + resolution: + { + integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==, + } + hasBin: true + dependencies: + detect-libc: 2.0.1 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.6.7 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.3.8 + tar: 6.1.13 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@npmcli/fs/1.1.1: + resolution: + { + integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==, + } + dependencies: + "@gar/promisify": 1.1.3 + semver: 7.3.8 + dev: false + optional: true + + /@npmcli/move-file/1.1.2: + resolution: + { + integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==, + } + engines: { node: ">=10" } + deprecated: This functionality has been moved to @npmcli/fs + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + dev: false + optional: true + + /@sentry/core/7.30.0: + resolution: + { + integrity: sha512-NeLigkBlpcK63ymM63GoIHurml6V3BUe1Vi+trwm4/qqOTzT7PQhvdJCX+o3+atzRBH+zdb6kd4VWx44Oye3KA==, + } + engines: { node: ">=8" } + dependencies: + "@sentry/types": 7.30.0 + "@sentry/utils": 7.30.0 + tslib: 1.14.1 + dev: false + + /@sentry/integrations/7.30.0: + resolution: + { + integrity: sha512-KU8TnJm1Yldxnhdu/EZcIGXU9ptGQPk6ot4smcNx/mKsy575VrDdyVDx8uIYURWyfsg7eOayt6VdC7ISSODp8A==, + } + engines: { node: ">=8" } + dependencies: + "@sentry/types": 7.30.0 + "@sentry/utils": 7.30.0 + localforage: 1.10.0 + tslib: 1.14.1 + dev: false + + /@sentry/node/7.30.0: + resolution: + { + integrity: sha512-YYasu6C3I0HBP4N1oc/ed2nunxhGJgtAWaKwq3lo8uk3uF6cB1A8+2e0CpjzU5ejhbaFPUBxHyj4th39Bvku/w==, + } + engines: { node: ">=8" } + dependencies: + "@sentry/core": 7.30.0 + "@sentry/types": 7.30.0 + "@sentry/utils": 7.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@sentry/tracing/7.30.0: + resolution: + { + integrity: sha512-bjGeDeKhpGAmLcWcrXFT/xOfHVwp/j0L1aRHzYHnqgTjVzD0NXcooPu/Nz8vF0paxz+hPD5bJwb8kz/ggJzGWQ==, + } + engines: { node: ">=8" } + dependencies: + "@sentry/core": 7.30.0 + "@sentry/types": 7.30.0 + "@sentry/utils": 7.30.0 + tslib: 1.14.1 + dev: false + + /@sentry/types/7.30.0: + resolution: + { + integrity: sha512-l4A86typvt/SfWh5JffpdxNGkg5EEA8m35BzpIcKmCAQZUDmnb4b478r8jdD2uuOjLmPNmZr1tifdRW4NCLuxQ==, + } + engines: { node: ">=8" } + dev: false + + /@sentry/utils/7.30.0: + resolution: + { + integrity: sha512-tSlBhr5u/LdE2emxIDTDmjmyRr99GnZGIAh5GwRxUgeDQ3VEfNUFlyFodBCbZ6yeYTYd6PWNih5xoHn1+Rf3Sw==, + } + engines: { node: ">=8" } + dependencies: + "@sentry/types": 7.30.0 + tslib: 1.14.1 + dev: false + + /@sqltools/formatter/1.2.5: + resolution: + { + integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==, + } + dev: false + + /@tokenizer/token/0.3.0: + resolution: + { + integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==, + } + dev: false + + /@tootallnate/once/1.1.2: + resolution: + { + integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==, + } + engines: { node: ">= 6" } + dev: false + + /@tsconfig/node10/1.0.9: + resolution: + { + integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==, + } + dev: false + + /@tsconfig/node12/1.0.11: + resolution: + { + integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, + } + dev: false + + /@tsconfig/node14/1.0.3: + resolution: + { + integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, + } + dev: false + + /@tsconfig/node16/1.0.3: + resolution: + { + integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==, + } + dev: false + + /@types/amqplib/0.8.2: + resolution: + { + integrity: sha512-p+TFLzo52f8UanB+Nq6gyUi65yecAcRY3nYowU6MPGFtaJvEDxcnFWrxssSTkF+ts1W3zyQDvgVICLQem5WxRA==, + } + dependencies: + "@types/bluebird": 3.5.38 + "@types/node": 18.11.18 + dev: true + + /@types/bcrypt/5.0.0: + resolution: + { + integrity: sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==, + } + dependencies: + "@types/node": 18.11.18 + dev: true + + /@types/bluebird/3.5.38: + resolution: + { + integrity: sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==, + } + dev: true + + /@types/body-parser/1.19.2: + resolution: + { + integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==, + } + dependencies: + "@types/connect": 3.4.35 + "@types/node": 18.11.18 + dev: true + + /@types/connect/3.4.35: + resolution: + { + integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==, + } + dependencies: + "@types/node": 18.11.18 + dev: true + + /@types/cookie-parser/1.4.3: + resolution: + { + integrity: sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==, + } + dependencies: + "@types/express": 4.17.15 + dev: true + + /@types/express-serve-static-core/4.17.32: + resolution: + { + integrity: sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==, + } + dependencies: + "@types/node": 18.11.18 + "@types/qs": 6.9.7 + "@types/range-parser": 1.2.4 + dev: true + + /@types/express/4.17.15: + resolution: + { + integrity: sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==, + } + dependencies: + "@types/body-parser": 1.19.2 + "@types/express-serve-static-core": 4.17.32 + "@types/qs": 6.9.7 + "@types/serve-static": 1.15.0 + dev: true + + /@types/i18next-node-fs-backend/2.1.1: + resolution: + { + integrity: sha512-ESvH90OICQkKU3yuuRzF6YfHt5KACE55FOiUM59mMGnC+h03lHGdEYo3z3THbwS5FdMskLyIs2O7f6Oaz8P9sw==, + } + dependencies: + i18next: 21.10.0 + dev: true + + /@types/json-bigint/1.0.1: + resolution: + { + integrity: sha512-zpchZLNsNuzJHi6v64UBoFWAvQlPhch7XAi36FkH6tL1bbbmimIF+cS7vwkzY4u5RaSWMoflQfu+TshMPPw8uw==, + } + dev: true + + /@types/json-schema/7.0.11: + resolution: + { + integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==, + } + dev: false + + /@types/jsonwebtoken/8.5.9: + resolution: + { + integrity: sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==, + } + dependencies: + "@types/node": 18.11.18 + dev: true + + /@types/mime/3.0.1: + resolution: + { + integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==, + } + dev: true + + /@types/minimatch/3.0.5: + resolution: + { + integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==, + } + dev: true + + /@types/morgan/1.9.4: + resolution: + { + integrity: sha512-cXoc4k+6+YAllH3ZHmx4hf7La1dzUk6keTR4bF4b4Sc0mZxU/zK4wO7l+ZzezXm/jkYj/qC+uYGZrarZdIVvyQ==, + } + dependencies: + "@types/node": 18.11.18 + dev: true + + /@types/multer/1.4.7: + resolution: + { + integrity: sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==, + } + dependencies: + "@types/express": 4.17.15 + dev: true + + /@types/needle/3.2.0: + resolution: + { + integrity: sha512-6XzvzEyJ2ozFNfPajFmqH9JOt0Hp+9TawaYpJT59iIP/zR0U37cfWCRwosyIeEBBZBi021Osq4jGAD3AOju5fg==, + } + dependencies: + "@types/node": 18.11.18 + dev: true + + /@types/node-fetch/2.6.2: + resolution: + { + integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==, + } + dependencies: + "@types/node": 18.11.18 + form-data: 3.0.1 + dev: true + + /@types/node-os-utils/1.3.0: + resolution: + { + integrity: sha512-XwVteWQx/XkfRPyaGkw8dEbrCAkoRZ73pI3XznUYIpzbCfpQB3UnDlR5TnmdhetlT889tUJGF8QWo9xrgTpsiA==, + } + dev: true + + /@types/node/14.18.36: + resolution: + { + integrity: sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==, + } + dev: false + + /@types/node/18.11.18: + resolution: + { + integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==, + } + + /@types/notp/2.0.2: + resolution: + { + integrity: sha512-JUcVYN9Tmw0AjoAfvjslS4hbv39fPBbZdftBK3b50g5z/DmhLsu6cd0UOEBiQuMwy2FirshF2Gk9gAvfWjshMw==, + } + dependencies: + "@types/node": 18.11.18 + dev: false + + /@types/probe-image-size/7.2.0: + resolution: + { + integrity: sha512-R5H3vw62gHNHrn+JGZbKejb+Z2D/6E5UNVlhCzIaBBLroMQMOFqy5Pap2gM+ZZHdqBtVU0/cx/M6to+mOJcoew==, + } + dependencies: + "@types/needle": 3.2.0 + "@types/node": 18.11.18 + dev: true + + /@types/qs/6.9.7: + resolution: + { + integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==, + } + dev: true + + /@types/range-parser/1.2.4: + resolution: + { + integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==, + } + dev: true + + /@types/serve-static/1.15.0: + resolution: + { + integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==, + } + dependencies: + "@types/mime": 3.0.1 + "@types/node": 18.11.18 + dev: true + + /@types/sharp/0.31.1: + resolution: + { + integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==, + } + dependencies: + "@types/node": 18.11.18 + dev: true + + /@types/stream-buffers/3.0.4: + resolution: + { + integrity: sha512-qU/K1tb2yUdhXkLIATzsIPwbtX6BpZk0l3dPW6xqWyhfzzM1ECaQ/8faEnu3CNraLiQ9LHyQQPBGp7N9Fbs25w==, + } + dependencies: + "@types/node": 18.11.18 + dev: false + + /@types/ws/8.5.4: + resolution: + { + integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==, + } + dependencies: + "@types/node": 18.11.18 + dev: true + + /@yukikaze-bot/erlpack/1.0.1: + resolution: + { + integrity: sha512-PCJ2lGCf8DsQtrE411PY+NTsolK48l4InNn1kcBo0iUllKZYGLqeqXEWGA/INrmwanKcoYkU4pBySqUFLQDEoA==, + } + requiresBuild: true + dependencies: + "@mapbox/node-pre-gyp": 1.0.10 + node-addon-api: 4.3.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + optional: true + + /abbrev/1.1.1: + resolution: + { + integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==, + } + dev: false + + /accepts/1.3.8: + resolution: + { + integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, + } + engines: { node: ">= 0.6" } + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + /acorn-walk/8.2.0: + resolution: + { + integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==, + } + engines: { node: ">=0.4.0" } + dev: false + + /acorn/8.8.1: + resolution: + { + integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==, + } + engines: { node: ">=0.4.0" } + hasBin: true + dev: false + + /agent-base/6.0.2: + resolution: + { + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, + } + engines: { node: ">= 6.0.0" } + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /agentkeepalive/4.2.1: + resolution: + { + integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==, + } + engines: { node: ">= 8.0.0" } + dependencies: + debug: 4.3.4 + depd: 1.1.2 + humanize-ms: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + + /aggregate-error/3.1.0: + resolution: + { + integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==, + } + engines: { node: ">=8" } + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: false + optional: true + + /ajv-formats/2.1.1_ajv@8.6.2: + resolution: + { + integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==, + } + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.6.2 + dev: false + + /ajv/8.6.2: + resolution: + { + integrity: sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==, + } + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: false + + /amqplib/0.10.3: + resolution: + { + integrity: sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==, + } + engines: { node: ">=10" } + dependencies: + "@acuminous/bitsyntax": 0.1.2 + buffer-more-ints: 1.0.0 + readable-stream: 1.1.14 + url-parse: 1.5.10 + transitivePeerDependencies: + - supports-color + dev: false + + /ansi-regex/5.0.1: + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } + dev: false + + /ansi-styles/4.3.0: + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } + dependencies: + color-convert: 2.0.1 + + /any-promise/1.3.0: + resolution: + { + integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==, + } + dev: false + + /app-root-path/3.1.0: + resolution: + { + integrity: sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==, + } + engines: { node: ">= 6.0.0" } + dev: false + + /append-field/1.0.0: + resolution: + { + integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==, + } + dev: false + + /aproba/2.0.0: + resolution: + { + integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==, + } + dev: false + + /are-we-there-yet/2.0.0: + resolution: + { + integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==, + } + engines: { node: ">=10" } + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.0 + dev: false + + /are-we-there-yet/3.0.1: + resolution: + { + integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.0 + dev: false + optional: true + + /arg/4.1.3: + resolution: + { + integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, + } + dev: false + + /argparse/1.0.10: + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } + dependencies: + sprintf-js: 1.0.3 + dev: false + + /argparse/2.0.1: + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } + dev: false + + /array-differ/3.0.0: + resolution: + { + integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==, + } + engines: { node: ">=8" } + dev: true + + /array-flatten/1.1.1: + resolution: + { + integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==, + } + + /array-union/2.1.0: + resolution: + { + integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, + } + engines: { node: ">=8" } + dev: true + + /arrify/2.0.1: + resolution: + { + integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==, + } + engines: { node: ">=8" } + dev: true + + /ast-types/0.13.4: + resolution: + { + integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==, + } + engines: { node: ">=4" } + dependencies: + tslib: 2.4.1 + dev: false + + /asynckit/0.4.0: + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } + + /balanced-match/1.0.2: + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } + + /base64-js/1.5.1: + resolution: + { + integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, + } + dev: false + + /basic-auth/2.0.1: + resolution: + { + integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==, + } + engines: { node: ">= 0.8" } + dependencies: + safe-buffer: 5.1.2 + dev: false + + /bcrypt/5.1.0: + resolution: + { + integrity: sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==, + } + engines: { node: ">= 10.0.0" } + requiresBuild: true + dependencies: + "@mapbox/node-pre-gyp": 1.0.10 + node-addon-api: 5.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /bignumber.js/9.1.1: + resolution: + { + integrity: sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==, + } + dev: false + + /body-parser/1.20.1: + resolution: + { + integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==, + } + engines: { node: ">= 0.8", npm: 1.2.8000 || >= 1.4.16 } + dependencies: + bytes: 3.1.2 + content-type: 1.0.4 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + /boolbase/1.0.0: + resolution: + { + integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, + } + dev: false + + /bowser/2.11.0: + resolution: + { + integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==, + } + dev: false + + /brace-expansion/1.1.11: + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + /buffer-equal-constant-time/1.0.1: + resolution: + { + integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==, + } + dev: false + + /buffer-from/1.1.2: + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } + dev: false + + /buffer-more-ints/1.0.0: + resolution: + { + integrity: sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==, + } + dev: false + + /buffer/6.0.3: + resolution: + { + integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==, + } + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /busboy/1.6.0: + resolution: + { + integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==, + } + engines: { node: ">=10.16.0" } + dependencies: + streamsearch: 1.1.0 + dev: false + + /bytes/3.1.2: + resolution: + { + integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, + } + engines: { node: ">= 0.8" } + + /cacache/15.3.0: + resolution: + { + integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==, + } + engines: { node: ">= 10" } + dependencies: + "@npmcli/fs": 1.1.1 + "@npmcli/move-file": 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.1.13 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + dev: false + optional: true + + /call-bind/1.0.2: + resolution: + { + integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==, + } + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.3 + + /chalk/3.0.0: + resolution: + { + integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==, + } + engines: { node: ">=8" } + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk/4.1.2: + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: ">=10" } + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + + /cheerio-select/2.1.0: + resolution: + { + integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==, + } + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.0.1 + dev: false + + /cheerio/1.0.0-rc.12: + resolution: + { + integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==, + } + engines: { node: ">= 6" } + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.0.1 + htmlparser2: 8.0.1 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + dev: false + + /chownr/2.0.0: + resolution: + { + integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==, + } + engines: { node: ">=10" } + dev: false + + /clean-stack/2.2.0: + resolution: + { + integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==, + } + engines: { node: ">=6" } + dev: false + optional: true + + /cli-highlight/2.1.11: + resolution: + { + integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==, + } + engines: { node: ">=8.0.0", npm: ">=5.0.0" } + hasBin: true + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + dev: false + + /cliui/7.0.4: + resolution: + { + integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==, + } + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: false + + /cliui/8.0.1: + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: ">=12" } + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: false + + /color-convert/2.0.1: + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } + dependencies: + color-name: 1.1.4 + + /color-name/1.1.4: + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } + + /color-support/1.1.3: + resolution: + { + integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==, + } + hasBin: true + dev: false + + /combined-stream/1.0.8: + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: ">= 0.8" } + dependencies: + delayed-stream: 1.0.0 + + /concat-map/0.0.1: + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } + + /concat-stream/1.6.2: + resolution: + { + integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==, + } + engines: { "0": node >= 0.8 } + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.7 + typedarray: 0.0.6 + dev: false + + /console-control-strings/1.1.0: + resolution: + { + integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==, + } + dev: false + + /content-disposition/0.5.4: + resolution: + { + integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==, + } + engines: { node: ">= 0.6" } + dependencies: + safe-buffer: 5.2.1 + + /content-type/1.0.4: + resolution: + { + integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==, + } + engines: { node: ">= 0.6" } + + /cookie-parser/1.4.6: + resolution: + { + integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==, + } + engines: { node: ">= 0.8.0" } + dependencies: + cookie: 0.4.1 + cookie-signature: 1.0.6 + dev: false + + /cookie-signature/1.0.6: + resolution: + { + integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==, + } + + /cookie/0.4.1: + resolution: + { + integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==, + } + engines: { node: ">= 0.6" } + dev: false + + /cookie/0.4.2: + resolution: + { + integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==, + } + engines: { node: ">= 0.6" } + dev: false + + /cookie/0.5.0: + resolution: + { + integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==, + } + engines: { node: ">= 0.6" } + + /core-util-is/1.0.3: + resolution: + { + integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==, + } + dev: false + + /create-require/1.1.1: + resolution: + { + integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, + } + dev: false + + /cross-spawn/7.0.3: + resolution: + { + integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, + } + engines: { node: ">= 8" } + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /css-select/5.1.0: + resolution: + { + integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==, + } + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.0.1 + nth-check: 2.1.1 + dev: false + + /css-what/6.1.0: + resolution: + { + integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==, + } + engines: { node: ">= 6" } + dev: false + + /data-uri-to-buffer/3.0.1: + resolution: + { + integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==, + } + engines: { node: ">= 6" } + dev: false + + /date-fns/2.29.3: + resolution: + { + integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==, + } + engines: { node: ">=0.11" } + dev: false + + /debug/2.6.9: + resolution: + { + integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, + } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + + /debug/3.2.7: + resolution: + { + integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==, + } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: false + + /debug/4.3.4: + resolution: + { + integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, + } + engines: { node: ">=6.0" } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + + /deep-is/0.1.4: + resolution: + { + integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, + } + dev: false + + /degenerator/3.0.2: + resolution: + { + integrity: sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ==, + } + engines: { node: ">= 6" } + dependencies: + ast-types: 0.13.4 + escodegen: 1.14.3 + esprima: 4.0.1 + vm2: 3.9.13 + dev: false + + /delayed-stream/1.0.0: + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: ">=0.4.0" } + + /delegates/1.0.0: + resolution: + { + integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==, + } + dev: false + + /depd/1.1.2: + resolution: + { + integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==, + } + engines: { node: ">= 0.6" } + dev: false + optional: true + + /depd/2.0.0: + resolution: + { + integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, + } + engines: { node: ">= 0.8" } + + /destroy/1.2.0: + resolution: + { + integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==, + } + engines: { node: ">= 0.8", npm: 1.2.8000 || >= 1.4.16 } + + /detect-libc/2.0.1: + resolution: + { + integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==, + } + engines: { node: ">=8" } + dev: false + + /diff/4.0.2: + resolution: + { + integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, + } + engines: { node: ">=0.3.1" } + dev: false + + /dom-serializer/2.0.0: + resolution: + { + integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==, + } + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.4.0 + dev: false + + /domelementtype/2.3.0: + resolution: + { + integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, + } + dev: false + + /domhandler/5.0.3: + resolution: + { + integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==, + } + engines: { node: ">= 4" } + dependencies: + domelementtype: 2.3.0 + dev: false + + /domutils/3.0.1: + resolution: + { + integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==, + } + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dev: false + + /dotenv/16.0.3: + resolution: + { + integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==, + } + engines: { node: ">=12" } + dev: false + + /ecdsa-sig-formatter/1.0.11: + resolution: + { + integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==, + } + dependencies: + safe-buffer: 5.2.1 + dev: false + + /ee-first/1.1.1: + resolution: + { + integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, + } + + /emoji-regex/8.0.0: + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } + dev: false + + /encodeurl/1.0.2: + resolution: + { + integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==, + } + engines: { node: ">= 0.8" } + + /encoding/0.1.13: + resolution: + { + integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==, + } + requiresBuild: true + dependencies: + iconv-lite: 0.6.3 + dev: false + optional: true + + /end-of-stream/1.4.4: + resolution: + { + integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==, + } + dependencies: + once: 1.4.0 + dev: true + + /entities/4.4.0: + resolution: + { + integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==, + } + engines: { node: ">=0.12" } + dev: false + + /env-paths/2.2.1: + resolution: + { + integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==, + } + engines: { node: ">=6" } + dev: false + optional: true + + /err-code/2.0.3: + resolution: + { + integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==, + } + dev: false + optional: true + + /escalade/3.1.1: + resolution: + { + integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, + } + engines: { node: ">=6" } + dev: false + + /escape-html/1.0.3: + resolution: + { + integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, + } + + /escodegen/1.14.3: + resolution: + { + integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==, + } + engines: { node: ">=4.0" } + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: false + + /esprima/4.0.1: + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: ">=4" } + hasBin: true + dev: false + + /estraverse/4.3.0: + resolution: + { + integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==, + } + engines: { node: ">=4.0" } + dev: false + + /esutils/2.0.3: + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: ">=0.10.0" } + dev: false + + /etag/1.8.1: + resolution: + { + integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, + } + engines: { node: ">= 0.6" } + + /execa/4.1.0: + resolution: + { + integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==, + } + engines: { node: ">=10" } + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /exif-be-gone/1.3.2: + resolution: + { + integrity: sha512-jVkZWBJNw1SrAzrZ99/ePYx6FqfN6t/+y1xnCAnV5wCcASLBr548OvABfp1WSZGffz31+6DNy0W4ZZSBjs6dJw==, + } + hasBin: true + dependencies: + "@types/stream-buffers": 3.0.4 + dev: false + + /express-async-errors/3.1.1_express@4.18.2: + resolution: + { + integrity: sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==, + } + peerDependencies: + express: ^4.16.2 + dependencies: + express: 4.18.2 + dev: false + + /express/4.18.2: + resolution: + { + integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==, + } + engines: { node: ">= 0.10.0" } + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.4 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + /fast-deep-equal/3.1.3: + resolution: + { + integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, + } + dev: false + + /fast-levenshtein/2.0.6: + resolution: + { + integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, + } + dev: false + + /fast-xml-parser/4.0.11: + resolution: + { + integrity: sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA==, + } + hasBin: true + dependencies: + strnum: 1.0.5 + dev: false + + /fast-zlib/2.0.1: + resolution: + { + integrity: sha512-DCoYgNagM2Bt1VIpXpdGnRx4LzqJeYG0oh6Nf/7cWo6elTXkFGMw9CrRCYYUIapYNrozYMoyDRflx9mgT3Awyw==, + } + dev: false + + /file-type/16.5.4: + resolution: + { + integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==, + } + engines: { node: ">=10" } + dependencies: + readable-web-to-node-stream: 3.0.2 + strtok3: 6.3.0 + token-types: 4.2.1 + dev: false + + /file-uri-to-path/2.0.0: + resolution: + { + integrity: sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==, + } + engines: { node: ">= 6" } + dev: false + + /finalhandler/1.2.0: + resolution: + { + integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==, + } + engines: { node: ">= 0.8" } + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + /find-up/4.1.0: + resolution: + { + integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, + } + engines: { node: ">=8" } + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /form-data/3.0.1: + resolution: + { + integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==, + } + engines: { node: ">= 6" } + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /form-data/4.0.0: + resolution: + { + integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, + } + engines: { node: ">= 6" } + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /forwarded/0.2.0: + resolution: + { + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, + } + engines: { node: ">= 0.6" } + + /fresh/0.5.2: + resolution: + { + integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==, + } + engines: { node: ">= 0.6" } + + /fs-extra/8.1.0: + resolution: + { + integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==, + } + engines: { node: ">=6 <7 || >=8" } + dependencies: + graceful-fs: 4.2.10 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: false + + /fs-minipass/2.1.0: + resolution: + { + integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==, + } + engines: { node: ">= 8" } + dependencies: + minipass: 3.3.6 + dev: false + + /fs.realpath/1.0.0: + resolution: + { + integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, + } + dev: false + + /ftp/0.3.10: + resolution: + { + integrity: sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==, + } + engines: { node: ">=0.8.0" } + dependencies: + readable-stream: 1.1.14 + xregexp: 2.0.0 + dev: false + + /function-bind/1.1.1: + resolution: + { + integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==, + } + + /gauge/3.0.2: + resolution: + { + integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==, + } + engines: { node: ">=10" } + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + + /gauge/4.0.4: + resolution: + { + integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + optional: true + + /get-caller-file/2.0.5: + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } + dev: false + + /get-intrinsic/1.1.3: + resolution: + { + integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==, + } + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + + /get-stream/5.2.0: + resolution: + { + integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==, + } + engines: { node: ">=8" } + dependencies: + pump: 3.0.0 + dev: true + + /get-uri/3.0.2: + resolution: + { + integrity: sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==, + } + engines: { node: ">= 6" } + dependencies: + "@tootallnate/once": 1.1.2 + data-uri-to-buffer: 3.0.1 + debug: 4.3.4 + file-uri-to-path: 2.0.0 + fs-extra: 8.1.0 + ftp: 0.3.10 + transitivePeerDependencies: + - supports-color + dev: false + + /glob/7.2.3: + resolution: + { + integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, + } + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: false + + /graceful-fs/4.2.10: + resolution: + { + integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==, + } + dev: false + + /has-flag/4.0.0: + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: ">=8" } + + /has-symbols/1.0.3: + resolution: + { + integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==, + } + engines: { node: ">= 0.4" } + + /has-unicode/2.0.1: + resolution: + { + integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==, + } + dev: false + + /has/1.0.3: + resolution: + { + integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==, + } + engines: { node: ">= 0.4.0" } + dependencies: + function-bind: 1.1.1 + + /helmet/4.6.0: + resolution: + { + integrity: sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==, + } + engines: { node: ">=10.0.0" } + dev: false + + /highlight.js/10.7.3: + resolution: + { + integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==, + } + dev: false + + /htmlparser2/8.0.1: + resolution: + { + integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==, + } + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.0.1 + entities: 4.4.0 + dev: false + + /http-cache-semantics/4.1.0: + resolution: + { + integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==, + } + dev: false + optional: true + + /http-errors/2.0.0: + resolution: + { + integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==, + } + engines: { node: ">= 0.8" } + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + /http-proxy-agent/4.0.1: + resolution: + { + integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==, + } + engines: { node: ">= 6" } + dependencies: + "@tootallnate/once": 1.1.2 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /https-proxy-agent/5.0.1: + resolution: + { + integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, + } + engines: { node: ">= 6" } + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /human-signals/1.1.1: + resolution: + { + integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==, + } + engines: { node: ">=8.12.0" } + dev: true + + /humanize-ms/1.2.1: + resolution: + { + integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==, + } + dependencies: + ms: 2.1.3 + dev: false + optional: true + + /husky/8.0.3: + resolution: + { + integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==, + } + engines: { node: ">=14" } + hasBin: true + dev: true + + /i18next-http-middleware/3.2.1: + resolution: + { + integrity: sha512-zBwXxDChT0YLoTXIR6jRuqnUUhXW0Iw7egoTnNXyaDRtTbfWNXwU0a53ThyuRPQ+k+tXu3ZMNKRzfLuononaRw==, + } + dev: false + + /i18next-node-fs-backend/2.1.3: + resolution: + { + integrity: sha512-CreMFiVl3ChlMc5ys/e0QfuLFOZyFcL40Jj6jaKD6DxZ/GCUMxPI9BpU43QMWUgC7r+PClpxg2cGXAl0CjG04g==, + } + deprecated: replaced by i18next-fs-backend + dependencies: + js-yaml: 3.13.1 + json5: 2.0.0 + dev: false + + /i18next/21.10.0: + resolution: + { + integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==, + } + dependencies: + "@babel/runtime": 7.20.7 + + /iconv-lite/0.4.24: + resolution: + { + integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, + } + engines: { node: ">=0.10.0" } + dependencies: + safer-buffer: 2.1.2 + + /iconv-lite/0.6.3: + resolution: + { + integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==, + } + engines: { node: ">=0.10.0" } + dependencies: + safer-buffer: 2.1.2 + dev: false + optional: true + + /ieee754/1.2.1: + resolution: + { + integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, + } + dev: false + + /ignore/5.2.4: + resolution: + { + integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==, + } + engines: { node: ">= 4" } + dev: true + + /image-size/1.0.2: + resolution: + { + integrity: sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==, + } + engines: { node: ">=14.0.0" } + hasBin: true + dependencies: + queue: 6.0.2 + dev: false + + /immediate/3.0.6: + resolution: + { + integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==, + } + dev: false + + /imurmurhash/0.1.4: + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: ">=0.8.19" } + dev: false + optional: true + + /indent-string/4.0.0: + resolution: + { + integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, + } + engines: { node: ">=8" } + dev: false + optional: true + + /infer-owner/1.0.4: + resolution: + { + integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==, + } + dev: false + optional: true + + /inflight/1.0.6: + resolution: + { + integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, + } + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: false + + /inherits/2.0.4: + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } + + /ip/1.1.8: + resolution: + { + integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==, + } + dev: false + + /ip/2.0.0: + resolution: + { + integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==, + } + dev: false + + /ipaddr.js/1.9.1: + resolution: + { + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, + } + engines: { node: ">= 0.10" } + + /is-fullwidth-code-point/3.0.0: + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } + dev: false + + /is-lambda/1.0.1: + resolution: + { + integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==, + } + dev: false + optional: true + + /is-stream/2.0.1: + resolution: + { + integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, + } + engines: { node: ">=8" } + dev: true + + /isarray/0.0.1: + resolution: + { + integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==, + } + dev: false + + /isarray/1.0.0: + resolution: + { + integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==, + } + dev: false + + /isexe/2.0.0: + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } + + /js-yaml/3.13.1: + resolution: + { + integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==, + } + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: false + + /js-yaml/4.1.0: + resolution: + { + integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, + } + hasBin: true + dependencies: + argparse: 2.0.1 + dev: false + + /json-bigint/1.0.0: + resolution: + { + integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==, + } + dependencies: + bignumber.js: 9.1.1 + dev: false + + /json-schema-traverse/1.0.0: + resolution: + { + integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, + } + dev: false + + /json-stable-stringify/1.0.2: + resolution: + { + integrity: sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==, + } + dependencies: + jsonify: 0.0.1 + dev: false + + /json5/2.0.0: + resolution: + { + integrity: sha512-0EdQvHuLm7yJ7lyG5dp7Q3X2ku++BG5ZHaJ5FTnaXpKqDrw4pMxel5Bt3oAYMthnrthFBdnZ1FcsXTPyrQlV0w==, + } + engines: { node: ">=6" } + hasBin: true + dependencies: + minimist: 1.2.7 + dev: false + + /jsonfile/4.0.0: + resolution: + { + integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, + } + optionalDependencies: + graceful-fs: 4.2.10 + dev: false + + /jsonify/0.0.1: + resolution: + { + integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==, + } + dev: false + + /jsonwebtoken/8.5.1: + resolution: + { + integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==, + } + engines: { node: ">=4", npm: ">=1.4.28" } + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 5.7.1 + dev: false + + /jwa/1.4.1: + resolution: + { + integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==, + } + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: false + + /jws/3.2.2: + resolution: + { + integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==, + } + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + dev: false + + /lambert-server/1.2.12: + resolution: + { + integrity: sha512-TY6k60KLVfBpPrl9lcrN54RJdTBg9f8JqJPoHg5d/FMLnnwwQtT4budpoQjyLDwBLhS+zpXo0aBCwnnGgTVGaw==, + } + dependencies: + body-parser: 1.20.1 + chalk: 4.1.2 + express: 4.18.2 + express-async-errors: 3.1.1_express@4.18.2 + helmet: 4.6.0 + missing-native-js-functions: 1.3.1 + transitivePeerDependencies: + - supports-color + dev: false + + /levn/0.3.0: + resolution: + { + integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==, + } + engines: { node: ">= 0.8.0" } + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: false + + /lie/3.1.1: + resolution: + { + integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==, + } + dependencies: + immediate: 3.0.6 + dev: false + + /localforage/1.10.0: + resolution: + { + integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==, + } + dependencies: + lie: 3.1.1 + dev: false + + /locate-path/5.0.0: + resolution: + { + integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, + } + engines: { node: ">=8" } + dependencies: + p-locate: 4.1.0 + dev: true + + /lodash.includes/4.3.0: + resolution: + { + integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==, + } + dev: false + + /lodash.isboolean/3.0.3: + resolution: + { + integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==, + } + dev: false + + /lodash.isinteger/4.0.4: + resolution: + { + integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==, + } + dev: false + + /lodash.isnumber/3.0.3: + resolution: + { + integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==, + } + dev: false + + /lodash.isplainobject/4.0.6: + resolution: + { + integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==, + } + dev: false + + /lodash.isstring/4.0.1: + resolution: + { + integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==, + } + dev: false + + /lodash.merge/4.6.2: + resolution: + { + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, + } + dev: false + + /lodash.once/4.1.1: + resolution: + { + integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==, + } + dev: false + + /lru-cache/5.1.1: + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } + dependencies: + yallist: 3.1.1 + dev: false + + /lru-cache/6.0.0: + resolution: + { + integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, + } + engines: { node: ">=10" } + dependencies: + yallist: 4.0.0 + dev: false + + /lru_map/0.3.3: + resolution: + { + integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==, + } + dev: false + + /make-dir/3.1.0: + resolution: + { + integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==, + } + engines: { node: ">=8" } + dependencies: + semver: 6.3.0 + dev: false + + /make-error/1.3.6: + resolution: + { + integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, + } + dev: false + + /make-fetch-happen/9.1.0: + resolution: + { + integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==, + } + engines: { node: ">= 10" } + dependencies: + agentkeepalive: 4.2.1 + cacache: 15.3.0 + http-cache-semantics: 4.1.0 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 1.4.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 6.2.1 + ssri: 8.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + dev: false + optional: true + + /media-typer/0.3.0: + resolution: + { + integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==, + } + engines: { node: ">= 0.6" } + + /merge-descriptors/1.0.1: + resolution: + { + integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==, + } + + /merge-stream/2.0.0: + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } + dev: true + + /methods/1.1.2: + resolution: + { + integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==, + } + engines: { node: ">= 0.6" } + + /mime-db/1.52.0: + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: ">= 0.6" } + + /mime-types/2.1.35: + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: ">= 0.6" } + dependencies: + mime-db: 1.52.0 + + /mime/1.6.0: + resolution: + { + integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, + } + engines: { node: ">=4" } + hasBin: true + + /mimic-fn/2.1.0: + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: ">=6" } + dev: true + + /minimatch/3.1.2: + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } + dependencies: + brace-expansion: 1.1.11 + + /minimist/1.2.7: + resolution: + { + integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==, + } + dev: false + + /minipass-collect/1.0.2: + resolution: + { + integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==, + } + engines: { node: ">= 8" } + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass-fetch/1.4.1: + resolution: + { + integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==, + } + engines: { node: ">=8" } + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + dev: false + optional: true + + /minipass-flush/1.0.5: + resolution: + { + integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==, + } + engines: { node: ">= 8" } + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass-pipeline/1.2.4: + resolution: + { + integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==, + } + engines: { node: ">=8" } + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass-sized/1.0.3: + resolution: + { + integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==, + } + engines: { node: ">=8" } + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass/3.3.6: + resolution: + { + integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==, + } + engines: { node: ">=8" } + dependencies: + yallist: 4.0.0 + dev: false + + /minipass/4.0.0: + resolution: + { + integrity: sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==, + } + engines: { node: ">=8" } + dependencies: + yallist: 4.0.0 + dev: false + + /minizlib/2.1.2: + resolution: + { + integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==, + } + engines: { node: ">= 8" } + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: false + + /missing-native-js-functions/1.3.1: + resolution: + { + integrity: sha512-+27YZhfXCDOwUVZ7qdtJzLWAaA8qYBt6jPrUuF91SpBYUOBLvKr+MgvhlJuNMVhjzNX0245p2zvYYSx9QpuLZQ==, + } + dev: false + + /mkdirp/0.5.6: + resolution: + { + integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==, + } + hasBin: true + dependencies: + minimist: 1.2.7 + dev: false + + /mkdirp/1.0.4: + resolution: + { + integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==, + } + engines: { node: ">=10" } + hasBin: true + dev: false + + /module-alias/2.2.2: + resolution: + { + integrity: sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==, + } + dev: false + + /morgan/1.10.0: + resolution: + { + integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==, + } + engines: { node: ">= 0.8.0" } + dependencies: + basic-auth: 2.0.1 + debug: 2.6.9 + depd: 2.0.0 + on-finished: 2.3.0 + on-headers: 1.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /mri/1.2.0: + resolution: + { + integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, + } + engines: { node: ">=4" } + dev: true + + /ms/2.0.0: + resolution: + { + integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, + } + + /ms/2.1.2: + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } + dev: false + + /ms/2.1.3: + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } + + /multer/1.4.5-lts.1: + resolution: + { + integrity: sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==, + } + engines: { node: ">= 6.0.0" } + dependencies: + append-field: 1.0.0 + busboy: 1.6.0 + concat-stream: 1.6.2 + mkdirp: 0.5.6 + object-assign: 4.1.1 + type-is: 1.6.18 + xtend: 4.0.2 + dev: false + + /multimatch/4.0.0: + resolution: + { + integrity: sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==, + } + engines: { node: ">=8" } + dependencies: + "@types/minimatch": 3.0.5 + array-differ: 3.0.0 + array-union: 2.1.0 + arrify: 2.0.1 + minimatch: 3.1.2 + dev: true + + /mz/2.7.0: + resolution: + { + integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==, + } + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: false + + /needle/2.9.1: + resolution: + { + integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==, + } + engines: { node: ">= 4.4.x" } + hasBin: true + dependencies: + debug: 3.2.7 + iconv-lite: 0.4.24 + sax: 1.2.4 + transitivePeerDependencies: + - supports-color + dev: false + + /negotiator/0.6.3: + resolution: + { + integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, + } + engines: { node: ">= 0.6" } + + /netmask/2.0.2: + resolution: + { + integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==, + } + engines: { node: ">= 0.4.0" } + dev: false + + /node-2fa/2.0.3: + resolution: + { + integrity: sha512-PQldrOhjuoZyoydMvMSctllPN1ZPZ1/NwkEcgYwY9faVqE/OymxR+3awPpbWZxm6acLKqvmNqQmdqTsqYyflFw==, + } + dependencies: + "@types/notp": 2.0.2 + notp: 2.0.3 + thirty-two: 1.0.2 + tslib: 2.4.1 + dev: false + + /node-addon-api/4.3.0: + resolution: + { + integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==, + } + dev: false + + /node-addon-api/5.0.0: + resolution: + { + integrity: sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==, + } + dev: false + + /node-fetch/2.6.7: + resolution: + { + integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==, + } + engines: { node: 4.x || >=6.0.0 } + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp/8.4.1: + resolution: + { + integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==, + } + engines: { node: ">= 10.12.0" } + hasBin: true + requiresBuild: true + dependencies: + env-paths: 2.2.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + make-fetch-happen: 9.1.0 + nopt: 5.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.3.8 + tar: 6.1.13 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + dev: false + optional: true + + /node-os-utils/1.3.7: + resolution: + { + integrity: sha512-fvnX9tZbR7WfCG5BAy3yO/nCLyjVWD6MghEq0z5FDfN+ZXpLWNITBdbifxQkQ25ebr16G0N7eRWJisOcMEHG3Q==, + } + dev: false + + /nopt/5.0.0: + resolution: + { + integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==, + } + engines: { node: ">=6" } + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: false + + /notp/2.0.3: + resolution: + { + integrity: sha512-oBig/2uqkjQ5AkBuw4QJYwkEWa/q+zHxI5/I5z6IeP2NT0alpJFsP/trrfCC+9xOAgQSZXssNi962kp5KBmypQ==, + } + engines: { node: "> v0.6.0" } + dev: false + + /npm-run-path/4.0.1: + resolution: + { + integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, + } + engines: { node: ">=8" } + dependencies: + path-key: 3.1.1 + dev: true + + /npmlog/5.0.1: + resolution: + { + integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==, + } + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: false + + /npmlog/6.0.2: + resolution: + { + integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + dev: false + optional: true + + /nth-check/2.1.1: + resolution: + { + integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, + } + dependencies: + boolbase: 1.0.0 + dev: false + + /object-assign/4.1.1: + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: ">=0.10.0" } + dev: false + + /object-inspect/1.12.2: + resolution: + { + integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==, + } + + /on-finished/2.3.0: + resolution: + { + integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==, + } + engines: { node: ">= 0.8" } + dependencies: + ee-first: 1.1.1 + dev: false + + /on-finished/2.4.1: + resolution: + { + integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, + } + engines: { node: ">= 0.8" } + dependencies: + ee-first: 1.1.1 + + /on-headers/1.0.2: + resolution: + { + integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==, + } + engines: { node: ">= 0.8" } + dev: false + + /once/1.4.0: + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } + dependencies: + wrappy: 1.0.2 + + /onetime/5.1.2: + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: ">=6" } + dependencies: + mimic-fn: 2.1.0 + dev: true + + /optionator/0.8.3: + resolution: + { + integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==, + } + engines: { node: ">= 0.8.0" } + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.3 + dev: false + + /p-limit/2.3.0: + resolution: + { + integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, + } + engines: { node: ">=6" } + dependencies: + p-try: 2.2.0 + dev: true + + /p-locate/4.1.0: + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: ">=8" } + dependencies: + p-limit: 2.3.0 + dev: true + + /p-map/4.0.0: + resolution: + { + integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==, + } + engines: { node: ">=10" } + dependencies: + aggregate-error: 3.1.0 + dev: false + optional: true + + /p-try/2.2.0: + resolution: + { + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + } + engines: { node: ">=6" } + dev: true + + /pac-proxy-agent/5.0.0: + resolution: + { + integrity: sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==, + } + engines: { node: ">= 8" } + dependencies: + "@tootallnate/once": 1.1.2 + agent-base: 6.0.2 + debug: 4.3.4 + get-uri: 3.0.2 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + pac-resolver: 5.0.1 + raw-body: 2.5.1 + socks-proxy-agent: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /pac-resolver/5.0.1: + resolution: + { + integrity: sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==, + } + engines: { node: ">= 8" } + dependencies: + degenerator: 3.0.2 + ip: 1.1.8 + netmask: 2.0.2 + dev: false + + /parse5-htmlparser2-tree-adapter/6.0.1: + resolution: + { + integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==, + } + dependencies: + parse5: 6.0.1 + dev: false + + /parse5-htmlparser2-tree-adapter/7.0.0: + resolution: + { + integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==, + } + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + dev: false + + /parse5/5.1.1: + resolution: + { + integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==, + } + dev: false + + /parse5/6.0.1: + resolution: + { + integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==, + } + dev: false + + /parse5/7.1.2: + resolution: + { + integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==, + } + dependencies: + entities: 4.4.0 + dev: false + + /parseurl/1.3.3: + resolution: + { + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, + } + engines: { node: ">= 0.8" } + + /path-exists/4.0.0: + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: ">=8" } + dev: true + + /path-is-absolute/1.0.1: + resolution: + { + integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, + } + engines: { node: ">=0.10.0" } + dev: false + + /path-key/3.1.1: + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: ">=8" } + dev: true + + /path-to-regexp/0.1.7: + resolution: + { + integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==, + } + + /peek-readable/4.1.0: + resolution: + { + integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==, + } + engines: { node: ">=8" } + dev: false + + /picocolors/1.0.0: + resolution: + { + integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, + } + dev: false + + /prelude-ls/1.1.2: + resolution: + { + integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==, + } + engines: { node: ">= 0.8.0" } + dev: false + + /prettier/2.8.2: + resolution: + { + integrity: sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==, + } + engines: { node: ">=10.13.0" } + hasBin: true + dev: true + + /pretty-quick/3.1.3_prettier@2.8.2: + resolution: + { + integrity: sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==, + } + engines: { node: ">=10.13" } + hasBin: true + peerDependencies: + prettier: ">=2.0.0" + dependencies: + chalk: 3.0.0 + execa: 4.1.0 + find-up: 4.1.0 + ignore: 5.2.4 + mri: 1.2.0 + multimatch: 4.0.0 + prettier: 2.8.2 + dev: true + + /probe-image-size/7.2.3: + resolution: + { + integrity: sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==, + } + dependencies: + lodash.merge: 4.6.2 + needle: 2.9.1 + stream-parser: 0.3.1 + transitivePeerDependencies: + - supports-color + dev: false + + /process-nextick-args/2.0.1: + resolution: + { + integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==, + } + dev: false + + /promise-inflight/1.0.1: + resolution: + { + integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==, + } + peerDependencies: + bluebird: "*" + peerDependenciesMeta: + bluebird: + optional: true + dev: false + optional: true + + /promise-retry/2.0.1: + resolution: + { + integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==, + } + engines: { node: ">=10" } + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + dev: false + optional: true + + /proxy-addr/2.0.7: + resolution: + { + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, + } + engines: { node: ">= 0.10" } + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + /proxy-agent/5.0.0: + resolution: + { + integrity: sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==, + } + engines: { node: ">= 8" } + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + lru-cache: 5.1.1 + pac-proxy-agent: 5.0.0 + proxy-from-env: 1.1.0 + socks-proxy-agent: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /proxy-from-env/1.1.0: + resolution: + { + integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, + } + dev: false + + /pump/3.0.0: + resolution: + { + integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==, + } + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /punycode/2.2.0: + resolution: + { + integrity: sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==, + } + engines: { node: ">=6" } + dev: false + + /qs/6.11.0: + resolution: + { + integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==, + } + engines: { node: ">=0.6" } + dependencies: + side-channel: 1.0.4 + + /querystringify/2.2.0: + resolution: + { + integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==, + } + dev: false + + /queue/6.0.2: + resolution: + { + integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==, + } + dependencies: + inherits: 2.0.4 + dev: false + + /range-parser/1.2.1: + resolution: + { + integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, + } + engines: { node: ">= 0.6" } + + /raw-body/2.5.1: + resolution: + { + integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==, + } + engines: { node: ">= 0.8" } + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + /readable-stream/1.1.14: + resolution: + { + integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==, + } + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: false + + /readable-stream/2.3.7: + resolution: + { + integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==, + } + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: false + + /readable-stream/3.6.0: + resolution: + { + integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==, + } + engines: { node: ">= 6" } + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /readable-web-to-node-stream/3.0.2: + resolution: + { + integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==, + } + engines: { node: ">=8" } + dependencies: + readable-stream: 3.6.0 + dev: false + + /reflect-metadata/0.1.13: + resolution: + { + integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==, + } + dev: false + + /regenerator-runtime/0.13.11: + resolution: + { + integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==, + } + + /require-directory/2.1.1: + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: ">=0.10.0" } + dev: false + + /require-from-string/2.0.2: + resolution: + { + integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, + } + engines: { node: ">=0.10.0" } + dev: false + + /requires-port/1.0.0: + resolution: + { + integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, + } + dev: false + + /retry/0.12.0: + resolution: + { + integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==, + } + engines: { node: ">= 4" } + dev: false + optional: true + + /rimraf/3.0.2: + resolution: + { + integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, + } + hasBin: true + dependencies: + glob: 7.2.3 + dev: false + + /safe-buffer/5.1.2: + resolution: + { + integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, + } + dev: false + + /safe-buffer/5.2.1: + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } + + /safer-buffer/2.1.2: + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } + + /sax/1.2.4: + resolution: + { + integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==, + } + dev: false + + /semver/5.7.1: + resolution: + { + integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==, + } + hasBin: true + dev: false + + /semver/6.3.0: + resolution: + { + integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==, + } + hasBin: true + dev: false + + /semver/7.3.8: + resolution: + { + integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==, + } + engines: { node: ">=10" } + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + + /send/0.18.0: + resolution: + { + integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==, + } + engines: { node: ">= 0.8.0" } + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + /serve-static/1.15.0: + resolution: + { + integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==, + } + engines: { node: ">= 0.8.0" } + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + /set-blocking/2.0.0: + resolution: + { + integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==, + } + dev: false + + /setprototypeof/1.2.0: + resolution: + { + integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, + } + + /sha.js/2.4.11: + resolution: + { + integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==, + } + hasBin: true + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + + /shebang-command/2.0.0: + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: ">=8" } + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/3.0.0: + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: ">=8" } + dev: true + + /side-channel/1.0.4: + resolution: + { + integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==, + } + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + object-inspect: 1.12.2 + + /signal-exit/3.0.7: + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } + + /smart-buffer/4.2.0: + resolution: + { + integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==, + } + engines: { node: ">= 6.0.0", npm: ">= 3.0.0" } + dev: false + + /socks-proxy-agent/5.0.1: + resolution: + { + integrity: sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==, + } + engines: { node: ">= 6" } + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: false + + /socks-proxy-agent/6.2.1: + resolution: + { + integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==, + } + engines: { node: ">= 10" } + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + + /socks/2.7.1: + resolution: + { + integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==, + } + engines: { node: ">= 10.13.0", npm: ">= 3.0.0" } + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: false + + /source-map-support/0.5.21: + resolution: + { + integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, + } + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: false + + /source-map/0.6.1: + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: ">=0.10.0" } + dev: false + + /sprintf-js/1.0.3: + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } + dev: false + + /sqlite3/5.1.4: + resolution: + { + integrity: sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==, + } + requiresBuild: true + peerDependenciesMeta: + node-gyp: + optional: true + dependencies: + "@mapbox/node-pre-gyp": 1.0.10 + node-addon-api: 4.3.0 + tar: 6.1.13 + optionalDependencies: + node-gyp: 8.4.1 + transitivePeerDependencies: + - bluebird + - encoding + - supports-color + dev: false + + /ssri/8.0.1: + resolution: + { + integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==, + } + engines: { node: ">= 8" } + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /statuses/2.0.1: + resolution: + { + integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==, + } + engines: { node: ">= 0.8" } + + /stream-parser/0.3.1: + resolution: + { + integrity: sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==, + } + dependencies: + debug: 2.6.9 + transitivePeerDependencies: + - supports-color + dev: false + + /streamsearch/1.1.0: + resolution: + { + integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==, + } + engines: { node: ">=10.0.0" } + dev: false + + /string-width/4.2.3: + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + + /string_decoder/0.10.31: + resolution: + { + integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==, + } + dev: false + + /string_decoder/1.1.1: + resolution: + { + integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==, + } + dependencies: + safe-buffer: 5.1.2 + dev: false + + /string_decoder/1.3.0: + resolution: + { + integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, + } + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-ansi/6.0.1: + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } + dependencies: + ansi-regex: 5.0.1 + dev: false + + /strip-final-newline/2.0.0: + resolution: + { + integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, + } + engines: { node: ">=6" } + dev: true + + /strnum/1.0.5: + resolution: + { + integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==, + } + dev: false + + /strtok3/6.3.0: + resolution: + { + integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==, + } + engines: { node: ">=10" } + dependencies: + "@tokenizer/token": 0.3.0 + peek-readable: 4.1.0 + dev: false + + /supports-color/7.2.0: + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: ">=8" } + dependencies: + has-flag: 4.0.0 + + /tar/6.1.13: + resolution: + { + integrity: sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==, + } + engines: { node: ">=10" } + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 4.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: false + + /thenify-all/1.6.0: + resolution: + { + integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==, + } + engines: { node: ">=0.8" } + dependencies: + thenify: 3.3.1 + dev: false + + /thenify/3.3.1: + resolution: + { + integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==, + } + dependencies: + any-promise: 1.3.0 + dev: false + + /thirty-two/1.0.2: + resolution: + { + integrity: sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==, + } + engines: { node: ">=0.2.6" } + dev: false + + /toidentifier/1.0.1: + resolution: + { + integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, + } + engines: { node: ">=0.6" } + + /token-types/4.2.1: + resolution: + { + integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==, + } + engines: { node: ">=10" } + dependencies: + "@tokenizer/token": 0.3.0 + ieee754: 1.2.1 + dev: false + + /tr46/0.0.3: + resolution: + { + integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, + } + dev: false + + /ts-node/10.9.1_awa2wsr5thmg3i7jqycphctjfq: + resolution: + { + integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==, + } + hasBin: true + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + dependencies: + "@cspotcode/source-map-support": 0.8.1 + "@tsconfig/node10": 1.0.9 + "@tsconfig/node12": 1.0.11 + "@tsconfig/node14": 1.0.3 + "@tsconfig/node16": 1.0.3 + "@types/node": 18.11.18 + acorn: 8.8.1 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + + /ts-node/9.1.1_typescript@4.2.4: + resolution: + { + integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==, + } + engines: { node: ">=10.0.0" } + hasBin: true + peerDependencies: + typescript: ">=2.7" + dependencies: + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + source-map-support: 0.5.21 + typescript: 4.2.4 + yn: 3.1.1 + dev: false + + /tslib/1.14.1: + resolution: + { + integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==, + } + dev: false + + /tslib/2.4.1: + resolution: + { + integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==, + } + dev: false + + /type-check/0.3.2: + resolution: + { + integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==, + } + engines: { node: ">= 0.8.0" } + dependencies: + prelude-ls: 1.1.2 + dev: false + + /type-is/1.6.18: + resolution: + { + integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==, + } + engines: { node: ">= 0.6" } + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + /typedarray/0.0.6: + resolution: + { + integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==, + } + dev: false + + /typeorm/0.3.11_h3l5zcb3i6sggvllyfknv6gs44: + resolution: + { + integrity: sha512-pzdOyWbVuz/z8Ww6gqvBW4nylsM0KLdUCDExr2gR20/x1khGSVxQkjNV/3YqliG90jrWzrknYbYscpk8yxFJVg==, + } + engines: { node: ">= 12.9.0" } + hasBin: true + peerDependencies: + "@google-cloud/spanner": ^5.18.0 + "@sap/hana-client": ^2.12.25 + better-sqlite3: ^7.1.2 || ^8.0.0 + hdb-pool: ^0.1.6 + ioredis: ^5.0.4 + mongodb: ^3.6.0 + mssql: ^7.3.0 + mysql2: ^2.2.5 + oracledb: ^5.1.0 + pg: ^8.5.1 + pg-native: ^3.0.0 + pg-query-stream: ^4.0.0 + redis: ^3.1.1 || ^4.0.0 + sql.js: ^1.4.0 + sqlite3: ^5.0.3 + ts-node: ^10.7.0 + typeorm-aurora-data-api-driver: ^2.0.0 + peerDependenciesMeta: + "@google-cloud/spanner": + optional: true + "@sap/hana-client": + optional: true + better-sqlite3: + optional: true + hdb-pool: + optional: true + ioredis: + optional: true + mongodb: + optional: true + mssql: + optional: true + mysql2: + optional: true + oracledb: + optional: true + pg: + optional: true + pg-native: + optional: true + pg-query-stream: + optional: true + redis: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + ts-node: + optional: true + typeorm-aurora-data-api-driver: + optional: true + dependencies: + "@sqltools/formatter": 1.2.5 + app-root-path: 3.1.0 + buffer: 6.0.3 + chalk: 4.1.2 + cli-highlight: 2.1.11 + date-fns: 2.29.3 + debug: 4.3.4 + dotenv: 16.0.3 + glob: 7.2.3 + js-yaml: 4.1.0 + mkdirp: 1.0.4 + reflect-metadata: 0.1.13 + sha.js: 2.4.11 + sqlite3: 5.1.4 + ts-node: 10.9.1_awa2wsr5thmg3i7jqycphctjfq + tslib: 2.4.1 + uuid: 8.3.2 + xml2js: 0.4.23 + yargs: 17.6.2 + transitivePeerDependencies: + - supports-color + dev: false + + /typescript-json-schema/0.50.1: + resolution: + { + integrity: sha512-GCof/SDoiTDl0qzPonNEV4CHyCsZEIIf+mZtlrjoD8vURCcEzEfa2deRuxYid8Znp/e27eDR7Cjg8jgGrimBCA==, + } + hasBin: true + dependencies: + "@types/json-schema": 7.0.11 + "@types/node": 14.18.36 + glob: 7.2.3 + json-stable-stringify: 1.0.2 + ts-node: 9.1.1_typescript@4.2.4 + typescript: 4.2.4 + yargs: 16.2.0 + dev: false + + /typescript/4.2.4: + resolution: + { + integrity: sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==, + } + engines: { node: ">=4.2.0" } + hasBin: true + dev: false + + /typescript/4.9.4: + resolution: + { + integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==, + } + engines: { node: ">=4.2.0" } + hasBin: true + + /unique-filename/1.1.1: + resolution: + { + integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==, + } + dependencies: + unique-slug: 2.0.2 + dev: false + optional: true + + /unique-slug/2.0.2: + resolution: + { + integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==, + } + dependencies: + imurmurhash: 0.1.4 + dev: false + optional: true + + /universalify/0.1.2: + resolution: + { + integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==, + } + engines: { node: ">= 4.0.0" } + dev: false + + /unpipe/1.0.0: + resolution: + { + integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, + } + engines: { node: ">= 0.8" } + + /uri-js/4.4.1: + resolution: + { + integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, + } + dependencies: + punycode: 2.2.0 + dev: false + + /url-parse/1.5.10: + resolution: + { + integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==, + } + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: false + + /util-deprecate/1.0.2: + resolution: + { + integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, + } + dev: false + + /utils-merge/1.0.1: + resolution: + { + integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==, + } + engines: { node: ">= 0.4.0" } + + /uuid/8.3.2: + resolution: + { + integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==, + } + hasBin: true + dev: false + + /v8-compile-cache-lib/3.0.1: + resolution: + { + integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, + } + dev: false + + /vary/1.1.2: + resolution: + { + integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, + } + engines: { node: ">= 0.8" } + + /vm2/3.9.13: + resolution: + { + integrity: sha512-0rvxpB8P8Shm4wX2EKOiMp7H2zq+HUE/UwodY0pCZXs9IffIKZq6vUti5OgkVCTakKo9e/fgO4X1fkwfjWxE3Q==, + } + engines: { node: ">=6.0" } + hasBin: true + dependencies: + acorn: 8.8.1 + acorn-walk: 8.2.0 + dev: false + + /webidl-conversions/3.0.1: + resolution: + { + integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, + } + dev: false + + /whatwg-url/5.0.0: + resolution: + { + integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, + } + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which/2.0.2: + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } + hasBin: true + dependencies: + isexe: 2.0.0 + + /wide-align/1.1.5: + resolution: + { + integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==, + } + dependencies: + string-width: 4.2.3 + dev: false + + /word-wrap/1.2.3: + resolution: + { + integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==, + } + engines: { node: ">=0.10.0" } + dev: false + + /wrap-ansi/7.0.0: + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrappy/1.0.2: + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } + + /wretch/2.3.2: + resolution: + { + integrity: sha512-brN97Z2Mwed+w5z+keYI1u5OwWhPIaW0sJi9CxtKBVxLc3aqP6j1+2FCoIskM7WJq6SUHdxTFx20ox0iDLa0mQ==, + } + engines: { node: ">=14" } + dev: false + + /ws/8.12.0: + resolution: + { + integrity: sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==, + } + engines: { node: ">=10.0.0" } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /xml2js/0.4.23: + resolution: + { + integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==, + } + engines: { node: ">=4.0.0" } + dependencies: + sax: 1.2.4 + xmlbuilder: 11.0.1 + dev: false + + /xmlbuilder/11.0.1: + resolution: + { + integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==, + } + engines: { node: ">=4.0" } + dev: false + + /xregexp/2.0.0: + resolution: + { + integrity: sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==, + } + dev: false + + /xtend/4.0.2: + resolution: + { + integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==, + } + engines: { node: ">=0.4" } + dev: false + + /y18n/5.0.8: + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: ">=10" } + dev: false + + /yallist/3.1.1: + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } + dev: false + + /yallist/4.0.0: + resolution: + { + integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, + } + dev: false + + /yargs-parser/20.2.9: + resolution: + { + integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==, + } + engines: { node: ">=10" } + dev: false + + /yargs-parser/21.1.1: + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: ">=12" } + dev: false + + /yargs/16.2.0: + resolution: + { + integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==, + } + engines: { node: ">=10" } + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + dev: false + + /yargs/17.6.2: + resolution: + { + integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==, + } + engines: { node: ">=12" } + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: false + + /yn/3.1.1: + resolution: + { + integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, + } + engines: { node: ">=6" } + dev: false diff --git a/src/api/Server.ts b/src/api/Server.ts
index 447a4802..472ab1d6 100644 --- a/src/api/Server.ts +++ b/src/api/Server.ts
@@ -25,6 +25,8 @@ import { registerRoutes, Sentry, WebAuthn, + ConnectionConfig, + ConnectionLoader, } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { Server, ServerOptions } from "lambert-server"; @@ -72,6 +74,7 @@ export class SpacebarServer extends Server { await Config.init(); await initEvent(); await Email.init(); + await ConnectionConfig.init(); await initInstance(); await Sentry.init(this.app); WebAuthn.init(); @@ -142,6 +145,8 @@ export class SpacebarServer extends Server { Sentry.errorHandler(this.app); + ConnectionLoader.loadConnections(); + if (logRequests) console.log( red( diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts
index 09644eee..d0e4d8a0 100644 --- a/src/api/middlewares/Authentication.ts +++ b/src/api/middlewares/Authentication.ts
@@ -52,6 +52,8 @@ export const NO_AUTHORIZATION_ROUTES = [ "/oauth2/callback", // Asset delivery /\/guilds\/\d+\/widget\.(json|png)/, + // Connections + /\/connections\/\w+\/callback/, ]; export const API_PREFIX = /^\/api(\/v\d+)?/; diff --git a/src/api/routes/connections/#connection_name/#connection_id/refresh.ts b/src/api/routes/connections/#connection_name/#connection_id/refresh.ts new file mode 100644
index 00000000..4fa64978 --- /dev/null +++ b/src/api/routes/connections/#connection_name/#connection_id/refresh.ts
@@ -0,0 +1,11 @@ +import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; +const router = Router(); + +router.post("/", route({}), async (req: Request, res: Response) => { + // TODO: + const { connection_name, connection_id } = req.params; + res.sendStatus(204); +}); + +export default router; diff --git a/src/api/routes/connections/#connection_name/authorize.ts b/src/api/routes/connections/#connection_name/authorize.ts new file mode 100644
index 00000000..63738e7c --- /dev/null +++ b/src/api/routes/connections/#connection_name/authorize.ts
@@ -0,0 +1,34 @@ +import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; +import { ConnectionStore, FieldErrors } from "../../../../util"; + +const router = Router(); + +router.get("/", route({}), async (req: Request, res: Response) => { + const { connection_name } = req.params; + const connection = ConnectionStore.connections.get(connection_name); + if (!connection) + throw FieldErrors({ + provider_id: { + code: "BASE_TYPE_CHOICES", + message: req.t("common:field.BASE_TYPE_CHOICES", { + types: Array.from(ConnectionStore.connections.keys()).join( + ", ", + ), + }), + }, + }); + + if (!connection.settings.enabled) + throw FieldErrors({ + provider_id: { + message: "This connection has been disabled server-side.", + }, + }); + + res.json({ + url: await connection.getAuthorizationUrl(req.user_id), + }); +}); + +export default router; diff --git a/src/api/routes/connections/#connection_name/callback.ts b/src/api/routes/connections/#connection_name/callback.ts new file mode 100644
index 00000000..74021170 --- /dev/null +++ b/src/api/routes/connections/#connection_name/callback.ts
@@ -0,0 +1,53 @@ +import { route } from "@spacebar/api"; +import { + ConnectionCallbackSchema, + ConnectionStore, + emitEvent, + FieldErrors, +} from "@spacebar/util"; +import { Request, Response, Router } from "express"; + +const router = Router(); + +router.post( + "/", + route({ body: "ConnectionCallbackSchema" }), + async (req: Request, res: Response) => { + const { connection_name } = req.params; + const connection = ConnectionStore.connections.get(connection_name); + if (!connection) + throw FieldErrors({ + provider_id: { + code: "BASE_TYPE_CHOICES", + message: req.t("common:field.BASE_TYPE_CHOICES", { + types: Array.from( + ConnectionStore.connections.keys(), + ).join(", "), + }), + }, + }); + + if (!connection.settings.enabled) + throw FieldErrors({ + provider_id: { + message: "This connection has been disabled server-side.", + }, + }); + + const body = req.body as ConnectionCallbackSchema; + const userId = connection.getUserId(body.state); + const connectedAccnt = await connection.handleCallback(body); + + // whether we should emit a connections update event, only used when a connection doesnt already exist + if (connectedAccnt) + emitEvent({ + event: "USER_CONNECTIONS_UPDATE", + data: { ...connectedAccnt, token_data: undefined }, + user_id: userId, + }); + + res.sendStatus(204); + }, +); + +export default router; diff --git a/src/api/routes/policies/instance/domains.ts b/src/api/routes/policies/instance/domains.ts
index fe032b50..696a8510 100644 --- a/src/api/routes/policies/instance/domains.ts +++ b/src/api/routes/policies/instance/domains.ts
@@ -31,7 +31,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { process.env.GATEWAY || "ws://localhost:3001", defaultApiVersion: api.defaultVersion ?? 9, - apiEndpoint: api.endpointPublic ?? "/api", + apiEndpoint: api.endpointPublic ?? "http://localhost:3001/api/", }; res.json(IdentityForm); diff --git a/src/api/routes/users/#id/profile.ts b/src/api/routes/users/#id/profile.ts
index 4727e215..2836c563 100644 --- a/src/api/routes/users/#id/profile.ts +++ b/src/api/routes/users/#id/profile.ts
@@ -133,7 +133,9 @@ router.get( guild_id, }; res.json({ - connected_accounts: user.connected_accounts, + connected_accounts: user.connected_accounts.filter( + (x) => x.visibility != 0, + ), premium_guild_since: premium_guild_since, // TODO premium_since: user.premium_since, // TODO mutual_guilds: mutual_guilds, // TODO {id: "", nick: null} when ?with_mutual_guilds=true diff --git a/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts b/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts new file mode 100644
index 00000000..a290d88a --- /dev/null +++ b/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts
@@ -0,0 +1,81 @@ +import { route } from "@spacebar/api"; +import { + ApiError, + ConnectedAccount, + ConnectionStore, + DiscordApiErrors, + FieldErrors, +} from "@spacebar/util"; +import { Request, Response, Router } from "express"; +import RefreshableConnection from "../../../../../../../util/connections/RefreshableConnection"; +const router = Router(); + +// TODO: this route is only used for spotify, twitch, and youtube. (battlenet seems to be able to PUT, maybe others also) + +// spotify is disabled here because it cant be used +const ALLOWED_CONNECTIONS = ["twitch", "youtube"]; + +// NOTE: this route has not been extensively tested, as the required connections are not implemented as of writing +router.get("/", route({}), async (req: Request, res: Response) => { + const { connection_name, connection_id } = req.params; + + const connection = ConnectionStore.connections.get(connection_name); + + if (!ALLOWED_CONNECTIONS.includes(connection_name) || !connection) + throw FieldErrors({ + provider_id: { + code: "BASE_TYPE_CHOICES", + message: req.t("common:field.BASE_TYPE_CHOICES", { + types: ALLOWED_CONNECTIONS.join(", "), + }), + }, + }); + + if (!connection.settings.enabled) + throw FieldErrors({ + provider_id: { + message: "This connection has been disabled server-side.", + }, + }); + + const connectedAccount = await ConnectedAccount.findOne({ + where: { + type: connection_name, + external_id: connection_id, + user_id: req.user_id, + }, + select: [ + "external_id", + "type", + "name", + "verified", + "visibility", + "show_activity", + "revoked", + "token_data", + "friend_sync", + "integrations", + ], + }); + if (!connectedAccount) throw DiscordApiErrors.UNKNOWN_CONNECTION; + if (connectedAccount.revoked) throw DiscordApiErrors.CONNECTION_REVOKED; + if (!connectedAccount.token_data) + throw new ApiError("No token data", 0, 400); + + let access_token = connectedAccount.token_data.access_token; + const { expires_at, expires_in, fetched_at } = connectedAccount.token_data; + + if ( + (expires_at && expires_at < Date.now()) || + (expires_in && fetched_at + expires_in * 1000 < Date.now()) + ) { + if (!(connection instanceof RefreshableConnection)) + throw new ApiError("Access token expired", 0, 400); + const tokenData = await connection.refresh(connectedAccount); + access_token = tokenData.access_token; + } + + res.json({ access_token }); +}); + +export default router; diff --git a/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts b/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts new file mode 100644
index 00000000..6a8d31ca --- /dev/null +++ b/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts
@@ -0,0 +1,85 @@ +import { route } from "@spacebar/api"; +import { + ConnectedAccount, + ConnectionUpdateSchema, + DiscordApiErrors, + emitEvent, +} from "@spacevar/util"; +import { Request, Response, Router } from "express"; +const router = Router(); + +// TODO: connection update schema +router.patch( + "/", + route({ body: "ConnectionUpdateSchema" }), + async (req: Request, res: Response) => { + const { connection_name, connection_id } = req.params; + const body = req.body as ConnectionUpdateSchema; + + const connection = await ConnectedAccount.findOne({ + where: { + user_id: req.user_id, + external_id: connection_id, + type: connection_name, + }, + select: [ + "external_id", + "type", + "name", + "verified", + "visibility", + "show_activity", + "revoked", + "friend_sync", + "integrations", + ], + }); + + if (!connection) return DiscordApiErrors.UNKNOWN_CONNECTION; + // TODO: do we need to do anything if the connection is revoked? + + if (typeof body.visibility === "boolean") + //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? + body.visibility = body.visibility ? 1 : 0; + if (typeof body.show_activity === "boolean") + //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? + body.show_activity = body.show_activity ? 1 : 0; + + connection.assign(req.body); + + await ConnectedAccount.update( + { + user_id: req.user_id, + external_id: connection_id, + type: connection_name, + }, + connection, + ); + res.json(connection.toJSON()); + }, +); + +router.delete("/", route({}), async (req: Request, res: Response) => { + const { connection_name, connection_id } = req.params; + + const account = await ConnectedAccount.findOneOrFail({ + where: { + user_id: req.user_id, + external_id: connection_id, + type: connection_name, + }, + }); + + await Promise.all([ + ConnectedAccount.remove(account), + emitEvent({ + event: "USER_CONNECTIONS_UPDATE", + data: account, + user_id: req.user_id, + }), + ]); + + return res.sendStatus(200); +}); + +export default router; diff --git a/src/api/routes/users/@me/connections.ts b/src/api/routes/users/@me/connections/index.ts
index 1d4564da..620ce3b5 100644 --- a/src/api/routes/users/@me/connections.ts +++ b/src/api/routes/users/@me/connections/index.ts
@@ -18,12 +18,30 @@ import { Request, Response, Router } from "express"; import { route } from "@spacebar/api"; +import { ConnectedAccount, ConnectedAccountDTO } from "@spacebar/util"; const router: Router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { - //TODO - res.json([]).status(200); + const connections = await ConnectedAccount.find({ + where: { + user_id: req.user_id, + }, + select: [ + "external_id", + "type", + "name", + "verified", + "visibility", + "show_activity", + "revoked", + "token_data", + "friend_sync", + "integrations", + ], + }); + + res.json(connections.map((x) => new ConnectedAccountDTO(x, true))); }); export default router; diff --git a/src/connections/BattleNet/BattleNetSettings.ts b/src/connections/BattleNet/BattleNetSettings.ts new file mode 100644
index 00000000..75e5c3ae --- /dev/null +++ b/src/connections/BattleNet/BattleNetSettings.ts
@@ -0,0 +1,5 @@ +export class BattleNetSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/BattleNet/index.ts b/src/connections/BattleNet/index.ts new file mode 100644
index 00000000..7ea919f1 --- /dev/null +++ b/src/connections/BattleNet/index.ts
@@ -0,0 +1,116 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { BattleNetSettings } from "./BattleNetSettings"; + +interface BattleNetConnectionUser { + sub: string; + id: number; + battletag: string; +} + +interface BattleNetErrorResponse { + error: string; + error_description: string; +} + +export default class BattleNetConnection extends Connection { + public readonly id = "battlenet"; + public readonly authorizeUrl = "https://oauth.battle.net/authorize"; + public readonly tokenUrl = "https://oauth.battle.net/token"; + public readonly userInfoUrl = "https://us.battle.net/oauth/userinfo"; + public readonly scopes = []; + settings: BattleNetSettings = new BattleNetSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as BattleNetSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + url.searchParams.append("response_type", "code"); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code: code, + client_id: this.settings.clientId!, + client_secret: this.settings.clientSecret!, + redirect_uri: this.getRedirectUri(), + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<BattleNetConnectionUser> { + const url = new URL(this.userInfoUrl); + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<BattleNetConnectionUser>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.id.toString()); + + if (exists) return null; + + return await this.createConnection({ + user_id: userId, + external_id: userInfo.id.toString(), + friend_sync: params.friend_sync, + name: userInfo.battletag, + type: this.id, + }); + } +} diff --git a/src/connections/Discord/DiscordSettings.ts b/src/connections/Discord/DiscordSettings.ts new file mode 100644
index 00000000..3751b041 --- /dev/null +++ b/src/connections/Discord/DiscordSettings.ts
@@ -0,0 +1,5 @@ +export class DiscordSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Discord/index.ts b/src/connections/Discord/index.ts new file mode 100644
index 00000000..24e90860 --- /dev/null +++ b/src/connections/Discord/index.ts
@@ -0,0 +1,115 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { DiscordSettings } from "./DiscordSettings"; + +interface UserResponse { + id: string; + username: string; + discriminator: string; + avatar_url: string | null; +} + +export default class DiscordConnection extends Connection { + public readonly id = "discord"; + public readonly authorizeUrl = "https://discord.com/api/oauth2/authorize"; + public readonly tokenUrl = "https://discord.com/api/oauth2/token"; + public readonly userInfoUrl = "https://discord.com/api/users/@me"; + public readonly scopes = ["identify"]; + settings: DiscordSettings = new DiscordSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as DiscordSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("state", state); + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("response_type", "code"); + // controls whether, on repeated authorizations, the consent screen is shown + url.searchParams.append("consent", "none"); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + }) + .body( + new URLSearchParams({ + client_id: this.settings.clientId!, + client_secret: this.settings.clientSecret!, + grant_type: "authorization_code", + code: code, + redirect_uri: this.getRedirectUri(), + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<UserResponse> { + const url = new URL(this.userInfoUrl); + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<UserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.id); + + if (exists) return null; + + return await this.createConnection({ + user_id: userId, + external_id: userInfo.id, + friend_sync: params.friend_sync, + name: `${userInfo.username}#${userInfo.discriminator}`, + type: this.id, + }); + } +} diff --git a/src/connections/EpicGames/EpicGamesSettings.ts b/src/connections/EpicGames/EpicGamesSettings.ts new file mode 100644
index 00000000..4820a88a --- /dev/null +++ b/src/connections/EpicGames/EpicGamesSettings.ts
@@ -0,0 +1,5 @@ +export class EpicGamesSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/EpicGames/index.ts b/src/connections/EpicGames/index.ts new file mode 100644
index 00000000..5e758540 --- /dev/null +++ b/src/connections/EpicGames/index.ts
@@ -0,0 +1,128 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { EpicGamesSettings } from "./EpicGamesSettings"; + +export interface UserResponse { + accountId: string; + displayName: string; + preferredLanguage: string; +} + +export interface EpicTokenResponse + extends ConnectedAccountCommonOAuthTokenResponse { + expires_at: string; + refresh_expires_in: number; + refresh_expires_at: string; + account_id: string; + client_id: string; + application_id: string; +} + +export default class EpicGamesConnection extends Connection { + public readonly id = "epicgames"; + public readonly authorizeUrl = "https://www.epicgames.com/id/authorize"; + public readonly tokenUrl = "https://api.epicgames.dev/epic/oauth/v1/token"; + public readonly userInfoUrl = + "https://api.epicgames.dev/epic/id/v1/accounts"; + public readonly scopes = ["basic profile"]; + settings: EpicGamesSettings = new EpicGamesSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as EpicGamesSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<EpicTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + Authorization: `Basic ${Buffer.from( + `${this.settings.clientId}:${this.settings.clientSecret}`, + ).toString("base64")}`, + "Content-Type": "application/x-www-form-urlencoded", + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code, + }), + ) + .post() + .json<EpicTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<UserResponse[]> { + const { sub } = JSON.parse( + Buffer.from(token.split(".")[1], "base64").toString("utf8"), + ); + const url = new URL(this.userInfoUrl); + url.searchParams.append("accountId", sub); + + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<UserResponse[]>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo[0].accountId); + + if (exists) return null; + + return await this.createConnection({ + user_id: userId, + external_id: userInfo[0].accountId, + friend_sync: params.friend_sync, + name: userInfo[0].displayName, + type: this.id, + }); + } +} diff --git a/src/connections/Facebook/FacebookSettings.ts b/src/connections/Facebook/FacebookSettings.ts new file mode 100644
index 00000000..cc3e3402 --- /dev/null +++ b/src/connections/Facebook/FacebookSettings.ts
@@ -0,0 +1,5 @@ +export class FacebookSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Facebook/index.ts b/src/connections/Facebook/index.ts new file mode 100644
index 00000000..8e0f8d27 --- /dev/null +++ b/src/connections/Facebook/index.ts
@@ -0,0 +1,119 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { FacebookSettings } from "./FacebookSettings"; + +export interface FacebookErrorResponse { + error: { + message: string; + type: string; + code: number; + fbtrace_id: string; + }; +} + +interface UserResponse { + name: string; + id: string; +} + +export default class FacebookConnection extends Connection { + public readonly id = "facebook"; + public readonly authorizeUrl = + "https://www.facebook.com/v14.0/dialog/oauth"; + public readonly tokenUrl = + "https://graph.facebook.com/v14.0/oauth/access_token"; + public readonly userInfoUrl = "https://graph.facebook.com/v14.0/me"; + public readonly scopes = ["public_profile"]; + settings: FacebookSettings = new FacebookSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as FacebookSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("state", state); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("display", "popup"); + return url.toString(); + } + + getTokenUrl(code: string): string { + const url = new URL(this.tokenUrl); + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("client_secret", this.settings.clientSecret!); + url.searchParams.append("code", code); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + return url.toString(); + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(code); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + }) + .get() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<UserResponse> { + const url = new URL(this.userInfoUrl); + + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<UserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.id); + + if (exists) return null; + + return await this.createConnection({ + user_id: userId, + external_id: userInfo.id, + friend_sync: params.friend_sync, + name: userInfo.name, + type: this.id, + }); + } +} diff --git a/src/connections/GitHub/GitHubSettings.ts b/src/connections/GitHub/GitHubSettings.ts new file mode 100644
index 00000000..1b4070d2 --- /dev/null +++ b/src/connections/GitHub/GitHubSettings.ts
@@ -0,0 +1,5 @@ +export class GitHubSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/GitHub/index.ts b/src/connections/GitHub/index.ts new file mode 100644
index 00000000..638a34af --- /dev/null +++ b/src/connections/GitHub/index.ts
@@ -0,0 +1,106 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { GitHubSettings } from "./GitHubSettings"; + +interface UserResponse { + login: string; + id: number; + name: string; +} + +export default class GitHubConnection extends Connection { + public readonly id = "github"; + public readonly authorizeUrl = "https://github.com/login/oauth/authorize"; + public readonly tokenUrl = "https://github.com/login/oauth/access_token"; + public readonly userInfoUrl = "https://api.github.com/user"; + public readonly scopes = ["read:user"]; + settings: GitHubSettings = new GitHubSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as GitHubSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + return url.toString(); + } + + getTokenUrl(code: string): string { + const url = new URL(this.tokenUrl); + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("client_secret", this.settings.clientSecret!); + url.searchParams.append("code", code); + return url.toString(); + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(code); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + }) + + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<UserResponse> { + const url = new URL(this.userInfoUrl); + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<UserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.id.toString()); + + if (exists) return null; + + return await this.createConnection({ + user_id: userId, + external_id: userInfo.id.toString(), + friend_sync: params.friend_sync, + name: userInfo.login, + type: this.id, + }); + } +} diff --git a/src/connections/Reddit/RedditSettings.ts b/src/connections/Reddit/RedditSettings.ts new file mode 100644
index 00000000..13208fb5 --- /dev/null +++ b/src/connections/Reddit/RedditSettings.ts
@@ -0,0 +1,5 @@ +export class RedditSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Reddit/index.ts b/src/connections/Reddit/index.ts new file mode 100644
index 00000000..2f3418c0 --- /dev/null +++ b/src/connections/Reddit/index.ts
@@ -0,0 +1,128 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { RedditSettings } from "./RedditSettings"; + +export interface UserResponse { + verified: boolean; + coins: number; + id: string; + is_mod: boolean; + has_verified_email: boolean; + total_karma: number; + name: string; + created: number; + gold_creddits: number; + created_utc: number; +} + +export interface ErrorResponse { + message: string; + error: number; +} + +export default class RedditConnection extends Connection { + public readonly id = "reddit"; + public readonly authorizeUrl = "https://www.reddit.com/api/v1/authorize"; + public readonly tokenUrl = "https://www.reddit.com/api/v1/access_token"; + public readonly userInfoUrl = "https://oauth.reddit.com/api/v1/me"; + public readonly scopes = ["identity"]; + settings: RedditSettings = new RedditSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as RedditSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + Authorization: `Basic ${Buffer.from( + `${this.settings.clientId}:${this.settings.clientSecret}`, + ).toString("base64")}`, + "Content-Type": "application/x-www-form-urlencoded", + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code: code, + redirect_uri: this.getRedirectUri(), + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<UserResponse> { + const url = new URL(this.userInfoUrl); + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<UserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.id.toString()); + + if (exists) return null; + + // TODO: connection metadata + + return await this.createConnection({ + user_id: userId, + external_id: userInfo.id.toString(), + friend_sync: params.friend_sync, + name: userInfo.name, + verified: userInfo.has_verified_email, + type: this.id, + }); + } +} diff --git a/src/connections/Spotify/SpotifySettings.ts b/src/connections/Spotify/SpotifySettings.ts new file mode 100644
index 00000000..e73c0304 --- /dev/null +++ b/src/connections/Spotify/SpotifySettings.ts
@@ -0,0 +1,5 @@ +export class SpotifySettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Spotify/index.ts b/src/connections/Spotify/index.ts new file mode 100644
index 00000000..c9517b1a --- /dev/null +++ b/src/connections/Spotify/index.ts
@@ -0,0 +1,171 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import RefreshableConnection from "../../util/connections/RefreshableConnection"; +import { SpotifySettings } from "./SpotifySettings"; + +export interface UserResponse { + display_name: string; + id: string; +} + +export interface TokenErrorResponse { + error: string; + error_description: string; +} + +export interface ErrorResponse { + error: { + status: number; + message: string; + }; +} + +export default class SpotifyConnection extends RefreshableConnection { + public readonly id = "spotify"; + public readonly authorizeUrl = "https://accounts.spotify.com/authorize"; + public readonly tokenUrl = "https://accounts.spotify.com/api/token"; + public readonly userInfoUrl = "https://api.spotify.com/v1/me"; + public readonly scopes = [ + "user-read-private", + "user-read-playback-state", + "user-modify-playback-state", + "user-read-currently-playing", + ]; + settings: SpotifySettings = new SpotifySettings(); + + init(): void { + /** + * The way Discord shows the currently playing song is by using Spotifys partner API. This is obviously not possible for us. + * So to prevent spamming the spotify api we disable the ability to refresh. + */ + this.refreshEnabled = false; + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as SpotifySettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${Buffer.from( + `${this.settings.clientId!}:${this.settings.clientSecret!}`, + ).toString("base64")}`, + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code: code, + redirect_uri: this.getRedirectUri(), + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async refreshToken( + connectedAccount: ConnectedAccount, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + if (!connectedAccount.token_data?.refresh_token) + throw new Error("No refresh token available."); + const refresh_token = connectedAccount.token_data.refresh_token; + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${Buffer.from( + `${this.settings.clientId!}:${this.settings.clientSecret!}`, + ).toString("base64")}`, + }) + .body( + new URLSearchParams({ + grant_type: "refresh_token", + refresh_token, + }), + ) + .post() + .unauthorized(async () => { + // assume the token was revoked + await connectedAccount.revoke(); + return DiscordApiErrors.CONNECTION_REVOKED; + }) + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<UserResponse> { + const url = new URL(this.userInfoUrl); + + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<UserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.id); + + if (exists) return null; + + return await this.createConnection({ + token_data: { ...tokenData, fetched_at: Date.now() }, + user_id: userId, + external_id: userInfo.id, + friend_sync: params.friend_sync, + name: userInfo.display_name, + type: this.id, + }); + } +} diff --git a/src/connections/Twitch/TwitchSettings.ts b/src/connections/Twitch/TwitchSettings.ts new file mode 100644
index 00000000..eb732c82 --- /dev/null +++ b/src/connections/Twitch/TwitchSettings.ts
@@ -0,0 +1,5 @@ +export class TwitchSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Twitch/index.ts b/src/connections/Twitch/index.ts new file mode 100644
index 00000000..d53215f1 --- /dev/null +++ b/src/connections/Twitch/index.ts
@@ -0,0 +1,163 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import RefreshableConnection from "../../util/connections/RefreshableConnection"; +import { TwitchSettings } from "./TwitchSettings"; + +interface TwitchConnectionUserResponse { + data: { + id: string; + login: string; + display_name: string; + type: string; + broadcaster_type: string; + description: string; + profile_image_url: string; + offline_image_url: string; + view_count: number; + created_at: string; + }[]; +} + +export default class TwitchConnection extends RefreshableConnection { + public readonly id = "twitch"; + public readonly authorizeUrl = "https://id.twitch.tv/oauth2/authorize"; + public readonly tokenUrl = "https://id.twitch.tv/oauth2/token"; + public readonly userInfoUrl = "https://api.twitch.tv/helix/users"; + public readonly scopes = [ + "channel_subscriptions", + "channel_check_subscription", + "channel:read:subscriptions", + ]; + settings: TwitchSettings = new TwitchSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as TwitchSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code: code, + client_id: this.settings.clientId!, + client_secret: this.settings.clientSecret!, + redirect_uri: this.getRedirectUri(), + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async refreshToken( + connectedAccount: ConnectedAccount, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + if (!connectedAccount.token_data?.refresh_token) + throw new Error("No refresh token available."); + const refresh_token = connectedAccount.token_data.refresh_token; + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + }) + .body( + new URLSearchParams({ + grant_type: "refresh_token", + client_id: this.settings.clientId!, + client_secret: this.settings.clientSecret!, + refresh_token: refresh_token, + }), + ) + .post() + .unauthorized(async () => { + // assume the token was revoked + await connectedAccount.revoke(); + return DiscordApiErrors.CONNECTION_REVOKED; + }) + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<TwitchConnectionUserResponse> { + const url = new URL(this.userInfoUrl); + + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + "Client-Id": this.settings.clientId!, + }) + .get() + .json<TwitchConnectionUserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.data[0].id); + + if (exists) return null; + + return await this.createConnection({ + token_data: { ...tokenData, fetched_at: Date.now() }, + user_id: userId, + external_id: userInfo.data[0].id, + friend_sync: params.friend_sync, + name: userInfo.data[0].display_name, + type: this.id, + }); + } +} diff --git a/src/connections/Twitter/TwitterSettings.ts b/src/connections/Twitter/TwitterSettings.ts new file mode 100644
index 00000000..e4aa58eb --- /dev/null +++ b/src/connections/Twitter/TwitterSettings.ts
@@ -0,0 +1,5 @@ +export class TwitterSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Twitter/index.ts b/src/connections/Twitter/index.ts new file mode 100644
index 00000000..f8eac894 --- /dev/null +++ b/src/connections/Twitter/index.ts
@@ -0,0 +1,165 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import RefreshableConnection from "../../util/connections/RefreshableConnection"; +import { TwitterSettings } from "./TwitterSettings"; + +interface TwitterUserResponse { + data: { + id: string; + name: string; + username: string; + created_at: string; + location: string; + url: string; + description: string; + verified: string; + }; +} + +interface TwitterErrorResponse { + error: string; + error_description: string; +} + +export default class TwitterConnection extends RefreshableConnection { + public readonly id = "twitter"; + public readonly authorizeUrl = "https://twitter.com/i/oauth2/authorize"; + public readonly tokenUrl = "https://api.twitter.com/2/oauth2/token"; + public readonly userInfoUrl = + "https://api.twitter.com/2/users/me?user.fields=created_at%2Cdescription%2Cid%2Cname%2Cusername%2Cverified%2Clocation%2Curl"; + public readonly scopes = ["users.read", "tweet.read"]; + settings: TwitterSettings = new TwitterSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as TwitterSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + url.searchParams.append("code_challenge", "challenge"); // TODO: properly use PKCE challenge + url.searchParams.append("code_challenge_method", "plain"); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${Buffer.from( + `${this.settings.clientId!}:${this.settings.clientSecret!}`, + ).toString("base64")}`, + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code: code, + client_id: this.settings.clientId!, + redirect_uri: this.getRedirectUri(), + code_verifier: "challenge", // TODO: properly use PKCE challenge + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async refreshToken( + connectedAccount: ConnectedAccount, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + if (!connectedAccount.token_data?.refresh_token) + throw new Error("No refresh token available."); + const refresh_token = connectedAccount.token_data.refresh_token; + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${Buffer.from( + `${this.settings.clientId!}:${this.settings.clientSecret!}`, + ).toString("base64")}`, + }) + .body( + new URLSearchParams({ + grant_type: "refresh_token", + refresh_token, + client_id: this.settings.clientId!, + redirect_uri: this.getRedirectUri(), + code_verifier: "challenge", // TODO: properly use PKCE challenge + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<TwitterUserResponse> { + const url = new URL(this.userInfoUrl); + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<TwitterUserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.data.id); + + if (exists) return null; + + return await this.createConnection({ + token_data: { ...tokenData, fetched_at: Date.now() }, + user_id: userId, + external_id: userInfo.data.id, + friend_sync: params.friend_sync, + name: userInfo.data.name, + type: this.id, + }); + } +} diff --git a/src/connections/Xbox/XboxSettings.ts b/src/connections/Xbox/XboxSettings.ts new file mode 100644
index 00000000..c1a41056 --- /dev/null +++ b/src/connections/Xbox/XboxSettings.ts
@@ -0,0 +1,5 @@ +export class XboxSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Xbox/index.ts b/src/connections/Xbox/index.ts new file mode 100644
index 00000000..011f87a8 --- /dev/null +++ b/src/connections/Xbox/index.ts
@@ -0,0 +1,180 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { XboxSettings } from "./XboxSettings"; + +interface XboxUserResponse { + IssueInstant: string; + NotAfter: string; + Token: string; + DisplayClaims: { + xui: { + gtg: string; + xid: string; + uhs: string; + agg: string; + usr: string; + utr: string; + prv: string; + }[]; + }; +} + +interface XboxErrorResponse { + error: string; + error_description: string; +} + +export default class XboxConnection extends Connection { + public readonly id = "xbox"; + public readonly authorizeUrl = + "https://login.live.com/oauth20_authorize.srf"; + public readonly tokenUrl = "https://login.live.com/oauth20_token.srf"; + public readonly userInfoUrl = + "https://xsts.auth.xboxlive.com/xsts/authorize"; + public readonly userAuthUrl = + "https://user.auth.xboxlive.com/user/authenticate"; + public readonly scopes = ["Xboxlive.signin", "Xboxlive.offline_access"]; + settings: XboxSettings = new XboxSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as XboxSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + url.searchParams.append("approval_prompt", "auto"); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async getUserToken(token: string): Promise<string> { + return wretch(this.userAuthUrl) + .headers({ + "x-xbl-contract-version": "3", + "Content-Type": "application/json", + Accept: "application/json", + }) + .body( + JSON.stringify({ + RelyingParty: "http://auth.xboxlive.com", + TokenType: "JWT", + Properties: { + AuthMethod: "RPS", + SiteName: "user.auth.xboxlive.com", + RpsTicket: `d=${token}`, + }, + }), + ) + .post() + .json((res: XboxUserResponse) => res.Token) + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${Buffer.from( + `${this.settings.clientId!}:${this.settings.clientSecret!}`, + ).toString("base64")}`, + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code: code, + client_id: this.settings.clientId!, + redirect_uri: this.getRedirectUri(), + scope: this.scopes.join(" "), + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<XboxUserResponse> { + const url = new URL(this.userInfoUrl); + + return wretch(url.toString()) + .headers({ + "x-xbl-contract-version": "3", + "Content-Type": "application/json", + Accept: "application/json", + }) + .body( + JSON.stringify({ + RelyingParty: "http://xboxlive.com", + TokenType: "JWT", + Properties: { + UserTokens: [token], + SandboxId: "RETAIL", + }, + }), + ) + .post() + .json<XboxUserResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userToken = await this.getUserToken(tokenData.access_token); + const userInfo = await this.getUser(userToken); + + const exists = await this.hasConnection( + userId, + userInfo.DisplayClaims.xui[0].xid, + ); + + if (exists) return null; + + return await this.createConnection({ + token_data: { ...tokenData, fetched_at: Date.now() }, + user_id: userId, + external_id: userInfo.DisplayClaims.xui[0].xid, + friend_sync: params.friend_sync, + name: userInfo.DisplayClaims.xui[0].gtg, + type: this.id, + }); + } +} diff --git a/src/connections/Youtube/YoutubeSettings.ts b/src/connections/Youtube/YoutubeSettings.ts new file mode 100644
index 00000000..5d11fa40 --- /dev/null +++ b/src/connections/Youtube/YoutubeSettings.ts
@@ -0,0 +1,5 @@ +export class YoutubeSettings { + enabled: boolean = false; + clientId: string | null = null; + clientSecret: string | null = null; +} diff --git a/src/connections/Youtube/index.ts b/src/connections/Youtube/index.ts new file mode 100644
index 00000000..4d90e452 --- /dev/null +++ b/src/connections/Youtube/index.ts
@@ -0,0 +1,133 @@ +import { + ConnectedAccount, + ConnectedAccountCommonOAuthTokenResponse, + ConnectionCallbackSchema, + ConnectionLoader, + DiscordApiErrors, +} from "@spacebar/util"; +import wretch from "wretch"; +import Connection from "../../util/connections/Connection"; +import { YoutubeSettings } from "./YoutubeSettings"; + +interface YouTubeConnectionChannelListResult { + items: { + snippet: { + // thumbnails: Thumbnails; + title: string; + country: string; + publishedAt: string; + // localized: Localized; + description: string; + }; + kind: string; + etag: string; + id: string; + }[]; + kind: string; + etag: string; + pageInfo: { + resultsPerPage: number; + totalResults: number; + }; +} + +export default class YoutubeConnection extends Connection { + public readonly id = "youtube"; + public readonly authorizeUrl = + "https://accounts.google.com/o/oauth2/v2/auth"; + public readonly tokenUrl = "https://oauth2.googleapis.com/token"; + public readonly userInfoUrl = + "https://www.googleapis.com/youtube/v3/channels?mine=true&part=snippet"; + public readonly scopes = [ + "https://www.googleapis.com/auth/youtube.readonly", + ]; + settings: YoutubeSettings = new YoutubeSettings(); + + init(): void { + this.settings = ConnectionLoader.getConnectionConfig( + this.id, + this.settings, + ) as YoutubeSettings; + } + + getAuthorizationUrl(userId: string): string { + const state = this.createState(userId); + const url = new URL(this.authorizeUrl); + + url.searchParams.append("client_id", this.settings.clientId!); + url.searchParams.append("redirect_uri", this.getRedirectUri()); + url.searchParams.append("response_type", "code"); + url.searchParams.append("scope", this.scopes.join(" ")); + url.searchParams.append("state", state); + return url.toString(); + } + + getTokenUrl(): string { + return this.tokenUrl; + } + + async exchangeCode( + state: string, + code: string, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + this.validateState(state); + + const url = this.getTokenUrl(); + + return wretch(url.toString()) + .headers({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + }) + .body( + new URLSearchParams({ + grant_type: "authorization_code", + code: code, + client_id: this.settings.clientId!, + client_secret: this.settings.clientSecret!, + redirect_uri: this.getRedirectUri(), + }), + ) + .post() + .json<ConnectedAccountCommonOAuthTokenResponse>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async getUser(token: string): Promise<YouTubeConnectionChannelListResult> { + const url = new URL(this.userInfoUrl); + return wretch(url.toString()) + .headers({ + Authorization: `Bearer ${token}`, + }) + .get() + .json<YouTubeConnectionChannelListResult>() + .catch((e) => { + console.error(e); + throw DiscordApiErrors.GENERAL_ERROR; + }); + } + + async handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null> { + const userId = this.getUserId(params.state); + const tokenData = await this.exchangeCode(params.state, params.code!); + const userInfo = await this.getUser(tokenData.access_token); + + const exists = await this.hasConnection(userId, userInfo.items[0].id); + + if (exists) return null; + + return await this.createConnection({ + token_data: { ...tokenData, fetched_at: Date.now() }, + user_id: userId, + external_id: userInfo.items[0].id, + friend_sync: params.friend_sync, + name: userInfo.items[0].snippet.title, + type: this.id, + }); + } +} diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts
index d3b55f0a..de3b3cfe 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts
@@ -43,6 +43,7 @@ import { ReadyGuildDTO, Guild, UserTokenData, + ConnectedAccount, } from "@spacebar/util"; import { Send } from "../util/Send"; import { CLOSECODES, OPCODES } from "../util/Constants"; @@ -78,52 +79,60 @@ export async function onIdentify(this: WebSocket, data: Payload) { this.user_id = decoded.id; const session_id = this.session_id; - const [user, read_states, members, recipients, session, application] = - await Promise.all([ - User.findOneOrFail({ - where: { id: this.user_id }, - relations: ["relationships", "relationships.to", "settings"], - select: [...PrivateUserProjection, "relationships"], - }), - ReadState.find({ where: { user_id: this.user_id } }), - Member.find({ - where: { id: this.user_id }, - select: MemberPrivateProjection, - relations: [ - "guild", - "guild.channels", - "guild.emojis", - "guild.roles", - "guild.stickers", - "user", - "roles", - ], - }), - Recipient.find({ - where: { user_id: this.user_id, closed: false }, - relations: [ - "channel", - "channel.recipients", - "channel.recipients.user", - ], - // TODO: public user selection - }), - // save the session and delete it when the websocket is closed - Session.create({ - user_id: this.user_id, - session_id: session_id, - // TODO: check if status is only one of: online, dnd, offline, idle - status: identify.presence?.status || "offline", //does the session always start as online? - client_info: { - //TODO read from identity - client: "desktop", - os: identify.properties?.os, - version: 0, - }, - activities: [], - }).save(), - Application.findOne({ where: { id: this.user_id } }), - ]); + const [ + user, + read_states, + members, + recipients, + session, + application, + connected_accounts, + ] = await Promise.all([ + User.findOneOrFail({ + where: { id: this.user_id }, + relations: ["relationships", "relationships.to", "settings"], + select: [...PrivateUserProjection, "relationships"], + }), + ReadState.find({ where: { user_id: this.user_id } }), + Member.find({ + where: { id: this.user_id }, + select: MemberPrivateProjection, + relations: [ + "guild", + "guild.channels", + "guild.emojis", + "guild.roles", + "guild.stickers", + "user", + "roles", + ], + }), + Recipient.find({ + where: { user_id: this.user_id, closed: false }, + relations: [ + "channel", + "channel.recipients", + "channel.recipients.user", + ], + // TODO: public user selection + }), + // save the session and delete it when the websocket is closed + Session.create({ + user_id: this.user_id, + session_id: session_id, + // TODO: check if status is only one of: online, dnd, offline, idle + status: identify.presence?.status || "offline", //does the session always start as online? + client_info: { + //TODO read from identity + client: "desktop", + os: identify.properties?.os, + version: 0, + }, + activities: [], + }).save(), + Application.findOne({ where: { id: this.user_id } }), + ConnectedAccount.find({ where: { user_id: this.user_id } }), + ]); if (!user) return this.close(CLOSECODES.Authentication_failed); if (!user.settings) { @@ -304,7 +313,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { private_channels: channels, session_id: session_id, analytics_token: "", // TODO - connected_accounts: [], // TODO + connected_accounts, consents: { personalization: { consented: false, // TODO diff --git a/src/util/config/types/ApiConfiguration.ts b/src/util/config/types/ApiConfiguration.ts
index 4d61521a..e5a317c7 100644 --- a/src/util/config/types/ApiConfiguration.ts +++ b/src/util/config/types/ApiConfiguration.ts
@@ -19,5 +19,5 @@ export class ApiConfiguration { defaultVersion: string = "9"; activeVersions: string[] = ["6", "7", "8", "9"]; - endpointPublic: string = "/api"; + endpointPublic: string | null = null; } diff --git a/src/util/connections/Connection.ts b/src/util/connections/Connection.ts new file mode 100644
index 00000000..26279299 --- /dev/null +++ b/src/util/connections/Connection.ts
@@ -0,0 +1,100 @@ +import crypto from "crypto"; +import { ConnectedAccount } from "../entities"; +import { ConnectedAccountSchema, ConnectionCallbackSchema } from "../schemas"; +import { Config, DiscordApiErrors } from "../util"; + +/** + * A connection that can be used to connect to an external service. + */ +export default abstract class Connection { + id: string; + settings: { enabled: boolean }; + states: Map<string, string> = new Map(); + + abstract init(): void; + + /** + * Generates an authorization url for the connection. + * @param args + */ + abstract getAuthorizationUrl(userId: string): string; + + /** + * Returns the redirect_uri for a connection type + * @returns redirect_uri for this connection + */ + getRedirectUri() { + const endpointPublic = + Config.get().api.endpointPublic ?? "http://localhost:3001"; + return `${endpointPublic}/connections/${this.id}/callback`; + } + + /** + * Processes the callback + * @param args Callback arguments + */ + abstract handleCallback( + params: ConnectionCallbackSchema, + ): Promise<ConnectedAccount | null>; + + /** + * Gets a user id from state + * @param state the state to get the user id from + * @returns the user id associated with the state + */ + getUserId(state: string): string { + if (!this.states.has(state)) throw DiscordApiErrors.INVALID_OAUTH_STATE; + return this.states.get(state) as string; + } + + /** + * Generates a state + * @param user_id The user id to generate a state for. + * @returns a new state + */ + createState(userId: string): string { + const state = crypto.randomBytes(16).toString("hex"); + this.states.set(state, userId); + + return state; + } + + /** + * Takes a state and checks if it is valid, and deletes it. + * @param state The state to check. + */ + validateState(state: string): void { + if (!this.states.has(state)) throw DiscordApiErrors.INVALID_OAUTH_STATE; + this.states.delete(state); + } + + /** + * Creates a Connected Account in the database. + * @param data connected account data + * @returns the new connected account + */ + async createConnection( + data: ConnectedAccountSchema, + ): Promise<ConnectedAccount> { + const ca = ConnectedAccount.create({ ...data }); + await ca.save(); + return ca; + } + + /** + * Checks if a user has an exist connected account for the given extenal id. + * @param userId the user id + * @param externalId the connection id to find + * @returns + */ + async hasConnection(userId: string, externalId: string): Promise<boolean> { + const existing = await ConnectedAccount.findOne({ + where: { + user_id: userId, + external_id: externalId, + }, + }); + + return !!existing; + } +} diff --git a/src/util/connections/ConnectionConfig.ts b/src/util/connections/ConnectionConfig.ts new file mode 100644
index 00000000..4950ae90 --- /dev/null +++ b/src/util/connections/ConnectionConfig.ts
@@ -0,0 +1,79 @@ +import { ConnectionConfigEntity } from "../entities/ConnectionConfigEntity"; + +let config: any; +let pairs: ConnectionConfigEntity[]; + +export const ConnectionConfig = { + init: async function init() { + if (config) return config; + console.log("[ConnectionConfig] Loading configuration..."); + pairs = await ConnectionConfigEntity.find(); + config = pairsToConfig(pairs); + + return this.set(config); + }, + get: function get() { + if (!config) { + return {}; + } + return config; + }, + set: function set(val: Partial<any>) { + if (!config || !val) return; + config = val.merge(config); + + // return applyConfig(config); + return applyConfig(val); + }, +}; + +function applyConfig(val: any) { + async function apply(obj: any, key = ""): Promise<any> { + if (typeof obj === "object" && obj !== null && !(obj instanceof Date)) + return Promise.all( + Object.keys(obj).map((k) => + apply(obj[k], key ? `${key}_${k}` : k), + ), + ); + + let pair = pairs.find((x) => x.key === key); + if (!pair) pair = new ConnectionConfigEntity(); + + pair.key = key; + + if (pair.value !== obj) { + pair.value = obj; + if (!pair.key || pair.key == null) { + console.log(`[ConnectionConfig] WARN: Empty key`); + console.log(pair); + } else return pair.save(); + } + } + + return apply(val); +} + +function pairsToConfig(pairs: ConnectionConfigEntity[]) { + const value: any = {}; + + pairs.forEach((p) => { + const keys = p.key.split("_"); + let obj = value; + let prev = ""; + let prevObj = obj; + let i = 0; + + for (const key of keys) { + if (!isNaN(Number(key)) && !prevObj[prev]?.length) + prevObj[prev] = obj = []; + if (i++ === keys.length - 1) obj[key] = p.value; + else if (!obj[key]) obj[key] = {}; + + prev = key; + prevObj = obj; + obj = obj[key]; + } + }); + + return value; +} diff --git a/src/util/connections/ConnectionLoader.ts b/src/util/connections/ConnectionLoader.ts new file mode 100644
index 00000000..0ca5b9e7 --- /dev/null +++ b/src/util/connections/ConnectionLoader.ts
@@ -0,0 +1,67 @@ +import fs from "fs"; +import path from "path"; +import { OrmUtils } from "../imports"; +import Connection from "./Connection"; +import { ConnectionConfig } from "./ConnectionConfig"; +import { ConnectionStore } from "./ConnectionStore"; + +const root = "dist/connections"; +const connectionsLoaded = false; + +export class ConnectionLoader { + public static async loadConnections() { + if (connectionsLoaded) return; + ConnectionConfig.init(); + const dirs = fs.readdirSync(root).filter((x) => { + try { + fs.readdirSync(path.join(root, x)); + return true; + } catch (e) { + return false; + } + }); + + dirs.forEach(async (x) => { + const modPath = path.resolve(path.join(root, x)); + const mod = new (require(modPath).default)() as Connection; + ConnectionStore.connections.set(mod.id, mod); + + mod.init(); + console.log(`[Connections] Loaded connection '${mod.id}'`); + }); + } + + public static getConnectionConfig(id: string, defaults?: any): any { + let cfg = ConnectionConfig.get()[id]; + if (defaults) { + if (cfg) cfg = Object.assign({}, defaults, cfg); + else { + cfg = defaults; + this.setConnectionConfig(id, cfg); + } + } + + if (!cfg) + console.log( + `[ConnectionConfig/WARN] Getting connection settings for '${id}' returned null! (Did you forget to add settings?)`, + ); + return cfg; + } + + public static async setConnectionConfig( + id: string, + config: Partial<any>, + ): Promise<void> { + if (!config) + console.log( + `[ConnectionConfig/WARN] ${id} tried to set config=null!`, + ); + + await ConnectionConfig.set({ + [id]: Object.assign( + config, + ConnectionLoader.getConnectionConfig(id) || {}, + ), + }); + } +} diff --git a/src/util/connections/ConnectionStore.ts b/src/util/connections/ConnectionStore.ts new file mode 100644
index 00000000..759b6de7 --- /dev/null +++ b/src/util/connections/ConnectionStore.ts
@@ -0,0 +1,7 @@ +import Connection from "./Connection"; +import RefreshableConnection from "./RefreshableConnection"; + +export class ConnectionStore { + public static connections: Map<string, Connection | RefreshableConnection> = + new Map(); +} diff --git a/src/util/connections/RefreshableConnection.ts b/src/util/connections/RefreshableConnection.ts new file mode 100644
index 00000000..87f5f6dd --- /dev/null +++ b/src/util/connections/RefreshableConnection.ts
@@ -0,0 +1,30 @@ +import { ConnectedAccount } from "../entities"; +import { ConnectedAccountCommonOAuthTokenResponse } from "../interfaces"; +import Connection from "./Connection"; + +/** + * A connection that can refresh its token. + */ +export default abstract class RefreshableConnection extends Connection { + refreshEnabled = true; + /** + * Refreshes the token for a connected account. + * @param connectedAccount The connected account to refresh + */ + abstract refreshToken( + connectedAccount: ConnectedAccount, + ): Promise<ConnectedAccountCommonOAuthTokenResponse>; + + /** + * Refreshes the token for a connected account and saves it to the database. + * @param connectedAccount The connected account to refresh + */ + async refresh( + connectedAccount: ConnectedAccount, + ): Promise<ConnectedAccountCommonOAuthTokenResponse> { + const tokenData = await this.refreshToken(connectedAccount); + connectedAccount.token_data = { ...tokenData, fetched_at: Date.now() }; + await connectedAccount.save(); + return tokenData; + } +} diff --git a/src/util/connections/index.ts b/src/util/connections/index.ts new file mode 100644
index 00000000..8d20bf27 --- /dev/null +++ b/src/util/connections/index.ts
@@ -0,0 +1,5 @@ +export * from "./Connection"; +export * from "./ConnectionConfig"; +export * from "./ConnectionLoader"; +export * from "./ConnectionStore"; +export * from "./RefreshableConnection"; diff --git a/src/util/dtos/ConnectedAccountDTO.ts b/src/util/dtos/ConnectedAccountDTO.ts new file mode 100644
index 00000000..a3618fd1 --- /dev/null +++ b/src/util/dtos/ConnectedAccountDTO.ts
@@ -0,0 +1,43 @@ +import { ConnectedAccount } from "../entities"; + +export class ConnectedAccountDTO { + id: string; + user_id: string; + access_token?: string; + friend_sync?: boolean; + name: string; + revoked?: boolean; + show_activity?: number; + type: string; + verified?: boolean; + visibility?: number; + integrations?: string[]; + metadata_?: any; + metadata_visibility?: number; + two_way_link?: boolean; + + constructor( + connectedAccount: ConnectedAccount, + with_token: boolean = false, + ) { + this.id = connectedAccount.external_id; + this.user_id = connectedAccount.user_id; + this.access_token = + connectedAccount.token_data && with_token + ? connectedAccount.token_data.access_token + : undefined; + this.friend_sync = connectedAccount.friend_sync; + this.name = connectedAccount.name; + this.revoked = connectedAccount.revoked; + this.show_activity = connectedAccount.show_activity; + this.type = connectedAccount.type; + this.verified = connectedAccount.verified; + this.visibility = +(connectedAccount.visibility || false); + this.integrations = connectedAccount.integrations; + this.metadata_ = connectedAccount.metadata_; + this.metadata_visibility = +( + connectedAccount.metadata_visibility || false + ); + this.two_way_link = connectedAccount.two_way_link; + } +} diff --git a/src/util/dtos/index.ts b/src/util/dtos/index.ts
index 04cd7b72..b7094227 100644 --- a/src/util/dtos/index.ts +++ b/src/util/dtos/index.ts
@@ -16,6 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ +export * from "./ConnectedAccountDTO"; export * from "./DmChannelDTO"; export * from "./ReadyGuildDTO"; export * from "./UserDTO"; diff --git a/src/util/entities/ConnectedAccount.ts b/src/util/entities/ConnectedAccount.ts
index 33550197..5dd21250 100644 --- a/src/util/entities/ConnectedAccount.ts +++ b/src/util/entities/ConnectedAccount.ts
@@ -17,6 +17,7 @@ */ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; +import { ConnectedAccountTokenData } from "../interfaces"; import { BaseClass } from "./BaseClass"; import { User } from "./User"; @@ -27,6 +28,9 @@ export type PublicConnectedAccount = Pick< @Entity("connected_accounts") export class ConnectedAccount extends BaseClass { + @Column() + external_id: string; + @Column({ nullable: true }) @RelationId((account: ConnectedAccount) => account.user) user_id: string; @@ -38,26 +42,44 @@ export class ConnectedAccount extends BaseClass { user: User; @Column({ select: false }) - access_token: string; - - @Column({ select: false }) - friend_sync: boolean; + friend_sync?: boolean = false; @Column() name: string; @Column({ select: false }) - revoked: boolean; + revoked?: boolean = false; @Column({ select: false }) - show_activity: boolean; + show_activity?: number = 0; @Column() type: string; @Column() - verified: boolean; + verified?: boolean = true; @Column({ select: false }) - visibility: number; + visibility?: number = 0; + + @Column({ type: "simple-array" }) + integrations?: string[] = []; + + @Column({ type: "simple-json", name: "metadata", nullable: true }) + metadata_?: any; + + @Column() + metadata_visibility?: number = 0; + + @Column() + two_way_link?: boolean = false; + + @Column({ select: false, nullable: true, type: "simple-json" }) + token_data?: ConnectedAccountTokenData | null; + + async revoke() { + this.revoked = true; + this.token_data = null; + await this.save(); + } } diff --git a/src/util/entities/ConnectionConfigEntity.ts b/src/util/entities/ConnectionConfigEntity.ts new file mode 100644
index 00000000..9c212b15 --- /dev/null +++ b/src/util/entities/ConnectionConfigEntity.ts
@@ -0,0 +1,11 @@ +import { Column, Entity } from "typeorm"; +import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass"; + +@Entity("connection_config") +export class ConnectionConfigEntity extends BaseClassWithoutId { + @PrimaryIdColumn() + key: string; + + @Column({ type: "simple-json", nullable: true }) + value: number | boolean | null | string | Date | undefined; +} diff --git a/src/util/entities/index.ts b/src/util/entities/index.ts
index 9b01aa77..aa943dca 100644 --- a/src/util/entities/index.ts +++ b/src/util/entities/index.ts
@@ -27,6 +27,7 @@ export * from "./Channel"; export * from "./ClientRelease"; export * from "./Config"; export * from "./ConnectedAccount"; +export * from "./ConnectionConfigEntity"; export * from "./EmbedCache"; export * from "./Emoji"; export * from "./Encryption"; diff --git a/src/util/index.ts b/src/util/index.ts
index 9174c3a1..c3d32bba 100644 --- a/src/util/index.ts +++ b/src/util/index.ts
@@ -25,3 +25,4 @@ export * from "./dtos/index"; export * from "./schemas"; export * from "./imports"; export * from "./config"; +export * from "./connections"; diff --git a/src/util/interfaces/ConnectedAccount.ts b/src/util/interfaces/ConnectedAccount.ts new file mode 100644
index 00000000..ede02f6d --- /dev/null +++ b/src/util/interfaces/ConnectedAccount.ts
@@ -0,0 +1,17 @@ +export interface ConnectedAccountCommonOAuthTokenResponse { + access_token: string; + token_type: string; + scope: string; + refresh_token?: string; + expires_in?: number; +} + +export interface ConnectedAccountTokenData { + access_token: string; + token_type?: string; + scope?: string; + refresh_token?: string; + expires_in?: number; + expires_at?: number; + fetched_at: number; +} diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts
index 3a0eadc5..76a5f8d0 100644 --- a/src/util/interfaces/Event.ts +++ b/src/util/interfaces/Event.ts
@@ -420,6 +420,10 @@ export interface UserDeleteEvent extends Event { }; } +export interface UserConnectionsUpdateEvent extends Event { + event: "USER_CONNECTIONS_UPDATE"; +} + export interface VoiceStateUpdateEvent extends Event { event: "VOICE_STATE_UPDATE"; data: VoiceState & { @@ -561,6 +565,7 @@ export type EventData = | TypingStartEvent | UserUpdateEvent | UserDeleteEvent + | UserConnectionsUpdateEvent | VoiceStateUpdateEvent | VoiceServerUpdateEvent | WebhooksUpdateEvent @@ -612,6 +617,7 @@ export enum EVENTEnum { TypingStart = "TYPING_START", UserUpdate = "USER_UPDATE", UserDelete = "USER_DELETE", + UserConnectionsUpdate = "USER_CONNECTIONS_UPDATE", WebhooksUpdate = "WEBHOOKS_UPDATE", InteractionCreate = "INTERACTION_CREATE", VoiceStateUpdate = "VOICE_STATE_UPDATE", @@ -663,6 +669,7 @@ export type EVENT = | "TYPING_START" | "USER_UPDATE" | "USER_DELETE" + | "USER_CONNECTIONS_UPDATE" | "USER_NOTE_UPDATE" | "WEBHOOKS_UPDATE" | "INTERACTION_CREATE" diff --git a/src/util/interfaces/index.ts b/src/util/interfaces/index.ts
index e37b8874..c6a00458 100644 --- a/src/util/interfaces/index.ts +++ b/src/util/interfaces/index.ts
@@ -17,7 +17,8 @@ */ export * from "./Activity"; -export * from "./Presence"; -export * from "./Interaction"; +export * from "./ConnectedAccount"; export * from "./Event"; +export * from "./Interaction"; +export * from "./Presence"; export * from "./Status"; diff --git a/src/util/schemas/ConnectedAccountSchema.ts b/src/util/schemas/ConnectedAccountSchema.ts new file mode 100644
index 00000000..fa834bd6 --- /dev/null +++ b/src/util/schemas/ConnectedAccountSchema.ts
@@ -0,0 +1,18 @@ +import { ConnectedAccountTokenData } from "../interfaces"; + +export interface ConnectedAccountSchema { + external_id: string; + user_id: string; + token_data?: ConnectedAccountTokenData; + friend_sync?: boolean; + name: string; + revoked?: boolean; + show_activity?: number; + type: string; + verified?: boolean; + visibility?: number; + integrations?: string[]; + metadata_?: any; + metadata_visibility?: number; + two_way_link?: boolean; +} diff --git a/src/util/schemas/ConnectionCallbackSchema.ts b/src/util/schemas/ConnectionCallbackSchema.ts new file mode 100644
index 00000000..09ae8a46 --- /dev/null +++ b/src/util/schemas/ConnectionCallbackSchema.ts
@@ -0,0 +1,7 @@ +export interface ConnectionCallbackSchema { + code?: string; + state: string; + insecure: boolean; + friend_sync: boolean; + openid_params?: any; // TODO: types +} diff --git a/src/util/schemas/ConnectionUpdateSchema.ts b/src/util/schemas/ConnectionUpdateSchema.ts new file mode 100644
index 00000000..eb6c0916 --- /dev/null +++ b/src/util/schemas/ConnectionUpdateSchema.ts
@@ -0,0 +1,4 @@ +export interface ConnectionUpdateSchema { + visibility?: boolean; + show_activity?: boolean; +} diff --git a/src/util/schemas/index.ts b/src/util/schemas/index.ts
index 498b5ad7..2d254752 100644 --- a/src/util/schemas/index.ts +++ b/src/util/schemas/index.ts
@@ -30,6 +30,9 @@ export * from "./ChannelModifySchema"; export * from "./ChannelPermissionOverwriteSchema"; export * from "./ChannelReorderSchema"; export * from "./CodesVerificationSchema"; +export * from "./ConnectedAccountSchema"; +export * from "./ConnectionCallbackSchema"; +export * from "./ConnectionUpdateSchema"; export * from "./DmChannelCreateSchema"; export * from "./EmojiCreateSchema"; export * from "./EmojiModifySchema"; diff --git a/src/util/util/Constants.ts b/src/util/util/Constants.ts
index d4adb54e..e68bb0b7 100644 --- a/src/util/util/Constants.ts +++ b/src/util/util/Constants.ts
@@ -578,6 +578,7 @@ export const DiscordApiErrors = { UNKNOWN_EMOJI: new ApiError("Unknown emoji", 10014), UNKNOWN_WEBHOOK: new ApiError("Unknown webhook", 10015), UNKNOWN_WEBHOOK_SERVICE: new ApiError("Unknown webhook service", 10016), + UNKNOWN_CONNECTION: new ApiError("Unknown connection", 10017, 400), UNKNOWN_SESSION: new ApiError("Unknown session", 10020), UNKNOWN_BAN: new ApiError("Unknown ban", 10026), UNKNOWN_SKU: new ApiError("Unknown SKU", 10027), @@ -786,6 +787,11 @@ export const DiscordApiErrors = { 40006, ), USER_BANNED: new ApiError("The user is banned from this guild", 40007), + CONNECTION_REVOKED: new ApiError( + "The connection has been revoked", + 40012, + 400, + ), TARGET_USER_IS_NOT_CONNECTED_TO_VOICE: new ApiError( "Target user is not connected to voice", 40032,