@ereo/core 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # @ereo/core
2
+
3
+ Core framework package for EreoJS providing the application container, request context, plugin system, caching, environment variables, and type definitions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @ereo/core
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { createApp, defineConfig, definePlugin } from '@ereo/core';
15
+
16
+ // Create application with configuration
17
+ const app = createApp({
18
+ config: defineConfig({
19
+ server: {
20
+ port: 3000,
21
+ hostname: 'localhost',
22
+ },
23
+ }),
24
+ });
25
+
26
+ // Define a custom plugin
27
+ const analyticsPlugin = definePlugin({
28
+ name: 'analytics',
29
+ setup(context) {
30
+ console.log('Analytics initialized in', context.mode, 'mode');
31
+ },
32
+ });
33
+
34
+ // Register the plugin
35
+ app.use(analyticsPlugin);
36
+
37
+ // Start the server
38
+ await app.start();
39
+ ```
40
+
41
+ ## Key Features
42
+
43
+ - **Application Container** - Create and configure EreoJS applications with `createApp` and `defineConfig`
44
+ - **Request Context** - Access request-scoped data with `createContext`, `getContext`, and `attachContext`
45
+ - **Plugin System** - Extend functionality with `definePlugin` and `composePlugins`
46
+ - **Environment Variables** - Type-safe env management with schema builders (`env.string()`, `env.number()`, etc.)
47
+ - **Unified Cache Interface** - Flexible caching with `createCache`, `createTaggedCache`, and tag-based invalidation
48
+ - **Full TypeScript Support** - Comprehensive type definitions for routes, loaders, actions, middleware, and more
49
+
50
+ ## Environment Variables
51
+
52
+ ```typescript
53
+ import { env, setupEnv, typedEnv } from '@ereo/core';
54
+
55
+ // Define environment schema
56
+ const envSchema = {
57
+ DATABASE_URL: env.string().required(),
58
+ PORT: env.port().default(3000),
59
+ DEBUG: env.boolean().default(false),
60
+ NODE_ENV: env.enum(['development', 'production', 'test']).default('development'),
61
+ };
62
+
63
+ // Validate and load environment
64
+ const result = await setupEnv('.', envSchema, 'development');
65
+
66
+ if (result.valid) {
67
+ // Access typed environment variables
68
+ const port = typedEnv.PORT; // number
69
+ }
70
+ ```
71
+
72
+ ## Caching
73
+
74
+ ```typescript
75
+ import { createTaggedCache } from '@ereo/core';
76
+
77
+ const cache = createTaggedCache({ maxSize: 1000 });
78
+
79
+ // Set with tags for grouped invalidation
80
+ await cache.set('user:123', userData, {
81
+ ttl: 3600,
82
+ tags: ['users', 'user:123']
83
+ });
84
+
85
+ // Invalidate all entries with a tag
86
+ await cache.invalidateTag('users');
87
+ ```
88
+
89
+ ## Documentation
90
+
91
+ For full documentation, visit [https://ereojs.dev/docs/core](https://ereojs.dev/docs/core)
92
+
93
+ ## Part of EreoJS
94
+
95
+ This package is part of the [EreoJS](https://github.com/ereojs/ereo) monorepo - a modern full-stack framework built for Bun.
96
+
97
+ ## License
98
+
99
+ MIT
package/dist/app.d.ts ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @ereo/core - Application Container
3
+ *
4
+ * The main application class that ties together routing, plugins,
5
+ * and request handling.
6
+ */
7
+ import type { Application, ApplicationOptions, FrameworkConfig, Plugin, Route, RouteMatch, MiddlewareHandler } from './types';
8
+ import { PluginRegistry } from './plugin';
9
+ /**
10
+ * Create a new EreoJS application.
11
+ */
12
+ export declare function createApp(options?: ApplicationOptions): EreoApp;
13
+ /**
14
+ * Define framework configuration with type safety.
15
+ */
16
+ export declare function defineConfig(config: FrameworkConfig): FrameworkConfig;
17
+ /**
18
+ * The main EreoJS application class.
19
+ */
20
+ export declare class EreoApp implements Application {
21
+ readonly config: FrameworkConfig;
22
+ routes: Route[];
23
+ plugins: Plugin[];
24
+ private pluginRegistry;
25
+ private middlewares;
26
+ private routeMatcher;
27
+ constructor(options?: ApplicationOptions);
28
+ /**
29
+ * Deep merge configuration objects.
30
+ */
31
+ private mergeConfig;
32
+ /**
33
+ * Register a plugin.
34
+ */
35
+ use(plugin: Plugin): this;
36
+ /**
37
+ * Register middleware.
38
+ */
39
+ middleware(handler: MiddlewareHandler): this;
40
+ /**
41
+ * Set the route matcher function.
42
+ * This is typically provided by @ereo/router.
43
+ */
44
+ setRouteMatcher(matcher: (pathname: string) => RouteMatch | null): void;
45
+ /**
46
+ * Set routes directly.
47
+ */
48
+ setRoutes(routes: Route[]): void;
49
+ /**
50
+ * Initialize all plugins.
51
+ */
52
+ private initializePlugins;
53
+ /**
54
+ * Handle an incoming request.
55
+ */
56
+ handle(request: Request): Promise<Response>;
57
+ /**
58
+ * Run middleware chain.
59
+ */
60
+ private runMiddleware;
61
+ /**
62
+ * Handle a route request.
63
+ */
64
+ private handleRoute;
65
+ /**
66
+ * Handle errors.
67
+ */
68
+ private handleError;
69
+ /**
70
+ * Start development server.
71
+ * This is typically called by @ereo/cli.
72
+ */
73
+ dev(): Promise<void>;
74
+ /**
75
+ * Build for production.
76
+ */
77
+ build(): Promise<void>;
78
+ /**
79
+ * Start production server.
80
+ */
81
+ start(): Promise<void>;
82
+ /**
83
+ * Get the plugin registry for advanced usage.
84
+ */
85
+ getPluginRegistry(): PluginRegistry;
86
+ }
87
+ /**
88
+ * Type guard to check if a value is an EreoApp.
89
+ */
90
+ export declare function isEreoApp(value: unknown): value is EreoApp;
91
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,MAAM,EACN,KAAK,EACL,UAAU,EACV,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAsB1C;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAEnE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAErE;AAED;;GAEG;AACH,qBAAa,OAAQ,YAAW,WAAW;IACzC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE,KAAK,EAAE,CAAM;IACrB,OAAO,EAAE,MAAM,EAAE,CAAM;IAEvB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,YAAY,CAA0D;gBAElE,OAAO,GAAE,kBAAuB;IAc5C;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKzB;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAK5C;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI;IAIvE;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;IAIhC;;OAEG;YACW,iBAAiB;IAU/B;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgBjD;;OAEG;YACW,aAAa;IAkB3B;;OAEG;YACW,WAAW;IAgFzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAuBnB;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAS1B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B;;OAEG;IACH,iBAAiB,IAAI,cAAc;CAGpC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * @ereo/core - Unified Cache Interface
3
+ *
4
+ * A unified cache adapter interface for the EreoJS framework.
5
+ * All cache implementations should implement CacheAdapter for interoperability.
6
+ */
7
+ /**
8
+ * Options for cache set operations.
9
+ */
10
+ export interface CacheSetOptions {
11
+ /** Time to live in seconds */
12
+ ttl?: number;
13
+ /** Cache tags for grouped invalidation */
14
+ tags?: string[];
15
+ }
16
+ /**
17
+ * Base cache adapter interface.
18
+ * All cache implementations in EreoJS should implement this interface.
19
+ *
20
+ * @example
21
+ * // Using a cache adapter
22
+ * const cache: CacheAdapter = createCache();
23
+ *
24
+ * await cache.set('user:123', userData, { ttl: 3600, tags: ['users'] });
25
+ * const user = await cache.get<User>('user:123');
26
+ * await cache.delete('user:123');
27
+ */
28
+ export interface CacheAdapter {
29
+ /**
30
+ * Get a value from the cache.
31
+ * @param key - Cache key
32
+ * @returns The cached value, or undefined if not found or expired
33
+ */
34
+ get<T>(key: string): Promise<T | undefined>;
35
+ /**
36
+ * Set a value in the cache.
37
+ * @param key - Cache key
38
+ * @param value - Value to cache
39
+ * @param options - Cache options (ttl, tags)
40
+ */
41
+ set<T>(key: string, value: T, options?: CacheSetOptions): Promise<void>;
42
+ /**
43
+ * Delete a value from the cache.
44
+ * @param key - Cache key
45
+ * @returns true if the key was deleted, false if it didn't exist
46
+ */
47
+ delete(key: string): Promise<boolean>;
48
+ /**
49
+ * Check if a key exists in the cache.
50
+ * @param key - Cache key
51
+ * @returns true if the key exists and is not expired
52
+ */
53
+ has(key: string): Promise<boolean>;
54
+ /**
55
+ * Clear all entries from the cache.
56
+ */
57
+ clear(): Promise<void>;
58
+ }
59
+ /**
60
+ * Extended cache adapter with tag-based invalidation support.
61
+ * Use this interface when you need to invalidate groups of cached items.
62
+ *
63
+ * @example
64
+ * const cache: TaggedCache = createCache({ tagged: true });
65
+ *
66
+ * // Store items with tags
67
+ * await cache.set('post:1', post1, { tags: ['posts', 'user:alice'] });
68
+ * await cache.set('post:2', post2, { tags: ['posts', 'user:bob'] });
69
+ *
70
+ * // Invalidate all posts
71
+ * await cache.invalidateTag('posts');
72
+ *
73
+ * // Invalidate by user
74
+ * await cache.invalidateTags(['user:alice']);
75
+ */
76
+ export interface TaggedCache extends CacheAdapter {
77
+ /**
78
+ * Invalidate all cache entries with a specific tag.
79
+ * @param tag - Tag to invalidate
80
+ */
81
+ invalidateTag(tag: string): Promise<void>;
82
+ /**
83
+ * Invalidate all cache entries with any of the specified tags.
84
+ * @param tags - Array of tags to invalidate
85
+ */
86
+ invalidateTags(tags: string[]): Promise<void>;
87
+ /**
88
+ * Get all cache keys associated with a specific tag.
89
+ * @param tag - Tag to look up
90
+ * @returns Array of cache keys with this tag
91
+ */
92
+ getByTag(tag: string): Promise<string[]>;
93
+ }
94
+ /**
95
+ * Options for creating a cache instance.
96
+ */
97
+ export interface CacheOptions {
98
+ /** Maximum number of entries to store */
99
+ maxSize?: number;
100
+ /** Default TTL for entries in seconds */
101
+ defaultTtl?: number;
102
+ /** Enable tag support */
103
+ tagged?: boolean;
104
+ }
105
+ /**
106
+ * Default in-memory cache implementation.
107
+ * Implements both CacheAdapter and TaggedCache interfaces.
108
+ */
109
+ export declare class MemoryCacheAdapter implements TaggedCache {
110
+ private readonly cache;
111
+ private readonly tagIndex;
112
+ private readonly maxSize;
113
+ private readonly defaultTtl?;
114
+ constructor(options?: CacheOptions);
115
+ get<T>(key: string): Promise<T | undefined>;
116
+ set<T>(key: string, value: T, options?: CacheSetOptions): Promise<void>;
117
+ delete(key: string): Promise<boolean>;
118
+ has(key: string): Promise<boolean>;
119
+ clear(): Promise<void>;
120
+ invalidateTag(tag: string): Promise<void>;
121
+ invalidateTags(tags: string[]): Promise<void>;
122
+ getByTag(tag: string): Promise<string[]>;
123
+ /**
124
+ * Get cache statistics.
125
+ */
126
+ getStats(): {
127
+ size: number;
128
+ tags: number;
129
+ };
130
+ /**
131
+ * Get all keys in the cache.
132
+ */
133
+ keys(): Promise<string[]>;
134
+ /**
135
+ * Check if an entry is expired.
136
+ */
137
+ private isExpired;
138
+ }
139
+ /**
140
+ * Create a new cache instance.
141
+ *
142
+ * @param options - Cache configuration options
143
+ * @returns A CacheAdapter (or TaggedCache if tagged option is true)
144
+ *
145
+ * @example
146
+ * // Simple cache
147
+ * const cache = createCache();
148
+ *
149
+ * // Cache with size limit
150
+ * const limitedCache = createCache({ maxSize: 1000 });
151
+ *
152
+ * // Cache with default TTL
153
+ * const ttlCache = createCache({ defaultTtl: 3600 });
154
+ *
155
+ * // Tagged cache for invalidation
156
+ * const taggedCache = createCache({ tagged: true });
157
+ */
158
+ export declare function createCache(options?: CacheOptions): CacheAdapter;
159
+ /**
160
+ * Create a tagged cache instance with invalidation support.
161
+ *
162
+ * @param options - Cache configuration options
163
+ * @returns A TaggedCache instance
164
+ */
165
+ export declare function createTaggedCache(options?: Omit<CacheOptions, 'tagged'>): TaggedCache;
166
+ /**
167
+ * Check if a cache adapter supports tag operations.
168
+ */
169
+ export declare function isTaggedCache(cache: CacheAdapter): cache is TaggedCache;
170
+ /**
171
+ * Wrap any object with get/set methods to conform to CacheAdapter interface.
172
+ * Useful for adapting existing cache implementations.
173
+ *
174
+ * @param impl - Object with cache-like methods
175
+ * @returns A conformant CacheAdapter
176
+ *
177
+ * @example
178
+ * // Adapt a simple Map-based cache
179
+ * const mapCache = new Map();
180
+ * const adapter = wrapCacheAdapter({
181
+ * get: async (key) => mapCache.get(key),
182
+ * set: async (key, value) => { mapCache.set(key, value); },
183
+ * delete: async (key) => mapCache.delete(key),
184
+ * has: async (key) => mapCache.has(key),
185
+ * clear: async () => mapCache.clear(),
186
+ * });
187
+ */
188
+ export declare function wrapCacheAdapter(impl: {
189
+ get: <T>(key: string) => Promise<T | undefined> | T | undefined;
190
+ set: <T>(key: string, value: T, options?: CacheSetOptions) => Promise<void> | void;
191
+ delete: (key: string) => Promise<boolean> | boolean;
192
+ has: (key: string) => Promise<boolean> | boolean;
193
+ clear: () => Promise<void> | void;
194
+ }): CacheAdapter;
195
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @ereo/core - Request Context
3
+ *
4
+ * Web Standards-based request context that travels through the request lifecycle.
5
+ * Provides cache control, key-value storage, and response header management.
6
+ */
7
+ import type { AppContext, CacheControl } from './types';
8
+ /**
9
+ * Create a new request context for handling a request.
10
+ * Each request gets its own isolated context.
11
+ */
12
+ export declare function createContext(request: Request): RequestContext;
13
+ /**
14
+ * Request-scoped context that provides:
15
+ * - Cache control configuration
16
+ * - Key-value storage for passing data between middleware/loaders
17
+ * - Response headers management
18
+ */
19
+ export declare class RequestContext implements AppContext {
20
+ readonly url: URL;
21
+ readonly env: Record<string, string | undefined>;
22
+ readonly responseHeaders: Headers;
23
+ private store;
24
+ private cacheOptions;
25
+ private cacheTags;
26
+ constructor(request: Request);
27
+ /**
28
+ * Cache control for the current request.
29
+ * Allows setting explicit caching with tags for invalidation.
30
+ */
31
+ readonly cache: CacheControl;
32
+ /**
33
+ * Get a value from the context store.
34
+ * Useful for sharing data between middleware and loaders.
35
+ */
36
+ get<T>(key: string): T | undefined;
37
+ /**
38
+ * Set a value in the context store.
39
+ * Values are scoped to the current request only.
40
+ */
41
+ set<T>(key: string, value: T): void;
42
+ /**
43
+ * Check if a key exists in the context store.
44
+ */
45
+ has(key: string): boolean;
46
+ /**
47
+ * Delete a key from the context store.
48
+ */
49
+ delete(key: string): boolean;
50
+ /**
51
+ * Build Cache-Control header value from options.
52
+ */
53
+ buildCacheControlHeader(): string | null;
54
+ /**
55
+ * Apply cache control and other context headers to a response.
56
+ */
57
+ applyToResponse(response: Response): Response;
58
+ }
59
+ /**
60
+ * Type guard to check if a value is a RequestContext.
61
+ */
62
+ export declare function isRequestContext(value: unknown): value is RequestContext;
63
+ export declare function attachContext(request: Request, context: RequestContext): void;
64
+ export declare function getContext(request: Request): RequestContext | undefined;
65
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAgB,MAAM,SAAS,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAE9D;AAED;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,UAAU;IAC/C,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAElC,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,SAAS,CAAgB;gBAErB,OAAO,EAAE,OAAO;IAM5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,YAAY,CAS1B;IAEF;;;OAGG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIlC;;;OAGG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAInC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B;;OAEG;IACH,uBAAuB,IAAI,MAAM,GAAG,IAAI;IAuBxC;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ;CAyB9C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAExE;AAQD,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAE7E;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAEvE"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @ereo/core - Environment Variable Management
3
+ *
4
+ * Type-safe environment variable handling with validation,
5
+ * .env file loading, and runtime access.
6
+ */
7
+ /** Supported environment variable types */
8
+ export type EnvType = 'string' | 'number' | 'boolean' | 'json' | 'array';
9
+ /** Environment variable schema definition */
10
+ export interface EnvSchema<T = unknown> {
11
+ type: EnvType;
12
+ required?: boolean;
13
+ default?: T;
14
+ description?: string;
15
+ /** Validation function */
16
+ validate?: (value: T) => boolean | string;
17
+ /** Transform function */
18
+ transform?: (value: string) => T;
19
+ /** Mark as public (exposed to client) */
20
+ public?: boolean;
21
+ }
22
+ /** Type-safe schema builder */
23
+ export interface EnvSchemaBuilder<T> {
24
+ /** Mark as required (no default) */
25
+ required(): EnvSchemaBuilder<T>;
26
+ /** Set default value */
27
+ default(value: T): EnvSchemaBuilder<T>;
28
+ /** Add description */
29
+ description(desc: string): EnvSchemaBuilder<T>;
30
+ /** Add validation */
31
+ validate(fn: (value: T) => boolean | string): EnvSchemaBuilder<T>;
32
+ /** Mark as public (exposed to client) */
33
+ public(): EnvSchemaBuilder<T>;
34
+ /** Get the schema definition */
35
+ _schema: EnvSchema<T>;
36
+ }
37
+ /** Parsed environment configuration */
38
+ export interface ParsedEnv {
39
+ [key: string]: string | number | boolean | unknown[] | Record<string, unknown> | null;
40
+ }
41
+ /** Environment validation result */
42
+ export interface EnvValidationResult {
43
+ valid: boolean;
44
+ errors: EnvValidationError[];
45
+ warnings: string[];
46
+ env: ParsedEnv;
47
+ }
48
+ /** Environment validation error */
49
+ export interface EnvValidationError {
50
+ key: string;
51
+ message: string;
52
+ expected?: string;
53
+ received?: string;
54
+ }
55
+ /** Environment config for defineConfig */
56
+ export interface EnvConfig {
57
+ [key: string]: EnvSchemaBuilder<unknown>;
58
+ }
59
+ /**
60
+ * Environment variable schema builders.
61
+ * Use these to define your environment variables in ereo.config.ts.
62
+ *
63
+ * @example
64
+ * import { env } from '@ereo/core';
65
+ *
66
+ * export default defineConfig({
67
+ * env: {
68
+ * DATABASE_URL: env.string().required(),
69
+ * PORT: env.number().default(3000),
70
+ * DEBUG: env.boolean().default(false),
71
+ * ALLOWED_ORIGINS: env.array().default([]),
72
+ * },
73
+ * });
74
+ */
75
+ export declare const env: {
76
+ /** String environment variable */
77
+ string(): EnvSchemaBuilder<string>;
78
+ /** Number environment variable */
79
+ number(): EnvSchemaBuilder<number>;
80
+ /** Boolean environment variable */
81
+ boolean(): EnvSchemaBuilder<boolean>;
82
+ /** JSON environment variable (parses as object) */
83
+ json<T = Record<string, unknown>>(): EnvSchemaBuilder<T>;
84
+ /** Array environment variable (comma-separated) */
85
+ array(): EnvSchemaBuilder<string[]>;
86
+ /** Enum environment variable (restricted values) */
87
+ enum<T extends string>(values: readonly T[]): EnvSchemaBuilder<T>;
88
+ /** URL environment variable */
89
+ url(): EnvSchemaBuilder<string>;
90
+ /** Port environment variable (1-65535) */
91
+ port(): EnvSchemaBuilder<number>;
92
+ };
93
+ /**
94
+ * Parse a .env file content into key-value pairs.
95
+ */
96
+ export declare function parseEnvFile(content: string): Record<string, string>;
97
+ /**
98
+ * Load environment variables from .env files.
99
+ * Priority (highest to lowest):
100
+ * 1. process.env (already set)
101
+ * 2. .env.local (never committed)
102
+ * 3. .env.[mode].local
103
+ * 4. .env.[mode]
104
+ * 5. .env
105
+ */
106
+ export declare function loadEnvFiles(root: string, mode?: 'development' | 'production' | 'test'): Promise<Record<string, string>>;
107
+ /**
108
+ * Validate and parse environment variables against a schema.
109
+ */
110
+ export declare function validateEnv(schema: EnvConfig, rawEnv: Record<string, string | undefined>): EnvValidationResult;
111
+ /**
112
+ * Initialize the environment with validated values.
113
+ * Called during app startup.
114
+ */
115
+ export declare function initializeEnv(validatedEnv: ParsedEnv): void;
116
+ /**
117
+ * Get an environment variable.
118
+ * Returns undefined if not set (and no default).
119
+ */
120
+ export declare function getEnv<T = string>(key: string): T | undefined;
121
+ /**
122
+ * Get an environment variable or throw if not set.
123
+ */
124
+ export declare function requireEnv<T = string>(key: string): T;
125
+ /**
126
+ * Get all environment variables.
127
+ */
128
+ export declare function getAllEnv(): Readonly<ParsedEnv>;
129
+ /**
130
+ * Get public environment variables (safe for client).
131
+ */
132
+ export declare function getPublicEnv(schema: EnvConfig): ParsedEnv;
133
+ /**
134
+ * Complete environment initialization.
135
+ * Loads .env files and validates against schema.
136
+ */
137
+ export declare function setupEnv(root: string, schema: EnvConfig, mode?: 'development' | 'production' | 'test'): Promise<EnvValidationResult>;
138
+ /**
139
+ * Generate TypeScript type definitions for environment variables.
140
+ */
141
+ export declare function generateEnvTypes(schema: EnvConfig): string;
142
+ /**
143
+ * Module augmentation target for environment types.
144
+ * Generated by the CLI during development.
145
+ */
146
+ export interface EnvTypes {
147
+ }
148
+ /**
149
+ * Type-safe environment variable accessor.
150
+ * Use after defining env schema in ereo.config.ts.
151
+ *
152
+ * @example
153
+ * const dbUrl = typedEnv.DATABASE_URL; // TypeScript knows this is string
154
+ */
155
+ export declare const typedEnv: EnvTypes;
156
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @ereo/core
3
+ *
4
+ * Core framework package providing the application container,
5
+ * request context, plugin system, and type definitions.
6
+ */
7
+ export { createApp, defineConfig, EreoApp, isEreoApp } from './app';
8
+ export { createContext, RequestContext, isRequestContext, attachContext, getContext, } from './context';
9
+ export { PluginRegistry, definePlugin, composePlugins, securityHeadersPlugin, isPlugin, } from './plugin';
10
+ export { env, parseEnvFile, loadEnvFiles, validateEnv, initializeEnv, getEnv, requireEnv, getAllEnv, getPublicEnv, setupEnv, generateEnvTypes, typedEnv, } from './env';
11
+ export { MemoryCacheAdapter, createCache, createTaggedCache, isTaggedCache, wrapCacheAdapter, } from './cache';
12
+ export type { CacheAdapter, TaggedCache, CacheSetOptions, CacheOptions as CacheAdapterOptions, } from './cache';
13
+ export type { EnvType, EnvSchema, EnvSchemaBuilder, ParsedEnv, EnvValidationResult, EnvValidationError, EnvConfig, EnvTypes, } from './env';
14
+ export type { BuildTarget, ServerConfig, BuildConfig, FrameworkConfig, MiddlewareReference, RenderMode, PrerenderConfig, StreamingConfig, CSRConfig, RenderConfig, IslandStrategy, IslandsConfig, RouteCacheConfig, ProgressiveConfig, RouteCompositionConfig, AuthConfig, DevConfig, ErrorConfig, RuntimeConfig, RouteVariant, RouteConfig, RouteModuleWithConfig, ParamValidationSchema, SearchParamValidationSchema, ParamValidator, Plugin, PluginContext, DevServer, Route, RouteParams, RouteMatch, RouteModule, RouteHandle, LoaderArgs, ActionArgs, LoaderFunction, ActionFunction, LoaderData, MetaArgs, MetaDescriptor, MetaFunction, HeadersArgs, HeadersFunction, RouteComponentProps, RouteErrorComponentProps,
15
+ /** @deprecated Use RouteErrorComponentProps instead */
16
+ ErrorBoundaryProps, NextFunction, MiddlewareHandler, Middleware, CacheOptions, CacheControl, AppContext, Application, ApplicationOptions, HydrationStrategy, IslandProps, MaybePromise, DeepPartial, InferLoaderData, InferActionData, RouteTypes, RouteTypeDefinition, TypedRoutes, RouteParamsFor, LoaderDataFor, SearchParamsFor, HashParamsFor, ContextFor, ActionDataFor, HandleFor, HasLoader, HasAction, RouteData, } from './types';
17
+ export type { InferParams, HasParams, ParamNames, IsOptionalParam, IsCatchAllParam, BuildPath, ValidateParams, StaticPrefix, IsStaticPath, ParentPath, PathMatches, PossiblePaths, BrandedPath, UnbrandPath, ParsedSegment, ParseSegment, ParsePathSegments, SplitPath, ExtractParams, } from './types/path-parser';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpE,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,UAAU,GACX,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,cAAc,EACd,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,QAAQ,GACT,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,GAAG,EACH,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,MAAM,EACN,UAAU,EACV,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,QAAQ,GACT,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,YAAY,IAAI,mBAAmB,GACpC,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,mBAAmB,EACnB,kBAAkB,EAClB,SAAS,EACT,QAAQ,GACT,MAAM,OAAO,CAAC;AAGf,YAAY,EAEV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,eAAe,EAGf,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,SAAS,EACT,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,cAAc,EAGd,MAAM,EACN,aAAa,EACb,SAAS,EAGT,KAAK,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EAGX,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,UAAU,EAGV,QAAQ,EACR,cAAc,EACd,YAAY,EAGZ,WAAW,EACX,eAAe,EAGf,mBAAmB,EACnB,wBAAwB;AACxB,uDAAuD;AACvD,kBAAkB,EAGlB,YAAY,EACZ,iBAAiB,EACjB,UAAU,EAGV,YAAY,EACZ,YAAY,EAGZ,UAAU,EAGV,WAAW,EACX,kBAAkB,EAGlB,iBAAiB,EACjB,WAAW,EAGX,YAAY,EACZ,WAAW,EACX,eAAe,EACf,eAAe,EAGf,UAAU,EACV,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,aAAa,EACb,eAAe,EACf,aAAa,EACb,UAAU,EACV,aAAa,EACb,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,GACV,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,WAAW,EACX,SAAS,EACT,UAAU,EACV,eAAe,EACf,eAAe,EACf,SAAS,EACT,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,MAAM,qBAAqB,CAAC"}