@webiny/mcp 6.0.0-rc.5 → 6.0.0-rc.6
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/package.json +4 -4
- package/skills/api-custom-feature/SKILL.md +195 -0
- package/skills/configure-auth0/SKILL.md +290 -0
- package/skills/configure-okta/SKILL.md +291 -0
- package/skills/custom-graphql-api/SKILL.md +145 -135
- package/skills/dependency-injection/SKILL.md +277 -149
- package/skills/infrastructure-extensions/SKILL.md +84 -66
- package/skills/lifecycle-events/SKILL.md +151 -6
- package/skills/local-development/SKILL.md +25 -16
|
@@ -24,24 +24,25 @@ import { Logger } from "webiny/api/logger";
|
|
|
24
24
|
import { BuildParams } from "webiny/api/build-params";
|
|
25
25
|
|
|
26
26
|
class MyImplementation implements SomeFactory.Interface {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
constructor(
|
|
28
|
+
private logger: Logger.Interface,
|
|
29
|
+
private buildParams: BuildParams.Interface
|
|
30
|
+
) {}
|
|
31
|
+
|
|
32
|
+
execute(/* factory-specific params */) {
|
|
33
|
+
this.logger.info("Doing something...");
|
|
34
|
+
const value = this.buildParams.get<string>("MY_PARAM");
|
|
35
|
+
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export default SomeFactory.createImplementation({
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
implementation: MyImplementation,
|
|
40
|
+
dependencies: [Logger, BuildParams]
|
|
41
41
|
});
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Key rules:
|
|
45
|
+
|
|
45
46
|
1. **One class per file** -- each extension file exports a single implementation.
|
|
46
47
|
2. **Constructor injection** -- dependencies are received as constructor parameters, in the same order as the `dependencies` array.
|
|
47
48
|
3. **Dependencies array** -- must exactly match the constructor parameter order and types.
|
|
@@ -49,146 +50,273 @@ Key rules:
|
|
|
49
50
|
|
|
50
51
|
## Where This Pattern Appears
|
|
51
52
|
|
|
52
|
-
| Extension Type
|
|
53
|
-
|
|
54
|
-
| Content Models
|
|
55
|
-
| GraphQL Schemas | `GraphQLSchemaFactory` | `"webiny/api/graphql"`
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| CLI Commands | `CliCommandFactory` | `"webiny/cli/command"` |
|
|
60
|
-
| Pulumi Handlers | `CorePulumi` | `"webiny/infra/core"` |
|
|
61
|
-
|
|
62
|
-
## Injectable Services
|
|
63
|
-
|
|
64
|
-
### Utility Services
|
|
53
|
+
| Extension Type | Factory | Import Path |
|
|
54
|
+
| --------------- | ---------------------- | ------------------------ |
|
|
55
|
+
| Content Models | `ModelFactory` | `"webiny/api/cms/model"` |
|
|
56
|
+
| GraphQL Schemas | `GraphQLSchemaFactory` | `"webiny/api/graphql"` |
|
|
57
|
+
| API Keys | `ApiKeyFactory` | `"webiny/api/security"` |
|
|
58
|
+
| CLI Commands | `CliCommandFactory` | `"webiny/cli/command"` |
|
|
59
|
+
| Pulumi Handlers | `CorePulumi` | `"webiny/infra/core"` |
|
|
65
60
|
|
|
66
|
-
|
|
67
|
-
|---|-----------------------------|---|---|---|
|
|
68
|
-
| `Logger` | `"webiny/api/logger"` | `Logger.Interface` | API | Logging (persists to CloudWatch) |
|
|
69
|
-
| `BuildParams` | `"webiny/api/build-params"` | `BuildParams.Interface` | API | Access build-time parameters |
|
|
70
|
-
| `Ui` (CLI) | `"webiny/cli"` | `Ui.Interface` | CLI | Terminal output formatting |
|
|
71
|
-
| `Ui` (Infra) | `"webiny/infra"` | `Ui.Interface` | Infra | Terminal output during deploy |
|
|
72
|
-
|
|
73
|
-
### Logger Methods
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
this.logger.info("Informational message");
|
|
77
|
-
this.logger.warn("Warning message");
|
|
78
|
-
this.logger.error("Error message");
|
|
79
|
-
this.logger.debug("Debug message");
|
|
80
|
-
```
|
|
61
|
+
> **Event handlers** use the same `createImplementation` pattern but are not injectable dependencies. See the `lifecycle-events` skill for the full list.
|
|
81
62
|
|
|
82
|
-
|
|
63
|
+
## Injectable Abstractions
|
|
83
64
|
|
|
84
|
-
|
|
85
|
-
// Get a string parameter
|
|
86
|
-
const value = this.buildParams.get<string>("MY_PARAM");
|
|
65
|
+
Every Abstraction listed below can be used as a constructor dependency or as a base for `createImplementation`. Import from the `"webiny/..."` path shown.
|
|
87
66
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
67
|
+
### `webiny/api/build-params`
|
|
68
|
+
|
|
69
|
+
| Abstraction | Purpose |
|
|
70
|
+
| ------------ | ------------------------ |
|
|
71
|
+
| `BuildParam` | Define a build parameter |
|
|
72
|
+
| `BuildParams` | Access build-time parameters |
|
|
91
73
|
|
|
92
|
-
|
|
74
|
+
### `webiny/api/logger`
|
|
75
|
+
|
|
76
|
+
| Abstraction | Purpose |
|
|
77
|
+
| ----------- | -------------------------------- |
|
|
78
|
+
| `Logger` | Logging (persists to CloudWatch) |
|
|
93
79
|
|
|
94
|
-
|
|
95
|
-
<Api.BuildParam paramName="MY_PARAM" value="customValue" />
|
|
96
|
-
<Api.BuildParam paramName="MY_CONFIG" value={{ myKey: 2, nested: { foo: "bar" } }} />
|
|
97
|
-
```
|
|
80
|
+
### `webiny/api/key-value-store`
|
|
98
81
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
| `
|
|
109
|
-
|
|
110
|
-
###
|
|
111
|
-
|
|
112
|
-
|
|
|
113
|
-
|
|
114
|
-
| `
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
| `
|
|
128
|
-
|
|
129
|
-
###
|
|
130
|
-
|
|
131
|
-
|
|
|
132
|
-
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
82
|
+
| Abstraction | Purpose |
|
|
83
|
+
| -------------------- | ------------------------------ |
|
|
84
|
+
| `GlobalKeyValueStore` | Global (cross-tenant) key-value store |
|
|
85
|
+
| `KeyValueStore` | Tenant-scoped key-value store |
|
|
86
|
+
|
|
87
|
+
### `webiny/api/event-publisher`
|
|
88
|
+
|
|
89
|
+
| Abstraction | Purpose |
|
|
90
|
+
| ---------------- | -------------------- |
|
|
91
|
+
| `EventPublisher` | Publish domain events |
|
|
92
|
+
|
|
93
|
+
### `webiny/api/graphql`
|
|
94
|
+
|
|
95
|
+
| Abstraction | Purpose |
|
|
96
|
+
| ---------------------- | --------------------- |
|
|
97
|
+
| `GraphQLSchemaFactory` | Define GraphQL schemas |
|
|
98
|
+
|
|
99
|
+
### `webiny/api/tasks`
|
|
100
|
+
|
|
101
|
+
| Abstraction | Purpose |
|
|
102
|
+
| ---------------- | ---------------------- |
|
|
103
|
+
| `TaskService` | Task management service |
|
|
104
|
+
| `TaskDefinition` | Define a background task |
|
|
105
|
+
|
|
106
|
+
### `webiny/api/system`
|
|
107
|
+
|
|
108
|
+
| Abstraction | Purpose |
|
|
109
|
+
| ---------------------- | ------------------------- |
|
|
110
|
+
| `InstallSystemUseCase` | System installation logic |
|
|
111
|
+
|
|
112
|
+
### `webiny/api/security`
|
|
113
|
+
|
|
114
|
+
| Abstraction | Purpose |
|
|
115
|
+
| --------------------- | ------------------------------------- |
|
|
116
|
+
| `IdentityContext` | Current user identity and permissions |
|
|
117
|
+
| `ApiKeyFactory` | Define custom API key types |
|
|
118
|
+
| `IdentityProvider` | Base identity provider abstraction |
|
|
119
|
+
| `OidcIdentityProvider` | OIDC identity provider |
|
|
120
|
+
| `JwtIdentityProvider` | JWT identity provider |
|
|
121
|
+
| `Authenticator` | Authentication logic |
|
|
122
|
+
| `Authorizer` | Authorization logic |
|
|
123
|
+
|
|
124
|
+
### `webiny/api/security/api-key`
|
|
125
|
+
|
|
126
|
+
| Abstraction | Purpose |
|
|
127
|
+
| ----------------------- | --------------------------- |
|
|
128
|
+
| `CreateApiKeyUseCase` | Create an API key |
|
|
129
|
+
| `DeleteApiKeyUseCase` | Delete an API key |
|
|
130
|
+
| `GetApiKeyUseCase` | Get API key by ID |
|
|
131
|
+
| `GetApiKeyByTokenUseCase` | Get API key by token |
|
|
132
|
+
| `ListApiKeysUseCase` | List all API keys |
|
|
133
|
+
| `UpdateApiKeyUseCase` | Update an API key |
|
|
134
|
+
| `ApiKeyFactory` | Define custom API key types |
|
|
135
|
+
|
|
136
|
+
### `webiny/api/security/role`
|
|
137
|
+
|
|
138
|
+
| Abstraction | Purpose |
|
|
139
|
+
| ----------------- | -------------- |
|
|
140
|
+
| `CreateRoleUseCase` | Create a role |
|
|
141
|
+
| `DeleteRoleUseCase` | Delete a role |
|
|
142
|
+
| `GetRoleUseCase` | Get role by ID |
|
|
143
|
+
| `ListRolesUseCase` | List all roles |
|
|
144
|
+
| `UpdateRoleUseCase` | Update a role |
|
|
145
|
+
|
|
146
|
+
### `webiny/api/security/user`
|
|
147
|
+
|
|
148
|
+
| Abstraction | Purpose |
|
|
149
|
+
| -------------------- | ----------------- |
|
|
150
|
+
| `CreateUserUseCase` | Create a user |
|
|
151
|
+
| `DeleteUserUseCase` | Delete a user |
|
|
152
|
+
| `UpdateUserUseCase` | Update a user |
|
|
153
|
+
| `GetUserUseCase` | Get user by ID |
|
|
154
|
+
| `ListUsersUseCase` | List all users |
|
|
155
|
+
| `ListUserTeamsUseCase` | List user's teams |
|
|
156
|
+
|
|
157
|
+
### `webiny/api/tenancy`
|
|
158
|
+
|
|
159
|
+
| Abstraction | Purpose |
|
|
160
|
+
| ------------------------ | ------------------------------------ |
|
|
161
|
+
| `TenantContext` | Current tenant information |
|
|
162
|
+
| `CreateTenantUseCase` | Create a tenant |
|
|
163
|
+
| `CreateTenantRepository` | Tenant creation storage |
|
|
164
|
+
| `GetTenantByIdUseCase` | Fetch tenant by ID |
|
|
165
|
+
| `UpdateTenantUseCase` | Update a tenant |
|
|
166
|
+
| `UpdateTenantRepository` | Tenant update storage |
|
|
167
|
+
| `DeleteTenantUseCase` | Delete a tenant |
|
|
168
|
+
| `DeleteTenantRepository` | Tenant deletion storage |
|
|
169
|
+
| `InstallTenantUseCase` | Install a tenant |
|
|
170
|
+
| `AppInstaller` | App installation during tenant install |
|
|
171
|
+
|
|
172
|
+
### `webiny/api/tenant-manager`
|
|
173
|
+
|
|
174
|
+
| Abstraction | Purpose |
|
|
175
|
+
| ---------------------- | ------------------------------ |
|
|
176
|
+
| `TenantModelExtension` | Extend tenant data model |
|
|
177
|
+
|
|
178
|
+
### `webiny/api/cms/entry`
|
|
179
|
+
|
|
180
|
+
| Abstraction | Purpose |
|
|
181
|
+
| --------------------------------------------------- | ----------------------------------- |
|
|
182
|
+
| `CreateEntryUseCase` | Create a CMS entry |
|
|
183
|
+
| `CreateEntryRevisionFromUseCase` | Create entry revision from existing |
|
|
184
|
+
| `DeleteEntryUseCase` | Delete an entry |
|
|
185
|
+
| `MoveEntryToBinUseCase` | Move entry to bin |
|
|
186
|
+
| `DeleteEntryRevisionUseCase` | Delete a specific revision |
|
|
187
|
+
| `DeleteMultipleEntriesUseCase` | Delete multiple entries |
|
|
188
|
+
| `MoveEntryUseCase` | Move entry to folder |
|
|
189
|
+
| `PublishEntryUseCase` | Publish an entry |
|
|
190
|
+
| `RepublishEntryUseCase` | Republish an entry |
|
|
191
|
+
| `RestoreEntryFromBinUseCase` | Restore entry from bin |
|
|
192
|
+
| `UnpublishEntryUseCase` | Unpublish an entry |
|
|
193
|
+
| `UpdateEntryUseCase` | Update an entry |
|
|
194
|
+
| `UpdateSingletonEntryUseCase` | Update a singleton entry |
|
|
195
|
+
| `GetEntriesByIdsUseCase` | Get entries by IDs |
|
|
196
|
+
| `GetEntryUseCase` | Get entry by query |
|
|
197
|
+
| `GetEntryByIdUseCase` | Get entry by revision ID |
|
|
198
|
+
| `GetLatestEntriesByIdsUseCase` | Get latest entries by IDs |
|
|
199
|
+
| `GetLatestRevisionByEntryIdBaseUseCase` | Get latest revision (base) |
|
|
200
|
+
| `GetLatestRevisionByEntryIdUseCase` | Get latest revision |
|
|
201
|
+
| `GetLatestDeletedRevisionByEntryIdUseCase` | Get latest deleted revision |
|
|
202
|
+
| `GetLatestRevisionByEntryIdIncludingDeletedUseCase` | Get latest revision (incl. deleted) |
|
|
203
|
+
| `GetPreviousRevisionByEntryIdBaseUseCase` | Get previous revision (base) |
|
|
204
|
+
| `GetPreviousRevisionByEntryIdUseCase` | Get previous revision |
|
|
205
|
+
| `GetPublishedEntriesByIdsUseCase` | Get published entries by IDs |
|
|
206
|
+
| `GetPublishedRevisionByEntryIdUseCase` | Get published revision |
|
|
207
|
+
| `GetRevisionByIdUseCase` | Get revision by ID |
|
|
208
|
+
| `GetRevisionsByEntryIdUseCase` | Get all revisions of an entry |
|
|
209
|
+
| `GetSingletonEntryUseCase` | Get singleton entry |
|
|
210
|
+
| `ListEntriesUseCase` | List entries (base) |
|
|
211
|
+
| `ListLatestEntriesUseCase` | List latest entries |
|
|
212
|
+
| `ListPublishedEntriesUseCase` | List published entries |
|
|
213
|
+
| `ListDeletedEntriesUseCase` | List deleted entries |
|
|
214
|
+
| `ValidateEntryUseCase` | Validate entry data |
|
|
215
|
+
| `CmsWhereMapper` | Map CMS where conditions |
|
|
216
|
+
| `CmsSortMapper` | Map CMS sort conditions |
|
|
217
|
+
|
|
218
|
+
### `webiny/api/cms/model`
|
|
219
|
+
|
|
220
|
+
| Abstraction | Purpose |
|
|
221
|
+
| --------------------- | ------------------------- |
|
|
222
|
+
| `ModelFactory` | Define CMS content models |
|
|
223
|
+
| `FieldType` | Define custom field types |
|
|
224
|
+
| `CreateModelUseCase` | Create a model |
|
|
225
|
+
| `CreateModelFromUseCase` | Clone a model |
|
|
226
|
+
| `UpdateModelUseCase` | Update a model |
|
|
227
|
+
| `DeleteModelUseCase` | Delete a model |
|
|
228
|
+
| `GetModelUseCase` | Get model by ID |
|
|
229
|
+
| `ListModelsUseCase` | List all models |
|
|
230
|
+
|
|
231
|
+
### `webiny/api/cms/group`
|
|
232
|
+
|
|
233
|
+
| Abstraction | Purpose |
|
|
234
|
+
| -------------------- | --------------- |
|
|
235
|
+
| `ModelGroupFactory` | Define model groups |
|
|
236
|
+
| `CreateGroupUseCase` | Create a group |
|
|
237
|
+
| `UpdateGroupUseCase` | Update a group |
|
|
238
|
+
| `DeleteGroupUseCase` | Delete a group |
|
|
239
|
+
| `ListGroupsUseCase` | List all groups |
|
|
240
|
+
| `GetGroupUseCase` | Get group by ID |
|
|
241
|
+
|
|
242
|
+
### `webiny/api/website-builder/nextjs`
|
|
243
|
+
|
|
244
|
+
| Abstraction | Purpose |
|
|
245
|
+
| ------------- | -------------------------- |
|
|
246
|
+
| `NextjsConfig` | Configure Next.js integration |
|
|
247
|
+
|
|
248
|
+
### `webiny/api/website-builder/page`
|
|
249
|
+
|
|
250
|
+
| Abstraction | Purpose |
|
|
251
|
+
| ------------------------------- | ---------------------------------- |
|
|
252
|
+
| `CreatePageUseCase` | Create a page |
|
|
253
|
+
| `CreatePageRevisionFromUseCase` | Create page revision from existing |
|
|
254
|
+
| `DeletePageUseCase` | Delete a page |
|
|
255
|
+
| `DuplicatePageUseCase` | Duplicate a page |
|
|
256
|
+
| `GetPageByIdUseCase` | Get page by ID |
|
|
257
|
+
| `GetPageByPathUseCase` | Get page by path |
|
|
258
|
+
| `GetPageRevisionsUseCase` | Get page revisions |
|
|
259
|
+
| `ListPagesUseCase` | List pages |
|
|
260
|
+
| `MovePageUseCase` | Move a page |
|
|
261
|
+
| `PublishPageUseCase` | Publish a page |
|
|
262
|
+
| `UnpublishPageUseCase` | Unpublish a page |
|
|
263
|
+
| `UpdatePageUseCase` | Update a page |
|
|
264
|
+
|
|
265
|
+
### `webiny/api/website-builder/redirect`
|
|
266
|
+
|
|
267
|
+
| Abstraction | Purpose |
|
|
268
|
+
| --------------------------------- | -------------------------- |
|
|
269
|
+
| `CreateRedirectUseCase` | Create a redirect |
|
|
270
|
+
| `DeleteRedirectUseCase` | Delete a redirect |
|
|
271
|
+
| `GetActiveRedirectsUseCase` | Get active redirects |
|
|
272
|
+
| `GetRedirectByIdUseCase` | Get redirect by ID |
|
|
273
|
+
| `InvalidateRedirectsCacheUseCase` | Invalidate redirects cache |
|
|
274
|
+
| `ListRedirectsUseCase` | List redirects |
|
|
275
|
+
| `MoveRedirectUseCase` | Move a redirect |
|
|
276
|
+
| `UpdateRedirectUseCase` | Update a redirect |
|
|
138
277
|
|
|
139
278
|
## Examples Across Extension Types
|
|
140
279
|
|
|
141
280
|
### API Extension (GraphQL Schema with DI)
|
|
142
281
|
|
|
282
|
+
GraphQL schemas use the **builder pattern**. The `execute` method receives a `builder` and uses `addTypeDefs` and `addResolver` to define the schema. Resolver-level DI is declared per-resolver via `dependencies` in `addResolver`, resolved at request time from the request-scoped container.
|
|
283
|
+
|
|
143
284
|
```typescript
|
|
144
285
|
import { GraphQLSchemaFactory } from "webiny/api/graphql";
|
|
145
286
|
import { IdentityContext } from "webiny/api/security";
|
|
146
287
|
|
|
147
|
-
class
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
288
|
+
class WhoAmISchema implements GraphQLSchemaFactory.Interface {
|
|
289
|
+
async execute(
|
|
290
|
+
builder: GraphQLSchemaFactory.SchemaBuilder
|
|
291
|
+
): Promise<GraphQLSchemaFactory.SchemaBuilder> {
|
|
292
|
+
builder.addTypeDefs(/* GraphQL */ `
|
|
293
|
+
extend type Query {
|
|
294
|
+
whoAmI: String
|
|
295
|
+
}
|
|
296
|
+
`);
|
|
297
|
+
|
|
298
|
+
builder.addResolver({
|
|
299
|
+
path: "Query.whoAmI",
|
|
300
|
+
dependencies: [IdentityContext],
|
|
301
|
+
resolver: (identityContext: IdentityContext.Interface) => {
|
|
302
|
+
return () => {
|
|
303
|
+
const identity = identityContext.getIdentity();
|
|
304
|
+
return `Hello, ${identity.displayName}!`;
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
return builder;
|
|
310
|
+
}
|
|
165
311
|
}
|
|
166
312
|
|
|
167
313
|
export default GraphQLSchemaFactory.createImplementation({
|
|
168
|
-
|
|
169
|
-
|
|
314
|
+
implementation: WhoAmISchema,
|
|
315
|
+
dependencies: []
|
|
170
316
|
});
|
|
171
317
|
```
|
|
172
318
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
import { EntryBeforeCreateEventHandler as Handler } from "webiny/api/cms/entry";
|
|
177
|
-
import { Logger } from "webiny/api/logger";
|
|
178
|
-
|
|
179
|
-
class MyHookImpl implements Handler.Interface {
|
|
180
|
-
constructor(private logger: Logger.Interface) {}
|
|
181
|
-
|
|
182
|
-
async handle(event: Handler.Event): Promise<void> {
|
|
183
|
-
this.logger.info(`Entry created for model: ${event.modelId}`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export default Handler.createImplementation({
|
|
188
|
-
implementation: MyHookImpl,
|
|
189
|
-
dependencies: [Logger]
|
|
190
|
-
});
|
|
191
|
-
```
|
|
319
|
+
Note: `GraphQLSchemaFactory` implementations typically have `dependencies: []` because DI happens at the resolver level via `addResolver({ dependencies })`, not at the class constructor level.
|
|
192
320
|
|
|
193
321
|
### CLI Command with DI
|
|
194
322
|
|
|
@@ -197,23 +325,23 @@ import { Ui } from "webiny/cli";
|
|
|
197
325
|
import { CliCommandFactory } from "webiny/cli/command";
|
|
198
326
|
|
|
199
327
|
class MyCommandImpl implements CliCommandFactory.Interface<{ name: string }> {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
328
|
+
constructor(private ui: Ui.Interface) {}
|
|
329
|
+
|
|
330
|
+
execute(): CliCommandFactory.CommandDefinition<{ name: string }> {
|
|
331
|
+
return {
|
|
332
|
+
name: "greet",
|
|
333
|
+
description: "Greet someone",
|
|
334
|
+
params: [{ name: "name", description: "Name", type: "string" }],
|
|
335
|
+
handler: async params => {
|
|
336
|
+
this.ui.success(`Hello, ${params.name}!`);
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
}
|
|
212
340
|
}
|
|
213
341
|
|
|
214
342
|
export default CliCommandFactory.createImplementation({
|
|
215
|
-
|
|
216
|
-
|
|
343
|
+
implementation: MyCommandImpl,
|
|
344
|
+
dependencies: [Ui]
|
|
217
345
|
});
|
|
218
346
|
```
|
|
219
347
|
|
|
@@ -224,16 +352,16 @@ import { Ui } from "webiny/infra";
|
|
|
224
352
|
import { CorePulumi } from "webiny/infra/core";
|
|
225
353
|
|
|
226
354
|
class MyPulumiImpl implements CorePulumi.Interface {
|
|
227
|
-
|
|
355
|
+
constructor(private ui: Ui.Interface) {}
|
|
228
356
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
357
|
+
execute(app: any) {
|
|
358
|
+
this.ui.info("Deploying with environment:", app.env);
|
|
359
|
+
}
|
|
232
360
|
}
|
|
233
361
|
|
|
234
362
|
export default CorePulumi.createImplementation({
|
|
235
|
-
|
|
236
|
-
|
|
363
|
+
implementation: MyPulumiImpl,
|
|
364
|
+
dependencies: [Ui]
|
|
237
365
|
});
|
|
238
366
|
```
|
|
239
367
|
|