appos 0.2.1 → 0.2.3-0

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 (232) hide show
  1. package/dist/bin/auth-schema-7KeUwlcd.mjs +2 -0
  2. package/dist/bin/concurrently.mjs +2 -0
  3. package/dist/bin/event-v2sCJkNd.mjs +2 -0
  4. package/dist/bin/extract-blob-metadata-TqNd9w-6.mjs +2 -0
  5. package/dist/bin/generate-image-variant-D8H9FxgD.mjs +2 -0
  6. package/dist/bin/generate-preview-5jLZLX6I.mjs +2 -0
  7. package/dist/bin/main.mjs +362 -0
  8. package/dist/bin/purge-attachment-CMlJMNOk.mjs +2 -0
  9. package/dist/bin/purge-audit-logs-hd6q6vnR.mjs +2 -0
  10. package/dist/bin/purge-unattached-blobs-BYv5b9R9.mjs +2 -0
  11. package/dist/bin/track-db-changes-q0Vl7Htm.mjs +2 -0
  12. package/dist/bin/vite.mjs +2 -0
  13. package/dist/bin/vitest.mjs +2 -0
  14. package/dist/bin/workflow-BagSlsMp.mjs +2 -0
  15. package/dist/bin/youch-handler-Jj6i1XIT.mjs +2 -0
  16. package/dist/exports/api/_virtual/rolldown_runtime.mjs +1 -0
  17. package/dist/exports/api/app-context.d.mts +115 -0
  18. package/dist/exports/api/app-context.mjs +1 -0
  19. package/dist/exports/api/auth-schema.d.mts +4248 -0
  20. package/dist/exports/api/auth-schema.mjs +1 -0
  21. package/dist/exports/api/auth.d.mts +398 -0
  22. package/dist/exports/api/auth.mjs +1 -0
  23. package/dist/exports/api/cache.d.mts +44 -0
  24. package/dist/exports/api/cache.mjs +1 -0
  25. package/dist/exports/api/config.d.mts +28 -0
  26. package/dist/exports/api/config.mjs +1 -0
  27. package/dist/exports/api/container.d.mts +210 -0
  28. package/dist/exports/api/container.mjs +1 -0
  29. package/dist/exports/api/database.d.mts +99 -0
  30. package/dist/exports/api/database.mjs +1 -0
  31. package/dist/exports/api/event.d.mts +235 -0
  32. package/dist/exports/api/event.mjs +1 -0
  33. package/dist/exports/api/i18n.d.mts +34 -0
  34. package/dist/exports/api/i18n.mjs +1 -0
  35. package/dist/exports/api/index.d.mts +21 -0
  36. package/dist/exports/api/index.mjs +1 -0
  37. package/dist/exports/api/logger.d.mts +21 -0
  38. package/dist/exports/api/logger.mjs +1 -0
  39. package/dist/exports/api/mailer.d.mts +70 -0
  40. package/dist/exports/api/mailer.mjs +1 -0
  41. package/dist/exports/api/middleware/request-logger.d.mts +24 -0
  42. package/dist/exports/api/middleware.d.mts +39 -0
  43. package/dist/exports/api/middleware.mjs +1 -0
  44. package/dist/exports/api/node_modules/.bun/change-case@5.4.4/node_modules/change-case/dist/index.mjs +1 -0
  45. package/dist/exports/api/openapi.d.mts +271 -0
  46. package/dist/exports/api/openapi.mjs +1 -0
  47. package/dist/exports/api/orm.d.mts +13 -0
  48. package/dist/exports/api/orm.mjs +1 -0
  49. package/dist/exports/api/otel.d.mts +40 -0
  50. package/dist/exports/api/otel.mjs +1 -0
  51. package/dist/exports/api/packages/appos/src/constants.mjs +1 -0
  52. package/dist/exports/api/packages/appos/src/instrumentation.d.mts +7 -0
  53. package/dist/exports/api/packages/appos/src/instrumentation.mjs +1 -0
  54. package/dist/exports/api/packages/appos/src/web/auth.mjs +1 -0
  55. package/dist/exports/api/redis.d.mts +34 -0
  56. package/dist/exports/api/redis.mjs +1 -0
  57. package/dist/exports/api/storage-schema.d.mts +707 -0
  58. package/dist/exports/api/storage-schema.mjs +1 -0
  59. package/dist/exports/api/storage.d.mts +506 -0
  60. package/dist/exports/api/storage.mjs +1 -0
  61. package/dist/exports/api/workflow.d.mts +250 -0
  62. package/dist/exports/api/workflow.mjs +1 -0
  63. package/dist/exports/api/workflows/_virtual/rolldown_runtime.mjs +1 -0
  64. package/dist/exports/api/workflows/auth-schema.mjs +1 -0
  65. package/dist/exports/api/workflows/auth.d.mts +375 -0
  66. package/dist/exports/api/workflows/cache.d.mts +44 -0
  67. package/dist/exports/api/workflows/config.d.mts +18 -0
  68. package/dist/exports/api/workflows/container.d.mts +167 -0
  69. package/dist/exports/api/workflows/database.d.mts +46 -0
  70. package/dist/exports/api/workflows/event.d.mts +68 -0
  71. package/dist/exports/api/workflows/event.mjs +1 -0
  72. package/dist/exports/api/workflows/extract-blob-metadata.mjs +1 -0
  73. package/dist/exports/api/workflows/generate-image-variant.d.mts +63 -0
  74. package/dist/exports/api/workflows/generate-image-variant.mjs +1 -0
  75. package/dist/exports/api/workflows/generate-preview.mjs +1 -0
  76. package/dist/exports/api/workflows/index.d.mts +2 -0
  77. package/dist/exports/api/workflows/index.mjs +1 -0
  78. package/dist/exports/api/workflows/logger.d.mts +21 -0
  79. package/dist/exports/api/workflows/mailer.d.mts +70 -0
  80. package/dist/exports/api/workflows/orm.d.mts +13 -0
  81. package/dist/exports/api/workflows/purge-attachment.mjs +1 -0
  82. package/dist/exports/api/workflows/purge-audit-logs.mjs +1 -0
  83. package/dist/exports/api/workflows/purge-unattached-blobs.mjs +1 -0
  84. package/dist/exports/api/workflows/redis.mjs +1 -0
  85. package/dist/exports/api/workflows/storage-schema.d.mts +699 -0
  86. package/dist/exports/api/workflows/storage.d.mts +396 -0
  87. package/dist/exports/api/workflows/track-db-changes.d.mts +72 -0
  88. package/dist/exports/api/workflows/track-db-changes.mjs +1 -0
  89. package/dist/exports/api/workflows/workflow.d.mts +24 -0
  90. package/dist/exports/api/workflows/workflow.mjs +1 -0
  91. package/dist/exports/cli/_virtual/rolldown_runtime.mjs +1 -0
  92. package/dist/exports/cli/api/auth-schema.mjs +1 -0
  93. package/dist/exports/cli/api/auth.d.mts +375 -0
  94. package/dist/exports/cli/api/cache.d.mts +44 -0
  95. package/dist/exports/cli/api/config.d.mts +18 -0
  96. package/dist/exports/cli/api/container.d.mts +167 -0
  97. package/dist/exports/cli/api/database.d.mts +46 -0
  98. package/dist/exports/cli/api/event.d.mts +68 -0
  99. package/dist/exports/cli/api/event.mjs +1 -0
  100. package/dist/exports/cli/api/logger.d.mts +21 -0
  101. package/dist/exports/cli/api/mailer.d.mts +70 -0
  102. package/dist/exports/cli/api/orm.d.mts +13 -0
  103. package/dist/exports/cli/api/redis.mjs +1 -0
  104. package/dist/exports/cli/api/storage-schema.d.mts +699 -0
  105. package/dist/exports/cli/api/storage.d.mts +396 -0
  106. package/dist/exports/cli/api/workflow.d.mts +2 -0
  107. package/dist/exports/cli/api/workflow.mjs +1 -0
  108. package/dist/exports/cli/api/workflows/extract-blob-metadata.mjs +1 -0
  109. package/dist/exports/cli/api/workflows/generate-image-variant.d.mts +63 -0
  110. package/dist/exports/cli/api/workflows/generate-image-variant.mjs +1 -0
  111. package/dist/exports/cli/api/workflows/generate-preview.mjs +1 -0
  112. package/dist/exports/cli/api/workflows/purge-attachment.mjs +1 -0
  113. package/dist/exports/cli/api/workflows/purge-audit-logs.mjs +1 -0
  114. package/dist/exports/cli/api/workflows/purge-unattached-blobs.mjs +1 -0
  115. package/dist/exports/cli/api/workflows/track-db-changes.mjs +1 -0
  116. package/dist/exports/cli/command.d.mts +54 -0
  117. package/dist/exports/cli/command.mjs +1 -0
  118. package/dist/exports/cli/context.d.mts +170 -0
  119. package/dist/exports/cli/index.d.mts +3 -0
  120. package/dist/exports/cli/index.mjs +1 -0
  121. package/dist/exports/devtools/index.d.ts +3 -0
  122. package/dist/exports/devtools/index.js +1 -0
  123. package/dist/exports/instrumentation.d.mts +1 -0
  124. package/dist/exports/instrumentation.mjs +1 -0
  125. package/dist/exports/tests/_virtual/rolldown_runtime.mjs +1 -0
  126. package/dist/exports/tests/api.d.mts +86 -0
  127. package/dist/exports/tests/api.mjs +1 -0
  128. package/dist/exports/tests/mock.d.mts +1 -0
  129. package/dist/exports/tests/mock.mjs +1 -0
  130. package/dist/exports/tests/node_modules/.bun/change-case@5.4.4/node_modules/change-case/dist/index.mjs +1 -0
  131. package/dist/exports/tests/node_modules/.bun/rate-limit-redis@4.3.1_f1fa5524233c9c60/node_modules/rate-limit-redis/dist/index.mjs +25 -0
  132. package/dist/exports/tests/packages/appos/src/api/app-context.d.mts +115 -0
  133. package/dist/exports/tests/packages/appos/src/api/auth-schema.d.mts +4248 -0
  134. package/dist/exports/tests/packages/appos/src/api/auth-schema.mjs +1 -0
  135. package/dist/exports/tests/packages/appos/src/api/auth.d.mts +398 -0
  136. package/dist/exports/tests/packages/appos/src/api/cache.d.mts +44 -0
  137. package/dist/exports/tests/packages/appos/src/api/config.d.mts +28 -0
  138. package/dist/exports/tests/packages/appos/src/api/container.d.mts +210 -0
  139. package/dist/exports/tests/packages/appos/src/api/database.d.mts +99 -0
  140. package/dist/exports/tests/packages/appos/src/api/database.mjs +1 -0
  141. package/dist/exports/tests/packages/appos/src/api/event.d.mts +235 -0
  142. package/dist/exports/tests/packages/appos/src/api/event.mjs +1 -0
  143. package/dist/exports/tests/packages/appos/src/api/i18n.d.mts +34 -0
  144. package/dist/exports/tests/packages/appos/src/api/index.d.mts +27 -0
  145. package/dist/exports/tests/packages/appos/src/api/logger.d.mts +21 -0
  146. package/dist/exports/tests/packages/appos/src/api/mailer.d.mts +70 -0
  147. package/dist/exports/tests/packages/appos/src/api/middleware/error-handler.mjs +1 -0
  148. package/dist/exports/tests/packages/appos/src/api/middleware/health.mjs +1 -0
  149. package/dist/exports/tests/packages/appos/src/api/middleware/i18n.mjs +1 -0
  150. package/dist/exports/tests/packages/appos/src/api/middleware/request-logger.d.mts +24 -0
  151. package/dist/exports/tests/packages/appos/src/api/middleware/request-logger.mjs +1 -0
  152. package/dist/exports/tests/packages/appos/src/api/middleware/shutdown.mjs +1 -0
  153. package/dist/exports/tests/packages/appos/src/api/middleware/timeout.mjs +1 -0
  154. package/dist/exports/tests/packages/appos/src/api/middleware/youch-handler.mjs +1 -0
  155. package/dist/exports/tests/packages/appos/src/api/middleware.d.mts +39 -0
  156. package/dist/exports/tests/packages/appos/src/api/middleware.mjs +1 -0
  157. package/dist/exports/tests/packages/appos/src/api/openapi.d.mts +271 -0
  158. package/dist/exports/tests/packages/appos/src/api/orm.d.mts +13 -0
  159. package/dist/exports/tests/packages/appos/src/api/otel.d.mts +40 -0
  160. package/dist/exports/tests/packages/appos/src/api/redis.d.mts +34 -0
  161. package/dist/exports/tests/packages/appos/src/api/redis.mjs +1 -0
  162. package/dist/exports/tests/packages/appos/src/api/server.mjs +1 -0
  163. package/dist/exports/tests/packages/appos/src/api/storage-schema.d.mts +707 -0
  164. package/dist/exports/tests/packages/appos/src/api/storage.d.mts +506 -0
  165. package/dist/exports/tests/packages/appos/src/api/workflow.d.mts +250 -0
  166. package/dist/exports/tests/packages/appos/src/api/workflow.mjs +1 -0
  167. package/dist/exports/tests/packages/appos/src/api/workflows/extract-blob-metadata.mjs +1 -0
  168. package/dist/exports/tests/packages/appos/src/api/workflows/generate-image-variant.d.mts +99 -0
  169. package/dist/exports/tests/packages/appos/src/api/workflows/generate-image-variant.mjs +1 -0
  170. package/dist/exports/tests/packages/appos/src/api/workflows/generate-preview.mjs +1 -0
  171. package/dist/exports/tests/packages/appos/src/api/workflows/purge-attachment.mjs +1 -0
  172. package/dist/exports/tests/packages/appos/src/api/workflows/purge-audit-logs.mjs +1 -0
  173. package/dist/exports/tests/packages/appos/src/api/workflows/purge-unattached-blobs.mjs +1 -0
  174. package/dist/exports/tests/packages/appos/src/api/workflows/track-db-changes.mjs +1 -0
  175. package/dist/exports/tests/packages/appos/src/constants.mjs +1 -0
  176. package/dist/exports/tests/packages/appos/src/instrumentation.d.mts +7 -0
  177. package/dist/exports/tests/packages/appos/src/instrumentation.mjs +1 -0
  178. package/dist/exports/tests/react.d.mts +2 -0
  179. package/dist/exports/tests/react.mjs +1 -0
  180. package/dist/exports/tests/setup.d.mts +1 -0
  181. package/dist/exports/tests/setup.mjs +1 -0
  182. package/dist/exports/vendors/date.js +1 -0
  183. package/dist/exports/vendors/toolkit.js +1 -0
  184. package/dist/exports/vendors/zod.d.ts +1 -0
  185. package/dist/exports/vendors/zod.js +1 -0
  186. package/dist/exports/vite/index.d.mts +19 -0
  187. package/dist/exports/vite/index.mjs +1 -0
  188. package/dist/exports/vitest/config.d.mts +1 -0
  189. package/dist/exports/vitest/config.mjs +1 -0
  190. package/dist/exports/vitest/globals.d.mts +1 -0
  191. package/dist/exports/vitest/globals.mjs +1 -0
  192. package/dist/exports/vitest/index.d.mts +1 -0
  193. package/dist/exports/vitest/index.mjs +1 -0
  194. package/dist/exports/web/api/auth.d.ts +125 -0
  195. package/dist/exports/web/api/database.d.ts +4 -0
  196. package/dist/exports/web/api/logger.d.ts +1 -0
  197. package/dist/exports/web/auth.d.ts +2388 -0
  198. package/dist/exports/web/auth.js +1 -0
  199. package/dist/exports/web/i18n.d.ts +42 -0
  200. package/dist/exports/web/i18n.js +1 -0
  201. package/dist/exports/web/index.d.ts +6 -0
  202. package/dist/exports/web/index.js +1 -0
  203. package/package.json +138 -98
  204. package/build/bin/main.mjs +0 -2
  205. package/build/exports/cli/index.d.mts +0 -325
  206. package/build/exports/cli/index.mjs +0 -1
  207. package/build/exports/instrumentation/execAsync-DaIUcs6_.mjs +0 -1
  208. package/build/exports/instrumentation/getMachineId-bsd-bB6ipDhm.mjs +0 -1
  209. package/build/exports/instrumentation/getMachineId-darwin-D1Bx5aCe.mjs +0 -2
  210. package/build/exports/instrumentation/getMachineId-linux-D_R9Tla0.mjs +0 -1
  211. package/build/exports/instrumentation/getMachineId-unsupported-BZKPE_Ev.mjs +0 -1
  212. package/build/exports/instrumentation/getMachineId-win-CmPvIqHL.mjs +0 -1
  213. package/build/exports/instrumentation/instrumentation.d.mts +0 -1
  214. package/build/exports/instrumentation/instrumentation.mjs +0 -80
  215. package/build/exports/server/index.d.mts +0 -327
  216. package/build/exports/server/index.mjs +0 -219
  217. package/build/exports/server/react-gPO8Jsy-.mjs +0 -13
  218. package/build/exports/server/server.node-D_9RYjm9.mjs +0 -210
  219. package/build/exports/store/index.d.mts +0 -58
  220. package/build/exports/store/index.mjs +0 -15
  221. package/build/exports/support/datetime.js +0 -1
  222. package/build/exports/support/utils.js +0 -1
  223. package/build/exports/support/zod.d.ts +0 -2
  224. package/build/exports/support/zod.js +0 -23
  225. package/build/exports/test/dist-DAsoCGWk.mjs +0 -348
  226. package/build/exports/test/index.d.mts +0 -3
  227. package/build/exports/test/index.mjs +0 -1
  228. package/build/exports/test/magic-string.es-BWgiB2kd.mjs +0 -14
  229. package/build/exports/test/setup.d.mts +0 -1
  230. package/build/exports/test/setup.mjs +0 -329
  231. /package/{build/exports/support/datetime.d.ts → dist/exports/vendors/date.d.ts} +0 -0
  232. /package/{build/exports/support/utils.d.ts → dist/exports/vendors/toolkit.d.ts} +0 -0
@@ -0,0 +1,70 @@
1
+ import Mail from "nodemailer/lib/mailer/index.ts";
2
+ import { JSX } from "react";
3
+
4
+ //#region src/api/mailer.d.ts
5
+
6
+ /**
7
+ * The mailer type.
8
+ */
9
+ type Mailer = ReturnType<typeof defineMailer>;
10
+ /**
11
+ * The mailer payload type with React component.
12
+ */
13
+ type MailerPayloadReact = Omit<Mail.Options, "from" | "html" | "text"> & {
14
+ /**
15
+ * The email address to send the email from.
16
+ */
17
+ from?: string;
18
+ /**
19
+ * The React component to render as the email body.
20
+ */
21
+ react: JSX.Element;
22
+ };
23
+ /**
24
+ * The mailer payload type with direct HTML and text.
25
+ */
26
+ type MailerPayloadHtml = Omit<Mail.Options, "from"> & {
27
+ /**
28
+ * The email address to send the email from.
29
+ */
30
+ from?: string;
31
+ /**
32
+ * The HTML content of the email.
33
+ */
34
+ html: string;
35
+ /**
36
+ * The plain text content of the email.
37
+ */
38
+ text: string;
39
+ };
40
+ /**
41
+ * The mailer payload type - supports either React component or direct HTML+text.
42
+ */
43
+ type MailerPayload = MailerPayloadReact | MailerPayloadHtml;
44
+ /**
45
+ * Define the options for the mailer.
46
+ */
47
+ interface DefineMailerOptions {
48
+ /**
49
+ * The default email address to use as the sender.
50
+ */
51
+ from: string;
52
+ /**
53
+ * The SMTP URL to use for sending emails.
54
+ */
55
+ smtpUrl: string;
56
+ }
57
+ /**
58
+ * Define the mailer.
59
+ *
60
+ * @param env - The environment variables.
61
+ * @returns The mailer.
62
+ */
63
+ declare function defineMailer({
64
+ from,
65
+ smtpUrl
66
+ }: DefineMailerOptions): {
67
+ send(payload: MailerPayload): Promise<void>;
68
+ };
69
+ //#endregion
70
+ export { DefineMailerOptions, Mailer, MailerPayload, MailerPayloadHtml, MailerPayloadReact, defineMailer };
@@ -0,0 +1 @@
1
+ import{render as e}from"@react-email/render";import{createTransport as t}from"nodemailer";function n({from:n,smtpUrl:r}){let i=t({url:r});return{async send(t){let r,a,o;if(`react`in t){[r,a]=await Promise.all([e(t.react),e(t.react,{plainText:!0})]);let{react:n,...i}=t;o=i}else{r=t.html,a=t.text;let{html:e,text:n,...i}=t;o=i}await i.sendMail({from:t.from||n,...o,html:r,text:a})}}}export{n as defineMailer};
@@ -0,0 +1,24 @@
1
+ import "../logger.mjs";
2
+ import { RequestHandler } from "ultimate-express";
3
+
4
+ //#region src/api/middleware/request-logger.d.ts
5
+
6
+ /**
7
+ * Metadata about the HTTP request.
8
+ */
9
+ interface RequestMetadata {
10
+ /**
11
+ * Client's IP address from X-Forwarded-For or RemoteAddr.
12
+ */
13
+ ipAddress: string;
14
+ /**
15
+ * Client's User-Agent header.
16
+ */
17
+ userAgent: string;
18
+ /**
19
+ * Client IP's country from CF-IPCountry header.
20
+ */
21
+ country: string;
22
+ }
23
+ //#endregion
24
+ export { RequestMetadata };
@@ -0,0 +1,39 @@
1
+ import { AppContainer } from "./container.mjs";
2
+ import { Express, RequestHandler } from "ultimate-express";
3
+
4
+ //#region src/api/middleware.d.ts
5
+ interface Middleware {
6
+ name: string | null;
7
+ handler: (container: AppContainer) => RequestHandler;
8
+ }
9
+ /**
10
+ * Defines a user middleware loaded from api/middleware/ directory.
11
+ *
12
+ * Use numeric prefixes (000_, 001_, etc.) to control load order.
13
+ *
14
+ * @example
15
+ * // api/middleware/000_custom-auth.ts
16
+ * export default defineMiddleware({
17
+ * handler: (container) => (req, res, next) => {
18
+ * // Custom logic using container
19
+ * next();
20
+ * },
21
+ * });
22
+ */
23
+ declare function defineMiddleware(config: {
24
+ name?: string;
25
+ handler: (container: AppContainer) => RequestHandler;
26
+ }): Middleware;
27
+ /**
28
+ * Loads user middleware from a directory and registers them with the app.
29
+ *
30
+ * Middleware files are loaded in alphabetical order by filename.
31
+ * Use numeric prefixes (000_, 001_, etc.) to control the load order.
32
+ *
33
+ * @param middlewareDir - The directory containing middleware files
34
+ * @param container - The application container
35
+ * @param app - The Express application instance
36
+ */
37
+ declare function loadMiddleware(middlewareDir: string, container: AppContainer, app: Express): Promise<void>;
38
+ //#endregion
39
+ export { Middleware, defineMiddleware, loadMiddleware };
@@ -0,0 +1 @@
1
+ import{camelCase as e}from"./node_modules/.bun/change-case@5.4.4/node_modules/change-case/dist/index.mjs";import{basename as t}from"node:path";import n,{glob as r}from"node:fs/promises";function i(e){return{name:e.name??null,handler:e.handler}}function a(n){return e(t(n,`.ts`).replace(/^\d+_/,``))}async function o(e,i,o){try{await n.access(e)}catch{return}let s=[];for await(let t of r(`${e}/**/*.ts`))!t.endsWith(`.test.ts`)&&!t.endsWith(`.spec.ts`)&&s.push(t);s.sort((e,n)=>t(e).localeCompare(t(n)));for(let e of s)try{let t=(await import(e)).default;if(t&&typeof t.handler==`function`){let n=t.name??a(e);i.logger.debug({name:n,file:e},`Loading user middleware`),o.use(t.handler(i))}else i.logger.warn({file:e},`Middleware file missing default export with handler function`)}catch(t){throw i.logger.error({file:e,error:t instanceof Error?t.message:t},`Failed to load middleware`),t}}export{i as defineMiddleware,o as loadMiddleware};
@@ -0,0 +1 @@
1
+ const e=/([\p{Ll}\d])(\p{Lu})/gu,t=/(\p{Lu})([\p{Lu}][\p{Ll}])/gu,n=/(\d)\p{Ll}|(\p{L})\d/u,r=/[^\p{L}\d]+/giu,i=`$1\0$2`;function a(n){let a=n.trim();a=a.replace(e,i).replace(t,i),a=a.replace(r,`\0`);let o=0,s=a.length;for(;a.charAt(o)===`\0`;)o++;if(o===s)return[];for(;a.charAt(s-1)===`\0`;)s--;return a.slice(o,s).split(/\0/g)}function o(e){let t=a(e);for(let e=0;e<t.length;e++){let r=t[e],i=n.exec(r);if(i){let n=i.index+(i[1]??i[2]).length;t.splice(e,1,r.slice(0,n),r.slice(n))}}return t}function s(e,t){let[n,r,i]=f(e,t),a=c(t?.locale),o=l(t?.locale),s=t?.mergeAmbiguousCharacters?u(a,o):d(a,o);return n+r.map((e,t)=>t===0?a(e):s(e,t)).join(t?.delimiter??``)+i}function c(e){return e===!1?e=>e.toLowerCase():t=>t.toLocaleLowerCase(e)}function l(e){return e===!1?e=>e.toUpperCase():t=>t.toLocaleUpperCase(e)}function u(e,t){return n=>`${t(n[0])}${e(n.slice(1))}`}function d(e,t){return(n,r)=>{let i=n[0];return(r>0&&i>=`0`&&i<=`9`?`_`+i:t(i))+e(n.slice(1))}}function f(e,t={}){let n=t.split??(t.separateNumbers?o:a),r=t.prefixCharacters??``,i=t.suffixCharacters??``,s=0,c=e.length;for(;s<e.length;){let t=e.charAt(s);if(!r.includes(t))break;s++}for(;c>s;){let t=c-1,n=e.charAt(t);if(!i.includes(n))break;c=t}return[e.slice(0,s),n(e.slice(s,c)),e.slice(c)]}export{s as camelCase};
@@ -0,0 +1,271 @@
1
+ import { Container } from "./container.mjs";
2
+ import { AppContext } from "./app-context.mjs";
3
+ import { z } from "zod";
4
+ import { Express, Request, RequestHandler } from "ultimate-express";
5
+ import * as _node_modules_zod_openapi_dist_components_B1DX_zYv_mjs0 from "#node_modules/zod-openapi/dist/components-B1DX_zYv.mjs";
6
+
7
+ //#region src/api/openapi.d.ts
8
+ declare const appDir: string;
9
+ /**
10
+ * Utility type to enforce exact type matching (no extra properties).
11
+ * This uses a tuple check to prevent objects with extra keys from being assigned.
12
+ * Arrays are handled specially to avoid treating numeric indices as object keys.
13
+ */
14
+ type Exact<T, Expected> = [T] extends [Expected] ? [Expected] extends [T] ? T : T extends readonly unknown[] ? Expected extends readonly unknown[] ? T extends readonly (infer TItem)[] ? Expected extends readonly (infer ExpectedItem)[] ? readonly Exact<TItem, ExpectedItem>[] : T : T : { [K in keyof T]: K extends keyof Expected ? Exact<T[K], Expected[K]> : ["Error: unexpected key", K] } : { [K in keyof T]: K extends keyof Expected ? Exact<T[K], Expected[K]> : ["Error: unexpected key", K] } : T;
15
+ /**
16
+ * Response marker type for Express compatibility.
17
+ */
18
+ type ResponseMarker<T = unknown> = {
19
+ __response: true;
20
+ status: number;
21
+ data: T;
22
+ };
23
+ /**
24
+ * Define typed response builders based on defined response schemas.
25
+ */
26
+ declare function defineTypedResponses<TResponses extends Record<number, {
27
+ description: string;
28
+ schema: z.ZodSchema;
29
+ }>>(responses: TResponses): { [K in keyof TResponses as GetMethodName<K>]: K extends number ? TResponses[K]["schema"] extends z.ZodNull ? () => ResponseMarker<null> : <T extends z.infer<TResponses[K]["schema"]>>(data: Exact<T, z.infer<TResponses[K]["schema"]>>) => ResponseMarker<z.infer<TResponses[K]["schema"]>> : never } & {
30
+ status: <S extends keyof TResponses & number>(statusCode: S, data: TResponses[S]["schema"] extends z.ZodNull ? undefined : Exact<z.infer<TResponses[S]["schema"]>, z.infer<TResponses[S]["schema"]>>) => ResponseMarker;
31
+ };
32
+ type GetMethodName<K$1> = K$1 extends 200 ? "ok" : K$1 extends 201 ? "created" : K$1 extends 202 ? "accepted" : K$1 extends 204 ? "noContent" : K$1 extends 400 ? "badRequest" : K$1 extends 401 ? "unauthorized" : K$1 extends 403 ? "forbidden" : K$1 extends 404 ? "notFound" : K$1 extends 409 ? "conflict" : K$1 extends 422 ? "unprocessableEntity" : K$1 extends 500 ? "internalServerError" : never;
33
+ /**
34
+ * Handler parameters with full type safety for request inputs.
35
+ */
36
+ type HandlerParams<TParams extends z.ZodSchema | undefined = undefined, TQuery extends z.ZodSchema | undefined = undefined, TBody extends z.ZodSchema | undefined = undefined, THeaders extends z.ZodSchema | undefined = undefined, TResponses extends Record<number, {
37
+ description: string;
38
+ schema: z.ZodSchema;
39
+ }> = Record<number, {
40
+ description: string;
41
+ schema: z.ZodSchema;
42
+ }>> = {
43
+ ctx: AppContext;
44
+ body: TBody extends z.ZodSchema ? z.infer<TBody> : unknown;
45
+ headers: THeaders extends z.ZodSchema ? z.infer<THeaders> : Record<string, string>;
46
+ params: TParams extends z.ZodSchema ? z.infer<TParams> : Record<string, unknown>;
47
+ query: TQuery extends z.ZodSchema ? z.infer<TQuery> : Record<string, unknown>;
48
+ request: Request;
49
+ response: ReturnType<typeof defineTypedResponses<TResponses>>;
50
+ };
51
+ /**
52
+ * Helper function to define an OpenAPI endpoint with full type safety.
53
+ */
54
+ declare function defineOpenAPIEndpoint<TParams extends z.ZodSchema | undefined = undefined, TQuery extends z.ZodSchema | undefined = undefined, TBody extends z.ZodSchema | undefined = undefined, THeaders extends z.ZodSchema | undefined = undefined, TResponses extends Record<number, {
55
+ description: string;
56
+ schema: z.ZodSchema;
57
+ }> = Record<number, {
58
+ description: string;
59
+ schema: z.ZodSchema;
60
+ }>>(spec: {
61
+ summary?: string;
62
+ description?: string;
63
+ params?: TParams;
64
+ query?: TQuery;
65
+ requestBody?: TBody;
66
+ headers?: THeaders;
67
+ responses: TResponses;
68
+ handler: (params: HandlerParams<TParams, TQuery, TBody, THeaders, TResponses>) => Promise<ResponseMarker>;
69
+ }): {
70
+ summary?: string;
71
+ description?: string;
72
+ params?: TParams;
73
+ query?: TQuery;
74
+ requestBody?: TBody;
75
+ headers?: THeaders;
76
+ responses: TResponses;
77
+ handler: (params: HandlerParams<TParams, TQuery, TBody, THeaders, TResponses>) => Promise<ResponseMarker>;
78
+ };
79
+ /**
80
+ * OpenAPI method specification type (for internal use).
81
+ */
82
+ type OpenAPIMethodSpec = {
83
+ summary?: string;
84
+ description?: string;
85
+ params?: z.ZodSchema;
86
+ query?: z.ZodSchema;
87
+ requestBody?: z.ZodSchema;
88
+ headers?: z.ZodSchema;
89
+ responses: Record<number, {
90
+ description: string;
91
+ schema: z.ZodSchema;
92
+ }>;
93
+ handler: (params: HandlerParams<any, any, any, any, any>) => Promise<ResponseMarker>;
94
+ };
95
+ /**
96
+ * Configuration object for defineOpenApi.
97
+ */
98
+ type DefineOpenAPIConfig = { [K in "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE"]?: OpenAPIMethodSpec };
99
+ /**
100
+ * OpenAPI configuration for document-level settings
101
+ */
102
+ type OpenAPIObjectConfigV31 = {
103
+ info: {
104
+ title: string;
105
+ version: string;
106
+ description?: string;
107
+ contact?: {
108
+ name?: string;
109
+ email?: string;
110
+ url?: string;
111
+ };
112
+ license?: {
113
+ name: string;
114
+ url?: string;
115
+ };
116
+ };
117
+ servers?: Array<{
118
+ url: string;
119
+ description?: string;
120
+ }>;
121
+ openapi: "3.1.0";
122
+ };
123
+ /**
124
+ * Simplified config input for defineOpenAPIConfig
125
+ */
126
+ type DefineOpenAPIConfigInput = {
127
+ info: OpenAPIObjectConfigV31["info"];
128
+ servers?: OpenAPIObjectConfigV31["servers"];
129
+ };
130
+ /**
131
+ * OpenAPI registration format (without path - CLI will add it)
132
+ */
133
+ type OpenAPIRegistration = {
134
+ method: "get" | "post" | "put" | "patch" | "delete" | "head";
135
+ summary?: string;
136
+ description?: string;
137
+ request?: {
138
+ params?: z.ZodSchema;
139
+ query?: z.ZodSchema;
140
+ body?: z.ZodSchema;
141
+ headers?: z.ZodSchema;
142
+ };
143
+ responses: Record<number, {
144
+ description: string;
145
+ content: {
146
+ "application/json": {
147
+ schema: z.ZodSchema;
148
+ };
149
+ };
150
+ }>;
151
+ };
152
+ /**
153
+ * Return type for defineOpenAPI function
154
+ */
155
+ type DefineOpenAPIReturn = {
156
+ handlers: Record<string, RequestHandler>;
157
+ openAPISpec: OpenAPIRegistration[];
158
+ };
159
+ /**
160
+ * RFC 9457 compliant validation error response
161
+ */
162
+ type ValidationErrorResponse = {
163
+ error: "validation_error";
164
+ status: number;
165
+ detail: string;
166
+ errors: Array<{
167
+ field: string;
168
+ message: string;
169
+ received: unknown;
170
+ }>;
171
+ };
172
+ /**
173
+ * Define OpenAPI-based route handlers with full type safety.
174
+ *
175
+ * @param config Configuration object with HTTP method specifications
176
+ * @returns Object containing Express handlers and openAPISpec
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * // Basic usage
181
+ * export default defineOpenAPI({
182
+ * GET: {
183
+ * summary: "Get user by ID",
184
+ * params: z.object({ id: z.uuid() }),
185
+ * responses: {
186
+ * 200: { description: "User data", schema: UserSchema }
187
+ * },
188
+ * handler: async ({ params, response }) => {
189
+ * const user = await getUser(params.id);
190
+ * return response.ok(user); // Fully typed!
191
+ * }
192
+ * },
193
+ * POST: {
194
+ * summary: "Create user",
195
+ * requestBody: CreateUserSchema,
196
+ * responses: {
197
+ * 201: { description: "User created", schema: UserSchema }
198
+ * },
199
+ * handler: async ({ body, response }) => {
200
+ * const user = await createUser(body);
201
+ * return response.created(user); // Fully typed!
202
+ * }
203
+ * }
204
+ * });
205
+ * ```
206
+ */
207
+ declare function defineOpenAPI(config: DefineOpenAPIConfig): DefineOpenAPIReturn;
208
+ /**
209
+ * Define OpenAPI document configuration with improved DX.
210
+ *
211
+ * Only allows specifying info and servers objects, ensuring a consistent
212
+ * OpenAPI v3.1.0 structure while preventing configuration of other fields.
213
+ *
214
+ * @param config Configuration object with info and optional servers
215
+ * @returns Complete OpenAPI configuration object
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * export const openAPIConfig = defineOpenAPIConfig({
220
+ * info: {
221
+ * title: "My API",
222
+ * version: "1.0.0",
223
+ * description: "API v1 - Authentication and core features",
224
+ * contact: {
225
+ * name: "API Support",
226
+ * email: "support@example.com",
227
+ * },
228
+ * },
229
+ * servers: [
230
+ * {
231
+ * url: process.env.API_URL || "http://localhost:8000",
232
+ * description: "API Server",
233
+ * },
234
+ * ],
235
+ * });
236
+ * ```
237
+ */
238
+ declare function defineOpenAPIConfig<TContainer extends Container = Container>(config: (container: TContainer) => DefineOpenAPIConfigInput): (container: TContainer) => OpenAPIObjectConfigV31;
239
+ /**
240
+ * Route module type for scanned API routes
241
+ */
242
+ type RouteModule = {
243
+ path: string;
244
+ filePath: string;
245
+ handlers: Record<string, RequestHandler>;
246
+ openAPISpec: OpenAPIRegistration[];
247
+ version?: string;
248
+ };
249
+ /**
250
+ * Generate complete OpenAPI 3.1.0 document from routes using zod-openapi
251
+ */
252
+ declare function generateOpenAPIDocument(routes: RouteModule[], version: string, config?: DefineOpenAPIConfigInput): _node_modules_zod_openapi_dist_components_B1DX_zYv_mjs0.it;
253
+ /**
254
+ * Scan routes directory and convert to Express route paths using remix-flat-routes.
255
+ */
256
+ declare function scanAPIRoutes(container: Container): Promise<RouteModule[]>;
257
+ /**
258
+ * Register scanned routes with Express app.
259
+ */
260
+ declare function registerRoutes(app: Express, routes: RouteModule[]): void;
261
+ /**
262
+ * Write OpenAPI specs to api/public/openapi directory.
263
+ */
264
+ declare function writeOpenAPISpecs<TContainer extends Container>(container: TContainer, routes: RouteModule[]): Promise<void>;
265
+ /**
266
+ * Load and register API routes with Express (convenience function).
267
+ * Also auto-generates OpenAPI specs in development mode.
268
+ */
269
+ declare function loadAndRegisterAPIRoutes<TContainer extends Container>(app: Express): Promise<void>;
270
+ //#endregion
271
+ export { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse, appDir, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineTypedResponses, generateOpenAPIDocument, loadAndRegisterAPIRoutes, registerRoutes, scanAPIRoutes, writeOpenAPISpecs };
@@ -0,0 +1 @@
1
+ import{defineAppContext as e}from"./app-context.mjs";import{PUBLIC_DIR as t}from"./packages/appos/src/constants.mjs";import{z as n}from"zod";import{join as r,resolve as i}from"node:path";import{access as a,mkdir as o,writeFile as s}from"node:fs/promises";import{remixRoutesOptionAdapter as c}from"@react-router/remix-routes-option-adapter";import{isEmpty as l}from"es-toolkit/compat";import{flatRoutes as u}from"remix-flat-routes";import{createDocument as d}from"zod-openapi";const f=`${process.env.NODE_ENV===`production`?`./build`:`.`}`,p=`routes`,m=i(`${f}/${t}/openapi`);function h(e){let t={};for(let[r,i]of Object.entries(e)){let e=Number(r),a=g(e);a&&(t[a]=t=>{let r=i.schema;if(r instanceof n.ZodNull||t==null)return{__response:!0,status:e,data:t??null};try{let i=r;if(r instanceof n.ZodObject)i=r.strict();else if(r instanceof n.ZodArray){let e=r.element;e instanceof n.ZodObject&&(i=n.array(e.strict()))}return{__response:!0,status:e,data:i.parse(t)}}catch(r){throw r instanceof n.ZodError?Error(`Response validation failed for status ${e}: ${JSON.stringify(r.issues,null,2)}\n\nData provided: ${JSON.stringify(t,null,2)}`):r}})}return t.status=(t,r)=>{let i=Number(t),a=e[t];if(!a)return{__response:!0,status:i,data:r??null};let o=a.schema;if(!o||o instanceof n.ZodNull||r==null)return{__response:!0,status:i,data:r??null};try{let e=o;if(o instanceof n.ZodObject)e=o.strict();else if(o instanceof n.ZodArray){let t=o.element;t instanceof n.ZodObject&&(e=n.array(t.strict()))}return{__response:!0,status:i,data:e.parse(r)}}catch(e){throw e instanceof n.ZodError?Error(`Response validation failed for status ${i}: ${JSON.stringify(e.issues,null,2)}\n\nData provided: ${JSON.stringify(r,null,2)}`):e}},t}function g(e){return{200:`ok`,201:`created`,202:`accepted`,204:`noContent`,400:`badRequest`,401:`unauthorized`,403:`forbidden`,404:`notFound`,409:`conflict`,422:`unprocessableEntity`,500:`internalServerError`}[e]||null}function _(e){return e}function v(e,t){return e?e.parse(t):t}function y(e,t){let n={};for(let[e,r]of t.searchParams.entries()){let t=n[e];t===void 0?n[e]=r:Array.isArray(t)?t.push(r):n[e]=[t,r]}return e?e.parse(n):n}function b(e,t){let n=t.body;return e?e.parse(n):n}function x(e,t){let n=t.headers;return e?e.parse(n):n}function S(e){switch(e){case`params`:case`query`:case`headers`:return 400;case`body`:return 422;default:return 400}}function C(e,t){let n=S(t);return{__response:!0,status:n,data:{error:`validation_error`,status:n,detail:`Request validation failed`,errors:e.issues.map(e=>({field:e.path.join(`.`),message:e.message,received:`received`in e?e.received:e.input}))}}}function w(t,r){return async(i,a,o)=>{try{let n=new URL(i.url||`/`,`http://${i.headers.host}`),r=v(t.params,i.params),o=y(t.query,n),s=b(t.requestBody,i),c=x(t.headers,i),l=h(t.responses),u=await e({apiKey:i.apiKey,container:i.app.locals.container,request:i,fetchSession:!1}),d=await t.handler({ctx:u,body:s,headers:c,params:r,query:o,request:i,response:l});if(d&&typeof d==`object`&&`__response`in d){let e=d;e.data===null||e.data===void 0?a.status(e.status).end():a.status(e.status).json(e.data)}else a.status(200).json(d)}catch(e){if(e instanceof n.ZodError){let t=C(e,r===`GET`||r===`HEAD`?`query`:`body`);a.status(t.status).json(t.data)}else o(e)}}}function T(e){let t=[];for(let n of[`GET`,`HEAD`,`POST`,`PUT`,`PATCH`,`DELETE`]){let r=e[n];if(!r)continue;let i={};r.params&&(i.params=r.params),r.query&&(i.query=r.query),r.requestBody&&(i.body=r.requestBody),r.headers&&(i.headers=r.headers);let a={};for(let[e,t]of Object.entries(r.responses))a[Number(e)]={description:t.description,content:{"application/json":{schema:t.schema}}};t.push({method:n.toLowerCase(),summary:r.summary,description:r.description,request:Object.keys(i).length>0?i:void 0,responses:a})}return t}function E(e){let t={};for(let n of[`GET`,`HEAD`,`POST`,`PUT`,`PATCH`,`DELETE`]){let r=e[n];r&&(t[n]=w(r,n))}return{handlers:t,openAPISpec:T(e)}}function D(e){return t=>{let n=e(t);return{info:n.info,servers:n.servers,openapi:`3.1.0`}}}function O(e){return e.match(/^\/(v\d+)/)?.[1]}function k(e){return e.replace(/:(\w+)/g,`{$1}`)}function A(e,t){let n=k(e),r={summary:t.summary,description:t.description};(t.request?.params||t.request?.query||t.request?.headers)&&(r.requestParams={},t.request.params&&(r.requestParams.path=t.request.params),t.request.query&&(r.requestParams.query=t.request.query),t.request.headers&&(r.requestParams.header=t.request.headers)),t.request?.body&&(r.requestBody={content:{"application/json":{schema:t.request.body}}}),r.responses={};for(let[e,n]of Object.entries(t.responses))r.responses[e]={description:n.description,content:{"application/json":{schema:n.content[`application/json`].schema}}};return{path:n,config:r}}function j(e,t,n){let r={};for(let n of e){if(n.version!==t)continue;let e=n.path.replace(`/${t}`,``)||`/`;for(let t of n.openAPISpec){let{path:n,config:i}=A(e,t);r[n]||(r[n]={}),r[n][t.method]=i}}return d({openapi:`3.1.0`,info:n?.info||{title:`API ${t.toUpperCase()}`,version:t.replace(`v`,``),description:`OpenAPI specification for ${t} API`},servers:n?.servers||[{url:`http://localhost:8000/${t}`,description:process.env.NODE_ENV===`production`?`Production server`:`Development server`}],paths:r})}async function M(e){let t=i(`${f}/${p}`);try{await a(t)}catch(t){return e.logger.error({error:t},`OpenAPI routes directory not found`),[]}let n=await c(e=>u(p,e,{appDir:f,ignoredRouteFiles:[`**/.*`,`**/*.{spec,test}.{ts,tsx}`,`**/*-????????.{js,ts}`]})),r=[];for(let[t,a]of Object.entries(n)){let t=i(`${f}/${a.file}`).replace(/.ts$/,process.env.NODE_ENV===`production`?`.js`:`.ts`);try{let n=(await import(t)).default;if(!n||l(n)||/\/openapi.(j|t)s$/.test(t))continue;if(!n?.handlers&&!n?.openAPISpec){e.logger.warn(`Missing default export with 'defineOpenAPI' for '${f}/${a.file}'`);continue}let i=`/${a.path}`;e.logger.info(`Registering route: ${i} from ${a.file}`),r.push({path:i,filePath:t,handlers:n.handlers,openAPISpec:n.openAPISpec,version:O(i)})}catch(t){e.logger.error(t,`Error loading route ${a.file}:`)}}return r}function N(e,t){for(let n of t)for(let[t,r]of Object.entries(n.handlers))e[t.toLowerCase()](n.path,r)}async function P(e,t){let n=i(`${f}/${p}/${t}+/openapi.ts`);try{let t=(await import(n)).default;return t?t(e):void 0}catch{return}}async function F(e,t){let n=[...new Set(t.map(e=>e.version).filter(Boolean))];n.length>0&&await o(m,{recursive:!0});for(let i of n){let n=j(t,i,await P(e,i));await s(r(m,`${i}.json`),JSON.stringify(n,null,2),`utf-8`)}}async function I(e){let t=await M(e.locals.container);N(e,t),process.env.NODE_ENV!==`production`&&await F(e.locals.container,t)}export{f as appDir,E as defineOpenAPI,D as defineOpenAPIConfig,_ as defineOpenAPIEndpoint,h as defineTypedResponses,j as generateOpenAPIDocument,I as loadAndRegisterAPIRoutes,N as registerRoutes,M as scanAPIRoutes,F as writeOpenAPISpecs};
@@ -0,0 +1,13 @@
1
+ import { __export, __reExport } from "./_virtual/rolldown_runtime.mjs";
2
+ import { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas } from "drizzle-orm/pg-core";
3
+ export * from "drizzle-orm";
4
+ export * from "drizzle-seed";
5
+
6
+ //#region src/api/orm.d.ts
7
+ declare namespace orm_d_exports {
8
+ export { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas };
9
+ }
10
+ import * as import_drizzle_orm from "drizzle-orm";
11
+ import * as import_drizzle_seed from "drizzle-seed";
12
+ //#endregion
13
+ export { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, orm_d_exports, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas };
@@ -0,0 +1 @@
1
+ import{__export as e,__reExport as t}from"./_virtual/rolldown_runtime.mjs";import{index as n,isPgEnum as r,isPgMaterializedView as i,isPgSchema as a,isPgSequence as o,isPgView as s,numeric as c,parsePgArray as l,parsePgNestedArray as u,pgEnum as d,pgMaterializedView as f,pgPolicy as p,pgRole as m,pgSchema as h,pgSequence as g,pgTable as _,pgTableCreator as v,pgView as y,serial as b,smallint as x,smallserial as S,sparsevec as C,unique as w,uniqueIndex as T,uniqueKeyName as E,withReplicas as D}from"drizzle-orm/pg-core";export*from"drizzle-orm";export*from"drizzle-seed";var O=e({index:()=>n,isPgEnum:()=>r,isPgMaterializedView:()=>i,isPgSchema:()=>a,isPgSequence:()=>o,isPgView:()=>s,numeric:()=>c,parsePgArray:()=>l,parsePgNestedArray:()=>u,pgEnum:()=>d,pgMaterializedView:()=>f,pgPolicy:()=>p,pgRole:()=>m,pgSchema:()=>h,pgSequence:()=>g,pgTable:()=>_,pgTableCreator:()=>v,pgView:()=>y,serial:()=>b,smallint:()=>x,smallserial:()=>S,sparsevec:()=>C,unique:()=>w,uniqueIndex:()=>T,uniqueKeyName:()=>E,withReplicas:()=>D});import*as k from"drizzle-orm";t(O,k);import*as A from"drizzle-seed";t(O,A);export{n as index,r as isPgEnum,i as isPgMaterializedView,a as isPgSchema,o as isPgSequence,s as isPgView,c as numeric,O as orm_exports,l as parsePgArray,u as parsePgNestedArray,d as pgEnum,f as pgMaterializedView,p as pgPolicy,m as pgRole,h as pgSchema,g as pgSequence,_ as pgTable,v as pgTableCreator,y as pgView,b as serial,x as smallint,S as smallserial,C as sparsevec,w as unique,T as uniqueIndex,E as uniqueKeyName,D as withReplicas};
@@ -0,0 +1,40 @@
1
+ import { instrumentation_d_exports } from "./packages/appos/src/instrumentation.mjs";
2
+
3
+ //#region src/api/otel.d.ts
4
+
5
+ /**
6
+ * Wraps an async function with an OpenTelemetry span for distributed tracing.
7
+ *
8
+ * Automatically handles span lifecycle (start/end), error recording, and context propagation.
9
+ * The span will appear as a child of the currently active span (if any).
10
+ *
11
+ * @param tracerName - Fully qualified module path (e.g., "api/routes/payouts", "packages/primitives/mailer")
12
+ * @param spanName - Operation name following {verb} {object} pattern (e.g., "fetch payouts", "send email")
13
+ * @param fn - The async function to execute within the span context. Receives span for custom attributes.
14
+ * @param attributes - Optional span attributes for high-cardinality data (IDs, counts, etc.).
15
+ * Use semantic conventions: https://opentelemetry.io/docs/specs/semconv/
16
+ * @returns Promise resolving to the function's return value.
17
+ *
18
+ * @example
19
+ * // Basic usage - simple business operation
20
+ * await withOtelSpan("api/routes/payouts", "fetch payouts", async () => {
21
+ * return await db.query.payouts.findMany();
22
+ * });
23
+ *
24
+ * @example
25
+ * // With attributes and custom span data
26
+ * const payouts = await withOtelSpan(
27
+ * "api/routes/payouts",
28
+ * "fetch payouts",
29
+ * async (span) => {
30
+ * const results = await db.query.payouts.findMany();
31
+ * span.setAttribute("payouts.count", results.length);
32
+ * span.addEvent("cache.miss");
33
+ * return results;
34
+ * },
35
+ * { "payouts.limit": 100, "payouts.offset": 0 }
36
+ * );
37
+ */
38
+ declare function withOtelSpan<T>(fn: (span: instrumentation_d_exports.Span) => Promise<T>, attributes?: Record<string, string | number | boolean>): Promise<T>;
39
+ //#endregion
40
+ export { withOtelSpan };
@@ -0,0 +1 @@
1
+ import{instrumentation_exports as e}from"./packages/appos/src/instrumentation.mjs";import{getCallSites as t}from"node:util";async function n(n,r){let i=t()[1],a=i.scriptName.replace(process.cwd(),``).replace(`file:///`,``),o=i.functionName,s=e.trace.getTracer(a.replace(`build/`,``)).startSpan(o,{attributes:r}),c=e.trace.setSpan(e.context.active(),s);try{let t=await e.context.with(c,()=>n(s));return s.end(),t}catch(e){throw s.recordException(e),s.end(),e}}export{n as withOtelSpan};
@@ -0,0 +1 @@
1
+ const e=`api`,t=`databases`,n=`workflows`,r=`events`,i=`public`,a=`locales`;export{e as APPOS_DIR,t as DATABASES_DIR,r as EVENTS_DIR,a as LOCALES_DIR,i as PUBLIC_DIR,n as WORKFLOWS_DIR};
@@ -0,0 +1,7 @@
1
+ export * from "@opentelemetry/api";
2
+
3
+ //#region src/instrumentation.d.ts
4
+
5
+ import * as import__opentelemetry_api from "@opentelemetry/api";
6
+ //#endregion
7
+ export { import__opentelemetry_api as instrumentation_d_exports };
@@ -0,0 +1 @@
1
+ import{__reExport as e}from"../../../_virtual/rolldown_runtime.mjs";import{register as t}from"node:module";import{getNodeAutoInstrumentations as n}from"@opentelemetry/auto-instrumentations-node";import{OTLPTraceExporter as r}from"@opentelemetry/exporter-trace-otlp-http";import{PinoInstrumentation as i}from"@opentelemetry/instrumentation-pino";import{resourceFromAttributes as a}from"@opentelemetry/resources";import{NodeSDK as o}from"@opentelemetry/sdk-node";import{BatchSpanProcessor as s}from"@opentelemetry/sdk-trace-node";import{ATTR_SERVICE_NAME as c,ATTR_SERVICE_VERSION as l}from"@opentelemetry/semantic-conventions";export*from"@opentelemetry/api";var u={};import*as d from"@opentelemetry/api";e(u,d),t(`@opentelemetry/instrumentation/hook.mjs`,import.meta.url);const f={name:process.env.APP_NAME||`appos`,version:process.env.APP_VERSION||`development`};new o({resource:a({[c]:f.name,[l]:f.version}),spanProcessors:[new s(new r({url:process.env.OTEL_EXPORTER_OTLP_ENDPOINT||`http://localhost:4318/v1/traces`,headers:process.env.OTEL_EXPORTER_OTLP_HEADERS?JSON.parse(process.env.OTEL_EXPORTER_OTLP_HEADERS):void 0}))],instrumentations:[n({"@opentelemetry/instrumentation-fs":{enabled:!1},"@opentelemetry/instrumentation-dns":{enabled:!1}}),new i({logHook:(e,t)=>{t[`service.name`]=f.name}})]}).start();export{u as instrumentation_exports};
@@ -0,0 +1 @@
1
+ import"@better-auth/passkey/client";import"@better-auth/sso/client";import"better-auth/client/plugins";import"better-auth/react";const e=`/auth`,t=``;export{e as AUTH_BASE_PATH,t as AUTH_BASE_URL};
@@ -0,0 +1,34 @@
1
+ import { Logger } from "./logger.mjs";
2
+ import { createClient, createCluster } from "redis";
3
+
4
+ //#region src/api/redis.d.ts
5
+ type RedisClient = ReturnType<typeof createClient> | ReturnType<typeof createCluster>;
6
+ /**
7
+ * Options for defining a Redis client.
8
+ */
9
+ interface DefineRedisClientOptions {
10
+ /**
11
+ * Logger instance for error reporting.
12
+ */
13
+ logger: Logger;
14
+ /**
15
+ * Redis URL(s). Single: "redis://localhost:6379", Cluster: comma-separated URLs
16
+ */
17
+ url: string;
18
+ }
19
+ /**
20
+ * Defines Redis client based on URL format with lazy connection.
21
+ * Single URL → createClient(), comma-separated URLs → createCluster()
22
+ *
23
+ * Algorithm:
24
+ * 1. Split URL by comma to detect cluster vs single
25
+ * 2. Create appropriate client type
26
+ * 3. Attach error handler with label for debugging
27
+ * 4. Wrap in proxy that auto-connects on first use
28
+ *
29
+ * @param opts Options for defining the Redis client.
30
+ * @returns Redis client that auto-connects on first operation.
31
+ */
32
+ declare function defineRedisClient(opts: DefineRedisClientOptions): RedisClient;
33
+ //#endregion
34
+ export { DefineRedisClientOptions, RedisClient, defineRedisClient };
@@ -0,0 +1 @@
1
+ import{createClient as e,createCluster as t}from"redis";function n(n){let r=n.url.split(`,`).map(e=>e.trim()).filter(Boolean),i;i=r.length===1?e({url:r[0]}):t({rootNodes:r.map(e=>({url:e}))}),i.on(`error`,e=>n.logger.error({err:e},`Redis error`));let a=null,o=async()=>{i.isOpen||(a??=i.connect(),await a)};return new Proxy(i,{get(e,t,n){let r=Reflect.get(e,t,n);return typeof r==`function`&&t!==`on`&&t!==`once`?async(...t)=>(await o(),r.apply(e,t)):r}})}export{n as defineRedisClient};