nitrostack 1.0.0 → 1.0.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.
Files changed (115) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +1 -1
  3. package/templates/typescript-auth/.env.example +23 -0
  4. package/templates/typescript-auth/src/app.module.ts +103 -0
  5. package/templates/typescript-auth/src/db/database.ts +163 -0
  6. package/templates/typescript-auth/src/db/seed.ts +374 -0
  7. package/templates/typescript-auth/src/db/setup.ts +87 -0
  8. package/templates/typescript-auth/src/events/analytics.service.ts +52 -0
  9. package/templates/typescript-auth/src/events/notification.service.ts +40 -0
  10. package/templates/typescript-auth/src/filters/global-exception.filter.ts +28 -0
  11. package/templates/typescript-auth/src/guards/README.md +75 -0
  12. package/templates/typescript-auth/src/guards/jwt.guard.ts +105 -0
  13. package/templates/typescript-auth/src/health/database.health.ts +41 -0
  14. package/templates/typescript-auth/src/index.ts +26 -0
  15. package/templates/typescript-auth/src/interceptors/transform.interceptor.ts +24 -0
  16. package/templates/typescript-auth/src/middleware/logging.middleware.ts +42 -0
  17. package/templates/typescript-auth/src/modules/addresses/addresses.module.ts +16 -0
  18. package/templates/typescript-auth/src/modules/addresses/addresses.prompts.ts +114 -0
  19. package/templates/typescript-auth/src/modules/addresses/addresses.resources.ts +40 -0
  20. package/templates/typescript-auth/src/modules/addresses/addresses.tools.ts +241 -0
  21. package/templates/typescript-auth/src/modules/auth/auth.module.ts +16 -0
  22. package/templates/typescript-auth/src/modules/auth/auth.prompts.ts +147 -0
  23. package/templates/typescript-auth/src/modules/auth/auth.resources.ts +84 -0
  24. package/templates/typescript-auth/src/modules/auth/auth.tools.ts +139 -0
  25. package/templates/typescript-auth/src/modules/cart/cart.module.ts +16 -0
  26. package/templates/typescript-auth/src/modules/cart/cart.prompts.ts +95 -0
  27. package/templates/typescript-auth/src/modules/cart/cart.resources.ts +44 -0
  28. package/templates/typescript-auth/src/modules/cart/cart.tools.ts +281 -0
  29. package/templates/typescript-auth/src/modules/orders/orders.module.ts +16 -0
  30. package/templates/typescript-auth/src/modules/orders/orders.prompts.ts +88 -0
  31. package/templates/typescript-auth/src/modules/orders/orders.resources.ts +48 -0
  32. package/templates/typescript-auth/src/modules/orders/orders.tools.ts +281 -0
  33. package/templates/typescript-auth/src/modules/products/products.module.ts +16 -0
  34. package/templates/typescript-auth/src/modules/products/products.prompts.ts +146 -0
  35. package/templates/typescript-auth/src/modules/products/products.resources.ts +98 -0
  36. package/templates/typescript-auth/src/modules/products/products.tools.ts +266 -0
  37. package/templates/typescript-auth/src/pipes/validation.pipe.ts +42 -0
  38. package/templates/typescript-auth/src/services/database.service.ts +90 -0
  39. package/templates/typescript-auth/src/widgets/app/add-to-cart/page.tsx +122 -0
  40. package/templates/typescript-auth/src/widgets/app/address-added/page.tsx +116 -0
  41. package/templates/typescript-auth/src/widgets/app/address-deleted/page.tsx +105 -0
  42. package/templates/typescript-auth/src/widgets/app/address-list/page.tsx +139 -0
  43. package/templates/typescript-auth/src/widgets/app/address-updated/page.tsx +153 -0
  44. package/templates/typescript-auth/src/widgets/app/cart-cleared/page.tsx +86 -0
  45. package/templates/typescript-auth/src/widgets/app/cart-updated/page.tsx +116 -0
  46. package/templates/typescript-auth/src/widgets/app/categories/page.tsx +134 -0
  47. package/templates/typescript-auth/src/widgets/app/layout.tsx +21 -0
  48. package/templates/typescript-auth/src/widgets/app/login-result/page.tsx +129 -0
  49. package/templates/typescript-auth/src/widgets/app/order-confirmation/page.tsx +206 -0
  50. package/templates/typescript-auth/src/widgets/app/order-details/page.tsx +225 -0
  51. package/templates/typescript-auth/src/widgets/app/order-history/page.tsx +218 -0
  52. package/templates/typescript-auth/src/widgets/app/product-card/page.tsx +121 -0
  53. package/templates/typescript-auth/src/widgets/app/products-grid/page.tsx +173 -0
  54. package/templates/typescript-auth/src/widgets/app/shopping-cart/page.tsx +187 -0
  55. package/templates/typescript-auth/src/widgets/app/whoami/page.tsx +165 -0
  56. package/templates/typescript-auth/src/widgets/next.config.js +38 -0
  57. package/templates/typescript-auth/src/widgets/package.json +18 -0
  58. package/templates/typescript-auth/src/widgets/styles/ecommerce.ts +169 -0
  59. package/templates/typescript-auth/src/widgets/tsconfig.json +28 -0
  60. package/templates/typescript-auth/src/widgets/types/tool-data.ts +141 -0
  61. package/templates/typescript-auth/src/widgets/widget-manifest.json +464 -0
  62. package/templates/typescript-auth/tsconfig.json +27 -0
  63. package/templates/typescript-auth-api-key/.env +15 -0
  64. package/templates/typescript-auth-api-key/.env.example +4 -0
  65. package/templates/typescript-auth-api-key/src/app.module.ts +38 -0
  66. package/templates/typescript-auth-api-key/src/guards/apikey.guard.ts +47 -0
  67. package/templates/typescript-auth-api-key/src/guards/multi-auth.guard.ts +157 -0
  68. package/templates/typescript-auth-api-key/src/health/system.health.ts +55 -0
  69. package/templates/typescript-auth-api-key/src/index.ts +47 -0
  70. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.module.ts +12 -0
  71. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.prompts.ts +73 -0
  72. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.resources.ts +60 -0
  73. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.tools.ts +71 -0
  74. package/templates/typescript-auth-api-key/src/modules/demo/demo.module.ts +18 -0
  75. package/templates/typescript-auth-api-key/src/modules/demo/demo.tools.ts +155 -0
  76. package/templates/typescript-auth-api-key/src/modules/demo/multi-auth.tools.ts +123 -0
  77. package/templates/typescript-auth-api-key/src/widgets/app/calculator-operations/page.tsx +133 -0
  78. package/templates/typescript-auth-api-key/src/widgets/app/calculator-result/page.tsx +134 -0
  79. package/templates/typescript-auth-api-key/src/widgets/app/layout.tsx +14 -0
  80. package/templates/typescript-auth-api-key/src/widgets/next.config.js +37 -0
  81. package/templates/typescript-auth-api-key/src/widgets/package.json +24 -0
  82. package/templates/typescript-auth-api-key/src/widgets/tsconfig.json +28 -0
  83. package/templates/typescript-auth-api-key/src/widgets/widget-manifest.json +48 -0
  84. package/templates/typescript-auth-api-key/tsconfig.json +23 -0
  85. package/templates/typescript-oauth/.env.example +91 -0
  86. package/templates/typescript-oauth/src/app.module.ts +89 -0
  87. package/templates/typescript-oauth/src/guards/oauth.guard.ts +127 -0
  88. package/templates/typescript-oauth/src/index.ts +74 -0
  89. package/templates/typescript-oauth/src/modules/demo/demo.module.ts +16 -0
  90. package/templates/typescript-oauth/src/modules/demo/demo.tools.ts +190 -0
  91. package/templates/typescript-oauth/src/widgets/app/calculator-operations/page.tsx +133 -0
  92. package/templates/typescript-oauth/src/widgets/app/calculator-result/page.tsx +134 -0
  93. package/templates/typescript-oauth/src/widgets/app/layout.tsx +14 -0
  94. package/templates/typescript-oauth/src/widgets/next.config.js +37 -0
  95. package/templates/typescript-oauth/src/widgets/package.json +24 -0
  96. package/templates/typescript-oauth/src/widgets/tsconfig.json +28 -0
  97. package/templates/typescript-oauth/src/widgets/widget-manifest.json +48 -0
  98. package/templates/typescript-oauth/tsconfig.json +23 -0
  99. package/templates/typescript-starter/.env.example +4 -0
  100. package/templates/typescript-starter/src/app.module.ts +34 -0
  101. package/templates/typescript-starter/src/health/system.health.ts +55 -0
  102. package/templates/typescript-starter/src/index.ts +27 -0
  103. package/templates/typescript-starter/src/modules/calculator/calculator.module.ts +12 -0
  104. package/templates/typescript-starter/src/modules/calculator/calculator.prompts.ts +73 -0
  105. package/templates/typescript-starter/src/modules/calculator/calculator.resources.ts +60 -0
  106. package/templates/typescript-starter/src/modules/calculator/calculator.tools.ts +71 -0
  107. package/templates/typescript-starter/src/widgets/app/calculator-operations/page.tsx +133 -0
  108. package/templates/typescript-starter/src/widgets/app/calculator-result/page.tsx +134 -0
  109. package/templates/typescript-starter/src/widgets/app/layout.tsx +14 -0
  110. package/templates/typescript-starter/src/widgets/next.config.js +37 -0
  111. package/templates/typescript-starter/src/widgets/package.json +24 -0
  112. package/templates/typescript-starter/src/widgets/tsconfig.json +28 -0
  113. package/templates/typescript-starter/src/widgets/widget-manifest.json +48 -0
  114. package/templates/typescript-starter/tsconfig.json +23 -0
  115. package/LICENSE_URLS_UPDATE_COMPLETE.md +0 -388
@@ -0,0 +1,123 @@
1
+ import { Injectable, ToolDecorator as Tool, UseGuards, z, ExecutionContext } from 'nitrostack';
2
+ import { MultiAuthGuard, DualAuthGuard } from '../../guards/multi-auth.guard.js';
3
+
4
+ /**
5
+ * Multi-Auth Demo Tools
6
+ *
7
+ * Demonstrates advanced authentication patterns:
8
+ * 1. Tools that accept EITHER JWT OR API key
9
+ * 2. Tools that require BOTH JWT AND API key
10
+ */
11
+
12
+ @Injectable()
13
+ export class MultiAuthTools {
14
+
15
+ /**
16
+ * FLEXIBLE AUTH - Accepts JWT OR API key
17
+ * Users can authenticate with either method
18
+ */
19
+ @Tool({
20
+ name: 'get_flexible_data',
21
+ description: 'Get data using JWT token OR API key (either works)',
22
+ inputSchema: z.object({
23
+ query: z.string().describe('Search query'),
24
+ }),
25
+ })
26
+ @UseGuards(MultiAuthGuard)
27
+ async getFlexibleData(args: { query: string }, context?: ExecutionContext) {
28
+ const authMethod = (context?.metadata as any)?._authMethod || 'unknown';
29
+ const subject = context?.auth?.subject || 'unknown';
30
+
31
+ return {
32
+ message: `Data retrieved successfully using ${authMethod}`,
33
+ authInfo: {
34
+ method: authMethod,
35
+ subject: subject,
36
+ flexibleAuth: true,
37
+ },
38
+ query: args.query,
39
+ results: [
40
+ { id: 1, title: 'Result 1', data: 'Sample data 1' },
41
+ { id: 2, title: 'Result 2', data: 'Sample data 2' },
42
+ { id: 3, title: 'Result 3', data: 'Sample data 3' },
43
+ ],
44
+ hint: 'This tool accepts either JWT token or API key. Try it with different auth methods!',
45
+ };
46
+ }
47
+
48
+ /**
49
+ * DUAL AUTH - Requires BOTH JWT AND API key
50
+ * For highly sensitive operations
51
+ */
52
+ @Tool({
53
+ name: 'perform_critical_action',
54
+ description: 'Perform critical action (requires BOTH JWT token AND API key)',
55
+ inputSchema: z.object({
56
+ actionType: z.enum(['delete_account', 'transfer_funds', 'change_permissions']).describe('Type of critical action'),
57
+ confirmation: z.boolean().describe('Confirmation (must be true)'),
58
+ }),
59
+ })
60
+ @UseGuards(DualAuthGuard)
61
+ async performCriticalAction(
62
+ args: { actionType: string; confirmation: boolean },
63
+ context?: ExecutionContext
64
+ ) {
65
+ if (!args.confirmation) {
66
+ throw new Error('Confirmation required for critical actions');
67
+ }
68
+
69
+ const subject = context?.auth?.subject || 'unknown';
70
+
71
+ return {
72
+ message: `Critical action "${args.actionType}" executed successfully`,
73
+ security: {
74
+ authMethod: 'JWT + API Key (Dual Authentication)',
75
+ subject: subject,
76
+ verified: true,
77
+ timestamp: new Date().toISOString(),
78
+ },
79
+ action: {
80
+ type: args.actionType,
81
+ status: 'completed',
82
+ confirmed: args.confirmation,
83
+ },
84
+ warning: '⚠️ This action required dual authentication for security',
85
+ };
86
+ }
87
+
88
+ /**
89
+ * AUTH INFO - Check which auth methods are active
90
+ * Uses flexible auth to demonstrate detection
91
+ */
92
+ @Tool({
93
+ name: 'check_auth_methods',
94
+ description: 'Check which authentication methods are currently active',
95
+ inputSchema: z.object({}),
96
+ })
97
+ @UseGuards(MultiAuthGuard)
98
+ async checkAuthMethods(args: {}, context?: ExecutionContext) {
99
+ const hasJWT = !!(context?.metadata?._jwt || context?.metadata?.authorization);
100
+ const hasAPIKey = !!(context?.metadata?.apiKey || context?.metadata?.['x-api-key']);
101
+ const authMethod = (context?.metadata as any)?._authMethod || 'unknown';
102
+
103
+ return {
104
+ message: 'Authentication methods detected',
105
+ activeAuth: {
106
+ method: authMethod,
107
+ jwt: hasJWT,
108
+ apiKey: hasAPIKey,
109
+ both: hasJWT && hasAPIKey,
110
+ },
111
+ subject: context?.auth?.subject || 'unknown',
112
+ scopes: context?.auth?.scopes || [],
113
+ recommendations: {
114
+ jwtOnly: hasJWT && !hasAPIKey ? '✓ Using JWT authentication' : null,
115
+ apiKeyOnly: !hasJWT && hasAPIKey ? '✓ Using API key authentication' : null,
116
+ both: hasJWT && hasAPIKey ? '✓ Using dual authentication (most secure!)' : null,
117
+ none: !hasJWT && !hasAPIKey ? '⚠️ No authentication detected (this should not happen)' : null,
118
+ },
119
+ hint: 'Set JWT token and/or API key in Studio Auth tab to see different combinations',
120
+ };
121
+ }
122
+ }
123
+
@@ -0,0 +1,133 @@
1
+ 'use client';
2
+
3
+ import { withToolData } from 'nitrostack/widgets';
4
+
5
+ /**
6
+ * Widget Metadata (stored in widget-manifest.json)
7
+ *
8
+ * This widget lists all available calculator operations.
9
+ *
10
+ * Example includes all four operations: add, subtract, multiply, divide
11
+ *
12
+ * Frontend developers: Edit widget-manifest.json to update examples
13
+ */
14
+
15
+ interface Operation {
16
+ name: string;
17
+ symbol: string;
18
+ description: string;
19
+ example: string;
20
+ }
21
+
22
+ interface OperationsData {
23
+ operations: Operation[];
24
+ }
25
+
26
+ function CalculatorOperations({ data }: { data: OperationsData }) {
27
+ const getOperationColor = (name: string) => {
28
+ const colors: Record<string, string> = {
29
+ add: '#10b981',
30
+ subtract: '#f59e0b',
31
+ multiply: '#3b82f6',
32
+ divide: '#8b5cf6'
33
+ };
34
+ return colors[name] || '#6b7280';
35
+ };
36
+
37
+ return (
38
+ <div style={{
39
+ padding: '24px',
40
+ background: 'linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%)',
41
+ borderRadius: '16px',
42
+ maxWidth: '500px'
43
+ }}>
44
+ <h3 style={{
45
+ margin: '0 0 20px 0',
46
+ fontSize: '24px',
47
+ color: '#1f2937',
48
+ display: 'flex',
49
+ alignItems: 'center',
50
+ gap: '12px'
51
+ }}>
52
+ <span style={{ fontSize: '32px' }}>🔢</span>
53
+ Calculator Operations
54
+ </h3>
55
+
56
+ <div style={{ display: 'grid', gap: '12px' }}>
57
+ {data.operations.map((op) => (
58
+ <div
59
+ key={op.name}
60
+ style={{
61
+ background: 'white',
62
+ borderRadius: '12px',
63
+ padding: '16px',
64
+ boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
65
+ borderLeft: `4px solid ${getOperationColor(op.name)}`
66
+ }}
67
+ >
68
+ <div style={{
69
+ display: 'flex',
70
+ alignItems: 'center',
71
+ gap: '12px',
72
+ marginBottom: '8px'
73
+ }}>
74
+ <div style={{
75
+ width: '40px',
76
+ height: '40px',
77
+ borderRadius: '10px',
78
+ background: getOperationColor(op.name),
79
+ display: 'flex',
80
+ alignItems: 'center',
81
+ justifyContent: 'center',
82
+ color: 'white',
83
+ fontSize: '24px',
84
+ fontWeight: 'bold'
85
+ }}>
86
+ {op.symbol}
87
+ </div>
88
+ <div>
89
+ <div style={{
90
+ fontSize: '16px',
91
+ fontWeight: 'bold',
92
+ color: '#1f2937',
93
+ textTransform: 'capitalize'
94
+ }}>
95
+ {op.name}
96
+ </div>
97
+ <div style={{
98
+ fontSize: '14px',
99
+ color: '#6b7280'
100
+ }}>
101
+ {op.description}
102
+ </div>
103
+ </div>
104
+ </div>
105
+ <div style={{
106
+ marginTop: '12px',
107
+ padding: '8px 12px',
108
+ background: '#f9fafb',
109
+ borderRadius: '8px',
110
+ fontFamily: 'monospace',
111
+ fontSize: '14px',
112
+ color: '#374151'
113
+ }}>
114
+ {op.example}
115
+ </div>
116
+ </div>
117
+ ))}
118
+ </div>
119
+
120
+ <div style={{
121
+ marginTop: '16px',
122
+ textAlign: 'center',
123
+ fontSize: '12px',
124
+ color: '#6b7280'
125
+ }}>
126
+ ✨ Use the 'calculate' tool to perform these operations
127
+ </div>
128
+ </div>
129
+ );
130
+ }
131
+
132
+ export default withToolData(CalculatorOperations);
133
+
@@ -0,0 +1,134 @@
1
+ 'use client';
2
+
3
+ import { withToolData } from 'nitrostack/widgets';
4
+
5
+ /**
6
+ * Widget Metadata (stored in widget-manifest.json)
7
+ *
8
+ * This widget displays calculation results with operation details.
9
+ *
10
+ * Examples defined in manifest:
11
+ * - Addition: 5 + 3 = 8
12
+ * - Multiplication: 6 × 7 = 42
13
+ * - Division: 20 ÷ 4 = 5
14
+ *
15
+ * Frontend developers: Edit widget-manifest.json to update examples
16
+ */
17
+
18
+ interface CalculatorData {
19
+ operation: string;
20
+ a: number;
21
+ b: number;
22
+ result: number;
23
+ expression: string;
24
+ }
25
+
26
+ function CalculatorResult({ data }: { data: CalculatorData }) {
27
+ const getOperationColor = (op: string) => {
28
+ const colors: Record<string, string> = {
29
+ add: '#10b981',
30
+ subtract: '#f59e0b',
31
+ multiply: '#3b82f6',
32
+ divide: '#8b5cf6'
33
+ };
34
+ return colors[op] || '#6b7280';
35
+ };
36
+
37
+ const getOperationIcon = (op: string) => {
38
+ const icons: Record<string, string> = {
39
+ add: '➕',
40
+ subtract: '➖',
41
+ multiply: '✖️',
42
+ divide: '➗'
43
+ };
44
+ return icons[op] || '🔢';
45
+ };
46
+
47
+ const color = getOperationColor(data.operation);
48
+
49
+ return (
50
+ <div style={{
51
+ padding: '24px',
52
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
53
+ borderRadius: '16px',
54
+ color: 'white',
55
+ maxWidth: '400px',
56
+ boxShadow: '0 10px 30px rgba(0,0,0,0.2)'
57
+ }}>
58
+ <div style={{
59
+ display: 'flex',
60
+ alignItems: 'center',
61
+ gap: '12px',
62
+ marginBottom: '20px'
63
+ }}>
64
+ <span style={{ fontSize: '32px' }}>
65
+ {getOperationIcon(data.operation)}
66
+ </span>
67
+ <div>
68
+ <h3 style={{ margin: 0, fontSize: '18px', opacity: 0.9 }}>
69
+ Calculator Result
70
+ </h3>
71
+ <p style={{ margin: '4px 0 0 0', fontSize: '14px', opacity: 0.7 }}>
72
+ {data.operation.charAt(0).toUpperCase() + data.operation.slice(1)}
73
+ </p>
74
+ </div>
75
+ </div>
76
+
77
+ <div style={{
78
+ background: 'rgba(255, 255, 255, 0.15)',
79
+ borderRadius: '12px',
80
+ padding: '20px',
81
+ backdropFilter: 'blur(10px)',
82
+ marginBottom: '16px'
83
+ }}>
84
+ <div style={{
85
+ fontSize: '28px',
86
+ fontWeight: 'bold',
87
+ textAlign: 'center',
88
+ marginBottom: '12px',
89
+ fontFamily: 'monospace'
90
+ }}>
91
+ {data.expression}
92
+ </div>
93
+
94
+ <div style={{
95
+ display: 'flex',
96
+ justifyContent: 'space-around',
97
+ fontSize: '14px',
98
+ opacity: 0.9,
99
+ marginTop: '16px'
100
+ }}>
101
+ <div style={{ textAlign: 'center' }}>
102
+ <div style={{ fontSize: '12px', opacity: 0.7 }}>First</div>
103
+ <div style={{ fontWeight: 'bold', fontSize: '20px' }}>{data.a}</div>
104
+ </div>
105
+ <div style={{ textAlign: 'center' }}>
106
+ <div style={{ fontSize: '12px', opacity: 0.7 }}>Second</div>
107
+ <div style={{ fontWeight: 'bold', fontSize: '20px' }}>{data.b}</div>
108
+ </div>
109
+ <div style={{ textAlign: 'center' }}>
110
+ <div style={{ fontSize: '12px', opacity: 0.7 }}>Result</div>
111
+ <div style={{
112
+ fontWeight: 'bold',
113
+ fontSize: '24px',
114
+ color: '#fbbf24'
115
+ }}>
116
+ {data.result}
117
+ </div>
118
+ </div>
119
+ </div>
120
+ </div>
121
+
122
+ <div style={{
123
+ fontSize: '12px',
124
+ textAlign: 'center',
125
+ opacity: 0.7
126
+ }}>
127
+ ✨ NitroStack Calculator
128
+ </div>
129
+ </div>
130
+ );
131
+ }
132
+
133
+ export default withToolData(CalculatorResult);
134
+
@@ -0,0 +1,14 @@
1
+ export default function RootLayout({
2
+ children,
3
+ }: {
4
+ children: React.ReactNode;
5
+ }) {
6
+ return (
7
+ <html lang="en">
8
+ <body style={{ margin: 0, padding: 0, fontFamily: 'system-ui, sans-serif' }}>
9
+ {children}
10
+ </body>
11
+ </html>
12
+ );
13
+ }
14
+
@@ -0,0 +1,37 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+ transpilePackages: ['nitrostack'],
5
+
6
+ // Development optimizations to prevent cache corruption
7
+ ...(process.env.NODE_ENV === 'development' && {
8
+ // Use memory cache instead of filesystem cache in dev to avoid stale chunks
9
+ webpack: (config, { isServer }) => {
10
+ // Disable persistent caching in development to prevent chunk reference errors
11
+ if (config.cache && config.cache.type === 'filesystem') {
12
+ config.cache = {
13
+ type: 'memory',
14
+ };
15
+ }
16
+
17
+ // Improve cache busting for new files
18
+ if (!isServer) {
19
+ config.cache = false; // Disable cache completely on client in dev
20
+ }
21
+
22
+ return config;
23
+ },
24
+
25
+ // Disable build activity indicator which can cause issues
26
+ devIndicators: {
27
+ buildActivity: false,
28
+ buildActivityPosition: 'bottom-right',
29
+ },
30
+
31
+ // Faster dev server
32
+ compress: false,
33
+ }),
34
+ };
35
+
36
+ export default nextConfig;
37
+
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "calculator-widgets",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "next dev -p 3001",
8
+ "build": "next build",
9
+ "start": "next start -p 3001"
10
+ },
11
+ "dependencies": {
12
+ "next": "^14.2.5",
13
+ "react": "^18.3.1",
14
+ "react-dom": "^18.3.1",
15
+ "nitrostack": "^1.0.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^20",
19
+ "@types/react": "^18",
20
+ "@types/react-dom": "^18",
21
+ "typescript": "^5"
22
+ }
23
+ }
24
+
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }
28
+
@@ -0,0 +1,48 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "widgets": [
4
+ {
5
+ "uri": "/calculator-result",
6
+ "name": "Calculator Result",
7
+ "description": "Displays the result of a calculation with operation details",
8
+ "examples": [
9
+ {
10
+ "name": "Addition Example",
11
+ "description": "Shows the result of adding 5 + 3",
12
+ "data": {
13
+ "operation": "add",
14
+ "a": 5,
15
+ "b": 3,
16
+ "result": 8,
17
+ "expression": "5 + 3 = 8"
18
+ }
19
+ },
20
+ {
21
+ "name": "Multiplication Example",
22
+ "description": "Shows the result of multiplying 6 × 7",
23
+ "data": {
24
+ "operation": "multiply",
25
+ "a": 6,
26
+ "b": 7,
27
+ "result": 42,
28
+ "expression": "6 × 7 = 42"
29
+ }
30
+ },
31
+ {
32
+ "name": "Division Example",
33
+ "description": "Shows the result of dividing 20 ÷ 4",
34
+ "data": {
35
+ "operation": "divide",
36
+ "a": 20,
37
+ "b": 4,
38
+ "result": 5,
39
+ "expression": "20 ÷ 4 = 5"
40
+ }
41
+ }
42
+ ],
43
+ "tags": ["calculator", "math", "result"]
44
+ }
45
+ ],
46
+ "generatedAt": "2025-01-01T00:00:00.000Z"
47
+ }
48
+
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ES2022",
5
+ "lib": ["ES2022"],
6
+ "moduleResolution": "node",
7
+ "rootDir": "./src",
8
+ "outDir": "./dist",
9
+ "esModuleInterop": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "sourceMap": true,
17
+ "experimentalDecorators": true,
18
+ "emitDecoratorMetadata": true
19
+ },
20
+ "include": ["src/**/*"],
21
+ "exclude": ["node_modules", "dist", "src/widgets"]
22
+ }
23
+
@@ -0,0 +1,91 @@
1
+ # OAuth 2.1 MCP Server Configuration
2
+
3
+ # =============================================================================
4
+ # REQUIRED: Server Configuration
5
+ # =============================================================================
6
+
7
+ # Your MCP server's public URL (used for token audience binding - RFC 8707)
8
+ # This MUST match the URL where your MCP server is accessible
9
+ # Example: https://mcp.yourapp.com or http://localhost:3000 for development
10
+ RESOURCE_URI=https://mcp.example.com
11
+
12
+ # Your OAuth 2.1 authorization server URL
13
+ # This is the base URL of your OAuth provider (Auth0, Okta, Keycloak, etc.)
14
+ # Example for Auth0: https://your-tenant.auth0.com
15
+ # Example for Okta: https://your-domain.okta.com
16
+ AUTH_SERVER_URL=https://auth.example.com
17
+
18
+ # =============================================================================
19
+ # OPTIONAL: Token Configuration
20
+ # =============================================================================
21
+
22
+ # Expected token audience (defaults to RESOURCE_URI if not set)
23
+ # This MUST match the audience claim in access tokens
24
+ TOKEN_AUDIENCE=https://mcp.example.com
25
+
26
+ # Expected token issuer (recommended for security)
27
+ # This MUST match the issuer claim in access tokens
28
+ # Example for Auth0: https://your-tenant.auth0.com/
29
+ # Example for Okta: https://your-domain.okta.com/oauth2/default
30
+ TOKEN_ISSUER=https://auth.example.com/
31
+
32
+ # =============================================================================
33
+ # OPTIONAL: Token Introspection (for opaque tokens)
34
+ # =============================================================================
35
+
36
+ # If your OAuth provider issues opaque tokens (not JWTs), configure these:
37
+
38
+ # Token introspection endpoint (RFC 7662)
39
+ # Example for Auth0: https://your-tenant.auth0.com/oauth/token/introspection
40
+ # Example for Okta: https://your-domain.okta.com/oauth2/default/v1/introspect
41
+ # INTROSPECTION_ENDPOINT=https://auth.example.com/oauth/introspect
42
+
43
+ # Client credentials for introspection
44
+ # These are separate from your MCP client credentials
45
+ # INTROSPECTION_CLIENT_ID=your-introspection-client-id
46
+ # INTROSPECTION_CLIENT_SECRET=your-introspection-client-secret
47
+
48
+ # =============================================================================
49
+ # Provider-Specific Examples
50
+ # =============================================================================
51
+
52
+ # --- Auth0 Example ---
53
+ # RESOURCE_URI=https://mcp.yourapp.com
54
+ # AUTH_SERVER_URL=https://your-tenant.auth0.com
55
+ # TOKEN_AUDIENCE=https://mcp.yourapp.com
56
+ # TOKEN_ISSUER=https://your-tenant.auth0.com/
57
+
58
+ # --- Okta Example ---
59
+ # RESOURCE_URI=https://mcp.yourapp.com
60
+ # AUTH_SERVER_URL=https://your-domain.okta.com/oauth2/default
61
+ # TOKEN_AUDIENCE=api://mcp.yourapp.com
62
+ # TOKEN_ISSUER=https://your-domain.okta.com/oauth2/default
63
+
64
+ # --- Keycloak Example ---
65
+ # RESOURCE_URI=https://mcp.yourapp.com
66
+ # AUTH_SERVER_URL=https://keycloak.yourapp.com/realms/your-realm
67
+ # TOKEN_AUDIENCE=mcp-server
68
+ # TOKEN_ISSUER=https://keycloak.yourapp.com/realms/your-realm
69
+
70
+ # =============================================================================
71
+ # Setup Instructions
72
+ # =============================================================================
73
+ #
74
+ # 1. Copy this file to .env:
75
+ # cp .env.example .env
76
+ #
77
+ # 2. Configure your OAuth provider (see OAUTH_SETUP.md)
78
+ #
79
+ # 3. Update the values above with your provider's URLs
80
+ #
81
+ # 4. Start the server:
82
+ # npm run dev
83
+ #
84
+ # 5. Configure OAuth in HyperMCP Studio:
85
+ # - Open Studio (http://localhost:3000)
86
+ # - Go to Auth → OAuth 2.1 tab
87
+ # - Click "Discover & Register"
88
+ # - Complete the OAuth flow
89
+ #
90
+ # For detailed setup guides for each provider, see OAUTH_SETUP.md
91
+