alepha 0.20.2 → 0.20.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 (208) hide show
  1. package/README.md +0 -1
  2. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  3. package/assets/swagger-ui/swagger-ui.css +1 -1
  4. package/dist/api/audits/index.browser.js +49 -0
  5. package/dist/api/audits/index.browser.js.map +1 -1
  6. package/dist/api/audits/index.d.ts.map +1 -1
  7. package/dist/api/audits/index.js +49 -0
  8. package/dist/api/audits/index.js.map +1 -1
  9. package/dist/api/files/index.d.ts.map +1 -1
  10. package/dist/api/files/index.js.map +1 -1
  11. package/dist/api/jobs/index.d.ts +16 -75
  12. package/dist/api/jobs/index.d.ts.map +1 -1
  13. package/dist/api/jobs/index.js.map +1 -1
  14. package/dist/api/keys/index.js.map +1 -1
  15. package/dist/api/notifications/index.d.ts +1 -10
  16. package/dist/api/notifications/index.d.ts.map +1 -1
  17. package/dist/api/organizations/index.d.ts.map +1 -1
  18. package/dist/api/parameters/index.browser.js +37 -0
  19. package/dist/api/parameters/index.browser.js.map +1 -1
  20. package/dist/api/parameters/index.d.ts +4 -65
  21. package/dist/api/parameters/index.d.ts.map +1 -1
  22. package/dist/api/parameters/index.js +37 -0
  23. package/dist/api/parameters/index.js.map +1 -1
  24. package/dist/api/payments/index.d.ts.map +1 -1
  25. package/dist/api/payments/index.js.map +1 -1
  26. package/dist/api/users/index.d.ts +207 -5184
  27. package/dist/api/users/index.d.ts.map +1 -1
  28. package/dist/api/users/index.js +2 -4
  29. package/dist/api/users/index.js.map +1 -1
  30. package/dist/api/verifications/index.d.ts.map +1 -1
  31. package/dist/api/verifications/index.js +2 -1
  32. package/dist/api/verifications/index.js.map +1 -1
  33. package/dist/bucket/index.js +5 -1
  34. package/dist/bucket/index.js.map +1 -1
  35. package/dist/bucket/index.workerd.js +5 -1
  36. package/dist/bucket/index.workerd.js.map +1 -1
  37. package/dist/cache/core/index.js.map +1 -1
  38. package/dist/cache/core/index.workerd.js.map +1 -1
  39. package/dist/captcha/index.js.map +1 -1
  40. package/dist/cli/core/index.d.ts +217 -11647
  41. package/dist/cli/core/index.d.ts.map +1 -1
  42. package/dist/cli/core/index.js +706 -42
  43. package/dist/cli/core/index.js.map +1 -1
  44. package/dist/cli/devtools/index.js +7 -1
  45. package/dist/cli/devtools/index.js.map +1 -1
  46. package/dist/cli/platform/index.d.ts +41 -64
  47. package/dist/cli/platform/index.d.ts.map +1 -1
  48. package/dist/cli/platform/index.js +47 -0
  49. package/dist/cli/platform/index.js.map +1 -1
  50. package/dist/cli/vendor/index.js +15 -0
  51. package/dist/cli/vendor/index.js.map +1 -1
  52. package/dist/command/index.js +1 -1
  53. package/dist/command/index.js.map +1 -1
  54. package/dist/core/index.browser.js.map +1 -1
  55. package/dist/core/index.d.ts +2 -8
  56. package/dist/core/index.d.ts.map +1 -1
  57. package/dist/core/index.js.map +1 -1
  58. package/dist/core/index.native.js.map +1 -1
  59. package/dist/core/index.workerd.js.map +1 -1
  60. package/dist/crypto/index.js.map +1 -1
  61. package/dist/datetime/index.js.map +1 -1
  62. package/dist/email/core/index.js.map +1 -1
  63. package/dist/email/smtp/index.js +2 -10522
  64. package/dist/email/smtp/index.js.map +1 -1
  65. package/dist/fake/index.d.ts +4 -8085
  66. package/dist/fake/index.d.ts.map +1 -1
  67. package/dist/fake/index.js +3 -33554
  68. package/dist/fake/index.js.map +1 -1
  69. package/dist/lock/core/index.js.map +1 -1
  70. package/dist/lock/redis/index.js.map +1 -1
  71. package/dist/logger/index.js +32 -1
  72. package/dist/logger/index.js.map +1 -1
  73. package/dist/mcp/index.js +5 -1
  74. package/dist/mcp/index.js.map +1 -1
  75. package/dist/orm/core/index.browser.js +1 -361
  76. package/dist/orm/core/index.browser.js.map +1 -1
  77. package/dist/orm/core/index.bun.js +14 -406
  78. package/dist/orm/core/index.bun.js.map +1 -1
  79. package/dist/orm/core/index.d.ts +96 -5117
  80. package/dist/orm/core/index.d.ts.map +1 -1
  81. package/dist/orm/core/index.js +23 -419
  82. package/dist/orm/core/index.js.map +1 -1
  83. package/dist/orm/postgres/index.bun.js +17 -20
  84. package/dist/orm/postgres/index.bun.js.map +1 -1
  85. package/dist/orm/postgres/index.d.ts +2 -613
  86. package/dist/orm/postgres/index.d.ts.map +1 -1
  87. package/dist/orm/postgres/index.js +17 -20
  88. package/dist/orm/postgres/index.js.map +1 -1
  89. package/dist/react/core/index.js.map +1 -1
  90. package/dist/react/i18n/index.js.map +1 -1
  91. package/dist/react/intro/index.js +22 -17
  92. package/dist/react/intro/index.js.map +1 -1
  93. package/dist/react/router/index.browser.js +78 -2
  94. package/dist/react/router/index.browser.js.map +1 -1
  95. package/dist/react/router/index.d.ts +22 -1
  96. package/dist/react/router/index.d.ts.map +1 -1
  97. package/dist/react/router/index.js +102 -4
  98. package/dist/react/router/index.js.map +1 -1
  99. package/dist/react/testing/index.d.ts +1 -411
  100. package/dist/react/testing/index.d.ts.map +1 -1
  101. package/dist/react/testing/index.js +13 -12293
  102. package/dist/react/testing/index.js.map +1 -1
  103. package/dist/react/ui/index.js +3 -0
  104. package/dist/react/ui/index.js.map +1 -1
  105. package/dist/react/websocket/index.js.map +1 -1
  106. package/dist/redis/index.js.map +1 -1
  107. package/dist/scheduler/index.d.ts +1 -83
  108. package/dist/scheduler/index.d.ts.map +1 -1
  109. package/dist/scheduler/index.js +2 -391
  110. package/dist/scheduler/index.js.map +1 -1
  111. package/dist/scheduler/index.workerd.js +2 -391
  112. package/dist/scheduler/index.workerd.js.map +1 -1
  113. package/dist/security/index.browser.js.map +1 -1
  114. package/dist/security/index.d.ts +2 -325
  115. package/dist/security/index.d.ts.map +1 -1
  116. package/dist/security/index.js +3 -1362
  117. package/dist/security/index.js.map +1 -1
  118. package/dist/server/auth/index.d.ts +1 -1054
  119. package/dist/server/auth/index.d.ts.map +1 -1
  120. package/dist/server/auth/index.js +16 -1224
  121. package/dist/server/auth/index.js.map +1 -1
  122. package/dist/server/cookies/index.js.map +1 -1
  123. package/dist/server/core/index.browser.js.map +1 -1
  124. package/dist/server/core/index.d.ts +1 -4
  125. package/dist/server/core/index.d.ts.map +1 -1
  126. package/dist/server/core/index.js +19 -4
  127. package/dist/server/core/index.js.map +1 -1
  128. package/dist/server/links/index.browser.js.map +1 -1
  129. package/dist/server/links/index.js.map +1 -1
  130. package/dist/server/metrics/index.d.ts +1 -514
  131. package/dist/server/metrics/index.d.ts.map +1 -1
  132. package/dist/server/metrics/index.js +4 -4356
  133. package/dist/server/metrics/index.js.map +1 -1
  134. package/dist/server/rate-limit/index.js.map +1 -1
  135. package/dist/server/static/index.js.map +1 -1
  136. package/dist/server/swagger/index.js +1 -1
  137. package/dist/server/swagger/index.js.map +1 -1
  138. package/dist/sms/index.js.map +1 -1
  139. package/dist/system/index.browser.js.map +1 -1
  140. package/dist/system/index.js.map +1 -1
  141. package/dist/system/index.workerd.js.map +1 -1
  142. package/dist/topic/core/index.js.map +1 -1
  143. package/dist/websocket/index.browser.js +21 -0
  144. package/dist/websocket/index.browser.js.map +1 -1
  145. package/dist/websocket/index.js +21 -0
  146. package/dist/websocket/index.js.map +1 -1
  147. package/package.json +18 -15
  148. package/src/api/files/__tests__/FileController.spec.ts +1 -1
  149. package/src/api/jobs/__tests__/$job.spec.ts +5 -1
  150. package/src/api/users/schemas/userQuerySchema.ts +0 -1
  151. package/src/api/users/services/UserService.ts +1 -5
  152. package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
  153. package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
  154. package/src/api/verifications/services/VerificationService.ts +1 -0
  155. package/src/cli/core/__tests__/init.spec.ts +208 -0
  156. package/src/cli/core/commands/init.ts +12 -0
  157. package/src/cli/core/services/PackageManagerUtils.ts +23 -6
  158. package/src/cli/core/services/ProjectScaffolder.ts +298 -20
  159. package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
  160. package/src/cli/core/tasks/BuildServerTask.ts +8 -0
  161. package/src/cli/core/templates/apiIndexTs.ts +23 -1
  162. package/src/cli/core/templates/componentsJsonTs.ts +39 -0
  163. package/src/cli/core/templates/mainCss.ts +1 -0
  164. package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
  165. package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
  166. package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
  167. package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
  168. package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
  169. package/src/cli/core/templates/webAppRouterTs.ts +104 -1
  170. package/src/cli/core/templates/webIndexTs.ts +23 -1
  171. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
  172. package/src/command/providers/CliProvider.ts +1 -1
  173. package/src/core/interfaces/Service.ts +3 -1
  174. package/src/core/providers/TypeProvider.ts +1 -1
  175. package/src/logger/services/Logger.ts +1 -1
  176. package/src/mcp/__tests__/$resource.spec.ts +1 -1
  177. package/src/mcp/__tests__/$tool.spec.ts +1 -1
  178. package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
  179. package/src/orm/__tests__/$repository-tests.ts +1 -0
  180. package/src/orm/__tests__/orm-next-tests.ts +2 -67
  181. package/src/orm/__tests__/orm-next.spec.ts +0 -21
  182. package/src/orm/core/index.shared.ts +0 -2
  183. package/src/orm/core/index.ts +1 -2
  184. package/src/orm/core/primitives/$repository.ts +3 -6
  185. package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
  186. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
  187. package/src/orm/core/services/ModelBuilder.ts +1 -13
  188. package/src/orm/core/services/Repository.ts +1 -42
  189. package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
  190. package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
  191. package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
  192. package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
  193. package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
  194. package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
  195. package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
  196. package/src/react/router/providers/ReactServerProvider.ts +1 -0
  197. package/src/scheduler/providers/CronProvider.ts +1 -1
  198. package/src/security/primitives/$basicAuth.ts +1 -1
  199. package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
  200. package/src/server/core/interfaces/ServerRequest.ts +1 -0
  201. package/src/server/core/providers/ServerProvider.ts +1 -1
  202. package/src/server/core/providers/ServerRouterProvider.ts +2 -2
  203. package/src/server/core/services/HttpClient.ts +1 -1
  204. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  205. package/dist/react/testing/chunk-DBEY4PJZ.js +0 -16
  206. package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
  207. package/src/orm/core/helpers/parseQueryString.ts +0 -502
  208. package/src/orm/core/primitives/$view.ts +0 -88
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":["Modes","text","binary","Mode","BufferParameter","ArrayBuffer","ArrayBufferView","MessageName","BackendMessage","name","length","parseComplete","bindComplete","closeComplete","noData","portalSuspended","replicationStart","emptyQuery","copyDone","AuthenticationOk","constructor","AuthenticationCleartextPassword","AuthenticationMD5Password","Uint8Array","salt","AuthenticationSASL","mechanisms","AuthenticationSASLContinue","data","AuthenticationSASLFinal","AuthenticationMessage","NoticeOrError","message","severity","code","detail","hint","position","internalPosition","internalQuery","where","schema","table","column","dataType","constraint","file","line","routine","DatabaseError","Error","CopyDataMessage","chunk","CopyResponse","columnTypes","columnCount","Field","tableID","columnID","dataTypeID","dataTypeSize","dataTypeModifier","format","RowDescriptionMessage","fieldCount","fields","ParameterDescriptionMessage","parameterCount","dataTypeIDs","ParameterStatusMessage","parameterName","parameterValue","BackendKeyDataMessage","processID","secretKey","NotificationResponseMessage","processId","channel","payload","ReadyForQueryMessage","status","CommandCompleteMessage","DataRowMessage","NoticeMessage","messages_AuthenticationCleartextPassword","messages_AuthenticationMD5Password","messages_AuthenticationMessage","messages_AuthenticationOk","messages_AuthenticationSASL","messages_AuthenticationSASLContinue","messages_AuthenticationSASLFinal","messages_BackendKeyDataMessage","messages_BackendMessage","messages_CommandCompleteMessage","messages_CopyDataMessage","messages_CopyResponse","messages_DataRowMessage","messages_DatabaseError","messages_Field","messages_MessageName","messages_NoticeMessage","messages_NotificationResponseMessage","messages_ParameterDescriptionMessage","messages_ParameterStatusMessage","messages_ReadyForQueryMessage","messages_RowDescriptionMessage","messages_bindComplete","messages_closeComplete","messages_copyDone","messages_emptyQuery","messages_noData","messages_parseComplete","messages_portalSuspended","messages_replicationStart","messages","IDBFS","Emscripten","FileSystemType","IDBDatabase","Record","quit","dbs","FS","filesystems","MEMFS","NODEFS","PostgresMod","EmscriptenModule","Array","WebAssembly","Memory","Blob","Promise","Omit","preInit","mod","preRun","postRun","thisProgram","stdin","wasmMemory","PROXYFS","WASM_PREFIX","pg_extensions","UTF8ToString","ptr","maxBytesToRead","stringToUTF8OnStack","s","_pgl_set_system_fn","system_fn","_pgl_set_popen_fn","popen_fn","_pgl_set_pclose_fn","pclose_fn","_pgl_set_rw_cbs","read_cb","write_cb","_pgl_set_pipe_fn","pipe_fn","_pgl_freopen","filepath","mode","stream","_pgl_pq_flush","_fopen","path","_fclose","_fflush","_pgl_proc_exit","addFunction","cb","signature","removeFunction","f","callMain","args","_PostgresMainLoopOnce","_PostgresMainLongJmp","_PostgresSendReadyForQueryIfNecessary","_ProcessStartupPacket","Port","ssl_done","gss_done","_IsTransactionBlock","_pgl_setPGliteActive","newValue","_pgl_startPGlite","_pgl_getMyProcPort","_pgl_sendConnData","ENV","_emscripten_force_exit","_pgl_run_atexit_funcs","_pq_buffer_remaining_data","PostgresFactory","T","Partial","moduleOverrides","_default","postgresMod_FS","postgresMod_PostgresMod","postgresMod","default","DumpTarCompressionOptions","FsType","Filesystem","PGlite","File","init","pg","emscriptenOptions","emscriptenOpts","syncToFs","relaxedDurability","initialSyncFs","dumpTar","dbname","compression","closeFs","EmscriptenBuiltinFilesystem","dataDir","_relaxedDurability","BaseFilesystem","debug","FsStats","chmod","close","fd","fstat","lstat","mkdir","recursive","options","open","flags","readdir","read","buffer","offset","rename","oldPath","newPath","rmdir","truncate","len","unlink","utimes","atime","mtime","writeFile","encoding","flag","write","dev","ino","nlink","uid","gid","rdev","size","blksize","blocks","ctime","ERRNO_CODES","EBADF","EBADFD","EEXIST","EINVAL","EISDIR","ENODEV","ENOENT","ENOTDIR","ENOTEMPTY","FilesystemType","DebugLevel","RowMode","ParserOptions","pgType","value","SerializerOptions","QueryOptions","rowMode","parsers","serializers","blob","onNotice","notice","paramTypes","ExecProtocolOptions","throwOnError","ExecProtocolOptionsStream","onRawData","ExtensionSetupResult","TNamespace","URL","namespaceObj","bundlePath","ExtensionSetup","PGliteInterface","clientOnly","Extension","setup","ExtensionNamespace","Extensions","namespace","InitializedExtensions","TExtensions","K","ExecProtocolResult","DumpDataDirResult","tarball","extension","filename","PGliteOptions","Module","noInitDb","username","database","fs","extensions","loadDataDir","initialMemory","pgliteWasmModule","initdbWasmModule","fsBundle","startParams","Results","TemplateStringsArray","DescribeQueryResult","Transaction","waitReady","ready","closed","query","params","sql","sqlStrings","exec","describeQuery","transaction","tx","callback","execProtocolRaw","execProtocolRawStream","execProtocol","runExclusive","fn","listen","unlisten","onNotification","offNotification","dumpDataDir","refreshArrayTypes","PGliteInterfaceExtensions","E","ReturnType","Awaited","N","Row","key","rows","affectedRows","rollback","Serializer","Parser","queryParams","serializer","resultFields","parser","BOOL","BYTEA","CHAR","INT8","INT2","INT4","REGPROC","TEXT","OID","TID","XID","CID","JSON","XML","PG_NODE_TREE","SMGR","PATH","POLYGON","CIDR","FLOAT4","FLOAT8","ABSTIME","RELTIME","TINTERVAL","CIRCLE","MACADDR8","MONEY","MACADDR","INET","ACLITEM","BPCHAR","VARCHAR","DATE","TIME","TIMESTAMP","TIMESTAMPTZ","INTERVAL","TIMETZ","BIT","VARBIT","NUMERIC","REFCURSOR","REGPROCEDURE","REGOPER","REGOPERATOR","REGCLASS","REGTYPE","UUID","TXID_SNAPSHOT","PG_LSN","PG_NDISTINCT","PG_DEPENDENCIES","TSVECTOR","TSQUERY","GTSVECTOR","REGCONFIG","REGDICTIONARY","JSONB","REGNAMESPACE","REGROLE","types","Date","string","to","from","serialize","x","parse","number","bigint","json","boolean","date","bytea","typeId","TypeHandler","TypeHandlers","parseType","type","arraySerializer","xs","typarray","arrayParser","types$1_ABSTIME","types$1_ACLITEM","types$1_BIT","types$1_BOOL","types$1_BPCHAR","types$1_BYTEA","types$1_CHAR","types$1_CID","types$1_CIDR","types$1_CIRCLE","types$1_DATE","types$1_FLOAT4","types$1_FLOAT8","types$1_GTSVECTOR","types$1_INET","types$1_INT2","types$1_INT4","types$1_INT8","types$1_INTERVAL","types$1_JSON","types$1_JSONB","types$1_MACADDR","types$1_MACADDR8","types$1_MONEY","types$1_NUMERIC","types$1_OID","types$1_PATH","types$1_PG_DEPENDENCIES","types$1_PG_LSN","types$1_PG_NDISTINCT","types$1_PG_NODE_TREE","types$1_POLYGON","types$1_Parser","types$1_REFCURSOR","types$1_REGCLASS","types$1_REGCONFIG","types$1_REGDICTIONARY","types$1_REGNAMESPACE","types$1_REGOPER","types$1_REGOPERATOR","types$1_REGPROC","types$1_REGPROCEDURE","types$1_REGROLE","types$1_REGTYPE","types$1_RELTIME","types$1_SMGR","types$1_Serializer","types$1_TEXT","types$1_TID","types$1_TIME","types$1_TIMESTAMP","types$1_TIMESTAMPTZ","types$1_TIMETZ","types$1_TINTERVAL","types$1_TSQUERY","types$1_TSVECTOR","types$1_TXID_SNAPSHOT","types$1_TypeHandler","types$1_TypeHandlers","types$1_UUID","types$1_VARBIT","types$1_VARCHAR","types$1_XID","types$1_XML","types$1_arrayParser","types$1_arraySerializer","types$1_parseType","types$1_parsers","types$1_serializers","types$1_types","types$1","BasePGlite","force","Pick","private","execProtocolStream","_handleBlob","_getWrittenBlob","_cleanupBlob","_checkReady","_runExclusiveQuery","_runExclusiveTransaction","_initArrayTypes","O","Symbol","asyncDispose","AsyncDisposable","POSTGRES_MAIN_LONGJMP","DEFAULT_RECV_BUF_SIZE","MAX_BUFFER_SIZE","externalCommandStreamFd","defaultStartParams","create","handleExternalCmd","cmd","execProtocolRawSync","isInTransaction","clone","_runExclusiveListen","A","B","C","D","F","G","I","M","P","Q","R","S","W","a","b","c","d","e","g","h","i","j","k","l","m","n","o","p","q","r","t","u","v","w","y","z"],"sources":["../../../src/orm/postgres/services/PostgresModelBuilder.ts","../../../src/orm/postgres/providers/PostgresProvider.ts","../../../src/orm/postgres/providers/BunPostgresProvider.ts","../../../src/orm/postgres/providers/CloudflareHyperdriveProvider.ts","../../../src/orm/postgres/providers/NodePostgresProvider.ts","../../../../../node_modules/@electric-sql/pglite/dist/pglite-BZlQ7pL-.d.ts","../../../src/orm/postgres/providers/PglitePostgresProvider.ts","../../../src/orm/postgres/schemas/postgresEnvSchema.ts","../../../src/orm/postgres/types/byte.ts","../../../src/orm/postgres/index.ts"],"x_google_ignoreList":[5],"mappings":";;;;;;;;;;;;;cAyCa,oBAAA,SAA6B,YAAA;EAAA,UAC9B,OAAA,EAAO,GAAA,SAAA,EAAA,CAAA,QAAA;;;;YAKP,iBAAA,CAAkB,GAAA,WAAW,cAAA,CAAA,UAAA,CAAA,EAAA,CAAA,oBAAA;EAAA,UAI7B,WAAA,CAAY,IAAA;EAqBf,UAAA,CACL,MAAA,EAAQ,eAAA,OACR,OAAA;IACE,MAAA,EAAQ,GAAA;IACR,KAAA,EAAO,GAAA;IACP,OAAA,EAAS,GAAA;IACT,MAAA;EAAA;EAgCG,SAAA,CACL,IAAA,EAAM,aAAA,EACN,OAAA;IACE,MAAA,EAAQ,GAAA;IACR,MAAA;EAAA;EA0BG,aAAA,CACL,QAAA,EAAU,iBAAA,EACV,OAAA;IACE,SAAA,EAAW,GAAA;IACX,MAAA;EAAA;EAHQ;;;EAAA,UAwBF,cAAA,CACR,MAAA,EAAQ,eAAA,EACR,MAAA,EAAQ,GAAA,sBAGJ,IAAA,EAAM,uBAAA,wBACH,uBAAA;EAsBT,iBAAA,aAA+B,OAAA,EAC7B,SAAA,UACA,MAAA,EAAQ,CAAA,EACR,GAAA,EAAK,QAAA,EACL,KAAA,EAAO,GAAA,mBACP,MAAA,EAAQ,GAAA,sBACP,UAAA,CAAW,CAAA;EAwDd,gBAAA,GACE,SAAA,UACA,SAAA,UACA,KAAA,EAAO,OAAA,EACP,GAAA,EAAK,QAAA,EACL,KAAA,EAAO,GAAA;EAnEsB;;;;;;EAmO/B,iBAAA,GAAqB,GAAA,UAAa,KAAA,EAAO,OAAA,KAAO,EAAA,CAAA,oBAAA,WAAA,EAAA,CAAA,qBAAA;;;;;;;;;;;;;;;;;;;;;AA3XlD;uBCfsB,gBAAA,SAAyB,gBAAA;EAAA,mBAC1B,GAAA;;;;qBACA,KAAA;;;;;;qBACA,OAAA,EAAO,oBAAA;EAAA,SAED,OAAA;EAAA,IAEd,IAAA,CAAA;EDqID;;;EAAA,UC9HA,gBAAA;EAAA,IAIU,GAAA,CAAA;EDuJV;;;EC5IY,OAAA,CACpB,SAAA,EAAW,OAAA,GACV,OAAA,CAAQ,KAAA,CAAM,MAAA;ED8IH;;;EAAA,ICvIM,MAAA,CAAA;EAAA,aAYS,EAAA,CAAA,GAAM,UAAA;EDwVM;;;EAAA,SCnVzB,OAAA,CAAA,GAAW,OAAA;EDmVqB;;;EAAA,SC9UhC,KAAA,CAAA,GAAS,OAAA;EAAA,mBAIN,OAAA,EAJa,QAAA,CAIN,aAAA;EAAA,mBAiBP,MAAA,EAjBO,QAAA,CAiBD,aAAA;EAAA,UAQf,WAAA,EAAW,QAAA,CAAA,mBAAA,OAAA,OAAA;EAAA,UAWL,kBAAA,CAAA,GAAkB,OAAA;EDpFxB;;;EAAA,UCqGM,cAAA,CAAA,GAAkB,OAAA;EDhGxB;;;;;;;;;EAAA,UCsHM,uBAAA,CAAA,GAA2B,OAAA;ED1FvC;;;;;EAAA,UC+IM,kBAAA,CAAmB,IAAA,UAAc,GAAA;AAAA;;;;;;;;;;;;;ADjL7C;;;;;;;;cEjBa,mBAAA,SAA4B,gBAAA;EAAA,UAC7B,MAAA,GAAS,GAAA,CAAI,GAAA;EAAA,UACb,KAAA,GAAQ,cAAA;EFqFV;;;EAAA,IEhFY,EAAA,CAAA,GAAM,UAAA;EAAA,UAQD,iBAAA,CACvB,gBAAA,WACC,OAAA;EAeU,OAAA,CAAA,GAAW,OAAA;EA8CX,KAAA,CAAA,GAAS,OAAA;AAAA;;;;;;;;;;;;;AF7DxB;cGxBa,4BAAA,SAAqC,gBAAA;EAAA,mBAC7B,OAAA,EAAO,oBAAA;EAAA,mBACP,GAAA;;;;MASC,MAAA,CAAA;EAAA,UAIV,UAAA;EAAA,UACA,SAAA;EAAA,UACA,WAAA;EAAA,IAEC,IAAA,CAAA;EAAA,IAIA,MAAA,CAAA;EAAA,SAIc,OAAA;EAAA,IAEL,GAAA,CAAA;EHwHV;;;;;;;EAAA,IG7GU,EAAA,CAAA,GAAM,UAAA;EAkCJ,OAAA,CACpB,KAAA,EAAO,OAAA,GACN,OAAA,CAAQ,KAAA,CAAM,MAAA;EAAA,mBAIE,OAAA,EAJT,QAAA,CAIgB,aAAA;EAAA,UAeV,iBAAA,CAAkB,gBAAA,WAA2B,OAAA;AAAA;;;cCxGlD,oBAAA,SAA6B,gBAAA;EAAA,gBACxB,SAAA;EAAA,UAON,MAAA,GAAS,QAAA,CAAS,GAAA;EAAA,UAClB,EAAA,GAAK,kBAAA;;;;MAKK,EAAA,CAAA,GAAM,kBAAA;EAAA,UAQD,iBAAA,CACvB,gBAAA,WACC,OAAA;EAiBU,OAAA,CAAA,GAAW,OAAA;EAwBX,KAAA,CAAA,GAAS,OAAA;EJhCU;;;EAAA,UIkDtB,gBAAA,CAAA,GAAoB,QAAA,CAAS,OAAA;EAAA,UA+B7B,GAAA,CACR,GAAA,EAAK,GAAA;AAAA;;;KCpHJO,WAAAA;AAAAA,KACAC,cAAAA;EACDC,IAAAA,EAAMF,WAAAA;EACNG,MAAAA;AAAAA;AAAAA,UA6CMqB,aAAAA;EACNC,OAAAA;EACAC,QAAAA;EACAC,IAAAA;EACAC,MAAAA;EACAC,IAAAA;EACAC,QAAAA;EACAC,gBAAAA;EACAC,aAAAA;EACAC,KAAAA;EACAC,MAAAA;EACAC,KAAAA;EACAC,MAAAA;EACAC,QAAAA;EACAC,UAAAA;EACAC,IAAAA;EACAC,IAAAA;EACAC,OAAAA;AAAAA;AAAAA,cAqGUmC,aAAAA,YAAyB3E,cAAAA,EAAgBuB,aAAAA;EAAAA,SAC1CrB,MAAAA;EAAAA,SACAsB,OAAAA;EACTZ,WAAAA,CAAYV,MAAAA,UAAgBsB,OAAAA;EAAAA,SACnBvB,IAAAA;EACTwB,QAAAA;EACAC,IAAAA;EACAC,MAAAA;EACAC,IAAAA;EACAC,QAAAA;EACAC,gBAAAA;EACAC,aAAAA;EACAC,KAAAA;EACAC,MAAAA;EACAC,KAAAA;EACAC,MAAAA;EACAC,QAAAA;EACAC,UAAAA;EACAC,IAAAA;EACAC,IAAAA;EACAC,OAAAA;AAAAA;AAAAA,KAwDCmE,KAAAA,GAAQC,UAAAA,CAAWC,cAAAA;EACpBG,IAAAA;EACAC,GAAAA,EAAKF,MAAAA,SAAeD,WAAAA;AAAAA;AAAAA,KAEnBI,EAAAA,UAAYA,EAAAA;EACbC,WAAAA;IACIC,KAAAA,EAAOR,UAAAA,CAAWC,cAAAA;IAClBQ,MAAAA,EAAQT,UAAAA,CAAWC,cAAAA;IACnBF,KAAAA,EAAOA,KAAAA;EAAAA;EAEXK,IAAAA;AAAAA;AAAAA,UAEMM,WAAAA,SAAoBO,IAAAA,CAAKN,gBAAAA;EAC/BO,OAAAA,EAASN,KAAAA;IAAAA,CACJO,GAAAA,EAAKT,WAAAA;EAAAA;EAEVU,MAAAA,EAAQR,KAAAA;IAAAA,CACHO,GAAAA,EAAKT,WAAAA;EAAAA;EAEVW,OAAAA,EAAST,KAAAA;IAAAA,CACJO,GAAAA,EAAKT,WAAAA;EAAAA;EAEVY,WAAAA;EACAC,KAAAA;EACAjB,EAAAA,EAAIA,EAAAA;EACJkB,UAAAA,EAAYX,WAAAA,CAAYC,MAAAA;EACxBW,OAAAA,EAASzB,UAAAA,CAAWC,cAAAA;EACpByB,WAAAA;EACAC,aAAAA,EAAexB,MAAAA,SAAea,OAAAA,CAAQD,IAAAA;EACtCa,YAAAA,GAAeC,GAAAA,UAAaC,cAAAA;EAC5BC,mBAAAA,GAAsBC,CAAAA;EACtBC,kBAAAA,GAAqBC,SAAAA;EACrBC,iBAAAA,GAAoBC,QAAAA;EACpBC,kBAAAA,GAAqBC,SAAAA;EACrBC,eAAAA,GAAkBC,OAAAA,UAAiBC,QAAAA;EACnCC,gBAAAA,GAAmBC,OAAAA;EACnBC,YAAAA,GAAeC,QAAAA,UAAkBC,IAAAA,UAAcC,MAAAA;EAC/CC,aAAAA;EACAC,MAAAA,GAASC,IAAAA,UAAcJ,IAAAA;EACvBK,OAAAA,GAAUJ,MAAAA;EACVK,OAAAA,GAAUL,MAAAA;EACVM,cAAAA,GAAiBvI,IAAAA;EACjBwI,WAAAA,GAAcC,EAAAA,GAAK1B,GAAAA,OAAUvI,MAAAA,mBAAyBkK,SAAAA;EACtDC,cAAAA,GAAiBC,CAAAA;EACjBC,QAAAA,GAAWC,IAAAA;EACXC,qBAAAA;EACAC,oBAAAA;EACAC,qCAAAA;EACAC,qBAAAA,GAAwBC,IAAAA,UAAcC,QAAAA,WAAmBC,QAAAA;EACzDC,mBAAAA;EACAC,oBAAAA,GAAuBC,QAAAA;EACvBC,gBAAAA;EACAC,kBAAAA;EACAC,iBAAAA;EACAC,GAAAA;EACAC,sBAAAA,GAAyB/G,MAAAA;EACzBgH,qBAAAA;EACAC,yBAAAA;AAAAA;AAAAA,KAWCU,yBAAAA;;;;;;UASKE,UAAAA;ED3OsB;;;EC+O5BG,IAAAA,CAAKC,EAAAA,EAAIH,MAAAA,EAAQI,iBAAAA,EAAmBd,OAAAA,CAAQtE,WAAAA,IAAeM,OAAAA;IACvD+E,cAAAA,EAAgBf,OAAAA,CAAQtE,WAAAA;EAAAA;EDhNpB;;;ECqNRsF,QAAAA,CAASC,iBAAAA,aAA8BjF,OAAAA;EAzUtC7H;;;EA6UD+M,aAAAA,IAAiBlF,OAAAA;EA7UL;AAAA;;EAiVZmF,OAAAA,CAAQC,MAAAA,UAAgBC,WAAAA,GAAcd,yBAAAA,GAA4BvE,OAAAA,CAAQ2E,IAAAA,GAAO5E,IAAAA;EA/UhE;;;EAmVjBuF,OAAAA,IAAWtF,OAAAA;AAAAA;;AAtSwK;;KAkYlL8I,UAAAA;AAAAA,KACAC,OAAAA;AAAAA,UACKC,aAAAA;EAAAA,CACLC,MAAAA,YAAkBC,KAAAA;AAAAA;AAAAA,UAEbC,iBAAAA;EAAAA,CACLF,MAAAA,YAAkBC,KAAAA;AAAAA;AAAAA,UAEbE,YAAAA;EACNC,OAAAA,GAAUN,OAAAA;EACVO,OAAAA,GAAUN,aAAAA;EACVO,WAAAA,GAAcJ,iBAAAA;EACdK,IAAAA,GAAOzJ,IAAAA,GAAO4E,IAAAA;EACd8E,QAAAA,IAAYC,MAAAA,EAAQ3M,aAAAA;EACpB4M,UAAAA;AAAAA;AAAAA,UAEMC,mBAAAA;EACN5E,QAAAA;EACA6E,YAAAA;EACAJ,QAAAA,IAAYC,MAAAA,EAAQ3M,aAAAA;AAAAA;AAAAA,UAEd+M,yBAAAA;EACN9E,QAAAA;EACA+E,SAAAA,GAAYvQ,IAAAA,EAAML,UAAAA;AAAAA;AAAAA,UAEZ6Q,oBAAAA;EACNjF,cAAAA;EACAoF,YAAAA,GAAeF,UAAAA;EACfG,UAAAA,GAAaF,GAAAA;EACbtF,IAAAA,SAAa5E,OAAAA;EACb8F,KAAAA,SAAc9F,OAAAA;AAAAA;AAAAA,KAEbqK,cAAAA,sBAAoCxF,EAAAA,EAAIyF,eAAAA,EAAiBvF,cAAAA,OAAqBwF,UAAAA,eAAyBvK,OAAAA,CAAQgK,oBAAAA,CAAqBC,UAAAA;AAAAA,UAC/HO,SAAAA;EACNnS,IAAAA;EACAoS,KAAAA,EAAOJ,cAAAA,CAAeJ,UAAAA;AAAAA;AAAAA,KAErBS,kBAAAA,MAAwB3G,CAAAA,SAAUyG,SAAAA,qBAA8BP,UAAAA;AAAAA,KAChEU,UAAAA;EAAAA,CACAC,SAAAA,WAAoBJ,SAAAA,GAAYN,GAAAA;AAAAA;AAAAA,KAEhCW,qBAAAA,qBAA0CF,UAAAA,GAAaA,UAAAA,kBAC5CG,WAAAA,GAAcJ,kBAAAA,CAAmBI,WAAAA,CAAYC,CAAAA;AAAAA,UAEnDC,kBAAAA;EACNlM,QAAAA,EAAU1G,cAAAA;EACVoB,IAAAA,EAAML,UAAAA;AAAAA;AAAAA,UAOAkS,aAAAA,qBAAkCV,UAAAA,GAAaA,UAAAA;EACrDY,QAAAA;EACA/F,OAAAA;EACAgG,QAAAA;EACAC,QAAAA;EACAC,EAAAA,GAAKjH,UAAAA;EACLkB,KAAAA,GAAQmD,UAAAA;EACR7D,iBAAAA;EACA0G,UAAAA,GAAab,WAAAA;EACbc,WAAAA,GAAc7L,IAAAA,GAAO4E,IAAAA;EACrBkH,aAAAA;EACAC,gBAAAA,GAAmBjM,WAAAA,CAAYyL,MAAAA;EAC/BS,gBAAAA,GAAmBlM,WAAAA,CAAYyL,MAAAA;EAC/BU,QAAAA,GAAWjM,IAAAA,GAAO4E,IAAAA;EAClB2E,OAAAA,GAAUN,aAAAA;EACVO,WAAAA,GAAcJ,iBAAAA;EACd8C,WAAAA;AAAAA;AAAAA,KAEC3B,eAAAA,WAA0BK,UAAAA,GAAaA,UAAAA,IAAcE,qBAAAA,CAAsB9G,CAAAA;EAAAA,SACnEuI,SAAAA,EAAWtM,OAAAA;EAAAA,SACX2F,KAAAA,EAAOmD,UAAAA;EAAAA,SACPyD,KAAAA;EAAAA,SACAC,MAAAA;EACT1G,KAAAA,IAAS9F,OAAAA;EACTyM,KAAAA,IAASA,KAAAA,UAAeC,MAAAA,UAAgBtG,OAAAA,GAAUgD,YAAAA,GAAepJ,OAAAA,CAAQkM,OAAAA,CAAQnI,CAAAA;EACjF4I,GAAAA,IAAOC,UAAAA,EAAYT,oBAAAA,KAAyBO,MAAAA,UAAgB1M,OAAAA,CAAQkM,OAAAA,CAAQnI,CAAAA;EAC5E8I,IAAAA,CAAKJ,KAAAA,UAAerG,OAAAA,GAAUgD,YAAAA,GAAepJ,OAAAA,CAAQJ,KAAAA,CAAMsM,OAAAA;EAC3DY,aAAAA,CAAcL,KAAAA,WAAgBzM,OAAAA,CAAQoM,mBAAAA;EACtCW,WAAAA,IAAeE,QAAAA,GAAWD,EAAAA,EAAIX,WAAAA,KAAgBrM,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EACnEmJ,eAAAA,CAAgBtT,OAAAA,EAAST,UAAAA,EAAYiN,OAAAA,GAAUwD,mBAAAA,GAAsB5J,OAAAA,CAAQ7G,UAAAA;EAC7EgU,qBAAAA,CAAsBvT,OAAAA,EAAST,UAAAA,EAAYiN,OAAAA,GAAU0D,yBAAAA,GAA4B9J,OAAAA;EACjFoN,YAAAA,CAAaxT,OAAAA,EAAST,UAAAA,EAAYiN,OAAAA,GAAUwD,mBAAAA,GAAsB5J,OAAAA,CAAQgL,kBAAAA;EAC1EqC,YAAAA,IAAgBC,EAAAA,QAAUtN,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EAC/CwJ,MAAAA,CAAO9Q,OAAAA,UAAiBwQ,QAAAA,GAAWvQ,OAAAA,mBAA0BsQ,EAAAA,GAAKX,WAAAA,GAAcrM,OAAAA,EAASgN,EAAAA,GAAKX,WAAAA,KAAgBrM,OAAAA;EAC9GwN,QAAAA,CAAS/Q,OAAAA,UAAiBwQ,QAAAA,IAAYvQ,OAAAA,mBAA0BsQ,EAAAA,GAAKX,WAAAA,GAAcrM,OAAAA;EACnFyN,cAAAA,CAAeR,QAAAA,GAAWxQ,OAAAA,UAAiBC,OAAAA;EAC3CgR,eAAAA,CAAgBT,QAAAA,GAAWxQ,OAAAA,UAAiBC,OAAAA;EAC5CiR,WAAAA,CAAYtI,WAAAA,GAAcd,yBAAAA,GAA4BvE,OAAAA,CAAQ2E,IAAAA,GAAO5E,IAAAA;EACrE6N,iBAAAA,IAAqB5N,OAAAA;AAAAA;AAAAA,KAEpB6N,yBAAAA,MAA+BC,CAAAA,SAAUnD,UAAAA,iBAC9BmD,CAAAA,GAAIA,CAAAA,CAAE/C,CAAAA,UAAWP,SAAAA,GAAYwD,OAAAA,CAAQD,UAAAA,CAAWD,CAAAA,CAAE/C,CAAAA,+CAAgDkD,CAAAA,2CAA4CA,CAAAA,qBAC1J9O,MAAAA;AAAAA,KACC+O,GAAAA;EAAAA,CACAC,GAAAA;AAAAA,KACApK,CAAAA;AAAAA,KACAmI,OAAAA;EAAAA,CACAiC,GAAAA;AAAAA;EAEDC,IAAAA,EAAMF,GAAAA,CAAInK,CAAAA;EACVsK,YAAAA;EACAxS,MAAAA;IACIxD,IAAAA;IACAkD,UAAAA;EAAAA;EAEJiO,IAAAA,GAAOzJ,IAAAA;AAAAA;AAAAA,UAEDsM,WAAAA;EACNI,KAAAA,IAASA,KAAAA,UAAeC,MAAAA,UAAgBtG,OAAAA,GAAUgD,YAAAA,GAAepJ,OAAAA,CAAQkM,OAAAA,CAAQnI,CAAAA;EACjF4I,GAAAA,IAAOC,UAAAA,EAAYT,oBAAAA,KAAyBO,MAAAA,UAAgB1M,OAAAA,CAAQkM,OAAAA,CAAQnI,CAAAA;EAC5E8I,IAAAA,CAAKJ,KAAAA,UAAerG,OAAAA,GAAUgD,YAAAA,GAAepJ,OAAAA,CAAQJ,KAAAA,CAAMsM,OAAAA;EAC3DoC,QAAAA,IAAYtO,OAAAA;EACZuN,MAAAA,CAAO9Q,OAAAA,UAAiBwQ,QAAAA,GAAWvQ,OAAAA,oBAA2BsD,OAAAA,EAASgN,EAAAA,GAAKX,WAAAA,KAAgBrM,OAAAA;EAAAA,IACxFwM,MAAAA;AAAAA;AAAAA,KAEHJ,mBAAAA;EACDqC,WAAAA;IACIlT,UAAAA;IACAmT,UAAAA,EAAYH,UAAAA;EAAAA;EAEhBI,YAAAA;IACItW,IAAAA;IACAkD,UAAAA;IACAqT,MAAAA,EAAQJ,MAAAA;EAAAA;AAAAA;AAAAA,KA4GXA,MAAAA,IAAUuE,CAAAA,UAAWQ,MAAAA;AAAAA,KACrBhF,UAAAA,IAAcwE,CAAAA;AAAAA,uBAgGIwF,UAAAA,YAAsBE,IAAAA,CAAKnO,eAAAA;EAAAA,CAC7CoO,OAAAA;EACDnP,WAAAA,EAAapK,MAAAA,kBAAwBoP,UAAAA;EACrCjF,OAAAA,EAASnK,MAAAA,kBAAwBqP,MAAAA;EAAAA,SACxB7I,KAAAA,EAAOmD,UAAAA;EAjRKnE;;;;;EAAAA,SAuRZyI,YAAAA,CAAaxT,OAAAA,EAAST,UAAAA;IAAc6L,QAAAA;IAAUyE;EAAAA,GAAYG,mBAAAA,GAAsB5J,OAAAA,CAAQgL,kBAAAA;EAjRnF7B;;;;;EAAAA,SAuRLwP,kBAAAA,CAAmB/e,OAAAA,EAAST,UAAAA;IAAc6L,QAAAA;IAAUyE;EAAAA,GAAYG,mBAAAA,GAAsB5J,OAAAA,CAAQ5H,cAAAA;EArSvGmT;;;;;;;;;;;EAAAA,SAiTS2B,eAAAA,CAAgBtT,OAAAA,EAAST,UAAAA;IAAc6L;EAAAA,GAAY4E,mBAAAA,GAAsB5J,OAAAA,CAAQ7G,UAAAA;EAzS5E4G;;;;;;;;;;;EAAAA,SAqTLoN,qBAAAA,CAAsBvT,OAAAA,EAAST,UAAAA;IAAc6L,QAAAA;IAAU+E;EAAAA,GAAaD,yBAAAA,GAA4B9J,OAAAA;EAhTzGsJ;;;;EAAAA,SAqTStE,QAAAA,CAAAA,GAAYhF,OAAAA;EAnTV;;AAAA;;EAAA,SAwTF4Y,WAAAA,CAAYpP,IAAAA,GAAO7E,IAAAA,GAAO5E,IAAAA,GAAOC,OAAAA;EAtTf2K;;;EAAAA,SA0TlBkO,eAAAA,CAAAA,GAAmB7Y,OAAAA,CAAQ2E,IAAAA,GAAO5E,IAAAA;EAzTvBC;;;EAAAA,SA6TX8Y,YAAAA,CAAAA,GAAgB9Y,OAAAA;EAAAA,SAChB+Y,WAAAA,CAAAA,GAAe/Y,OAAAA;EAAAA,SACfgZ,kBAAAA,GAAAA,CAAsB1L,EAAAA,QAAUtN,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EAAAA,SACrDkV,wBAAAA,GAAAA,CAA4B3L,EAAAA,QAAUtN,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EA1TjDoI;;;EAAAA,SA8TVoB,MAAAA,CAAO9Q,OAAAA,UAAiBwQ,QAAAA,GAAWvQ,OAAAA,mBAA0BsQ,EAAAA,GAAKX,WAAAA,GAAcrM,OAAAA,EAASgN,EAAAA,GAAKX,WAAAA,KAAgBrM,OAAAA;EA7TzFoJ;;;;;;;;EAsU9B8P,eAAAA,CAAAA;IAAkBV;EAAAA;IACdA,KAAAA;EAAAA,IACAxY,OAAAA;EArUqB7G;;;;EA0UzByU,iBAAAA,CAAAA,GAAqB5N,OAAAA;EAzUgC8J;;;;;;;EAiVrD2C,KAAAA,GAAAA,CAASA,KAAAA,UAAeC,MAAAA,UAAgBtG,OAAAA,GAAUgD,YAAAA,GAAepJ,OAAAA,CAAQkM,OAAAA,CAAQnI,CAAAA;EA/UlCA;;;;;;;;;;;;;;;;;EAiW/C4I,GAAAA,GAAAA,CAAOC,UAAAA,EAAYT,oBAAAA,KAAyBO,MAAAA,UAAgB1M,OAAAA,CAAQkM,OAAAA,CAAQnI,CAAAA;EA/WtB8G;;;;;;EAsXtDgC,IAAAA,CAAKJ,KAAAA,UAAerG,OAAAA,GAAUgD,YAAAA,GAAepJ,OAAAA,CAAQJ,KAAAA,CAAMsM,OAAAA;EAlXlDM;;;;;EAwXTM,aAAAA,CAAcL,KAAAA,UAAerG,OAAAA,GAAUgD,YAAAA,GAAepJ,OAAAA,CAAQoM,mBAAAA;EAtXtCM;;;;;EA4XxBK,WAAAA,GAAAA,CAAeE,QAAAA,GAAWD,EAAAA,EAAIX,WAAAA,KAAgBrM,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EA3XnE4I;;;;;;;;EAoYAU,YAAAA,GAAAA,CAAgBC,EAAAA,QAAUtN,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;AAAAA;AAAAA,cAGrCW,MAAAA,SAAe6T,UAAAA,YAAsBjO,eAAAA,EAAiBgP,eAAAA;EAAAA,CAC/DZ,OAAAA;EACDhN,EAAAA,GAAKjH,UAAAA;EAAAA,UACKtE,GAAAA,GAAMT,WAAAA;EAAAA,iBACC6Z,qBAAAA;EAAAA,IACb7V,GAAAA,CAAAA;EAAAA,SACK8B,OAAAA;EAAAA,SACA8G,SAAAA,EAAWtM,OAAAA;EAAAA,SACX2F,KAAAA,EAAOmD,UAAAA;EAAAA,gBACA0Q,qBAAAA;EAAAA,gBACAC,eAAAA;EAChBC,uBAAAA;EAAAA,gBACgBC,kBAAAA;EAhZsC5V;;;;;;;EAwZtD/K,WAAAA,CAAYwM,OAAAA,WAAkBY,OAAAA,GAAUiF,aAAAA;EAvZHjF;;;;EA4ZrCpN,WAAAA,CAAYoN,OAAAA,GAAUiF,aAAAA;EA3ZAzR;;;;;;;EAAAA,OAmafggB,MAAAA,WAAiBvO,aAAAA,CAAAA,CAAejF,OAAAA,GAAU+S,CAAAA,GAAInZ,OAAAA,CAAQ0E,MAAAA,GAASmJ,yBAAAA,CAA0BsL,CAAAA;EAla9D/S;;;;;;;;;;EAAAA,OA6a3BwT,MAAAA,WAAiBvO,aAAAA,CAAAA,CAAe7F,OAAAA,WAAkBY,OAAAA,GAAU+S,CAAAA,GAAInZ,OAAAA,CAAQ0E,MAAAA,GAASmJ,yBAAAA,CAA0BsL,CAAAA;EAClHU,iBAAAA,CAAkBC,GAAAA,UAAahY,IAAAA;EA5aIpF;;;EAAAA,IAgb/B4O,MAAAA,CAAAA,GAAU5L,WAAAA;EAhbkEM;;;EAAAA,IAob5EuM,KAAAA,CAAAA;EAnbJiB;;;EAAAA,IAubIhB,MAAAA,CAAAA;EAvbiEH;;;;EA4brEvG,KAAAA,CAAAA,GAAS9F,OAAAA;EA3bkCtD;;;;;EAAAA,CAic1C0c,MAAAA,CAAOC,YAAAA,KAAiBrZ,OAAAA;EA/bzB2N;;;;EAocAiL,WAAAA,CAAYpP,IAAAA,GAAO7E,IAAAA,GAAO5E,IAAAA,GAAOC,OAAAA;EApcoCD;;;EAwcrE+Y,YAAAA,CAAAA,GAAgB9Y,OAAAA;EAvcY;AAAA;;;EA4c5B6Y,eAAAA,CAAAA,GAAmB7Y,OAAAA,CAAQD,IAAAA;EA1ce4K;;;EA8c1CoO,WAAAA,CAAAA,GAAe/Y,OAAAA;EA7ccwK;;;;;EAmd7BuP,mBAAAA,CAAoBngB,OAAAA,EAAST,UAAAA,GAAaA,UAAAA;EAldpC;;;;;;;;;;;EA8dN+T,eAAAA,CAAgBtT,OAAAA,EAAST,UAAAA;IAAc6L;EAAAA,IAAa4E,mBAAAA,GAAsB5J,OAAAA,CAAQ7G,UAAAA;EA/dtB2U;;;;;;;;AACtD;;;EA0eNX,qBAAAA,CAAsBvT,OAAAA,EAAST,UAAAA;IAAc6L,QAAAA;IAAU+E;EAAAA,GAAaD,yBAAAA,GAA4B9J,OAAAA;EAze3F+D;;;;;EA+eLqJ,YAAAA,CAAaxT,OAAAA,EAAST,UAAAA;IAAc6L,QAAAA;IAAU6E,YAAAA;IAAcJ;EAAAA,IAAcG,mBAAAA,GAAsB5J,OAAAA,CAAQgL,kBAAAA;EA5ehG;;;;;EAkfR2N,kBAAAA,CAAmB/e,OAAAA,EAAST,UAAAA;IAAc6L,QAAAA;IAAU6E,YAAAA;IAAcJ;EAAAA,IAAaG,mBAAAA,GAAsB5J,OAAAA,CAAQ5H,cAAAA;EAzelG;;;;EA8eX4hB,eAAAA,CAAAA;EApfUjW;;;;EAyfViB,QAAAA,CAAAA,GAAYhF,OAAAA;EAnfZwJ;;;;AAAW;EAyfX+D,MAAAA,CAAO9Q,OAAAA,UAAiBwQ,QAAAA,GAAWvQ,OAAAA,mBAA0BsQ,EAAAA,GAAKX,WAAAA,GAAcrM,OAAAA,EAASgN,EAAAA,GAAKX,WAAAA,KAAgBrM,OAAAA;EAvf7F+D;;;;;EA6fjByJ,QAAAA,CAAS/Q,OAAAA,UAAiBwQ,QAAAA,IAAYvQ,OAAAA,mBAA0BsQ,EAAAA,GAAKX,WAAAA,GAAcrM,OAAAA;EA3fP+D;;;;EAggB5E0J,cAAAA,CAAeR,QAAAA,GAAWxQ,OAAAA,UAAiBC,OAAAA;EA/fUkD;;;;EAogBrD8N,eAAAA,CAAgBT,QAAAA,GAAWxQ,OAAAA,UAAiBC,OAAAA;EAlgBkBsD;;;;;EAwgB9D2N,WAAAA,CAAYtI,WAAAA,GAAcd,yBAAAA,GAA4BvE,OAAAA,CAAQ2E,IAAAA,GAAO5E,IAAAA;EA5gB7C2M;;;;;EAkhBxBsM,kBAAAA,GAAAA,CAAsB1L,EAAAA,QAAUtN,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EAjhBrD4I;;;;;EAuhBAsM,wBAAAA,GAAAA,CAA4B3L,EAAAA,QAAUtN,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EAC3DkW,KAAAA,CAAAA,GAASja,OAAAA,CAAQsK,eAAAA;EACjB4P,mBAAAA,GAAAA,CAAuB5M,EAAAA,QAAUtN,OAAAA,CAAQ+D,CAAAA,IAAK/D,OAAAA,CAAQ+D,CAAAA;EACtDpB,QAAAA,CAASC,IAAAA;AAAAA;;;UCvjCI,YAAA;EACf,MAAA,SAAe,MAAA;AAAA;AAAA,cAGJ,sBAAA,SAA+B,gBAAA;EAAA,OAC5B,YAAA,CAAA,GAAgB,YAAA;EAAA,IAQV,MAAA,CAAA;EAAA,mBAID,GAAA;;;;qBACA,KAAA;;;;;;qBACA,OAAA,EAAO,oBAAA;EAAA,UAEhB,MAAA,GAAS,MAAA;EAAA,UACT,MAAA,GAAS,cAAA;EAAA,IAER,IAAA,CAAA;EAAA,IAIA,MAAA,CAAA;EAAA,SAIc,OAAA;EAAA,IAEL,oBAAA,CAAA;EAAA,IAIA,GAAA,CAAA;EAAA,IAqBA,EAAA,CAAA,GAAM,cAAA;EAQJ,OAAA,CACpB,SAAA,EAAW,OAAA,GACV,OAAA,CAAQ,KAAA,CAAM,MAAA;EAAA,mBAKE,OAAA,EALT,QAAA,CAKgB,aAAA;EAAA,mBAkCP,MAAA,EAlCO,QAAA,CAkCD,aAAA;EAAA,UAaT,iBAAA,CAAkB,gBAAA,WAA2B,OAAA;AAAA;;;;;;;;cC7HlD,iBAAA,WAAiB,OAAA;;;;sCAoB5B,QAAA,CAAA,OAAA;;;APcF;;EAAkC;;;;EAMO;;;;;;YOjB7B,GAAA,SAAY,OAAA,CAAQ,MAAA,QAAc,iBAAA;AAAA;;;;;;cCzBjC,IAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;cCiBA,iBAAA,EAAiB,QAAA,CAAA,OAAA,CAwC5B,QAAA,CAxC4B,MAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/orm/postgres/services/PostgresModelBuilder.ts","../../../src/orm/postgres/providers/PostgresProvider.ts","../../../src/orm/postgres/providers/BunPostgresProvider.ts","../../../src/orm/postgres/providers/CloudflareHyperdriveProvider.ts","../../../src/orm/postgres/providers/NodePostgresProvider.ts","../../../src/orm/postgres/providers/PglitePostgresProvider.ts","../../../src/orm/postgres/schemas/postgresEnvSchema.ts","../../../src/orm/postgres/types/byte.ts","../../../src/orm/postgres/index.ts"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { AlephaOrm, DatabaseProvider, DbMigrationError, ModelBuilder, PG_CREATED
4
4
  import { sql as sql$1 } from "drizzle-orm";
5
5
  import { $lock } from "alepha/lock";
6
6
  import * as pg from "drizzle-orm/pg-core";
7
- import { check, customType, foreignKey, index, pgEnum, pgMaterializedView, pgSchema, pgSequence, pgTable, pgView, unique, uniqueIndex } from "drizzle-orm/pg-core";
7
+ import { check, customType, foreignKey, index, pgEnum, pgSchema, pgSequence, pgTable, unique, uniqueIndex } from "drizzle-orm/pg-core";
8
8
  import { drizzle } from "drizzle-orm/postgres-js";
9
9
  import { migrate } from "drizzle-orm/postgres-js/migrator";
10
10
  import postgres from "postgres";
@@ -17,9 +17,21 @@ import { migrate as migrate$1 } from "drizzle-orm/pglite/migrator";
17
17
  * Additional env vars for PostgreSQL providers on top of `databaseEnvSchema`.
18
18
  */
19
19
  const postgresEnvSchema = t.object({
20
+ /**
21
+ * PostgreSQL schema name (defaults to `"public"` when unset).
22
+ */
20
23
  POSTGRES_SCHEMA: t.optional(t.text()),
24
+ /**
25
+ * Maximum number of connections in the pool.
26
+ */
21
27
  POOL_MAX: t.optional(t.integer()),
28
+ /**
29
+ * Seconds a connection can be idle before being closed.
30
+ */
22
31
  POOL_IDLE_TIMEOUT: t.optional(t.integer()),
32
+ /**
33
+ * Seconds to wait when establishing a new connection.
34
+ */
23
35
  POOL_CONNECT_TIMEOUT: t.optional(t.integer())
24
36
  });
25
37
  //#endregion
@@ -58,19 +70,6 @@ var PostgresModelBuilder = class extends ModelBuilder {
58
70
  const table = nsp.table(tableName, columns, configFn);
59
71
  options.tables.set(tableName, table);
60
72
  }
61
- buildView(view, options) {
62
- const viewName = view.name;
63
- if (options.tables.has(viewName)) return;
64
- const columns = this.schemaToPgColumns(viewName, view.schema, {
65
- enum: pgEnum,
66
- table: pgTable,
67
- sequence: pgSequence
68
- }, /* @__PURE__ */ new Map(), options.tables);
69
- let drizzleView;
70
- if (view.materialized) drizzleView = pgMaterializedView(viewName, columns).existing();
71
- else drizzleView = pgView(viewName, columns).existing();
72
- options.tables.set(viewName, drizzleView);
73
- }
74
73
  buildSequence(sequence, options) {
75
74
  const sequenceName = sequence.name;
76
75
  if (options.sequences.has(sequenceName)) return;
@@ -114,10 +113,8 @@ var PostgresModelBuilder = class extends ModelBuilder {
114
113
  col = col.generatedAlwaysAs(gen.expression);
115
114
  }
116
115
  if (schema.required?.includes(key)) col = col.notNull();
117
- return {
118
- ...columns,
119
- [key]: col
120
- };
116
+ columns[key] = col;
117
+ return columns;
121
118
  }, {});
122
119
  };
123
120
  mapFieldToColumn = (tableName, fieldName, value, nsp, enums) => {
@@ -149,11 +146,11 @@ var PostgresModelBuilder = class extends ModelBuilder {
149
146
  if (value.format === "int64") return pg.bigint(key, { mode: "number" });
150
147
  return pg.numeric(key);
151
148
  }
152
- if (t.schema.isString(value)) return this.mapStringToColumn(key, value);
149
+ const isTypeEnum = (value) => t.schema.isUnsafe(value) && "type" in value && value.type === "string" && "enum" in value && Array.isArray(value.enum);
150
+ if (t.schema.isString(value) && !isTypeEnum(value)) return this.mapStringToColumn(key, value);
153
151
  if (t.schema.isBoolean(value)) return pg.boolean(key);
154
152
  if (t.schema.isObject(value)) return schema(key, value);
155
153
  if (t.schema.isRecord(value)) return schema(key, value);
156
- const isTypeEnum = (value) => t.schema.isUnsafe(value) && "type" in value && value.type === "string" && "enum" in value && Array.isArray(value.enum);
157
154
  if (t.schema.isArray(value)) {
158
155
  if (t.schema.isObject(value.items)) return schema(key, value);
159
156
  if (t.schema.isRecord(value.items)) return schema(key, value);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["sql","sql","sql","sql","sql","migrate"],"sources":["../../../src/orm/postgres/schemas/postgresEnvSchema.ts","../../../src/orm/postgres/types/byte.ts","../../../src/orm/postgres/services/PostgresModelBuilder.ts","../../../src/orm/postgres/providers/PostgresProvider.ts","../../../src/orm/postgres/providers/BunPostgresProvider.ts","../../../src/orm/postgres/providers/CloudflareHyperdriveProvider.ts","../../../src/orm/postgres/providers/NodePostgresProvider.ts","../../../src/orm/postgres/providers/PglitePostgresProvider.ts","../../../src/orm/postgres/index.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\n\n/**\n * PostgreSQL-specific environment schema.\n *\n * Additional env vars for PostgreSQL providers on top of `databaseEnvSchema`.\n */\nexport const postgresEnvSchema = t.object({\n /**\n * PostgreSQL schema name (defaults to `\"public\"` when unset).\n */\n POSTGRES_SCHEMA: t.optional(t.text()),\n\n /**\n * Maximum number of connections in the pool.\n */\n POOL_MAX: t.optional(t.integer()),\n\n /**\n * Seconds a connection can be idle before being closed.\n */\n POOL_IDLE_TIMEOUT: t.optional(t.integer()),\n\n /**\n * Seconds to wait when establishing a new connection.\n */\n POOL_CONNECT_TIMEOUT: t.optional(t.integer()),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof postgresEnvSchema>> {}\n}\n","import { customType } from \"drizzle-orm/pg-core\";\n\n/**\n * Postgres bytea type.\n */\nexport const byte = customType<{\n data: Buffer;\n}>({\n dataType: () => \"bytea\",\n});\n","import { AlephaError, type TObject, type TSchema, t } from \"alepha\";\nimport {\n type EntityPrimitive,\n type FromSchema,\n ModelBuilder,\n PG_CREATED_AT,\n PG_GENERATED,\n PG_IDENTITY,\n PG_PRIMARY_KEY,\n PG_REF,\n PG_SERIAL,\n PG_UPDATED_AT,\n type PgGeneratedOptions,\n type PgIdentityOptions,\n type PgRefOptions,\n type SequencePrimitive,\n schema,\n sql,\n type ViewPrimitive,\n} from \"alepha/orm\";\nimport type { BuildExtraConfigColumns } from \"drizzle-orm\";\nimport * as pg from \"drizzle-orm/pg-core\";\nimport {\n check,\n foreignKey,\n index,\n type PgEnum,\n type PgSchema,\n type PgTableExtraConfigValue,\n type PgTableWithColumns,\n pgEnum,\n pgMaterializedView,\n pgSchema,\n pgSequence,\n pgTable,\n pgView,\n unique,\n uniqueIndex,\n} from \"drizzle-orm/pg-core\";\nimport { byte } from \"../types/byte.ts\";\n\nexport class PostgresModelBuilder extends ModelBuilder {\n protected schemas = new Map<string, PgSchema>();\n\n /**\n * Create a primary key column with UUID v7\n */\n protected getPrimaryKeyUUID(key: string) {\n return pg.uuid(key).default(sql`uuidv7()`);\n }\n\n protected getPgSchema(name: string) {\n if (!this.schemas.has(name) && name !== \"public\") {\n this.schemas.set(name, pgSchema(name));\n }\n\n const nsp =\n name !== \"public\"\n ? this.schemas.get(name)\n : ({\n enum: pgEnum,\n table: pgTable,\n sequence: pgSequence,\n } as any);\n\n if (!nsp) {\n throw new AlephaError(`Postgres schema ${name} not found`);\n }\n\n return nsp;\n }\n\n public buildTable(\n entity: EntityPrimitive<any>,\n options: {\n tables: Map<string, unknown>;\n enums: Map<string, unknown>;\n schemas: Map<string, unknown>;\n schema: string;\n },\n ) {\n const tableName = entity.name;\n if (options.tables.has(tableName)) {\n return;\n }\n\n const nsp = this.getPgSchema(options.schema);\n\n // Register PgSchema so drizzle-kit knows the schema is declared in code.\n // Without this, pushSchema diffs \"schema exists in DB but not in code\" → DROP.\n if (options.schema !== \"public\" && !options.schemas.has(options.schema)) {\n options.schemas.set(options.schema, nsp);\n }\n\n const columns = this.schemaToPgColumns(\n tableName,\n entity.schema,\n nsp,\n options.enums,\n options.tables,\n );\n\n // Build the config function that includes indexes, foreign keys, constraints, and custom config\n const configFn = this.getTableConfig(entity, options.tables);\n\n const table = nsp.table(tableName, columns, configFn);\n\n options.tables.set(tableName, table);\n }\n\n public buildView(\n view: ViewPrimitive,\n options: {\n tables: Map<string, unknown>;\n schema: string;\n },\n ) {\n const viewName = view.name;\n if (options.tables.has(viewName)) {\n return;\n }\n\n const columns = this.schemaToPgColumns(\n viewName,\n view.schema,\n { enum: pgEnum, table: pgTable, sequence: pgSequence } as any,\n new Map(),\n options.tables,\n );\n\n let drizzleView: unknown;\n if (view.materialized) {\n drizzleView = pgMaterializedView(viewName, columns).existing();\n } else {\n drizzleView = pgView(viewName, columns).existing();\n }\n\n options.tables.set(viewName, drizzleView);\n }\n\n public buildSequence(\n sequence: SequencePrimitive,\n options: {\n sequences: Map<string, unknown>;\n schema: string;\n },\n ) {\n const sequenceName = sequence.name;\n if (options.sequences.has(sequenceName)) {\n return;\n }\n\n const nsp = this.getPgSchema(options.schema);\n\n options.sequences.set(\n sequenceName,\n nsp.sequence(sequenceName, sequence.options),\n );\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Get PostgreSQL-specific config builder for the table.\n */\n protected getTableConfig(\n entity: EntityPrimitive,\n tables: Map<string, unknown>,\n ):\n | ((\n self: BuildExtraConfigColumns<string, any, \"pg\">,\n ) => PgTableExtraConfigValue[])\n | undefined {\n // PostgreSQL-specific builders\n const pgBuilders = {\n index,\n uniqueIndex,\n unique,\n check,\n foreignKey,\n };\n\n // Table resolver function\n const tableResolver = (entityName: string) => {\n return tables.get(entityName) as any;\n };\n\n return this.buildTableConfig<\n PgTableExtraConfigValue,\n BuildExtraConfigColumns<string, any, \"pg\">\n >(entity, pgBuilders as any, tableResolver);\n }\n\n schemaToPgColumns = <T extends TObject>(\n tableName: string,\n schema: T,\n nsp: PgSchema,\n enums: Map<string, unknown>,\n tables: Map<string, unknown>,\n ): FromSchema<T> => {\n return Object.entries(schema.properties).reduce<Partial<FromSchema<T>>>(\n (columns, [key, value]) => {\n let col = this.mapFieldToColumn(tableName, key, value, nsp, enums);\n\n if (\"default\" in value && value.default != null) {\n col = col.default(value.default as any);\n }\n\n if (PG_PRIMARY_KEY in value) {\n col = col.primaryKey();\n }\n\n if (PG_REF in value) {\n const config = value[PG_REF] as PgRefOptions;\n col = col.references(() => {\n const ref = config.ref();\n const table = tables.get(\n ref.entity.name,\n ) as PgTableWithColumns<any>;\n\n if (!table) {\n throw new AlephaError(\n `Referenced table ${ref.entity.name} not found for ${tableName}.${key}`,\n );\n }\n\n const target = table[ref.name];\n if (!target) {\n throw new AlephaError(\n `Referenced column ${ref.name} not found in table ${ref.entity.name} for ${tableName}.${key}`,\n );\n }\n\n return target;\n }, config.actions);\n }\n\n if (PG_GENERATED in value) {\n const gen = value[PG_GENERATED] as PgGeneratedOptions;\n col = col.generatedAlwaysAs(gen.expression);\n }\n\n if (schema.required?.includes(key)) {\n col = col.notNull();\n }\n\n return {\n ...columns,\n [key]: col,\n };\n },\n {},\n ) as FromSchema<T>;\n };\n\n mapFieldToColumn = (\n tableName: string,\n fieldName: string,\n value: TSchema,\n nsp: PgSchema,\n enums: Map<string, any>,\n ) => {\n const key = this.toColumnName(fieldName);\n\n if (\n // is nullish ?\n \"anyOf\" in value &&\n Array.isArray(value.anyOf) &&\n value.anyOf.length === 2 &&\n value.anyOf.some((it: TSchema) => t.schema.isNull(it))\n ) {\n // then, remove nullish\n value = value.anyOf.find((it: TSchema) => !t.schema.isNull(it))!;\n }\n\n if (t.schema.isInteger(value)) {\n if (PG_SERIAL in value) {\n return pg.serial(key);\n }\n\n if (PG_IDENTITY in value) {\n const options = value[PG_IDENTITY] as PgIdentityOptions;\n if (options.mode === \"byDefault\") {\n return pg.integer(key).generatedByDefaultAsIdentity(options);\n }\n return pg.integer(key).generatedAlwaysAsIdentity(options);\n }\n\n return pg.integer(key);\n }\n\n if (t.schema.isBigInt(value)) {\n if (PG_IDENTITY in value) {\n const options = value[PG_IDENTITY] as PgIdentityOptions;\n if (options.mode === \"byDefault\") {\n return pg\n .bigint(key, { mode: \"bigint\" })\n .generatedByDefaultAsIdentity(options);\n }\n return pg\n .bigint(key, { mode: \"bigint\" })\n .generatedAlwaysAsIdentity(options);\n }\n\n return pg.bigint(key, { mode: \"bigint\" });\n }\n\n if (t.schema.isNumber(value)) {\n if (PG_IDENTITY in value) {\n const options = value[PG_IDENTITY] as PgIdentityOptions;\n if (options.mode === \"byDefault\") {\n return pg\n .bigint(key, { mode: \"number\" })\n .generatedByDefaultAsIdentity(options);\n }\n return pg\n .bigint(key, { mode: \"number\" })\n .generatedAlwaysAsIdentity(options);\n }\n\n if (value.format === \"int64\") {\n return pg.bigint(key, { mode: \"number\" });\n }\n\n return pg.numeric(key);\n }\n\n if (t.schema.isString(value)) {\n return this.mapStringToColumn(key, value);\n }\n\n if (t.schema.isBoolean(value)) {\n return pg.boolean(key);\n }\n\n if (t.schema.isObject(value)) {\n return schema(key, value);\n }\n\n if (t.schema.isRecord(value)) {\n return schema(key, value);\n }\n\n const isTypeEnum = (value: any): value is { enum: any[] } =>\n t.schema.isUnsafe(value) &&\n \"type\" in value &&\n value.type === \"string\" &&\n \"enum\" in value &&\n Array.isArray(value.enum);\n\n if (t.schema.isArray(value)) {\n if (t.schema.isObject(value.items)) {\n return schema(key, value);\n }\n if (t.schema.isRecord(value.items)) {\n return schema(key, value);\n }\n if (t.schema.isString(value.items)) {\n return pg.text(key).array();\n }\n if (t.schema.isInteger(value.items)) {\n return pg.integer(key).array();\n }\n if (t.schema.isNumber(value.items)) {\n return pg.numeric(key).array();\n }\n if (t.schema.isBoolean(value.items)) {\n return pg.boolean(key).array();\n }\n if (isTypeEnum(value.items)) {\n return pg.text(key).array();\n }\n }\n\n // Enum handling\n if (isTypeEnum(value)) {\n if (!value.enum.every((it) => typeof it === \"string\")) {\n throw new AlephaError(\n `Enum for ${fieldName} must be an array of strings, got ${JSON.stringify(\n value.enum,\n )}`,\n );\n }\n\n // SQL Enum (default for t.enum unless mode: \"text\")\n if ((value as any).mode !== \"text\") {\n const enumName = (value as any).enumName ?? `${tableName}_${key}_enum`;\n\n if (enums.has(enumName)) {\n const values = (\n enums.get(enumName) as PgEnum<[string]>\n ).enumValues.join(\",\");\n const newValues = value.enum.join(\",\");\n if (values !== newValues) {\n throw new AlephaError(\n `Enum name conflict for ${enumName}: [${values}] vs [${newValues}]`,\n );\n }\n }\n\n enums.set(enumName, nsp.enum(enumName, value.enum as [string]));\n\n return enums.get(enumName)(key);\n }\n\n // else, map to TEXT\n return this.mapStringToColumn(key, value);\n }\n\n throw new AlephaError(\n `Unsupported schema type for ${fieldName} as ${JSON.stringify(value)}`,\n );\n };\n\n /**\n * Map a string to a PG column.\n *\n * @param key The key of the field.\n * @param value The value of the field.\n */\n mapStringToColumn = (key: string, value: TSchema) => {\n if (\"format\" in value) {\n if (value.format === \"uuid\") {\n if (PG_PRIMARY_KEY in value) {\n return this.getPrimaryKeyUUID(key);\n }\n\n return pg.uuid(key);\n }\n\n if (value.format === \"byte\") {\n return byte(key);\n }\n\n if (value.format === \"date-time\") {\n if (PG_CREATED_AT in value) {\n return pg\n .timestamp(key, { mode: \"string\", withTimezone: true })\n .defaultNow();\n }\n if (PG_UPDATED_AT in value) {\n return pg\n .timestamp(key, { mode: \"string\", withTimezone: true })\n .defaultNow();\n }\n return pg.timestamp(key, { mode: \"string\", withTimezone: true });\n }\n\n if (value.format === \"date\") {\n return pg.date(key, { mode: \"string\" });\n }\n }\n\n return pg.text(key);\n };\n}\n","import { $env, $hook, $inject, $pipeline, AlephaError } from \"alepha\";\nimport { $lock } from \"alepha/lock\";\nimport {\n DatabaseProvider,\n DbMigrationError,\n databaseEnvSchema,\n type SQLLike,\n} from \"alepha/orm\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { postgresEnvSchema } from \"../schemas/postgresEnvSchema.ts\";\nimport { PostgresModelBuilder } from \"../services/PostgresModelBuilder.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Abstract base class for PostgreSQL database providers.\n *\n * Provides shared logic for Node.js and Bun PostgreSQL providers:\n * - Environment variable handling (DATABASE_URL, POSTGRES_SCHEMA)\n * - Schema name resolution (with test schema generation)\n * - SQL execution with error wrapping\n * - Lifecycle hooks (start with migration lock, stop with test cleanup)\n *\n * Subclasses must implement `connect()`, `close()`, and `executeMigrations()`.\n */\nexport abstract class PostgresProvider extends DatabaseProvider {\n protected readonly env = $env(databaseEnvSchema);\n protected readonly pgEnv = $env(postgresEnvSchema);\n protected readonly builder = $inject(PostgresModelBuilder);\n\n public override readonly dialect = \"postgresql\";\n\n public get name() {\n return \"postgres\";\n }\n\n /**\n * In testing mode, the schema name will be generated and deleted after the test.\n */\n protected schemaForTesting = this.alepha.isTest()\n ? this.generateTestSchemaName()\n : undefined;\n\n public override get url() {\n if (!this.env.DATABASE_URL) {\n throw new AlephaError(\"DATABASE_URL is not defined in the environment\");\n }\n\n return this.env.DATABASE_URL;\n }\n\n /**\n * Execute a SQL statement.\n */\n public override async execute(\n statement: SQLLike,\n ): Promise<Array<Record<string, unknown>>> {\n return await this.db.execute(statement);\n }\n\n /**\n * Get Postgres schema used by this provider.\n */\n public override get schema(): string {\n if (this.schemaForTesting) {\n return this.schemaForTesting;\n }\n\n if (this.pgEnv.POSTGRES_SCHEMA) {\n return this.pgEnv.POSTGRES_SCHEMA;\n }\n\n return \"public\";\n }\n\n public abstract override get db(): PgDatabase<any>;\n\n /**\n * Establish the database connection.\n */\n public abstract connect(): Promise<void>;\n\n /**\n * Close the database connection.\n */\n public abstract close(): Promise<void>;\n\n // -------------------------------------------------------------------------------------------------------------------\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n await this.connect();\n await this.generateTestSchema();\n\n // never migrate in serverless mode (vercel, netlify, ...)\n if (!this.alepha.isServerless()) {\n try {\n await this.migrateLock.run();\n } catch (error) {\n throw new DbMigrationError(error);\n }\n }\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: async () => {\n await this.dropTestSchema();\n await this.close();\n },\n });\n\n protected migrateLock = $pipeline({\n use: [$lock({ name: \"postgres:migrate\" })],\n handler: async () => {\n await this.migrate();\n },\n });\n\n // -------------------------------------------------------------------------------------------------------------------\n // Create unique schema for tests and clean up after. Format: test_alepha_{epoch_seconds}_{random8}\n // -------------------------------------------------------------------------------------------------------------------\n\n protected async generateTestSchema() {\n if (\n this.alepha.isTest() &&\n this.schemaForTesting?.startsWith(\"test_alepha_\")\n ) {\n // Self-healing: drop stale schemas left behind by crashed/failed test runs\n await this.cleanupStaleTestSchemas();\n\n await this.execute(\n sql`CREATE SCHEMA IF NOT EXISTS ${sql.raw(this.schemaForTesting)}`,\n );\n }\n }\n\n /**\n * Drop the current test schema if applicable.\n */\n protected async dropTestSchema(): Promise<void> {\n if (\n this.alepha.isTest() &&\n this.schemaForTesting?.startsWith(\"test_alepha_\")\n ) {\n this.log.info(`Deleting test schema '${this.schemaForTesting}' ...`);\n await this.execute(\n sql`DROP SCHEMA IF EXISTS ${sql.raw(this.schemaForTesting)} CASCADE`,\n );\n this.log.info(`Test schema '${this.schemaForTesting}' deleted`);\n }\n }\n\n /**\n * Remove stale test schemas older than 1 hour.\n *\n * Parses the embedded epoch from schema names (format: test_alepha_{epoch}_{random8})\n * and drops any that exceed the TTL. This handles schemas left behind by crashed tests,\n * killed processes, or failed startups where stop() never fired.\n *\n * Uses a PG advisory lock so only one concurrent test process performs the cleanup.\n */\n protected async cleanupStaleTestSchemas(): Promise<void> {\n try {\n // Non-blocking advisory lock — first process in cleans, others skip\n const [lock] = await this.execute(\n sql`SELECT pg_try_advisory_lock(hashtext('alepha:test:schema:cleanup')) AS acquired`,\n );\n\n if (!lock?.acquired) {\n return;\n }\n\n try {\n const result = await this.execute(\n sql`SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'test_alepha_%'`,\n );\n\n const now = this.dateTime.nowMillis();\n const maxAge = 60 * 60 * 1000; // 1 hour\n\n for (const row of result) {\n const name = row.schema_name as string;\n\n // Skip our own schema (it was just created or is about to be)\n if (name === this.schemaForTesting) {\n continue;\n }\n\n const age = this.parseTestSchemaAge(name, now);\n if (age !== undefined && age > maxAge) {\n this.log.warn(\n `Dropping stale test schema '${name}' (age: ${Math.round(age / 60_000)}min) ...`,\n );\n await this.execute(\n sql`DROP SCHEMA IF EXISTS ${sql.raw(name)} CASCADE`,\n );\n }\n }\n } finally {\n await this.execute(\n sql`SELECT pg_advisory_unlock(hashtext('alepha:test:schema:cleanup'))`,\n );\n }\n } catch (error) {\n // Don't fail test setup if stale cleanup fails\n this.log.warn(\"Failed to clean up stale test schemas\", { error });\n }\n }\n\n /**\n * Parse the age in milliseconds from a test schema name.\n * Format: test_alepha_{epoch_seconds}_{random8}\n * Returns undefined if the name doesn't match the expected format.\n */\n protected parseTestSchemaAge(name: string, now: number): number | undefined {\n const parts = name.split(\"_\");\n // test_alepha_{epoch}_{random} → [\"test\", \"alepha\", epoch, random]\n if (parts.length !== 4 || parts[0] !== \"test\" || parts[1] !== \"alepha\") {\n return undefined;\n }\n\n const epoch = Number(parts[2]);\n if (!Number.isFinite(epoch) || epoch <= 0) {\n return undefined;\n }\n\n return now - epoch * 1000;\n }\n}\n","import { AlephaError } from \"alepha\";\nimport { sql } from \"drizzle-orm\";\nimport type { BunSQLDatabase } from \"drizzle-orm/bun-sql\";\nimport type { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { PostgresProvider } from \"./PostgresProvider.ts\";\n\n/**\n * Bun PostgreSQL provider using Drizzle ORM with Bun's native SQL client.\n *\n * This provider uses Bun's built-in SQL class for PostgreSQL connections,\n * which provides excellent performance on the Bun runtime.\n *\n * @example\n * ```ts\n * // Set DATABASE_URL environment variable\n * // DATABASE_URL=postgres://user:password@localhost:5432/database\n *\n * // Or configure programmatically\n * alepha.with({\n * provide: DatabaseProvider,\n * use: BunPostgresProvider,\n * });\n * ```\n */\nexport class BunPostgresProvider extends PostgresProvider {\n protected client?: Bun.SQL;\n protected bunDb?: BunSQLDatabase;\n\n /**\n * Get the Drizzle Postgres database instance.\n */\n public override get db(): PgDatabase<any> {\n if (!this.bunDb) {\n throw new AlephaError(\"Database not initialized\");\n }\n\n return this.bunDb as unknown as PgDatabase<any>;\n }\n\n protected override async executeMigrations(\n migrationsFolder: string,\n ): Promise<void> {\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n const { migrate } = await import(\"drizzle-orm/bun-sql/migrator\");\n await migrate(this.bunDb!, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n public async connect(): Promise<void> {\n this.log.debug(\"Connect ..\");\n\n // Check if we're running in Bun\n if (typeof Bun === \"undefined\") {\n throw new AlephaError(\n \"BunPostgresProvider requires the Bun runtime. Use NodePostgresProvider for Node.js.\",\n );\n }\n\n const { drizzle } = await import(\"drizzle-orm/bun-sql\");\n\n // Create Bun SQL client with pool options\n // Set search_path via connection URL so all pool connections use the correct schema\n let connectionUrl = this.url;\n if (this.schema !== \"public\") {\n const separator = connectionUrl.includes(\"?\") ? \"&\" : \"?\";\n connectionUrl += `${separator}search_path=${this.schema},public`;\n }\n const bunOptions: Record<string, any> = { url: connectionUrl };\n if (this.pgEnv.POOL_MAX != null) {\n bunOptions.max = this.pgEnv.POOL_MAX;\n }\n if (this.pgEnv.POOL_IDLE_TIMEOUT != null) {\n bunOptions.idleTimeout = this.pgEnv.POOL_IDLE_TIMEOUT;\n }\n if (this.pgEnv.POOL_CONNECT_TIMEOUT != null) {\n bunOptions.connectionTimeout = this.pgEnv.POOL_CONNECT_TIMEOUT;\n }\n this.client = new Bun.SQL(bunOptions);\n\n // Test connection\n await this.client.unsafe(\"SELECT 1\");\n\n this.bunDb = drizzle({\n client: this.client,\n logger: {\n logQuery: (query: string, params: unknown[]) => {\n this.log.trace(query, { params });\n },\n },\n });\n\n this.log.info(\"Connection OK\");\n }\n\n public async close(): Promise<void> {\n if (this.client) {\n this.log.debug(\"Close...\");\n\n await this.client.close();\n\n this.client = undefined;\n this.bunDb = undefined;\n\n this.log.info(\"Connection closed\");\n }\n }\n}\n","import { $env, $hook, $inject, AlephaError, t } from \"alepha\";\nimport { DatabaseProvider, type SQLLike } from \"alepha/orm\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { PostgresModelBuilder } from \"../services/PostgresModelBuilder.ts\";\n\n/**\n * Cloudflare Hyperdrive PostgreSQL provider using Drizzle ORM.\n *\n * Connects to an external PostgreSQL database through Cloudflare Hyperdrive,\n * which provides connection pooling and caching at the edge.\n *\n * Creates a fresh connection per request, since Cloudflare Workers\n * cannot reuse I/O objects across request contexts.\n *\n * URL format: hyperdrive://BINDING_NAME\n */\nexport class CloudflareHyperdriveProvider extends DatabaseProvider {\n protected readonly builder = $inject(PostgresModelBuilder);\n protected readonly env = $env(\n t.object({\n DATABASE_URL: t.string({\n description: \"Expect to be 'hyperdrive://BINDING'\",\n }),\n POSTGRES_SCHEMA: t.optional(t.text()),\n }),\n );\n\n public override get schema(): string {\n return this.env.POSTGRES_SCHEMA ?? \"public\";\n }\n\n protected postgresFn?: any;\n protected drizzleFn?: any;\n protected bindingName?: string;\n\n public get name() {\n return \"postgres\";\n }\n\n public get driver() {\n return \"hyperdrive\";\n }\n\n public override readonly dialect = \"postgresql\";\n\n public override get url(): string {\n return this.env.DATABASE_URL;\n }\n\n /**\n * Get a fresh Drizzle instance per request.\n *\n * Reads the current Hyperdrive binding from `cloudflare.env`\n * and creates a new postgres client each time, avoiding the\n * \"Cannot perform I/O on behalf of a different request\" error.\n */\n public override get db(): PgDatabase<any> {\n if (!this.postgresFn || !this.drizzleFn || !this.bindingName) {\n throw new AlephaError(\"Hyperdrive database not initialized\");\n }\n\n const cloudflareEnv = this.alepha.get(\"cloudflare.env\") as\n | Record<string, unknown>\n | undefined;\n if (!cloudflareEnv) {\n throw new AlephaError(\n \"Cloudflare Workers environment not found in Alepha store under 'cloudflare.env'.\",\n );\n }\n\n const binding = cloudflareEnv[this.bindingName] as\n | { connectionString: string }\n | undefined;\n if (!binding?.connectionString) {\n throw new AlephaError(\n `Hyperdrive binding '${this.bindingName}' not found in Cloudflare Workers environment.`,\n );\n }\n\n const pgOptions: Record<string, any> = { prepare: false };\n\n // Set search_path so schema-free migration SQL resolves to the correct schema.\n if (this.schema !== \"public\") {\n pgOptions.connection = { search_path: `${this.schema}, public` };\n }\n\n const client = this.postgresFn(binding.connectionString, pgOptions);\n return this.drizzleFn(client as any) as unknown as PgDatabase<any>;\n }\n\n public override async execute(\n query: SQLLike,\n ): Promise<Array<Record<string, unknown>>> {\n return this.db.execute(query);\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n this.bindingName = this.env.DATABASE_URL.replace(\"hyperdrive://\", \"\");\n\n // Pre-load modules so db getter is synchronous\n const pgModule = await import(\"postgres\");\n const drizzleModule = await import(\"drizzle-orm/postgres-js\");\n this.postgresFn = pgModule.default ?? pgModule;\n this.drizzleFn = drizzleModule.drizzle;\n\n this.log.info(\"Using Cloudflare Hyperdrive (PostgreSQL)\");\n },\n });\n\n protected async executeMigrations(migrationsFolder: string): Promise<void> {\n this.log.debug(`Running Postgres migrations from '${migrationsFolder}'...`);\n try {\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n const { migrate } = await import(\"drizzle-orm/postgres-js/migrator\");\n await migrate(this.db as any, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n this.log.debug(\"Postgres migrations completed successfully\");\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? `${error.name}: ${error.message}`\n : String(error);\n throw new AlephaError(\n `Postgres migration failed from '${migrationsFolder}': ${errorMessage}`,\n { cause: error },\n );\n }\n }\n}\n","import { AlephaError } from \"alepha\";\nimport { sql } from \"drizzle-orm\";\nimport type { PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport { drizzle } from \"drizzle-orm/postgres-js\";\nimport { migrate } from \"drizzle-orm/postgres-js/migrator\";\nimport postgres from \"postgres\";\nimport { PostgresProvider } from \"./PostgresProvider.ts\";\n\nexport class NodePostgresProvider extends PostgresProvider {\n static readonly SSL_MODES = [\n \"require\",\n \"allow\",\n \"prefer\",\n \"verify-full\",\n ] as const;\n\n protected client?: postgres.Sql;\n protected pg?: PostgresJsDatabase;\n\n /**\n * Get the Drizzle Postgres database instance.\n */\n public override get db(): PostgresJsDatabase {\n if (!this.pg) {\n throw new AlephaError(\"Database not initialized\");\n }\n\n return this.pg;\n }\n\n protected override async executeMigrations(\n migrationsFolder: string,\n ): Promise<void> {\n // Set search_path so schema-free migration SQL resolves to the correct schema.\n // postgres.js doesn't support the `connection` startup parameter with pooled\n // connections (e.g. Neon), so we SET it explicitly before running migrations.\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n await migrate(this.db, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n public async connect(): Promise<void> {\n const options = this.getClientOptions();\n\n this.log.debug(\"Connect ..\", {\n ...options,\n password: options.password ? \"****\" : undefined, // hide password\n });\n\n const client = postgres(options);\n await client`SELECT 1`; // test connection\n\n this.client = client;\n this.pg = drizzle(client, {\n logger: {\n // forward logs\n logQuery: (query: string, params: unknown[]) => {\n this.log.trace(query, { params });\n },\n },\n });\n\n this.log.info(\"Connection OK\");\n }\n\n public async close(): Promise<void> {\n if (this.client) {\n this.log.debug(\"Close...\");\n\n await this.client.end();\n\n this.client = undefined;\n this.pg = undefined;\n\n this.log.info(\"Connection closed\");\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Map the DATABASE_URL to postgres client options.\n */\n protected getClientOptions(): postgres.Options<any> {\n const url = new URL(this.url);\n\n const options: postgres.Options<any> = {\n host: url.hostname,\n user: decodeURIComponent(url.username),\n database: decodeURIComponent(url.pathname.replace(\"/\", \"\")),\n password: decodeURIComponent(url.password),\n port: Number(url.port || 5432),\n ssl: this.ssl(url),\n onnotice: () => {\n // let drizzle handle logs\n },\n };\n\n // Pool options — only set when explicitly configured via env vars\n if (this.pgEnv.POOL_MAX != null) options.max = this.pgEnv.POOL_MAX;\n if (this.pgEnv.POOL_IDLE_TIMEOUT != null)\n options.idle_timeout = this.pgEnv.POOL_IDLE_TIMEOUT;\n if (this.pgEnv.POOL_CONNECT_TIMEOUT != null)\n options.connect_timeout = this.pgEnv.POOL_CONNECT_TIMEOUT;\n\n // Set search_path at connection level so schema-free migration SQL\n // resolves to the correct PostgreSQL schema across all pool connections.\n if (this.schema !== \"public\") {\n options.connection = { search_path: `${this.schema}, public` };\n }\n\n return options;\n }\n\n protected ssl(\n url: URL,\n ): \"require\" | \"allow\" | \"prefer\" | \"verify-full\" | undefined {\n const mode = url.searchParams.get(\"sslmode\");\n for (const it of NodePostgresProvider.SSL_MODES) {\n if (mode === it) {\n return it;\n }\n }\n }\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport type { PGlite } from \"@electric-sql/pglite\";\nimport { $env, $hook, $inject, AlephaError } from \"alepha\";\nimport { DatabaseProvider, databaseEnvSchema, type SQLLike } from \"alepha/orm\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgliteDatabase } from \"drizzle-orm/pglite\";\nimport { migrate } from \"drizzle-orm/pglite/migrator\";\nimport { postgresEnvSchema } from \"../schemas/postgresEnvSchema.ts\";\nimport { PostgresModelBuilder } from \"../services/PostgresModelBuilder.ts\";\n\nexport interface PgLiteModule {\n PGlite: typeof PGlite;\n}\n\nexport class PglitePostgresProvider extends DatabaseProvider {\n public static importPglite(): PgLiteModule | undefined {\n try {\n return createRequire(import.meta.url)(\"@electric-sql/pglite\");\n } catch {\n // ignored\n }\n }\n\n public override get schema(): string {\n return this.pgEnv.POSTGRES_SCHEMA ?? \"public\";\n }\n\n protected readonly env = $env(databaseEnvSchema);\n protected readonly pgEnv = $env(postgresEnvSchema);\n protected readonly builder = $inject(PostgresModelBuilder);\n\n protected client?: PGlite;\n protected pglite?: PgliteDatabase;\n\n public get name() {\n return \"postgres\";\n }\n\n public get driver() {\n return \"pglite\";\n }\n\n public override readonly dialect = \"postgresql\";\n\n public override get supportsTransactions(): boolean {\n return false;\n }\n\n public override get url(): string {\n let path = this.env.DATABASE_URL;\n\n if (!path) {\n if (this.alepha.isTest()) {\n path = \":memory:\"; // use in-memory database for tests by default\n } else {\n path = \"node_modules/.alepha/pglite\"; // default path for dev\n }\n } else {\n if (path.includes(\":memory:\")) {\n // like postgres://:memory: or pglite://:memory:\n path = \":memory:\";\n } else if (path.startsWith(\"file://\")) {\n path = path.replace(\"file://\", \"\");\n }\n }\n\n return path;\n }\n\n public override get db(): PgliteDatabase {\n if (!this.pglite) {\n throw new AlephaError(\"Database not initialized\");\n }\n\n return this.pglite;\n }\n\n public override async execute(\n statement: SQLLike,\n ): Promise<Array<Record<string, unknown>>> {\n const { rows } = await this.db.execute(statement);\n return rows;\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n if (Object.keys(this.kit.getModels(this)).length === 0) {\n return;\n }\n\n const module = PglitePostgresProvider.importPglite();\n if (!module) {\n throw new AlephaError(\n \"@electric-sql/pglite is not installed. Please install it to use the pglite driver.\",\n );\n }\n\n const { drizzle } = createRequire(import.meta.url)(\"drizzle-orm/pglite\");\n const path = this.url;\n\n if (path !== \":memory:\") {\n await mkdir(path, { recursive: true }).catch(() => null);\n this.client = new module.PGlite(path);\n } else {\n this.client = new module.PGlite();\n }\n\n this.pglite = drizzle({\n client: this.client,\n });\n\n await this.migrate();\n\n this.log.info(`Using PGlite database at ${path}`);\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: async () => {\n if (this.client) {\n this.log.debug(\"Closing PGlite connection...\");\n await this.client.close();\n this.client = undefined;\n this.pglite = undefined;\n this.log.info(\"PGlite connection closed\");\n }\n },\n });\n\n protected async executeMigrations(migrationsFolder: string): Promise<void> {\n // Set search_path so schema-free migration SQL resolves to the correct schema.\n // PGlite uses a single connection, so SET persists through the migration.\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n await migrate(this.db, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n }\n}\n","import { $module, type Alepha } from \"alepha\";\nimport { AlephaOrm, DatabaseProvider, databaseEnvSchema } from \"alepha/orm\";\nimport { BunPostgresProvider } from \"./providers/BunPostgresProvider.ts\";\nimport { CloudflareHyperdriveProvider } from \"./providers/CloudflareHyperdriveProvider.ts\";\nimport { NodePostgresProvider } from \"./providers/NodePostgresProvider.ts\";\nimport { PglitePostgresProvider } from \"./providers/PglitePostgresProvider.ts\";\nimport { PostgresProvider } from \"./providers/PostgresProvider.ts\";\nimport { PostgresModelBuilder } from \"./services/PostgresModelBuilder.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./providers/BunPostgresProvider.ts\";\nexport * from \"./providers/CloudflareHyperdriveProvider.ts\";\nexport * from \"./providers/NodePostgresProvider.ts\";\nexport * from \"./providers/PglitePostgresProvider.ts\";\nexport * from \"./providers/PostgresProvider.ts\";\nexport * from \"./schemas/postgresEnvSchema.ts\";\nexport * from \"./services/PostgresModelBuilder.ts\";\nexport * from \"./types/byte.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaOrmPostgres = $module({\n name: \"alepha.orm.postgres\",\n services: [PostgresModelBuilder],\n variants: [\n PostgresProvider,\n CloudflareHyperdriveProvider,\n NodePostgresProvider,\n BunPostgresProvider,\n PglitePostgresProvider,\n ],\n register: (alepha: Alepha) => {\n const env = alepha.parseEnv(databaseEnvSchema);\n\n const url = env.DATABASE_URL;\n const isBun = alepha.isBun();\n\n if (url?.startsWith(\"hyperdrive:\")) {\n alepha.with({\n optional: true,\n provide: DatabaseProvider,\n use: CloudflareHyperdriveProvider,\n });\n } else if (url?.startsWith(\"pglite:\")) {\n alepha.with({\n optional: true,\n provide: DatabaseProvider,\n use: PglitePostgresProvider,\n });\n } else if (url?.startsWith(\"postgres:\")) {\n alepha.with({\n optional: true,\n provide: DatabaseProvider,\n use: isBun ? BunPostgresProvider : NodePostgresProvider,\n });\n }\n\n // Chain core ORM module AFTER substitution so its own SQLite default\n // doesn't preempt our Postgres-specific provider choice.\n alepha.with(AlephaOrm);\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["sql","sql","sql","sql","sql","migrate"],"sources":["../../../src/orm/postgres/schemas/postgresEnvSchema.ts","../../../src/orm/postgres/types/byte.ts","../../../src/orm/postgres/services/PostgresModelBuilder.ts","../../../src/orm/postgres/providers/PostgresProvider.ts","../../../src/orm/postgres/providers/BunPostgresProvider.ts","../../../src/orm/postgres/providers/CloudflareHyperdriveProvider.ts","../../../src/orm/postgres/providers/NodePostgresProvider.ts","../../../src/orm/postgres/providers/PglitePostgresProvider.ts","../../../src/orm/postgres/index.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\n\n/**\n * PostgreSQL-specific environment schema.\n *\n * Additional env vars for PostgreSQL providers on top of `databaseEnvSchema`.\n */\nexport const postgresEnvSchema = t.object({\n /**\n * PostgreSQL schema name (defaults to `\"public\"` when unset).\n */\n POSTGRES_SCHEMA: t.optional(t.text()),\n\n /**\n * Maximum number of connections in the pool.\n */\n POOL_MAX: t.optional(t.integer()),\n\n /**\n * Seconds a connection can be idle before being closed.\n */\n POOL_IDLE_TIMEOUT: t.optional(t.integer()),\n\n /**\n * Seconds to wait when establishing a new connection.\n */\n POOL_CONNECT_TIMEOUT: t.optional(t.integer()),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof postgresEnvSchema>> {}\n}\n","import { customType } from \"drizzle-orm/pg-core\";\n\n/**\n * Postgres bytea type.\n */\nexport const byte = customType<{\n data: Buffer;\n}>({\n dataType: () => \"bytea\",\n});\n","import { AlephaError, type TObject, type TSchema, t } from \"alepha\";\nimport {\n type EntityPrimitive,\n type FromSchema,\n ModelBuilder,\n PG_CREATED_AT,\n PG_GENERATED,\n PG_IDENTITY,\n PG_PRIMARY_KEY,\n PG_REF,\n PG_SERIAL,\n PG_UPDATED_AT,\n type PgGeneratedOptions,\n type PgIdentityOptions,\n type PgRefOptions,\n type SequencePrimitive,\n schema,\n sql,\n} from \"alepha/orm\";\nimport type { BuildExtraConfigColumns } from \"drizzle-orm\";\nimport * as pg from \"drizzle-orm/pg-core\";\nimport {\n check,\n foreignKey,\n index,\n type PgEnum,\n type PgSchema,\n type PgTableExtraConfigValue,\n type PgTableWithColumns,\n pgEnum,\n pgSchema,\n pgSequence,\n pgTable,\n unique,\n uniqueIndex,\n} from \"drizzle-orm/pg-core\";\nimport { byte } from \"../types/byte.ts\";\n\nexport class PostgresModelBuilder extends ModelBuilder {\n protected schemas = new Map<string, PgSchema>();\n\n /**\n * Create a primary key column with UUID v7\n */\n protected getPrimaryKeyUUID(key: string) {\n return pg.uuid(key).default(sql`uuidv7()`);\n }\n\n protected getPgSchema(name: string) {\n if (!this.schemas.has(name) && name !== \"public\") {\n this.schemas.set(name, pgSchema(name));\n }\n\n const nsp =\n name !== \"public\"\n ? this.schemas.get(name)\n : ({\n enum: pgEnum,\n table: pgTable,\n sequence: pgSequence,\n } as any);\n\n if (!nsp) {\n throw new AlephaError(`Postgres schema ${name} not found`);\n }\n\n return nsp;\n }\n\n public buildTable(\n entity: EntityPrimitive<any>,\n options: {\n tables: Map<string, unknown>;\n enums: Map<string, unknown>;\n schemas: Map<string, unknown>;\n schema: string;\n },\n ) {\n const tableName = entity.name;\n if (options.tables.has(tableName)) {\n return;\n }\n\n const nsp = this.getPgSchema(options.schema);\n\n // Register PgSchema so drizzle-kit knows the schema is declared in code.\n // Without this, pushSchema diffs \"schema exists in DB but not in code\" → DROP.\n if (options.schema !== \"public\" && !options.schemas.has(options.schema)) {\n options.schemas.set(options.schema, nsp);\n }\n\n const columns = this.schemaToPgColumns(\n tableName,\n entity.schema,\n nsp,\n options.enums,\n options.tables,\n );\n\n // Build the config function that includes indexes, foreign keys, constraints, and custom config\n const configFn = this.getTableConfig(entity, options.tables);\n\n const table = nsp.table(tableName, columns, configFn);\n\n options.tables.set(tableName, table);\n }\n\n public buildSequence(\n sequence: SequencePrimitive,\n options: {\n sequences: Map<string, unknown>;\n schema: string;\n },\n ) {\n const sequenceName = sequence.name;\n if (options.sequences.has(sequenceName)) {\n return;\n }\n\n const nsp = this.getPgSchema(options.schema);\n\n options.sequences.set(\n sequenceName,\n nsp.sequence(sequenceName, sequence.options),\n );\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Get PostgreSQL-specific config builder for the table.\n */\n protected getTableConfig(\n entity: EntityPrimitive,\n tables: Map<string, unknown>,\n ):\n | ((\n self: BuildExtraConfigColumns<string, any, \"pg\">,\n ) => PgTableExtraConfigValue[])\n | undefined {\n // PostgreSQL-specific builders\n const pgBuilders = {\n index,\n uniqueIndex,\n unique,\n check,\n foreignKey,\n };\n\n // Table resolver function\n const tableResolver = (entityName: string) => {\n return tables.get(entityName) as any;\n };\n\n return this.buildTableConfig<\n PgTableExtraConfigValue,\n BuildExtraConfigColumns<string, any, \"pg\">\n >(entity, pgBuilders as any, tableResolver);\n }\n\n schemaToPgColumns = <T extends TObject>(\n tableName: string,\n schema: T,\n nsp: PgSchema,\n enums: Map<string, unknown>,\n tables: Map<string, unknown>,\n ): FromSchema<T> => {\n return Object.entries(schema.properties).reduce<Partial<FromSchema<T>>>(\n (columns, [key, value]) => {\n let col = this.mapFieldToColumn(tableName, key, value, nsp, enums);\n\n if (\"default\" in value && value.default != null) {\n col = col.default(value.default as any);\n }\n\n if (PG_PRIMARY_KEY in value) {\n col = col.primaryKey();\n }\n\n if (PG_REF in value) {\n const config = value[PG_REF] as PgRefOptions;\n col = col.references(() => {\n const ref = config.ref();\n const table = tables.get(\n ref.entity.name,\n ) as PgTableWithColumns<any>;\n\n if (!table) {\n throw new AlephaError(\n `Referenced table ${ref.entity.name} not found for ${tableName}.${key}`,\n );\n }\n\n const target = table[ref.name];\n if (!target) {\n throw new AlephaError(\n `Referenced column ${ref.name} not found in table ${ref.entity.name} for ${tableName}.${key}`,\n );\n }\n\n return target;\n }, config.actions);\n }\n\n if (PG_GENERATED in value) {\n const gen = value[PG_GENERATED] as PgGeneratedOptions;\n col = col.generatedAlwaysAs(gen.expression);\n }\n\n if (schema.required?.includes(key)) {\n col = col.notNull();\n }\n\n (columns as Record<string, unknown>)[key] = col;\n return columns;\n },\n {},\n ) as FromSchema<T>;\n };\n\n mapFieldToColumn = (\n tableName: string,\n fieldName: string,\n value: TSchema,\n nsp: PgSchema,\n enums: Map<string, any>,\n ) => {\n const key = this.toColumnName(fieldName);\n\n if (\n // is nullish ?\n \"anyOf\" in value &&\n Array.isArray(value.anyOf) &&\n value.anyOf.length === 2 &&\n value.anyOf.some((it: TSchema) => t.schema.isNull(it))\n ) {\n // then, remove nullish\n value = value.anyOf.find((it: TSchema) => !t.schema.isNull(it))!;\n }\n\n if (t.schema.isInteger(value)) {\n if (PG_SERIAL in value) {\n return pg.serial(key);\n }\n\n if (PG_IDENTITY in value) {\n const options = value[PG_IDENTITY] as PgIdentityOptions;\n if (options.mode === \"byDefault\") {\n return pg.integer(key).generatedByDefaultAsIdentity(options);\n }\n return pg.integer(key).generatedAlwaysAsIdentity(options);\n }\n\n return pg.integer(key);\n }\n\n if (t.schema.isBigInt(value)) {\n if (PG_IDENTITY in value) {\n const options = value[PG_IDENTITY] as PgIdentityOptions;\n if (options.mode === \"byDefault\") {\n return pg\n .bigint(key, { mode: \"bigint\" })\n .generatedByDefaultAsIdentity(options);\n }\n return pg\n .bigint(key, { mode: \"bigint\" })\n .generatedAlwaysAsIdentity(options);\n }\n\n return pg.bigint(key, { mode: \"bigint\" });\n }\n\n if (t.schema.isNumber(value)) {\n if (PG_IDENTITY in value) {\n const options = value[PG_IDENTITY] as PgIdentityOptions;\n if (options.mode === \"byDefault\") {\n return pg\n .bigint(key, { mode: \"number\" })\n .generatedByDefaultAsIdentity(options);\n }\n return pg\n .bigint(key, { mode: \"number\" })\n .generatedAlwaysAsIdentity(options);\n }\n\n if (value.format === \"int64\") {\n return pg.bigint(key, { mode: \"number\" });\n }\n\n return pg.numeric(key);\n }\n\n const isTypeEnum = (value: any): value is { enum: any[] } =>\n t.schema.isUnsafe(value) &&\n \"type\" in value &&\n value.type === \"string\" &&\n \"enum\" in value &&\n Array.isArray(value.enum);\n\n if (t.schema.isString(value) && !isTypeEnum(value)) {\n return this.mapStringToColumn(key, value);\n }\n\n if (t.schema.isBoolean(value)) {\n return pg.boolean(key);\n }\n\n if (t.schema.isObject(value)) {\n return schema(key, value);\n }\n\n if (t.schema.isRecord(value)) {\n return schema(key, value);\n }\n\n if (t.schema.isArray(value)) {\n if (t.schema.isObject(value.items)) {\n return schema(key, value);\n }\n if (t.schema.isRecord(value.items)) {\n return schema(key, value);\n }\n if (t.schema.isString(value.items)) {\n return pg.text(key).array();\n }\n if (t.schema.isInteger(value.items)) {\n return pg.integer(key).array();\n }\n if (t.schema.isNumber(value.items)) {\n return pg.numeric(key).array();\n }\n if (t.schema.isBoolean(value.items)) {\n return pg.boolean(key).array();\n }\n if (isTypeEnum(value.items)) {\n return pg.text(key).array();\n }\n }\n\n // Enum handling\n if (isTypeEnum(value)) {\n if (!value.enum.every((it) => typeof it === \"string\")) {\n throw new AlephaError(\n `Enum for ${fieldName} must be an array of strings, got ${JSON.stringify(\n value.enum,\n )}`,\n );\n }\n\n // SQL Enum (default for t.enum unless mode: \"text\")\n if ((value as any).mode !== \"text\") {\n const enumName = (value as any).enumName ?? `${tableName}_${key}_enum`;\n\n if (enums.has(enumName)) {\n const values = (\n enums.get(enumName) as PgEnum<[string]>\n ).enumValues.join(\",\");\n const newValues = value.enum.join(\",\");\n if (values !== newValues) {\n throw new AlephaError(\n `Enum name conflict for ${enumName}: [${values}] vs [${newValues}]`,\n );\n }\n }\n\n enums.set(enumName, nsp.enum(enumName, value.enum as [string]));\n\n return enums.get(enumName)(key);\n }\n\n // else, map to TEXT\n return this.mapStringToColumn(key, value);\n }\n\n throw new AlephaError(\n `Unsupported schema type for ${fieldName} as ${JSON.stringify(value)}`,\n );\n };\n\n /**\n * Map a string to a PG column.\n *\n * @param key The key of the field.\n * @param value The value of the field.\n */\n mapStringToColumn = (key: string, value: TSchema) => {\n if (\"format\" in value) {\n if (value.format === \"uuid\") {\n if (PG_PRIMARY_KEY in value) {\n return this.getPrimaryKeyUUID(key);\n }\n\n return pg.uuid(key);\n }\n\n if (value.format === \"byte\") {\n return byte(key);\n }\n\n if (value.format === \"date-time\") {\n if (PG_CREATED_AT in value) {\n return pg\n .timestamp(key, { mode: \"string\", withTimezone: true })\n .defaultNow();\n }\n if (PG_UPDATED_AT in value) {\n return pg\n .timestamp(key, { mode: \"string\", withTimezone: true })\n .defaultNow();\n }\n return pg.timestamp(key, { mode: \"string\", withTimezone: true });\n }\n\n if (value.format === \"date\") {\n return pg.date(key, { mode: \"string\" });\n }\n }\n\n return pg.text(key);\n };\n}\n","import { $env, $hook, $inject, $pipeline, AlephaError } from \"alepha\";\nimport { $lock } from \"alepha/lock\";\nimport {\n DatabaseProvider,\n DbMigrationError,\n databaseEnvSchema,\n type SQLLike,\n} from \"alepha/orm\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { postgresEnvSchema } from \"../schemas/postgresEnvSchema.ts\";\nimport { PostgresModelBuilder } from \"../services/PostgresModelBuilder.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Abstract base class for PostgreSQL database providers.\n *\n * Provides shared logic for Node.js and Bun PostgreSQL providers:\n * - Environment variable handling (DATABASE_URL, POSTGRES_SCHEMA)\n * - Schema name resolution (with test schema generation)\n * - SQL execution with error wrapping\n * - Lifecycle hooks (start with migration lock, stop with test cleanup)\n *\n * Subclasses must implement `connect()`, `close()`, and `executeMigrations()`.\n */\nexport abstract class PostgresProvider extends DatabaseProvider {\n protected readonly env = $env(databaseEnvSchema);\n protected readonly pgEnv = $env(postgresEnvSchema);\n protected readonly builder = $inject(PostgresModelBuilder);\n\n public override readonly dialect = \"postgresql\";\n\n public get name() {\n return \"postgres\";\n }\n\n /**\n * In testing mode, the schema name will be generated and deleted after the test.\n */\n protected schemaForTesting = this.alepha.isTest()\n ? this.generateTestSchemaName()\n : undefined;\n\n public override get url() {\n if (!this.env.DATABASE_URL) {\n throw new AlephaError(\"DATABASE_URL is not defined in the environment\");\n }\n\n return this.env.DATABASE_URL;\n }\n\n /**\n * Execute a SQL statement.\n */\n public override async execute(\n statement: SQLLike,\n ): Promise<Array<Record<string, unknown>>> {\n return await this.db.execute(statement);\n }\n\n /**\n * Get Postgres schema used by this provider.\n */\n public override get schema(): string {\n if (this.schemaForTesting) {\n return this.schemaForTesting;\n }\n\n if (this.pgEnv.POSTGRES_SCHEMA) {\n return this.pgEnv.POSTGRES_SCHEMA;\n }\n\n return \"public\";\n }\n\n public abstract override get db(): PgDatabase<any>;\n\n /**\n * Establish the database connection.\n */\n public abstract connect(): Promise<void>;\n\n /**\n * Close the database connection.\n */\n public abstract close(): Promise<void>;\n\n // -------------------------------------------------------------------------------------------------------------------\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n await this.connect();\n await this.generateTestSchema();\n\n // never migrate in serverless mode (vercel, netlify, ...)\n if (!this.alepha.isServerless()) {\n try {\n await this.migrateLock.run();\n } catch (error) {\n throw new DbMigrationError(error);\n }\n }\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: async () => {\n await this.dropTestSchema();\n await this.close();\n },\n });\n\n protected migrateLock = $pipeline({\n use: [$lock({ name: \"postgres:migrate\" })],\n handler: async () => {\n await this.migrate();\n },\n });\n\n // -------------------------------------------------------------------------------------------------------------------\n // Create unique schema for tests and clean up after. Format: test_alepha_{epoch_seconds}_{random8}\n // -------------------------------------------------------------------------------------------------------------------\n\n protected async generateTestSchema() {\n if (\n this.alepha.isTest() &&\n this.schemaForTesting?.startsWith(\"test_alepha_\")\n ) {\n // Self-healing: drop stale schemas left behind by crashed/failed test runs\n await this.cleanupStaleTestSchemas();\n\n await this.execute(\n sql`CREATE SCHEMA IF NOT EXISTS ${sql.raw(this.schemaForTesting)}`,\n );\n }\n }\n\n /**\n * Drop the current test schema if applicable.\n */\n protected async dropTestSchema(): Promise<void> {\n if (\n this.alepha.isTest() &&\n this.schemaForTesting?.startsWith(\"test_alepha_\")\n ) {\n this.log.info(`Deleting test schema '${this.schemaForTesting}' ...`);\n await this.execute(\n sql`DROP SCHEMA IF EXISTS ${sql.raw(this.schemaForTesting)} CASCADE`,\n );\n this.log.info(`Test schema '${this.schemaForTesting}' deleted`);\n }\n }\n\n /**\n * Remove stale test schemas older than 1 hour.\n *\n * Parses the embedded epoch from schema names (format: test_alepha_{epoch}_{random8})\n * and drops any that exceed the TTL. This handles schemas left behind by crashed tests,\n * killed processes, or failed startups where stop() never fired.\n *\n * Uses a PG advisory lock so only one concurrent test process performs the cleanup.\n */\n protected async cleanupStaleTestSchemas(): Promise<void> {\n try {\n // Non-blocking advisory lock — first process in cleans, others skip\n const [lock] = await this.execute(\n sql`SELECT pg_try_advisory_lock(hashtext('alepha:test:schema:cleanup')) AS acquired`,\n );\n\n if (!lock?.acquired) {\n return;\n }\n\n try {\n const result = await this.execute(\n sql`SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'test_alepha_%'`,\n );\n\n const now = this.dateTime.nowMillis();\n const maxAge = 60 * 60 * 1000; // 1 hour\n\n for (const row of result) {\n const name = row.schema_name as string;\n\n // Skip our own schema (it was just created or is about to be)\n if (name === this.schemaForTesting) {\n continue;\n }\n\n const age = this.parseTestSchemaAge(name, now);\n if (age !== undefined && age > maxAge) {\n this.log.warn(\n `Dropping stale test schema '${name}' (age: ${Math.round(age / 60_000)}min) ...`,\n );\n await this.execute(\n sql`DROP SCHEMA IF EXISTS ${sql.raw(name)} CASCADE`,\n );\n }\n }\n } finally {\n await this.execute(\n sql`SELECT pg_advisory_unlock(hashtext('alepha:test:schema:cleanup'))`,\n );\n }\n } catch (error) {\n // Don't fail test setup if stale cleanup fails\n this.log.warn(\"Failed to clean up stale test schemas\", { error });\n }\n }\n\n /**\n * Parse the age in milliseconds from a test schema name.\n * Format: test_alepha_{epoch_seconds}_{random8}\n * Returns undefined if the name doesn't match the expected format.\n */\n protected parseTestSchemaAge(name: string, now: number): number | undefined {\n const parts = name.split(\"_\");\n // test_alepha_{epoch}_{random} → [\"test\", \"alepha\", epoch, random]\n if (parts.length !== 4 || parts[0] !== \"test\" || parts[1] !== \"alepha\") {\n return undefined;\n }\n\n const epoch = Number(parts[2]);\n if (!Number.isFinite(epoch) || epoch <= 0) {\n return undefined;\n }\n\n return now - epoch * 1000;\n }\n}\n","import { AlephaError } from \"alepha\";\nimport { sql } from \"drizzle-orm\";\nimport type { BunSQLDatabase } from \"drizzle-orm/bun-sql\";\nimport type { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { PostgresProvider } from \"./PostgresProvider.ts\";\n\n/**\n * Bun PostgreSQL provider using Drizzle ORM with Bun's native SQL client.\n *\n * This provider uses Bun's built-in SQL class for PostgreSQL connections,\n * which provides excellent performance on the Bun runtime.\n *\n * @example\n * ```ts\n * // Set DATABASE_URL environment variable\n * // DATABASE_URL=postgres://user:password@localhost:5432/database\n *\n * // Or configure programmatically\n * alepha.with({\n * provide: DatabaseProvider,\n * use: BunPostgresProvider,\n * });\n * ```\n */\nexport class BunPostgresProvider extends PostgresProvider {\n protected client?: Bun.SQL;\n protected bunDb?: BunSQLDatabase;\n\n /**\n * Get the Drizzle Postgres database instance.\n */\n public override get db(): PgDatabase<any> {\n if (!this.bunDb) {\n throw new AlephaError(\"Database not initialized\");\n }\n\n return this.bunDb as unknown as PgDatabase<any>;\n }\n\n protected override async executeMigrations(\n migrationsFolder: string,\n ): Promise<void> {\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n const { migrate } = await import(\"drizzle-orm/bun-sql/migrator\");\n await migrate(this.bunDb!, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n public async connect(): Promise<void> {\n this.log.debug(\"Connect ..\");\n\n // Check if we're running in Bun\n if (typeof Bun === \"undefined\") {\n throw new AlephaError(\n \"BunPostgresProvider requires the Bun runtime. Use NodePostgresProvider for Node.js.\",\n );\n }\n\n const { drizzle } = await import(\"drizzle-orm/bun-sql\");\n\n // Create Bun SQL client with pool options\n // Set search_path via connection URL so all pool connections use the correct schema\n let connectionUrl = this.url;\n if (this.schema !== \"public\") {\n const separator = connectionUrl.includes(\"?\") ? \"&\" : \"?\";\n connectionUrl += `${separator}search_path=${this.schema},public`;\n }\n const bunOptions: Record<string, any> = { url: connectionUrl };\n if (this.pgEnv.POOL_MAX != null) {\n bunOptions.max = this.pgEnv.POOL_MAX;\n }\n if (this.pgEnv.POOL_IDLE_TIMEOUT != null) {\n bunOptions.idleTimeout = this.pgEnv.POOL_IDLE_TIMEOUT;\n }\n if (this.pgEnv.POOL_CONNECT_TIMEOUT != null) {\n bunOptions.connectionTimeout = this.pgEnv.POOL_CONNECT_TIMEOUT;\n }\n this.client = new Bun.SQL(bunOptions);\n\n // Test connection\n await this.client.unsafe(\"SELECT 1\");\n\n this.bunDb = drizzle({\n client: this.client,\n logger: {\n logQuery: (query: string, params: unknown[]) => {\n this.log.trace(query, { params });\n },\n },\n });\n\n this.log.info(\"Connection OK\");\n }\n\n public async close(): Promise<void> {\n if (this.client) {\n this.log.debug(\"Close...\");\n\n await this.client.close();\n\n this.client = undefined;\n this.bunDb = undefined;\n\n this.log.info(\"Connection closed\");\n }\n }\n}\n","import { $env, $hook, $inject, AlephaError, t } from \"alepha\";\nimport { DatabaseProvider, type SQLLike } from \"alepha/orm\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { PostgresModelBuilder } from \"../services/PostgresModelBuilder.ts\";\n\n/**\n * Cloudflare Hyperdrive PostgreSQL provider using Drizzle ORM.\n *\n * Connects to an external PostgreSQL database through Cloudflare Hyperdrive,\n * which provides connection pooling and caching at the edge.\n *\n * Creates a fresh connection per request, since Cloudflare Workers\n * cannot reuse I/O objects across request contexts.\n *\n * URL format: hyperdrive://BINDING_NAME\n */\nexport class CloudflareHyperdriveProvider extends DatabaseProvider {\n protected readonly builder = $inject(PostgresModelBuilder);\n protected readonly env = $env(\n t.object({\n DATABASE_URL: t.string({\n description: \"Expect to be 'hyperdrive://BINDING'\",\n }),\n POSTGRES_SCHEMA: t.optional(t.text()),\n }),\n );\n\n public override get schema(): string {\n return this.env.POSTGRES_SCHEMA ?? \"public\";\n }\n\n protected postgresFn?: any;\n protected drizzleFn?: any;\n protected bindingName?: string;\n\n public get name() {\n return \"postgres\";\n }\n\n public get driver() {\n return \"hyperdrive\";\n }\n\n public override readonly dialect = \"postgresql\";\n\n public override get url(): string {\n return this.env.DATABASE_URL;\n }\n\n /**\n * Get a fresh Drizzle instance per request.\n *\n * Reads the current Hyperdrive binding from `cloudflare.env`\n * and creates a new postgres client each time, avoiding the\n * \"Cannot perform I/O on behalf of a different request\" error.\n */\n public override get db(): PgDatabase<any> {\n if (!this.postgresFn || !this.drizzleFn || !this.bindingName) {\n throw new AlephaError(\"Hyperdrive database not initialized\");\n }\n\n const cloudflareEnv = this.alepha.get(\"cloudflare.env\") as\n | Record<string, unknown>\n | undefined;\n if (!cloudflareEnv) {\n throw new AlephaError(\n \"Cloudflare Workers environment not found in Alepha store under 'cloudflare.env'.\",\n );\n }\n\n const binding = cloudflareEnv[this.bindingName] as\n | { connectionString: string }\n | undefined;\n if (!binding?.connectionString) {\n throw new AlephaError(\n `Hyperdrive binding '${this.bindingName}' not found in Cloudflare Workers environment.`,\n );\n }\n\n const pgOptions: Record<string, any> = { prepare: false };\n\n // Set search_path so schema-free migration SQL resolves to the correct schema.\n if (this.schema !== \"public\") {\n pgOptions.connection = { search_path: `${this.schema}, public` };\n }\n\n const client = this.postgresFn(binding.connectionString, pgOptions);\n return this.drizzleFn(client as any) as unknown as PgDatabase<any>;\n }\n\n public override async execute(\n query: SQLLike,\n ): Promise<Array<Record<string, unknown>>> {\n return this.db.execute(query);\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n this.bindingName = this.env.DATABASE_URL.replace(\"hyperdrive://\", \"\");\n\n // Pre-load modules so db getter is synchronous\n const pgModule = await import(\"postgres\");\n const drizzleModule = await import(\"drizzle-orm/postgres-js\");\n this.postgresFn = pgModule.default ?? pgModule;\n this.drizzleFn = drizzleModule.drizzle;\n\n this.log.info(\"Using Cloudflare Hyperdrive (PostgreSQL)\");\n },\n });\n\n protected async executeMigrations(migrationsFolder: string): Promise<void> {\n this.log.debug(`Running Postgres migrations from '${migrationsFolder}'...`);\n try {\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n const { migrate } = await import(\"drizzle-orm/postgres-js/migrator\");\n await migrate(this.db as any, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n this.log.debug(\"Postgres migrations completed successfully\");\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? `${error.name}: ${error.message}`\n : String(error);\n throw new AlephaError(\n `Postgres migration failed from '${migrationsFolder}': ${errorMessage}`,\n { cause: error },\n );\n }\n }\n}\n","import { AlephaError } from \"alepha\";\nimport { sql } from \"drizzle-orm\";\nimport type { PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport { drizzle } from \"drizzle-orm/postgres-js\";\nimport { migrate } from \"drizzle-orm/postgres-js/migrator\";\nimport postgres from \"postgres\";\nimport { PostgresProvider } from \"./PostgresProvider.ts\";\n\nexport class NodePostgresProvider extends PostgresProvider {\n static readonly SSL_MODES = [\n \"require\",\n \"allow\",\n \"prefer\",\n \"verify-full\",\n ] as const;\n\n protected client?: postgres.Sql;\n protected pg?: PostgresJsDatabase;\n\n /**\n * Get the Drizzle Postgres database instance.\n */\n public override get db(): PostgresJsDatabase {\n if (!this.pg) {\n throw new AlephaError(\"Database not initialized\");\n }\n\n return this.pg;\n }\n\n protected override async executeMigrations(\n migrationsFolder: string,\n ): Promise<void> {\n // Set search_path so schema-free migration SQL resolves to the correct schema.\n // postgres.js doesn't support the `connection` startup parameter with pooled\n // connections (e.g. Neon), so we SET it explicitly before running migrations.\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n await migrate(this.db, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n public async connect(): Promise<void> {\n const options = this.getClientOptions();\n\n this.log.debug(\"Connect ..\", {\n ...options,\n password: options.password ? \"****\" : undefined, // hide password\n });\n\n const client = postgres(options);\n await client`SELECT 1`; // test connection\n\n this.client = client;\n this.pg = drizzle(client, {\n logger: {\n // forward logs\n logQuery: (query: string, params: unknown[]) => {\n this.log.trace(query, { params });\n },\n },\n });\n\n this.log.info(\"Connection OK\");\n }\n\n public async close(): Promise<void> {\n if (this.client) {\n this.log.debug(\"Close...\");\n\n await this.client.end();\n\n this.client = undefined;\n this.pg = undefined;\n\n this.log.info(\"Connection closed\");\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Map the DATABASE_URL to postgres client options.\n */\n protected getClientOptions(): postgres.Options<any> {\n const url = new URL(this.url);\n\n const options: postgres.Options<any> = {\n host: url.hostname,\n user: decodeURIComponent(url.username),\n database: decodeURIComponent(url.pathname.replace(\"/\", \"\")),\n password: decodeURIComponent(url.password),\n port: Number(url.port || 5432),\n ssl: this.ssl(url),\n onnotice: () => {\n // let drizzle handle logs\n },\n };\n\n // Pool options — only set when explicitly configured via env vars\n if (this.pgEnv.POOL_MAX != null) options.max = this.pgEnv.POOL_MAX;\n if (this.pgEnv.POOL_IDLE_TIMEOUT != null)\n options.idle_timeout = this.pgEnv.POOL_IDLE_TIMEOUT;\n if (this.pgEnv.POOL_CONNECT_TIMEOUT != null)\n options.connect_timeout = this.pgEnv.POOL_CONNECT_TIMEOUT;\n\n // Set search_path at connection level so schema-free migration SQL\n // resolves to the correct PostgreSQL schema across all pool connections.\n if (this.schema !== \"public\") {\n options.connection = { search_path: `${this.schema}, public` };\n }\n\n return options;\n }\n\n protected ssl(\n url: URL,\n ): \"require\" | \"allow\" | \"prefer\" | \"verify-full\" | undefined {\n const mode = url.searchParams.get(\"sslmode\");\n for (const it of NodePostgresProvider.SSL_MODES) {\n if (mode === it) {\n return it;\n }\n }\n }\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport type { PGlite } from \"@electric-sql/pglite\";\nimport { $env, $hook, $inject, AlephaError } from \"alepha\";\nimport { DatabaseProvider, databaseEnvSchema, type SQLLike } from \"alepha/orm\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgliteDatabase } from \"drizzle-orm/pglite\";\nimport { migrate } from \"drizzle-orm/pglite/migrator\";\nimport { postgresEnvSchema } from \"../schemas/postgresEnvSchema.ts\";\nimport { PostgresModelBuilder } from \"../services/PostgresModelBuilder.ts\";\n\nexport interface PgLiteModule {\n PGlite: typeof PGlite;\n}\n\nexport class PglitePostgresProvider extends DatabaseProvider {\n public static importPglite(): PgLiteModule | undefined {\n try {\n return createRequire(import.meta.url)(\"@electric-sql/pglite\");\n } catch {\n // ignored\n }\n }\n\n public override get schema(): string {\n return this.pgEnv.POSTGRES_SCHEMA ?? \"public\";\n }\n\n protected readonly env = $env(databaseEnvSchema);\n protected readonly pgEnv = $env(postgresEnvSchema);\n protected readonly builder = $inject(PostgresModelBuilder);\n\n protected client?: PGlite;\n protected pglite?: PgliteDatabase;\n\n public get name() {\n return \"postgres\";\n }\n\n public get driver() {\n return \"pglite\";\n }\n\n public override readonly dialect = \"postgresql\";\n\n public override get supportsTransactions(): boolean {\n return false;\n }\n\n public override get url(): string {\n let path = this.env.DATABASE_URL;\n\n if (!path) {\n if (this.alepha.isTest()) {\n path = \":memory:\"; // use in-memory database for tests by default\n } else {\n path = \"node_modules/.alepha/pglite\"; // default path for dev\n }\n } else {\n if (path.includes(\":memory:\")) {\n // like postgres://:memory: or pglite://:memory:\n path = \":memory:\";\n } else if (path.startsWith(\"file://\")) {\n path = path.replace(\"file://\", \"\");\n }\n }\n\n return path;\n }\n\n public override get db(): PgliteDatabase {\n if (!this.pglite) {\n throw new AlephaError(\"Database not initialized\");\n }\n\n return this.pglite;\n }\n\n public override async execute(\n statement: SQLLike,\n ): Promise<Array<Record<string, unknown>>> {\n const { rows } = await this.db.execute(statement);\n return rows;\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n if (Object.keys(this.kit.getModels(this)).length === 0) {\n return;\n }\n\n const module = PglitePostgresProvider.importPglite();\n if (!module) {\n throw new AlephaError(\n \"@electric-sql/pglite is not installed. Please install it to use the pglite driver.\",\n );\n }\n\n const { drizzle } = createRequire(import.meta.url)(\"drizzle-orm/pglite\");\n const path = this.url;\n\n if (path !== \":memory:\") {\n await mkdir(path, { recursive: true }).catch(() => null);\n this.client = new module.PGlite(path);\n } else {\n this.client = new module.PGlite();\n }\n\n this.pglite = drizzle({\n client: this.client,\n });\n\n await this.migrate();\n\n this.log.info(`Using PGlite database at ${path}`);\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: async () => {\n if (this.client) {\n this.log.debug(\"Closing PGlite connection...\");\n await this.client.close();\n this.client = undefined;\n this.pglite = undefined;\n this.log.info(\"PGlite connection closed\");\n }\n },\n });\n\n protected async executeMigrations(migrationsFolder: string): Promise<void> {\n // Set search_path so schema-free migration SQL resolves to the correct schema.\n // PGlite uses a single connection, so SET persists through the migration.\n if (this.schema !== \"public\") {\n await this.db.execute(\n sql.raw(`SET search_path TO ${this.schema}, public`),\n );\n }\n await migrate(this.db, {\n migrationsFolder,\n migrationsTable: this.migrationsTable,\n });\n }\n}\n","import { $module, type Alepha } from \"alepha\";\nimport { AlephaOrm, DatabaseProvider, databaseEnvSchema } from \"alepha/orm\";\nimport { BunPostgresProvider } from \"./providers/BunPostgresProvider.ts\";\nimport { CloudflareHyperdriveProvider } from \"./providers/CloudflareHyperdriveProvider.ts\";\nimport { NodePostgresProvider } from \"./providers/NodePostgresProvider.ts\";\nimport { PglitePostgresProvider } from \"./providers/PglitePostgresProvider.ts\";\nimport { PostgresProvider } from \"./providers/PostgresProvider.ts\";\nimport { PostgresModelBuilder } from \"./services/PostgresModelBuilder.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./providers/BunPostgresProvider.ts\";\nexport * from \"./providers/CloudflareHyperdriveProvider.ts\";\nexport * from \"./providers/NodePostgresProvider.ts\";\nexport * from \"./providers/PglitePostgresProvider.ts\";\nexport * from \"./providers/PostgresProvider.ts\";\nexport * from \"./schemas/postgresEnvSchema.ts\";\nexport * from \"./services/PostgresModelBuilder.ts\";\nexport * from \"./types/byte.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaOrmPostgres = $module({\n name: \"alepha.orm.postgres\",\n services: [PostgresModelBuilder],\n variants: [\n PostgresProvider,\n CloudflareHyperdriveProvider,\n NodePostgresProvider,\n BunPostgresProvider,\n PglitePostgresProvider,\n ],\n register: (alepha: Alepha) => {\n const env = alepha.parseEnv(databaseEnvSchema);\n\n const url = env.DATABASE_URL;\n const isBun = alepha.isBun();\n\n if (url?.startsWith(\"hyperdrive:\")) {\n alepha.with({\n optional: true,\n provide: DatabaseProvider,\n use: CloudflareHyperdriveProvider,\n });\n } else if (url?.startsWith(\"pglite:\")) {\n alepha.with({\n optional: true,\n provide: DatabaseProvider,\n use: PglitePostgresProvider,\n });\n } else if (url?.startsWith(\"postgres:\")) {\n alepha.with({\n optional: true,\n provide: DatabaseProvider,\n use: isBun ? BunPostgresProvider : NodePostgresProvider,\n });\n }\n\n // Chain core ORM module AFTER substitution so its own SQLite default\n // doesn't preempt our Postgres-specific provider choice.\n alepha.with(AlephaOrm);\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;AAOA,MAAa,oBAAoB,EAAE,OAAO;;;;CAIxC,iBAAiB,EAAE,SAAS,EAAE,MAAM,CAAC;;;;CAKrC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC;;;;CAKjC,mBAAmB,EAAE,SAAS,EAAE,SAAS,CAAC;;;;CAK1C,sBAAsB,EAAE,SAAS,EAAE,SAAS,CAAC;CAC9C,CAAC;;;;;;ACtBF,MAAa,OAAO,WAEjB,EACD,gBAAgB,SACjB,CAAC;;;AC6BF,IAAa,uBAAb,cAA0C,aAAa;CACrD,0BAAoB,IAAI,KAAuB;;;;CAK/C,kBAA4B,KAAa;AACvC,SAAO,GAAG,KAAK,IAAI,CAAC,QAAQ,GAAG,WAAW;;CAG5C,YAAsB,MAAc;AAClC,MAAI,CAAC,KAAK,QAAQ,IAAI,KAAK,IAAI,SAAS,SACtC,MAAK,QAAQ,IAAI,MAAM,SAAS,KAAK,CAAC;EAGxC,MAAM,MACJ,SAAS,WACL,KAAK,QAAQ,IAAI,KAAK,GACrB;GACC,MAAM;GACN,OAAO;GACP,UAAU;GACX;AAEP,MAAI,CAAC,IACH,OAAM,IAAI,YAAY,mBAAmB,KAAK,YAAY;AAG5D,SAAO;;CAGT,WACE,QACA,SAMA;EACA,MAAM,YAAY,OAAO;AACzB,MAAI,QAAQ,OAAO,IAAI,UAAU,CAC/B;EAGF,MAAM,MAAM,KAAK,YAAY,QAAQ,OAAO;AAI5C,MAAI,QAAQ,WAAW,YAAY,CAAC,QAAQ,QAAQ,IAAI,QAAQ,OAAO,CACrE,SAAQ,QAAQ,IAAI,QAAQ,QAAQ,IAAI;EAG1C,MAAM,UAAU,KAAK,kBACnB,WACA,OAAO,QACP,KACA,QAAQ,OACR,QAAQ,OACT;EAGD,MAAM,WAAW,KAAK,eAAe,QAAQ,QAAQ,OAAO;EAE5D,MAAM,QAAQ,IAAI,MAAM,WAAW,SAAS,SAAS;AAErD,UAAQ,OAAO,IAAI,WAAW,MAAM;;CAGtC,cACE,UACA,SAIA;EACA,MAAM,eAAe,SAAS;AAC9B,MAAI,QAAQ,UAAU,IAAI,aAAa,CACrC;EAGF,MAAM,MAAM,KAAK,YAAY,QAAQ,OAAO;AAE5C,UAAQ,UAAU,IAChB,cACA,IAAI,SAAS,cAAc,SAAS,QAAQ,CAC7C;;;;;CAQH,eACE,QACA,QAKY;EAEZ,MAAM,aAAa;GACjB;GACA;GACA;GACA;GACA;GACD;EAGD,MAAM,iBAAiB,eAAuB;AAC5C,UAAO,OAAO,IAAI,WAAW;;AAG/B,SAAO,KAAK,iBAGV,QAAQ,YAAmB,cAAc;;CAG7C,qBACE,WACA,QACA,KACA,OACA,WACkB;AAClB,SAAO,OAAO,QAAQ,OAAO,WAAW,CAAC,QACtC,SAAS,CAAC,KAAK,WAAW;GACzB,IAAI,MAAM,KAAK,iBAAiB,WAAW,KAAK,OAAO,KAAK,MAAM;AAElE,OAAI,aAAa,SAAS,MAAM,WAAW,KACzC,OAAM,IAAI,QAAQ,MAAM,QAAe;AAGzC,OAAI,kBAAkB,MACpB,OAAM,IAAI,YAAY;AAGxB,OAAI,UAAU,OAAO;IACnB,MAAM,SAAS,MAAM;AACrB,UAAM,IAAI,iBAAiB;KACzB,MAAM,MAAM,OAAO,KAAK;KACxB,MAAM,QAAQ,OAAO,IACnB,IAAI,OAAO,KACZ;AAED,SAAI,CAAC,MACH,OAAM,IAAI,YACR,oBAAoB,IAAI,OAAO,KAAK,iBAAiB,UAAU,GAAG,MACnE;KAGH,MAAM,SAAS,MAAM,IAAI;AACzB,SAAI,CAAC,OACH,OAAM,IAAI,YACR,qBAAqB,IAAI,KAAK,sBAAsB,IAAI,OAAO,KAAK,OAAO,UAAU,GAAG,MACzF;AAGH,YAAO;OACN,OAAO,QAAQ;;AAGpB,OAAI,gBAAgB,OAAO;IACzB,MAAM,MAAM,MAAM;AAClB,UAAM,IAAI,kBAAkB,IAAI,WAAW;;AAG7C,OAAI,OAAO,UAAU,SAAS,IAAI,CAChC,OAAM,IAAI,SAAS;AAGpB,WAAoC,OAAO;AAC5C,UAAO;KAET,EAAE,CACH;;CAGH,oBACE,WACA,WACA,OACA,KACA,UACG;EACH,MAAM,MAAM,KAAK,aAAa,UAAU;AAExC,MAEE,WAAW,SACX,MAAM,QAAQ,MAAM,MAAM,IAC1B,MAAM,MAAM,WAAW,KACvB,MAAM,MAAM,MAAM,OAAgB,EAAE,OAAO,OAAO,GAAG,CAAC,CAGtD,SAAQ,MAAM,MAAM,MAAM,OAAgB,CAAC,EAAE,OAAO,OAAO,GAAG,CAAC;AAGjE,MAAI,EAAE,OAAO,UAAU,MAAM,EAAE;AAC7B,OAAI,aAAa,MACf,QAAO,GAAG,OAAO,IAAI;AAGvB,OAAI,eAAe,OAAO;IACxB,MAAM,UAAU,MAAM;AACtB,QAAI,QAAQ,SAAS,YACnB,QAAO,GAAG,QAAQ,IAAI,CAAC,6BAA6B,QAAQ;AAE9D,WAAO,GAAG,QAAQ,IAAI,CAAC,0BAA0B,QAAQ;;AAG3D,UAAO,GAAG,QAAQ,IAAI;;AAGxB,MAAI,EAAE,OAAO,SAAS,MAAM,EAAE;AAC5B,OAAI,eAAe,OAAO;IACxB,MAAM,UAAU,MAAM;AACtB,QAAI,QAAQ,SAAS,YACnB,QAAO,GACJ,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC,CAC/B,6BAA6B,QAAQ;AAE1C,WAAO,GACJ,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC,CAC/B,0BAA0B,QAAQ;;AAGvC,UAAO,GAAG,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC;;AAG3C,MAAI,EAAE,OAAO,SAAS,MAAM,EAAE;AAC5B,OAAI,eAAe,OAAO;IACxB,MAAM,UAAU,MAAM;AACtB,QAAI,QAAQ,SAAS,YACnB,QAAO,GACJ,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC,CAC/B,6BAA6B,QAAQ;AAE1C,WAAO,GACJ,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC,CAC/B,0BAA0B,QAAQ;;AAGvC,OAAI,MAAM,WAAW,QACnB,QAAO,GAAG,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC;AAG3C,UAAO,GAAG,QAAQ,IAAI;;EAGxB,MAAM,cAAc,UAClB,EAAE,OAAO,SAAS,MAAM,IACxB,UAAU,SACV,MAAM,SAAS,YACf,UAAU,SACV,MAAM,QAAQ,MAAM,KAAK;AAE3B,MAAI,EAAE,OAAO,SAAS,MAAM,IAAI,CAAC,WAAW,MAAM,CAChD,QAAO,KAAK,kBAAkB,KAAK,MAAM;AAG3C,MAAI,EAAE,OAAO,UAAU,MAAM,CAC3B,QAAO,GAAG,QAAQ,IAAI;AAGxB,MAAI,EAAE,OAAO,SAAS,MAAM,CAC1B,QAAO,OAAO,KAAK,MAAM;AAG3B,MAAI,EAAE,OAAO,SAAS,MAAM,CAC1B,QAAO,OAAO,KAAK,MAAM;AAG3B,MAAI,EAAE,OAAO,QAAQ,MAAM,EAAE;AAC3B,OAAI,EAAE,OAAO,SAAS,MAAM,MAAM,CAChC,QAAO,OAAO,KAAK,MAAM;AAE3B,OAAI,EAAE,OAAO,SAAS,MAAM,MAAM,CAChC,QAAO,OAAO,KAAK,MAAM;AAE3B,OAAI,EAAE,OAAO,SAAS,MAAM,MAAM,CAChC,QAAO,GAAG,KAAK,IAAI,CAAC,OAAO;AAE7B,OAAI,EAAE,OAAO,UAAU,MAAM,MAAM,CACjC,QAAO,GAAG,QAAQ,IAAI,CAAC,OAAO;AAEhC,OAAI,EAAE,OAAO,SAAS,MAAM,MAAM,CAChC,QAAO,GAAG,QAAQ,IAAI,CAAC,OAAO;AAEhC,OAAI,EAAE,OAAO,UAAU,MAAM,MAAM,CACjC,QAAO,GAAG,QAAQ,IAAI,CAAC,OAAO;AAEhC,OAAI,WAAW,MAAM,MAAM,CACzB,QAAO,GAAG,KAAK,IAAI,CAAC,OAAO;;AAK/B,MAAI,WAAW,MAAM,EAAE;AACrB,OAAI,CAAC,MAAM,KAAK,OAAO,OAAO,OAAO,OAAO,SAAS,CACnD,OAAM,IAAI,YACR,YAAY,UAAU,oCAAoC,KAAK,UAC7D,MAAM,KACP,GACF;AAIH,OAAK,MAAc,SAAS,QAAQ;IAClC,MAAM,WAAY,MAAc,YAAY,GAAG,UAAU,GAAG,IAAI;AAEhE,QAAI,MAAM,IAAI,SAAS,EAAE;KACvB,MAAM,SACJ,MAAM,IAAI,SAAS,CACnB,WAAW,KAAK,IAAI;KACtB,MAAM,YAAY,MAAM,KAAK,KAAK,IAAI;AACtC,SAAI,WAAW,UACb,OAAM,IAAI,YACR,0BAA0B,SAAS,KAAK,OAAO,QAAQ,UAAU,GAClE;;AAIL,UAAM,IAAI,UAAU,IAAI,KAAK,UAAU,MAAM,KAAiB,CAAC;AAE/D,WAAO,MAAM,IAAI,SAAS,CAAC,IAAI;;AAIjC,UAAO,KAAK,kBAAkB,KAAK,MAAM;;AAG3C,QAAM,IAAI,YACR,+BAA+B,UAAU,MAAM,KAAK,UAAU,MAAM,GACrE;;;;;;;;CASH,qBAAqB,KAAa,UAAmB;AACnD,MAAI,YAAY,OAAO;AACrB,OAAI,MAAM,WAAW,QAAQ;AAC3B,QAAI,kBAAkB,MACpB,QAAO,KAAK,kBAAkB,IAAI;AAGpC,WAAO,GAAG,KAAK,IAAI;;AAGrB,OAAI,MAAM,WAAW,OACnB,QAAO,KAAK,IAAI;AAGlB,OAAI,MAAM,WAAW,aAAa;AAChC,QAAI,iBAAiB,MACnB,QAAO,GACJ,UAAU,KAAK;KAAE,MAAM;KAAU,cAAc;KAAM,CAAC,CACtD,YAAY;AAEjB,QAAI,iBAAiB,MACnB,QAAO,GACJ,UAAU,KAAK;KAAE,MAAM;KAAU,cAAc;KAAM,CAAC,CACtD,YAAY;AAEjB,WAAO,GAAG,UAAU,KAAK;KAAE,MAAM;KAAU,cAAc;KAAM,CAAC;;AAGlE,OAAI,MAAM,WAAW,OACnB,QAAO,GAAG,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;;AAI3C,SAAO,GAAG,KAAK,IAAI;;;;;;;;;;;;;;;;ACxYvB,IAAsB,mBAAtB,cAA+C,iBAAiB;CAC9D,MAAyB,KAAK,kBAAkB;CAChD,QAA2B,KAAK,kBAAkB;CAClD,UAA6B,QAAQ,qBAAqB;CAE1D,UAAmC;CAEnC,IAAW,OAAO;AAChB,SAAO;;;;;CAMT,mBAA6B,KAAK,OAAO,QAAQ,GAC7C,KAAK,wBAAwB,GAC7B,KAAA;CAEJ,IAAoB,MAAM;AACxB,MAAI,CAAC,KAAK,IAAI,aACZ,OAAM,IAAI,YAAY,iDAAiD;AAGzE,SAAO,KAAK,IAAI;;;;;CAMlB,MAAsB,QACpB,WACyC;AACzC,SAAO,MAAM,KAAK,GAAG,QAAQ,UAAU;;;;;CAMzC,IAAoB,SAAiB;AACnC,MAAI,KAAK,iBACP,QAAO,KAAK;AAGd,MAAI,KAAK,MAAM,gBACb,QAAO,KAAK,MAAM;AAGpB,SAAO;;CAiBT,UAA6B,MAAM;EACjC,IAAI;EACJ,SAAS,YAAY;AACnB,SAAM,KAAK,SAAS;AACpB,SAAM,KAAK,oBAAoB;AAG/B,OAAI,CAAC,KAAK,OAAO,cAAc,CAC7B,KAAI;AACF,UAAM,KAAK,YAAY,KAAK;YACrB,OAAO;AACd,UAAM,IAAI,iBAAiB,MAAM;;;EAIxC,CAAC;CAEF,SAA4B,MAAM;EAChC,IAAI;EACJ,SAAS,YAAY;AACnB,SAAM,KAAK,gBAAgB;AAC3B,SAAM,KAAK,OAAO;;EAErB,CAAC;CAEF,cAAwB,UAAU;EAChC,KAAK,CAAC,MAAM,EAAE,MAAM,oBAAoB,CAAC,CAAC;EAC1C,SAAS,YAAY;AACnB,SAAM,KAAK,SAAS;;EAEvB,CAAC;CAMF,MAAgB,qBAAqB;AACnC,MACE,KAAK,OAAO,QAAQ,IACpB,KAAK,kBAAkB,WAAW,eAAe,EACjD;AAEA,SAAM,KAAK,yBAAyB;AAEpC,SAAM,KAAK,QACT,KAAG,+BAA+BA,MAAI,IAAI,KAAK,iBAAiB,GACjE;;;;;;CAOL,MAAgB,iBAAgC;AAC9C,MACE,KAAK,OAAO,QAAQ,IACpB,KAAK,kBAAkB,WAAW,eAAe,EACjD;AACA,QAAK,IAAI,KAAK,yBAAyB,KAAK,iBAAiB,OAAO;AACpE,SAAM,KAAK,QACT,KAAG,yBAAyBA,MAAI,IAAI,KAAK,iBAAiB,CAAC,UAC5D;AACD,QAAK,IAAI,KAAK,gBAAgB,KAAK,iBAAiB,WAAW;;;;;;;;;;;;CAanE,MAAgB,0BAAyC;AACvD,MAAI;GAEF,MAAM,CAAC,QAAQ,MAAM,KAAK,QACxB,KAAG,kFACJ;AAED,OAAI,CAAC,MAAM,SACT;AAGF,OAAI;IACF,MAAM,SAAS,MAAM,KAAK,QACxB,KAAG,6FACJ;IAED,MAAM,MAAM,KAAK,SAAS,WAAW;IACrC,MAAM,SAAS,OAAU;AAEzB,SAAK,MAAM,OAAO,QAAQ;KACxB,MAAM,OAAO,IAAI;AAGjB,SAAI,SAAS,KAAK,iBAChB;KAGF,MAAM,MAAM,KAAK,mBAAmB,MAAM,IAAI;AAC9C,SAAI,QAAQ,KAAA,KAAa,MAAM,QAAQ;AACrC,WAAK,IAAI,KACP,+BAA+B,KAAK,UAAU,KAAK,MAAM,MAAM,IAAO,CAAC,UACxE;AACD,YAAM,KAAK,QACT,KAAG,yBAAyBA,MAAI,IAAI,KAAK,CAAC,UAC3C;;;aAGG;AACR,UAAM,KAAK,QACT,KAAG,oEACJ;;WAEI,OAAO;AAEd,QAAK,IAAI,KAAK,yCAAyC,EAAE,OAAO,CAAC;;;;;;;;CASrE,mBAA6B,MAAc,KAAiC;EAC1E,MAAM,QAAQ,KAAK,MAAM,IAAI;AAE7B,MAAI,MAAM,WAAW,KAAK,MAAM,OAAO,UAAU,MAAM,OAAO,SAC5D;EAGF,MAAM,QAAQ,OAAO,MAAM,GAAG;AAC9B,MAAI,CAAC,OAAO,SAAS,MAAM,IAAI,SAAS,EACtC;AAGF,SAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;AC9MzB,IAAa,sBAAb,cAAyC,iBAAiB;CACxD;CACA;;;;CAKA,IAAoB,KAAsB;AACxC,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,YAAY,2BAA2B;AAGnD,SAAO,KAAK;;CAGd,MAAyB,kBACvB,kBACe;AACf,MAAI,KAAK,WAAW,SAClB,OAAM,KAAK,GAAG,QACZC,MAAI,IAAI,sBAAsB,KAAK,OAAO,UAAU,CACrD;EAEH,MAAM,EAAE,YAAY,MAAM,OAAO;AACjC,QAAM,QAAQ,KAAK,OAAQ;GACzB;GACA,iBAAiB,KAAK;GACvB,CAAC;;CAKJ,MAAa,UAAyB;AACpC,OAAK,IAAI,MAAM,aAAa;AAG5B,MAAI,OAAO,QAAQ,YACjB,OAAM,IAAI,YACR,sFACD;EAGH,MAAM,EAAE,YAAY,MAAM,OAAO;EAIjC,IAAI,gBAAgB,KAAK;AACzB,MAAI,KAAK,WAAW,UAAU;GAC5B,MAAM,YAAY,cAAc,SAAS,IAAI,GAAG,MAAM;AACtD,oBAAiB,GAAG,UAAU,cAAc,KAAK,OAAO;;EAE1D,MAAM,aAAkC,EAAE,KAAK,eAAe;AAC9D,MAAI,KAAK,MAAM,YAAY,KACzB,YAAW,MAAM,KAAK,MAAM;AAE9B,MAAI,KAAK,MAAM,qBAAqB,KAClC,YAAW,cAAc,KAAK,MAAM;AAEtC,MAAI,KAAK,MAAM,wBAAwB,KACrC,YAAW,oBAAoB,KAAK,MAAM;AAE5C,OAAK,SAAS,IAAI,IAAI,IAAI,WAAW;AAGrC,QAAM,KAAK,OAAO,OAAO,WAAW;AAEpC,OAAK,QAAQ,QAAQ;GACnB,QAAQ,KAAK;GACb,QAAQ,EACN,WAAW,OAAe,WAAsB;AAC9C,SAAK,IAAI,MAAM,OAAO,EAAE,QAAQ,CAAC;MAEpC;GACF,CAAC;AAEF,OAAK,IAAI,KAAK,gBAAgB;;CAGhC,MAAa,QAAuB;AAClC,MAAI,KAAK,QAAQ;AACf,QAAK,IAAI,MAAM,WAAW;AAE1B,SAAM,KAAK,OAAO,OAAO;AAEzB,QAAK,SAAS,KAAA;AACd,QAAK,QAAQ,KAAA;AAEb,QAAK,IAAI,KAAK,oBAAoB;;;;;;;;;;;;;;;;;AC9FxC,IAAa,+BAAb,cAAkD,iBAAiB;CACjE,UAA6B,QAAQ,qBAAqB;CAC1D,MAAyB,KACvB,EAAE,OAAO;EACP,cAAc,EAAE,OAAO,EACrB,aAAa,uCACd,CAAC;EACF,iBAAiB,EAAE,SAAS,EAAE,MAAM,CAAC;EACtC,CAAC,CACH;CAED,IAAoB,SAAiB;AACnC,SAAO,KAAK,IAAI,mBAAmB;;CAGrC;CACA;CACA;CAEA,IAAW,OAAO;AAChB,SAAO;;CAGT,IAAW,SAAS;AAClB,SAAO;;CAGT,UAAmC;CAEnC,IAAoB,MAAc;AAChC,SAAO,KAAK,IAAI;;;;;;;;;CAUlB,IAAoB,KAAsB;AACxC,MAAI,CAAC,KAAK,cAAc,CAAC,KAAK,aAAa,CAAC,KAAK,YAC/C,OAAM,IAAI,YAAY,sCAAsC;EAG9D,MAAM,gBAAgB,KAAK,OAAO,IAAI,iBAAiB;AAGvD,MAAI,CAAC,cACH,OAAM,IAAI,YACR,mFACD;EAGH,MAAM,UAAU,cAAc,KAAK;AAGnC,MAAI,CAAC,SAAS,iBACZ,OAAM,IAAI,YACR,uBAAuB,KAAK,YAAY,gDACzC;EAGH,MAAM,YAAiC,EAAE,SAAS,OAAO;AAGzD,MAAI,KAAK,WAAW,SAClB,WAAU,aAAa,EAAE,aAAa,GAAG,KAAK,OAAO,WAAW;EAGlE,MAAM,SAAS,KAAK,WAAW,QAAQ,kBAAkB,UAAU;AACnE,SAAO,KAAK,UAAU,OAAc;;CAGtC,MAAsB,QACpB,OACyC;AACzC,SAAO,KAAK,GAAG,QAAQ,MAAM;;CAG/B,UAA6B,MAAM;EACjC,IAAI;EACJ,SAAS,YAAY;AACnB,QAAK,cAAc,KAAK,IAAI,aAAa,QAAQ,iBAAiB,GAAG;GAGrE,MAAM,WAAW,MAAM,OAAO;GAC9B,MAAM,gBAAgB,MAAM,OAAO;AACnC,QAAK,aAAa,SAAS,WAAW;AACtC,QAAK,YAAY,cAAc;AAE/B,QAAK,IAAI,KAAK,2CAA2C;;EAE5D,CAAC;CAEF,MAAgB,kBAAkB,kBAAyC;AACzE,OAAK,IAAI,MAAM,qCAAqC,iBAAiB,MAAM;AAC3E,MAAI;AACF,OAAI,KAAK,WAAW,SAClB,OAAM,KAAK,GAAG,QACZC,MAAI,IAAI,sBAAsB,KAAK,OAAO,UAAU,CACrD;GAEH,MAAM,EAAE,YAAY,MAAM,OAAO;AACjC,SAAM,QAAQ,KAAK,IAAW;IAC5B;IACA,iBAAiB,KAAK;IACvB,CAAC;AACF,QAAK,IAAI,MAAM,6CAA6C;WACrD,OAAO;AAKd,SAAM,IAAI,YACR,mCAAmC,iBAAiB,KAJpD,iBAAiB,QACb,GAAG,MAAM,KAAK,IAAI,MAAM,YACxB,OAAO,MAAM,IAGjB,EAAE,OAAO,OAAO,CACjB;;;;;;AC9HP,IAAa,uBAAb,MAAa,6BAA6B,iBAAiB;CACzD,OAAgB,YAAY;EAC1B;EACA;EACA;EACA;EACD;CAED;CACA;;;;CAKA,IAAoB,KAAyB;AAC3C,MAAI,CAAC,KAAK,GACR,OAAM,IAAI,YAAY,2BAA2B;AAGnD,SAAO,KAAK;;CAGd,MAAyB,kBACvB,kBACe;AAIf,MAAI,KAAK,WAAW,SAClB,OAAM,KAAK,GAAG,QACZC,MAAI,IAAI,sBAAsB,KAAK,OAAO,UAAU,CACrD;AAEH,QAAM,QAAQ,KAAK,IAAI;GACrB;GACA,iBAAiB,KAAK;GACvB,CAAC;;CAKJ,MAAa,UAAyB;EACpC,MAAM,UAAU,KAAK,kBAAkB;AAEvC,OAAK,IAAI,MAAM,cAAc;GAC3B,GAAG;GACH,UAAU,QAAQ,WAAW,SAAS,KAAA;GACvC,CAAC;EAEF,MAAM,SAAS,SAAS,QAAQ;AAChC,QAAM,MAAM;AAEZ,OAAK,SAAS;AACd,OAAK,KAAK,QAAQ,QAAQ,EACxB,QAAQ,EAEN,WAAW,OAAe,WAAsB;AAC9C,QAAK,IAAI,MAAM,OAAO,EAAE,QAAQ,CAAC;KAEpC,EACF,CAAC;AAEF,OAAK,IAAI,KAAK,gBAAgB;;CAGhC,MAAa,QAAuB;AAClC,MAAI,KAAK,QAAQ;AACf,QAAK,IAAI,MAAM,WAAW;AAE1B,SAAM,KAAK,OAAO,KAAK;AAEvB,QAAK,SAAS,KAAA;AACd,QAAK,KAAK,KAAA;AAEV,QAAK,IAAI,KAAK,oBAAoB;;;;;;CAStC,mBAAoD;EAClD,MAAM,MAAM,IAAI,IAAI,KAAK,IAAI;EAE7B,MAAM,UAAiC;GACrC,MAAM,IAAI;GACV,MAAM,mBAAmB,IAAI,SAAS;GACtC,UAAU,mBAAmB,IAAI,SAAS,QAAQ,KAAK,GAAG,CAAC;GAC3D,UAAU,mBAAmB,IAAI,SAAS;GAC1C,MAAM,OAAO,IAAI,QAAQ,KAAK;GAC9B,KAAK,KAAK,IAAI,IAAI;GAClB,gBAAgB;GAGjB;AAGD,MAAI,KAAK,MAAM,YAAY,KAAM,SAAQ,MAAM,KAAK,MAAM;AAC1D,MAAI,KAAK,MAAM,qBAAqB,KAClC,SAAQ,eAAe,KAAK,MAAM;AACpC,MAAI,KAAK,MAAM,wBAAwB,KACrC,SAAQ,kBAAkB,KAAK,MAAM;AAIvC,MAAI,KAAK,WAAW,SAClB,SAAQ,aAAa,EAAE,aAAa,GAAG,KAAK,OAAO,WAAW;AAGhE,SAAO;;CAGT,IACE,KAC4D;EAC5D,MAAM,OAAO,IAAI,aAAa,IAAI,UAAU;AAC5C,OAAK,MAAM,MAAM,qBAAqB,UACpC,KAAI,SAAS,GACX,QAAO;;;;;ACjHf,IAAa,yBAAb,MAAa,+BAA+B,iBAAiB;CAC3D,OAAc,eAAyC;AACrD,MAAI;AACF,UAAO,cAAc,OAAO,KAAK,IAAI,CAAC,uBAAuB;UACvD;;CAKV,IAAoB,SAAiB;AACnC,SAAO,KAAK,MAAM,mBAAmB;;CAGvC,MAAyB,KAAK,kBAAkB;CAChD,QAA2B,KAAK,kBAAkB;CAClD,UAA6B,QAAQ,qBAAqB;CAE1D;CACA;CAEA,IAAW,OAAO;AAChB,SAAO;;CAGT,IAAW,SAAS;AAClB,SAAO;;CAGT,UAAmC;CAEnC,IAAoB,uBAAgC;AAClD,SAAO;;CAGT,IAAoB,MAAc;EAChC,IAAI,OAAO,KAAK,IAAI;AAEpB,MAAI,CAAC,KACH,KAAI,KAAK,OAAO,QAAQ,CACtB,QAAO;MAEP,QAAO;WAGL,KAAK,SAAS,WAAW,CAE3B,QAAO;WACE,KAAK,WAAW,UAAU,CACnC,QAAO,KAAK,QAAQ,WAAW,GAAG;AAItC,SAAO;;CAGT,IAAoB,KAAqB;AACvC,MAAI,CAAC,KAAK,OACR,OAAM,IAAI,YAAY,2BAA2B;AAGnD,SAAO,KAAK;;CAGd,MAAsB,QACpB,WACyC;EACzC,MAAM,EAAE,SAAS,MAAM,KAAK,GAAG,QAAQ,UAAU;AACjD,SAAO;;CAGT,UAA6B,MAAM;EACjC,IAAI;EACJ,SAAS,YAAY;AACnB,OAAI,OAAO,KAAK,KAAK,IAAI,UAAU,KAAK,CAAC,CAAC,WAAW,EACnD;GAGF,MAAM,SAAS,uBAAuB,cAAc;AACpD,OAAI,CAAC,OACH,OAAM,IAAI,YACR,qFACD;GAGH,MAAM,EAAE,YAAY,cAAc,OAAO,KAAK,IAAI,CAAC,qBAAqB;GACxE,MAAM,OAAO,KAAK;AAElB,OAAI,SAAS,YAAY;AACvB,UAAM,MAAM,MAAM,EAAE,WAAW,MAAM,CAAC,CAAC,YAAY,KAAK;AACxD,SAAK,SAAS,IAAI,OAAO,OAAO,KAAK;SAErC,MAAK,SAAS,IAAI,OAAO,QAAQ;AAGnC,QAAK,SAAS,QAAQ,EACpB,QAAQ,KAAK,QACd,CAAC;AAEF,SAAM,KAAK,SAAS;AAEpB,QAAK,IAAI,KAAK,4BAA4B,OAAO;;EAEpD,CAAC;CAEF,SAA4B,MAAM;EAChC,IAAI;EACJ,SAAS,YAAY;AACnB,OAAI,KAAK,QAAQ;AACf,SAAK,IAAI,MAAM,+BAA+B;AAC9C,UAAM,KAAK,OAAO,OAAO;AACzB,SAAK,SAAS,KAAA;AACd,SAAK,SAAS,KAAA;AACd,SAAK,IAAI,KAAK,2BAA2B;;;EAG9C,CAAC;CAEF,MAAgB,kBAAkB,kBAAyC;AAGzE,MAAI,KAAK,WAAW,SAClB,OAAM,KAAK,GAAG,QACZC,MAAI,IAAI,sBAAsB,KAAK,OAAO,UAAU,CACrD;AAEH,QAAMC,UAAQ,KAAK,IAAI;GACrB;GACA,iBAAiB,KAAK;GACvB,CAAC;;;;;ACzHN,MAAa,oBAAoB,QAAQ;CACvC,MAAM;CACN,UAAU,CAAC,qBAAqB;CAChC,UAAU;EACR;EACA;EACA;EACA;EACA;EACD;CACD,WAAW,WAAmB;EAG5B,MAAM,MAFM,OAAO,SAAS,kBAEb,CAAC;EAChB,MAAM,QAAQ,OAAO,OAAO;AAE5B,MAAI,KAAK,WAAW,cAAc,CAChC,QAAO,KAAK;GACV,UAAU;GACV,SAAS;GACT,KAAK;GACN,CAAC;WACO,KAAK,WAAW,UAAU,CACnC,QAAO,KAAK;GACV,UAAU;GACV,SAAS;GACT,KAAK;GACN,CAAC;WACO,KAAK,WAAW,YAAY,CACrC,QAAO,KAAK;GACV,UAAU;GACV,SAAS;GACT,KAAK,QAAQ,sBAAsB;GACpC,CAAC;AAKJ,SAAO,KAAK,UAAU;;CAEzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/core/components/ClientOnly.tsx","../../../src/react/core/components/ErrorBoundary.tsx","../../../src/react/core/contexts/AlephaContext.ts","../../../src/react/core/contexts/AlephaProvider.tsx","../../../src/react/core/hooks/useAlepha.ts","../../../src/react/core/hooks/useInject.ts","../../../src/react/core/hooks/useAction.ts","../../../src/react/core/hooks/useClient.ts","../../../src/react/core/hooks/useEvents.ts","../../../src/react/core/hooks/useStore.ts","../../../src/react/core/index.ts"],"sourcesContent":["import {\n type PropsWithChildren,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\nexport interface ClientOnlyProps {\n fallback?: ReactNode;\n disabled?: boolean;\n}\n\n/**\n * A small utility component that renders its children only on the client side.\n *\n * Optionally, you can provide a fallback React node that will be rendered.\n *\n * You should use this component when\n * - you have code that relies on browser-specific APIs\n * - you want to avoid server-side rendering for a specific part of your application\n * - you want to prevent pre-rendering of a component\n *\n * @example\n * ```tsx\n * import { ClientOnly } from \"alepha/react\";\n *\n * const MyComponent = () => {\n * // Avoids SSR issues with Date API\n * return (\n * <ClientOnly>\n * {new Date().toLocaleTimeString()}\n * </ClientOnly>\n * );\n * }\n * ```\n */\nconst ClientOnly = (props: PropsWithChildren<ClientOnlyProps>) => {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => setMounted(true), []);\n\n if (props.disabled) {\n return props.children;\n }\n\n return mounted ? props.children : props.fallback;\n};\n\nexport default ClientOnly;\n","import React, {\n type ErrorInfo,\n type PropsWithChildren,\n type ReactNode,\n} from \"react\";\n\n/**\n * Props for the ErrorBoundary component.\n */\nexport interface ErrorBoundaryProps {\n /**\n * Fallback React node to render when an error is caught.\n * If not provided, a default error message will be shown.\n */\n fallback: (error: Error, reset: () => void) => ReactNode;\n\n /**\n * Optional callback that receives the error and error info.\n * Use this to log errors to a monitoring service.\n */\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\n/**\n * State of the ErrorBoundary component.\n */\ninterface ErrorBoundaryState {\n error?: Error;\n}\n\n/**\n * A reusable error boundary for catching rendering errors in any part of the React component tree.\n *\n * It's already included in the Alepha React framework when using page or layout components.\n */\nexport class ErrorBoundary extends React.Component<\n PropsWithChildren<ErrorBoundaryProps>,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {};\n }\n\n /**\n * Update state so the next render shows the fallback UI.\n */\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return {\n error,\n };\n }\n\n /**\n * Lifecycle method called when an error is caught.\n * You can log the error or perform side effects here.\n */\n componentDidCatch(error: Error, info: ErrorInfo): void {\n if (this.props.onError) {\n this.props.onError(error, info);\n }\n }\n\n render(): ReactNode {\n if (this.state.error) {\n const reset = () => {\n this.setState({ error: undefined });\n };\n return this.props.fallback(this.state.error, reset);\n }\n\n return this.props.children;\n }\n}\n\nexport default ErrorBoundary;\n","import type { Alepha } from \"alepha\";\nimport { createContext } from \"react\";\n\n/**\n * React context to provide the Alepha instance throughout the component tree.\n */\nexport const AlephaContext = createContext<Alepha | undefined>(undefined);\n","import { Alepha } from \"alepha\";\nimport { type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { AlephaContext } from \"./AlephaContext.ts\";\n\nexport interface AlephaProviderProps {\n children: ReactNode;\n onError: (error: Error) => ReactNode;\n onLoading: () => ReactNode;\n}\n\n/**\n * AlephaProvider component to initialize and provide Alepha instance to the app.\n *\n * This isn't recommended for apps using `alepha/react/router`, as Router will handle this for you.\n */\nexport const AlephaProvider = (props: AlephaProviderProps) => {\n const alepha = useMemo(() => Alepha.create(), []);\n\n const [started, setStarted] = useState(false);\n const [error, setError] = useState<Error | undefined>();\n\n useEffect(() => {\n alepha\n .start()\n .then(() => setStarted(true))\n .catch((err) => setError(err));\n }, [alepha]);\n\n if (error) {\n return props.onError(error);\n }\n\n if (!started) {\n return props.onLoading();\n }\n\n return (\n <AlephaContext.Provider value={alepha}>\n {props.children}\n </AlephaContext.Provider>\n );\n};\n","import { type Alepha, AlephaError } from \"alepha\";\nimport { useContext } from \"react\";\nimport { AlephaContext } from \"../contexts/AlephaContext.ts\";\n\n/**\n * Main Alepha hook.\n *\n * It provides access to the Alepha instance within a React component.\n *\n * With Alepha, you can access the core functionalities of the framework:\n *\n * - alepha.state() for state management\n * - alepha.inject() for dependency injection\n * - alepha.events.emit() for event handling\n * etc...\n */\nexport const useAlepha = (): Alepha => {\n const alepha = useContext(AlephaContext);\n if (!alepha) {\n throw new AlephaError(\n \"Hook 'useAlepha()' must be used within an AlephaContext.Provider\",\n );\n }\n\n return alepha;\n};\n","import type { Service } from \"alepha\";\nimport { useMemo } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to inject a service instance.\n * It's a wrapper of `useAlepha().inject(service)` with a memoization.\n */\nexport const useInject = <T extends object>(service: Service<T>): T => {\n const alepha = useAlepha();\n return useMemo(() => alepha.inject(service), []);\n};\n","import type { Async } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n type Interval,\n type Timeout,\n} from \"alepha/datetime\";\nimport {\n type DependencyList,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\nimport { useInject } from \"./useInject.ts\";\n\n/**\n * Hook for handling async actions with automatic error handling and event emission.\n *\n * By default, prevents concurrent executions - if an action is running and you call it again,\n * the second call will be ignored. Use `debounce` option to delay execution instead.\n *\n * Emits lifecycle events:\n * - `react:action:begin` - When action starts\n * - `react:action:success` - When action completes successfully\n * - `react:action:error` - When action throws an error\n * - `react:action:end` - Always emitted at the end\n *\n * @example Basic usage\n * ```tsx\n * const action = useAction({\n * handler: async (data) => {\n * await api.save(data);\n * }\n * }, []);\n *\n * <button onClick={() => action.run(data)} disabled={action.loading}>\n * Save\n * </button>\n * ```\n *\n * @example With debounce (search input)\n * ```tsx\n * const search = useAction({\n * handler: async (query: string) => {\n * await api.search(query);\n * },\n * debounce: 300 // Wait 300ms after last call\n * }, []);\n *\n * <input onChange={(e) => search.run(e.target.value)} />\n * ```\n *\n * @example Run on component mount\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => {\n * const data = await api.getData();\n * return data;\n * },\n * runOnInit: true // Runs once when component mounts\n * }, []);\n * ```\n *\n * @example Run periodically (polling)\n * ```tsx\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: 5000 // Run every 5 seconds\n * }, []);\n *\n * // Or with duration tuple\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: [30, 'seconds'] // Run every 30 seconds\n * }, []);\n * ```\n *\n * @example With AbortController\n * ```tsx\n * const fetch = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * // Automatically cancelled on unmount or when new request starts\n * ```\n *\n * @example With error handling\n * ```tsx\n * const deleteAction = useAction({\n * handler: async (id: string) => {\n * await api.delete(id);\n * },\n * onError: (error) => {\n * if (error.code === 'NOT_FOUND') {\n * // Custom error handling\n * }\n * }\n * }, []);\n *\n * {deleteAction.error && <div>Error: {deleteAction.error.message}</div>}\n * ```\n *\n * @example Global error handling\n * ```tsx\n * // In your root app setup\n * alepha.events.on(\"react:action:error\", ({ error }) => {\n * toast.danger(error.message);\n * Sentry.captureException(error);\n * });\n * ```\n */\nexport function useAction<Args extends any[], Result = void>(\n options: UseActionOptions<Args, Result>,\n deps: DependencyList,\n): UseActionReturn<Args, Result> {\n const alepha = useAlepha();\n const dateTimeProvider = useInject(DateTimeProvider);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>();\n const [result, setResult] = useState<Result | undefined>();\n const isExecutingRef = useRef(false);\n const debounceTimerRef = useRef<Timeout | undefined>(undefined);\n const abortControllerRef = useRef<AbortController | undefined>(undefined);\n const isMountedRef = useRef(true);\n const intervalRef = useRef<Interval | undefined>(undefined);\n\n // Track mount state — must set true in body for React StrictMode double-invoke\n useEffect(() => {\n isMountedRef.current = true;\n\n return () => {\n isMountedRef.current = false;\n\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // clear interval\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n };\n }, []);\n\n const executeAction = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n // Prevent concurrent executions\n if (isExecutingRef.current) {\n return;\n }\n\n // Abort previous request if still running\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n // Create new AbortController for this request\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n isExecutingRef.current = true;\n setLoading(true);\n setError(undefined);\n\n try {\n await alepha.events.emit(\"react:action:begin\", {\n type: \"custom\",\n id: options.id,\n });\n // Pass abort signal as last argument to handler\n const result = await options.handler(...args, {\n signal: abortController.signal,\n } as any);\n\n // Only update state if still mounted and not aborted\n if (!isMountedRef.current || abortController.signal.aborted) {\n return;\n }\n\n setResult(result as Result);\n\n await alepha.events.emit(\"react:action:success\", {\n type: \"custom\",\n id: options.id,\n });\n\n if (options.onSuccess) {\n await options.onSuccess(result);\n }\n\n return result;\n } catch (err) {\n // Ignore abort errors\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n // Only update state if still mounted\n if (!isMountedRef.current) {\n return;\n }\n\n const error = err as Error;\n setError(error);\n\n await alepha.events.emit(\"react:action:error\", {\n type: \"custom\",\n id: options.id,\n error,\n });\n\n if (options.onError) {\n await options.onError(error);\n } else {\n // Re-throw if no custom error handler\n throw error;\n }\n } finally {\n isExecutingRef.current = false;\n if (isMountedRef.current) {\n setLoading(false);\n }\n\n await alepha.events.emit(\"react:action:end\", {\n type: \"custom\",\n id: options.id,\n });\n\n // Clean up abort controller\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [...deps, options.id, options.onError, options.onSuccess],\n );\n\n const handler = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n if (options.debounce) {\n // clear existing timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n }\n\n // Set new timer\n return new Promise((resolve) => {\n debounceTimerRef.current = dateTimeProvider.createTimeout(\n async () => {\n const result = await executeAction(...args);\n resolve(result);\n },\n options.debounce ?? 0,\n );\n });\n }\n\n return executeAction(...args);\n },\n [executeAction, options.debounce],\n );\n\n const cancel = useCallback(() => {\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n\n // reset state\n if (isMountedRef.current) {\n isExecutingRef.current = false;\n setLoading(false);\n }\n }, []);\n\n // Run action on mount if runOnInit is true\n useEffect(() => {\n if (options.runOnInit) {\n handler(...([] as any));\n }\n }, deps);\n\n // Run action periodically if runEvery is specified\n useEffect(() => {\n if (!options.runEvery) {\n return;\n }\n\n // Set up interval\n intervalRef.current = dateTimeProvider.createInterval(\n () => handler(...([] as any)),\n options.runEvery,\n true,\n );\n\n // cleanup on unmount or when runEvery changes\n return () => {\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n };\n }, [handler, options.runEvery]);\n\n return {\n run: handler,\n loading,\n error,\n cancel,\n result,\n };\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Context object passed as the last argument to action handlers.\n * Contains an AbortSignal that can be used to cancel the request.\n */\nexport interface ActionContext {\n /**\n * AbortSignal that can be passed to fetch or other async operations.\n * The signal will be aborted when:\n * - The component unmounts\n * - A new action is triggered (cancels previous)\n * - The cancel() method is called\n *\n * @example\n * ```tsx\n * const action = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * ```\n */\n signal: AbortSignal;\n}\n\nexport interface UseActionOptions<Args extends any[] = any[], Result = any> {\n /**\n * The async action handler function.\n * Receives the action arguments plus an ActionContext as the last parameter.\n */\n handler: (...args: [...Args, ActionContext]) => Async<Result>;\n\n /**\n * Custom error handler. If provided, prevents default error re-throw.\n */\n onError?: (error: Error) => void | Promise<void>;\n\n /**\n * Custom success handler.\n */\n onSuccess?: (result: Result) => void | Promise<void>;\n\n /**\n * Optional identifier for this action (useful for debugging/analytics)\n */\n id?: string;\n\n name?: string;\n\n /**\n * Debounce delay in milliseconds. If specified, the action will only execute\n * after the specified delay has passed since the last call. Useful for search inputs\n * or other high-frequency events.\n *\n * @example\n * ```tsx\n * // Execute search 300ms after user stops typing\n * const search = useAction({ handler: search, debounce: 300 }, [])\n * ```\n */\n debounce?: number;\n\n /**\n * If true, the action will be executed once when the component mounts.\n *\n * @example\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => await api.getData(),\n * runOnInit: true\n * }, []);\n * ```\n */\n runOnInit?: boolean;\n\n /**\n * If specified, the action will be executed periodically at the given interval.\n * The interval is specified as a DurationLike value (number in ms, Duration object, or [number, unit] tuple).\n *\n * @example\n * ```tsx\n * // Run every 5 seconds\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: 5000\n * }, []);\n * ```\n *\n * @example\n * ```tsx\n * // Run every 1 minute\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: [1, 'minute']\n * }, []);\n * ```\n */\n runEvery?: DurationLike;\n}\n\nexport interface UseActionReturn<Args extends any[], Result> {\n /**\n * Execute the action with the provided arguments.\n *\n * @example\n * ```tsx\n * const action = useAction({ handler: async (data) => { ... } }, []);\n * action.run(data);\n * ```\n */\n run: (...args: Args) => Promise<Result | undefined>;\n\n /**\n * Loading state - true when action is executing.\n */\n loading: boolean;\n\n /**\n * Error state - contains error if action failed, undefined otherwise.\n */\n error?: Error;\n\n /**\n * Cancel any pending debounced action or abort the current in-flight request.\n *\n * @example\n * ```tsx\n * const action = useAction({ ... }, []);\n *\n * <button onClick={action.cancel} disabled={!action.loading}>\n * Cancel\n * </button>\n * ```\n */\n cancel: () => void;\n\n /**\n * The result data from the last successful action execution.\n */\n result?: Result;\n}\n","import {\n type ClientScope,\n type HttpVirtualClient,\n LinkProvider,\n} from \"alepha/server/links\";\nimport { useMemo } from \"react\";\nimport { useInject } from \"./useInject.ts\";\n\n/**\n * Hook to get a virtual client for the specified scope.\n *\n * It's the React-hook version of `$client()`, from `AlephaServerLinks` module.\n */\nexport const useClient = <T extends object>(\n scope?: ClientScope,\n): HttpVirtualClient<T> => {\n const linkProvider = useInject(LinkProvider);\n\n return useMemo(() => {\n return linkProvider.client<T>(scope);\n }, [scope]);\n};\n","import type { Async, Hook, Hooks } from \"alepha\";\nimport { type DependencyList, useEffect } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Allow subscribing to multiple Alepha events. See {@link Hooks} for available events.\n *\n * useEvents is fully typed to ensure correct event callback signatures.\n *\n * @example\n * ```tsx\n * useEvents(\n * {\n * \"react:transition:begin\": (ev) => {\n * console.log(\"Transition began to:\", ev.to);\n * },\n * \"react:transition:error\": {\n * priority: \"first\",\n * callback: (ev) => {\n * console.error(\"Transition error:\", ev.error);\n * },\n * },\n * },\n * [],\n * );\n * ```\n */\nexport const useEvents = (opts: UseEvents, deps: DependencyList) => {\n const alepha = useAlepha();\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const subs: Function[] = [];\n for (const [name, hook] of Object.entries(opts)) {\n subs.push(alepha.events.on(name as any, hook as any));\n }\n\n return () => {\n for (const clear of subs) {\n clear();\n }\n };\n }, deps);\n};\n\ntype UseEvents = {\n [T in keyof Hooks]?: Hook<T> | ((payload: Hooks[T]) => Async<void>);\n};\n","import type { State, Static, TAtomObject } from \"alepha\";\nimport { Atom } from \"alepha\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to access and mutate the Alepha state.\n */\nfunction useStore<T extends TAtomObject>(\n target: Atom<T>,\n defaultValue?: Static<T>,\n): UseStoreReturn<Static<T>>;\nfunction useStore<Key extends keyof State>(\n target: Key,\n defaultValue?: State[Key],\n): UseStoreReturn<State[Key]>;\nfunction useStore(target: any, defaultValue?: any): any {\n const alepha = useAlepha();\n\n useMemo(() => {\n if (defaultValue != null && alepha.store.get(target) == null) {\n alepha.store.set(target, defaultValue);\n }\n }, [defaultValue]);\n\n const [state, setState] = useState(alepha.store.get(target));\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const key = target instanceof Atom ? target.key : target;\n\n return alepha.events.on(\"state:mutate\", (ev) => {\n if (ev.key === key) {\n setState(ev.value);\n }\n });\n }, []);\n\n return [\n state,\n (value: any) => {\n alepha.store.set(target, value);\n },\n ] as const;\n}\n\nexport type UseStoreReturn<T> = [T, (value: T) => void];\n\nexport { useStore };\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport type * from \"./components/ClientOnly.tsx\";\nexport { default as ClientOnly } from \"./components/ClientOnly.tsx\";\nexport type * from \"./components/ErrorBoundary.tsx\";\nexport { default as ErrorBoundary } from \"./components/ErrorBoundary.tsx\";\nexport * from \"./contexts/AlephaContext.ts\";\nexport * from \"./contexts/AlephaProvider.tsx\";\nexport * from \"./hooks/useAction.ts\";\nexport * from \"./hooks/useAlepha.ts\";\nexport * from \"./hooks/useClient.ts\";\nexport * from \"./hooks/useEvents.ts\";\nexport * from \"./hooks/useInject.ts\";\nexport * from \"./hooks/useStore.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n interface Hooks {\n /**\n * Fires when a user action is starting.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:begin\": {\n type: string;\n id?: string;\n };\n /**\n * Fires when a user action has succeeded.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:success\": {\n type: string;\n id?: string;\n };\n /**\n * Fires when a user action has failed.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:error\": {\n type: string;\n id?: string;\n error: Error;\n };\n /**\n * Fires when a user action has completed, regardless of success or failure.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:end\": {\n type: string;\n id?: string;\n };\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Full-stack React framework with server-side rendering.\n *\n * **Features:**\n * - React page routes with type-safe params\n * - Async action handler with loading/error/cancel states\n * - Type-safe HTTP client access\n * - Dependency injection in components\n * - Global state management\n * - Router navigation methods\n * - Current route state access\n * - Check if path is active\n * - URL query parameters\n * - Access route schema\n * - Subscribe to Alepha events\n * - Type-safe form handling with validation\n * - Error handling wrapper component\n * - Client-side only rendering component\n * - Server-side rendering with hydration\n * - Automatic code splitting\n * - Event system for action tracking\n *\n * @module alepha.react\n */\nexport const AlephaReact = $module({\n name: \"alepha.react.core\",\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/core/components/ClientOnly.tsx","../../../src/react/core/components/ErrorBoundary.tsx","../../../src/react/core/contexts/AlephaContext.ts","../../../src/react/core/contexts/AlephaProvider.tsx","../../../src/react/core/hooks/useAlepha.ts","../../../src/react/core/hooks/useInject.ts","../../../src/react/core/hooks/useAction.ts","../../../src/react/core/hooks/useClient.ts","../../../src/react/core/hooks/useEvents.ts","../../../src/react/core/hooks/useStore.ts","../../../src/react/core/index.ts"],"sourcesContent":["import {\n type PropsWithChildren,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\nexport interface ClientOnlyProps {\n fallback?: ReactNode;\n disabled?: boolean;\n}\n\n/**\n * A small utility component that renders its children only on the client side.\n *\n * Optionally, you can provide a fallback React node that will be rendered.\n *\n * You should use this component when\n * - you have code that relies on browser-specific APIs\n * - you want to avoid server-side rendering for a specific part of your application\n * - you want to prevent pre-rendering of a component\n *\n * @example\n * ```tsx\n * import { ClientOnly } from \"alepha/react\";\n *\n * const MyComponent = () => {\n * // Avoids SSR issues with Date API\n * return (\n * <ClientOnly>\n * {new Date().toLocaleTimeString()}\n * </ClientOnly>\n * );\n * }\n * ```\n */\nconst ClientOnly = (props: PropsWithChildren<ClientOnlyProps>) => {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => setMounted(true), []);\n\n if (props.disabled) {\n return props.children;\n }\n\n return mounted ? props.children : props.fallback;\n};\n\nexport default ClientOnly;\n","import React, {\n type ErrorInfo,\n type PropsWithChildren,\n type ReactNode,\n} from \"react\";\n\n/**\n * Props for the ErrorBoundary component.\n */\nexport interface ErrorBoundaryProps {\n /**\n * Fallback React node to render when an error is caught.\n * If not provided, a default error message will be shown.\n */\n fallback: (error: Error, reset: () => void) => ReactNode;\n\n /**\n * Optional callback that receives the error and error info.\n * Use this to log errors to a monitoring service.\n */\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\n/**\n * State of the ErrorBoundary component.\n */\ninterface ErrorBoundaryState {\n error?: Error;\n}\n\n/**\n * A reusable error boundary for catching rendering errors in any part of the React component tree.\n *\n * It's already included in the Alepha React framework when using page or layout components.\n */\nexport class ErrorBoundary extends React.Component<\n PropsWithChildren<ErrorBoundaryProps>,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {};\n }\n\n /**\n * Update state so the next render shows the fallback UI.\n */\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return {\n error,\n };\n }\n\n /**\n * Lifecycle method called when an error is caught.\n * You can log the error or perform side effects here.\n */\n componentDidCatch(error: Error, info: ErrorInfo): void {\n if (this.props.onError) {\n this.props.onError(error, info);\n }\n }\n\n render(): ReactNode {\n if (this.state.error) {\n const reset = () => {\n this.setState({ error: undefined });\n };\n return this.props.fallback(this.state.error, reset);\n }\n\n return this.props.children;\n }\n}\n\nexport default ErrorBoundary;\n","import type { Alepha } from \"alepha\";\nimport { createContext } from \"react\";\n\n/**\n * React context to provide the Alepha instance throughout the component tree.\n */\nexport const AlephaContext = createContext<Alepha | undefined>(undefined);\n","import { Alepha } from \"alepha\";\nimport { type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { AlephaContext } from \"./AlephaContext.ts\";\n\nexport interface AlephaProviderProps {\n children: ReactNode;\n onError: (error: Error) => ReactNode;\n onLoading: () => ReactNode;\n}\n\n/**\n * AlephaProvider component to initialize and provide Alepha instance to the app.\n *\n * This isn't recommended for apps using `alepha/react/router`, as Router will handle this for you.\n */\nexport const AlephaProvider = (props: AlephaProviderProps) => {\n const alepha = useMemo(() => Alepha.create(), []);\n\n const [started, setStarted] = useState(false);\n const [error, setError] = useState<Error | undefined>();\n\n useEffect(() => {\n alepha\n .start()\n .then(() => setStarted(true))\n .catch((err) => setError(err));\n }, [alepha]);\n\n if (error) {\n return props.onError(error);\n }\n\n if (!started) {\n return props.onLoading();\n }\n\n return (\n <AlephaContext.Provider value={alepha}>\n {props.children}\n </AlephaContext.Provider>\n );\n};\n","import { type Alepha, AlephaError } from \"alepha\";\nimport { useContext } from \"react\";\nimport { AlephaContext } from \"../contexts/AlephaContext.ts\";\n\n/**\n * Main Alepha hook.\n *\n * It provides access to the Alepha instance within a React component.\n *\n * With Alepha, you can access the core functionalities of the framework:\n *\n * - alepha.state() for state management\n * - alepha.inject() for dependency injection\n * - alepha.events.emit() for event handling\n * etc...\n */\nexport const useAlepha = (): Alepha => {\n const alepha = useContext(AlephaContext);\n if (!alepha) {\n throw new AlephaError(\n \"Hook 'useAlepha()' must be used within an AlephaContext.Provider\",\n );\n }\n\n return alepha;\n};\n","import type { Service } from \"alepha\";\nimport { useMemo } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to inject a service instance.\n * It's a wrapper of `useAlepha().inject(service)` with a memoization.\n */\nexport const useInject = <T extends object>(service: Service<T>): T => {\n const alepha = useAlepha();\n return useMemo(() => alepha.inject(service), []);\n};\n","import type { Async } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n type Interval,\n type Timeout,\n} from \"alepha/datetime\";\nimport {\n type DependencyList,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\nimport { useInject } from \"./useInject.ts\";\n\n/**\n * Hook for handling async actions with automatic error handling and event emission.\n *\n * By default, prevents concurrent executions - if an action is running and you call it again,\n * the second call will be ignored. Use `debounce` option to delay execution instead.\n *\n * Emits lifecycle events:\n * - `react:action:begin` - When action starts\n * - `react:action:success` - When action completes successfully\n * - `react:action:error` - When action throws an error\n * - `react:action:end` - Always emitted at the end\n *\n * @example Basic usage\n * ```tsx\n * const action = useAction({\n * handler: async (data) => {\n * await api.save(data);\n * }\n * }, []);\n *\n * <button onClick={() => action.run(data)} disabled={action.loading}>\n * Save\n * </button>\n * ```\n *\n * @example With debounce (search input)\n * ```tsx\n * const search = useAction({\n * handler: async (query: string) => {\n * await api.search(query);\n * },\n * debounce: 300 // Wait 300ms after last call\n * }, []);\n *\n * <input onChange={(e) => search.run(e.target.value)} />\n * ```\n *\n * @example Run on component mount\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => {\n * const data = await api.getData();\n * return data;\n * },\n * runOnInit: true // Runs once when component mounts\n * }, []);\n * ```\n *\n * @example Run periodically (polling)\n * ```tsx\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: 5000 // Run every 5 seconds\n * }, []);\n *\n * // Or with duration tuple\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: [30, 'seconds'] // Run every 30 seconds\n * }, []);\n * ```\n *\n * @example With AbortController\n * ```tsx\n * const fetch = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * // Automatically cancelled on unmount or when new request starts\n * ```\n *\n * @example With error handling\n * ```tsx\n * const deleteAction = useAction({\n * handler: async (id: string) => {\n * await api.delete(id);\n * },\n * onError: (error) => {\n * if (error.code === 'NOT_FOUND') {\n * // Custom error handling\n * }\n * }\n * }, []);\n *\n * {deleteAction.error && <div>Error: {deleteAction.error.message}</div>}\n * ```\n *\n * @example Global error handling\n * ```tsx\n * // In your root app setup\n * alepha.events.on(\"react:action:error\", ({ error }) => {\n * toast.danger(error.message);\n * Sentry.captureException(error);\n * });\n * ```\n */\nexport function useAction<Args extends any[], Result = void>(\n options: UseActionOptions<Args, Result>,\n deps: DependencyList,\n): UseActionReturn<Args, Result> {\n const alepha = useAlepha();\n const dateTimeProvider = useInject(DateTimeProvider);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>();\n const [result, setResult] = useState<Result | undefined>();\n const isExecutingRef = useRef(false);\n const debounceTimerRef = useRef<Timeout | undefined>(undefined);\n const abortControllerRef = useRef<AbortController | undefined>(undefined);\n const isMountedRef = useRef(true);\n const intervalRef = useRef<Interval | undefined>(undefined);\n\n // Track mount state — must set true in body for React StrictMode double-invoke\n useEffect(() => {\n isMountedRef.current = true;\n\n return () => {\n isMountedRef.current = false;\n\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // clear interval\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n };\n }, []);\n\n const executeAction = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n // Prevent concurrent executions\n if (isExecutingRef.current) {\n return;\n }\n\n // Abort previous request if still running\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n // Create new AbortController for this request\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n isExecutingRef.current = true;\n setLoading(true);\n setError(undefined);\n\n try {\n await alepha.events.emit(\"react:action:begin\", {\n type: \"custom\",\n id: options.id,\n });\n // Pass abort signal as last argument to handler\n const result = await options.handler(...args, {\n signal: abortController.signal,\n } as any);\n\n // Only update state if still mounted and not aborted\n if (!isMountedRef.current || abortController.signal.aborted) {\n return;\n }\n\n setResult(result as Result);\n\n await alepha.events.emit(\"react:action:success\", {\n type: \"custom\",\n id: options.id,\n });\n\n if (options.onSuccess) {\n await options.onSuccess(result);\n }\n\n return result;\n } catch (err) {\n // Ignore abort errors\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n // Only update state if still mounted\n if (!isMountedRef.current) {\n return;\n }\n\n const error = err as Error;\n setError(error);\n\n await alepha.events.emit(\"react:action:error\", {\n type: \"custom\",\n id: options.id,\n error,\n });\n\n if (options.onError) {\n await options.onError(error);\n } else {\n // Re-throw if no custom error handler\n throw error;\n }\n } finally {\n isExecutingRef.current = false;\n if (isMountedRef.current) {\n setLoading(false);\n }\n\n await alepha.events.emit(\"react:action:end\", {\n type: \"custom\",\n id: options.id,\n });\n\n // Clean up abort controller\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [...deps, options.id, options.onError, options.onSuccess],\n );\n\n const handler = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n if (options.debounce) {\n // clear existing timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n }\n\n // Set new timer\n return new Promise((resolve) => {\n debounceTimerRef.current = dateTimeProvider.createTimeout(\n async () => {\n const result = await executeAction(...args);\n resolve(result);\n },\n options.debounce ?? 0,\n );\n });\n }\n\n return executeAction(...args);\n },\n [executeAction, options.debounce],\n );\n\n const cancel = useCallback(() => {\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n\n // reset state\n if (isMountedRef.current) {\n isExecutingRef.current = false;\n setLoading(false);\n }\n }, []);\n\n // Run action on mount if runOnInit is true\n useEffect(() => {\n if (options.runOnInit) {\n handler(...([] as any));\n }\n }, deps);\n\n // Run action periodically if runEvery is specified\n useEffect(() => {\n if (!options.runEvery) {\n return;\n }\n\n // Set up interval\n intervalRef.current = dateTimeProvider.createInterval(\n () => handler(...([] as any)),\n options.runEvery,\n true,\n );\n\n // cleanup on unmount or when runEvery changes\n return () => {\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n };\n }, [handler, options.runEvery]);\n\n return {\n run: handler,\n loading,\n error,\n cancel,\n result,\n };\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Context object passed as the last argument to action handlers.\n * Contains an AbortSignal that can be used to cancel the request.\n */\nexport interface ActionContext {\n /**\n * AbortSignal that can be passed to fetch or other async operations.\n * The signal will be aborted when:\n * - The component unmounts\n * - A new action is triggered (cancels previous)\n * - The cancel() method is called\n *\n * @example\n * ```tsx\n * const action = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * ```\n */\n signal: AbortSignal;\n}\n\nexport interface UseActionOptions<Args extends any[] = any[], Result = any> {\n /**\n * The async action handler function.\n * Receives the action arguments plus an ActionContext as the last parameter.\n */\n handler: (...args: [...Args, ActionContext]) => Async<Result>;\n\n /**\n * Custom error handler. If provided, prevents default error re-throw.\n */\n onError?: (error: Error) => void | Promise<void>;\n\n /**\n * Custom success handler.\n */\n onSuccess?: (result: Result) => void | Promise<void>;\n\n /**\n * Optional identifier for this action (useful for debugging/analytics)\n */\n id?: string;\n\n name?: string;\n\n /**\n * Debounce delay in milliseconds. If specified, the action will only execute\n * after the specified delay has passed since the last call. Useful for search inputs\n * or other high-frequency events.\n *\n * @example\n * ```tsx\n * // Execute search 300ms after user stops typing\n * const search = useAction({ handler: search, debounce: 300 }, [])\n * ```\n */\n debounce?: number;\n\n /**\n * If true, the action will be executed once when the component mounts.\n *\n * @example\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => await api.getData(),\n * runOnInit: true\n * }, []);\n * ```\n */\n runOnInit?: boolean;\n\n /**\n * If specified, the action will be executed periodically at the given interval.\n * The interval is specified as a DurationLike value (number in ms, Duration object, or [number, unit] tuple).\n *\n * @example\n * ```tsx\n * // Run every 5 seconds\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: 5000\n * }, []);\n * ```\n *\n * @example\n * ```tsx\n * // Run every 1 minute\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: [1, 'minute']\n * }, []);\n * ```\n */\n runEvery?: DurationLike;\n}\n\nexport interface UseActionReturn<Args extends any[], Result> {\n /**\n * Execute the action with the provided arguments.\n *\n * @example\n * ```tsx\n * const action = useAction({ handler: async (data) => { ... } }, []);\n * action.run(data);\n * ```\n */\n run: (...args: Args) => Promise<Result | undefined>;\n\n /**\n * Loading state - true when action is executing.\n */\n loading: boolean;\n\n /**\n * Error state - contains error if action failed, undefined otherwise.\n */\n error?: Error;\n\n /**\n * Cancel any pending debounced action or abort the current in-flight request.\n *\n * @example\n * ```tsx\n * const action = useAction({ ... }, []);\n *\n * <button onClick={action.cancel} disabled={!action.loading}>\n * Cancel\n * </button>\n * ```\n */\n cancel: () => void;\n\n /**\n * The result data from the last successful action execution.\n */\n result?: Result;\n}\n","import {\n type ClientScope,\n type HttpVirtualClient,\n LinkProvider,\n} from \"alepha/server/links\";\nimport { useMemo } from \"react\";\nimport { useInject } from \"./useInject.ts\";\n\n/**\n * Hook to get a virtual client for the specified scope.\n *\n * It's the React-hook version of `$client()`, from `AlephaServerLinks` module.\n */\nexport const useClient = <T extends object>(\n scope?: ClientScope,\n): HttpVirtualClient<T> => {\n const linkProvider = useInject(LinkProvider);\n\n return useMemo(() => {\n return linkProvider.client<T>(scope);\n }, [scope]);\n};\n","import type { Async, Hook, Hooks } from \"alepha\";\nimport { type DependencyList, useEffect } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Allow subscribing to multiple Alepha events. See {@link Hooks} for available events.\n *\n * useEvents is fully typed to ensure correct event callback signatures.\n *\n * @example\n * ```tsx\n * useEvents(\n * {\n * \"react:transition:begin\": (ev) => {\n * console.log(\"Transition began to:\", ev.to);\n * },\n * \"react:transition:error\": {\n * priority: \"first\",\n * callback: (ev) => {\n * console.error(\"Transition error:\", ev.error);\n * },\n * },\n * },\n * [],\n * );\n * ```\n */\nexport const useEvents = (opts: UseEvents, deps: DependencyList) => {\n const alepha = useAlepha();\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const subs: Function[] = [];\n for (const [name, hook] of Object.entries(opts)) {\n subs.push(alepha.events.on(name as any, hook as any));\n }\n\n return () => {\n for (const clear of subs) {\n clear();\n }\n };\n }, deps);\n};\n\ntype UseEvents = {\n [T in keyof Hooks]?: Hook<T> | ((payload: Hooks[T]) => Async<void>);\n};\n","import type { State, Static, TAtomObject } from \"alepha\";\nimport { Atom } from \"alepha\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to access and mutate the Alepha state.\n */\nfunction useStore<T extends TAtomObject>(\n target: Atom<T>,\n defaultValue?: Static<T>,\n): UseStoreReturn<Static<T>>;\nfunction useStore<Key extends keyof State>(\n target: Key,\n defaultValue?: State[Key],\n): UseStoreReturn<State[Key]>;\nfunction useStore(target: any, defaultValue?: any): any {\n const alepha = useAlepha();\n\n useMemo(() => {\n if (defaultValue != null && alepha.store.get(target) == null) {\n alepha.store.set(target, defaultValue);\n }\n }, [defaultValue]);\n\n const [state, setState] = useState(alepha.store.get(target));\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const key = target instanceof Atom ? target.key : target;\n\n return alepha.events.on(\"state:mutate\", (ev) => {\n if (ev.key === key) {\n setState(ev.value);\n }\n });\n }, []);\n\n return [\n state,\n (value: any) => {\n alepha.store.set(target, value);\n },\n ] as const;\n}\n\nexport type UseStoreReturn<T> = [T, (value: T) => void];\n\nexport { useStore };\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport type * from \"./components/ClientOnly.tsx\";\nexport { default as ClientOnly } from \"./components/ClientOnly.tsx\";\nexport type * from \"./components/ErrorBoundary.tsx\";\nexport { default as ErrorBoundary } from \"./components/ErrorBoundary.tsx\";\nexport * from \"./contexts/AlephaContext.ts\";\nexport * from \"./contexts/AlephaProvider.tsx\";\nexport * from \"./hooks/useAction.ts\";\nexport * from \"./hooks/useAlepha.ts\";\nexport * from \"./hooks/useClient.ts\";\nexport * from \"./hooks/useEvents.ts\";\nexport * from \"./hooks/useInject.ts\";\nexport * from \"./hooks/useStore.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n interface Hooks {\n /**\n * Fires when a user action is starting.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:begin\": {\n type: string;\n id?: string;\n };\n /**\n * Fires when a user action has succeeded.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:success\": {\n type: string;\n id?: string;\n };\n /**\n * Fires when a user action has failed.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:error\": {\n type: string;\n id?: string;\n error: Error;\n };\n /**\n * Fires when a user action has completed, regardless of success or failure.\n * Action can be a form submission, a route transition, or a custom action.\n */\n \"react:action:end\": {\n type: string;\n id?: string;\n };\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Full-stack React framework with server-side rendering.\n *\n * **Features:**\n * - React page routes with type-safe params\n * - Async action handler with loading/error/cancel states\n * - Type-safe HTTP client access\n * - Dependency injection in components\n * - Global state management\n * - Router navigation methods\n * - Current route state access\n * - Check if path is active\n * - URL query parameters\n * - Access route schema\n * - Subscribe to Alepha events\n * - Type-safe form handling with validation\n * - Error handling wrapper component\n * - Client-side only rendering component\n * - Server-side rendering with hydration\n * - Automatic code splitting\n * - Event system for action tracking\n *\n * @module alepha.react\n */\nexport const AlephaReact = $module({\n name: \"alepha.react.core\",\n});\n"],"mappings":"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"}