@skillsmith/mcp-server 0.3.0 → 0.3.1
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 +1 -1
- package/dist/.tsbuildinfo +0 -1
- package/dist/src/__tests__/get-skill.test.d.ts +0 -6
- package/dist/src/__tests__/get-skill.test.d.ts.map +0 -1
- package/dist/src/__tests__/get-skill.test.js +0 -88
- package/dist/src/__tests__/get-skill.test.js.map +0 -1
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts +0 -7
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts.map +0 -1
- package/dist/src/__tests__/middleware/errorFormatter.test.js +0 -304
- package/dist/src/__tests__/middleware/errorFormatter.test.js.map +0 -1
- package/dist/src/__tests__/middleware/license.test.d.ts +0 -7
- package/dist/src/__tests__/middleware/license.test.d.ts.map +0 -1
- package/dist/src/__tests__/middleware/license.test.js +0 -500
- package/dist/src/__tests__/middleware/license.test.js.map +0 -1
- package/dist/src/__tests__/search.test.d.ts +0 -6
- package/dist/src/__tests__/search.test.d.ts.map +0 -1
- package/dist/src/__tests__/search.test.js +0 -86
- package/dist/src/__tests__/search.test.js.map +0 -1
- package/dist/src/__tests__/test-utils.d.ts +0 -20
- package/dist/src/__tests__/test-utils.d.ts.map +0 -1
- package/dist/src/__tests__/test-utils.js +0 -91
- package/dist/src/__tests__/test-utils.js.map +0 -1
- package/dist/src/context/index.d.ts +0 -19
- package/dist/src/context/index.d.ts.map +0 -1
- package/dist/src/context/index.js +0 -25
- package/dist/src/context/index.js.map +0 -1
- package/dist/src/context/project-detector.d.ts +0 -145
- package/dist/src/context/project-detector.d.ts.map +0 -1
- package/dist/src/context/project-detector.js +0 -321
- package/dist/src/context/project-detector.js.map +0 -1
- package/dist/src/context.d.ts +0 -157
- package/dist/src/context.d.ts.map +0 -1
- package/dist/src/context.js +0 -231
- package/dist/src/context.js.map +0 -1
- package/dist/src/core-shim.d.ts +0 -7
- package/dist/src/core-shim.d.ts.map +0 -1
- package/dist/src/core-shim.js +0 -9
- package/dist/src/core-shim.js.map +0 -1
- package/dist/src/health/healthCheck.d.ts +0 -88
- package/dist/src/health/healthCheck.d.ts.map +0 -1
- package/dist/src/health/healthCheck.js +0 -117
- package/dist/src/health/healthCheck.js.map +0 -1
- package/dist/src/health/index.d.ts +0 -21
- package/dist/src/health/index.d.ts.map +0 -1
- package/dist/src/health/index.js +0 -21
- package/dist/src/health/index.js.map +0 -1
- package/dist/src/health/readinessCheck.d.ts +0 -139
- package/dist/src/health/readinessCheck.d.ts.map +0 -1
- package/dist/src/health/readinessCheck.js +0 -266
- package/dist/src/health/readinessCheck.js.map +0 -1
- package/dist/src/index.d.ts +0 -9
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -236
- package/dist/src/index.js.map +0 -1
- package/dist/src/index.test.d.ts +0 -2
- package/dist/src/index.test.d.ts.map +0 -1
- package/dist/src/index.test.js +0 -43
- package/dist/src/index.test.js.map +0 -1
- package/dist/src/logger.d.ts +0 -26
- package/dist/src/logger.d.ts.map +0 -1
- package/dist/src/logger.js +0 -179
- package/dist/src/logger.js.map +0 -1
- package/dist/src/middleware/__tests__/csp.test.d.ts +0 -2
- package/dist/src/middleware/__tests__/csp.test.d.ts.map +0 -1
- package/dist/src/middleware/__tests__/csp.test.js +0 -390
- package/dist/src/middleware/__tests__/csp.test.js.map +0 -1
- package/dist/src/middleware/csp.d.ts +0 -103
- package/dist/src/middleware/csp.d.ts.map +0 -1
- package/dist/src/middleware/csp.js +0 -273
- package/dist/src/middleware/csp.js.map +0 -1
- package/dist/src/middleware/degradation.d.ts +0 -105
- package/dist/src/middleware/degradation.d.ts.map +0 -1
- package/dist/src/middleware/degradation.js +0 -319
- package/dist/src/middleware/degradation.js.map +0 -1
- package/dist/src/middleware/errorFormatter.d.ts +0 -119
- package/dist/src/middleware/errorFormatter.d.ts.map +0 -1
- package/dist/src/middleware/errorFormatter.js +0 -294
- package/dist/src/middleware/errorFormatter.js.map +0 -1
- package/dist/src/middleware/index.d.ts +0 -11
- package/dist/src/middleware/index.d.ts.map +0 -1
- package/dist/src/middleware/index.js +0 -16
- package/dist/src/middleware/index.js.map +0 -1
- package/dist/src/middleware/license.d.ts +0 -169
- package/dist/src/middleware/license.d.ts.map +0 -1
- package/dist/src/middleware/license.js +0 -292
- package/dist/src/middleware/license.js.map +0 -1
- package/dist/src/middleware/quota.d.ts +0 -182
- package/dist/src/middleware/quota.d.ts.map +0 -1
- package/dist/src/middleware/quota.js +0 -309
- package/dist/src/middleware/quota.js.map +0 -1
- package/dist/src/middleware/toolFeatureMapping.d.ts +0 -36
- package/dist/src/middleware/toolFeatureMapping.d.ts.map +0 -1
- package/dist/src/middleware/toolFeatureMapping.js +0 -96
- package/dist/src/middleware/toolFeatureMapping.js.map +0 -1
- package/dist/src/onboarding/first-run.d.ts +0 -65
- package/dist/src/onboarding/first-run.d.ts.map +0 -1
- package/dist/src/onboarding/first-run.js +0 -79
- package/dist/src/onboarding/first-run.js.map +0 -1
- package/dist/src/onboarding/index.d.ts +0 -7
- package/dist/src/onboarding/index.d.ts.map +0 -1
- package/dist/src/onboarding/index.js +0 -7
- package/dist/src/onboarding/index.js.map +0 -1
- package/dist/src/onboarding/install-assets.d.ts +0 -27
- package/dist/src/onboarding/install-assets.d.ts.map +0 -1
- package/dist/src/onboarding/install-assets.js +0 -128
- package/dist/src/onboarding/install-assets.js.map +0 -1
- package/dist/src/suggestions/index.d.ts +0 -21
- package/dist/src/suggestions/index.d.ts.map +0 -1
- package/dist/src/suggestions/index.js +0 -20
- package/dist/src/suggestions/index.js.map +0 -1
- package/dist/src/suggestions/suggestion-engine.d.ts +0 -185
- package/dist/src/suggestions/suggestion-engine.d.ts.map +0 -1
- package/dist/src/suggestions/suggestion-engine.js +0 -352
- package/dist/src/suggestions/suggestion-engine.js.map +0 -1
- package/dist/src/suggestions/types.d.ts +0 -88
- package/dist/src/suggestions/types.d.ts.map +0 -1
- package/dist/src/suggestions/types.js +0 -21
- package/dist/src/suggestions/types.js.map +0 -1
- package/dist/src/tools/analyze.d.ts +0 -151
- package/dist/src/tools/analyze.d.ts.map +0 -1
- package/dist/src/tools/analyze.js +0 -205
- package/dist/src/tools/analyze.js.map +0 -1
- package/dist/src/tools/compare.d.ts +0 -149
- package/dist/src/tools/compare.d.ts.map +0 -1
- package/dist/src/tools/compare.js +0 -464
- package/dist/src/tools/compare.js.map +0 -1
- package/dist/src/tools/get-skill.d.ts +0 -107
- package/dist/src/tools/get-skill.d.ts.map +0 -1
- package/dist/src/tools/get-skill.js +0 -260
- package/dist/src/tools/get-skill.js.map +0 -1
- package/dist/src/tools/index.d.ts +0 -20
- package/dist/src/tools/index.d.ts.map +0 -1
- package/dist/src/tools/index.js +0 -20
- package/dist/src/tools/index.js.map +0 -1
- package/dist/src/tools/install.d.ts +0 -122
- package/dist/src/tools/install.d.ts.map +0 -1
- package/dist/src/tools/install.js +0 -326
- package/dist/src/tools/install.js.map +0 -1
- package/dist/src/tools/recommend.d.ts +0 -169
- package/dist/src/tools/recommend.d.ts.map +0 -1
- package/dist/src/tools/recommend.js +0 -357
- package/dist/src/tools/recommend.js.map +0 -1
- package/dist/src/tools/search.d.ts +0 -114
- package/dist/src/tools/search.d.ts.map +0 -1
- package/dist/src/tools/search.js +0 -247
- package/dist/src/tools/search.js.map +0 -1
- package/dist/src/tools/suggest.d.ts +0 -181
- package/dist/src/tools/suggest.d.ts.map +0 -1
- package/dist/src/tools/suggest.js +0 -310
- package/dist/src/tools/suggest.js.map +0 -1
- package/dist/src/tools/uninstall.d.ts +0 -123
- package/dist/src/tools/uninstall.d.ts.map +0 -1
- package/dist/src/tools/uninstall.js +0 -250
- package/dist/src/tools/uninstall.js.map +0 -1
- package/dist/src/tools/validate.d.ts +0 -122
- package/dist/src/tools/validate.d.ts.map +0 -1
- package/dist/src/tools/validate.js +0 -497
- package/dist/src/tools/validate.js.map +0 -1
- package/dist/src/utils/installed-skills.d.ts +0 -101
- package/dist/src/utils/installed-skills.d.ts.map +0 -1
- package/dist/src/utils/installed-skills.js +0 -220
- package/dist/src/utils/installed-skills.js.map +0 -1
- package/dist/src/utils/validation.d.ts +0 -95
- package/dist/src/utils/validation.d.ts.map +0 -1
- package/dist/src/utils/validation.js +0 -186
- package/dist/src/utils/validation.js.map +0 -1
- package/dist/src/webhooks/index.d.ts +0 -8
- package/dist/src/webhooks/index.d.ts.map +0 -1
- package/dist/src/webhooks/index.js +0 -9
- package/dist/src/webhooks/index.js.map +0 -1
- package/dist/src/webhooks/webhook-endpoint.d.ts +0 -149
- package/dist/src/webhooks/webhook-endpoint.d.ts.map +0 -1
- package/dist/src/webhooks/webhook-endpoint.js +0 -339
- package/dist/src/webhooks/webhook-endpoint.js.map +0 -1
- package/dist/tests/compare.test.d.ts +0 -6
- package/dist/tests/compare.test.d.ts.map +0 -1
- package/dist/tests/compare.test.js +0 -225
- package/dist/tests/compare.test.js.map +0 -1
- package/dist/tests/context/project-detector.test.d.ts +0 -6
- package/dist/tests/context/project-detector.test.d.ts.map +0 -1
- package/dist/tests/context/project-detector.test.js +0 -719
- package/dist/tests/context/project-detector.test.js.map +0 -1
- package/dist/tests/e2e/compare.e2e.test.d.ts +0 -10
- package/dist/tests/e2e/compare.e2e.test.d.ts.map +0 -1
- package/dist/tests/e2e/compare.e2e.test.js +0 -296
- package/dist/tests/e2e/compare.e2e.test.js.map +0 -1
- package/dist/tests/e2e/install-flow.e2e.test.d.ts +0 -10
- package/dist/tests/e2e/install-flow.e2e.test.d.ts.map +0 -1
- package/dist/tests/e2e/install-flow.e2e.test.js +0 -229
- package/dist/tests/e2e/install-flow.e2e.test.js.map +0 -1
- package/dist/tests/e2e/recommend.e2e.test.d.ts +0 -12
- package/dist/tests/e2e/recommend.e2e.test.d.ts.map +0 -1
- package/dist/tests/e2e/recommend.e2e.test.js +0 -357
- package/dist/tests/e2e/recommend.e2e.test.js.map +0 -1
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts +0 -10
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts.map +0 -1
- package/dist/tests/e2e/skill-flow.e2e.test.js +0 -311
- package/dist/tests/e2e/skill-flow.e2e.test.js.map +0 -1
- package/dist/tests/e2e/suggest.e2e.test.d.ts +0 -13
- package/dist/tests/e2e/suggest.e2e.test.d.ts.map +0 -1
- package/dist/tests/e2e/suggest.e2e.test.js +0 -367
- package/dist/tests/e2e/suggest.e2e.test.js.map +0 -1
- package/dist/tests/e2e/utils/baseline-collector.d.ts +0 -107
- package/dist/tests/e2e/utils/baseline-collector.d.ts.map +0 -1
- package/dist/tests/e2e/utils/baseline-collector.js +0 -211
- package/dist/tests/e2e/utils/baseline-collector.js.map +0 -1
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts +0 -46
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +0 -1
- package/dist/tests/e2e/utils/hardcoded-detector.js +0 -255
- package/dist/tests/e2e/utils/hardcoded-detector.js.map +0 -1
- package/dist/tests/e2e/utils/index.d.ts +0 -7
- package/dist/tests/e2e/utils/index.d.ts.map +0 -1
- package/dist/tests/e2e/utils/index.js +0 -7
- package/dist/tests/e2e/utils/index.js.map +0 -1
- package/dist/tests/e2e/utils/linear-reporter.d.ts +0 -60
- package/dist/tests/e2e/utils/linear-reporter.d.ts.map +0 -1
- package/dist/tests/e2e/utils/linear-reporter.js +0 -232
- package/dist/tests/e2e/utils/linear-reporter.js.map +0 -1
- package/dist/tests/health.test.d.ts +0 -9
- package/dist/tests/health.test.d.ts.map +0 -1
- package/dist/tests/health.test.js +0 -308
- package/dist/tests/health.test.js.map +0 -1
- package/dist/tests/integration/analyze.integration.test.d.ts +0 -2
- package/dist/tests/integration/analyze.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/analyze.integration.test.js +0 -244
- package/dist/tests/integration/analyze.integration.test.js.map +0 -1
- package/dist/tests/integration/compare.integration.test.d.ts +0 -2
- package/dist/tests/integration/compare.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/compare.integration.test.js +0 -120
- package/dist/tests/integration/compare.integration.test.js.map +0 -1
- package/dist/tests/integration/fixtures/test-skills.d.ts +0 -62
- package/dist/tests/integration/fixtures/test-skills.d.ts.map +0 -1
- package/dist/tests/integration/fixtures/test-skills.js +0 -644
- package/dist/tests/integration/fixtures/test-skills.js.map +0 -1
- package/dist/tests/integration/get-skill.integration.test.d.ts +0 -6
- package/dist/tests/integration/get-skill.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/get-skill.integration.test.js +0 -203
- package/dist/tests/integration/get-skill.integration.test.js.map +0 -1
- package/dist/tests/integration/github-api.integration.test.d.ts +0 -14
- package/dist/tests/integration/github-api.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/github-api.integration.test.js +0 -190
- package/dist/tests/integration/github-api.integration.test.js.map +0 -1
- package/dist/tests/integration/install.integration.test.d.ts +0 -6
- package/dist/tests/integration/install.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/install.integration.test.js +0 -282
- package/dist/tests/integration/install.integration.test.js.map +0 -1
- package/dist/tests/integration/recommend.integration.test.d.ts +0 -2
- package/dist/tests/integration/recommend.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/recommend.integration.test.js +0 -217
- package/dist/tests/integration/recommend.integration.test.js.map +0 -1
- package/dist/tests/integration/search.integration.test.d.ts +0 -6
- package/dist/tests/integration/search.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/search.integration.test.js +0 -229
- package/dist/tests/integration/search.integration.test.js.map +0 -1
- package/dist/tests/integration/setup.d.ts +0 -74
- package/dist/tests/integration/setup.d.ts.map +0 -1
- package/dist/tests/integration/setup.js +0 -131
- package/dist/tests/integration/setup.js.map +0 -1
- package/dist/tests/integration/uninstall.integration.test.d.ts +0 -6
- package/dist/tests/integration/uninstall.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/uninstall.integration.test.js +0 -296
- package/dist/tests/integration/uninstall.integration.test.js.map +0 -1
- package/dist/tests/integration/validate.integration.test.d.ts +0 -2
- package/dist/tests/integration/validate.integration.test.d.ts.map +0 -1
- package/dist/tests/integration/validate.integration.test.js +0 -181
- package/dist/tests/integration/validate.integration.test.js.map +0 -1
- package/dist/tests/onboarding/first-run.test.d.ts +0 -7
- package/dist/tests/onboarding/first-run.test.d.ts.map +0 -1
- package/dist/tests/onboarding/first-run.test.js +0 -264
- package/dist/tests/onboarding/first-run.test.js.map +0 -1
- package/dist/tests/performance/search-performance.test.d.ts +0 -10
- package/dist/tests/performance/search-performance.test.d.ts.map +0 -1
- package/dist/tests/performance/search-performance.test.js +0 -222
- package/dist/tests/performance/search-performance.test.js.map +0 -1
- package/dist/tests/recommend.test.d.ts +0 -6
- package/dist/tests/recommend.test.d.ts.map +0 -1
- package/dist/tests/recommend.test.js +0 -210
- package/dist/tests/recommend.test.js.map +0 -1
- package/dist/tests/suggestions/suggestion-engine.test.d.ts +0 -6
- package/dist/tests/suggestions/suggestion-engine.test.d.ts.map +0 -1
- package/dist/tests/suggestions/suggestion-engine.test.js +0 -448
- package/dist/tests/suggestions/suggestion-engine.test.js.map +0 -1
- package/dist/tests/test-utils.d.ts +0 -74
- package/dist/tests/test-utils.d.ts.map +0 -1
- package/dist/tests/test-utils.js +0 -98
- package/dist/tests/test-utils.js.map +0 -1
- package/dist/tests/tools.test.d.ts +0 -5
- package/dist/tests/tools.test.d.ts.map +0 -1
- package/dist/tests/tools.test.js +0 -138
- package/dist/tests/tools.test.js.map +0 -1
- package/dist/tests/unit/installed-skills.test.d.ts +0 -6
- package/dist/tests/unit/installed-skills.test.d.ts.map +0 -1
- package/dist/tests/unit/installed-skills.test.js +0 -285
- package/dist/tests/unit/installed-skills.test.js.map +0 -1
- package/dist/tests/unit/logger.test.d.ts +0 -6
- package/dist/tests/unit/logger.test.d.ts.map +0 -1
- package/dist/tests/unit/logger.test.js +0 -281
- package/dist/tests/unit/logger.test.js.map +0 -1
- package/dist/tests/validate.test.d.ts +0 -5
- package/dist/tests/validate.test.d.ts.map +0 -1
- package/dist/tests/validate.test.js +0 -303
- package/dist/tests/validate.test.js.map +0 -1
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts +0 -8
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts.map +0 -1
- package/dist/tests/webhooks/proxy-trust.security.test.js +0 -145
- package/dist/tests/webhooks/proxy-trust.security.test.js.map +0 -1
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts +0 -8
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts.map +0 -1
- package/dist/tests/webhooks/rate-limiter.security.test.js +0 -122
- package/dist/tests/webhooks/rate-limiter.security.test.js.map +0 -1
- package/dist/vitest.config.d.ts +0 -6
- package/dist/vitest.config.d.ts.map +0 -1
- package/dist/vitest.config.js +0 -13
- package/dist/vitest.config.js.map +0 -1
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* License validation middleware for MCP server
|
|
3
|
-
*
|
|
4
|
-
* Validates that the user has the required license features for enterprise tools.
|
|
5
|
-
* Gracefully degrades if @skillsmith/enterprise is not installed.
|
|
6
|
-
*
|
|
7
|
-
* @see SMI-1055: Add license middleware to MCP server
|
|
8
|
-
*/
|
|
9
|
-
import { TOOL_FEATURES, FEATURE_DISPLAY_NAMES, FEATURE_TIERS, } from './toolFeatureMapping.js';
|
|
10
|
-
/**
|
|
11
|
-
* Configuration for the upgrade URL
|
|
12
|
-
*/
|
|
13
|
-
const UPGRADE_URL = 'https://skillsmith.app/pricing';
|
|
14
|
-
/**
|
|
15
|
-
* Type guard to validate enterprise module structure
|
|
16
|
-
*/
|
|
17
|
-
function isEnterpriseModule(mod) {
|
|
18
|
-
return (typeof mod === 'object' &&
|
|
19
|
-
mod !== null &&
|
|
20
|
-
'LicenseValidator' in mod &&
|
|
21
|
-
typeof mod['LicenseValidator'] === 'function');
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Attempt to load the enterprise license validator
|
|
25
|
-
* Returns null if the package is not installed
|
|
26
|
-
*/
|
|
27
|
-
async function tryLoadEnterpriseValidator() {
|
|
28
|
-
try {
|
|
29
|
-
// Dynamic import with variable to prevent TypeScript from resolving at compile time
|
|
30
|
-
// This is an optional peer dependency that may not be installed
|
|
31
|
-
const packageName = '@skillsmith/enterprise';
|
|
32
|
-
const enterprise = await import(/* webpackIgnore: true */ packageName);
|
|
33
|
-
if (isEnterpriseModule(enterprise)) {
|
|
34
|
-
return new enterprise.LicenseValidator();
|
|
35
|
-
}
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// Enterprise package not installed - this is expected for community users
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Check if a tool name corresponds to an enterprise feature
|
|
45
|
-
*
|
|
46
|
-
* @param toolName - The name of the MCP tool
|
|
47
|
-
* @returns true if the tool requires an enterprise license
|
|
48
|
-
*/
|
|
49
|
-
export function isEnterpriseFeature(toolName) {
|
|
50
|
-
const feature = TOOL_FEATURES[toolName];
|
|
51
|
-
if (feature == null) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
return FEATURE_TIERS[feature] === 'enterprise';
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Check if a tool name requires any license (team or enterprise)
|
|
58
|
-
*
|
|
59
|
-
* @param toolName - The name of the MCP tool
|
|
60
|
-
* @returns true if the tool requires any license
|
|
61
|
-
*/
|
|
62
|
-
export function requiresLicense(toolName) {
|
|
63
|
-
return TOOL_FEATURES[toolName] !== null && TOOL_FEATURES[toolName] !== undefined;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get the required feature for a tool
|
|
67
|
-
*
|
|
68
|
-
* @param toolName - The name of the MCP tool
|
|
69
|
-
* @returns The feature flag required, or null if community tool
|
|
70
|
-
*/
|
|
71
|
-
export function getRequiredFeature(toolName) {
|
|
72
|
-
return TOOL_FEATURES[toolName] ?? null;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Check if license is expiring soon (within 30 days)
|
|
76
|
-
*/
|
|
77
|
-
function getExpirationWarning(expiresAt) {
|
|
78
|
-
if (!expiresAt)
|
|
79
|
-
return undefined;
|
|
80
|
-
const daysUntilExpiry = Math.floor((expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
|
|
81
|
-
if (daysUntilExpiry <= 30 && daysUntilExpiry > 0) {
|
|
82
|
-
return `Your license expires in ${daysUntilExpiry} day${daysUntilExpiry === 1 ? '' : 's'}. Please renew to avoid service interruption.`;
|
|
83
|
-
}
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Create a license middleware factory
|
|
88
|
-
*
|
|
89
|
-
* This middleware reads the license key from environment variables and
|
|
90
|
-
* validates tool access based on the license features.
|
|
91
|
-
*
|
|
92
|
-
* @param options - Optional configuration
|
|
93
|
-
* @returns License middleware instance
|
|
94
|
-
*/
|
|
95
|
-
export function createLicenseMiddleware(options) {
|
|
96
|
-
const envVar = options?.licenseKeyEnvVar ?? 'SKILLSMITH_LICENSE_KEY';
|
|
97
|
-
const cacheTtl = options?.cacheTtlMs ?? 5 * 60 * 1000; // 5 minutes default
|
|
98
|
-
const context = {
|
|
99
|
-
validator: null,
|
|
100
|
-
licenseKey: process.env[envVar],
|
|
101
|
-
cachedLicense: null,
|
|
102
|
-
cacheExpiry: 0,
|
|
103
|
-
};
|
|
104
|
-
// Initialize validator lazily
|
|
105
|
-
let validatorPromise = null;
|
|
106
|
-
async function getValidator() {
|
|
107
|
-
if (!validatorPromise) {
|
|
108
|
-
validatorPromise = tryLoadEnterpriseValidator();
|
|
109
|
-
}
|
|
110
|
-
if (context.validator === null) {
|
|
111
|
-
context.validator = await validatorPromise;
|
|
112
|
-
}
|
|
113
|
-
return context.validator;
|
|
114
|
-
}
|
|
115
|
-
async function getLicenseInfo() {
|
|
116
|
-
// Check cache first
|
|
117
|
-
if (context.cachedLicense && Date.now() < context.cacheExpiry) {
|
|
118
|
-
return context.cachedLicense;
|
|
119
|
-
}
|
|
120
|
-
// No license key = community user
|
|
121
|
-
if (!context.licenseKey) {
|
|
122
|
-
const communityLicense = {
|
|
123
|
-
valid: true,
|
|
124
|
-
tier: 'community',
|
|
125
|
-
features: [],
|
|
126
|
-
};
|
|
127
|
-
context.cachedLicense = communityLicense;
|
|
128
|
-
context.cacheExpiry = Date.now() + cacheTtl;
|
|
129
|
-
return communityLicense;
|
|
130
|
-
}
|
|
131
|
-
// Try to validate with enterprise package
|
|
132
|
-
const validator = await getValidator();
|
|
133
|
-
if (!validator) {
|
|
134
|
-
// Enterprise package not installed but license key provided
|
|
135
|
-
// Security-conscious decision: Return null to indicate validation failure
|
|
136
|
-
// rather than silently degrading to community tier. This ensures paying
|
|
137
|
-
// customers get feedback that their license couldn't be validated.
|
|
138
|
-
// See SMI-1130 for rationale.
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
const result = await validator.validate(context.licenseKey);
|
|
143
|
-
// Check if validation was successful
|
|
144
|
-
if (!result.valid || !result.license) {
|
|
145
|
-
// Invalid license - return null to indicate validation failure
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
// Convert enterprise License to middleware LicenseInfo
|
|
149
|
-
const license = {
|
|
150
|
-
valid: true,
|
|
151
|
-
tier: result.license.tier,
|
|
152
|
-
features: result.license.features,
|
|
153
|
-
expiresAt: result.license.expiresAt,
|
|
154
|
-
organizationId: result.license.customerId,
|
|
155
|
-
};
|
|
156
|
-
context.cachedLicense = license;
|
|
157
|
-
context.cacheExpiry = Date.now() + cacheTtl;
|
|
158
|
-
return license;
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
// Validation threw an exception - treat as invalid license
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
async function checkFeature(feature) {
|
|
166
|
-
const license = await getLicenseInfo();
|
|
167
|
-
// No valid license
|
|
168
|
-
if (!license || !license.valid) {
|
|
169
|
-
const tier = FEATURE_TIERS[feature];
|
|
170
|
-
const displayName = FEATURE_DISPLAY_NAMES[feature];
|
|
171
|
-
return {
|
|
172
|
-
valid: false,
|
|
173
|
-
feature,
|
|
174
|
-
message: `The "${displayName}" feature requires a ${tier} license. Your license could not be validated.`,
|
|
175
|
-
upgradeUrl: `${UPGRADE_URL}?feature=${feature}`,
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
// Community tier - no paid features
|
|
179
|
-
if (license.tier === 'community') {
|
|
180
|
-
const tier = FEATURE_TIERS[feature];
|
|
181
|
-
const displayName = FEATURE_DISPLAY_NAMES[feature];
|
|
182
|
-
return {
|
|
183
|
-
valid: false,
|
|
184
|
-
feature,
|
|
185
|
-
message: `The "${displayName}" feature requires a ${tier} license. You are currently on the community tier.`,
|
|
186
|
-
upgradeUrl: `${UPGRADE_URL}?feature=${feature}¤t=community`,
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
// Individual tier - only individual features (basic_analytics, email_support)
|
|
190
|
-
const featureTier = FEATURE_TIERS[feature];
|
|
191
|
-
if (license.tier === 'individual' && (featureTier === 'team' || featureTier === 'enterprise')) {
|
|
192
|
-
const displayName = FEATURE_DISPLAY_NAMES[feature];
|
|
193
|
-
return {
|
|
194
|
-
valid: false,
|
|
195
|
-
feature,
|
|
196
|
-
message: `The "${displayName}" feature requires a ${featureTier} license. You are currently on the individual tier.`,
|
|
197
|
-
upgradeUrl: `${UPGRADE_URL}?feature=${feature}¤t=individual`,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
// Team tier - only team features (not enterprise)
|
|
201
|
-
if (license.tier === 'team' && featureTier === 'enterprise') {
|
|
202
|
-
const displayName = FEATURE_DISPLAY_NAMES[feature];
|
|
203
|
-
return {
|
|
204
|
-
valid: false,
|
|
205
|
-
feature,
|
|
206
|
-
message: `The "${displayName}" feature requires an enterprise license. You are currently on the team tier.`,
|
|
207
|
-
upgradeUrl: `${UPGRADE_URL}?feature=${feature}¤t=team`,
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
// Check if feature is in the license
|
|
211
|
-
if (!license.features.includes(feature)) {
|
|
212
|
-
const displayName = FEATURE_DISPLAY_NAMES[feature];
|
|
213
|
-
const tier = FEATURE_TIERS[feature];
|
|
214
|
-
return {
|
|
215
|
-
valid: false,
|
|
216
|
-
feature,
|
|
217
|
-
message: `The "${displayName}" feature is not included in your license. Please upgrade to access this ${tier} feature.`,
|
|
218
|
-
upgradeUrl: `${UPGRADE_URL}?feature=${feature}&upgrade=true`,
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
const warning = getExpirationWarning(license.expiresAt);
|
|
222
|
-
return { valid: true, warning };
|
|
223
|
-
}
|
|
224
|
-
async function checkTool(toolName) {
|
|
225
|
-
const requiredFeature = getRequiredFeature(toolName);
|
|
226
|
-
// Community tool - no license required
|
|
227
|
-
if (requiredFeature === null) {
|
|
228
|
-
return { valid: true };
|
|
229
|
-
}
|
|
230
|
-
return checkFeature(requiredFeature);
|
|
231
|
-
}
|
|
232
|
-
function invalidateCache() {
|
|
233
|
-
context.cachedLicense = null;
|
|
234
|
-
context.cacheExpiry = 0;
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
checkFeature,
|
|
238
|
-
checkTool,
|
|
239
|
-
getLicenseInfo,
|
|
240
|
-
invalidateCache,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Higher-order function to create feature requirement middleware
|
|
245
|
-
*
|
|
246
|
-
* Use this to wrap tool handlers that require specific features.
|
|
247
|
-
*
|
|
248
|
-
* @param feature - The feature flag required
|
|
249
|
-
* @returns Middleware function that checks the feature
|
|
250
|
-
*
|
|
251
|
-
* @example
|
|
252
|
-
* ```typescript
|
|
253
|
-
* const middleware = createLicenseMiddleware();
|
|
254
|
-
* const requireAudit = requireFeature('audit_logging');
|
|
255
|
-
*
|
|
256
|
-
* // In tool handler:
|
|
257
|
-
* const validation = await requireAudit(middleware);
|
|
258
|
-
* if (!validation.valid) {
|
|
259
|
-
* return { error: validation.message, upgradeUrl: validation.upgradeUrl };
|
|
260
|
-
* }
|
|
261
|
-
* ```
|
|
262
|
-
*/
|
|
263
|
-
export function requireFeature(feature) {
|
|
264
|
-
return async (middleware) => {
|
|
265
|
-
return middleware.checkFeature(feature);
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Create an error response for license validation failures
|
|
270
|
-
*
|
|
271
|
-
* @param result - The license validation result
|
|
272
|
-
* @returns MCP-formatted error response
|
|
273
|
-
*/
|
|
274
|
-
export function createLicenseErrorResponse(result) {
|
|
275
|
-
return {
|
|
276
|
-
content: [
|
|
277
|
-
{
|
|
278
|
-
type: 'text',
|
|
279
|
-
text: JSON.stringify({
|
|
280
|
-
error: 'license_required',
|
|
281
|
-
message: result.message,
|
|
282
|
-
feature: result.feature,
|
|
283
|
-
upgradeUrl: result.upgradeUrl,
|
|
284
|
-
}, null, 2),
|
|
285
|
-
},
|
|
286
|
-
],
|
|
287
|
-
isError: true,
|
|
288
|
-
_meta: result.upgradeUrl ? { upgradeUrl: result.upgradeUrl } : undefined,
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
export { TOOL_FEATURES, FEATURE_DISPLAY_NAMES, FEATURE_TIERS } from './toolFeatureMapping.js';
|
|
292
|
-
//# sourceMappingURL=license.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"license.js","sourceRoot":"","sources":["../../../src/middleware/license.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,aAAa,GAEd,MAAM,yBAAyB,CAAA;AAEhC;;GAEG;AACH,MAAM,WAAW,GAAG,gCAAgC,CAAA;AAgEpD;;GAEG;AACH,SAAS,kBAAkB,CACzB,GAAY;IAEZ,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,kBAAkB,IAAI,GAAG;QACzB,OAAQ,GAA+B,CAAC,kBAAkB,CAAC,KAAK,UAAU,CAC3E,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,0BAA0B;IACvC,IAAI,CAAC;QACH,oFAAoF;QACpF,gEAAgE;QAChE,MAAM,WAAW,GAAG,wBAAwB,CAAA;QAC5C,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAA;QACtE,IAAI,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,UAAU,CAAC,gBAAgB,EAAE,CAAA;QAC1C,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;QAC1E,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,aAAa,CAAC,OAAO,CAAC,KAAK,YAAY,CAAA;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,aAAa,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAA;AAClF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,aAAa,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAA;AACxC,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,SAAgB;IAC5C,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAA;IAChC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IAC9F,IAAI,eAAe,IAAI,EAAE,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO,2BAA2B,eAAe,OAAO,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,+CAA+C,CAAA;IACzI,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAqCD;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAGvC;IACC,MAAM,MAAM,GAAG,OAAO,EAAE,gBAAgB,IAAI,wBAAwB,CAAA;IACpE,MAAM,QAAQ,GAAG,OAAO,EAAE,UAAU,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,oBAAoB;IAE1E,MAAM,OAAO,GAA6B;QACxC,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QAC/B,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,CAAC;KACf,CAAA;IAED,8BAA8B;IAC9B,IAAI,gBAAgB,GAA+C,IAAI,CAAA;IAEvE,KAAK,UAAU,YAAY;QACzB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,gBAAgB,GAAG,0BAA0B,EAAE,CAAA;QACjD,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC/B,OAAO,CAAC,SAAS,GAAG,MAAM,gBAAgB,CAAA;QAC5C,CAAC;QACD,OAAO,OAAO,CAAC,SAAS,CAAA;IAC1B,CAAC;IAED,KAAK,UAAU,cAAc;QAC3B,oBAAoB;QACpB,IAAI,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9D,OAAO,OAAO,CAAC,aAAa,CAAA;QAC9B,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YACxB,MAAM,gBAAgB,GAAgB;gBACpC,KAAK,EAAE,IAAI;gBACX,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,EAAE;aACb,CAAA;YACD,OAAO,CAAC,aAAa,GAAG,gBAAgB,CAAA;YACxC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAA;YAC3C,OAAO,gBAAgB,CAAA;QACzB,CAAC;QAED,0CAA0C;QAC1C,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAA;QACtC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,4DAA4D;YAC5D,0EAA0E;YAC1E,wEAAwE;YACxE,mEAAmE;YACnE,8BAA8B;YAC9B,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;YAE3D,qCAAqC;YACrC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrC,+DAA+D;gBAC/D,OAAO,IAAI,CAAA;YACb,CAAC;YAED,uDAAuD;YACvD,MAAM,OAAO,GAAgB;gBAC3B,KAAK,EAAE,IAAI;gBACX,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;gBACzB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ;gBACjC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;gBACnC,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU;aAC1C,CAAA;YAED,OAAO,CAAC,aAAa,GAAG,OAAO,CAAA;YAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAA;YAC3C,OAAO,OAAO,CAAA;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,2DAA2D;YAC3D,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,KAAK,UAAU,YAAY,CAAC,OAAoB;QAC9C,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAA;QAEtC,mBAAmB;QACnB,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;YACnC,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAClD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,OAAO;gBACP,OAAO,EAAE,QAAQ,WAAW,wBAAwB,IAAI,gDAAgD;gBACxG,UAAU,EAAE,GAAG,WAAW,YAAY,OAAO,EAAE;aAChD,CAAA;QACH,CAAC;QAED,oCAAoC;QACpC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;YACnC,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAClD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,OAAO;gBACP,OAAO,EAAE,QAAQ,WAAW,wBAAwB,IAAI,oDAAoD;gBAC5G,UAAU,EAAE,GAAG,WAAW,YAAY,OAAO,oBAAoB;aAClE,CAAA;QACH,CAAC;QAED,8EAA8E;QAC9E,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QAC1C,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,WAAW,KAAK,MAAM,IAAI,WAAW,KAAK,YAAY,CAAC,EAAE,CAAC;YAC9F,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAClD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,OAAO;gBACP,OAAO,EAAE,QAAQ,WAAW,wBAAwB,WAAW,qDAAqD;gBACpH,UAAU,EAAE,GAAG,WAAW,YAAY,OAAO,qBAAqB;aACnE,CAAA;QACH,CAAC;QAED,kDAAkD;QAClD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;YAC5D,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAClD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,OAAO;gBACP,OAAO,EAAE,QAAQ,WAAW,+EAA+E;gBAC3G,UAAU,EAAE,GAAG,WAAW,YAAY,OAAO,eAAe;aAC7D,CAAA;QACH,CAAC;QAED,qCAAqC;QACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAClD,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;YACnC,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,OAAO;gBACP,OAAO,EAAE,QAAQ,WAAW,4EAA4E,IAAI,WAAW;gBACvH,UAAU,EAAE,GAAG,WAAW,YAAY,OAAO,eAAe;aAC7D,CAAA;QACH,CAAC;QAED,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACvD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IACjC,CAAC;IAED,KAAK,UAAU,SAAS,CAAC,QAAgB;QACvC,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;QAEpD,uCAAuC;QACvC,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YAC7B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;QACxB,CAAC;QAED,OAAO,YAAY,CAAC,eAAe,CAAC,CAAA;IACtC,CAAC;IAED,SAAS,eAAe;QACtB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAA;QAC5B,OAAO,CAAC,WAAW,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,OAAO;QACL,YAAY;QACZ,SAAS;QACT,cAAc;QACd,eAAe;KAChB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAoB;IAEpB,OAAO,KAAK,EAAE,UAA6B,EAAE,EAAE;QAC7C,OAAO,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IACzC,CAAC,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAA+B;IAKxE,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,KAAK,EAAE,kBAAkB;oBACzB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,UAAU,EAAE,MAAM,CAAC,UAAU;iBAC9B,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;QACD,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS;KACzE,CAAA;AACH,CAAC;AAID,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA"}
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SMI-1091: Quota Enforcement Middleware for MCP Server
|
|
3
|
-
*
|
|
4
|
-
* Enforces API call quotas based on license tier.
|
|
5
|
-
* Integrates with the license middleware and QuotaEnforcementService.
|
|
6
|
-
*
|
|
7
|
-
* Tier Limits:
|
|
8
|
-
* - Community: 1,000 API calls/month (free)
|
|
9
|
-
* - Individual: 10,000 API calls/month ($9.99/mo)
|
|
10
|
-
* - Team: 100,000 API calls/month ($25/user/mo)
|
|
11
|
-
* - Enterprise: Unlimited
|
|
12
|
-
*
|
|
13
|
-
* @see SMI-1055: Add license middleware to MCP server
|
|
14
|
-
* @see packages/enterprise/src/quota/QuotaEnforcementService.ts
|
|
15
|
-
*/
|
|
16
|
-
import type { LicenseMiddleware, LicenseInfo, LicenseTier } from './license.js';
|
|
17
|
-
import { type MCPErrorResponse } from './errorFormatter.js';
|
|
18
|
-
/**
|
|
19
|
-
* Warning threshold type for quota levels
|
|
20
|
-
*/
|
|
21
|
-
type WarningLevel = 0 | 80 | 90 | 100;
|
|
22
|
-
/**
|
|
23
|
-
* Quota check result returned after validating usage
|
|
24
|
-
*/
|
|
25
|
-
export interface QuotaCheckResult {
|
|
26
|
-
/** Whether the tool call is allowed */
|
|
27
|
-
allowed: boolean;
|
|
28
|
-
/** Remaining API calls in the current period */
|
|
29
|
-
remaining: number;
|
|
30
|
-
/** Total limit for the current tier (-1 for unlimited) */
|
|
31
|
-
limit: number;
|
|
32
|
-
/** Percentage of quota used (0-100+) */
|
|
33
|
-
percentUsed: number;
|
|
34
|
-
/** Current warning level (0, 80, 90, or 100) */
|
|
35
|
-
warningLevel: WarningLevel;
|
|
36
|
-
/** When the quota resets (start of next billing period) */
|
|
37
|
-
resetAt: Date;
|
|
38
|
-
/** Warning or error message if applicable */
|
|
39
|
-
message?: string;
|
|
40
|
-
/** Upgrade URL if quota is exceeded or near limit */
|
|
41
|
-
upgradeUrl?: string;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Quota information to include in response metadata
|
|
45
|
-
*/
|
|
46
|
-
export interface QuotaMetadata {
|
|
47
|
-
/** Remaining API calls */
|
|
48
|
-
remaining: number;
|
|
49
|
-
/** Total limit (-1 for unlimited) */
|
|
50
|
-
limit: number;
|
|
51
|
-
/** When the quota resets */
|
|
52
|
-
resetAt: string;
|
|
53
|
-
/** Warning message if approaching limit */
|
|
54
|
-
warning?: string;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Quota middleware configuration options
|
|
58
|
-
*/
|
|
59
|
-
export interface QuotaMiddlewareOptions {
|
|
60
|
-
/**
|
|
61
|
-
* Cost of each API call (default: 1)
|
|
62
|
-
* Can be customized per tool if some tools are more expensive
|
|
63
|
-
*/
|
|
64
|
-
defaultCost?: number;
|
|
65
|
-
/**
|
|
66
|
-
* Whether to track usage even for unlimited tiers (enterprise)
|
|
67
|
-
* Useful for analytics purposes
|
|
68
|
-
*/
|
|
69
|
-
trackUnlimited?: boolean;
|
|
70
|
-
/**
|
|
71
|
-
* Custom storage adapter for quota tracking
|
|
72
|
-
* If not provided, uses in-memory storage (resets on restart)
|
|
73
|
-
*/
|
|
74
|
-
storage?: QuotaStorage;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Interface for quota storage adapters
|
|
78
|
-
*/
|
|
79
|
-
export interface QuotaStorage {
|
|
80
|
-
/** Get current usage for a customer in the current period */
|
|
81
|
-
getUsage(customerId: string): Promise<{
|
|
82
|
-
used: number;
|
|
83
|
-
periodStart: Date;
|
|
84
|
-
periodEnd: Date;
|
|
85
|
-
}>;
|
|
86
|
-
/** Increment usage count */
|
|
87
|
-
incrementUsage(customerId: string, cost: number): Promise<void>;
|
|
88
|
-
/** Initialize quota for a new billing period */
|
|
89
|
-
initializePeriod(customerId: string, limit: number): Promise<void>;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Quota middleware instance
|
|
93
|
-
*/
|
|
94
|
-
export interface QuotaMiddleware {
|
|
95
|
-
/**
|
|
96
|
-
* Check if a tool call is allowed and track usage
|
|
97
|
-
* Call this BEFORE executing the tool
|
|
98
|
-
*/
|
|
99
|
-
checkAndTrack(toolName: string, licenseInfo: LicenseInfo | null, customerId?: string): Promise<QuotaCheckResult>;
|
|
100
|
-
/**
|
|
101
|
-
* Get current quota status without incrementing
|
|
102
|
-
*/
|
|
103
|
-
getStatus(licenseInfo: LicenseInfo | null, customerId?: string): Promise<QuotaCheckResult>;
|
|
104
|
-
/**
|
|
105
|
-
* Build quota metadata for response _meta field
|
|
106
|
-
*/
|
|
107
|
-
buildMetadata(result: QuotaCheckResult): QuotaMetadata;
|
|
108
|
-
/**
|
|
109
|
-
* Build error response for quota exceeded
|
|
110
|
-
*/
|
|
111
|
-
buildExceededResponse(result: QuotaCheckResult): MCPErrorResponse;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Create a quota enforcement middleware
|
|
115
|
-
*
|
|
116
|
-
* @param options - Configuration options
|
|
117
|
-
* @returns Quota middleware instance
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* ```typescript
|
|
121
|
-
* import { createQuotaMiddleware } from './middleware/quota.js';
|
|
122
|
-
* import { createLicenseMiddleware } from './middleware/license.js';
|
|
123
|
-
*
|
|
124
|
-
* const licenseMiddleware = createLicenseMiddleware();
|
|
125
|
-
* const quotaMiddleware = createQuotaMiddleware();
|
|
126
|
-
*
|
|
127
|
-
* // In tool handler:
|
|
128
|
-
* async function handleTool(toolName: string, params: unknown) {
|
|
129
|
-
* const licenseInfo = await licenseMiddleware.getLicenseInfo();
|
|
130
|
-
* const quotaResult = await quotaMiddleware.checkAndTrack(toolName, licenseInfo);
|
|
131
|
-
*
|
|
132
|
-
* if (!quotaResult.allowed) {
|
|
133
|
-
* return quotaMiddleware.buildExceededResponse(quotaResult);
|
|
134
|
-
* }
|
|
135
|
-
*
|
|
136
|
-
* // Execute tool...
|
|
137
|
-
* const result = await executeTool(toolName, params);
|
|
138
|
-
*
|
|
139
|
-
* // Add quota metadata to response
|
|
140
|
-
* return {
|
|
141
|
-
* ...result,
|
|
142
|
-
* _meta: {
|
|
143
|
-
* ...result._meta,
|
|
144
|
-
* quota: quotaMiddleware.buildMetadata(quotaResult),
|
|
145
|
-
* },
|
|
146
|
-
* };
|
|
147
|
-
* }
|
|
148
|
-
* ```
|
|
149
|
-
*/
|
|
150
|
-
export declare function createQuotaMiddleware(options?: QuotaMiddlewareOptions): QuotaMiddleware;
|
|
151
|
-
/**
|
|
152
|
-
* Wrap a tool handler with quota enforcement
|
|
153
|
-
*
|
|
154
|
-
* @param handler - The original tool handler
|
|
155
|
-
* @param licenseMiddleware - License middleware instance
|
|
156
|
-
* @param quotaMiddleware - Quota middleware instance
|
|
157
|
-
* @returns Wrapped handler with quota enforcement
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```typescript
|
|
161
|
-
* const searchHandler = withQuotaEnforcement(
|
|
162
|
-
* originalSearchHandler,
|
|
163
|
-
* licenseMiddleware,
|
|
164
|
-
* quotaMiddleware
|
|
165
|
-
* );
|
|
166
|
-
* ```
|
|
167
|
-
*/
|
|
168
|
-
export declare function withQuotaEnforcement<TParams, TResult>(handler: (params: TParams) => Promise<TResult>, licenseMiddleware: LicenseMiddleware, quotaMiddleware: QuotaMiddleware): (toolName: string, params: TParams) => Promise<TResult | MCPErrorResponse>;
|
|
169
|
-
/**
|
|
170
|
-
* Check if a tier has unlimited quota
|
|
171
|
-
*/
|
|
172
|
-
export declare function isUnlimitedTier(tier: LicenseTier): boolean;
|
|
173
|
-
/**
|
|
174
|
-
* Get the quota limit for a tier
|
|
175
|
-
*/
|
|
176
|
-
export declare function getQuotaLimit(tier: LicenseTier): number;
|
|
177
|
-
/**
|
|
178
|
-
* Format quota remaining for display
|
|
179
|
-
*/
|
|
180
|
-
export declare function formatQuotaRemaining(remaining: number, limit: number): string;
|
|
181
|
-
export {};
|
|
182
|
-
//# sourceMappingURL=quota.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../../../src/middleware/quota.ts"],"names":[],"mappings":"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"}
|