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