@alepha/devtools 0.19.1 → 0.19.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.
Files changed (130) hide show
  1. package/assets/ui/200.html +10 -0
  2. package/assets/ui/200.html.br +1 -0
  3. package/assets/ui/404.html +10 -0
  4. package/assets/ui/404.html.br +1 -0
  5. package/assets/ui/CNAME +1 -0
  6. package/assets/ui/asset.CHpVij2M.css +1 -0
  7. package/assets/ui/asset.CHpVij2M.css.br +0 -0
  8. package/assets/ui/asset.Cxu56LSy.css +1 -0
  9. package/assets/ui/asset.Cxu56LSy.css.br +0 -0
  10. package/assets/ui/chunk.9plHAFDW.js +1 -0
  11. package/assets/ui/chunk.9plHAFDW.js.br +0 -0
  12. package/assets/ui/chunk.B82rsdDI.js +1 -0
  13. package/assets/ui/chunk.B82rsdDI.js.br +0 -0
  14. package/assets/ui/chunk.B9jGefQy.js +1 -0
  15. package/assets/ui/chunk.B9jGefQy.js.br +0 -0
  16. package/assets/ui/chunk.BHYZ9sAK.js +1 -0
  17. package/assets/ui/chunk.BHYZ9sAK.js.br +0 -0
  18. package/assets/ui/chunk.Bc7_n90V.js +1 -0
  19. package/assets/ui/chunk.Bc7_n90V.js.br +0 -0
  20. package/assets/ui/chunk.CCbhJSL_.js +1 -0
  21. package/assets/ui/chunk.CCbhJSL_.js.br +0 -0
  22. package/assets/ui/chunk.CJt_09bu.js +1 -0
  23. package/assets/ui/chunk.CJt_09bu.js.br +0 -0
  24. package/assets/ui/chunk.CK6Z-I-W.js +1 -0
  25. package/assets/ui/chunk.CK6Z-I-W.js.br +1 -0
  26. package/assets/ui/chunk.Cj1opA98.js +1 -0
  27. package/assets/ui/chunk.Cj1opA98.js.br +0 -0
  28. package/assets/ui/chunk.CvCu4yZb.js +2 -0
  29. package/assets/ui/chunk.CvCu4yZb.js.br +0 -0
  30. package/assets/ui/chunk.D93ZmnLR.js +1 -0
  31. package/assets/ui/chunk.D93ZmnLR.js.br +6 -0
  32. package/assets/ui/chunk.D9MCnLj_.js +7 -0
  33. package/assets/ui/chunk.D9MCnLj_.js.br +0 -0
  34. package/assets/ui/chunk.DOwjsMaD.js +1 -0
  35. package/assets/ui/chunk.DOwjsMaD.js.br +0 -0
  36. package/assets/ui/chunk.DYIu-C82.js +1 -0
  37. package/assets/ui/chunk.DYIu-C82.js.br +0 -0
  38. package/assets/ui/chunk.D_-fkSwu.js +1 -0
  39. package/assets/ui/chunk.D_-fkSwu.js.br +0 -0
  40. package/assets/ui/chunk.Dc4PCYcb.js +1 -0
  41. package/assets/ui/chunk.Dc4PCYcb.js.br +0 -0
  42. package/assets/ui/chunk.De1vj4hM.js +1 -0
  43. package/assets/ui/chunk.De1vj4hM.js.br +0 -0
  44. package/assets/ui/chunk.DuQak1OK.js +1 -0
  45. package/assets/ui/chunk.DuQak1OK.js.br +0 -0
  46. package/assets/ui/chunk.DxnuHDOY.js +1 -0
  47. package/assets/ui/chunk.DxnuHDOY.js.br +0 -0
  48. package/assets/ui/chunk.TIounDiA.js +1 -0
  49. package/assets/ui/chunk.TIounDiA.js.br +0 -0
  50. package/assets/ui/chunk.p3hCiSrt.js +80 -0
  51. package/assets/ui/chunk.p3hCiSrt.js.br +0 -0
  52. package/assets/ui/chunk.yh4jaMrg.js +1 -0
  53. package/assets/ui/chunk.yh4jaMrg.js.br +0 -0
  54. package/assets/ui/entry.DnXws2rz.js +2 -0
  55. package/assets/ui/entry.DnXws2rz.js.br +0 -0
  56. package/assets/ui/index.html +10 -0
  57. package/assets/ui/index.html.br +1 -0
  58. package/dist/public/200.html +10 -0
  59. package/dist/public/200.html.br +1 -0
  60. package/dist/public/404.html +10 -0
  61. package/dist/public/404.html.br +1 -0
  62. package/dist/public/CNAME +1 -0
  63. package/dist/public/asset.CHpVij2M.css +1 -0
  64. package/dist/public/asset.CHpVij2M.css.br +0 -0
  65. package/dist/public/asset.Cxu56LSy.css +1 -0
  66. package/dist/public/asset.Cxu56LSy.css.br +0 -0
  67. package/dist/public/chunk.9plHAFDW.js +1 -0
  68. package/dist/public/chunk.9plHAFDW.js.br +0 -0
  69. package/dist/public/chunk.B82rsdDI.js +1 -0
  70. package/dist/public/chunk.B82rsdDI.js.br +0 -0
  71. package/dist/public/chunk.B9jGefQy.js +1 -0
  72. package/dist/public/chunk.B9jGefQy.js.br +0 -0
  73. package/dist/public/chunk.BHYZ9sAK.js +1 -0
  74. package/dist/public/chunk.BHYZ9sAK.js.br +0 -0
  75. package/dist/public/chunk.Bc7_n90V.js +1 -0
  76. package/dist/public/chunk.Bc7_n90V.js.br +0 -0
  77. package/dist/public/chunk.CCbhJSL_.js +1 -0
  78. package/dist/public/chunk.CCbhJSL_.js.br +0 -0
  79. package/dist/public/chunk.CJt_09bu.js +1 -0
  80. package/dist/public/chunk.CJt_09bu.js.br +0 -0
  81. package/dist/public/chunk.CK6Z-I-W.js +1 -0
  82. package/dist/public/chunk.CK6Z-I-W.js.br +1 -0
  83. package/dist/public/chunk.Cj1opA98.js +1 -0
  84. package/dist/public/chunk.Cj1opA98.js.br +0 -0
  85. package/dist/public/chunk.CvCu4yZb.js +2 -0
  86. package/dist/public/chunk.CvCu4yZb.js.br +0 -0
  87. package/dist/public/chunk.D93ZmnLR.js +1 -0
  88. package/dist/public/chunk.D93ZmnLR.js.br +6 -0
  89. package/dist/public/chunk.D9MCnLj_.js +7 -0
  90. package/dist/public/chunk.D9MCnLj_.js.br +0 -0
  91. package/dist/public/chunk.DOwjsMaD.js +1 -0
  92. package/dist/public/chunk.DOwjsMaD.js.br +0 -0
  93. package/dist/public/chunk.DYIu-C82.js +1 -0
  94. package/dist/public/chunk.DYIu-C82.js.br +0 -0
  95. package/dist/public/chunk.D_-fkSwu.js +1 -0
  96. package/dist/public/chunk.D_-fkSwu.js.br +0 -0
  97. package/dist/public/chunk.Dc4PCYcb.js +1 -0
  98. package/dist/public/chunk.Dc4PCYcb.js.br +0 -0
  99. package/dist/public/chunk.De1vj4hM.js +1 -0
  100. package/dist/public/chunk.De1vj4hM.js.br +0 -0
  101. package/dist/public/chunk.DuQak1OK.js +1 -0
  102. package/dist/public/chunk.DuQak1OK.js.br +0 -0
  103. package/dist/public/chunk.DxnuHDOY.js +1 -0
  104. package/dist/public/chunk.DxnuHDOY.js.br +0 -0
  105. package/dist/public/chunk.TIounDiA.js +1 -0
  106. package/dist/public/chunk.TIounDiA.js.br +0 -0
  107. package/dist/public/chunk.p3hCiSrt.js +80 -0
  108. package/dist/public/chunk.p3hCiSrt.js.br +0 -0
  109. package/dist/public/chunk.yh4jaMrg.js +1 -0
  110. package/dist/public/chunk.yh4jaMrg.js.br +0 -0
  111. package/dist/public/entry.DnXws2rz.js +2 -0
  112. package/dist/public/entry.DnXws2rz.js.br +0 -0
  113. package/dist/public/index.html +10 -0
  114. package/dist/public/index.html.br +1 -0
  115. package/package.json +18 -17
  116. package/src/providers/DevToolsMetadataProvider.ts +1 -1
  117. package/src/providers/DevToolsProvider.ts +115 -1
  118. package/src/ui/AppRouter.tsx +18 -0
  119. package/src/ui/components/DevLayout.tsx +14 -15
  120. package/src/ui/components/configuration/ConfigEnv.tsx +1 -1
  121. package/src/ui/components/dashboard/DevDashboard.tsx +32 -13
  122. package/src/ui/components/database/DatabaseEditor.tsx +5 -2
  123. package/src/ui/components/emails/DevEmails.tsx +250 -0
  124. package/src/ui/components/explorer/DevExplorer.tsx +1 -1
  125. package/src/ui/components/sms/DevSms.tsx +225 -0
  126. package/dist/index.browser.js +0 -224
  127. package/dist/index.browser.js.map +0 -1
  128. package/dist/index.d.ts +0 -499
  129. package/dist/index.js +0 -782
  130. package/dist/index.js.map +0 -1
package/dist/index.js DELETED
@@ -1,782 +0,0 @@
1
- import { $hook, $inject, $module, Alepha, t } from "alepha";
2
- import { $action, $route, AlephaServer, ServerProvider } from "alepha/server";
3
- import { $serve, AlephaServerStatic } from "alepha/server/static";
4
- import { $bucket } from "alepha/bucket";
5
- import { $cache } from "alepha/cache";
6
- import { DateTimeProvider } from "alepha/datetime";
7
- import { $logger, MemoryDestinationProvider } from "alepha/logger";
8
- import { PG_CREATED_AT, PG_DEFAULT, PG_DELETED_AT, PG_IDENTITY, PG_PRIMARY_KEY, PG_REF, PG_SERIAL, PG_UPDATED_AT, PG_VERSION, RepositoryProvider } from "alepha/orm";
9
- import { $queue } from "alepha/queue";
10
- import { $page } from "alepha/react/router";
11
- import { $scheduler } from "alepha/scheduler";
12
- import { $issuer } from "alepha/security";
13
- import { $topic } from "alepha/topic";
14
- import { join } from "node:path";
15
- import { fileURLToPath } from "node:url";
16
- //#region src/providers/DevToolsMetadataProvider.ts
17
- var DevToolsMetadataProvider = class {
18
- alepha = $inject(Alepha);
19
- dateTime = $inject(DateTimeProvider);
20
- log = $logger();
21
- serverProvider = $inject(ServerProvider);
22
- startedAt = this.dateTime.nowMillis();
23
- getActions() {
24
- return this.alepha.primitives($action).map((action) => {
25
- const schema = action.schema;
26
- const options = action.options;
27
- return {
28
- name: action.name,
29
- group: action.group,
30
- method: action.method,
31
- path: action.path,
32
- prefix: action.prefix,
33
- fullPath: action.route.path,
34
- description: action.options.description,
35
- summary: options.summary,
36
- disabled: action.options.disabled,
37
- secure: action.middlewares.some((m) => m?.name === "$secure") || void 0,
38
- hide: options.hide,
39
- body: schema?.body,
40
- params: schema?.params,
41
- query: schema?.query,
42
- response: schema?.response,
43
- bodyContentType: action.getBodyContentType(),
44
- middlewares: action.middlewares.filter(Boolean).length ? action.middlewares.filter(Boolean) : void 0
45
- };
46
- });
47
- }
48
- getQueues() {
49
- return this.alepha.primitives($queue).map((queue) => ({
50
- name: queue.name,
51
- description: queue.options.description,
52
- schema: queue.options.schema,
53
- provider: this.getProviderName(queue.options.provider)
54
- }));
55
- }
56
- getSchedulers() {
57
- return this.alepha.primitives($scheduler).map((scheduler) => ({
58
- name: scheduler.name,
59
- description: scheduler.options.description,
60
- cron: scheduler.options.cron,
61
- interval: scheduler.options.interval,
62
- lock: scheduler.options.lock
63
- }));
64
- }
65
- getTopics() {
66
- const topicPrimitives = this.alepha.primitives($topic);
67
- const topicMap = /* @__PURE__ */ new Map();
68
- for (const topic of topicPrimitives) {
69
- const existing = topicMap.get(topic.name);
70
- if (existing) existing.subscribers++;
71
- else topicMap.set(topic.name, {
72
- name: topic.name,
73
- description: topic.options.description,
74
- schema: topic.options.schema,
75
- provider: this.getProviderName(topic.options.provider),
76
- subscribers: 1
77
- });
78
- }
79
- return Array.from(topicMap.values());
80
- }
81
- getBuckets() {
82
- return this.alepha.primitives($bucket).map((bucket) => ({
83
- name: bucket.name,
84
- description: bucket.options.description,
85
- mimeTypes: bucket.options.mimeTypes,
86
- maxSize: bucket.options.maxSize,
87
- provider: this.getProviderName(bucket.options.provider)
88
- }));
89
- }
90
- getRealms() {
91
- return this.alepha.primitives($issuer).map((realm) => ({
92
- name: realm.name,
93
- description: realm.options.description,
94
- roles: realm.options.roles,
95
- type: "secret" in realm.options ? "internal" : "external",
96
- settings: {
97
- accessTokenExpiration: realm.options.settings?.accessToken?.expiration,
98
- refreshTokenExpiration: realm.options.settings?.refreshToken?.expiration,
99
- hasOnCreateSession: !!realm.options.settings?.onCreateSession,
100
- hasOnRefreshSession: !!realm.options.settings?.onRefreshSession,
101
- hasOnDeleteSession: !!realm.options.settings?.onDeleteSession
102
- }
103
- }));
104
- }
105
- getCaches() {
106
- return this.alepha.primitives($cache).map((cache) => ({
107
- name: cache.container,
108
- ttl: cache.options.ttl,
109
- disabled: cache.options.disabled,
110
- provider: this.getProviderName(cache.options.provider)
111
- }));
112
- }
113
- getPages() {
114
- return this.alepha.primitives($page).map((page) => {
115
- const children = typeof page.options.children === "function" ? page.options.children() : page.options.children;
116
- const childrenNames = Array.isArray(children) ? children.map((c) => c.name).filter(Boolean) : void 0;
117
- return {
118
- name: page.name,
119
- label: page.options.label,
120
- description: page.options.description,
121
- path: page.options.path,
122
- parentName: page.options.parent?.name,
123
- params: page.options.schema?.params,
124
- query: page.options.schema?.query,
125
- hasComponent: !!page.options.component,
126
- hasLazy: !!page.options.lazy,
127
- hasResolve: !!page.options.resolve,
128
- childrenNames: childrenNames?.length ? childrenNames : void 0,
129
- hasChildren: !!page.options.children,
130
- hasParent: !!page.options.parent,
131
- hasErrorHandler: !!page.options.errorHandler,
132
- static: typeof page.options.static === "boolean" ? page.options.static : !!page.options.static,
133
- cache: page.options.cache,
134
- client: page.options.client,
135
- animation: page.options.animation
136
- };
137
- });
138
- }
139
- getProviders() {
140
- const graph = this.alepha.graph();
141
- return Object.entries(graph).map(([name, info]) => ({
142
- name,
143
- module: info.module ?? name,
144
- dependencies: info.from,
145
- aliases: info.as
146
- }));
147
- }
148
- getModules() {
149
- const graph = this.alepha.graph();
150
- const moduleMap = /* @__PURE__ */ new Map();
151
- for (const [providerName, info] of Object.entries(graph)) if (info.module) {
152
- if (!moduleMap.has(info.module)) moduleMap.set(info.module, /* @__PURE__ */ new Set());
153
- moduleMap.get(info.module).add(providerName);
154
- }
155
- return Array.from(moduleMap.entries()).map(([name, providers]) => ({
156
- name,
157
- providers: Array.from(providers)
158
- }));
159
- }
160
- getEntities() {
161
- try {
162
- return this.alepha.inject(RepositoryProvider).getRepositories().map((repo) => {
163
- const entity = repo.entity;
164
- const schema = entity.schema;
165
- const options = entity.options;
166
- const columns = Object.entries(schema.properties).map(([name, field]) => {
167
- const fieldSchema = field;
168
- const refData = fieldSchema[PG_REF];
169
- return {
170
- name,
171
- type: this.getColumnType(fieldSchema),
172
- nullable: this.isNullable(fieldSchema),
173
- primaryKey: PG_PRIMARY_KEY in fieldSchema,
174
- identity: PG_IDENTITY in fieldSchema || PG_SERIAL in fieldSchema,
175
- createdAt: PG_CREATED_AT in fieldSchema,
176
- updatedAt: PG_UPDATED_AT in fieldSchema,
177
- deletedAt: PG_DELETED_AT in fieldSchema,
178
- version: PG_VERSION in fieldSchema,
179
- hasDefault: PG_DEFAULT in fieldSchema,
180
- ref: refData ? {
181
- entity: refData.ref?.()?.entity?.name ?? "unknown",
182
- column: refData.ref?.()?.name ?? "unknown",
183
- onUpdate: refData.actions?.onUpdate,
184
- onDelete: refData.actions?.onDelete
185
- } : void 0
186
- };
187
- });
188
- const indexes = (options.indexes ?? []).map((idx) => {
189
- if (typeof idx === "string") return {
190
- columns: [idx],
191
- unique: false
192
- };
193
- return {
194
- name: idx.name,
195
- columns: idx.column ? [idx.column] : idx.columns ?? [],
196
- unique: idx.unique ?? false
197
- };
198
- });
199
- const foreignKeys = (options.foreignKeys ?? []).map((fk) => ({
200
- name: fk.name,
201
- columns: fk.columns.map(String),
202
- foreignEntity: fk.foreignColumns?.[0]?.()?.entity?.name ?? "unknown",
203
- foreignColumns: fk.foreignColumns?.map((fc) => fc?.()?.name ?? "unknown")
204
- }));
205
- const constraints = (options.constraints ?? []).map((c) => ({
206
- name: c.name,
207
- columns: c.columns.map(String),
208
- unique: !!c.unique,
209
- hasCheck: !!c.check
210
- }));
211
- return {
212
- name: entity.name,
213
- provider: repo.provider.constructor.name,
214
- columns,
215
- indexes,
216
- foreignKeys,
217
- constraints,
218
- schema: entity.schema,
219
- insertSchema: entity.insertSchema,
220
- updateSchema: entity.updateSchema
221
- };
222
- });
223
- } catch {
224
- return [];
225
- }
226
- }
227
- getColumnType(field) {
228
- if (t.schema.isUnion(field) && field.anyOf) {
229
- const nonNull = field.anyOf.find((type) => !t.schema.isNull(type));
230
- if (nonNull) return this.getColumnType(nonNull);
231
- }
232
- const f = field;
233
- if (t.schema.isUnsafe(field) && f.type === "string" && Array.isArray(f.enum)) return "enum";
234
- if (t.schema.isString(field)) {
235
- if (f.enum) return "enum";
236
- if (f.format === "uuid") return "uuid";
237
- if (f.format === "date-time") return "datetime";
238
- if (f.format === "date") return "date";
239
- if (f.format === "bigint") return "bigint";
240
- return "text";
241
- }
242
- if (t.schema.isInteger(field)) return "integer";
243
- if (t.schema.isNumber(field)) return "number";
244
- if (t.schema.isBoolean(field)) return "boolean";
245
- if (t.schema.isArray(field)) return "array";
246
- if (t.schema.isObject(field)) return "json";
247
- if (t.schema.isLiteral(field)) return "literal";
248
- return "unknown";
249
- }
250
- isNullable(field) {
251
- if (t.schema.isUnion(field) && field.anyOf) return field.anyOf.some((type) => t.schema.isNull(type));
252
- return false;
253
- }
254
- getRoutes() {
255
- return [];
256
- }
257
- getEnvs() {
258
- return this.alepha.getEnvSchemas().map((item, index) => ({
259
- propertyKey: `env_${index}`,
260
- schema: item.schema,
261
- values: item.values,
262
- serviceName: void 0
263
- }));
264
- }
265
- getAtoms() {
266
- return this.alepha.store.getAtoms(false).map(({ atom, value }) => ({
267
- name: atom.key,
268
- description: atom.options.description,
269
- schema: atom.schema,
270
- defaultValue: atom.options.default,
271
- currentValue: value
272
- }));
273
- }
274
- getSystem() {
275
- const isBun = typeof globalThis.Bun !== "undefined";
276
- const port = Number(this.alepha.env.SERVER_PORT) || 3e3;
277
- return {
278
- alephaVersion: String(this.alepha.env.npm_package_version ?? "unknown"),
279
- nodeVersion: isBun ? globalThis.Bun?.version ?? "unknown" : process.version,
280
- runtime: isBun ? "bun" : "node",
281
- mode: this.alepha.isProduction() ? "production" : "development",
282
- port,
283
- uptime: (this.dateTime.nowMillis() - this.startedAt) / 1e3,
284
- memoryUsage: process.memoryUsage?.()?.rss ?? 0
285
- };
286
- }
287
- getMetadata() {
288
- return {
289
- system: this.getSystem(),
290
- actions: this.getActions(),
291
- queues: this.getQueues(),
292
- schedulers: this.getSchedulers(),
293
- topics: this.getTopics(),
294
- buckets: this.getBuckets(),
295
- realms: this.getRealms(),
296
- caches: this.getCaches(),
297
- pages: this.getPages(),
298
- providers: this.getProviders(),
299
- modules: this.getModules(),
300
- entities: this.getEntities(),
301
- routes: this.getRoutes(),
302
- envs: this.getEnvs(),
303
- atoms: this.getAtoms()
304
- };
305
- }
306
- getProviderName(provider) {
307
- if (!provider) return "default";
308
- if (provider === "memory") return "memory";
309
- return provider.name || "custom";
310
- }
311
- };
312
- //#endregion
313
- //#region src/assets.ts
314
- const devtoolsAssets = { ui: join(fileURLToPath(import.meta.url), "../../assets/ui") };
315
- //#endregion
316
- //#region src/schemas/DevActionMetadata.ts
317
- const devActionMetadataSchema = t.object({
318
- name: t.text(),
319
- group: t.text(),
320
- method: t.text(),
321
- path: t.text(),
322
- prefix: t.text(),
323
- fullPath: t.text(),
324
- description: t.optional(t.text()),
325
- summary: t.optional(t.text()),
326
- disabled: t.optional(t.boolean()),
327
- secure: t.optional(t.boolean()),
328
- hide: t.optional(t.boolean()),
329
- body: t.optional(t.any()),
330
- params: t.optional(t.any()),
331
- query: t.optional(t.any()),
332
- response: t.optional(t.any()),
333
- bodyContentType: t.optional(t.text()),
334
- middlewares: t.optional(t.array(t.object({
335
- name: t.text(),
336
- options: t.optional(t.any())
337
- })))
338
- });
339
- //#endregion
340
- //#region src/schemas/DevAtomMetadata.ts
341
- const devAtomMetadataSchema = t.object({
342
- name: t.text(),
343
- description: t.optional(t.text()),
344
- schema: t.any(),
345
- defaultValue: t.optional(t.any()),
346
- currentValue: t.optional(t.any())
347
- });
348
- //#endregion
349
- //#region src/schemas/DevBucketMetadata.ts
350
- const devBucketMetadataSchema = t.object({
351
- name: t.text(),
352
- description: t.optional(t.text()),
353
- mimeTypes: t.optional(t.array(t.text())),
354
- maxSize: t.optional(t.number()),
355
- provider: t.text()
356
- });
357
- //#endregion
358
- //#region src/schemas/DevCacheMetadata.ts
359
- const devCacheMetadataSchema = t.object({
360
- name: t.text(),
361
- ttl: t.optional(t.any()),
362
- disabled: t.optional(t.boolean()),
363
- provider: t.text()
364
- });
365
- //#endregion
366
- //#region src/schemas/DevEntityMetadata.ts
367
- const devEntityColumnSchema = t.object({
368
- name: t.text(),
369
- type: t.text(),
370
- nullable: t.boolean(),
371
- primaryKey: t.boolean(),
372
- identity: t.boolean(),
373
- createdAt: t.boolean(),
374
- updatedAt: t.boolean(),
375
- deletedAt: t.boolean(),
376
- version: t.boolean(),
377
- hasDefault: t.boolean(),
378
- ref: t.optional(t.object({
379
- entity: t.text(),
380
- column: t.text(),
381
- onUpdate: t.optional(t.text()),
382
- onDelete: t.optional(t.text())
383
- }))
384
- });
385
- const devEntityIndexSchema = t.object({
386
- name: t.optional(t.text()),
387
- columns: t.array(t.text()),
388
- unique: t.boolean()
389
- });
390
- const devEntityForeignKeySchema = t.object({
391
- name: t.optional(t.text()),
392
- columns: t.array(t.text()),
393
- foreignEntity: t.text(),
394
- foreignColumns: t.array(t.text())
395
- });
396
- const devEntityConstraintSchema = t.object({
397
- name: t.optional(t.text()),
398
- columns: t.array(t.text()),
399
- unique: t.boolean(),
400
- hasCheck: t.boolean()
401
- });
402
- const devEntityMetadataSchema = t.object({
403
- name: t.text(),
404
- provider: t.text(),
405
- columns: t.array(devEntityColumnSchema),
406
- indexes: t.array(devEntityIndexSchema),
407
- foreignKeys: t.array(devEntityForeignKeySchema),
408
- constraints: t.array(devEntityConstraintSchema),
409
- schema: t.optional(t.any()),
410
- insertSchema: t.optional(t.any()),
411
- updateSchema: t.optional(t.any())
412
- });
413
- //#endregion
414
- //#region src/schemas/DevEnvMetadata.ts
415
- const devEnvMetadataSchema = t.object({
416
- propertyKey: t.text(),
417
- schema: t.any(),
418
- values: t.record(t.text(), t.any()),
419
- serviceName: t.optional(t.text())
420
- });
421
- //#endregion
422
- //#region src/schemas/DevModuleMetadata.ts
423
- const devModuleMetadataSchema = t.object({
424
- name: t.text(),
425
- providers: t.array(t.text())
426
- });
427
- //#endregion
428
- //#region src/schemas/DevPageMetadata.ts
429
- const devPageMetadataSchema = t.object({
430
- name: t.text(),
431
- label: t.optional(t.text()),
432
- description: t.optional(t.text()),
433
- path: t.optional(t.text()),
434
- parentName: t.optional(t.text()),
435
- params: t.optional(t.any()),
436
- query: t.optional(t.any()),
437
- hasComponent: t.boolean(),
438
- hasLazy: t.boolean(),
439
- hasResolve: t.boolean(),
440
- childrenNames: t.optional(t.array(t.text())),
441
- hasChildren: t.boolean(),
442
- hasParent: t.boolean(),
443
- hasErrorHandler: t.boolean(),
444
- static: t.optional(t.boolean()),
445
- cache: t.optional(t.any()),
446
- client: t.optional(t.any()),
447
- animation: t.optional(t.any())
448
- });
449
- //#endregion
450
- //#region src/schemas/DevProviderMetadata.ts
451
- const devProviderMetadataSchema = t.object({
452
- name: t.text(),
453
- module: t.optional(t.text()),
454
- dependencies: t.array(t.text()),
455
- aliases: t.optional(t.array(t.text()))
456
- });
457
- //#endregion
458
- //#region src/schemas/DevQueueMetadata.ts
459
- const devQueueMetadataSchema = t.object({
460
- name: t.text(),
461
- description: t.optional(t.text()),
462
- schema: t.optional(t.any()),
463
- provider: t.text()
464
- });
465
- //#endregion
466
- //#region src/schemas/DevRealmMetadata.ts
467
- const devRealmMetadataSchema = t.object({
468
- name: t.text(),
469
- description: t.optional(t.text()),
470
- roles: t.optional(t.array(t.any())),
471
- type: t.enum(["internal", "external"]),
472
- settings: t.optional(t.object({
473
- accessTokenExpiration: t.optional(t.any()),
474
- refreshTokenExpiration: t.optional(t.any()),
475
- hasOnCreateSession: t.boolean(),
476
- hasOnRefreshSession: t.boolean(),
477
- hasOnDeleteSession: t.boolean()
478
- }))
479
- });
480
- //#endregion
481
- //#region src/schemas/DevRouteMetadata.ts
482
- const devRouteMetadataSchema = t.object({
483
- method: t.text(),
484
- path: t.text()
485
- });
486
- //#endregion
487
- //#region src/schemas/DevSchedulerMetadata.ts
488
- const devSchedulerMetadataSchema = t.object({
489
- name: t.text(),
490
- description: t.optional(t.text()),
491
- cron: t.optional(t.text()),
492
- interval: t.optional(t.any()),
493
- lock: t.optional(t.boolean())
494
- });
495
- //#endregion
496
- //#region src/schemas/DevTopicMetadata.ts
497
- const devTopicMetadataSchema = t.object({
498
- name: t.text(),
499
- description: t.optional(t.text()),
500
- schema: t.optional(t.any()),
501
- provider: t.text(),
502
- subscribers: t.integer()
503
- });
504
- //#endregion
505
- //#region src/schemas/DevMetadata.ts
506
- const devSystemSchema = t.object({
507
- alephaVersion: t.text(),
508
- nodeVersion: t.text(),
509
- runtime: t.enum(["node", "bun"]),
510
- mode: t.enum(["development", "production"]),
511
- port: t.integer(),
512
- uptime: t.number(),
513
- memoryUsage: t.number()
514
- });
515
- const devMetadataSchema = t.object({
516
- system: devSystemSchema,
517
- actions: t.array(devActionMetadataSchema),
518
- queues: t.array(devQueueMetadataSchema),
519
- schedulers: t.array(devSchedulerMetadataSchema),
520
- topics: t.array(devTopicMetadataSchema),
521
- buckets: t.array(devBucketMetadataSchema),
522
- realms: t.array(devRealmMetadataSchema),
523
- caches: t.array(devCacheMetadataSchema),
524
- pages: t.array(devPageMetadataSchema),
525
- providers: t.array(devProviderMetadataSchema),
526
- modules: t.array(devModuleMetadataSchema),
527
- entities: t.array(devEntityMetadataSchema),
528
- routes: t.array(devRouteMetadataSchema),
529
- envs: t.array(devEnvMetadataSchema),
530
- atoms: t.array(devAtomMetadataSchema)
531
- });
532
- //#endregion
533
- //#region src/providers/DevToolsProvider.ts
534
- var DevToolsProvider = class {
535
- log = $logger();
536
- alepha = $inject(Alepha);
537
- serverProvider = $inject(ServerProvider);
538
- devCollectorProvider = $inject(DevToolsMetadataProvider);
539
- memoryDestination = $inject(MemoryDestinationProvider);
540
- onStart = $hook({
541
- on: "start",
542
- handler: () => {
543
- this.log.info("Devtools OK", { url: `${this.serverProvider.hostname}/__devtools/` });
544
- }
545
- });
546
- /**
547
- * Capture all logs into memory so the devtools UI can display them.
548
- * In dev mode, LogDestinationProvider is bound to ConsoleDestinationProvider,
549
- * so MemoryDestinationProvider would otherwise never receive writes.
550
- */
551
- onLog = $hook({
552
- on: "log",
553
- handler: ({ entry }) => {
554
- this.memoryDestination.write("", entry);
555
- }
556
- });
557
- uiRoute = $serve({
558
- path: "/__devtools",
559
- root: devtoolsAssets.ui,
560
- historyApiFallback: true,
561
- silent: true
562
- });
563
- metadataRoute = $route({
564
- method: "GET",
565
- path: "/__devtools/api/metadata",
566
- silent: true,
567
- schema: { response: devMetadataSchema },
568
- handler: () => {
569
- return this.devCollectorProvider.getMetadata();
570
- }
571
- });
572
- updateAtomRoute = $route({
573
- method: "POST",
574
- path: "/__devtools/api/atoms",
575
- silent: true,
576
- schema: {
577
- body: t.object({
578
- name: t.text(),
579
- value: t.any()
580
- }),
581
- response: t.object({ success: t.boolean() })
582
- },
583
- handler: ({ body }) => {
584
- const atomEntry = this.alepha.store.getAtoms(false).find((a) => a.atom.key === body.name);
585
- if (atomEntry) {
586
- this.alepha.store.set(atomEntry.atom, body.value);
587
- return { success: true };
588
- }
589
- return { success: false };
590
- }
591
- });
592
- logsRoute = $route({
593
- method: "GET",
594
- path: "/__devtools/api/logs",
595
- silent: true,
596
- schema: {
597
- query: t.object({
598
- level: t.optional(t.text()),
599
- type: t.optional(t.text()),
600
- module: t.optional(t.text()),
601
- search: t.optional(t.text()),
602
- since: t.optional(t.text()),
603
- limit: t.optional(t.text()),
604
- offset: t.optional(t.text())
605
- }),
606
- response: t.object({
607
- logs: t.array(t.any()),
608
- total: t.integer()
609
- })
610
- },
611
- handler: ({ query }) => {
612
- const levelOrder = [
613
- "TRACE",
614
- "DEBUG",
615
- "INFO",
616
- "WARN",
617
- "ERROR"
618
- ];
619
- let entries = this.memoryDestination.logs;
620
- if (query.level) {
621
- const minIndex = levelOrder.indexOf(query.level.toUpperCase());
622
- if (minIndex >= 0) entries = entries.filter((e) => levelOrder.indexOf(e.level) >= minIndex);
623
- }
624
- if (query.type) {
625
- const types = query.type.split(",").map((t) => t.trim());
626
- entries = entries.filter((e) => {
627
- if (!e.data || typeof e.data !== "object") return false;
628
- const d = e.data;
629
- for (const t of types) if (t === "http" || t === "http:request") {
630
- if (d.status && d.method && d.path && d.duration) return true;
631
- } else if (t === "db" || t === "db:query") {
632
- if (d.type === "db:query") return true;
633
- } else if (d.type === t) return true;
634
- return false;
635
- });
636
- }
637
- if (query.module) entries = entries.filter((e) => e.module === query.module);
638
- if (query.search) {
639
- const terms = query.search.toLowerCase().split(/\s+/);
640
- entries = entries.filter((e) => {
641
- const text = `${e.message} ${e.module} ${e.service}`.toLowerCase();
642
- return terms.every((term) => text.includes(term));
643
- });
644
- }
645
- if (query.since) {
646
- const since = Number(query.since);
647
- if (!Number.isNaN(since)) entries = entries.filter((e) => e.timestamp >= since);
648
- }
649
- const total = entries.length;
650
- entries = entries.reverse();
651
- const offset = query.offset ? Number(query.offset) : 0;
652
- const limit = query.limit ? Number(query.limit) : 100;
653
- entries = entries.slice(offset, offset + limit);
654
- return {
655
- logs: entries,
656
- total
657
- };
658
- }
659
- });
660
- dbListRoute = $route({
661
- method: "GET",
662
- path: "/__devtools/api/db/:entity/records",
663
- silent: true,
664
- schema: {
665
- params: t.object({ entity: t.text() }),
666
- query: t.object({
667
- page: t.optional(t.text()),
668
- size: t.optional(t.text()),
669
- sort: t.optional(t.text())
670
- }),
671
- response: t.record(t.text(), t.any())
672
- },
673
- handler: async ({ params, query }) => {
674
- const repo = this.getRepository(params.entity);
675
- if (!repo) return {
676
- content: [],
677
- page: { totalElements: 0 }
678
- };
679
- return repo.paginate({
680
- page: query.page ? Number(query.page) : 0,
681
- size: query.size ? Number(query.size) : 50,
682
- sort: query.sort || void 0
683
- }, {}, { count: true });
684
- }
685
- });
686
- dbCreateRoute = $route({
687
- method: "POST",
688
- path: "/__devtools/api/db/:entity/records",
689
- silent: true,
690
- schema: {
691
- params: t.object({ entity: t.text() }),
692
- body: t.record(t.text(), t.any()),
693
- response: t.record(t.text(), t.any())
694
- },
695
- handler: async ({ params, body }) => {
696
- const repo = this.getRepository(params.entity);
697
- if (!repo) return { error: "Entity not found" };
698
- return repo.create(body);
699
- }
700
- });
701
- dbUpdateRoute = $route({
702
- method: "PUT",
703
- path: "/__devtools/api/db/:entity/records/:id",
704
- silent: true,
705
- schema: {
706
- params: t.object({
707
- entity: t.text(),
708
- id: t.text()
709
- }),
710
- body: t.record(t.text(), t.any()),
711
- response: t.record(t.text(), t.any())
712
- },
713
- handler: async ({ params, body }) => {
714
- const repo = this.getRepository(params.entity);
715
- if (!repo) return { error: "Entity not found" };
716
- const idValue = this.parseId(repo, params.id);
717
- return repo.updateById(idValue, body);
718
- }
719
- });
720
- dbDeleteRoute = $route({
721
- method: "DELETE",
722
- path: "/__devtools/api/db/:entity/records/:id",
723
- silent: true,
724
- schema: {
725
- params: t.object({
726
- entity: t.text(),
727
- id: t.text()
728
- }),
729
- response: t.record(t.text(), t.any())
730
- },
731
- handler: async ({ params }) => {
732
- const repo = this.getRepository(params.entity);
733
- if (!repo) return { error: "Entity not found" };
734
- const idValue = this.parseId(repo, params.id);
735
- return repo.deleteById(idValue);
736
- }
737
- });
738
- getRepository(entityName) {
739
- try {
740
- return this.alepha.inject(RepositoryProvider).getRepositories().find((r) => r.entity.name === entityName);
741
- } catch {
742
- return;
743
- }
744
- }
745
- parseId(repo, rawId) {
746
- const idType = repo.id.type;
747
- if (idType?.type === "integer" || idType?.type === "number") return Number(rawId);
748
- return rawId;
749
- }
750
- };
751
- //#endregion
752
- //#region src/index.ts
753
- /**
754
- * Runtime inspection and debugging UI.
755
- *
756
- * **Features:**
757
- * - DevTools UI at `GET /devtools`
758
- * - Application metadata at `GET /devtools/metadata`
759
- * - Last 10,000 logs at `GET /devtools/logs`
760
- * - Runtime inspection of actions, queues, schedulers, topics, buckets
761
- * - Log viewer with filtering
762
- * - React Flow visualization
763
- * - Provider and module browsing
764
- *
765
- * @module alepha.devtools
766
- */
767
- const AlephaDevtools = $module({
768
- name: "alepha.devtools",
769
- primitives: [],
770
- services: [DevToolsMetadataProvider, DevToolsProvider],
771
- register: (alepha) => {
772
- alepha.with(AlephaServer);
773
- alepha.with(AlephaServerStatic);
774
- alepha.with(DevToolsProvider);
775
- alepha.with(DevToolsMetadataProvider);
776
- alepha.store.push("alepha.build.assets", "alepha");
777
- }
778
- });
779
- //#endregion
780
- export { AlephaDevtools, DevToolsMetadataProvider, devActionMetadataSchema, devAtomMetadataSchema, devBucketMetadataSchema, devCacheMetadataSchema, devEntityColumnSchema, devEntityConstraintSchema, devEntityForeignKeySchema, devEntityIndexSchema, devEntityMetadataSchema, devEnvMetadataSchema, devMetadataSchema, devModuleMetadataSchema, devPageMetadataSchema, devProviderMetadataSchema, devQueueMetadataSchema, devRealmMetadataSchema, devRouteMetadataSchema, devSchedulerMetadataSchema, devSystemSchema, devTopicMetadataSchema };
781
-
782
- //# sourceMappingURL=index.js.map