pulse-js-framework 1.10.4 → 1.11.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 (65) hide show
  1. package/README.md +11 -0
  2. package/cli/build.js +13 -3
  3. package/compiler/directives.js +356 -0
  4. package/compiler/lexer.js +18 -3
  5. package/compiler/parser/core.js +6 -0
  6. package/compiler/parser/view.js +2 -6
  7. package/compiler/preprocessor.js +43 -23
  8. package/compiler/sourcemap.js +3 -1
  9. package/compiler/transformer/actions.js +329 -0
  10. package/compiler/transformer/export.js +7 -0
  11. package/compiler/transformer/expressions.js +85 -33
  12. package/compiler/transformer/imports.js +3 -0
  13. package/compiler/transformer/index.js +2 -0
  14. package/compiler/transformer/store.js +1 -1
  15. package/compiler/transformer/style.js +45 -16
  16. package/compiler/transformer/view.js +23 -2
  17. package/loader/rollup-plugin-server-components.js +391 -0
  18. package/loader/vite-plugin-server-components.js +420 -0
  19. package/loader/webpack-loader-server-components.js +356 -0
  20. package/package.json +124 -82
  21. package/runtime/async.js +4 -0
  22. package/runtime/context.js +16 -3
  23. package/runtime/dom-adapter.js +5 -3
  24. package/runtime/dom-virtual-list.js +2 -1
  25. package/runtime/form.js +8 -3
  26. package/runtime/graphql/cache.js +1 -1
  27. package/runtime/graphql/client.js +22 -0
  28. package/runtime/graphql/hooks.js +12 -6
  29. package/runtime/graphql/subscriptions.js +2 -0
  30. package/runtime/hmr.js +6 -3
  31. package/runtime/http.js +1 -0
  32. package/runtime/i18n.js +2 -0
  33. package/runtime/lru-cache.js +3 -1
  34. package/runtime/native.js +46 -20
  35. package/runtime/pulse.js +3 -0
  36. package/runtime/router/core.js +5 -1
  37. package/runtime/router/index.js +17 -1
  38. package/runtime/router/psc-integration.js +301 -0
  39. package/runtime/security.js +58 -29
  40. package/runtime/server-components/actions-server.js +798 -0
  41. package/runtime/server-components/actions.js +389 -0
  42. package/runtime/server-components/client.js +447 -0
  43. package/runtime/server-components/error-sanitizer.js +438 -0
  44. package/runtime/server-components/index.js +275 -0
  45. package/runtime/server-components/security-csrf.js +593 -0
  46. package/runtime/server-components/security-errors.js +227 -0
  47. package/runtime/server-components/security-ratelimit.js +733 -0
  48. package/runtime/server-components/security-validation.js +467 -0
  49. package/runtime/server-components/security.js +598 -0
  50. package/runtime/server-components/serializer.js +617 -0
  51. package/runtime/server-components/server.js +382 -0
  52. package/runtime/server-components/types.js +383 -0
  53. package/runtime/server-components/utils/mutex.js +60 -0
  54. package/runtime/server-components/utils/path-sanitizer.js +109 -0
  55. package/runtime/ssr.js +2 -1
  56. package/runtime/store.js +19 -10
  57. package/runtime/utils.js +12 -128
  58. package/types/animation.d.ts +300 -0
  59. package/types/i18n.d.ts +283 -0
  60. package/types/persistence.d.ts +267 -0
  61. package/types/sse.d.ts +248 -0
  62. package/types/sw.d.ts +150 -0
  63. package/runtime/a11y.js.original +0 -1844
  64. package/runtime/graphql.js.original +0 -1326
  65. package/runtime/router.js.original +0 -1605
@@ -0,0 +1,438 @@
1
+ /**
2
+ * Pulse Server Components - Error Sanitizer
3
+ *
4
+ * Sanitizes error objects before sending to client to prevent sensitive data leakage.
5
+ *
6
+ * Security Protections:
7
+ * 1. Stack Trace Filtering - Removes internal file paths, function names
8
+ * 2. Message Redaction - Strips secrets, connection strings, env vars
9
+ * 3. Production Mode - Returns minimal safe errors in production
10
+ * 4. Context Filtering - Removes sensitive error context properties
11
+ *
12
+ * @module pulse-js-framework/runtime/server-components/error-sanitizer
13
+ */
14
+
15
+ import { loggers } from '../logger.js';
16
+ import { escapeHtml } from '../security.js';
17
+
18
+ const log = loggers.dom;
19
+
20
+ // ============================================================================
21
+ // Constants - Sensitive Patterns
22
+ // ============================================================================
23
+
24
+ /**
25
+ * Patterns to redact from error messages.
26
+ * Covers secrets, connection strings, file paths, env vars.
27
+ */
28
+ const SENSITIVE_MESSAGE_PATTERNS = [
29
+ // Connection strings
30
+ /postgres:\/\/[^@]+@[^/]+/gi, // PostgreSQL
31
+ /mongodb(\+srv)?:\/\/[^@]+@[^/]+/gi, // MongoDB
32
+ /mysql:\/\/[^@]+@[^/]+/gi, // MySQL
33
+ /redis:\/\/[^@]+@[^/]+/gi, // Redis
34
+
35
+ // API keys and tokens (common formats)
36
+ /[a-zA-Z0-9_-]{20,}/g, // Generic long tokens
37
+
38
+ // Environment variable values (KEY=value patterns)
39
+ /\b[A-Z_]+=[^\s]+/g,
40
+
41
+ // File paths (Unix and Windows)
42
+ /\/[a-zA-Z0-9_\-./]+\.(js|ts|json|env|config)/gi,
43
+ /[A-Z]:\\[^"\s]+\.(js|ts|json|env|config)/gi,
44
+
45
+ // Email addresses
46
+ /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
47
+
48
+ // IP addresses
49
+ /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g
50
+ ];
51
+
52
+ /**
53
+ * Stack trace line patterns to remove entirely.
54
+ * Removes internal framework paths, node_modules, and system paths.
55
+ */
56
+ const STACK_TRACE_FILTER_PATTERNS = [
57
+ /node_modules/, // Dependencies
58
+ /node:internal/, // Node.js internals
59
+ /runtime\/server-components/, // Internal framework paths (keep only public error location)
60
+ /\/Users\/[^/]+/, // User home directories (macOS/Linux)
61
+ /C:\\Users\\[^\\]+/, // User home directories (Windows)
62
+ /<anonymous>/ // Anonymous functions (often internal)
63
+ ];
64
+
65
+ /**
66
+ * Error properties to remove before serialization.
67
+ * These often contain sensitive context or internal state.
68
+ */
69
+ const SENSITIVE_ERROR_PROPERTIES = [
70
+ 'request', // HTTP request object
71
+ 'response', // HTTP response object
72
+ 'config', // Config objects (may contain secrets)
73
+ 'data', // Request/response data
74
+ 'headers', // HTTP headers (may contain auth tokens)
75
+ 'cookies', // Cookies
76
+ 'session', // Session data
77
+ 'locals', // Express locals
78
+ 'params', // Request params
79
+ 'query', // Query strings
80
+ 'body', // Request body
81
+ 'connection', // Database connections
82
+ 'socket', // Network sockets
83
+ 'client', // Client objects
84
+ '_originalError' // Original error chains
85
+ ];
86
+
87
+ // ============================================================================
88
+ // Mode Detection
89
+ // ============================================================================
90
+
91
+ /**
92
+ * Check if running in production mode.
93
+ *
94
+ * @returns {boolean} True if production
95
+ */
96
+ export function isProductionMode() {
97
+ return process.env.NODE_ENV === 'production';
98
+ }
99
+
100
+ /**
101
+ * Check if running in development mode.
102
+ *
103
+ * @returns {boolean} True if development
104
+ */
105
+ export function isDevelopmentMode() {
106
+ return process.env.NODE_ENV === 'development';
107
+ }
108
+
109
+ // ============================================================================
110
+ // Stack Trace Sanitization
111
+ // ============================================================================
112
+
113
+ /**
114
+ * Sanitize a stack trace by removing internal paths and sensitive info.
115
+ *
116
+ * Filters out:
117
+ * - node_modules paths
118
+ * - User home directories
119
+ * - Internal framework paths
120
+ * - Anonymous function traces
121
+ *
122
+ * Preserves:
123
+ * - User application code paths (relative)
124
+ * - Line numbers
125
+ * - Function names (if not anonymous)
126
+ *
127
+ * @param {string} stack - Raw stack trace
128
+ * @returns {string} Sanitized stack trace
129
+ *
130
+ * @example
131
+ * const raw = `Error: Test
132
+ * at /Users/alice/project/app.js:10:5
133
+ * at /Users/alice/project/node_modules/express/lib/router.js:42:12`;
134
+ * const sanitized = sanitizeStackTrace(raw);
135
+ * // Returns: "Error: Test\n at app.js:10:5"
136
+ */
137
+ export function sanitizeStackTrace(stack) {
138
+ if (!stack || typeof stack !== 'string') {
139
+ return '';
140
+ }
141
+
142
+ const lines = stack.split('\n');
143
+ const sanitized = [];
144
+
145
+ for (const line of lines) {
146
+ // Keep error message line (first line)
147
+ if (!line.trim().startsWith('at ')) {
148
+ sanitized.push(line);
149
+ continue;
150
+ }
151
+
152
+ // First, strip absolute paths to relative paths
153
+ let sanitizedLine = line;
154
+
155
+ // Replace absolute paths with relative (Unix)
156
+ sanitizedLine = sanitizedLine.replace(/\/[a-zA-Z0-9_\-./]+\/([a-zA-Z0-9_\-./]+\.(js|ts))/g, '$1');
157
+
158
+ // Replace absolute paths with relative (Windows)
159
+ sanitizedLine = sanitizedLine.replace(/[A-Z]:\\[^"]+\\([a-zA-Z0-9_\-./\\]+\.(js|ts))/g, '$1');
160
+
161
+ // NOW filter out internal/sensitive paths (after path conversion)
162
+ let shouldFilter = false;
163
+ for (const pattern of STACK_TRACE_FILTER_PATTERNS) {
164
+ if (pattern.test(sanitizedLine)) {
165
+ shouldFilter = true;
166
+ break;
167
+ }
168
+ }
169
+
170
+ if (shouldFilter) {
171
+ continue; // Skip this line
172
+ }
173
+
174
+ sanitized.push(sanitizedLine);
175
+ }
176
+
177
+ return sanitized.join('\n');
178
+ }
179
+
180
+ /**
181
+ * Limit stack trace to a maximum number of lines.
182
+ *
183
+ * @param {string} stack - Stack trace
184
+ * @param {number} maxLines - Maximum lines to keep (default: 5)
185
+ * @returns {string} Truncated stack trace
186
+ */
187
+ export function truncateStackTrace(stack, maxLines = 5) {
188
+ if (!stack) {
189
+ return '';
190
+ }
191
+
192
+ const lines = stack.split('\n');
193
+ if (lines.length <= maxLines) {
194
+ return stack;
195
+ }
196
+
197
+ const truncated = lines.slice(0, maxLines);
198
+ truncated.push(` ... (${lines.length - maxLines} more lines)`);
199
+ return truncated.join('\n');
200
+ }
201
+
202
+ // ============================================================================
203
+ // Message Sanitization
204
+ // ============================================================================
205
+
206
+ /**
207
+ * Sanitize an error message by redacting sensitive patterns.
208
+ *
209
+ * Redacts:
210
+ * - Connection strings (postgres://, mongodb://, etc.)
211
+ * - API keys and tokens
212
+ * - File paths
213
+ * - Email addresses
214
+ * - IP addresses
215
+ * - Environment variables
216
+ *
217
+ * @param {string} message - Raw error message
218
+ * @returns {string} Sanitized message
219
+ *
220
+ * @example
221
+ * const raw = 'Connection failed: postgres://user:pass@localhost/db';
222
+ * const sanitized = sanitizeErrorMessage(raw);
223
+ * // Returns: 'Connection failed: [REDACTED]'
224
+ */
225
+ export function sanitizeErrorMessage(message) {
226
+ if (!message || typeof message !== 'string') {
227
+ return '';
228
+ }
229
+
230
+ let sanitized = message;
231
+
232
+ // Replace each sensitive pattern with [REDACTED]
233
+ for (const pattern of SENSITIVE_MESSAGE_PATTERNS) {
234
+ sanitized = sanitized.replace(pattern, '[REDACTED]');
235
+ }
236
+
237
+ return sanitized;
238
+ }
239
+
240
+ // ============================================================================
241
+ // Error Object Sanitization
242
+ // ============================================================================
243
+
244
+ /**
245
+ * Sanitization options.
246
+ *
247
+ * @typedef {Object} SanitizationOptions
248
+ * @property {'production'|'development'|'test'} [mode] - Override mode detection
249
+ * @property {boolean} [includeStack=true] - Include stack trace (sanitized)
250
+ * @property {number} [maxStackLines=5] - Max stack trace lines
251
+ * @property {boolean} [redactMessages=true] - Redact sensitive patterns in messages
252
+ * @property {string[]} [allowedProperties] - Whitelist of error properties to keep
253
+ */
254
+
255
+ /**
256
+ * Sanitize an error object for safe transmission to client.
257
+ *
258
+ * Removes:
259
+ * - Sensitive error properties (request, config, headers, etc.)
260
+ * - Internal stack traces
261
+ * - Secrets from error messages
262
+ *
263
+ * Preserves:
264
+ * - Error type/name
265
+ * - Sanitized message
266
+ * - Sanitized stack (if enabled)
267
+ * - Error code (if present)
268
+ * - Allowed custom properties
269
+ *
270
+ * @param {Error} error - Error object to sanitize
271
+ * @param {SanitizationOptions} [options] - Sanitization options
272
+ * @returns {Object} Sanitized error object (plain object, not Error instance)
273
+ *
274
+ * @example
275
+ * try {
276
+ * await db.connect('postgres://user:secret@localhost/db');
277
+ * } catch (error) {
278
+ * const safe = sanitizeError(error);
279
+ * res.json({ error: safe });
280
+ * }
281
+ * // Client receives: { name: 'Error', message: 'Connection failed: [REDACTED]' }
282
+ */
283
+ export function sanitizeError(error, options = {}) {
284
+ const {
285
+ mode = isProductionMode() ? 'production' : 'development',
286
+ includeStack = mode === 'development',
287
+ maxStackLines = 5,
288
+ redactMessages = true,
289
+ allowedProperties = []
290
+ } = options;
291
+
292
+ // Base safe error
293
+ const safe = {
294
+ name: error.name || 'Error',
295
+ message: redactMessages ? sanitizeErrorMessage(error.message) : error.message
296
+ };
297
+
298
+ // Add error code if present (usually safe)
299
+ if (error.code) {
300
+ safe.code = error.code;
301
+ }
302
+
303
+ // Add stack trace (development only, sanitized)
304
+ if (includeStack && error.stack) {
305
+ let stack = sanitizeStackTrace(error.stack);
306
+ if (maxStackLines > 0) {
307
+ stack = truncateStackTrace(stack, maxStackLines);
308
+ }
309
+ safe.stack = stack;
310
+ }
311
+
312
+ // Add allowed custom properties (whitelist only)
313
+ for (const prop of allowedProperties) {
314
+ if (error[prop] !== undefined && !SENSITIVE_ERROR_PROPERTIES.includes(prop)) {
315
+ safe[prop] = error[prop];
316
+ }
317
+ }
318
+
319
+ // Special handling for Pulse errors (preserve suggestion, context if safe)
320
+ if (error.suggestion && typeof error.suggestion === 'string') {
321
+ safe.suggestion = error.suggestion;
322
+ }
323
+
324
+ if (error.context && typeof error.context === 'string') {
325
+ safe.context = redactMessages ? sanitizeErrorMessage(error.context) : error.context;
326
+ }
327
+
328
+ return safe;
329
+ }
330
+
331
+ /**
332
+ * Create a production-safe error with minimal information.
333
+ *
334
+ * Returns a generic error message without any potentially sensitive details.
335
+ * Use this for critical errors where you want to hide all implementation details.
336
+ *
337
+ * @param {Error} error - Original error
338
+ * @param {string} [genericMessage='An error occurred'] - Generic message
339
+ * @returns {Object} Minimal safe error object
340
+ *
341
+ * @example
342
+ * try {
343
+ * await processPayment(secretKey, card);
344
+ * } catch (error) {
345
+ * const safe = createProductionSafeError(error, 'Payment processing failed');
346
+ * res.status(500).json({ error: safe });
347
+ * }
348
+ * // Client receives: { name: 'Error', message: 'Payment processing failed' }
349
+ */
350
+ export function createProductionSafeError(error, genericMessage = 'An error occurred') {
351
+ // Log original error server-side (for debugging)
352
+ log.error('Production error (details hidden from client):', error);
353
+
354
+ return {
355
+ name: 'Error',
356
+ message: genericMessage
357
+ };
358
+ }
359
+
360
+ /**
361
+ * Sanitize an array of errors (for aggregate errors, validation errors, etc.).
362
+ *
363
+ * @param {Error[]} errors - Array of errors
364
+ * @param {SanitizationOptions} [options] - Sanitization options
365
+ * @returns {Object[]} Array of sanitized errors
366
+ *
367
+ * @example
368
+ * const validationErrors = [
369
+ * new Error('Invalid email'),
370
+ * new Error('Password too short')
371
+ * ];
372
+ * const safe = sanitizeErrors(validationErrors);
373
+ */
374
+ export function sanitizeErrors(errors, options = {}) {
375
+ if (!Array.isArray(errors)) {
376
+ return [];
377
+ }
378
+
379
+ return errors.map(error => sanitizeError(error, options));
380
+ }
381
+
382
+ // ============================================================================
383
+ // Validation Error Sanitization
384
+ // ============================================================================
385
+
386
+ // escapeHtml imported from ../security.js (single source of truth)
387
+
388
+ /**
389
+ * Sanitize validation errors specifically.
390
+ * Validation errors are usually safe, but may contain user input that needs XSS sanitization.
391
+ *
392
+ * @param {Object} validationErrors - Validation errors object (key: fieldName, value: error)
393
+ * @returns {Object} Sanitized validation errors
394
+ *
395
+ * @example
396
+ * const errors = {
397
+ * email: 'Invalid email: <script>alert(1)</script>',
398
+ * password: 'Too short'
399
+ * };
400
+ * const safe = sanitizeValidationErrors(errors);
401
+ * // { email: 'Invalid email: &lt;script&gt;alert(1)&lt;/script&gt;', password: 'Too short' }
402
+ */
403
+ export function sanitizeValidationErrors(validationErrors) {
404
+ if (!validationErrors || typeof validationErrors !== 'object') {
405
+ return {};
406
+ }
407
+
408
+ const sanitized = {};
409
+
410
+ for (const [field, error] of Object.entries(validationErrors)) {
411
+ if (typeof error === 'string') {
412
+ // Escape HTML/XSS first, then redact sensitive patterns
413
+ sanitized[field] = sanitizeErrorMessage(escapeHtml(error));
414
+ } else if (error instanceof Error) {
415
+ sanitized[field] = sanitizeError(error, { includeStack: false }).message;
416
+ } else {
417
+ sanitized[field] = String(error);
418
+ }
419
+ }
420
+
421
+ return sanitized;
422
+ }
423
+
424
+ // ============================================================================
425
+ // Exports
426
+ // ============================================================================
427
+
428
+ export default {
429
+ sanitizeError,
430
+ sanitizeErrors,
431
+ sanitizeStackTrace,
432
+ truncateStackTrace,
433
+ sanitizeErrorMessage,
434
+ sanitizeValidationErrors,
435
+ createProductionSafeError,
436
+ isProductionMode,
437
+ isDevelopmentMode
438
+ };
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Pulse Server Components (PSC)
3
+ *
4
+ * Main entry point for Server Components functionality.
5
+ * Re-exports all public APIs from submodules.
6
+ *
7
+ * @module pulse-js-framework/runtime/server-components
8
+ *
9
+ * @example
10
+ * // Server-side
11
+ * import { serializeToPSC, renderServerComponent } from 'pulse-js-framework/runtime/server-components';
12
+ *
13
+ * const node = await renderServerComponent(MyComponent, props);
14
+ * const payload = serializeToPSC(node, { clientManifest });
15
+ *
16
+ * @example
17
+ * // Client-side
18
+ * import { reconstructPSCTree, loadClientComponent } from 'pulse-js-framework/runtime/server-components';
19
+ *
20
+ * const payload = await fetch('/api/component').then(r => r.json());
21
+ * const domTree = await reconstructPSCTree(payload);
22
+ */
23
+
24
+ // ============================================================================
25
+ // Type Definitions & Constants
26
+ // ============================================================================
27
+
28
+ export {
29
+ // Type guards
30
+ isPSCElement,
31
+ isPSCText,
32
+ isPSCClientBoundary,
33
+ isPSCFragment,
34
+ isPSCComment,
35
+ // Validation
36
+ validatePSCPayload,
37
+ validatePSCNode,
38
+ // Constants
39
+ PSCNodeType,
40
+ PSC_VERSION
41
+ } from './types.js';
42
+
43
+ // ============================================================================
44
+ // Serialization (Server-Side)
45
+ // ============================================================================
46
+
47
+ export {
48
+ // Core serialization
49
+ serializeNode,
50
+ serializeToPSC,
51
+ // Client boundary detection
52
+ isClientBoundary,
53
+ markClientBoundary,
54
+ // Constants
55
+ CLIENT_BOUNDARY_ATTR,
56
+ CLIENT_PROPS_ATTR
57
+ } from './serializer.js';
58
+
59
+ // ============================================================================
60
+ // Reconstruction (Client-Side)
61
+ // ============================================================================
62
+
63
+ export {
64
+ // Core reconstruction
65
+ reconstructNode,
66
+ reconstructPSCTree,
67
+ // Client component loading
68
+ loadClientComponent,
69
+ preloadClientComponent,
70
+ // Hydration
71
+ hydrateClientComponents,
72
+ // Cache management
73
+ clearComponentCache,
74
+ getComponentCacheStats
75
+ } from './client.js';
76
+
77
+ // ============================================================================
78
+ // Server Rendering Helpers
79
+ // ============================================================================
80
+
81
+ export {
82
+ // Component rendering
83
+ renderServerComponent,
84
+ executeAsyncComponent,
85
+ // Boundary detection
86
+ markClientBoundaries,
87
+ // SSR integration
88
+ renderServerComponentToHTML,
89
+ // Component registry
90
+ componentRegistry,
91
+ createComponentRegistry
92
+ } from './server.js';
93
+
94
+ // ============================================================================
95
+ // Server Actions (RPC Mechanism)
96
+ // ============================================================================
97
+
98
+ export {
99
+ // Client-side actions
100
+ registerAction,
101
+ createActionInvoker,
102
+ useServerAction,
103
+ bindFormAction,
104
+ getActionConfig,
105
+ clearActionRegistry
106
+ } from './actions.js';
107
+
108
+ export {
109
+ // Server-side actions
110
+ registerServerAction,
111
+ executeServerAction,
112
+ getServerActions,
113
+ clearServerActions,
114
+ // Middleware
115
+ createServerActionMiddleware,
116
+ createFastifyActionPlugin,
117
+ createHonoActionMiddleware,
118
+ // CSRF helpers
119
+ generateCSRFTokenForResponse,
120
+ getGlobalCSRFStore,
121
+ setCSRFStore
122
+ } from './actions-server.js';
123
+
124
+ // ============================================================================
125
+ // Security (Prop Validation & Error Sanitization)
126
+ // ============================================================================
127
+
128
+ export {
129
+ // Secret detection
130
+ detectSecrets,
131
+ // XSS sanitization
132
+ sanitizePropsForXSS,
133
+ // Size validation
134
+ validatePropSizeLimits,
135
+ PROP_SIZE_LIMITS,
136
+ // Main validator
137
+ validatePropSecurity
138
+ } from './security.js';
139
+
140
+ export {
141
+ // Serialization validation (NEW)
142
+ detectNonSerializable,
143
+ detectEnvironmentVariables,
144
+ validatePropSerialization
145
+ } from './security-validation.js';
146
+
147
+ export {
148
+ // Security error classes
149
+ PSCSecurityError,
150
+ PSCSerializationError,
151
+ PSCEnvVarError,
152
+ PSCCSRFError,
153
+ PSCRateLimitError
154
+ } from './security-errors.js';
155
+
156
+ export {
157
+ // Error sanitization
158
+ sanitizeError,
159
+ sanitizeErrors,
160
+ sanitizeStackTrace,
161
+ truncateStackTrace,
162
+ sanitizeErrorMessage,
163
+ sanitizeValidationErrors,
164
+ createProductionSafeError,
165
+ // Mode detection
166
+ isProductionMode,
167
+ isDevelopmentMode
168
+ } from './error-sanitizer.js';
169
+
170
+ // ============================================================================
171
+ // CSRF Protection
172
+ // ============================================================================
173
+
174
+ export {
175
+ // CSRF token management
176
+ CSRFTokenStore,
177
+ generateCSRFToken,
178
+ validateCSRFToken,
179
+ createCSRFMiddleware
180
+ } from './security-csrf.js';
181
+
182
+ // ============================================================================
183
+ // Rate Limiting
184
+ // ============================================================================
185
+
186
+ export {
187
+ // Rate limiter
188
+ RateLimiter,
189
+ RateLimitStore,
190
+ MemoryRateLimitStore,
191
+ RedisRateLimitStore,
192
+ createRateLimitMiddleware
193
+ } from './security-ratelimit.js';
194
+
195
+ // ============================================================================
196
+ // Default Export (import everything first for bundle)
197
+ // ============================================================================
198
+
199
+ import * as types from './types.js';
200
+ import * as serializer from './serializer.js';
201
+ import * as client from './client.js';
202
+ import * as server from './server.js';
203
+ import * as actions from './actions.js';
204
+ import * as actionsServer from './actions-server.js';
205
+ import * as security from './security.js';
206
+ import * as securityValidation from './security-validation.js';
207
+ import * as securityErrors from './security-errors.js';
208
+ import * as errorSanitizer from './error-sanitizer.js';
209
+ import * as csrf from './security-csrf.js';
210
+ import * as ratelimit from './security-ratelimit.js';
211
+
212
+ export default {
213
+ // Types
214
+ PSCNodeType: types.PSCNodeType,
215
+ PSC_VERSION: types.PSC_VERSION,
216
+ // Serialization
217
+ serializeNode: serializer.serializeNode,
218
+ serializeToPSC: serializer.serializeToPSC,
219
+ isClientBoundary: serializer.isClientBoundary,
220
+ markClientBoundary: serializer.markClientBoundary,
221
+ // Reconstruction
222
+ reconstructNode: client.reconstructNode,
223
+ reconstructPSCTree: client.reconstructPSCTree,
224
+ loadClientComponent: client.loadClientComponent,
225
+ preloadClientComponent: client.preloadClientComponent,
226
+ hydrateClientComponents: client.hydrateClientComponents,
227
+ // Server
228
+ renderServerComponent: server.renderServerComponent,
229
+ executeAsyncComponent: server.executeAsyncComponent,
230
+ markClientBoundaries: server.markClientBoundaries,
231
+ renderServerComponentToHTML: server.renderServerComponentToHTML,
232
+ componentRegistry: server.componentRegistry,
233
+ createComponentRegistry: server.createComponentRegistry,
234
+ // Actions (client)
235
+ registerAction: actions.registerAction,
236
+ createActionInvoker: actions.createActionInvoker,
237
+ useServerAction: actions.useServerAction,
238
+ bindFormAction: actions.bindFormAction,
239
+ // Actions (server)
240
+ registerServerAction: actionsServer.registerServerAction,
241
+ executeServerAction: actionsServer.executeServerAction,
242
+ createServerActionMiddleware: actionsServer.createServerActionMiddleware,
243
+ generateCSRFTokenForResponse: actionsServer.generateCSRFTokenForResponse,
244
+ getGlobalCSRFStore: actionsServer.getGlobalCSRFStore,
245
+ setCSRFStore: actionsServer.setCSRFStore,
246
+ // Security
247
+ validatePropSecurity: security.validatePropSecurity,
248
+ detectSecrets: security.detectSecrets,
249
+ sanitizePropsForXSS: security.sanitizePropsForXSS,
250
+ // Serialization validation
251
+ detectNonSerializable: securityValidation.detectNonSerializable,
252
+ detectEnvironmentVariables: securityValidation.detectEnvironmentVariables,
253
+ validatePropSerialization: securityValidation.validatePropSerialization,
254
+ // Security errors
255
+ PSCSecurityError: securityErrors.PSCSecurityError,
256
+ PSCSerializationError: securityErrors.PSCSerializationError,
257
+ PSCEnvVarError: securityErrors.PSCEnvVarError,
258
+ PSCCSRFError: securityErrors.PSCCSRFError,
259
+ PSCRateLimitError: securityErrors.PSCRateLimitError,
260
+ // CSRF protection
261
+ CSRFTokenStore: csrf.CSRFTokenStore,
262
+ generateCSRFToken: csrf.generateCSRFToken,
263
+ validateCSRFToken: csrf.validateCSRFToken,
264
+ createCSRFMiddleware: csrf.createCSRFMiddleware,
265
+ // Rate limiting
266
+ RateLimiter: ratelimit.RateLimiter,
267
+ RateLimitStore: ratelimit.RateLimitStore,
268
+ MemoryRateLimitStore: ratelimit.MemoryRateLimitStore,
269
+ RedisRateLimitStore: ratelimit.RedisRateLimitStore,
270
+ createRateLimitMiddleware: ratelimit.createRateLimitMiddleware,
271
+ // Error sanitization
272
+ sanitizeError: errorSanitizer.sanitizeError,
273
+ sanitizeStackTrace: errorSanitizer.sanitizeStackTrace,
274
+ sanitizeErrorMessage: errorSanitizer.sanitizeErrorMessage
275
+ };