@open-mercato/shared 0.6.6-develop.6460.1.f94c74174c → 0.6.6-develop.6471.1.9ab5bdd79a

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 (164) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +1 -0
  3. package/dist/lib/commands/command-bus.js +4 -2
  4. package/dist/lib/commands/command-bus.js.map +2 -2
  5. package/dist/lib/commands/command-interceptor-runner.js +4 -2
  6. package/dist/lib/commands/command-interceptor-runner.js.map +2 -2
  7. package/dist/lib/commands/flush.js +3 -4
  8. package/dist/lib/commands/flush.js.map +2 -2
  9. package/dist/lib/commands/helpers.js +3 -1
  10. package/dist/lib/commands/helpers.js.map +2 -2
  11. package/dist/lib/commands/registry.js +5 -3
  12. package/dist/lib/commands/registry.js.map +2 -2
  13. package/dist/lib/commands/scope.js +5 -3
  14. package/dist/lib/commands/scope.js.map +2 -2
  15. package/dist/lib/crud/advanced-filter-integration.js +3 -1
  16. package/dist/lib/crud/advanced-filter-integration.js.map +2 -2
  17. package/dist/lib/crud/cache.js +3 -1
  18. package/dist/lib/crud/cache.js.map +2 -2
  19. package/dist/lib/crud/custom-fields.js +4 -2
  20. package/dist/lib/crud/custom-fields.js.map +2 -2
  21. package/dist/lib/crud/enricher-runner.js +6 -10
  22. package/dist/lib/crud/enricher-runner.js.map +2 -2
  23. package/dist/lib/crud/factory.js +10 -8
  24. package/dist/lib/crud/factory.js.map +2 -2
  25. package/dist/lib/crud/interceptor-registry.js +3 -3
  26. package/dist/lib/crud/interceptor-registry.js.map +2 -2
  27. package/dist/lib/crud/mutation-guard.js +4 -2
  28. package/dist/lib/crud/mutation-guard.js.map +2 -2
  29. package/dist/lib/crud/optimistic-lock.js +5 -6
  30. package/dist/lib/crud/optimistic-lock.js.map +2 -2
  31. package/dist/lib/crud/route-mutation-guard.js +3 -1
  32. package/dist/lib/crud/route-mutation-guard.js.map +2 -2
  33. package/dist/lib/crud/sync-event-runner.js +3 -1
  34. package/dist/lib/crud/sync-event-runner.js.map +2 -2
  35. package/dist/lib/data/engine.js +5 -5
  36. package/dist/lib/data/engine.js.map +2 -2
  37. package/dist/lib/db/mikro.js +5 -3
  38. package/dist/lib/db/mikro.js.map +2 -2
  39. package/dist/lib/di/container.js +3 -1
  40. package/dist/lib/di/container.js.map +2 -2
  41. package/dist/lib/encryption/aes.js +3 -1
  42. package/dist/lib/encryption/aes.js.map +2 -2
  43. package/dist/lib/encryption/entityFields.js +3 -1
  44. package/dist/lib/encryption/entityFields.js.map +2 -2
  45. package/dist/lib/encryption/entityIds.js +3 -1
  46. package/dist/lib/encryption/entityIds.js.map +2 -2
  47. package/dist/lib/encryption/kms.js +25 -32
  48. package/dist/lib/encryption/kms.js.map +2 -2
  49. package/dist/lib/encryption/subscriber.js +3 -1
  50. package/dist/lib/encryption/subscriber.js.map +2 -2
  51. package/dist/lib/encryption/tenantDataEncryptionService.js +3 -1
  52. package/dist/lib/encryption/tenantDataEncryptionService.js.map +2 -2
  53. package/dist/lib/indexers/error-log.js +4 -2
  54. package/dist/lib/indexers/error-log.js.map +2 -2
  55. package/dist/lib/indexers/status-log.js +5 -3
  56. package/dist/lib/indexers/status-log.js.map +2 -2
  57. package/dist/lib/logger/index.js +28 -0
  58. package/dist/lib/logger/index.js.map +7 -0
  59. package/dist/lib/logger/level.js +43 -0
  60. package/dist/lib/logger/level.js.map +7 -0
  61. package/dist/lib/logger/transport.console.js +39 -0
  62. package/dist/lib/logger/transport.console.js.map +7 -0
  63. package/dist/lib/logger/transport.js +17 -0
  64. package/dist/lib/logger/transport.js.map +7 -0
  65. package/dist/lib/logger/transport.pretty.js +85 -0
  66. package/dist/lib/logger/transport.pretty.js.map +7 -0
  67. package/dist/lib/logger/transport.server.js +85 -0
  68. package/dist/lib/logger/transport.server.js.map +7 -0
  69. package/dist/lib/middleware/page-executor.js +3 -1
  70. package/dist/lib/middleware/page-executor.js.map +2 -2
  71. package/dist/lib/modules/registry.js +3 -1
  72. package/dist/lib/modules/registry.js.map +2 -2
  73. package/dist/lib/profiler/index.js +3 -2
  74. package/dist/lib/profiler/index.js.map +2 -2
  75. package/dist/lib/query/engine.js +5 -6
  76. package/dist/lib/query/engine.js.map +2 -2
  77. package/dist/lib/query/query-extension-runner.js +5 -11
  78. package/dist/lib/query/query-extension-runner.js.map +2 -2
  79. package/dist/lib/redis/connection.js +3 -1
  80. package/dist/lib/redis/connection.js.map +2 -2
  81. package/dist/lib/url.js +7 -5
  82. package/dist/lib/url.js.map +2 -2
  83. package/dist/lib/version.js +1 -1
  84. package/dist/lib/version.js.map +1 -1
  85. package/dist/modules/analytics.js +3 -1
  86. package/dist/modules/analytics.js.map +2 -2
  87. package/dist/modules/dashboard/widgets.js +3 -1
  88. package/dist/modules/dashboard/widgets.js.map +2 -2
  89. package/dist/modules/events/factory.js +5 -3
  90. package/dist/modules/events/factory.js.map +2 -2
  91. package/dist/modules/overrides.js +16 -34
  92. package/dist/modules/overrides.js.map +2 -2
  93. package/dist/modules/registry.js +3 -1
  94. package/dist/modules/registry.js.map +2 -2
  95. package/dist/modules/search.js +3 -1
  96. package/dist/modules/search.js.map +2 -2
  97. package/dist/modules/widgets/injection-loader.js +6 -6
  98. package/dist/modules/widgets/injection-loader.js.map +2 -2
  99. package/dist/modules/widgets/injection-position.js +3 -1
  100. package/dist/modules/widgets/injection-position.js.map +2 -2
  101. package/package.json +7 -2
  102. package/src/lib/commands/__tests__/command-interceptor-runner.test.ts +19 -6
  103. package/src/lib/commands/__tests__/flush.test.ts +24 -15
  104. package/src/lib/commands/__tests__/normalizeAuthorUserId.test.ts +14 -2
  105. package/src/lib/commands/__tests__/registry.test.ts +17 -2
  106. package/src/lib/commands/__tests__/scope.test.ts +21 -9
  107. package/src/lib/commands/command-bus.ts +5 -2
  108. package/src/lib/commands/command-interceptor-runner.ts +5 -2
  109. package/src/lib/commands/flush.ts +4 -5
  110. package/src/lib/commands/helpers.ts +9 -2
  111. package/src/lib/commands/registry.ts +6 -3
  112. package/src/lib/commands/scope.ts +6 -3
  113. package/src/lib/crud/__tests__/optimistic-lock.test.ts +21 -6
  114. package/src/lib/crud/__tests__/route-mutation-guard.test.ts +17 -2
  115. package/src/lib/crud/__tests__/sync-event-runner.test.ts +17 -3
  116. package/src/lib/crud/advanced-filter-integration.ts +4 -1
  117. package/src/lib/crud/cache.ts +4 -1
  118. package/src/lib/crud/custom-fields.ts +5 -2
  119. package/src/lib/crud/enricher-runner.ts +7 -10
  120. package/src/lib/crud/factory.ts +11 -10
  121. package/src/lib/crud/interceptor-registry.ts +4 -3
  122. package/src/lib/crud/mutation-guard.ts +5 -2
  123. package/src/lib/crud/optimistic-lock.ts +6 -10
  124. package/src/lib/crud/route-mutation-guard.ts +4 -1
  125. package/src/lib/crud/sync-event-runner.ts +4 -1
  126. package/src/lib/data/__tests__/engine.event-validation.test.ts +26 -15
  127. package/src/lib/data/engine.ts +6 -6
  128. package/src/lib/db/mikro.ts +6 -3
  129. package/src/lib/di/container.ts +4 -1
  130. package/src/lib/encryption/aes.ts +4 -2
  131. package/src/lib/encryption/entityFields.ts +5 -1
  132. package/src/lib/encryption/entityIds.ts +4 -1
  133. package/src/lib/encryption/kms.ts +27 -33
  134. package/src/lib/encryption/subscriber.ts +4 -2
  135. package/src/lib/encryption/tenantDataEncryptionService.ts +4 -2
  136. package/src/lib/indexers/__tests__/status-log.test.ts +22 -10
  137. package/src/lib/indexers/error-log.ts +5 -2
  138. package/src/lib/indexers/status-log.ts +6 -3
  139. package/src/lib/logger/__tests__/logger.test.ts +539 -0
  140. package/src/lib/logger/index.ts +33 -0
  141. package/src/lib/logger/level.ts +50 -0
  142. package/src/lib/logger/transport.console.ts +41 -0
  143. package/src/lib/logger/transport.pretty.ts +94 -0
  144. package/src/lib/logger/transport.server.ts +125 -0
  145. package/src/lib/logger/transport.ts +17 -0
  146. package/src/lib/middleware/page-executor.ts +4 -1
  147. package/src/lib/modules/__tests__/registry.test.ts +28 -21
  148. package/src/lib/modules/registry.ts +4 -1
  149. package/src/lib/profiler/index.ts +4 -2
  150. package/src/lib/query/__tests__/query-extension-runner.test.ts +21 -7
  151. package/src/lib/query/engine.ts +7 -10
  152. package/src/lib/query/query-extension-runner.ts +6 -11
  153. package/src/lib/redis/connection.ts +5 -1
  154. package/src/lib/url.ts +10 -5
  155. package/src/modules/__tests__/overrides.test.ts +17 -3
  156. package/src/modules/__tests__/route-overrides.test.ts +29 -20
  157. package/src/modules/analytics.ts +5 -1
  158. package/src/modules/dashboard/widgets.ts +4 -1
  159. package/src/modules/events/factory.ts +6 -3
  160. package/src/modules/overrides.ts +18 -34
  161. package/src/modules/registry.ts +4 -1
  162. package/src/modules/search.ts +4 -1
  163. package/src/modules/widgets/injection-loader.ts +7 -6
  164. package/src/modules/widgets/injection-position.ts +5 -1
@@ -26,7 +26,22 @@ import {
26
26
  resetModuleContractOverridesForTests,
27
27
  type ApiRouteOverridesMap,
28
28
  } from '../overrides'
29
+ import { createLogger } from '@open-mercato/shared/lib/logger'
30
+
31
+ jest.mock('@open-mercato/shared/lib/logger', () => {
32
+ const mocked = {
33
+ debug: jest.fn(),
34
+ info: jest.fn(),
35
+ warn: jest.fn(),
36
+ error: jest.fn(),
37
+ child: jest.fn(),
38
+ }
39
+ mocked.child.mockImplementation(() => mocked)
40
+ return { createLogger: jest.fn(() => mocked) }
41
+ })
42
+ const loggerWarn = createLogger('shared').warn as jest.Mock
29
43
  import {
44
+
30
45
  getApiRouteManifests,
31
46
  getBackendRouteManifests,
32
47
  getFrontendRouteManifests,
@@ -165,20 +180,19 @@ describe('applyApiOverridesToManifests', () => {
165
180
  })
166
181
 
167
182
  it('warns when an override key does not match any manifest entry', () => {
168
- const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
183
+ loggerWarn.mockClear()
169
184
  applyApiOverridesToManifests([makeEntry('a', '/api/foo', ['GET'])], {
170
185
  'GET /api/missing': null,
171
186
  })
172
- const staleCalls = warnSpy.mock.calls.filter((args) =>
187
+ const staleCalls = loggerWarn.mock.calls.filter((args) =>
173
188
  typeof args[0] === 'string' && args[0].includes('did not match any registered API route'),
174
189
  )
175
190
  expect(staleCalls).toHaveLength(1)
176
- expect(staleCalls[0][0]).toContain('GET /api/missing')
177
- warnSpy.mockRestore()
191
+ expect(staleCalls[0][1]).toEqual(expect.objectContaining({ key: 'GET /api/missing' }))
178
192
  })
179
193
 
180
194
  it('skips malformed override values (not null and not a definition)', () => {
181
- const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
195
+ loggerWarn.mockClear()
182
196
  const entries = [makeEntry('a', '/api/foo', ['GET'])]
183
197
  const result = applyApiOverridesToManifests(entries, {
184
198
  // @ts-expect-error intentionally malformed
@@ -186,8 +200,7 @@ describe('applyApiOverridesToManifests', () => {
186
200
  })
187
201
  expect(result).toHaveLength(1)
188
202
  expect(result[0].methods).toEqual(['GET'])
189
- expect(warnSpy).toHaveBeenCalled()
190
- warnSpy.mockRestore()
203
+ expect(loggerWarn).toHaveBeenCalled()
191
204
  })
192
205
  })
193
206
 
@@ -203,17 +216,16 @@ describe('applyApiRouteOverrides (programmatic)', () => {
203
216
  })
204
217
 
205
218
  it('warns on malformed keys and skips them', () => {
206
- const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
219
+ loggerWarn.mockClear()
207
220
  applyApiRouteOverrides({
208
221
  'NOT_A_METHOD /api/foo': null,
209
222
  'GET': null,
210
223
  '': null,
211
224
  })
212
225
  expect(Object.keys(composeApiRouteOverrides())).toHaveLength(0)
213
- expect(warnSpy.mock.calls.filter((c) =>
226
+ expect(loggerWarn.mock.calls.filter((c) =>
214
227
  typeof c[0] === 'string' && c[0].includes('malformed routes.api key'),
215
228
  )).toHaveLength(3)
216
- warnSpy.mockRestore()
217
229
  })
218
230
 
219
231
  it('supersedes modules.ts inline overrides for the same key', () => {
@@ -231,23 +243,22 @@ describe('applyApiRouteOverrides (programmatic)', () => {
231
243
 
232
244
  describe('dispatcher → routes applier', () => {
233
245
  it('routes `overrides.routes.api` to the wired applier without the "not yet wired" warning', () => {
234
- const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
246
+ loggerWarn.mockClear()
235
247
  applyModuleOverridesFromEnabledModules([
236
248
  {
237
249
  id: 'app',
238
250
  overrides: { routes: { api: { 'GET /api/foo': null } } },
239
251
  },
240
252
  ])
241
- const unwiredCalls = warnSpy.mock.calls.filter((args) =>
242
- typeof args[0] === 'string' && args[0].includes('Domain "routes" not yet wired'),
253
+ const unwiredCalls = loggerWarn.mock.calls.filter((args) =>
254
+ typeof args[0] === 'string' && args[0].includes('not yet wired') && args[1]?.domain === 'routes',
243
255
  )
244
256
  expect(unwiredCalls).toHaveLength(0)
245
257
  expect(composeApiRouteOverrides()['GET /api/foo']).toBeNull()
246
- warnSpy.mockRestore()
247
258
  })
248
259
 
249
260
  it('routes `overrides.routes.pages` to the page override composer', () => {
250
- const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
261
+ loggerWarn.mockClear()
251
262
  applyModuleOverridesFromEnabledModules([
252
263
  {
253
264
  id: 'first',
@@ -271,7 +282,7 @@ describe('dispatcher → routes applier', () => {
271
282
  },
272
283
  },
273
284
  ])
274
- const unwiredCalls = warnSpy.mock.calls.filter((args) =>
285
+ const unwiredCalls = loggerWarn.mock.calls.filter((args) =>
275
286
  typeof args[0] === 'string' && args[0].includes('not yet wired'),
276
287
  )
277
288
  expect(unwiredCalls).toHaveLength(0)
@@ -280,7 +291,6 @@ describe('dispatcher → routes applier', () => {
280
291
  'backend:/backend/bar': null,
281
292
  'frontend:/store': { metadata: { title: 'Store Override' } },
282
293
  })
283
- warnSpy.mockRestore()
284
294
  })
285
295
 
286
296
  it('preserves module load order when multiple entries override the same key (last wins)', () => {
@@ -301,7 +311,7 @@ describe('dispatcher → routes applier', () => {
301
311
  })
302
312
 
303
313
  it('ignores malformed sub-keys but still processes well-formed ones', () => {
304
- const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
314
+ loggerWarn.mockClear()
305
315
  const handler = makeHandler('ok')
306
316
  applyModuleOverridesFromEnabledModules([
307
317
  {
@@ -317,10 +327,9 @@ describe('dispatcher → routes applier', () => {
317
327
  },
318
328
  ])
319
329
  expect(composeApiRouteOverrides()['GET /api/ok']).toEqual({ handler })
320
- expect(warnSpy.mock.calls.filter((c) =>
330
+ expect(loggerWarn.mock.calls.filter((c) =>
321
331
  typeof c[0] === 'string' && c[0].includes('malformed routes.api key'),
322
332
  )).toHaveLength(1)
323
- warnSpy.mockRestore()
324
333
  })
325
334
  })
326
335
 
@@ -1,3 +1,7 @@
1
+ import { createLogger } from '../lib/logger'
2
+
3
+ const logger = createLogger('shared').child({ component: 'analytics-registry' })
4
+
1
5
  export type AggregateFunction = 'count' | 'sum' | 'avg' | 'min' | 'max'
2
6
 
3
7
  export type DateGranularity = 'day' | 'week' | 'month' | 'quarter' | 'year'
@@ -38,7 +42,7 @@ let _analyticsModuleConfigs: AnalyticsModuleConfig[] | null = null
38
42
 
39
43
  export function registerAnalyticsModuleConfigs(configs: AnalyticsModuleConfig[]): void {
40
44
  if (_analyticsModuleConfigs !== null && process.env.NODE_ENV === 'development') {
41
- console.debug('[Bootstrap] Analytics module configs re-registered (this may occur during HMR)')
45
+ logger.debug('Analytics module configs re-registered (this may occur during HMR)')
42
46
  }
43
47
  _analyticsModuleConfigs = configs
44
48
  }
@@ -1,4 +1,7 @@
1
1
  import React, { type ComponentType } from 'react'
2
+ import { createLogger } from '../../lib/logger'
3
+
4
+ const logger = createLogger('dashboard').child({ component: 'widgets' })
2
5
 
3
6
  export type DashboardWidgetSize = 'sm' | 'md' | 'lg'
4
7
 
@@ -94,7 +97,7 @@ export function lazyDashboardWidget<TSettings>(
94
97
  .catch((err) => {
95
98
  if (!cancelled) {
96
99
  try {
97
- console.error('Failed to load dashboard widget component', err)
100
+ logger.error('Failed to load dashboard widget component', { err })
98
101
  } catch {}
99
102
  setTick((value) => value + 1)
100
103
  }
@@ -4,6 +4,7 @@
4
4
  * Provides factory functions for creating type-safe event configurations.
5
5
  */
6
6
 
7
+ import { createLogger } from '../../lib/logger'
7
8
  import type {
8
9
  EventDefinition,
9
10
  EventModuleConfig,
@@ -13,6 +14,8 @@ import type {
13
14
  ModuleEventEmitter,
14
15
  } from './types'
15
16
 
17
+ const logger = createLogger('events').child({ component: 'factory' })
18
+
16
19
  // =============================================================================
17
20
  // Global Event Bus Reference
18
21
  // =============================================================================
@@ -130,7 +133,7 @@ let _registeredEventConfigs: EventModuleConfig[] | null = null
130
133
  */
131
134
  export function registerEventModuleConfigs(configs: EventModuleConfig[]): void {
132
135
  if (_registeredEventConfigs !== null && process.env.NODE_ENV === 'development') {
133
- console.debug('[Bootstrap] Event module configs re-registered (this may occur during HMR)')
136
+ logger.debug('Event module configs re-registered (this may occur during HMR)')
134
137
  }
135
138
  _registeredEventConfigs = configs
136
139
  for (const config of configs) {
@@ -224,7 +227,7 @@ export function createModuleEvents<
224
227
  if (strict) {
225
228
  throw new Error(message)
226
229
  } else {
227
- console.error(message)
230
+ logger.error('Module tried to emit undeclared event — add it to the module events.ts first', { moduleId, eventId })
228
231
  // In non-strict mode, still emit but with warning
229
232
  }
230
233
  }
@@ -232,7 +235,7 @@ export function createModuleEvents<
232
235
  // Get event bus from global reference
233
236
  const eventBus = getGlobalEventBus()
234
237
  if (!eventBus) {
235
- console.warn(`[events] Event bus not available, cannot emit "${eventId}"`)
238
+ logger.warn('Event bus not available, cannot emit event', { eventId })
236
239
  return
237
240
  }
238
241
 
@@ -59,6 +59,7 @@ export interface AiOverridesShape {
59
59
  extensions?: unknown[]
60
60
  }
61
61
 
62
+
62
63
  type LooseOverrideMap = Record<string, unknown>
63
64
 
64
65
  /**
@@ -270,9 +271,7 @@ export function applyModuleOverridesFromEnabledModules(
270
271
  if (!warnedUnwiredDomains.has(domain)) {
271
272
  warnedUnwiredDomains.add(domain)
272
273
  const moduleIds = Array.from(new Set(entries.map((e) => e.moduleId))).join(', ')
273
- console.warn(
274
- `[Module Overrides] Domain "${domain}" not yet wired — entry.overrides.${domain} for module(s) [${moduleIds}] was ignored. ${TRACKING_ISSUE_HINT}`,
275
- )
274
+ logger.warn('Override domain not yet wired — entry ignored', { domain, moduleIds, hint: TRACKING_ISSUE_HINT })
276
275
  }
277
276
  continue
278
277
  }
@@ -330,6 +329,7 @@ import type {
330
329
  ModuleSubscriber,
331
330
  ModuleWorker,
332
331
  } from './registry'
332
+ import { createLogger } from '../lib/logger'
333
333
  import type { ModuleInjectionTable } from './widgets/injection'
334
334
  import type { ComponentOverride } from './widgets/component-registry'
335
335
  import type { NotificationHandler } from './notifications/handler'
@@ -341,6 +341,8 @@ import type { ResponseEnricher } from '../lib/crud/response-enricher'
341
341
  import type { CommandInterceptor } from '../lib/commands/command-interceptor'
342
342
  import type { PageMiddlewareRegistryEntry, PageRouteMiddleware } from './middleware/page'
343
343
 
344
+ const logger = createLogger('shared').child({ component: 'module-overrides' })
345
+
344
346
  /** Override for a single API route entry: replace handler/metadata, or `null` to disable. */
345
347
  export interface ApiRouteOverrideDefinition {
346
348
  /** Replacement handler. Same signature as the original API route handler. */
@@ -443,7 +445,7 @@ function normalizeIdOverrideKey(key: string, label: string): string | null {
443
445
  if (typeof key !== 'string') return null
444
446
  const trimmed = key.trim()
445
447
  if (trimmed) return trimmed
446
- console.warn(`[Module Overrides] Skipping malformed ${label} key "${key}" — expected a non-empty string.`)
448
+ logger.warn('Skipping malformed override key — expected a non-empty string', { label, key })
447
449
  return null
448
450
  }
449
451
 
@@ -514,17 +516,13 @@ function applyArrayOverrides<T>(
514
516
  const replacement = overrides[id]
515
517
  if (replacement === null) continue
516
518
  if (options.isReplacement && !options.isReplacement(replacement)) {
517
- console.warn(
518
- `[Module Overrides] Skipping malformed ${options.label} override for "${id}" — replacement has the wrong shape.`,
519
- )
519
+ logger.warn('Skipping malformed override — replacement has the wrong shape', { label: options.label, id })
520
520
  result.push(item)
521
521
  continue
522
522
  }
523
523
  const replacementId = options.getId(replacement)
524
524
  if (replacementId !== id) {
525
- console.warn(
526
- `[Module Overrides] Skipping malformed ${options.label} override for "${id}" — replacement id must match the override key.`,
527
- )
525
+ logger.warn('Skipping malformed override — replacement id must match the override key', { label: options.label, id })
528
526
  result.push(item)
529
527
  continue
530
528
  }
@@ -537,7 +535,7 @@ function applyArrayOverrides<T>(
537
535
  function warnStaleOverrides(label: string, overrides: Readonly<Record<string, unknown>>, consumed: ReadonlySet<string>): void {
538
536
  for (const key of Object.keys(overrides)) {
539
537
  if (!consumed.has(key)) {
540
- console.warn(`[Module Overrides] ${label} override "${key}" did not match any registered entry — override skipped.`)
538
+ logger.warn('Override did not match any registered entry — override skipped', { label, key })
541
539
  }
542
540
  }
543
541
  }
@@ -686,9 +684,7 @@ export function applyApiRouteOverrides(overrides: ApiRouteOverridesMap): void {
686
684
  for (const [rawKey, value] of Object.entries(overrides)) {
687
685
  const key = normalizeApiRouteOverrideKey(rawKey)
688
686
  if (!key) {
689
- console.warn(
690
- `[Module Overrides] Skipping malformed routes.api key "${rawKey}" — expected "METHOD /api/path".`,
691
- )
687
+ logger.warn('Skipping malformed routes.api key — expected "METHOD /api/path"', { key: rawKey })
692
688
  continue
693
689
  }
694
690
  programmaticApiRouteOverrides[key] = value
@@ -929,9 +925,7 @@ export function applyApiOverridesToManifests<T extends ApiRouteManifestEntry>(
929
925
  methodOverrides.set(method, value)
930
926
  remainingMethods.push(method)
931
927
  } else {
932
- console.warn(
933
- `[Module Overrides] Skipping malformed routes.api override for "${key}" — expected { handler, metadata? } or null.`,
934
- )
928
+ logger.warn('Skipping malformed routes.api override — expected { handler, metadata? } or null', { key })
935
929
  remainingMethods.push(method)
936
930
  }
937
931
  }
@@ -971,9 +965,7 @@ export function applyApiOverridesToManifests<T extends ApiRouteManifestEntry>(
971
965
 
972
966
  for (const key of overrideKeys) {
973
967
  if (!consumedKeys.has(key)) {
974
- console.warn(
975
- `[Module Overrides] routes.api override "${key}" did not match any registered API route — override skipped.`,
976
- )
968
+ logger.warn('routes.api override did not match any registered API route — override skipped', { key })
977
969
  }
978
970
  }
979
971
 
@@ -990,9 +982,7 @@ export function applyPageOverridesToManifests<T extends BackendRouteManifestEntr
990
982
  for (const [rawKey, value] of Object.entries(overrides)) {
991
983
  const key = normalizePageRouteOverrideKey(rawKey)
992
984
  if (!key) {
993
- console.warn(
994
- `[Module Overrides] Skipping malformed routes.pages key "${rawKey}" — expected "/backend/path" or "/frontend/path".`,
995
- )
985
+ logger.warn('Skipping malformed routes.pages key — expected "/backend/path" or "/frontend/path"', { key: rawKey })
996
986
  continue
997
987
  }
998
988
  normalizedOverrides[key] = value
@@ -1015,9 +1005,7 @@ export function applyPageOverridesToManifests<T extends BackendRouteManifestEntr
1015
1005
  const override = normalizedOverrides[key]
1016
1006
  if (override === null) continue
1017
1007
  if (!override || typeof override !== 'object') {
1018
- console.warn(
1019
- `[Module Overrides] Skipping malformed routes.pages override for "${key}" — expected { load?, Component?, metadata? } or null.`,
1020
- )
1008
+ logger.warn('Skipping malformed routes.pages override — expected { load?, Component?, metadata? } or null', { key })
1021
1009
  result.push(entry)
1022
1010
  continue
1023
1011
  }
@@ -1025,9 +1013,7 @@ export function applyPageOverridesToManifests<T extends BackendRouteManifestEntr
1025
1013
  const hasLoad = typeof override.load === 'function'
1026
1014
  const hasComponent = typeof override.Component === 'function'
1027
1015
  if (!hasLoad && !hasComponent && override.metadata === undefined) {
1028
- console.warn(
1029
- `[Module Overrides] Skipping malformed routes.pages override for "${key}" — expected a loader, component, metadata, or null.`,
1030
- )
1016
+ logger.warn('Skipping malformed routes.pages override — expected a loader, component, metadata, or null', { key })
1031
1017
  result.push(entry)
1032
1018
  continue
1033
1019
  }
@@ -1182,13 +1168,13 @@ export function applyComponentOverridesToEntries(
1182
1168
  const value = overrides[key]
1183
1169
  if (value === null) continue
1184
1170
  if (!isComponentOverrideValue(value)) {
1185
- console.warn(`[Module Overrides] Skipping malformed widgets.components override for "${key}" — expected ComponentOverride, ComponentOverride[], or null.`)
1171
+ logger.warn('Skipping malformed widgets.components override — expected ComponentOverride, ComponentOverride[], or null', { key })
1186
1172
  continue
1187
1173
  }
1188
1174
  const values = Array.isArray(value) ? value : [value]
1189
1175
  for (const override of values) {
1190
1176
  if (override.target.componentId !== key) {
1191
- console.warn(`[Module Overrides] Skipping malformed widgets.components override for "${key}" — target.componentId must match the override key.`)
1177
+ logger.warn('Skipping malformed widgets.components override — target.componentId must match the override key', { key })
1192
1178
  continue
1193
1179
  }
1194
1180
  additions.push(override)
@@ -1415,9 +1401,7 @@ function routesOverridesApplier(
1415
1401
  for (const [rawKey, value] of Object.entries(api)) {
1416
1402
  const key = normalizeApiRouteOverrideKey(rawKey)
1417
1403
  if (!key) {
1418
- console.warn(
1419
- `[Module Overrides] Skipping malformed routes.api key "${rawKey}" — expected "METHOD /api/path".`,
1420
- )
1404
+ logger.warn('Skipping malformed routes.api key — expected "METHOD /api/path"', { key: rawKey })
1421
1405
  continue
1422
1406
  }
1423
1407
  modulesConfigApiRouteOverrides[key] = value as ApiRouteOverride
@@ -4,6 +4,7 @@ import type { SyncCrudEventResult } from '../lib/crud/sync-event-types'
4
4
  import type { DashboardWidgetModule } from './dashboard/widgets'
5
5
  import type { InjectionAnyWidgetModule, ModuleInjectionTable } from './widgets/injection'
6
6
  import type { IntegrationBundle, IntegrationDefinition } from './integrations/types'
7
+ import { createLogger } from '../lib/logger'
7
8
  import {
8
9
  applyApiOverridesToManifests,
9
10
  applyModuleOverridesToModules,
@@ -12,6 +13,8 @@ import {
12
13
  composePageRouteOverrides,
13
14
  } from './overrides'
14
15
 
16
+ const logger = createLogger('shared').child({ component: 'cli-registry' })
17
+
15
18
  // Context passed to dynamic metadata guards
16
19
  export type RouteVisibilityContext = { path?: string; auth?: any }
17
20
 
@@ -481,7 +484,7 @@ let _cliModules: Module[] | null = null
481
484
 
482
485
  export function registerCliModules(modules: Module[]) {
483
486
  if (_cliModules !== null && process.env.NODE_ENV === 'development') {
484
- console.debug('[Bootstrap] CLI modules re-registered (this may occur during HMR)')
487
+ logger.debug('CLI modules re-registered (this may occur during HMR)')
485
488
  }
486
489
  _cliModules = applyModuleOverridesToModules(modules)
487
490
  }
@@ -1,4 +1,7 @@
1
1
  import type { EntityId } from './entities'
2
+ import { createLogger } from '../lib/logger'
3
+
4
+ const logger = createLogger('shared').child({ component: 'search-registry' })
2
5
 
3
6
  // =============================================================================
4
7
  // Strategy Identifiers
@@ -337,7 +340,7 @@ let _searchModuleConfigs: SearchModuleConfig[] | null = null
337
340
  */
338
341
  export function registerSearchModuleConfigs(configs: SearchModuleConfig[]): void {
339
342
  if (_searchModuleConfigs !== null && process.env.NODE_ENV === 'development') {
340
- console.debug('[Bootstrap] Search module configs re-registered (this may occur during HMR)')
343
+ logger.debug('Search module configs re-registered (this may occur during HMR)')
341
344
  }
342
345
  _searchModuleConfigs = configs
343
346
  }
@@ -10,11 +10,14 @@ import type {
10
10
  ModuleInjectionTable,
11
11
  InjectionWidgetPlacement,
12
12
  } from './injection'
13
+ import { createLogger } from '../../lib/logger'
13
14
  import {
14
15
  applyInjectionWidgetOverridesToEntries,
15
16
  applyInjectionWidgetOverridesToTables,
16
17
  } from '../overrides'
17
18
 
19
+ const logger = createLogger('widgets').child({ component: 'injection-loader' })
20
+
18
21
  type LoadedWidgetModule = InjectionWidgetModule<any, any> & { metadata: InjectionWidgetMetadata }
19
22
  type LoadedDataWidgetModule = InjectionDataWidgetModule & { metadata: InjectionWidgetMetadata }
20
23
 
@@ -140,7 +143,7 @@ function notifyInjectionRegistryChanged() {
140
143
 
141
144
  export function registerCoreInjectionWidgets(entries: ModuleInjectionWidgetEntry[]) {
142
145
  if (_coreInjectionWidgetEntries !== null && process.env.NODE_ENV === 'development') {
143
- console.debug('[Bootstrap] Core injection widgets re-registered (this may occur during HMR)')
146
+ logger.debug('Core injection widgets re-registered (this may occur during HMR)')
144
147
  }
145
148
  const finalEntries = applyInjectionWidgetOverridesToEntries(entries)
146
149
  _coreInjectionWidgetEntries = finalEntries
@@ -163,7 +166,7 @@ export function getCoreInjectionWidgets(): ModuleInjectionWidgetEntry[] {
163
166
 
164
167
  export function registerCoreInjectionTables(tables: Array<{ moduleId: string; table: ModuleInjectionTable }>) {
165
168
  if (_coreInjectionTables !== null && process.env.NODE_ENV === 'development') {
166
- console.debug('[Bootstrap] Core injection tables re-registered (this may occur during HMR)')
169
+ logger.debug('Core injection tables re-registered (this may occur during HMR)')
167
170
  }
168
171
  const finalTables = applyInjectionWidgetOverridesToTables(tables)
169
172
  _coreInjectionTables = finalTables
@@ -186,7 +189,7 @@ export function registerEnabledModuleIds(moduleIds: Iterable<string>) {
186
189
  if (typeof moduleId === 'string' && moduleId.length > 0) next.add(moduleId)
187
190
  }
188
191
  if (_enabledModuleIds !== null && process.env.NODE_ENV === 'development') {
189
- console.debug('[Bootstrap] Enabled module IDs re-registered (this may occur during HMR)')
192
+ logger.debug('Enabled module IDs re-registered (this may occur during HMR)')
190
193
  }
191
194
  _enabledModuleIds = next
192
195
  writeGlobalEnabledModuleIds(next)
@@ -539,9 +542,7 @@ function warnSkippedWidget(metadataId: string, missingModules: string[]) {
539
542
  if (warnedRequiredModuleSkips.has(key)) return
540
543
  warnedRequiredModuleSkips.add(key)
541
544
  if (process.env.NODE_ENV === 'development') {
542
- console.debug(
543
- `[InjectionLoader] Skipping widget "${metadataId}" — required module(s) not enabled: ${missingModules.join(', ')}`,
544
- )
545
+ logger.debug('Skipping widget — required module(s) not enabled', { metadataId, missingModules })
545
546
  }
546
547
  }
547
548
 
@@ -1,3 +1,7 @@
1
+ import { createLogger } from '../../lib/logger'
2
+
3
+ const logger = createLogger('widgets').child({ component: 'injection-placement' })
4
+
1
5
  export enum InjectionPosition {
2
6
  Before = 'before',
3
7
  After = 'after',
@@ -18,7 +22,7 @@ export function getInjectionPosition(placement?: InjectionPlacement): InjectionP
18
22
  function warnInvalidRelativeTo(relativeTo: string | undefined) {
19
23
  if (process.env.NODE_ENV !== 'development') return
20
24
  if (!relativeTo) return
21
- console.warn(`[InjectionPlacement] relativeTo target "${relativeTo}" not found, appending item at the end.`)
25
+ logger.warn('relativeTo target not found, appending item at the end', { relativeTo })
22
26
  }
23
27
 
24
28
  export function insertByInjectionPlacement<T>(