3 Commits
0.3.0 ... 0.3.1

Author SHA1 Message Date
MapleLeaf
c87b6f9514 release v0.3.1 2022-01-11 16:49:09 -06:00
MapleLeaf
dbbcf0f79c build before release 2022-01-11 16:48:22 -06:00
Darius
4e089bae15 Add useInstance (#6) 2022-01-11 16:39:35 -06:00
12 changed files with 232 additions and 91 deletions

View File

@@ -12,7 +12,7 @@ export function pruneNullishValues<T>(input: T): PruneNullishValues<T> {
const result: any = {} const result: any = {}
for (const [key, value] of Object.entries(input)) { for (const [key, value] of Object.entries(input)) {
if (value != undefined) { if (value != undefined) {
result[key] = isObject(value) ? pruneNullishValues(value) : value result[key] = pruneNullishValues(value)
} }
} }
return result return result

View File

@@ -0,0 +1,20 @@
import * as React from "react"
import { raise } from "../../helpers/raise"
import type { ReacordInstance } from "./instance"
const Context = React.createContext<ReacordInstance | undefined>(undefined)
export const InstanceProvider = Context.Provider
/**
* Get the associated instance for the current component.
*
* @category Core
* @see https://reacord.fly.dev/guides/use-instance
*/
export function useInstance(): ReacordInstance {
return (
React.useContext(Context) ??
raise("Could not find instance, was this component rendered via Reacord?")
)
}

View File

@@ -154,7 +154,8 @@ export class ReacordDiscordJs extends Reacord {
// todo please dear god clean this up // todo please dear god clean this up
const channel: ChannelInfo = interaction.channel const channel: ChannelInfo = interaction.channel
? { ? {
...pick(pruneNullishValues(interaction.channel), [ ...pruneNullishValues(
pick(interaction.channel, [
"topic", "topic",
"nsfw", "nsfw",
"lastMessageId", "lastMessageId",
@@ -162,6 +163,7 @@ export class ReacordDiscordJs extends Reacord {
"parentId", "parentId",
"rateLimitPerUser", "rateLimitPerUser",
]), ]),
),
id: interaction.channelId, id: interaction.channelId,
} }
: raise("Non-channel interactions are not supported") : raise("Non-channel interactions are not supported")
@@ -190,7 +192,8 @@ export class ReacordDiscordJs extends Reacord {
const member: GuildMemberInfo | undefined = const member: GuildMemberInfo | undefined =
interaction.member instanceof Discord.GuildMember interaction.member instanceof Discord.GuildMember
? { ? {
...pick(pruneNullishValues(interaction.member), [ ...pruneNullishValues(
pick(interaction.member, [
"id", "id",
"nick", "nick",
"displayName", "displayName",
@@ -199,6 +202,7 @@ export class ReacordDiscordJs extends Reacord {
"color", "color",
"pending", "pending",
]), ]),
),
displayName: interaction.member.displayName, displayName: interaction.member.displayName,
roles: [...interaction.member.roles.cache.map((role) => role.id)], roles: [...interaction.member.roles.cache.map((role) => role.id)],
joinedAt: interaction.member.joinedAt?.toISOString(), joinedAt: interaction.member.joinedAt?.toISOString(),
@@ -210,18 +214,15 @@ export class ReacordDiscordJs extends Reacord {
const guild: GuildInfo | undefined = interaction.guild const guild: GuildInfo | undefined = interaction.guild
? { ? {
...pick(pruneNullishValues(interaction.guild), ["id", "name"]), ...pruneNullishValues(pick(interaction.guild, ["id", "name"])),
member: member ?? raise("unexpected: member is undefined"), member: member ?? raise("unexpected: member is undefined"),
} }
: undefined : undefined
const user: UserInfo = { const user: UserInfo = {
...pick(pruneNullishValues(interaction.user), [ ...pruneNullishValues(
"id", pick(interaction.user, ["id", "username", "discriminator", "tag"]),
"username", ),
"discriminator",
"tag",
]),
avatarUrl: interaction.user.avatarURL()!, avatarUrl: interaction.user.avatarURL()!,
accentColor: interaction.user.accentColor ?? undefined, accentColor: interaction.user.accentColor ?? undefined,
} }

View File

@@ -1,8 +1,10 @@
import type { ReactNode } from "react" import type { ReactNode } from "react"
import React from "react"
import type { ComponentInteraction } from "../internal/interaction" import type { ComponentInteraction } from "../internal/interaction"
import { reconciler } from "../internal/reconciler.js" import { reconciler } from "../internal/reconciler.js"
import type { Renderer } from "../internal/renderers/renderer" import type { Renderer } from "../internal/renderers/renderer"
import type { ReacordInstance } from "./instance" import type { ReacordInstance } from "./instance"
import { InstanceProvider } from "./instance-context"
/** /**
* @category Core * @category Core
@@ -47,13 +49,12 @@ export abstract class Reacord {
const container = reconciler.createContainer(renderer, 0, false, {}) const container = reconciler.createContainer(renderer, 0, false, {})
if (initialContent !== undefined) { const instance: ReacordInstance = {
reconciler.updateContainer(initialContent, container)
}
return {
render: (content: ReactNode) => { render: (content: ReactNode) => {
reconciler.updateContainer(content, container) reconciler.updateContainer(
<InstanceProvider value={instance}>{content}</InstanceProvider>,
container,
)
}, },
deactivate: () => { deactivate: () => {
this.deactivate(renderer) this.deactivate(renderer)
@@ -63,6 +64,12 @@ export abstract class Reacord {
renderer.destroy() renderer.destroy()
}, },
} }
if (initialContent !== undefined) {
instance.render(initialContent)
}
return instance
} }
private deactivate(renderer: Renderer) { private deactivate(renderer: Renderer) {

View File

@@ -13,5 +13,6 @@ export * from "./core/components/link"
export * from "./core/components/option" export * from "./core/components/option"
export * from "./core/components/select" export * from "./core/components/select"
export * from "./core/instance" export * from "./core/instance"
export { useInstance } from "./core/instance-context"
export * from "./core/reacord" export * from "./core/reacord"
export * from "./core/reacord-discord-js" export * from "./core/reacord-discord-js"

View File

@@ -2,7 +2,7 @@
"name": "reacord", "name": "reacord",
"type": "module", "type": "module",
"description": "Create interactive Discord messages using React.", "description": "Create interactive Discord messages using React.",
"version": "0.2.0", "version": "0.3.1",
"types": "./dist/main.d.ts", "types": "./dist/main.d.ts",
"files": [ "files": [
"dist" "dist"
@@ -23,14 +23,14 @@
"test": "vitest --coverage --no-watch", "test": "vitest --coverage --no-watch",
"test-dev": "vitest", "test-dev": "vitest",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"playground": "nodemon --exec esmo --ext ts,tsx ./playground/main.tsx", "playground": "nodemon --exec esmo --ext ts,tsx --inspect=5858 --enable-source-maps ./playground/main.tsx",
"release": "release-it" "release": "pnpm build && release-it"
}, },
"dependencies": { "dependencies": {
"@types/node": "*", "@types/node": "*",
"@types/react": "*", "@types/react": "*",
"@types/react-reconciler": "^0.26.4", "@types/react-reconciler": "^0.26.4",
"nanoid": "^3.1.30", "nanoid": "^3.1.31",
"react-reconciler": "^0.26.2", "react-reconciler": "^0.26.2",
"rxjs": "^7.5.2" "rxjs": "^7.5.2"
}, },
@@ -47,7 +47,7 @@
"@types/lodash-es": "^4.17.5", "@types/lodash-es": "^4.17.5",
"c8": "^7.11.0", "c8": "^7.11.0",
"discord.js": "^13.5.1", "discord.js": "^13.5.1",
"dotenv": "^10.0.0", "dotenv": "^11.0.0",
"esbuild": "latest", "esbuild": "latest",
"esbuild-jest": "^0.5.0", "esbuild-jest": "^0.5.0",
"esmo": "^0.13.0", "esmo": "^0.13.0",
@@ -61,7 +61,7 @@
"type-fest": "^2.9.0", "type-fest": "^2.9.0",
"typescript": "^4.5.4", "typescript": "^4.5.4",
"vite": "^2.7.10", "vite": "^2.7.10",
"vitest": "^0.0.140" "vitest": "^0.0.141"
}, },
"resolutions": { "resolutions": {
"esbuild": "latest" "esbuild": "latest"

View File

@@ -1,7 +1,7 @@
import { Client } from "discord.js" import { Client } from "discord.js"
import "dotenv/config" import "dotenv/config"
import React from "react" import React from "react"
import { Button, ReacordDiscordJs } from "../library/main" import { Button, ReacordDiscordJs, useInstance } from "../library/main"
import { createCommandHandler } from "./command-handler" import { createCommandHandler } from "./command-handler"
import { Counter } from "./counter" import { Counter } from "./counter"
import { FruitSelect } from "./fruit-select" import { FruitSelect } from "./fruit-select"
@@ -93,6 +93,17 @@ createCommandHandler(client, [
) )
}, },
}, },
{
name: "delete-this",
description: "delete this",
run: (interaction) => {
function DeleteThis() {
const instance = useInstance()
return <Button label="delete this" onClick={() => instance.destroy()} />
}
reacord.reply(interaction, <DeleteThis />)
},
},
]) ])
await client.login(process.env.TEST_BOT_TOKEN) await client.login(process.env.TEST_BOT_TOKEN)

View File

@@ -37,6 +37,8 @@ import { InteractionReplyRenderer } from "../library/internal/renderers/interact
const nextTickPromise = promisify(nextTick) const nextTickPromise = promisify(nextTick)
export type MessageSample = ReturnType<ReacordTester["sampleMessages"]>[0]
/** /**
* A Record adapter for automated tests. WIP * A Record adapter for automated tests. WIP
*/ */
@@ -51,33 +53,32 @@ export class ReacordTester extends Reacord {
return [...this.messageContainer] return [...this.messageContainer]
} }
override send(): ReacordInstance { override send(initialContent?: ReactNode): ReacordInstance {
return this.createInstance( return this.createInstance(
new ChannelMessageRenderer(new TestChannel(this.messageContainer)), new ChannelMessageRenderer(new TestChannel(this.messageContainer)),
initialContent,
) )
} }
override reply(): ReacordInstance { override reply(initialContent?: ReactNode): ReacordInstance {
return this.createInstance( return this.createInstance(
new InteractionReplyRenderer( new InteractionReplyRenderer(
new TestCommandInteraction(this.messageContainer), new TestCommandInteraction(this.messageContainer),
), ),
initialContent,
) )
} }
override ephemeralReply(): ReacordInstance { override ephemeralReply(initialContent?: ReactNode): ReacordInstance {
return this.reply() return this.reply(initialContent)
} }
async assertMessages(expected: ReturnType<this["sampleMessages"]>) { async assertMessages(expected: MessageSample[]) {
await nextTickPromise() await nextTickPromise()
expect(this.sampleMessages()).toEqual(expected) expect(this.sampleMessages()).toEqual(expected)
} }
async assertRender( async assertRender(content: ReactNode, expected: MessageSample[]) {
content: ReactNode,
expected: ReturnType<this["sampleMessages"]>,
) {
const instance = this.reply() const instance = this.reply()
instance.render(content) instance.render(content)
await this.assertMessages(expected) await this.assertMessages(expected)
@@ -274,11 +275,11 @@ class TestComponentEvent {
guild: GuildInfo = {} as any // todo guild: GuildInfo = {} as any // todo
reply(content?: ReactNode): ReacordInstance { reply(content?: ReactNode): ReacordInstance {
return this.tester.reply() return this.tester.reply(content)
} }
ephemeralReply(content?: ReactNode): ReacordInstance { ephemeralReply(content?: ReactNode): ReacordInstance {
return this.tester.ephemeralReply() return this.tester.ephemeralReply(content)
} }
} }

View File

@@ -0,0 +1,72 @@
import React from "react"
import { describe, expect, it } from "vitest"
import type { ReacordInstance } from "../library/main"
import { Button, useInstance } from "../library/main"
import type { MessageSample } from "./test-adapter"
import { ReacordTester } from "./test-adapter"
describe("useInstance", () => {
it("returns the instance of itself", async () => {
let instanceFromHook: ReacordInstance | undefined
function TestComponent({ name }: { name: string }) {
const instance = useInstance()
instanceFromHook ??= instance
return (
<>
<Button
label={`create ${name}`}
onClick={(event) => {
event.reply(<TestComponent name="child" />)
}}
/>
<Button
label={`destroy ${name}`}
onClick={() => instance.destroy()}
/>
</>
)
}
function messageOutput(name: string): MessageSample {
return {
content: "",
embeds: [],
actionRows: [
[
{
type: "button",
label: `create ${name}`,
style: "secondary",
},
{
type: "button",
label: `destroy ${name}`,
style: "secondary",
},
],
],
}
}
const tester = new ReacordTester()
const instance = tester.send(<TestComponent name="parent" />)
await tester.assertMessages([messageOutput("parent")])
expect(instanceFromHook).toBe(instance)
tester.findButtonByLabel("create parent").click()
await tester.assertMessages([
messageOutput("parent"),
messageOutput("child"),
])
// this test ensures that the only the child instance is destroyed,
// and not the parent instance
tester.findButtonByLabel("destroy child").click()
await tester.assertMessages([messageOutput("parent")])
tester.findButtonByLabel("destroy parent").click()
await tester.assertMessages([])
})
})

View File

@@ -0,0 +1,26 @@
---
meta:
title: useInstance
description: Using useInstance to get the current instance within a component
---
# useInstance
You can use `useInstance` to get the current [instance](/guides/sending-messages) within a component. This can be used to let a component destroy or deactivate itself.
```jsx
import { Button, useInstance } from "reacord"
function SelfDestruct() {
const instance = useInstance()
return (
<Button
style="danger"
label="delete this"
onClick={() => instance.destroy()}
/>
)
}
reacord.send(channelId, <SelfDestruct />)
```

View File

@@ -25,7 +25,7 @@
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"remix": "^1.1.1", "remix": "^1.1.1",
"remix-tailwind": "^0.2.1", "remix-tailwind": "^0.2.1",
"tailwindcss": "^3.0.12" "tailwindcss": "^3.0.13"
}, },
"devDependencies": { "devDependencies": {
"@remix-run/dev": "^1.1.1", "@remix-run/dev": "^1.1.1",
@@ -39,7 +39,7 @@
"concurrently": "^7.0.0", "concurrently": "^7.0.0",
"cypress": "^9.2.1", "cypress": "^9.2.1",
"execa": "^6.0.0", "execa": "^6.0.0",
"rehype-prism-plus": "^1.3.0", "rehype-prism-plus": "^1.3.1",
"typedoc": "^0.22.10", "typedoc": "^0.22.10",
"typescript": "^4.5.4", "typescript": "^4.5.4",
"wait-on": "^6.0.0" "wait-on": "^6.0.0"

82
pnpm-lock.yaml generated
View File

@@ -44,12 +44,12 @@ importers:
'@types/react-reconciler': ^0.26.4 '@types/react-reconciler': ^0.26.4
c8: ^7.11.0 c8: ^7.11.0
discord.js: ^13.5.1 discord.js: ^13.5.1
dotenv: ^10.0.0 dotenv: ^11.0.0
esbuild: latest esbuild: latest
esbuild-jest: ^0.5.0 esbuild-jest: ^0.5.0
esmo: ^0.13.0 esmo: ^0.13.0
lodash-es: ^4.17.21 lodash-es: ^4.17.21
nanoid: ^3.1.30 nanoid: ^3.1.31
nodemon: ^2.0.15 nodemon: ^2.0.15
prettier: ^2.5.1 prettier: ^2.5.1
pretty-ms: ^7.0.1 pretty-ms: ^7.0.1
@@ -61,19 +61,19 @@ importers:
type-fest: ^2.9.0 type-fest: ^2.9.0
typescript: ^4.5.4 typescript: ^4.5.4
vite: ^2.7.10 vite: ^2.7.10
vitest: ^0.0.140 vitest: ^0.0.141
dependencies: dependencies:
'@types/node': 17.0.8 '@types/node': 17.0.8
'@types/react': 17.0.38 '@types/react': 17.0.38
'@types/react-reconciler': 0.26.4 '@types/react-reconciler': 0.26.4
nanoid: 3.1.30 nanoid: 3.1.31
react-reconciler: 0.26.2_react@17.0.2 react-reconciler: 0.26.2_react@17.0.2
rxjs: 7.5.2 rxjs: 7.5.2
devDependencies: devDependencies:
'@types/lodash-es': 4.17.5 '@types/lodash-es': 4.17.5
c8: 7.11.0 c8: 7.11.0
discord.js: 13.5.1 discord.js: 13.5.1
dotenv: 10.0.0 dotenv: 11.0.0
esbuild: 0.14.11 esbuild: 0.14.11
esbuild-jest: 0.5.0_esbuild@0.14.11 esbuild-jest: 0.5.0_esbuild@0.14.11
esmo: 0.13.0_typescript@4.5.4 esmo: 0.13.0_typescript@4.5.4
@@ -87,7 +87,7 @@ importers:
type-fest: 2.9.0 type-fest: 2.9.0
typescript: 4.5.4 typescript: 4.5.4
vite: 2.7.10 vite: 2.7.10
vitest: 0.0.140_c8@7.11.0 vitest: 0.0.141_c8@7.11.0
packages/website: packages/website:
specifiers: specifiers:
@@ -114,10 +114,10 @@ importers:
reacord: workspace:* reacord: workspace:*
react: ^17.0.2 react: ^17.0.2
react-dom: ^17.0.2 react-dom: ^17.0.2
rehype-prism-plus: ^1.3.0 rehype-prism-plus: ^1.3.1
remix: ^1.1.1 remix: ^1.1.1
remix-tailwind: ^0.2.1 remix-tailwind: ^0.2.1
tailwindcss: ^3.0.12 tailwindcss: ^3.0.13
typedoc: ^0.22.10 typedoc: ^0.22.10
typescript: ^4.5.4 typescript: ^4.5.4
wait-on: ^6.0.0 wait-on: ^6.0.0
@@ -125,7 +125,7 @@ importers:
'@heroicons/react': 1.0.5_react@17.0.2 '@heroicons/react': 1.0.5_react@17.0.2
'@remix-run/react': 1.1.1_react-dom@17.0.2+react@17.0.2 '@remix-run/react': 1.1.1_react-dom@17.0.2+react@17.0.2
'@remix-run/serve': 1.1.1_react-dom@17.0.2+react@17.0.2 '@remix-run/serve': 1.1.1_react-dom@17.0.2+react@17.0.2
'@tailwindcss/typography': 0.5.0_tailwindcss@3.0.12 '@tailwindcss/typography': 0.5.0_tailwindcss@3.0.13
autoprefixer: 10.4.2_postcss@8.4.5 autoprefixer: 10.4.2_postcss@8.4.5
clsx: 1.1.1 clsx: 1.1.1
fast-glob: 3.2.10 fast-glob: 3.2.10
@@ -135,8 +135,8 @@ importers:
react: 17.0.2 react: 17.0.2
react-dom: 17.0.2_react@17.0.2 react-dom: 17.0.2_react@17.0.2
remix: 1.1.1 remix: 1.1.1
remix-tailwind: 0.2.1_7b354341833d038270b90ce5c50910b6 remix-tailwind: 0.2.1_8cbcda2c835593b4e5c6cfe0d6a6e9a3
tailwindcss: 3.0.12_ef48b3b8837f8a23677bffe8f9cd866d tailwindcss: 3.0.13_ef48b3b8837f8a23677bffe8f9cd866d
devDependencies: devDependencies:
'@remix-run/dev': 1.1.1 '@remix-run/dev': 1.1.1
'@remix-run/node': 1.1.1_react-dom@17.0.2+react@17.0.2 '@remix-run/node': 1.1.1_react-dom@17.0.2+react@17.0.2
@@ -149,7 +149,7 @@ importers:
concurrently: 7.0.0 concurrently: 7.0.0
cypress: 9.2.1 cypress: 9.2.1
execa: 6.0.0 execa: 6.0.0
rehype-prism-plus: 1.3.0 rehype-prism-plus: 1.3.1
typedoc: 0.22.10_typescript@4.5.4 typedoc: 0.22.10_typescript@4.5.4
typescript: 4.5.4 typescript: 4.5.4
wait-on: 6.0.0 wait-on: 6.0.0
@@ -968,7 +968,7 @@ packages:
defer-to-connect: 2.0.1 defer-to-connect: 2.0.1
dev: true dev: true
/@tailwindcss/typography/0.5.0_tailwindcss@3.0.12: /@tailwindcss/typography/0.5.0_tailwindcss@3.0.13:
resolution: {integrity: sha512-1p/3C6C+JJziS/ghtG8ACYalbA2SyLJY27Pm33cVTlAoY6VQ7zfm2H64cPxUMBkVIlWXTtWHhZcZJPobMRmQAA==} resolution: {integrity: sha512-1p/3C6C+JJziS/ghtG8ACYalbA2SyLJY27Pm33cVTlAoY6VQ7zfm2H64cPxUMBkVIlWXTtWHhZcZJPobMRmQAA==}
peerDependencies: peerDependencies:
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || insiders' tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || insiders'
@@ -977,7 +977,7 @@ packages:
lodash.isplainobject: 4.0.6 lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2 lodash.merge: 4.6.2
lodash.uniq: 4.5.0 lodash.uniq: 4.5.0
tailwindcss: 3.0.12_ef48b3b8837f8a23677bffe8f9cd866d tailwindcss: 3.0.13_ef48b3b8837f8a23677bffe8f9cd866d
dev: false dev: false
/@testing-library/cypress/8.0.2_cypress@9.2.1: /@testing-library/cypress/8.0.2_cypress@9.2.1:
@@ -2010,7 +2010,7 @@ packages:
hasBin: true hasBin: true
dependencies: dependencies:
caniuse-lite: 1.0.30001298 caniuse-lite: 1.0.30001298
electron-to-chromium: 1.4.40 electron-to-chromium: 1.4.41
escalade: 3.1.1 escalade: 3.1.1
node-releases: 2.0.1 node-releases: 2.0.1
picocolors: 1.0.0 picocolors: 1.0.0
@@ -2957,9 +2957,9 @@ packages:
is-obj: 2.0.0 is-obj: 2.0.0
dev: true dev: true
/dotenv/10.0.0: /dotenv/11.0.0:
resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} resolution: {integrity: sha512-Fp/b504Y5W+e+FpCxTFMUZ7ZEQkQYF0rx+KZtmwixJxGQbLHrhCwo3FjZgNC8vIfrSi29PABNbMoCGD9YoiXbQ==}
engines: {node: '>=10'} engines: {node: '>=12'}
dev: true dev: true
/duplexer3/0.1.4: /duplexer3/0.1.4:
@@ -2977,8 +2977,8 @@ packages:
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
dev: false dev: false
/electron-to-chromium/1.4.40: /electron-to-chromium/1.4.41:
resolution: {integrity: sha512-j+eVIyQGt2EU5xPWUblhpp5P5z5xyAdRgzogBgfe2F5JGV17gr9pfzWBua6DlPL00LavbOjxubWkWkbVQe9Wlw==} resolution: {integrity: sha512-VQEXEJc+8rJIva85H8EPtB5Ux9g8TzkNGBanqphM9ZWMZ34elueKJ+5g+BPhz3Lk8gkujfQRcIZ+fpA0btUIuw==}
/emoji-regex/8.0.0: /emoji-regex/8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -4359,7 +4359,7 @@ packages:
'@types/unist': 2.0.6 '@types/unist': 2.0.6
hastscript: 7.0.2 hastscript: 7.0.2
property-information: 6.1.1 property-information: 6.1.1
vfile: 5.2.1 vfile: 5.3.0
vfile-location: 4.0.1 vfile-location: 4.0.1
web-namespaces: 2.0.1 web-namespaces: 2.0.1
dev: true dev: true
@@ -6018,8 +6018,8 @@ packages:
thenify-all: 1.6.0 thenify-all: 1.6.0
dev: true dev: true
/nanoid/3.1.30: /nanoid/3.1.31:
resolution: {integrity: sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==} resolution: {integrity: sha512-ZivnJm0o9bb13p2Ot5CpgC2rQdzB9Uxm/mFZweqm5eMViqOJe3PV6LU2E30SiLgheesmcPrjquqraoolONSA0A==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
@@ -6503,7 +6503,7 @@ packages:
dependencies: dependencies:
is-ssh: 1.3.3 is-ssh: 1.3.3
protocols: 1.4.8 protocols: 1.4.8
qs: 6.10.2 qs: 6.10.3
query-string: 6.14.1 query-string: 6.14.1
dev: true dev: true
@@ -6681,7 +6681,7 @@ packages:
resolution: {integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==} resolution: {integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
dependencies: dependencies:
nanoid: 3.1.30 nanoid: 3.1.31
picocolors: 1.0.0 picocolors: 1.0.0
source-map-js: 1.0.1 source-map-js: 1.0.1
@@ -6802,8 +6802,8 @@ packages:
escape-goat: 2.1.1 escape-goat: 2.1.1
dev: true dev: true
/qs/6.10.2: /qs/6.10.3:
resolution: {integrity: sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==} resolution: {integrity: sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==}
engines: {node: '>=0.6'} engines: {node: '>=0.6'}
dependencies: dependencies:
side-channel: 1.0.4 side-channel: 1.0.4
@@ -7046,8 +7046,8 @@ packages:
unified: 10.1.1 unified: 10.1.1
dev: true dev: true
/rehype-prism-plus/1.3.0: /rehype-prism-plus/1.3.1:
resolution: {integrity: sha512-qipMym4Acp2xwMY50zPW8l8f2RAAjFd/DSg75rTRfvTWZ9xIy2ZEnIiDmqoPLH4BQ/VybrQcFxG0lwZau9l+Qw==} resolution: {integrity: sha512-wMxGPCuU96Bi3zbC9lc7nx4vxFJ5i5i2CrM+ZOZUe8zEPmFqUNF7RJIwwcZ3vfVpghMcHi35A8cSF2tKyrsYxw==}
dependencies: dependencies:
hast-util-to-string: 2.0.0 hast-util-to-string: 2.0.0
parse-numeric-range: 1.3.0 parse-numeric-range: 1.3.0
@@ -7133,7 +7133,7 @@ packages:
unified: 10.1.1 unified: 10.1.1
dev: true dev: true
/remix-tailwind/0.2.1_7b354341833d038270b90ce5c50910b6: /remix-tailwind/0.2.1_8cbcda2c835593b4e5c6cfe0d6a6e9a3:
resolution: {integrity: sha512-MqUQzOYiDGXpfJtWC5gbQW3mqM2ly4+Uljo0fvGG4NYZLCzh0OTKGxqwUj7R3lt7iN29Ff4TIo1a/N2adqfUnA==} resolution: {integrity: sha512-MqUQzOYiDGXpfJtWC5gbQW3mqM2ly4+Uljo0fvGG4NYZLCzh0OTKGxqwUj7R3lt7iN29Ff4TIo1a/N2adqfUnA==}
peerDependencies: peerDependencies:
postcss: '>=8' postcss: '>=8'
@@ -7142,7 +7142,7 @@ packages:
'@remix-run/node': 1.1.1_react-dom@17.0.2+react@17.0.2 '@remix-run/node': 1.1.1_react-dom@17.0.2+react@17.0.2
'@types/tailwindcss': 2.2.4 '@types/tailwindcss': 2.2.4
postcss: 8.4.5 postcss: 8.4.5
tailwindcss: 3.0.12_ef48b3b8837f8a23677bffe8f9cd866d tailwindcss: 3.0.13_ef48b3b8837f8a23677bffe8f9cd866d
transitivePeerDependencies: transitivePeerDependencies:
- react - react
- react-dom - react-dom
@@ -7532,6 +7532,7 @@ packages:
/source-map-resolve/0.5.3: /source-map-resolve/0.5.3:
resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==}
deprecated: See https://github.com/lydell/source-map-resolve#deprecated
dependencies: dependencies:
atob: 2.1.2 atob: 2.1.2
decode-uri-component: 0.2.0 decode-uri-component: 0.2.0
@@ -7541,6 +7542,7 @@ packages:
/source-map-url/0.4.1: /source-map-url/0.4.1:
resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==}
deprecated: See https://github.com/lydell/source-map-url#deprecated
/source-map/0.5.7: /source-map/0.5.7:
resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=} resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=}
@@ -7784,8 +7786,8 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
/tailwindcss/3.0.12_ef48b3b8837f8a23677bffe8f9cd866d: /tailwindcss/3.0.13_ef48b3b8837f8a23677bffe8f9cd866d:
resolution: {integrity: sha512-VqhF86z2c34sJyS5ZS8Q2nYuN0KzqZw1GGsuQQO9kJ3mY1oG7Fsag0vICkxUVXk6P+1sUkTkjMjKWCjEF0hNHw==} resolution: {integrity: sha512-raRPGFwQSGXn/3h0ttHND9jyPYfqk/ur2NXtlQuK25+ZnrCjlH1s1j4/oPswHGMoZzGNykUVycZ/LcROanUE0A==}
engines: {node: '>=12.13.0'} engines: {node: '>=12.13.0'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@@ -8142,7 +8144,7 @@ packages:
is-buffer: 2.0.5 is-buffer: 2.0.5
is-plain-obj: 4.0.0 is-plain-obj: 4.0.0
trough: 2.0.2 trough: 2.0.2
vfile: 5.2.1 vfile: 5.3.0
dev: true dev: true
/union-value/1.0.1: /union-value/1.0.1:
@@ -8397,7 +8399,7 @@ packages:
resolution: {integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==} resolution: {integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==}
dependencies: dependencies:
'@types/unist': 2.0.6 '@types/unist': 2.0.6
vfile: 5.2.1 vfile: 5.3.0
dev: true dev: true
/vfile-message/3.1.0: /vfile-message/3.1.0:
@@ -8407,8 +8409,8 @@ packages:
unist-util-stringify-position: 3.0.0 unist-util-stringify-position: 3.0.0
dev: true dev: true
/vfile/5.2.1: /vfile/5.3.0:
resolution: {integrity: sha512-vXW5XKbELM6mLj88kmkJ+gjFGZ/2gTmpdqPDjs3y+qbvI5i7md7rba/+pbYEawa7t22W7ynywPV6lUUAS1WiYg==} resolution: {integrity: sha512-Tj44nY/48OQvarrE4FAjUfrv7GZOYzPbl5OD65HxVKwLJKMPU7zmfV8cCgCnzKWnSfYG2f3pxu+ALqs7j22xQQ==}
dependencies: dependencies:
'@types/unist': 2.0.6 '@types/unist': 2.0.6
is-buffer: 2.0.5 is-buffer: 2.0.5
@@ -8440,8 +8442,8 @@ packages:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
/vitest/0.0.140_c8@7.11.0: /vitest/0.0.141_c8@7.11.0:
resolution: {integrity: sha512-tBv9rMKUH7AA7Vg9X5FMNZ7zyjGLNtNCBcKc2NNjPHKO1+cPttjF+jVvGIOP0Bo0l6pkRZWvsd3nywvktqVvvQ==} resolution: {integrity: sha512-CQwNWGbifAs5OrG1MXyiveeFT3KYpU/UZiZzNUR5ZHMUWKam9OeoDX0U3sFuyaERp/0b2vhoL0oaMccY2PJPSQ==}
engines: {node: '>=14.14.0'} engines: {node: '>=14.14.0'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@@ -8667,7 +8669,7 @@ packages:
unist-util-position-from-estree: 1.1.1 unist-util-position-from-estree: 1.1.1
unist-util-stringify-position: 3.0.0 unist-util-stringify-position: 3.0.0
unist-util-visit: 4.1.0 unist-util-visit: 4.1.0
vfile: 5.2.1 vfile: 5.3.0
optionalDependencies: optionalDependencies:
deasync: 0.1.24 deasync: 0.1.24
transitivePeerDependencies: transitivePeerDependencies: