serverless-plugin-module-registry 1.0.4 → 1.0.8
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/README.md +257 -11
- package/dist/index.d.ts +373 -63
- package/dist/index.js +10198 -453
- package/dist/index.js.map +1 -1
- package/package.json +17 -8
package/README.md
CHANGED
|
@@ -120,6 +120,10 @@ The plugin creates an **intermodular** `ModuleRegistry` table using **AWS SDK v3
|
|
|
120
120
|
- **GSI1PK**: `MODULES` (for listing all modules)
|
|
121
121
|
- **GSI1SK**: `MODULE#{moduleName}` (for grouping by module)
|
|
122
122
|
|
|
123
|
+
### Global Secondary Index (GSI2)
|
|
124
|
+
- **GSI2PK**: `FEATURES` (for listing all features)
|
|
125
|
+
- **GSI2SK**: `FEATURE#{featureId}` (for direct feature lookup by ID)
|
|
126
|
+
|
|
123
127
|
### Data Structure
|
|
124
128
|
```json
|
|
125
129
|
{
|
|
@@ -188,6 +192,19 @@ const feature = await dynamoClient.getItem({
|
|
|
188
192
|
})
|
|
189
193
|
```
|
|
190
194
|
|
|
195
|
+
### Get Feature by ID (GSI2)
|
|
196
|
+
```javascript
|
|
197
|
+
// Query GSI2 with featureId
|
|
198
|
+
const feature = await dynamoClient.query({
|
|
199
|
+
IndexName: 'GSI2',
|
|
200
|
+
KeyConditionExpression: 'GSI2PK = :pk AND GSI2SK = :sk',
|
|
201
|
+
ExpressionAttributeValues: {
|
|
202
|
+
':pk': 'FEATURES',
|
|
203
|
+
':sk': `FEATURE#${featureId}`
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
```
|
|
207
|
+
|
|
191
208
|
## ⚙️ Configuration Options
|
|
192
209
|
|
|
193
210
|
| Option | Type | Default | Description |
|
|
@@ -262,15 +279,15 @@ Example output:
|
|
|
262
279
|
|
|
263
280
|
### TypeScript/ES6 Imports
|
|
264
281
|
```typescript
|
|
265
|
-
// In your handlers
|
|
266
|
-
import {
|
|
267
|
-
listAllModules,
|
|
268
|
-
getModuleFeatures,
|
|
282
|
+
// In your handlers - import from the generated service package
|
|
283
|
+
import {
|
|
284
|
+
listAllModules,
|
|
285
|
+
getModuleFeatures,
|
|
269
286
|
getFeatureDetails,
|
|
270
287
|
createModuleRegistryLogger,
|
|
271
288
|
type ModuleInfo,
|
|
272
289
|
type FeatureInfo
|
|
273
|
-
} from '
|
|
290
|
+
} from 'module-registry'
|
|
274
291
|
|
|
275
292
|
const logger = createModuleRegistryLogger('my-handler')
|
|
276
293
|
|
|
@@ -279,16 +296,28 @@ export const myHandler = async (event: any) => {
|
|
|
279
296
|
logger.info(`Found ${modules.length} modules`)
|
|
280
297
|
return { modules }
|
|
281
298
|
}
|
|
299
|
+
|
|
300
|
+
// Example: Get feature by ID without knowing module
|
|
301
|
+
export const getFeatureHandler = async (event: any) => {
|
|
302
|
+
const { featureId } = event.pathParameters
|
|
303
|
+
const feature = await getFeatureById(featureId)
|
|
304
|
+
|
|
305
|
+
if (!feature) {
|
|
306
|
+
return { statusCode: 404, body: { error: 'Feature not found' } }
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return { statusCode: 200, body: feature }
|
|
310
|
+
}
|
|
282
311
|
```
|
|
283
312
|
|
|
284
313
|
### CommonJS/Node.js Require
|
|
285
314
|
```javascript
|
|
286
|
-
// In your handlers
|
|
287
|
-
const {
|
|
288
|
-
listAllModules,
|
|
289
|
-
getModuleFeatures,
|
|
290
|
-
createModuleRegistryLogger
|
|
291
|
-
} = require('
|
|
315
|
+
// In your handlers - require from the generated service package
|
|
316
|
+
const {
|
|
317
|
+
listAllModules,
|
|
318
|
+
getModuleFeatures,
|
|
319
|
+
createModuleRegistryLogger
|
|
320
|
+
} = require('module-registry')
|
|
292
321
|
|
|
293
322
|
const logger = createModuleRegistryLogger('my-handler')
|
|
294
323
|
|
|
@@ -306,6 +335,7 @@ exports.myHandler = async (event) => {
|
|
|
306
335
|
| `listAllModules()` | List all deployed modules | `Promise<ModuleInfo[]>` |
|
|
307
336
|
| `getModuleFeatures(moduleName)` | Get features for a module | `Promise<FeatureInfo[]>` |
|
|
308
337
|
| `getFeatureDetails(moduleName, featureName)` | Get feature details | `Promise<FeatureDetails \| null>` |
|
|
338
|
+
| `getFeatureById(featureId)` | Get feature by ID only (uses GSI2) | `Promise<FeatureDetails \| null>` |
|
|
309
339
|
| `getModuleMetadata(moduleName)` | Get module metadata only | `Promise<ModuleInfo \| null>` |
|
|
310
340
|
| `getAllEndpoints()` | Get all endpoints across modules | `Promise<EndpointInfo[]>` |
|
|
311
341
|
| `createModuleRegistryLogger(context)` | Create logger for service functions | `Logger` |
|
|
@@ -351,6 +381,222 @@ export const listModules = http(async (event) => {
|
|
|
351
381
|
})
|
|
352
382
|
```
|
|
353
383
|
|
|
384
|
+
## 🚀 CLI Commands
|
|
385
|
+
|
|
386
|
+
The plugin provides powerful CLI commands for managing module registries:
|
|
387
|
+
|
|
388
|
+
### Generate Registry with AI (`registryGenerate`)
|
|
389
|
+
|
|
390
|
+
Automatically generate registry files for a module using AI analysis:
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# Generate registry for a specific module
|
|
394
|
+
serverless registryGenerate --module workforce
|
|
395
|
+
|
|
396
|
+
# Force overwrite existing registry files
|
|
397
|
+
serverless registryGenerate --module workforce --force
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Prerequisites:**
|
|
401
|
+
- Set `OPENROUTER_API_KEY` environment variable for AI generation
|
|
402
|
+
- Module must have function descriptions in serverless function definitions
|
|
403
|
+
- Only functions with `aws_iam` authorizer are included in registry
|
|
404
|
+
|
|
405
|
+
**What it does:**
|
|
406
|
+
1. Analyzes module structure (functions, resources, endpoints)
|
|
407
|
+
2. Uses AI (Claude 3.5 Sonnet) to generate AWS-style feature groupings
|
|
408
|
+
3. Creates `registry/module.yml` and `registry/features/*.yml` files
|
|
409
|
+
4. Follows AWS IAM naming conventions (e.g., `EmployeeReadAccess`, `UserSelfService`)
|
|
410
|
+
|
|
411
|
+
### Generate Service Package (`registryGeneratePackage`)
|
|
412
|
+
|
|
413
|
+
Generate the virtual service package for importing registry functions:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
# Generate service package
|
|
417
|
+
serverless registryGeneratePackage
|
|
418
|
+
|
|
419
|
+
# Force regeneration
|
|
420
|
+
serverless registryGeneratePackage --force --verbose
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
**What it creates:**
|
|
424
|
+
- `node_modules/module-registry/service.js` - Service functions
|
|
425
|
+
- `node_modules/module-registry/service.d.ts` - TypeScript definitions
|
|
426
|
+
- `node_modules/module-registry/env.js` - Environment configuration
|
|
427
|
+
- `node_modules/module-registry/package.json` - Package manifest
|
|
428
|
+
|
|
429
|
+
## 🛠️ Development
|
|
430
|
+
|
|
431
|
+
### Prerequisites
|
|
432
|
+
|
|
433
|
+
- Node.js ≥14.0.0
|
|
434
|
+
- TypeScript ≥5.0
|
|
435
|
+
- Serverless Framework ≥2.0.0
|
|
436
|
+
|
|
437
|
+
### Setup
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
# Install dependencies
|
|
441
|
+
npm install
|
|
442
|
+
|
|
443
|
+
# Build the plugin
|
|
444
|
+
npm run build
|
|
445
|
+
|
|
446
|
+
# Watch for changes during development
|
|
447
|
+
npm run watch
|
|
448
|
+
|
|
449
|
+
# Run type checking
|
|
450
|
+
npm run typecheck
|
|
451
|
+
|
|
452
|
+
# Run linting
|
|
453
|
+
npm run lint
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Build Configuration
|
|
457
|
+
|
|
458
|
+
The project uses [tsup](https://tsup.egoist.dev/) for building:
|
|
459
|
+
|
|
460
|
+
- **Entry**: `src/index.ts` (main plugin), `src/service.ts` (service functions)
|
|
461
|
+
- **Output**: `dist/` directory with CommonJS and TypeScript definitions
|
|
462
|
+
- **Target**: Node.js 14+ compatibility
|
|
463
|
+
- **External**: Serverless Framework excluded from bundle
|
|
464
|
+
|
|
465
|
+
### Testing
|
|
466
|
+
|
|
467
|
+
Tests are currently disabled but the framework is set up with Jest:
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
# Tests are disabled - would run with:
|
|
471
|
+
npm test # Currently outputs: "Tests disabled"
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
## 🔧 Troubleshooting
|
|
475
|
+
|
|
476
|
+
### Common Issues
|
|
477
|
+
|
|
478
|
+
**Plugin not found**
|
|
479
|
+
```
|
|
480
|
+
Error: Plugin "serverless-plugin-module-registry" not found
|
|
481
|
+
```
|
|
482
|
+
Solution: Ensure plugin is installed and listed in `serverless.yml` plugins section
|
|
483
|
+
|
|
484
|
+
**Variable resolution errors**
|
|
485
|
+
```
|
|
486
|
+
Module Registry: Unresolved variables in configuration
|
|
487
|
+
```
|
|
488
|
+
Solution: Check that all variables in `custom.moduleRegistry` section can be resolved
|
|
489
|
+
|
|
490
|
+
**DynamoDB table creation fails**
|
|
491
|
+
```
|
|
492
|
+
Failed to create table: AccessDenied
|
|
493
|
+
```
|
|
494
|
+
Solution: Ensure AWS credentials have DynamoDB permissions:
|
|
495
|
+
- `dynamodb:CreateTable`
|
|
496
|
+
- `dynamodb:DescribeTable`
|
|
497
|
+
- `dynamodb:UpdateContinuousBackups`
|
|
498
|
+
- `dynamodb:TagResource`
|
|
499
|
+
|
|
500
|
+
**AI generation fails**
|
|
501
|
+
```
|
|
502
|
+
OPENROUTER_API_KEY environment variable is required
|
|
503
|
+
```
|
|
504
|
+
Solution: Set OpenRouter API key: `export OPENROUTER_API_KEY=your_key_here`
|
|
505
|
+
|
|
506
|
+
**Registry generation requires function descriptions**
|
|
507
|
+
```
|
|
508
|
+
Function 'myFunction' is missing required 'description' field
|
|
509
|
+
```
|
|
510
|
+
Solution: Add descriptions to all functions in your serverless function definitions
|
|
511
|
+
|
|
512
|
+
### Debug Mode
|
|
513
|
+
|
|
514
|
+
Enable detailed logging:
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
serverless deploy --verbose
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Look for `[module-registry]` prefixed logs for plugin-specific information.
|
|
521
|
+
|
|
522
|
+
## 📊 Performance Considerations
|
|
523
|
+
|
|
524
|
+
### DynamoDB Costs
|
|
525
|
+
|
|
526
|
+
- Plugin creates one table per service/stage combination
|
|
527
|
+
- Uses **Pay-Per-Request** billing mode
|
|
528
|
+
- Table persists across deployments (not recreated)
|
|
529
|
+
- Point-in-time recovery enabled by default
|
|
530
|
+
|
|
531
|
+
### Batch Operations
|
|
532
|
+
|
|
533
|
+
- Registry updates use batch writes (25 items per batch)
|
|
534
|
+
- Automatic cleanup of stale entries during deployment
|
|
535
|
+
- Optimized for sparse access patterns
|
|
536
|
+
|
|
537
|
+
### CloudFormation Policies
|
|
538
|
+
|
|
539
|
+
- IAM policies generated as CloudFormation resources
|
|
540
|
+
- Policy ARNs resolved at deployment time
|
|
541
|
+
- No runtime AWS API calls for policy management
|
|
542
|
+
|
|
543
|
+
## 🔒 Security Considerations
|
|
544
|
+
|
|
545
|
+
### IAM Policies
|
|
546
|
+
|
|
547
|
+
- Generated policies follow **least privilege** principle
|
|
548
|
+
- Endpoint-specific resource ARNs (not wildcards)
|
|
549
|
+
- Custom policies allow fine-grained permission control
|
|
550
|
+
|
|
551
|
+
### Access Control
|
|
552
|
+
|
|
553
|
+
- Registry table access requires DynamoDB permissions
|
|
554
|
+
- Cross-module access controlled via IAM policy ARNs
|
|
555
|
+
- Service functions inherit Lambda execution role permissions
|
|
556
|
+
|
|
557
|
+
### Best Practices
|
|
558
|
+
|
|
559
|
+
1. **Review generated policies** before deployment
|
|
560
|
+
2. **Use strict mode** (`strict: true`) in production
|
|
561
|
+
3. **Regularly audit** endpoint permissions
|
|
562
|
+
4. **Implement proper** IAM role boundaries
|
|
563
|
+
|
|
564
|
+
## 🤝 Contributing
|
|
565
|
+
|
|
566
|
+
### Development Workflow
|
|
567
|
+
|
|
568
|
+
1. Fork the repository
|
|
569
|
+
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
570
|
+
3. Make changes and test thoroughly
|
|
571
|
+
4. Update documentation if needed
|
|
572
|
+
5. Submit a pull request
|
|
573
|
+
|
|
574
|
+
### Code Standards
|
|
575
|
+
|
|
576
|
+
- Follow TypeScript best practices
|
|
577
|
+
- Use provided ESLint configuration
|
|
578
|
+
- Add JSDoc comments for public APIs
|
|
579
|
+
- Maintain backward compatibility
|
|
580
|
+
|
|
581
|
+
### Testing
|
|
582
|
+
|
|
583
|
+
When contributing:
|
|
584
|
+
- Add test cases for new features
|
|
585
|
+
- Ensure existing functionality isn't broken
|
|
586
|
+
- Test with multiple Serverless Framework versions
|
|
587
|
+
|
|
588
|
+
## 📋 Version Compatibility
|
|
589
|
+
|
|
590
|
+
| Plugin Version | Serverless Framework | Node.js |
|
|
591
|
+
|----------------|---------------------|---------|
|
|
592
|
+
| 1.0.x | 2.x, 3.x, 4.x | ≥14.0 |
|
|
593
|
+
|
|
594
|
+
### Serverless Framework Features
|
|
595
|
+
|
|
596
|
+
- **v2**: Basic hook support, CloudFormation resources
|
|
597
|
+
- **v3**: Enhanced variable resolution, improved logging
|
|
598
|
+
- **v4**: Full ESM support, performance optimizations
|
|
599
|
+
|
|
354
600
|
## 📄 License
|
|
355
601
|
|
|
356
602
|
MIT License - see the [LICENSE](LICENSE) file for details.
|