@objectstack/runtime 0.6.0 → 0.7.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.
@@ -0,0 +1,176 @@
1
+ /**
2
+ * MiddlewareManager
3
+ *
4
+ * Manages middleware registration, ordering, and execution.
5
+ * Provides fine-grained control over middleware chains with:
6
+ * - Execution order management
7
+ * - Path-based filtering
8
+ * - Enable/disable individual middleware
9
+ * - Middleware categorization by type
10
+ *
11
+ * @example
12
+ * const manager = new MiddlewareManager();
13
+ *
14
+ * // Register middleware with configuration
15
+ * manager.register({
16
+ * name: 'auth',
17
+ * type: 'authentication',
18
+ * order: 10,
19
+ * paths: { exclude: ['/health', '/metrics'] }
20
+ * }, authMiddleware);
21
+ *
22
+ * // Get sorted middleware chain
23
+ * const chain = manager.getMiddlewareChain();
24
+ * chain.forEach(mw => server.use(mw));
25
+ */
26
+ export class MiddlewareManager {
27
+ constructor() {
28
+ this.middlewares = new Map();
29
+ }
30
+ /**
31
+ * Register middleware with configuration
32
+ * @param config - Middleware configuration
33
+ * @param middleware - Middleware function
34
+ */
35
+ register(config, middleware) {
36
+ const entry = {
37
+ name: config.name,
38
+ type: config.type,
39
+ middleware,
40
+ order: config.order ?? 100,
41
+ enabled: config.enabled ?? true,
42
+ paths: config.paths,
43
+ };
44
+ this.middlewares.set(config.name, entry);
45
+ }
46
+ /**
47
+ * Unregister middleware by name
48
+ * @param name - Middleware name
49
+ */
50
+ unregister(name) {
51
+ this.middlewares.delete(name);
52
+ }
53
+ /**
54
+ * Enable middleware by name
55
+ * @param name - Middleware name
56
+ */
57
+ enable(name) {
58
+ const entry = this.middlewares.get(name);
59
+ if (entry) {
60
+ entry.enabled = true;
61
+ }
62
+ }
63
+ /**
64
+ * Disable middleware by name
65
+ * @param name - Middleware name
66
+ */
67
+ disable(name) {
68
+ const entry = this.middlewares.get(name);
69
+ if (entry) {
70
+ entry.enabled = false;
71
+ }
72
+ }
73
+ /**
74
+ * Get middleware entry by name
75
+ * @param name - Middleware name
76
+ */
77
+ get(name) {
78
+ return this.middlewares.get(name);
79
+ }
80
+ /**
81
+ * Get all middleware entries
82
+ */
83
+ getAll() {
84
+ return Array.from(this.middlewares.values());
85
+ }
86
+ /**
87
+ * Get middleware by type
88
+ * @param type - Middleware type
89
+ */
90
+ getByType(type) {
91
+ return this.getAll().filter(entry => entry.type === type);
92
+ }
93
+ /**
94
+ * Get middleware chain sorted by order
95
+ * Returns only enabled middleware
96
+ */
97
+ getMiddlewareChain() {
98
+ return this.getAll()
99
+ .filter(entry => entry.enabled)
100
+ .sort((a, b) => a.order - b.order)
101
+ .map(entry => entry.middleware);
102
+ }
103
+ /**
104
+ * Get middleware chain with path filtering
105
+ * @param path - Request path to match against
106
+ */
107
+ getMiddlewareChainForPath(path) {
108
+ return this.getAll()
109
+ .filter(entry => {
110
+ if (!entry.enabled)
111
+ return false;
112
+ // Check path filters
113
+ if (entry.paths) {
114
+ // Check exclude patterns
115
+ if (entry.paths.exclude) {
116
+ const excluded = entry.paths.exclude.some(pattern => this.matchPath(path, pattern));
117
+ if (excluded)
118
+ return false;
119
+ }
120
+ // Check include patterns (if specified)
121
+ if (entry.paths.include) {
122
+ const included = entry.paths.include.some(pattern => this.matchPath(path, pattern));
123
+ if (!included)
124
+ return false;
125
+ }
126
+ }
127
+ return true;
128
+ })
129
+ .sort((a, b) => a.order - b.order)
130
+ .map(entry => entry.middleware);
131
+ }
132
+ /**
133
+ * Match path against pattern (simple glob matching)
134
+ * @param path - Request path
135
+ * @param pattern - Pattern to match (supports * wildcard)
136
+ */
137
+ matchPath(path, pattern) {
138
+ // Convert glob pattern to regex
139
+ const regexPattern = pattern
140
+ .replace(/\*/g, '.*')
141
+ .replace(/\?/g, '.');
142
+ const regex = new RegExp(`^${regexPattern}$`);
143
+ return regex.test(path);
144
+ }
145
+ /**
146
+ * Clear all middleware
147
+ */
148
+ clear() {
149
+ this.middlewares.clear();
150
+ }
151
+ /**
152
+ * Get middleware count
153
+ */
154
+ count() {
155
+ return this.middlewares.size;
156
+ }
157
+ /**
158
+ * Create a composite middleware from the chain
159
+ * This can be used to apply all middleware at once
160
+ */
161
+ createCompositeMiddleware() {
162
+ const chain = this.getMiddlewareChain();
163
+ return async (req, res, next) => {
164
+ let index = 0;
165
+ const executeNext = async () => {
166
+ if (index >= chain.length) {
167
+ await next();
168
+ return;
169
+ }
170
+ const middleware = chain[index++];
171
+ await middleware(req, res, executeNext);
172
+ };
173
+ await executeNext();
174
+ };
175
+ }
176
+ }
@@ -0,0 +1,74 @@
1
+ import { IHttpServer } from '@objectstack/core';
2
+ import { RouteManager } from './route-manager';
3
+ import { RestServerConfig } from '@objectstack/spec/api';
4
+ import { ObjectStackProtocol } from '@objectstack/spec/api';
5
+ /**
6
+ * RestServer
7
+ *
8
+ * Provides automatic REST API endpoint generation for ObjectStack.
9
+ * Generates standard RESTful CRUD endpoints, metadata endpoints, and batch operations
10
+ * based on the configured protocol provider.
11
+ *
12
+ * Features:
13
+ * - Automatic CRUD endpoint generation (GET, POST, PUT, PATCH, DELETE)
14
+ * - Metadata API endpoints (/meta)
15
+ * - Batch operation endpoints (/batch, /createMany, /updateMany, /deleteMany)
16
+ * - Discovery endpoint
17
+ * - Configurable path prefixes and patterns
18
+ *
19
+ * @example
20
+ * const restServer = new RestServer(httpServer, protocolProvider, {
21
+ * api: {
22
+ * version: 'v1',
23
+ * basePath: '/api'
24
+ * },
25
+ * crud: {
26
+ * dataPrefix: '/data'
27
+ * }
28
+ * });
29
+ *
30
+ * restServer.registerRoutes();
31
+ */
32
+ export declare class RestServer {
33
+ private server;
34
+ private protocol;
35
+ private config;
36
+ private routeManager;
37
+ constructor(server: IHttpServer, protocol: ObjectStackProtocol, config?: RestServerConfig);
38
+ /**
39
+ * Normalize configuration with defaults
40
+ */
41
+ private normalizeConfig;
42
+ /**
43
+ * Get the full API base path
44
+ */
45
+ private getApiBasePath;
46
+ /**
47
+ * Register all REST API routes
48
+ */
49
+ registerRoutes(): void;
50
+ /**
51
+ * Register discovery endpoints
52
+ */
53
+ private registerDiscoveryEndpoints;
54
+ /**
55
+ * Register metadata endpoints
56
+ */
57
+ private registerMetadataEndpoints;
58
+ /**
59
+ * Register CRUD endpoints for data operations
60
+ */
61
+ private registerCrudEndpoints;
62
+ /**
63
+ * Register batch operation endpoints
64
+ */
65
+ private registerBatchEndpoints;
66
+ /**
67
+ * Get the route manager
68
+ */
69
+ getRouteManager(): RouteManager;
70
+ /**
71
+ * Get all registered routes
72
+ */
73
+ getRoutes(): import("./route-manager").RouteEntry[];
74
+ }