@owlmeans/api-config-client 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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 OwlMeans Common — Fullstack typescript framework
3
+ Copyright (c) 2026 OwlMeans Common — Fullstack typescript framework
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,48 +1,22 @@
1
1
  # @owlmeans/api-config-client
2
2
 
3
- The **@owlmeans/api-config-client** package provides client-side functionality for fetching and applying API configuration from OwlMeans Common Libraries servers, designed for fullstack microservices and microclients development with focus on security and proper authentication and authorization.
3
+ Client-side middleware that fetches server config from `GET /assets/config.json` and merges it into the client context.
4
4
 
5
- ## Purpose
5
+ ## Overview
6
6
 
7
- This package serves as the client-side component of the OwlMeans configuration system that:
7
+ - `apiConfigMiddleware` — context middleware that calls the config endpoint on startup
8
+ - Elevates `@owlmeans/api-config` modules into the client module system
9
+ - Merges the server `ApiConfig` into the client's `CommonConfig` at initialization time
8
10
 
9
- - **Fetches configuration from servers** using the API config module system
10
- - **Applies configuration dynamically** to client contexts during initialization
11
- - **Integrates with client modules** for seamless API communication
12
- - **Supports multi-service architecture** with configurable primary hosts
13
- - **Provides middleware integration** for automatic configuration loading
11
+ ## Installation
14
12
 
15
- ## Core Concepts
16
-
17
- ### API Configuration Module
18
- The package elevates the common API config module to a client module, enabling it to make HTTP requests to fetch configuration from servers.
19
-
20
- ### Configuration Middleware
21
- Provides middleware that automatically fetches and merges server configuration during client context initialization, ensuring the client has the latest configuration before becoming operational.
22
-
23
- ### Primary Host Configuration
24
- Supports configuration of primary hosts and ports for API communication, allowing clients to know where to fetch their configuration from.
25
-
26
- ## API Reference
27
-
28
- ### Modules
29
-
30
- #### `modules`
31
-
32
- Exported client modules array containing the elevated API config module.
33
-
34
- ```typescript
35
- import { modules } from '@owlmeans/api-config-client'
36
-
37
- // Register all client API config modules
38
- context.registerModules(modules)
13
+ ```bash
14
+ bun add @owlmeans/api-config-client
39
15
  ```
40
16
 
41
- ### Middleware
17
+ ## Usage
42
18
 
43
- #### `apiConfigMiddleware`
44
-
45
- Middleware that fetches configuration from the API config endpoint during context loading.
19
+ Register the middleware in your client context setup:
46
20
 
47
21
  ```typescript
48
22
  import { apiConfigMiddleware } from '@owlmeans/api-config-client'
@@ -50,264 +24,15 @@ import { apiConfigMiddleware } from '@owlmeans/api-config-client'
50
24
  context.registerMiddleware(apiConfigMiddleware)
51
25
  ```
52
26
 
53
- **Properties:**
54
- - `type`: `MiddlewareType.Context`
55
- - `stage`: `MiddlewareStage.Loading`
56
-
57
- **Behavior:**
58
- - Executes during the Loading stage of context initialization
59
- - Checks if `primaryHost` is configured in the client config
60
- - Fetches configuration from the API config module endpoint
61
- - Merges received configuration with the existing client configuration
62
- - Handles errors gracefully by logging them without breaking initialization
63
-
64
- ### Dependencies
65
-
66
- The package depends on several OwlMeans Common packages:
67
- - `@owlmeans/api-config` - Common API config module definitions
68
- - `@owlmeans/client-context` - Client-side context management
69
- - `@owlmeans/client-module` - Client-side module system
70
- - `@owlmeans/context` - Core context functionality
71
-
72
- ## Usage Examples
73
-
74
- ### Basic Integration
75
-
76
- ```typescript
77
- import { makeClientContext, makeClientConfig } from '@owlmeans/client-context'
78
- import { modules, apiConfigMiddleware } from '@owlmeans/api-config-client'
79
- import { AppType } from '@owlmeans/context'
80
-
81
- // Create client configuration with primary host
82
- const config = makeClientConfig(AppType.Frontend, 'web-client', {
83
- primaryHost: 'api.myapp.com',
84
- primaryPort: 443
85
- })
86
-
87
- // Create and configure context
88
- const context = makeClientContext(config)
89
-
90
- // Register API config middleware
91
- context.registerMiddleware(apiConfigMiddleware)
92
-
93
- // Register API config modules
94
- context.registerModules(modules)
95
-
96
- // Configure and initialize - configuration will be fetched automatically
97
- context.configure()
98
- await context.init()
99
-
100
- // Context now has merged configuration from server
101
- console.log('Final config:', await context.config)
102
- ```
103
-
104
- ### Manual Configuration Fetching
105
-
106
- ```typescript
107
- import { modules } from '@owlmeans/api-config-client'
108
- import { API_CONFIG } from '@owlmeans/api-config'
109
-
110
- // Get the API config module
111
- const configModule = context.module(API_CONFIG)
112
-
113
- // Manually fetch configuration
114
- try {
115
- const [serverConfig] = await configModule.call()
116
- console.log('Server configuration:', serverConfig)
117
- } catch (error) {
118
- console.error('Failed to fetch configuration:', error)
119
- }
120
- ```
121
-
122
- ### Advanced Configuration
123
-
124
- ```typescript
125
- import { makeClientContext, makeClientConfig } from '@owlmeans/client-context'
126
- import { modules, apiConfigMiddleware } from '@owlmeans/api-config-client'
127
- import { AppType } from '@owlmeans/context'
128
-
129
- const config = makeClientConfig(AppType.Frontend, 'mobile-client', {
130
- primaryHost: 'api.example.com',
131
- primaryPort: 8080,
132
- // Additional client configuration
133
- debug: { all: true },
134
- services: {
135
- 'user-service': {
136
- host: 'users.example.com',
137
- port: 8081
138
- }
139
- }
140
- })
141
-
142
- const context = makeClientContext(config)
143
-
144
- // Register middleware first
145
- context.registerMiddleware(apiConfigMiddleware)
146
-
147
- // Register modules
148
- context.registerModules(modules)
149
-
150
- // Add custom middleware to run after config is loaded
151
- context.registerMiddleware({
152
- type: MiddlewareType.Context,
153
- stage: MiddlewareStage.Ready,
154
- apply: async (ctx) => {
155
- console.log('Configuration loaded and merged')
156
- const finalConfig = await ctx.config
157
- console.log('Available services:', Object.keys(finalConfig.services || {}))
158
- }
159
- })
160
-
161
- await context.configure().init()
162
- ```
163
-
164
- ### Error Handling
165
-
166
- ```typescript
167
- import { modules, apiConfigMiddleware } from '@owlmeans/api-config-client'
168
-
169
- // The middleware handles errors gracefully
170
- context.registerMiddleware(apiConfigMiddleware)
171
-
172
- // You can also add custom error handling
173
- context.registerMiddleware({
174
- type: MiddlewareType.Context,
175
- stage: MiddlewareStage.Loading,
176
- apply: async (ctx) => {
177
- const clientCtx = ctx as ClientContext
178
- if (clientCtx.cfg.primaryHost) {
179
- try {
180
- const configModule = clientCtx.module(API_CONFIG)
181
- const [config] = await configModule.call()
182
- console.log('Successfully fetched config')
183
- } catch (error) {
184
- console.warn('Config fetch failed, using defaults:', error.message)
185
- // Implement fallback configuration logic
186
- }
187
- }
188
- }
189
- })
190
- ```
191
-
192
- ### Multiple Service Configuration
193
-
194
- ```typescript
195
- // Client can fetch configuration that includes multiple service endpoints
196
- const config = makeClientConfig(AppType.Frontend, 'dashboard-client', {
197
- primaryHost: 'config.myapp.com'
198
- })
199
-
200
- const context = makeClientContext(config)
201
- context.registerMiddleware(apiConfigMiddleware)
202
- context.registerModules(modules)
203
-
204
- await context.configure().init()
205
-
206
- // After initialization, context will have configuration for all services
207
- const finalConfig = await context.config
208
- console.log('Auth service:', finalConfig.services?.auth)
209
- console.log('User service:', finalConfig.services?.users)
210
- console.log('Payment service:', finalConfig.services?.payments)
211
- ```
212
-
213
- ## Integration Patterns
214
-
215
- ### With React Applications
216
-
217
- ```typescript
218
- import React from 'react'
219
- import { ClientContext } from '@owlmeans/client-context'
220
- import { modules, apiConfigMiddleware } from '@owlmeans/api-config-client'
221
-
222
- const initializeApp = async () => {
223
- const config = makeClientConfig(AppType.Frontend, 'react-app', {
224
- primaryHost: process.env.REACT_APP_API_HOST
225
- })
226
-
227
- const context = makeClientContext(config)
228
- context.registerMiddleware(apiConfigMiddleware)
229
- context.registerModules(modules)
230
-
231
- await context.configure().init()
232
- return context
233
- }
234
-
235
- const App: React.FC = () => {
236
- const [context, setContext] = useState<ClientContext | null>(null)
237
-
238
- useEffect(() => {
239
- initializeApp().then(setContext)
240
- }, [])
241
-
242
- if (!context) return <div>Loading configuration...</div>
243
-
244
- return (
245
- <ClientContext.Provider value={context}>
246
- {/* Your app components */}
247
- </ClientContext.Provider>
248
- )
249
- }
250
- ```
251
-
252
- ### With Service Workers
253
-
254
- ```typescript
255
- // In service worker or background process
256
- import { modules, apiConfigMiddleware } from '@owlmeans/api-config-client'
257
-
258
- const setupBackgroundSync = async () => {
259
- const config = makeClientConfig(AppType.Frontend, 'sw-client', {
260
- primaryHost: self.registration.scope + 'api'
261
- })
262
-
263
- const context = makeClientContext(config)
264
- context.registerMiddleware(apiConfigMiddleware)
265
- context.registerModules(modules)
266
-
267
- await context.configure().init()
268
-
269
- // Now context has all service configurations for background operations
270
- return context
271
- }
272
- ```
273
-
274
- ## Configuration Flow
275
-
276
- 1. **Context Creation** - Create client context with `primaryHost` configuration
277
- 2. **Middleware Registration** - Register `apiConfigMiddleware` to handle automatic config fetching
278
- 3. **Module Registration** - Register API config modules for communication
279
- 4. **Context Initialization** - During `init()`, middleware fetches server configuration
280
- 5. **Configuration Merge** - Server configuration is merged with local client configuration
281
- 6. **Ready State** - Context becomes ready with complete configuration
282
-
283
- ## Error Handling
284
-
285
- The package handles various error scenarios:
286
-
287
- - **Network failures** - Logged but don't prevent initialization
288
- - **Invalid responses** - Gracefully handled with fallback to existing configuration
289
- - **Missing primary host** - Middleware skips execution if no primary host configured
290
- - **Module call failures** - Errors are caught and logged without breaking the initialization flow
291
-
292
- ## Best Practices
27
+ On initialization, the middleware calls the `API_CONFIG` module and merges the response into the context config.
293
28
 
294
- 1. **Set primary host early** - Configure `primaryHost` in your client configuration
295
- 2. **Register middleware first** - Ensure middleware is registered before modules
296
- 3. **Handle initialization** - Always await context initialization before use
297
- 4. **Monitor errors** - Log and monitor configuration fetch failures
298
- 5. **Implement fallbacks** - Have default configurations ready for offline scenarios
299
- 6. **Secure communication** - Use HTTPS for production API config endpoints
29
+ ## API
300
30
 
301
- ## Security Considerations
31
+ ### `apiConfigMiddleware: Middleware`
302
32
 
303
- - **Validate endpoints** - Ensure primary host is a trusted server
304
- - **Handle secrets carefully** - Configuration may contain sensitive service information
305
- - **Monitor traffic** - Log configuration requests for security auditing
306
- - **Use authentication** - Combine with auth modules for secured configuration access
33
+ A context initialization middleware. Calls `API_CONFIG` module, receives `ApiConfig`, and applies it to the context via `mergeConfig`.
307
34
 
308
35
  ## Related Packages
309
36
 
310
- - [`@owlmeans/api-config`](../api-config) - Common API config module definitions
311
- - [`@owlmeans/api-config-server`](../api-config-server) - Server-side API config implementation
312
- - [`@owlmeans/client-context`](../client-context) - Client-side context management
313
- - [`@owlmeans/client-module`](../client-module) - Client-side module system
37
+ - [`@owlmeans/api-config`](../api-config) — `API_CONFIG` alias and `ApiConfig` type
38
+ - [`@owlmeans/api-config-server`](../api-config-server) — server that serves the config endpoint
@@ -6,7 +6,7 @@ export const apiConfigMiddleware = {
6
6
  stage: MiddlewareStage.Loading,
7
7
  apply: async (ctx) => {
8
8
  const context = assertContext(ctx, 'api-config-middleware');
9
- const module = context.module(API_CONFIG);
9
+ const module = context.entrypoint(API_CONFIG);
10
10
  if (context.cfg.primaryHost != null) {
11
11
  module.route.route.host = context.cfg.primaryHost;
12
12
  if (context.cfg.primaryPort != null) {
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAGlF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAI9C,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,IAAI,EAAE,cAAc,CAAC,OAAO;IAC5B,KAAK,EAAE,eAAe,CAAC,OAAO;IAC9B,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,aAAa,CAC3B,GAAU,EAAE,uBAAuB,CACpC,CAAA;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAA0B,UAAU,CAAC,CAAA;QAClE,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YACjD,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;gBACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YACnD,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;gBACpC,MAAM,MAAM,GAAiB,OAAO,CAAC,GAA8B,CAAA;gBACnE,WAAW,CAAC,MAAM,EAAE,MAAsB,CAAC,CAAA;YAC7C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAClB,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAGlF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAI9C,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,IAAI,EAAE,cAAc,CAAC,OAAO;IAC5B,KAAK,EAAE,eAAe,CAAC,OAAO;IAC9B,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,aAAa,CAC3B,GAAU,EAAE,uBAAuB,CACpC,CAAA;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAA8B,UAAU,CAAC,CAAA;QAC1E,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YACjD,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;gBACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YACnD,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;gBACpC,MAAM,MAAM,GAAiB,OAAO,CAAC,GAA8B,CAAA;gBACnE,WAAW,CAAC,MAAM,EAAE,MAAsB,CAAC,CAAA;YAC7C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAClB,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAA"}
@@ -1,2 +1,2 @@
1
- export declare const modules: import("@owlmeans/module").CommonModule[];
1
+ export declare const modules: import("@owlmeans/entrypoint").CommonEntrypoint[];
2
2
  //# sourceMappingURL=modules.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,OAAO,2CAAS,CAAA"}
1
+ {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,OAAO,mDAAS,CAAA"}
package/build/modules.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { modules as config, API_CONFIG } from '@owlmeans/api-config';
2
- import { elevate } from '@owlmeans/client-module';
2
+ import { elevate } from '@owlmeans/client-entrypoint';
3
3
  elevate(config, API_CONFIG);
4
4
  export const modules = config;
5
5
  //# sourceMappingURL=modules.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"modules.js","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAEjD,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAE3B,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAA"}
1
+ {"version":3,"file":"modules.js","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAErD,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAE3B,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@owlmeans/api-config-client",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
+ "license": "MIT",
4
5
  "type": "module",
5
6
  "scripts": {
6
7
  "build": "tsc -b",
@@ -20,14 +21,15 @@
20
21
  }
21
22
  },
22
23
  "dependencies": {
23
- "@owlmeans/api-config": "^0.1.1",
24
- "@owlmeans/client-context": "^0.1.1",
25
- "@owlmeans/client-module": "^0.1.1",
26
- "@owlmeans/context": "^0.1.1"
24
+ "@owlmeans/api-config": "^0.1.3",
25
+ "@owlmeans/client-context": "^0.1.3",
26
+ "@owlmeans/client-entrypoint": "^0.1.3",
27
+ "@owlmeans/context": "^0.1.3"
27
28
  },
28
29
  "devDependencies": {
30
+ "@owlmeans/dep-config": "workspace:*",
29
31
  "nodemon": "^3.1.11",
30
- "typescript": "^5.8.3"
32
+ "typescript": "^6.0.2"
31
33
  },
32
34
  "publishConfig": {
33
35
  "access": "public"
package/src/middleware.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Middleware } from '@owlmeans/context'
2
2
  import { MiddlewareType, MiddlewareStage, assertContext } from '@owlmeans/context'
3
- import type { ClientModule } from '@owlmeans/client-module'
3
+ import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
4
4
  import type { ApiConfig } from '@owlmeans/api-config'
5
5
  import { API_CONFIG } from '@owlmeans/api-config'
6
6
  import { mergeConfig } from '@owlmeans/config'
@@ -14,7 +14,7 @@ export const apiConfigMiddleware: Middleware = {
14
14
  const context = assertContext<ClientConfig, ClientContext<ClientConfig>>(
15
15
  ctx as any, 'api-config-middleware'
16
16
  )
17
- const module = context.module<ClientModule<ApiConfig>>(API_CONFIG)
17
+ const module = context.entrypoint<ClientEntrypoint<ApiConfig>>(API_CONFIG)
18
18
  if (context.cfg.primaryHost != null) {
19
19
  module.route.route.host = context.cfg.primaryHost
20
20
  if (context.cfg.primaryPort != null) {
package/src/modules.ts CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  import { modules as config, API_CONFIG } from '@owlmeans/api-config'
3
- import { elevate } from '@owlmeans/client-module'
3
+ import { elevate } from '@owlmeans/client-entrypoint'
4
4
 
5
5
  elevate(config, API_CONFIG)
6
6
 
package/tsconfig.json CHANGED
@@ -1,14 +1,10 @@
1
1
  {
2
2
  "extends": [
3
- "../tsconfig.default.json"
3
+ "@owlmeans/dep-config/tsconfig.base.json"
4
4
  ],
5
5
  "compilerOptions": {
6
- "rootDir": "./src/", /* Specify the root folder within your source files. */
7
- "outDir": "./build/", /* Specify an output folder for all emitted files. */
6
+ "rootDir": "./src/",
7
+ "outDir": "./build/"
8
8
  },
9
- "exclude": [
10
- "./dist/**/*",
11
- "./build/**/*",
12
- "./*.ts"
13
- ]
14
- }
9
+ "exclude": ["./dist/**/*", "./build/**/*", "./*.ts"]
10
+ }