@soulbatical/tetra-core 0.1.1 → 0.1.3

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.

Potentially problematic release.


This version of @soulbatical/tetra-core might be problematic. Click here for more details.

@@ -0,0 +1,70 @@
1
+ /**
2
+ * Application Bootstrap — createApp()
3
+ *
4
+ * Standardized Express app creation with security middleware,
5
+ * error handling, and graceful shutdown.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * import { createApp } from '@tetra/core';
10
+ *
11
+ * const { app, start, shutdown } = createApp({
12
+ * projectName: 'my-project',
13
+ * security: {
14
+ * allowedOrigins: ['https://myapp.com'],
15
+ * },
16
+ * initAuth: () => initAuth(),
17
+ * setupRoutes: (app) => {
18
+ * app.use('/api/users', authenticateToken, usersRouter);
19
+ * },
20
+ * });
21
+ *
22
+ * start();
23
+ * ```
24
+ */
25
+ import express, { Express, Request, Response, NextFunction } from 'express';
26
+ import { SecurityConfig } from '../middleware/securityMiddleware.js';
27
+ export interface CreateAppConfig {
28
+ /** Project name for logging */
29
+ projectName: string;
30
+ /** Port (default: process.env.PORT || 3000) */
31
+ port?: number;
32
+ /** Security middleware config */
33
+ security?: SecurityConfig;
34
+ /** Called before routes are set up (for auth init, etc.) */
35
+ initAuth?: () => void;
36
+ /** Mount your routes on the Express app */
37
+ setupRoutes: (app: Express) => void;
38
+ /** Called after server starts listening (for background services) */
39
+ onStarted?: () => Promise<void>;
40
+ /** Called during shutdown (stop background services) */
41
+ onShutdown?: () => Promise<void>;
42
+ /** Trust proxy setting (default: 1 for Railway/Netlify) */
43
+ trustProxy?: number | string | boolean;
44
+ /** Raw body paths (e.g., ['/api/webhooks/stripe'] for Stripe signature verification) */
45
+ rawBodyPaths?: string[];
46
+ /** Body limit (default: '50mb') */
47
+ bodyLimit?: string;
48
+ /** Skip cookie parser (default: false) */
49
+ skipCookieParser?: boolean;
50
+ /** Custom error handler (default: logs + returns 500) */
51
+ errorHandler?: (err: Error, req: Request, res: Response, next: NextFunction) => void;
52
+ }
53
+ export declare function createApp(config: CreateAppConfig): {
54
+ app: import("express-serve-static-core").Express;
55
+ start: () => Promise<void>;
56
+ shutdown: () => Promise<void>;
57
+ security: {
58
+ enforceHTTPS: (req: Request, res: Response, next: NextFunction) => void;
59
+ securityHeaders: (req: import("http").IncomingMessage, res: import("http").ServerResponse, next: (err?: unknown) => void) => void;
60
+ configureCORS: (req: Request, res: Response, next: NextFunction) => express.Response<any, Record<string, any>>;
61
+ generalRateLimiter: import("express-rate-limit").RateLimitRequestHandler;
62
+ strictRateLimiter: import("express-rate-limit").RateLimitRequestHandler;
63
+ publicContentRateLimiter: import("express-rate-limit").RateLimitRequestHandler;
64
+ createRateLimiter: (windowMs?: number, max?: number) => import("express-rate-limit").RateLimitRequestHandler;
65
+ smartRateLimiter: (limiter: any) => (req: Request, res: Response, next: NextFunction) => any;
66
+ limitRequestSize: (req: Request, res: Response, next: NextFunction) => express.Response<any, Record<string, any>>;
67
+ sanitizeInput: (req: Request, res: Response, next: NextFunction) => void;
68
+ };
69
+ };
70
+ //# sourceMappingURL=createApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../../src/core/createApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,EAAqB,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAExF,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,2CAA2C;IAC3C,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACvC,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yDAAyD;IACzD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CACtF;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe;;;;;;6GA4G8oB,CAAC;;;;;;6CAA20B,YAAY,EAAC,aAAc,EAAC,kBAAmB;;;;EADzjD"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Application Bootstrap — createApp()
3
+ *
4
+ * Standardized Express app creation with security middleware,
5
+ * error handling, and graceful shutdown.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * import { createApp } from '@tetra/core';
10
+ *
11
+ * const { app, start, shutdown } = createApp({
12
+ * projectName: 'my-project',
13
+ * security: {
14
+ * allowedOrigins: ['https://myapp.com'],
15
+ * },
16
+ * initAuth: () => initAuth(),
17
+ * setupRoutes: (app) => {
18
+ * app.use('/api/users', authenticateToken, usersRouter);
19
+ * },
20
+ * });
21
+ *
22
+ * start();
23
+ * ```
24
+ */
25
+ import express from 'express';
26
+ import cookieParser from 'cookie-parser';
27
+ import { createLogger } from '../utils/logger.js';
28
+ import { configureSecurity } from '../middleware/securityMiddleware.js';
29
+ export function createApp(config) {
30
+ const logger = createLogger(`system:app:${config.projectName}`);
31
+ const app = express();
32
+ const port = config.port || parseInt(process.env.PORT || '3000', 10);
33
+ // Trust proxy
34
+ app.set('trust proxy', config.trustProxy ?? 1);
35
+ // Security middleware
36
+ const security = configureSecurity({
37
+ bodyLimit: config.bodyLimit || '50mb',
38
+ ...config.security,
39
+ });
40
+ app.use(security.enforceHTTPS);
41
+ app.use(security.securityHeaders);
42
+ app.use(security.configureCORS);
43
+ app.use(security.limitRequestSize);
44
+ app.use(security.sanitizeInput);
45
+ // Raw body for webhook paths (must be before JSON parser)
46
+ if (config.rawBodyPaths) {
47
+ for (const path of config.rawBodyPaths) {
48
+ app.use(path, express.raw({ type: 'application/json' }));
49
+ }
50
+ }
51
+ // JSON + URL-encoded body parser
52
+ const bodyLimit = config.bodyLimit || '50mb';
53
+ app.use(express.json({ limit: bodyLimit }));
54
+ app.use(express.urlencoded({ extended: true, limit: bodyLimit }));
55
+ // Cookie parser
56
+ if (!config.skipCookieParser) {
57
+ app.use(cookieParser());
58
+ }
59
+ // Auth init
60
+ if (config.initAuth) {
61
+ config.initAuth();
62
+ }
63
+ // Health check
64
+ app.get('/api/health', (_req, res) => {
65
+ res.json({ status: 'ok', project: config.projectName });
66
+ });
67
+ // Routes
68
+ config.setupRoutes(app);
69
+ // Error handler
70
+ const errorHandler = config.errorHandler || ((err, _req, res, _next) => {
71
+ logger.error({ error: err }, 'Global error handler triggered');
72
+ res.status(500).json({
73
+ message: 'Internal server error',
74
+ error: process.env.NODE_ENV !== 'production' ? err.message : 'Something went wrong'
75
+ });
76
+ });
77
+ app.use(errorHandler);
78
+ // Server instance
79
+ let server = null;
80
+ const start = async () => {
81
+ server = app.listen(port, () => {
82
+ logger.info({ port, project: config.projectName, env: process.env.NODE_ENV }, 'Server started');
83
+ });
84
+ server.on('error', (error) => {
85
+ if (error.code === 'EADDRINUSE') {
86
+ logger.fatal({ port }, 'Port already in use');
87
+ process.exit(1);
88
+ }
89
+ throw error;
90
+ });
91
+ // Start background services after server is listening
92
+ if (config.onStarted) {
93
+ setImmediate(async () => {
94
+ try {
95
+ await config.onStarted();
96
+ logger.info('Background services started');
97
+ }
98
+ catch (error) {
99
+ logger.error({ error }, 'Error starting background services');
100
+ }
101
+ });
102
+ }
103
+ };
104
+ const shutdown = async () => {
105
+ logger.info('Shutting down');
106
+ if (config.onShutdown) {
107
+ await config.onShutdown();
108
+ }
109
+ if (server) {
110
+ await new Promise((resolve) => {
111
+ server.close(() => resolve());
112
+ });
113
+ }
114
+ logger.info('Shutdown complete');
115
+ };
116
+ // Graceful shutdown handlers
117
+ process.on('SIGTERM', async () => { await shutdown(); process.exit(0); });
118
+ process.on('SIGINT', async () => { await shutdown(); process.exit(0); });
119
+ return { app, start, shutdown, security };
120
+ }
121
+ //# sourceMappingURL=createApp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createApp.js","sourceRoot":"","sources":["../../src/core/createApp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * FeatureForm — Config-driven create/edit form component
3
+ *
4
+ * Replaces ALL per-feature form implementations with a single generic component
5
+ * driven by FeatureConfig.formFields[].
6
+ *
7
+ * Before (200+ lines boilerplate PER feature):
8
+ * <Form onSubmit={handleSubmit}>
9
+ * <Input name="title" label="Title" ... />
10
+ * <Select name="status" options={statusOptions} ... />
11
+ * <Textarea name="description" ... />
12
+ * </Form>
13
+ *
14
+ * After (ZERO boilerplate):
15
+ * <FeatureForm config={ordersConfig} mode="create" onSubmit={handleCreate} />
16
+ *
17
+ * Field type → UI mapping:
18
+ * - text/email/password/url/phone → text input
19
+ * - number/currency/percentage → number input (with prefix/suffix)
20
+ * - textarea → textarea
21
+ * - select/combobox → select dropdown
22
+ * - multiselect → multi-checkbox dropdown
23
+ * - boolean/switch/checkbox → toggle / checkbox
24
+ * - date/datetime → date/datetime input
25
+ * - daterange → two date inputs
26
+ * - color → color input
27
+ * - file/image → file input
28
+ * - hidden → hidden input
29
+ * - richtext → textarea (upgrade to rich editor via customComponents)
30
+ * - custom → custom component from registry
31
+ *
32
+ * @module @tetra/core/frontend
33
+ * Created: February 20, 2026
34
+ */
35
+ import React from 'react';
36
+ import type { FeatureConfig, FormFieldConfig } from '../../shared/types/feature-config.js';
37
+ /** Registry of custom field components */
38
+ export type CustomComponentMap = Record<string, (props: {
39
+ field: FormFieldConfig;
40
+ value: unknown;
41
+ onChange: (value: unknown) => void;
42
+ error?: string;
43
+ disabled?: boolean;
44
+ }) => React.ReactNode>;
45
+ export interface FeatureFormProps<TItem = Record<string, unknown>> {
46
+ /** Feature configuration with formFields[] */
47
+ config: FeatureConfig<TItem>;
48
+ /** Form mode: determines which fields to show and submit label */
49
+ mode: 'create' | 'edit';
50
+ /** Initial values for edit mode (existing record data) */
51
+ defaultValues?: Partial<TItem>;
52
+ /** Submit handler — receives validated form data */
53
+ onSubmit: (data: Record<string, unknown>) => void | Promise<void>;
54
+ /** Cancel handler */
55
+ onCancel?: () => void;
56
+ /** External validation errors (e.g., from API response) */
57
+ errors?: Record<string, string>;
58
+ /** Zod schema for validation (optional — uses config.required as fallback) */
59
+ schema?: {
60
+ parse: (data: unknown) => unknown;
61
+ safeParse: (data: unknown) => {
62
+ success: boolean;
63
+ error?: {
64
+ issues: Array<{
65
+ path: Array<string | number>;
66
+ message: string;
67
+ }>;
68
+ };
69
+ };
70
+ };
71
+ /** Custom field components (keyed by customComponent name) */
72
+ customComponents?: CustomComponentMap;
73
+ /** Submit button label (default: 'Create' / 'Save') */
74
+ submitLabel?: string;
75
+ /** Cancel button label (default: 'Cancel') */
76
+ cancelLabel?: string;
77
+ /** Show cancel button (default: true if onCancel provided) */
78
+ showCancel?: boolean;
79
+ /** Form is submitting (shows loading state) */
80
+ submitting?: boolean;
81
+ /** CSS class for form wrapper */
82
+ className?: string;
83
+ /** Disable all fields (e.g., while submitting) */
84
+ disabled?: boolean;
85
+ /** Layout: single column or two columns (default: auto based on field.width) */
86
+ layout?: 'single' | 'grid';
87
+ }
88
+ /**
89
+ * FeatureForm — Config-driven create/edit form
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * import { ordersConfig } from '@/config/features/orders.config';
94
+ * import { FeatureForm } from '@tetra/core/frontend';
95
+ *
96
+ * function CreateOrderDialog() {
97
+ * return (
98
+ * <FeatureForm
99
+ * config={ordersConfig}
100
+ * mode="create"
101
+ * onSubmit={async (data) => {
102
+ * await createOrder(data);
103
+ * }}
104
+ * onCancel={() => setOpen(false)}
105
+ * />
106
+ * );
107
+ * }
108
+ *
109
+ * function EditOrderDialog({ order }) {
110
+ * return (
111
+ * <FeatureForm
112
+ * config={ordersConfig}
113
+ * mode="edit"
114
+ * defaultValues={order}
115
+ * onSubmit={async (data) => {
116
+ * await updateOrder(order.id, data);
117
+ * }}
118
+ * onCancel={() => setOpen(false)}
119
+ * />
120
+ * );
121
+ * }
122
+ * ```
123
+ */
124
+ export declare function FeatureForm<TItem = Record<string, unknown>>({ config, mode, defaultValues, onSubmit, onCancel, errors: externalErrors, schema, customComponents, submitLabel, cancelLabel, showCancel, submitting, className, disabled: formDisabled, layout, }: FeatureFormProps<TItem>): import("react/jsx-runtime").JSX.Element;
125
+ //# sourceMappingURL=FeatureForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureForm.d.ts","sourceRoot":"","sources":["../../../src/frontend/components/FeatureForm.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAyC,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAmB3F,0CAA0C;AAC1C,MAAM,MAAM,kBAAkB,GAAG,MAAM,CACrC,MAAM,EACN,CAAC,KAAK,EAAE;IACN,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,KAAK,KAAK,CAAC,SAAS,CACtB,CAAC;AAEF,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/D,8CAA8C;IAC9C,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAE7B,kEAAkE;IAClE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAExB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE/B,oDAAoD;IACpD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE,qBAAqB;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,8EAA8E;IAC9E,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;QAAC,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,KAAK,CAAC,EAAE;gBAAE,MAAM,EAAE,KAAK,CAAC;oBAAE,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAA;iBAAE,CAAC,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC;IAEjL,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IAEtC,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,gFAAgF;IAChF,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC5B;AAshBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,WAAW,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC3D,MAAM,EACN,IAAI,EACJ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,MAAM,EAAE,cAAc,EACtB,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,WAAsB,EACtB,UAAU,EACV,UAAkB,EAClB,SAAS,EACT,QAAQ,EAAE,YAAoB,EAC9B,MAAM,GACP,EAAE,gBAAgB,CAAC,KAAK,CAAC,2CAuNzB"}