@botonic/nx-plugin 2.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +420 -0
- package/README.md +279 -0
- package/executors.json +55 -0
- package/generators.json +61 -0
- package/migrations.json +40 -0
- package/package.json +54 -0
- package/src/cursor-commands/update-bot.md +114 -0
- package/src/cursor-commands/update-botonic.md +63 -0
- package/src/executors/build-node-app/executor.d.ts +5 -0
- package/src/executors/build-node-app/executor.js +65 -0
- package/src/executors/build-node-app/schema.d.js +16 -0
- package/src/executors/build-node-app/schema.json +25 -0
- package/src/executors/delete-bot/executor.d.ts +5 -0
- package/src/executors/delete-bot/executor.js +112 -0
- package/src/executors/delete-bot/schema.d.js +16 -0
- package/src/executors/delete-bot/schema.json +35 -0
- package/src/executors/deploy-local-runtime/executor.d.ts +5 -0
- package/src/executors/deploy-local-runtime/executor.js +144 -0
- package/src/executors/deploy-local-runtime/schema.d.js +16 -0
- package/src/executors/deploy-local-runtime/schema.json +34 -0
- package/src/executors/deploy-netlify-snapshot/executor.d.ts +8 -0
- package/src/executors/deploy-netlify-snapshot/executor.js +79 -0
- package/src/executors/deploy-netlify-snapshot/schema.d.js +16 -0
- package/src/executors/deploy-netlify-snapshot/schema.json +31 -0
- package/src/executors/deploy-to-hubtype/executor.d.ts +5 -0
- package/src/executors/deploy-to-hubtype/executor.js +308 -0
- package/src/executors/deploy-to-hubtype/schema.d.js +16 -0
- package/src/executors/deploy-to-hubtype/schema.json +31 -0
- package/src/executors/e2e-webchat/botonic-package-publish.spec.ts +84 -0
- package/src/executors/e2e-webchat/executor.d.ts +5 -0
- package/src/executors/e2e-webchat/executor.js +134 -0
- package/src/executors/e2e-webchat/schema.d.js +16 -0
- package/src/executors/e2e-webchat/schema.json +35 -0
- package/src/executors/integrate-provider/executor.d.ts +5 -0
- package/src/executors/integrate-provider/executor.js +155 -0
- package/src/executors/integrate-provider/schema.d.js +16 -0
- package/src/executors/integrate-provider/schema.json +30 -0
- package/src/executors/login-to-hubtype/executor.d.ts +5 -0
- package/src/executors/login-to-hubtype/executor.js +79 -0
- package/src/executors/login-to-hubtype/schema.d.js +16 -0
- package/src/executors/login-to-hubtype/schema.json +25 -0
- package/src/executors/logout-from-hubtype/executor.d.ts +3 -0
- package/src/executors/logout-from-hubtype/executor.js +54 -0
- package/src/executors/logout-from-hubtype/schema.d.js +16 -0
- package/src/executors/logout-from-hubtype/schema.json +9 -0
- package/src/executors/run-lambda/executor.d.ts +5 -0
- package/src/executors/run-lambda/executor.js +65 -0
- package/src/executors/run-lambda/schema.d.js +16 -0
- package/src/executors/run-lambda/schema.json +20 -0
- package/src/executors/serve-bot/executor.d.ts +5 -0
- package/src/executors/serve-bot/executor.js +330 -0
- package/src/executors/serve-bot/schema.d.js +16 -0
- package/src/executors/serve-bot/schema.json +40 -0
- package/src/generators/action/files/__name__.spec.ts.template +15 -0
- package/src/generators/action/files/__name__.ts.template +15 -0
- package/src/generators/action/generator.d.ts +4 -0
- package/src/generators/action/generator.js +112 -0
- package/src/generators/action/schema.d.ts +7 -0
- package/src/generators/action/schema.js +16 -0
- package/src/generators/action/schema.json +43 -0
- package/src/generators/bot-app/files/.eslintrc.json.template +18 -0
- package/src/generators/bot-app/files/README.md.template +148 -0
- package/src/generators/bot-app/files/src/client/custom-messages/index.ts.template +2 -0
- package/src/generators/bot-app/files/src/client/webchat/index.html.template +35 -0
- package/src/generators/bot-app/files/src/client/webchat/index.tsx.template +107 -0
- package/src/generators/bot-app/files/src/client/webchat/styles.css.template +17 -0
- package/src/generators/bot-app/files/src/client/webchat/webchat-tokens-overrides.css.template +2 -0
- package/src/generators/bot-app/files/src/client/webviews/app.tsx.template +8 -0
- package/src/generators/bot-app/files/src/client/webviews/index.html.template +32 -0
- package/src/generators/bot-app/files/src/client/webviews/index.tsx.template +18 -0
- package/src/generators/bot-app/files/src/server/bot/actions/index.ts.template +2 -0
- package/src/generators/bot-app/files/src/server/bot/actions/not-found.ts.template +13 -0
- package/src/generators/bot-app/files/src/server/bot/actions/welcome.ts.template +13 -0
- package/src/generators/bot-app/files/src/server/bot/index.ts.template +43 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/ai-agents/index.ts.template +30 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/flow-builder/index.ts.template +28 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/index.ts.template +11 -0
- package/src/generators/bot-app/files/src/server/bot/routes.ts.template +23 -0
- package/src/generators/bot-app/files/src/server/bot/tools/index.ts.template +5 -0
- package/src/generators/bot-app/files/src/server/bot/tracking.ts.template +35 -0
- package/src/generators/bot-app/files/src/server/bot/types.ts.template +4 -0
- package/src/generators/bot-app/files/src/server/bot/utils.ts.template +9 -0
- package/src/generators/bot-app/files/src/server/lambda/handler.js.template +24 -0
- package/src/generators/bot-app/files/src/server/lambda/package.json +20 -0
- package/src/generators/bot-app/files/src/server/lambda/template.yaml.template +20 -0
- package/src/generators/bot-app/files/src/shared/constants.ts.template +12 -0
- package/src/generators/bot-app/files/vite/base-client.config.ts.template +14 -0
- package/src/generators/bot-app/files/vite/base.config.ts.template +20 -0
- package/src/generators/bot-app/files/vite/build.config.ts.template +65 -0
- package/src/generators/bot-app/files/vite/node.config.ts.template +41 -0
- package/src/generators/bot-app/files/vite/plugins/move-html.plugin.ts.template +36 -0
- package/src/generators/bot-app/files/vite/webchat.config.ts.template +58 -0
- package/src/generators/bot-app/files/vite/webviews.config.ts.template +57 -0
- package/src/generators/bot-app/files/vite.config.ts.template +36 -0
- package/src/generators/bot-app/generator.d.ts +4 -0
- package/src/generators/bot-app/generator.js +294 -0
- package/src/generators/bot-app/schema.d.ts +6 -0
- package/src/generators/bot-app/schema.js +16 -0
- package/src/generators/bot-app/schema.json +36 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.js +92 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/schema.json +15 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.js +97 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/schema.json +15 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.js +165 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/schema.json +15 -0
- package/src/generators/custom-message/files/__name__-output.ts.template +21 -0
- package/src/generators/custom-message/files/__name__.spec.tsx.template +27 -0
- package/src/generators/custom-message/files/__name__.tsx.template +18 -0
- package/src/generators/custom-message/generator.d.ts +4 -0
- package/src/generators/custom-message/generator.js +235 -0
- package/src/generators/custom-message/schema.d.ts +7 -0
- package/src/generators/custom-message/schema.js +16 -0
- package/src/generators/custom-message/schema.json +44 -0
- package/src/generators/preset/files/.cursor/commands/update-bot.md +5 -0
- package/src/generators/preset/files/.cursor/commands/update-botonic.md +5 -0
- package/src/generators/preset/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
- package/src/generators/preset/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
- package/src/generators/preset/files/.cursor/skills/botonic-action/SKILL.md +167 -0
- package/src/generators/preset/files/.cursor/skills/botonic-custom-message/SKILL.md +231 -0
- package/src/generators/preset/files/.cursor/skills/botonic-webview/SKILL.md +179 -0
- package/src/generators/preset/files/.env.prod.template +2 -0
- package/src/generators/preset/files/.env.template +2 -0
- package/src/generators/preset/files/.npmrc.template +1 -0
- package/src/generators/preset/files/README.md.template +174 -0
- package/src/generators/preset/files/nx.json +66 -0
- package/src/generators/preset/files/package.json +26 -0
- package/src/generators/preset/files/tsconfig.base.json +27 -0
- package/src/generators/preset/files/tsconfig.base.json.template +27 -0
- package/src/generators/preset/files/tsconfig.json +9 -0
- package/src/generators/preset/generator.d.ts +4 -0
- package/src/generators/preset/generator.js +127 -0
- package/src/generators/preset/schema.d.ts +6 -0
- package/src/generators/preset/schema.js +16 -0
- package/src/generators/preset/schema.json +50 -0
- package/src/generators/remove-custom-message/generator.d.ts +4 -0
- package/src/generators/remove-custom-message/generator.js +259 -0
- package/src/generators/remove-custom-message/schema.d.ts +6 -0
- package/src/generators/remove-custom-message/schema.js +16 -0
- package/src/generators/remove-custom-message/schema.json +39 -0
- package/src/generators/shared/bot-app-utils.d.ts +25 -0
- package/src/generators/shared/bot-app-utils.js +209 -0
- package/src/generators/webview/files/__name__.spec.tsx.template +20 -0
- package/src/generators/webview/files/__name__.tsx.template +19 -0
- package/src/generators/webview/generator.d.ts +4 -0
- package/src/generators/webview/generator.js +179 -0
- package/src/generators/webview/schema.d.ts +5 -0
- package/src/generators/webview/schema.js +16 -0
- package/src/generators/webview/schema.json +34 -0
- package/src/index.d.ts +7 -0
- package/src/index.js +56 -0
- package/src/lib/api-service.d.ts +110 -0
- package/src/lib/api-service.js +591 -0
- package/src/lib/bot-config.d.ts +30 -0
- package/src/lib/bot-config.js +203 -0
- package/src/lib/cloudflared-tunnel.d.ts +29 -0
- package/src/lib/cloudflared-tunnel.js +95 -0
- package/src/lib/constants.d.ts +13 -0
- package/src/lib/constants.js +60 -0
- package/src/lib/credentials-handler.d.ts +40 -0
- package/src/lib/credentials-handler.js +115 -0
- package/src/lib/index.d.ts +10 -0
- package/src/lib/index.js +47 -0
- package/src/lib/interfaces.d.ts +49 -0
- package/src/lib/interfaces.js +16 -0
- package/src/lib/util/executor-helpers.d.ts +97 -0
- package/src/lib/util/executor-helpers.js +574 -0
- package/src/lib/util/file-system.d.ts +8 -0
- package/src/lib/util/file-system.js +65 -0
- package/src/lib/util/sam-container-cleanup.d.ts +11 -0
- package/src/lib/util/sam-container-cleanup.js +55 -0
- package/src/lib/util/sam-template.d.ts +9 -0
- package/src/lib/util/sam-template.js +71 -0
- package/src/lib/util/system.d.ts +1 -0
- package/src/lib/util/system.js +30 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.d.ts +2 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.js +52 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.md +23 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-bot.md +5 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-botonic.md +5 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
- package/src/migrations/add-botonic-update-bots-skill/schema.json +5 -0
- package/src/migrations/add-lilara-registry/add-lilara-registry.migration.d.ts +2 -0
- package/src/migrations/add-lilara-registry/add-lilara-registry.migration.js +49 -0
- package/src/migrations/add-lilara-registry/schema.json +5 -0
- package/src/migrations/fix-css-code-split/fix-css-code-split.migration.md +45 -0
- package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.d.ts +2 -0
- package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.js +59 -0
- package/src/migrations/remove-codeartifact-registry/schema.json +5 -0
- package/src/migrations/sync-pending-bot-migrations/schema.json +5 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.d.ts +2 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.js +137 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.md +19 -0
- package/src/migrations/update-cursor-commands-to-stubs/schema.json +5 -0
- package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.d.ts +2 -0
- package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.js +61 -0
- package/src/migrations/update-pnpm-workspace-scripts/schema.json +4 -0
- package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.d.ts +2 -0
- package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.js +47 -0
- package/src/migrations/utils/migration-utils.d.ts +109 -0
- package/src/migrations/utils/migration-utils.js +448 -0
- package/src/plugin.d.ts +15 -0
- package/src/plugin.js +246 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: botonic-custom-message
|
|
3
|
+
description: Scaffold and implement a Botonic custom webchat message component using the Nx generator, then guide implementation. Use when the user says "create custom message", "add custom message", "new custom message", "generate custom message", or wants to render a rich or custom UI component in the webchat conversation in a Botonic bot project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Botonic Custom Message
|
|
7
|
+
|
|
8
|
+
Scaffold a custom webchat message component and help implement the React component and its output action.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
### Step 1 — Gather inputs
|
|
13
|
+
|
|
14
|
+
Collect from context or ask:
|
|
15
|
+
|
|
16
|
+
- **`name`** (required): kebab-case name, e.g. `rating-card`, `product-tile`
|
|
17
|
+
- **`project`** (required): Nx project name of the bot app, e.g. `my-bot`
|
|
18
|
+
- **`directory`** (optional): subdirectory inside `custom-messages/` to group related components, e.g. `cards`
|
|
19
|
+
- **`skipTests`** (optional): `true` to skip spec file generation
|
|
20
|
+
- **`skipAction`** (optional): `true` to skip generating the output action and route
|
|
21
|
+
|
|
22
|
+
### Step 2 — Run the generator
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm nx g @botonic/nx-plugin:custom-message --name=<name> --project=<project>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
With optional flags:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm nx g @botonic/nx-plugin:custom-message rating-card --project my-bot --directory cards
|
|
32
|
+
pnpm nx g @botonic/nx-plugin:custom-message info-banner --project my-bot --skipAction
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Step 3 — Understand what was generated
|
|
36
|
+
|
|
37
|
+
The generator creates and updates:
|
|
38
|
+
|
|
39
|
+
- `src/client/custom-messages/<name>.tsx` — new React component
|
|
40
|
+
- `src/client/custom-messages/<name>.spec.tsx` — test file (unless `--skipTests`)
|
|
41
|
+
- `src/client/custom-messages/index.ts` — import + registration in `customMessages` map added
|
|
42
|
+
- `src/server/bot/actions/<name>-output.ts` — output action (unless `--skipAction`)
|
|
43
|
+
- `src/server/bot/actions/index.ts` — export added
|
|
44
|
+
- `src/server/bot/routes.ts` — route entry added
|
|
45
|
+
- `src/shared/constants.ts` — `CUSTOM_MESSAGE_TYPES.<CONSTANT>` entry added
|
|
46
|
+
|
|
47
|
+
Read both the component and output action files and show the user the starting points.
|
|
48
|
+
|
|
49
|
+
### Step 4 — Ask what to implement
|
|
50
|
+
|
|
51
|
+
If not already clear from context, ask: "What data should this message display? What props does the component need?"
|
|
52
|
+
|
|
53
|
+
### Step 5 — Implement the React component
|
|
54
|
+
|
|
55
|
+
#### Root wrapper: always `Message` with `variant="bot"`
|
|
56
|
+
|
|
57
|
+
Import `Message` from `@botonic/webchat-react` and use it as the root. It handles layout, avatar, timestamp, and — crucially — wraps the children in a `MessageBubble` automatically. Always pass `variant="bot"` explicitly since custom messages are almost always sent by the bot.
|
|
58
|
+
|
|
59
|
+
Never use a plain `<div>` as the root — the message will not render with correct bubble styling, spacing, or theming. Never nest a `MessageBubble` inside `Message` — `Message` already creates one internally; nesting would double-wrap.
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { Message } from '@botonic/webchat-react'
|
|
63
|
+
import React from 'react'
|
|
64
|
+
|
|
65
|
+
import styles from './rating-card.module.css'
|
|
66
|
+
|
|
67
|
+
export const RatingCard: React.FC<RatingCardProps> = (props: any) => {
|
|
68
|
+
return (
|
|
69
|
+
<Message variant='bot' className={styles.bubble}>
|
|
70
|
+
<div className={styles.content}>{/* your content here */}</div>
|
|
71
|
+
</Message>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Buttons inside the custom message
|
|
77
|
+
|
|
78
|
+
`ButtonComponent` (exported from `@botonic/webchat-react`) can be rendered inside the `Message`. The webchat automatically injects an `onButtonClick` callback into the component props — use it as the `onClick` handler. The button data (`BotonicButtonContent`) should be built server-side (e.g. with `BotServerMessageFactory.createWebviewButton`) and passed as a prop so the server can embed dynamic values like webview URLs.
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { BotonicButtonContent } from '@botonic/shared'
|
|
82
|
+
import { ButtonComponent, Message } from '@botonic/webchat-react'
|
|
83
|
+
|
|
84
|
+
export interface ProductCardProps {
|
|
85
|
+
title: string
|
|
86
|
+
price: string
|
|
87
|
+
button?: BotonicButtonContent
|
|
88
|
+
onButtonClick?: (button: BotonicButtonContent) => void // injected automatically
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const ProductCard: React.FC<ProductCardProps> = (props: any) => {
|
|
92
|
+
const { title, price, button, onButtonClick } = props
|
|
93
|
+
return (
|
|
94
|
+
<Message variant='bot'>
|
|
95
|
+
<div className={styles.content}>
|
|
96
|
+
<div className={styles.title}>{title}</div>
|
|
97
|
+
<div className={styles.price}>{price}</div>
|
|
98
|
+
{button && onButtonClick && <ButtonComponent text={button.title} button={button} onClick={onButtonClick} variant='secondary' />}
|
|
99
|
+
</div>
|
|
100
|
+
</Message>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
In the output action, build the button server-side and pass it as a prop:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
export async function productCardOutput({ sendMessage, session }: BotContext) {
|
|
109
|
+
const button = BotServerMessageFactory.createWebviewButton({ title: 'View details', webview: WEBVIEWS.PRODUCT }, session)
|
|
110
|
+
await sendMessage(
|
|
111
|
+
BotServerMessageFactory.createCustom({
|
|
112
|
+
name: CUSTOM_MESSAGE_TYPES.PRODUCT_CARD,
|
|
113
|
+
props: { title: 'Widget Pro', price: '€9.99', button },
|
|
114
|
+
})
|
|
115
|
+
)
|
|
116
|
+
return { status: 200, response: 'OK' }
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### Multiple bubbles: send multiple messages from the action
|
|
121
|
+
|
|
122
|
+
`Message` always renders exactly one bubble. If the design requires multiple separate bubbles (e.g. an image bubble followed by a text bubble), send them as separate messages from the output action — do not try to nest multiple `MessageBubble` components inside one `Message`.
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// In the output action
|
|
126
|
+
await sendMessage(BotServerMessageFactory.createCustom({ name: CUSTOM_MESSAGE_TYPES.PRODUCT_IMAGE, props: { url } }))
|
|
127
|
+
await sendMessage(BotServerMessageFactory.createCustom({ name: CUSTOM_MESSAGE_TYPES.PRODUCT_DETAIL, props: { title, price } }))
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Styling: CSS modules only, no inline styles
|
|
131
|
+
|
|
132
|
+
Create `<name>.module.css` next to the component. Never use inline `style={{}}` props.
|
|
133
|
+
|
|
134
|
+
```css
|
|
135
|
+
/* rating-card.module.css */
|
|
136
|
+
.content {
|
|
137
|
+
display: flex;
|
|
138
|
+
flex-direction: column;
|
|
139
|
+
gap: var(--spacing-xs);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.label {
|
|
143
|
+
font-size: var(--font-size-sm);
|
|
144
|
+
font-weight: var(--font-weight-medium);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Overriding bubble colours: use component tokens
|
|
149
|
+
|
|
150
|
+
The bubble reads from CSS custom properties. Override them scoped to the component by targeting the class passed to `Message`:
|
|
151
|
+
|
|
152
|
+
```css
|
|
153
|
+
/* rating-card.module.css */
|
|
154
|
+
.bubble {
|
|
155
|
+
--webchat-message-bubble-bot-bg: #f0f7ff;
|
|
156
|
+
--webchat-message-bubble-bot-text: #1a3c5e;
|
|
157
|
+
--webchat-message-bubble-bot-border-color: #b3d1f0;
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Pass the class to `Message`:
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
<Message className={styles.bubble}>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The token overrides cascade into `MessageBubble` automatically. Available tokens:
|
|
168
|
+
|
|
169
|
+
| Token | Purpose |
|
|
170
|
+
| ------------------------------------------- | ----------------- |
|
|
171
|
+
| `--webchat-message-bubble-bot-bg` | Background colour |
|
|
172
|
+
| `--webchat-message-bubble-bot-text` | Text colour |
|
|
173
|
+
| `--webchat-message-bubble-bot-border-color` | Border colour |
|
|
174
|
+
|
|
175
|
+
Use these same tokens inside the component CSS so colours stay in sync:
|
|
176
|
+
|
|
177
|
+
```css
|
|
178
|
+
.divider {
|
|
179
|
+
border-top: 1px solid var(--webchat-message-bubble-bot-border-color);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Step 6 — Implement the output action
|
|
184
|
+
|
|
185
|
+
Update `<name>-output.ts` to pass the required props in `data`:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
export async function ratingCardOutput({ sendMessage }: BotContext) {
|
|
189
|
+
await sendMessage(
|
|
190
|
+
BotServerMessageFactory.createCustom({
|
|
191
|
+
name: CUSTOM_MESSAGE_TYPES.RATING_CARD,
|
|
192
|
+
props: {
|
|
193
|
+
rating: 0,
|
|
194
|
+
label: 'How was your experience?',
|
|
195
|
+
},
|
|
196
|
+
})
|
|
197
|
+
)
|
|
198
|
+
return { status: 200, response: 'OK' }
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The `data.props` object must match the component's props interface exactly.
|
|
203
|
+
|
|
204
|
+
### Step 7 — Trigger from a route
|
|
205
|
+
|
|
206
|
+
The output action is already wired to a route in `routes.ts`. Call it from another action when needed:
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { ratingCardOutput } from './rating-card-output'
|
|
210
|
+
|
|
211
|
+
export async function EndConversation(ctx: BotContext) {
|
|
212
|
+
await ratingCardOutput(ctx)
|
|
213
|
+
return { status: 200, response: 'OK' }
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Removing a custom message
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
pnpm nx g @botonic/nx-plugin:remove-custom-message <name> --project=<project>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Options reference
|
|
224
|
+
|
|
225
|
+
| Option | Default | Notes |
|
|
226
|
+
| ------------ | ------- | ------------------------------------------------- |
|
|
227
|
+
| `name` | — | Required. kebab-case recommended |
|
|
228
|
+
| `project` | — | Required. Nx project name |
|
|
229
|
+
| `directory` | — | Subdirectory inside `custom-messages/` (optional) |
|
|
230
|
+
| `skipTests` | `false` | Omit `<name>.spec.tsx` |
|
|
231
|
+
| `skipAction` | `false` | Omit output action and route |
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: botonic-webview
|
|
3
|
+
description: Scaffold and implement a Botonic webview component using the Nx generator, then guide implementation. Use when the user says "create webview", "add webview", "new webview", "generate webview", or wants to build an in-chat form, panel, or interactive UI component in a Botonic bot project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Botonic Webview
|
|
7
|
+
|
|
8
|
+
Scaffold a client-side webview component and help implement its UI.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
### Step 1 — Gather inputs
|
|
13
|
+
|
|
14
|
+
Collect from context or ask:
|
|
15
|
+
|
|
16
|
+
- **`name`** (required): kebab-case name, e.g. `booking-form`, `order-detail`
|
|
17
|
+
- **`project`** (required): Nx project name of the bot app, e.g. `my-bot`
|
|
18
|
+
- **`skipTests`** (optional): `true` to skip spec file generation
|
|
19
|
+
|
|
20
|
+
### Step 2 — Run the generator
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm nx g @botonic/nx-plugin:webview --name=<name> --project=<project>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Step 3 — Understand what was generated
|
|
27
|
+
|
|
28
|
+
The generator creates and updates:
|
|
29
|
+
|
|
30
|
+
- `src/client/webviews/<name>.tsx` — new webview component
|
|
31
|
+
- `src/client/webviews/<name>.spec.tsx` — test file (unless `--skipTests`)
|
|
32
|
+
- `src/client/webviews/index.tsx` — import + `WebviewDefinition` entry added
|
|
33
|
+
- `src/shared/constants.ts` — `WEBVIEWS.<CONSTANT>` entry added
|
|
34
|
+
|
|
35
|
+
Read the generated component file and show the user the starting point.
|
|
36
|
+
|
|
37
|
+
### Step 4 — Ask what to implement
|
|
38
|
+
|
|
39
|
+
If not already clear from context, ask: "What should this webview display or allow the user to do?"
|
|
40
|
+
|
|
41
|
+
### Step 5 — Implement the webview
|
|
42
|
+
|
|
43
|
+
Use `WebviewFrame`, `WebviewHeader`, `WebviewBody` from `@botonic/webviews` as the structural shell.
|
|
44
|
+
Access request data and the close handler via `useWebviewRequest`.
|
|
45
|
+
|
|
46
|
+
> **CSS reset and design tokens are loaded automatically.** `WebviewApp` imports `@lilara/foundations/reset.css` and `@lilara/foundations/tokens.css` as side effects — no manual CSS import is needed in the app's `index.tsx`.
|
|
47
|
+
|
|
48
|
+
#### Always use UI components from `@botonic/webchat-react`
|
|
49
|
+
|
|
50
|
+
Never use raw HTML elements (`<input>`, `<button>`, `<select>`, etc.) in webviews. All interactive and display elements must come from `@botonic/webchat-react`, which re-exports the full design system.
|
|
51
|
+
|
|
52
|
+
> **react-aria conventions.** These components are built on react-aria — prop names differ from standard HTML. Check the `.d.ts` types before using any component. Key differences: `Button` uses `onPress` not `onClick`; `Checkbox` and `Switch` use `isSelected` not `checked`, and `onChange` receives a `boolean` not an event.
|
|
53
|
+
|
|
54
|
+
| Component | Use for |
|
|
55
|
+
| ----------------------------------------- | ----------------------------------- |
|
|
56
|
+
| `Button` | Any clickable action |
|
|
57
|
+
| `TextInput` | Single-line text fields |
|
|
58
|
+
| `TextArea` | Multi-line text fields |
|
|
59
|
+
| `Checkbox` | Boolean toggles |
|
|
60
|
+
| `Switch` | On/off toggles |
|
|
61
|
+
| `Select` / `SelectWithSections` | Single-choice dropdowns |
|
|
62
|
+
| `Multiselect` / `MultiselectWithSections` | Multi-choice dropdowns |
|
|
63
|
+
| `Slider` | Numeric range input |
|
|
64
|
+
| `Banner` | Inline alerts and feedback messages |
|
|
65
|
+
| `Tooltip` | Contextual hints |
|
|
66
|
+
| `Badge` / `Tag` | Status indicators |
|
|
67
|
+
| `Spinner` | Loading states |
|
|
68
|
+
|
|
69
|
+
**Static content**
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { useWebviewRequest, WebviewBody, WebviewFrame, WebviewHeader } from '@botonic/webviews'
|
|
73
|
+
|
|
74
|
+
export const OrderDetail = () => {
|
|
75
|
+
const { payload, closeWebview } = useWebviewRequest<{ orderId: string }>()
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<WebviewFrame>
|
|
79
|
+
<WebviewHeader title='Order Detail' onClose={closeWebview} />
|
|
80
|
+
<WebviewBody variant='padded'>
|
|
81
|
+
<p>Order ID: {payload?.orderId}</p>
|
|
82
|
+
</WebviewBody>
|
|
83
|
+
</WebviewFrame>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Form with submission**
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { Button, TextInput } from '@botonic/webchat-react'
|
|
92
|
+
import { useWebviewRequest, WebviewBody, WebviewFrame, WebviewHeader } from '@botonic/webviews'
|
|
93
|
+
|
|
94
|
+
export const BookingForm = () => {
|
|
95
|
+
const { closeWebview } = useWebviewRequest()
|
|
96
|
+
const [name, setName] = useState('')
|
|
97
|
+
|
|
98
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
99
|
+
e.preventDefault()
|
|
100
|
+
closeWebview({ name })
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<WebviewFrame>
|
|
105
|
+
<WebviewHeader title='Booking' />
|
|
106
|
+
<WebviewBody variant='padded'>
|
|
107
|
+
<form onSubmit={handleSubmit}>
|
|
108
|
+
<TextInput value={name} onChange={e => setName(e.target.value)} placeholder='Your name' />
|
|
109
|
+
<Button type='submit'>Confirm</Button>
|
|
110
|
+
</form>
|
|
111
|
+
</WebviewBody>
|
|
112
|
+
</WebviewFrame>
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Fetching data on load**
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { Banner, Spinner } from '@botonic/webchat-react'
|
|
121
|
+
import { useWebviewRequest, WebviewBody, WebviewFrame, WebviewHeader } from '@botonic/webviews'
|
|
122
|
+
|
|
123
|
+
export const OrderDetail = () => {
|
|
124
|
+
const { payload, closeWebview } = useWebviewRequest<{ orderId: string }>()
|
|
125
|
+
const [order, setOrder] = useState<Order>()
|
|
126
|
+
const [error, setError] = useState<string>()
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
if (!payload?.orderId) return
|
|
130
|
+
let cancelled = false
|
|
131
|
+
fetchOrder(payload.orderId)
|
|
132
|
+
.then(o => {
|
|
133
|
+
if (!cancelled) setOrder(o)
|
|
134
|
+
})
|
|
135
|
+
.catch(err => {
|
|
136
|
+
if (!cancelled) setError(err?.message ?? 'Failed to load order')
|
|
137
|
+
})
|
|
138
|
+
return () => {
|
|
139
|
+
cancelled = true
|
|
140
|
+
}
|
|
141
|
+
}, [payload?.orderId])
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<WebviewFrame>
|
|
145
|
+
<WebviewHeader title='Order Detail' onClose={closeWebview} />
|
|
146
|
+
<WebviewBody variant='padded'>
|
|
147
|
+
{error && <Banner variant='error'>{error}</Banner>}
|
|
148
|
+
{!order && !error && <Spinner />}
|
|
149
|
+
{order && <p>{order.statusMessage}</p>}
|
|
150
|
+
</WebviewBody>
|
|
151
|
+
</WebviewFrame>
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Step 6 — Open it from a bot action
|
|
157
|
+
|
|
158
|
+
After the webview is ready, remind the user to open it from an action using `BotServerMessageFactory.createWebviewButton`:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { WEBVIEWS } from '../../shared/constants'
|
|
162
|
+
|
|
163
|
+
await sendMessage(
|
|
164
|
+
BotServerMessageFactory.createButtonMessage({
|
|
165
|
+
text: 'Need to book a slot?',
|
|
166
|
+
buttons: [BotServerMessageFactory.createWebviewButton({ title: 'Open form', webview: WEBVIEWS.BOOKING_FORM }, session)],
|
|
167
|
+
})
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Use the `botonic-action` skill if the user also needs to create the triggering action.
|
|
172
|
+
|
|
173
|
+
## Options reference
|
|
174
|
+
|
|
175
|
+
| Option | Default | Notes |
|
|
176
|
+
| ----------- | ------- | -------------------------------- |
|
|
177
|
+
| `name` | — | Required. kebab-case recommended |
|
|
178
|
+
| `project` | — | Required. Nx project name |
|
|
179
|
+
| `skipTests` | `false` | Omit `<name>.spec.tsx` |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @botonic/* and @lilara/* use the public npm registry by default.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# <%= name %>
|
|
2
|
+
|
|
3
|
+
This workspace was generated using the Botonic Nx Plugin.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
### 1. Backend Setup
|
|
8
|
+
```bash
|
|
9
|
+
# Clone and setup hubtype-backend
|
|
10
|
+
git clone https://github.com/metis-ai/hubtype-backend
|
|
11
|
+
cd hubtype-backend
|
|
12
|
+
# Follow setup instructions: https://www.notion.so/Laptop-Setup-macOS-0ae7e69f670d40f8b99bf2fb833b59b4
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Tunnel Configuration
|
|
16
|
+
```bash
|
|
17
|
+
# Setup ngrok tunnel for local development
|
|
18
|
+
# Replace {YOUR_TUNNEL_SUBDOMAIN} with your actual subdomain
|
|
19
|
+
# Target URL: https://{YOUR_TUNNEL_SUBDOMAIN}-be-dev.metis.ai/
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 3. AWS SAM CLI Installation
|
|
23
|
+
```bash
|
|
24
|
+
# Install AWS SAM CLI for local lambda execution
|
|
25
|
+
# Follow: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 4. Environment Configuration
|
|
29
|
+
Create/update `hubtype-backend/local.env` with:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
HUBTYPE_HOST=https://{YOUR_TUNNEL_SUBDOMAIN}-be-dev.metis.ai
|
|
33
|
+
EXTRA_ALLOWED={YOUR_TUNNEL_SUBDOMAIN}-be-dev.metis.ai
|
|
34
|
+
HUBTYPE_FRONTEND_HOST=http://localhost:4200
|
|
35
|
+
CORS_ALLOWED_ORIGINS=http://localhost:4200,http://localhost:4201,http://localhost:4202,http://localhost:3001
|
|
36
|
+
# Note: ports 4201, 4202, 3001 are used by botonic v2 serve mode
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Getting Started
|
|
40
|
+
|
|
41
|
+
### Backend Commands
|
|
42
|
+
From within `hubtype-backend` directory:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Local development mode - uses local lambda
|
|
46
|
+
make run-botonic-local
|
|
47
|
+
|
|
48
|
+
# Remote mode - uses deployed lambda
|
|
49
|
+
make run-botonic-remote
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Tunnel Setup
|
|
53
|
+
Start cloudflare tunnel before running the options below:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Replace {YOUR_TOKEN} with your actual Cloudflare tunnel token
|
|
57
|
+
docker run --rm --network host cloudflare/cloudflared:latest tunnel --no-autoupdate run --token {YOUR_TOKEN} --url http://localhost:8000
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 1. Initialize Bot Monorepo
|
|
61
|
+
```bash
|
|
62
|
+
# Navigate to your desired directory
|
|
63
|
+
cd /path/to/your/workspace
|
|
64
|
+
|
|
65
|
+
# Generate new bot monorepo (replace {YOUR_BOTS_MONOREPO_NAME})
|
|
66
|
+
npx nx generate @botonic/nx-plugin:preset {YOUR_BOTS_MONOREPO_NAME}
|
|
67
|
+
|
|
68
|
+
# Alternative: Use Nx UI (Cmd+Shift+P → Nx: Generate (UI))
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 2. Create Bot Application
|
|
72
|
+
```bash
|
|
73
|
+
# From within the generated monorepo
|
|
74
|
+
cd {YOUR_BOTS_MONOREPO_NAME}
|
|
75
|
+
|
|
76
|
+
# Generate new bot app (replace {BOT_NAME})
|
|
77
|
+
npx nx g @botonic/nx-plugin:bot-app {BOT_NAME}
|
|
78
|
+
|
|
79
|
+
# Alternative: Use Nx UI (Cmd+Shift+P → Nx: Generate (UI))
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 3. Local Development Setup
|
|
83
|
+
```bash
|
|
84
|
+
# Step 1: Start backend in local mode
|
|
85
|
+
cd hubtype-backend
|
|
86
|
+
make run-botonic-local
|
|
87
|
+
|
|
88
|
+
# Step 2: Login to local backend (from bot monorepo)
|
|
89
|
+
cd {YOUR_BOTS_MONOREPO_NAME}
|
|
90
|
+
nx run {BOT_NAME}:login-to-hubtype --configuration=local
|
|
91
|
+
|
|
92
|
+
# Step 3: Deploy local runtime (creates bot in database)
|
|
93
|
+
nx run {BOT_NAME}:deploy-local-runtime --configuration=local
|
|
94
|
+
|
|
95
|
+
# Step 4: Start bot in local mode
|
|
96
|
+
nx serve {BOT_NAME} --mode=local
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 4. Production Deployment
|
|
100
|
+
```bash
|
|
101
|
+
# Logout from current environment
|
|
102
|
+
nx run {BOT_NAME}:logout-from-hubtype
|
|
103
|
+
|
|
104
|
+
# Login to target environment (dev, dev2, qa, prod)
|
|
105
|
+
nx run {BOT_NAME}:login-to-hubtype --configuration=dev2
|
|
106
|
+
|
|
107
|
+
# Deploy to target environment
|
|
108
|
+
nx run {BOT_NAME}:deploy-to-hubtype --configuration=dev2
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
This workspace contains tools and configurations for building Botonic bot applications.
|
|
113
|
+
|
|
114
|
+
### Available Commands
|
|
115
|
+
|
|
116
|
+
- `nx g @botonic/nx-plugin:bot-app <name>` - Generate a new bot application
|
|
117
|
+
- `nx build <bot-name>` - Build a bot application
|
|
118
|
+
- `nx serve <bot-name>` - Serve a bot application for development
|
|
119
|
+
- `nx test <bot-name>` - Run tests for a bot application
|
|
120
|
+
|
|
121
|
+
### AI Commands (Cursor)
|
|
122
|
+
|
|
123
|
+
- `/update-bot` — Update a Botonic bot to a newer version using Nx migrations. Type `/update-bot` in Cursor chat; it discovers bots, lets you pick one, and runs migrations one version at a time with git branch management.
|
|
124
|
+
|
|
125
|
+
### Project Structure
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
<%= name %>/
|
|
129
|
+
├── apps/ # Bot applications
|
|
130
|
+
├── libs/ # Shared libraries
|
|
131
|
+
├── tools/ # Build tools and scripts
|
|
132
|
+
├── nx.json # Nx workspace configuration
|
|
133
|
+
├── package.json # Dependencies and scripts
|
|
134
|
+
└── README.md # This file
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Creating Your First Bot
|
|
138
|
+
|
|
139
|
+
To create a new bot application:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
nx g @botonic/nx-plugin:bot-app my-bot
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This will create a new bot application in the `apps/my-bot` directory with:
|
|
146
|
+
- Basic bot structure
|
|
147
|
+
- Routes and actions
|
|
148
|
+
- Configuration files
|
|
149
|
+
- Build and development scripts
|
|
150
|
+
|
|
151
|
+
### Development
|
|
152
|
+
|
|
153
|
+
To start developing your bot:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Serve the bot for development
|
|
157
|
+
nx serve my-bot
|
|
158
|
+
|
|
159
|
+
# Build the bot for production
|
|
160
|
+
nx build my-bot
|
|
161
|
+
|
|
162
|
+
# Run tests
|
|
163
|
+
nx test my-bot
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Learn More
|
|
167
|
+
|
|
168
|
+
- [Botonic Documentation](https://botonic.io/docs/)
|
|
169
|
+
- [Nx Documentation](https://nx.dev/)
|
|
170
|
+
- [Hubtype Documentation](https://docs.hubtype.com/)
|
|
171
|
+
|
|
172
|
+
## Support
|
|
173
|
+
|
|
174
|
+
For support and questions, please visit our [GitHub repository](https://github.com/hubtype/botonic).
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/nx/schemas/nx-schema.json",
|
|
3
|
+
"defaultBase": "main",
|
|
4
|
+
"namedInputs": {
|
|
5
|
+
"default": ["{projectRoot}/**/*", "sharedGlobals"],
|
|
6
|
+
"production": [
|
|
7
|
+
"default",
|
|
8
|
+
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
|
|
9
|
+
"!{projectRoot}/tsconfig.spec.json",
|
|
10
|
+
"!{projectRoot}/jest.config.[jt]s",
|
|
11
|
+
"!{projectRoot}/src/test-setup.[jt]s",
|
|
12
|
+
"!{projectRoot}/test-setup.[jt]s",
|
|
13
|
+
"!{projectRoot}/.eslintrc.json",
|
|
14
|
+
"!{projectRoot}/eslint.config.js"
|
|
15
|
+
],
|
|
16
|
+
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
|
|
17
|
+
},
|
|
18
|
+
"generators": {
|
|
19
|
+
"@nx/react": {
|
|
20
|
+
"application": {
|
|
21
|
+
"babel": true,
|
|
22
|
+
"style": "css",
|
|
23
|
+
"linter": "eslint",
|
|
24
|
+
"bundler": "vite",
|
|
25
|
+
"projectNameAndRootFormat": "as-provided"
|
|
26
|
+
},
|
|
27
|
+
"component": {
|
|
28
|
+
"style": "css"
|
|
29
|
+
},
|
|
30
|
+
"library": {
|
|
31
|
+
"style": "css",
|
|
32
|
+
"linter": "eslint",
|
|
33
|
+
"unitTestRunner": "vitest",
|
|
34
|
+
"projectNameAndRootFormat": "as-provided"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"targetDefaults": {
|
|
39
|
+
"build": {
|
|
40
|
+
"cache": true,
|
|
41
|
+
"dependsOn": ["^build"],
|
|
42
|
+
"inputs": ["production", "^production"]
|
|
43
|
+
},
|
|
44
|
+
"test": {
|
|
45
|
+
"cache": true,
|
|
46
|
+
"inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"]
|
|
47
|
+
},
|
|
48
|
+
"lint": {
|
|
49
|
+
"cache": true,
|
|
50
|
+
"inputs": [
|
|
51
|
+
"default",
|
|
52
|
+
"{workspaceRoot}/.eslintrc.json",
|
|
53
|
+
"{workspaceRoot}/.eslintignore",
|
|
54
|
+
"{workspaceRoot}/eslint.config.js"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"typecheck": {
|
|
58
|
+
"cache": true,
|
|
59
|
+
"inputs": ["default", "^production"]
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"plugins": ["@botonic/nx-plugin"],
|
|
63
|
+
"tui": {
|
|
64
|
+
"autoExit": 0
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "<%= name %>",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A Botonic workspace using NPM workspaces and TypeScript project references",
|
|
5
|
+
"private": true,
|
|
6
|
+
"workspaces": [
|
|
7
|
+
"packages/*",
|
|
8
|
+
"apps/*"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "nx run-many --target=build",
|
|
12
|
+
"test": "nx run-many --target=test",
|
|
13
|
+
"lint": "nx run-many --target=lint",
|
|
14
|
+
"typecheck": "nx run-many --target=typecheck"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@nx/js": "21.0.3",
|
|
18
|
+
"@swc-node/register": "~1.9.1",
|
|
19
|
+
"@swc/core": "~1.5.7",
|
|
20
|
+
"@swc/helpers": "~0.5.11",
|
|
21
|
+
"nx": "21.0.3",
|
|
22
|
+
"prettier": "^2.6.2",
|
|
23
|
+
"tslib": "^2.3.0",
|
|
24
|
+
"typescript": "~5.8.2"
|
|
25
|
+
}
|
|
26
|
+
}
|