@webiny/mcp 0.0.0-unstable.6844005670
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/Extension.d.ts +2 -0
- package/Extension.js +11 -0
- package/Extension.js.map +1 -0
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/agents/claude.d.ts +15 -0
- package/agents/claude.js +33 -0
- package/agents/claude.js.map +1 -0
- package/agents/cline.d.ts +17 -0
- package/agents/cline.js +29 -0
- package/agents/cline.js.map +1 -0
- package/agents/copilot.d.ts +17 -0
- package/agents/copilot.js +64 -0
- package/agents/copilot.js.map +1 -0
- package/agents/cursor.d.ts +15 -0
- package/agents/cursor.js +33 -0
- package/agents/cursor.js.map +1 -0
- package/agents/instructions.d.ts +7 -0
- package/agents/instructions.js +13 -0
- package/agents/instructions.js.map +1 -0
- package/agents/shared.d.ts +41 -0
- package/agents/shared.js +124 -0
- package/agents/shared.js.map +1 -0
- package/agents/windsurf.d.ts +15 -0
- package/agents/windsurf.js +33 -0
- package/agents/windsurf.js.map +1 -0
- package/cli/ConfigureMcp.d.ts +15 -0
- package/cli/ConfigureMcp.js +57 -0
- package/cli/ConfigureMcp.js.map +1 -0
- package/cli/McpServer.d.ts +12 -0
- package/cli/McpServer.js +239 -0
- package/cli/McpServer.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +3 -0
- package/index.js.map +1 -0
- package/package.json +49 -0
- package/skills/admin-ui-extensions/SKILL.md +267 -0
- package/skills/cli-extensions/SKILL.md +133 -0
- package/skills/content-models/SKILL.md +306 -0
- package/skills/custom-graphql-api/SKILL.md +199 -0
- package/skills/dependency-injection/SKILL.md +252 -0
- package/skills/infrastructure-extensions/SKILL.md +192 -0
- package/skills/lifecycle-events/SKILL.md +203 -0
- package/skills/local-development/SKILL.md +245 -0
- package/skills/project-structure/SKILL.md +156 -0
- package/skills/webiny-sdk/SKILL.md +271 -0
- package/skills/website-builder/SKILL.md +384 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: webiny-local-development
|
|
3
|
+
context: webiny-extensions
|
|
4
|
+
description: >
|
|
5
|
+
Deploying, developing locally, managing environments, and debugging Webiny projects.
|
|
6
|
+
Use this skill when the developer asks about deployment commands (deploy, destroy, info),
|
|
7
|
+
local development with watch mode (API or Admin), the Local Lambda Development system,
|
|
8
|
+
environment management (long-lived vs short-lived, production vs dev modes), build parameters,
|
|
9
|
+
state files, debugging API/Admin/Infrastructure errors, or the redeploy-after-watch requirement.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Local Development and Deployment
|
|
13
|
+
|
|
14
|
+
## TL;DR
|
|
15
|
+
|
|
16
|
+
Webiny is a serverless platform on AWS. Deploy with `yarn webiny deploy`, develop locally with `yarn webiny watch` (API uses Local Lambda Development, Admin runs a local React dev server). Projects support multiple environments (long-lived and short-lived). Always redeploy after stopping watch mode.
|
|
17
|
+
|
|
18
|
+
## Deployment
|
|
19
|
+
|
|
20
|
+
### Initial Deployment
|
|
21
|
+
|
|
22
|
+
Deploy all three applications (Core, API, Admin) at once:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
yarn webiny deploy
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This deploys to the `dev` environment by default. First deployment takes 5-15 minutes.
|
|
29
|
+
|
|
30
|
+
### Deploying Individual Applications
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn webiny deploy core # Infrastructure only
|
|
34
|
+
yarn webiny deploy api # Backend API only
|
|
35
|
+
yarn webiny deploy admin # Admin frontend only
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Deploy to a Specific Environment
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
yarn webiny deploy --env prod
|
|
42
|
+
yarn webiny deploy api --env staging
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Get Deployment Info
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
yarn webiny info # Shows all URLs (Admin, API, CloudFront)
|
|
49
|
+
yarn webiny info --env prod # Info for a specific environment
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Local Development
|
|
53
|
+
|
|
54
|
+
Before developing locally, you must deploy Core and API first:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
yarn webiny deploy core api
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Admin Development
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
yarn webiny watch admin
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Starts a local dev server at `http://localhost:3001`
|
|
67
|
+
- Hot module replacement for instant feedback
|
|
68
|
+
- Standard React development experience
|
|
69
|
+
- Use for: custom Admin UI extensions, white-label branding, custom views
|
|
70
|
+
|
|
71
|
+
### API Development (Local Lambda Development)
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
yarn webiny watch api
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
How it works:
|
|
78
|
+
1. **Lambda stubs deployed** -- real Lambda functions are replaced with stubs that forward events
|
|
79
|
+
2. **Events forwarded** -- requests to AWS get forwarded to your local machine
|
|
80
|
+
3. **Local execution** -- your code runs locally with full AWS Lambda environment
|
|
81
|
+
4. **Response routing** -- responses sent back through the Lambda stub
|
|
82
|
+
|
|
83
|
+
Benefits:
|
|
84
|
+
- See backend code changes instantly (no redeployment)
|
|
85
|
+
- Debug locally with standard Node.js tools
|
|
86
|
+
- Console logs appear directly in your terminal
|
|
87
|
+
|
|
88
|
+
**IMPORTANT: Redeploy After Watch**
|
|
89
|
+
|
|
90
|
+
When you stop `yarn webiny watch api`, your Lambda functions still contain stub code. You **must** redeploy:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
yarn webiny deploy api
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The watch command prints a reminder when you stop it.
|
|
97
|
+
|
|
98
|
+
### Running Both
|
|
99
|
+
|
|
100
|
+
You can run both watch commands simultaneously in separate terminals:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Terminal 1
|
|
104
|
+
yarn webiny watch api
|
|
105
|
+
|
|
106
|
+
# Terminal 2
|
|
107
|
+
yarn webiny watch admin
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Environments
|
|
111
|
+
|
|
112
|
+
### Long-Lived Environments
|
|
113
|
+
|
|
114
|
+
Persistent environments maintained over time:
|
|
115
|
+
- **dev** -- daily development
|
|
116
|
+
- **staging** -- pre-production testing
|
|
117
|
+
- **prod** -- production
|
|
118
|
+
|
|
119
|
+
Best practice: manage via CI/CD pipelines.
|
|
120
|
+
|
|
121
|
+
### Short-Lived Environments
|
|
122
|
+
|
|
123
|
+
Temporary environments for specific purposes:
|
|
124
|
+
- Feature branch testing
|
|
125
|
+
- PR previews
|
|
126
|
+
- Experimentation
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Create a short-lived environment
|
|
130
|
+
yarn webiny deploy --env feature-123
|
|
131
|
+
|
|
132
|
+
# Destroy when done
|
|
133
|
+
yarn webiny destroy --env feature-123
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Deployment Modes
|
|
137
|
+
|
|
138
|
+
Webiny has two deployment templates:
|
|
139
|
+
- **dev** -- smaller, cheaper infrastructure for development
|
|
140
|
+
- **prod** -- production-grade infrastructure with HA, backups, auto-scaling
|
|
141
|
+
|
|
142
|
+
The mode is determined by whether the environment name is in the `ProductionEnvironments` list:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
// webiny.config.tsx
|
|
146
|
+
<Infra.ProductionEnvironments environments={["prod", "staging"]} />
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## State Files
|
|
150
|
+
|
|
151
|
+
State files are JSON files that track the current state of your deployment:
|
|
152
|
+
- Store infrastructure resource info, configurations, and metadata
|
|
153
|
+
- Essential for managing environments and tracking changes
|
|
154
|
+
- Stored in S3 by default
|
|
155
|
+
|
|
156
|
+
## Build Parameters
|
|
157
|
+
|
|
158
|
+
Pass custom config values from `webiny.config.tsx` to your extensions:
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
// webiny.config.tsx
|
|
162
|
+
<Api.BuildParam paramName="MY_PARAM" value="customValue" />
|
|
163
|
+
<Api.BuildParam paramName="MY_CONFIG" value={{ myKey: 2, nested: { foo: "bar" } }} />
|
|
164
|
+
<Admin.BuildParam paramName="ADMIN_PARAM" value="adminValue" />
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Access in API extensions:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { BuildParams } from "webiny/api/build-params";
|
|
171
|
+
|
|
172
|
+
class MyExtension implements SomeFactory.Interface {
|
|
173
|
+
constructor(private buildParams: BuildParams.Interface) {}
|
|
174
|
+
|
|
175
|
+
execute() {
|
|
176
|
+
const value = this.buildParams.get<string>("MY_PARAM");
|
|
177
|
+
const config = this.buildParams.get<{ myKey: number }>("MY_CONFIG");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Debugging
|
|
183
|
+
|
|
184
|
+
### API Errors
|
|
185
|
+
|
|
186
|
+
During `yarn webiny watch api`:
|
|
187
|
+
- **Console logs** appear directly in the terminal
|
|
188
|
+
- Use `console.log()` for quick debugging
|
|
189
|
+
- Use `Logger` (DI-injected) for production logging to CloudWatch
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { Logger } from "webiny/api/logger";
|
|
193
|
+
|
|
194
|
+
// In your extension class
|
|
195
|
+
this.logger.info("Processing request...");
|
|
196
|
+
this.logger.warn("Something unexpected");
|
|
197
|
+
this.logger.error("Something failed");
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Admin Errors
|
|
201
|
+
|
|
202
|
+
Use browser DevTools:
|
|
203
|
+
- **Console** -- view logs and errors
|
|
204
|
+
- **Network tab** -- inspect GraphQL requests/responses
|
|
205
|
+
- **React Developer Tools** -- debug component state/props
|
|
206
|
+
- **GraphQL Network Inspector** -- inspect GraphQL operations
|
|
207
|
+
|
|
208
|
+
### Infrastructure Errors
|
|
209
|
+
|
|
210
|
+
Deployment errors from Pulumi typically relate to:
|
|
211
|
+
- IAM permission issues
|
|
212
|
+
- AWS service quotas
|
|
213
|
+
- Resource configuration problems
|
|
214
|
+
|
|
215
|
+
Check the deployment output for specific error messages.
|
|
216
|
+
|
|
217
|
+
## CLI Commands Reference
|
|
218
|
+
|
|
219
|
+
| Command | Purpose |
|
|
220
|
+
|---|---|
|
|
221
|
+
| `yarn webiny deploy` | Deploy all applications |
|
|
222
|
+
| `yarn webiny deploy [core\|api\|admin]` | Deploy specific application |
|
|
223
|
+
| `yarn webiny deploy --env <name>` | Deploy to specific environment |
|
|
224
|
+
| `yarn webiny destroy --env <name>` | Destroy an environment |
|
|
225
|
+
| `yarn webiny watch api` | Start local API development |
|
|
226
|
+
| `yarn webiny watch admin` | Start local Admin development |
|
|
227
|
+
| `yarn webiny info` | Show deployment info and URLs |
|
|
228
|
+
| `yarn webiny info --env <name>` | Show info for specific environment |
|
|
229
|
+
| `yarn webiny extension <name>` | Install a pre-built extension |
|
|
230
|
+
|
|
231
|
+
## Quick Reference
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
First deploy: yarn webiny deploy
|
|
235
|
+
Dev API: yarn webiny watch api
|
|
236
|
+
Dev Admin: yarn webiny watch admin
|
|
237
|
+
Get URLs: yarn webiny info
|
|
238
|
+
Deploy env: yarn webiny deploy --env staging
|
|
239
|
+
After watch: yarn webiny deploy api (MUST redeploy!)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Related Skills
|
|
243
|
+
|
|
244
|
+
- `project-structure` -- Project layout and `webiny.config.tsx`
|
|
245
|
+
- `infrastructure-extensions` -- Customizing AWS infrastructure and environments
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: webiny-project-structure
|
|
3
|
+
context: webiny-extensions
|
|
4
|
+
description: >
|
|
5
|
+
Webiny project layout, webiny.config.tsx anatomy, and extension registration.
|
|
6
|
+
Use this skill when the developer asks about folder structure, where custom code goes,
|
|
7
|
+
how to register extensions, what webiny.config.tsx does, or how the project is organized.
|
|
8
|
+
Also use when they need to understand the relationship between extensions/, webiny.config.tsx,
|
|
9
|
+
and the different extension types (Api, Admin, Infra, CLI).
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Webiny Project Structure
|
|
13
|
+
|
|
14
|
+
## TL;DR
|
|
15
|
+
|
|
16
|
+
A Webiny project has a flat structure centered around `webiny.config.tsx` -- the single configuration file where all extensions are registered. Custom code lives in the `extensions/` folder. Extensions are registered as React components (`<Api.Extension>`, `<Admin.Extension>`, `<Infra.*>`, `<Cli.Command>`) and can be conditionally loaded per environment.
|
|
17
|
+
|
|
18
|
+
## Project Layout
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
my-webiny-project/
|
|
22
|
+
├── extensions/ # All custom code -- API, Admin, Infra, CLI extensions
|
|
23
|
+
│ └── README.md
|
|
24
|
+
├── public/ # Static assets for the Admin app
|
|
25
|
+
│ ├── favicon.ico
|
|
26
|
+
│ ├── global.css
|
|
27
|
+
│ ├── index.html
|
|
28
|
+
│ └── robots.txt
|
|
29
|
+
├── eslint.config.js # ESLint configuration
|
|
30
|
+
├── package.json # Single package.json for the whole project
|
|
31
|
+
├── tsconfig.json # Single TypeScript config
|
|
32
|
+
├── webiny.config.tsx # Main configuration -- all extensions registered here
|
|
33
|
+
├── webiny-env.d.ts # TypeScript environment types
|
|
34
|
+
└── yarn.lock
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Key points:
|
|
38
|
+
- **Single `package.json`** -- no monorepo, no workspaces needed.
|
|
39
|
+
- **Single `tsconfig.json`** -- straightforward TypeScript setup.
|
|
40
|
+
- **`webiny.config.tsx`** -- the entry point for everything. All extensions, infrastructure options, and project settings are declared here.
|
|
41
|
+
- **`extensions/`** -- where all your custom code lives. Organize with subfolders as needed (e.g., `extensions/contactSubmission/`, `extensions/AdminBranding/`).
|
|
42
|
+
|
|
43
|
+
## The `webiny.config.tsx` File
|
|
44
|
+
|
|
45
|
+
This file exports a single React component called `Extensions`. It uses JSX to declaratively register all configuration:
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
// webiny.config.tsx
|
|
49
|
+
import React from "react";
|
|
50
|
+
import { Admin, Api, Cli, Infra, Project, Security } from "webiny/extensions";
|
|
51
|
+
import { Cognito } from "@webiny/cognito";
|
|
52
|
+
|
|
53
|
+
export const Extensions = () => {
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
{/* Infrastructure configuration */}
|
|
57
|
+
<Infra.Aws.DefaultRegion name={"us-east-1"} />
|
|
58
|
+
<Infra.OpenSearch enabled={true} />
|
|
59
|
+
<Infra.Aws.Tags tags={{ OWNER: "me", PROJECT: "my-project" }} />
|
|
60
|
+
|
|
61
|
+
{/* Identity provider */}
|
|
62
|
+
<Cognito />
|
|
63
|
+
|
|
64
|
+
{/* API extensions (backend) */}
|
|
65
|
+
<Api.Extension src={"/extensions/ProductCategoryModel.ts"} />
|
|
66
|
+
<Api.Extension src={"/extensions/ProductModel.ts"} />
|
|
67
|
+
<Api.Extension src={"/extensions/contactSubmission/ContactSubmissionHook.ts"} />
|
|
68
|
+
|
|
69
|
+
{/* Security hooks */}
|
|
70
|
+
<Api.Extension src={"/extensions/MyApiKey.ts"} />
|
|
71
|
+
<Security.ApiKey.AfterUpdate src={"/extensions/MyApiKeyAfterUpdate.ts"} />
|
|
72
|
+
|
|
73
|
+
{/* Admin extensions (frontend) */}
|
|
74
|
+
<Admin.Extension src={"/extensions/AdminTheme/AdminTheme.tsx"} />
|
|
75
|
+
<Admin.Extension src={"/extensions/AdminTitleLogo/AdminTitleLogo.tsx"} />
|
|
76
|
+
<Admin.Extension src={"/extensions/contactSubmission/EmailEntryListColumn.tsx"} />
|
|
77
|
+
|
|
78
|
+
{/* Infrastructure / Pulumi extensions */}
|
|
79
|
+
<Infra.Core.Pulumi src={"/extensions/MyCorePulumiHandler.ts"} />
|
|
80
|
+
|
|
81
|
+
{/* CLI extensions */}
|
|
82
|
+
<Cli.Command src={"/extensions/MyCustomCommand.ts"} />
|
|
83
|
+
|
|
84
|
+
{/* Project settings */}
|
|
85
|
+
<Project.Telemetry enabled={false} />
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Extension Types
|
|
92
|
+
|
|
93
|
+
| JSX Element | What It Does | File Type |
|
|
94
|
+
|---|---|---|
|
|
95
|
+
| `<Api.Extension src="..." />` | Registers a backend extension (GraphQL schemas, content models, lifecycle hooks) | `.ts` |
|
|
96
|
+
| `<Admin.Extension src="..." />` | Registers a frontend Admin UI extension (themes, branding, custom columns, custom forms) | `.tsx` |
|
|
97
|
+
| `<Infra.Core.Pulumi src="..." />` | Registers a Pulumi infrastructure handler | `.ts` |
|
|
98
|
+
| `<Cli.Command src="..." />` | Registers a custom CLI command | `.ts` |
|
|
99
|
+
| `<Security.ApiKey.AfterUpdate src="..." />` | Registers a security lifecycle hook | `.ts` |
|
|
100
|
+
|
|
101
|
+
## Infrastructure Components
|
|
102
|
+
|
|
103
|
+
Declarative components for configuring AWS infrastructure:
|
|
104
|
+
|
|
105
|
+
| Component | Purpose |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `<Infra.Aws.DefaultRegion name="us-east-1" />` | Set the AWS region |
|
|
108
|
+
| `<Infra.Aws.Tags tags={{ KEY: "value" }} />` | Apply tags to all AWS resources |
|
|
109
|
+
| `<Infra.OpenSearch enabled={true} />` | Enable/disable OpenSearch |
|
|
110
|
+
| `<Infra.Vpc enabled={true} />` | Enable/disable VPC deployment |
|
|
111
|
+
| `<Infra.PulumiResourceNamePrefix prefix="myproj-" />` | Prefix all Pulumi resource names |
|
|
112
|
+
| `<Infra.ProductionEnvironments environments={["prod", "staging"]} />` | Define which envs use production infra |
|
|
113
|
+
| `<Project.Telemetry enabled={false} />` | Enable/disable telemetry |
|
|
114
|
+
|
|
115
|
+
## Environment-Conditional Configuration
|
|
116
|
+
|
|
117
|
+
Use `<Infra.Env.Is>` to load extensions or config only in specific environments:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
<Infra.Env.Is env="prod">
|
|
121
|
+
<Infra.Aws.Tags tags={{ ENV: "production" }} />
|
|
122
|
+
<Infra.OpenSearch enabled={true} />
|
|
123
|
+
</Infra.Env.Is>
|
|
124
|
+
|
|
125
|
+
<Infra.Env.Is env={["dev", "staging"]}>
|
|
126
|
+
<Infra.Aws.Tags tags={{ ENV: "non-production" }} />
|
|
127
|
+
<Infra.OpenSearch enabled={false} />
|
|
128
|
+
</Infra.Env.Is>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Build Parameters
|
|
132
|
+
|
|
133
|
+
Pass custom values from config to extensions at build time:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
<Api.BuildParam paramName="MY_CUSTOM_PARAM" value="customValue" />
|
|
137
|
+
<Api.BuildParam paramName="MY_CONFIG" value={{ myKey: 2, nested: { foo: "bar" } }} />
|
|
138
|
+
<Admin.BuildParam paramName="ADMIN_CUSTOM_PARAM" value="adminValue" />
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
These are accessed in extensions via the `BuildParams` feature (see dependency-injection skill).
|
|
142
|
+
|
|
143
|
+
## Installing Pre-Built Extensions
|
|
144
|
+
|
|
145
|
+
Webiny provides official extensions you can install with:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
yarn webiny extension <extension-name>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
This downloads the extension code into `extensions/`, updates `webiny.config.tsx` to register it, and gives you full access to modify the code.
|
|
152
|
+
|
|
153
|
+
## Related Skills
|
|
154
|
+
|
|
155
|
+
- `dependency-injection` -- How extensions use DI to access services
|
|
156
|
+
- `local-development` -- How to deploy and develop locally
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: webiny-sdk
|
|
3
|
+
context: webiny-extensions
|
|
4
|
+
description: >
|
|
5
|
+
Using @webiny/sdk to read and write CMS data from external applications.
|
|
6
|
+
Use this skill when the developer is building a Next.js, Vue, Node.js, or any external app
|
|
7
|
+
that needs to fetch or write content to Webiny, set up the SDK, use the Result pattern,
|
|
8
|
+
list/get/create/update/publish entries, filter and sort queries, use TypeScript generics
|
|
9
|
+
for type safety, work with the File Manager, or create API keys programmatically. Also
|
|
10
|
+
covers the three API types (Read, Manage, Preview) and CmsEntryData typing.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Webiny SDK
|
|
14
|
+
|
|
15
|
+
## TL;DR
|
|
16
|
+
|
|
17
|
+
The `@webiny/sdk` package provides a TypeScript interface for external apps (Next.js, Vue, Node.js) to interact with Webiny's Headless CMS and File Manager. Every method returns a `Result` object (checked with `isOk()`). Supports listing, getting, creating, updating, publishing, and unpublishing entries with filtering, sorting, pagination, and TypeScript generics for type safety.
|
|
18
|
+
|
|
19
|
+
## Installation & Setup
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @webiny/sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Initialize once and reuse:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// lib/webiny.ts
|
|
29
|
+
import { Sdk } from "@webiny/sdk";
|
|
30
|
+
|
|
31
|
+
export const sdk = new Sdk({
|
|
32
|
+
token: process.env.WEBINY_API_TOKEN!,
|
|
33
|
+
endpoint: process.env.WEBINY_API_ENDPOINT!,
|
|
34
|
+
tenant: process.env.WEBINY_API_TENANT || "root"
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- `token` -- API key token generated in Webiny Admin (Settings > API Keys)
|
|
39
|
+
- `endpoint` -- The base CloudFront URL (e.g., `https://xxx.cloudfront.net`). Run `yarn webiny info` to find it.
|
|
40
|
+
- `tenant` -- Tenant ID, defaults to `"root"`
|
|
41
|
+
|
|
42
|
+
## The Three API Types
|
|
43
|
+
|
|
44
|
+
Webiny provides three separate GraphQL APIs:
|
|
45
|
+
|
|
46
|
+
| API | URL Path | Returns | Can Write | Use For |
|
|
47
|
+
|---|---|---|---|---|
|
|
48
|
+
| **Read** | `/cms/read` | Published entries only | No | Public-facing apps, SSG |
|
|
49
|
+
| **Manage** | `/cms/manage` | All revisions (drafts + published) | Yes | Admin tools, content creation |
|
|
50
|
+
| **Preview** | `/cms/preview` | Latest revisions (drafts + published) | No | Content preview |
|
|
51
|
+
|
|
52
|
+
The SDK automatically routes to the correct API based on the method:
|
|
53
|
+
- `listEntries`, `getEntry` -> Read API
|
|
54
|
+
- `createEntry`, `updateEntry`, `publishEntry`, `unpublishEntry` -> Manage API
|
|
55
|
+
|
|
56
|
+
## The Result Pattern
|
|
57
|
+
|
|
58
|
+
Every SDK method returns a `Result` object -- it never throws:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const result = await sdk.cms.listEntries({ modelId: "product", fields: ["id"] });
|
|
62
|
+
|
|
63
|
+
if (result.isOk()) {
|
|
64
|
+
console.log(result.value.data); // success -- typed data
|
|
65
|
+
} else {
|
|
66
|
+
console.error(result.error.message); // failure -- error info
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## TypeScript Generics
|
|
71
|
+
|
|
72
|
+
Pass a type parameter for full type safety on `values`:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import type { CmsEntryData } from "@webiny/sdk";
|
|
76
|
+
|
|
77
|
+
interface Product {
|
|
78
|
+
name: string;
|
|
79
|
+
price: number;
|
|
80
|
+
sku: string;
|
|
81
|
+
description: string;
|
|
82
|
+
category?: CmsEntryData<ProductCategory>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface ProductCategory {
|
|
86
|
+
name: string;
|
|
87
|
+
slug: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const result = await sdk.cms.listEntries<Product>({
|
|
91
|
+
modelId: "product"
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (result.isOk()) {
|
|
95
|
+
// result.value.data is CmsEntryData<Product>[]
|
|
96
|
+
const products = result.value.data;
|
|
97
|
+
// products[0].values.name -- fully typed
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Reference fields like `category` are typed as `CmsEntryData<T>`, which wraps referenced entries with `id`, `entryId`, and `values`.
|
|
102
|
+
|
|
103
|
+
## Reading Data
|
|
104
|
+
|
|
105
|
+
### List Entries
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const result = await sdk.cms.listEntries<Product>({
|
|
109
|
+
modelId: "product",
|
|
110
|
+
sort: ["values.name_ASC"],
|
|
111
|
+
limit: 10
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### List with Filters
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const result = await sdk.cms.listEntries<Product>({
|
|
119
|
+
modelId: "product",
|
|
120
|
+
where: {
|
|
121
|
+
"values.price_gte": 100,
|
|
122
|
+
"values.name_contains": "Pro"
|
|
123
|
+
},
|
|
124
|
+
sort: ["values.price_DESC"]
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Filter Operators
|
|
129
|
+
|
|
130
|
+
| Operator | Description | Example |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `_eq` | Equals (default) | `"values.status": "active"` |
|
|
133
|
+
| `_not` | Not equals | `"values.status_not": "archived"` |
|
|
134
|
+
| `_contains` | Contains substring | `"values.name_contains": "Pro"` |
|
|
135
|
+
| `_startsWith` | Starts with | `"values.name_startsWith": "Web"` |
|
|
136
|
+
| `_gt` / `_gte` | Greater than / >= | `"values.price_gte": 100` |
|
|
137
|
+
| `_lt` / `_lte` | Less than / <= | `"values.price_lt": 500` |
|
|
138
|
+
| `_in` | In array | `"values.status_in": ["active", "featured"]` |
|
|
139
|
+
|
|
140
|
+
### Sort Format
|
|
141
|
+
|
|
142
|
+
Sort strings follow the pattern `values.<fieldId>_ASC` or `values.<fieldId>_DESC`:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
sort: ["values.name_ASC"] // alphabetical
|
|
146
|
+
sort: ["values.price_DESC"] // highest price first
|
|
147
|
+
sort: ["values.createdOn_DESC"] // newest first
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Get Single Entry
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const result = await sdk.cms.getEntry<Product>({
|
|
154
|
+
modelId: "product",
|
|
155
|
+
id: "abc123#0001"
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### The `fields` Parameter
|
|
160
|
+
|
|
161
|
+
Control which fields are returned:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const result = await sdk.cms.listEntries<Product>({
|
|
165
|
+
modelId: "product",
|
|
166
|
+
fields: ["id", "values.name", "values.price"]
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
When omitted, all fields are returned. The `depth` parameter (default: `1`) controls how deeply reference fields are resolved.
|
|
171
|
+
|
|
172
|
+
## Writing Data
|
|
173
|
+
|
|
174
|
+
### Create an Entry
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const result = await sdk.cms.createEntry({
|
|
178
|
+
modelId: "contactSubmission",
|
|
179
|
+
data: {
|
|
180
|
+
name: "John Doe",
|
|
181
|
+
email: "john@example.com",
|
|
182
|
+
message: "Hello from the contact form!"
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Update an Entry
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const result = await sdk.cms.updateEntry({
|
|
191
|
+
modelId: "product",
|
|
192
|
+
id: "abc123#0001",
|
|
193
|
+
data: {
|
|
194
|
+
price: 29.99
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Publish / Unpublish
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
await sdk.cms.publishEntry({ modelId: "product", id: "abc123#0001" });
|
|
203
|
+
await sdk.cms.unpublishEntry({ modelId: "product", id: "abc123#0001" });
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## File Manager
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
// List files
|
|
210
|
+
const files = await sdk.fileManager.listFiles({ limit: 20 });
|
|
211
|
+
|
|
212
|
+
// Upload a file
|
|
213
|
+
const uploaded = await sdk.fileManager.uploadFile({ file: myFile });
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Creating API Keys via Code
|
|
217
|
+
|
|
218
|
+
For programmatic access, create API keys as an extension:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// extensions/MyApiKey.ts
|
|
222
|
+
import { ApiKeyFactory } from "webiny/api/security";
|
|
223
|
+
|
|
224
|
+
class MyApiKeyImpl implements ApiKeyFactory.Interface {
|
|
225
|
+
execute(): ApiKeyFactory.Return {
|
|
226
|
+
return [
|
|
227
|
+
{
|
|
228
|
+
name: "Universal API Key",
|
|
229
|
+
slug: "universal-key",
|
|
230
|
+
token: "wat_12345678",
|
|
231
|
+
permissions: [{ name: "*" }]
|
|
232
|
+
}
|
|
233
|
+
];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export default ApiKeyFactory.createImplementation({
|
|
238
|
+
implementation: MyApiKeyImpl,
|
|
239
|
+
dependencies: []
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Register:
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
<Api.Extension src={"/extensions/MyApiKey.ts"} />
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## SDK Modules Reference
|
|
250
|
+
|
|
251
|
+
| Module | Webiny App | What You Can Do |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| `sdk.cms` | Headless CMS | List, get, create, update, publish, unpublish entries |
|
|
254
|
+
| `sdk.fileManager` | File Manager | List, upload, and manage files and folders |
|
|
255
|
+
| `sdk.websiteBuilder` | Website Builder | List and retrieve website builder content |
|
|
256
|
+
|
|
257
|
+
## Quick Reference
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
Install: npm install @webiny/sdk
|
|
261
|
+
Import: import { Sdk } from "@webiny/sdk";
|
|
262
|
+
Type import: import type { CmsEntryData } from "@webiny/sdk";
|
|
263
|
+
Initialize: new Sdk({ token, endpoint, tenant })
|
|
264
|
+
Result check: result.isOk() -> result.value.data / result.error.message
|
|
265
|
+
API endpoint: yarn webiny info (in your Webiny project)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Related Skills
|
|
269
|
+
|
|
270
|
+
- `content-models` -- Define the models you query with the SDK
|
|
271
|
+
- `website-builder` -- Use the SDK inside Website Builder components to fetch CMS data
|