appos 0.2.4-0 → 0.3.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/event-Su-wo96Y.mjs +2 -0
- package/dist/bin/extract-blob-metadata-CPnQ5z-I.mjs +2 -0
- package/dist/bin/generate-image-variant-0jPXp8Gu.mjs +2 -0
- package/dist/bin/generate-preview-QDAk8NkM.mjs +2 -0
- package/dist/bin/main.mjs +13 -37
- package/dist/bin/{purge-attachment-CMlJMNOk.mjs → purge-attachment-BNMcVoEh.mjs} +1 -1
- package/dist/bin/{purge-audit-logs-hd6q6vnR.mjs → purge-audit-logs-C6bh2l3g.mjs} +1 -1
- package/dist/bin/{purge-unattached-blobs-BYv5b9R9.mjs → purge-unattached-blobs-CmLk3lNK.mjs} +1 -1
- package/dist/bin/{track-db-changes-q0Vl7Htm.mjs → track-db-changes-BUCo-YXD.mjs} +1 -1
- package/dist/bin/workflow-CsbetKWL.mjs +2 -0
- package/dist/exports/api/auth.mjs +1 -1
- package/dist/exports/api/constants.mjs +1 -0
- package/dist/exports/api/database.mjs +1 -1
- package/dist/exports/api/event.mjs +1 -1
- package/dist/exports/api/i18n.mjs +1 -1
- package/dist/exports/api/index.d.mts +2 -2
- package/dist/exports/api/index.mjs +1 -1
- package/dist/exports/api/instrumentation.mjs +1 -0
- package/dist/exports/api/middleware.mjs +1 -1
- package/dist/exports/api/openapi.d.mts +2 -2
- package/dist/exports/api/openapi.mjs +1 -1
- package/dist/exports/api/otel.d.mts +1 -1
- package/dist/exports/api/otel.mjs +1 -1
- package/dist/exports/api/workflow.mjs +1 -1
- package/dist/exports/api/workflows/api/event.mjs +1 -0
- package/dist/exports/api/workflows/{orm.d.mts → api/orm.d.mts} +1 -1
- package/dist/exports/api/workflows/{storage.d.mts → api/storage.d.mts} +1 -1
- package/dist/exports/api/workflows/api/workflow.mjs +1 -0
- package/dist/exports/api/workflows/constants.mjs +1 -0
- package/dist/exports/api/workflows/extract-blob-metadata.mjs +1 -1
- package/dist/exports/api/workflows/generate-image-variant.d.mts +2 -2
- package/dist/exports/api/workflows/generate-image-variant.mjs +1 -1
- package/dist/exports/api/workflows/generate-preview.mjs +1 -1
- package/dist/exports/api/workflows/purge-attachment.mjs +1 -1
- package/dist/exports/api/workflows/purge-audit-logs.mjs +1 -1
- package/dist/exports/api/workflows/purge-unattached-blobs.mjs +1 -1
- package/dist/exports/api/workflows/track-db-changes.d.mts +2 -2
- package/dist/exports/api/workflows/track-db-changes.mjs +1 -1
- package/dist/exports/cli/api/event.mjs +1 -1
- package/dist/exports/cli/api/workflow.mjs +1 -1
- package/dist/exports/cli/api/workflows/extract-blob-metadata.mjs +1 -1
- package/dist/exports/cli/api/workflows/generate-image-variant.mjs +1 -1
- package/dist/exports/cli/api/workflows/generate-preview.mjs +1 -1
- package/dist/exports/cli/constants.mjs +1 -0
- package/dist/exports/tests/api/app-context.mjs +1 -0
- package/dist/exports/tests/api/event.mjs +1 -0
- package/dist/exports/tests/{packages/appos/src/api → api}/index.d.mts +2 -2
- package/dist/exports/tests/api/middleware.mjs +1 -0
- package/dist/exports/tests/{packages/appos/src/api → api}/openapi.d.mts +2 -2
- package/dist/exports/tests/api/openapi.mjs +1 -0
- package/dist/exports/tests/{packages/appos/src/api → api}/orm.d.mts +1 -1
- package/dist/exports/tests/api/server.mjs +1 -0
- package/dist/exports/tests/api/workflow.mjs +1 -0
- package/dist/exports/tests/api/workflows/extract-blob-metadata.mjs +1 -0
- package/dist/exports/tests/api/workflows/generate-image-variant.mjs +1 -0
- package/dist/exports/tests/api/workflows/generate-preview.mjs +1 -0
- package/dist/exports/tests/api.d.mts +3 -3
- package/dist/exports/tests/api.mjs +1 -1
- package/dist/exports/tests/constants.mjs +1 -0
- package/dist/exports/tests/instrumentation.mjs +1 -0
- package/package.json +8 -10
- package/dist/bin/event-v2sCJkNd.mjs +0 -2
- package/dist/bin/extract-blob-metadata-TqNd9w-6.mjs +0 -2
- package/dist/bin/generate-image-variant-D8H9FxgD.mjs +0 -2
- package/dist/bin/generate-preview-5jLZLX6I.mjs +0 -2
- package/dist/bin/workflow-BagSlsMp.mjs +0 -2
- package/dist/exports/api/node_modules/.bun/change-case@5.4.4/node_modules/change-case/dist/index.mjs +0 -1
- package/dist/exports/api/packages/appos/src/constants.mjs +0 -1
- package/dist/exports/api/packages/appos/src/instrumentation.mjs +0 -1
- package/dist/exports/api/workflows/event.mjs +0 -1
- package/dist/exports/api/workflows/workflow.mjs +0 -1
- package/dist/exports/tests/node_modules/.bun/change-case@5.4.4/node_modules/change-case/dist/index.mjs +0 -1
- package/dist/exports/tests/node_modules/.bun/rate-limit-redis@4.3.1_f1fa5524233c9c60/node_modules/rate-limit-redis/dist/index.mjs +0 -25
- package/dist/exports/tests/packages/appos/src/api/event.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/api/middleware.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/api/server.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/api/workflow.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/api/workflows/extract-blob-metadata.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/api/workflows/generate-image-variant.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/api/workflows/generate-preview.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/constants.mjs +0 -1
- package/dist/exports/tests/packages/appos/src/instrumentation.mjs +0 -1
- /package/dist/exports/api/{packages/appos/src/instrumentation.d.mts → instrumentation.d.mts} +0 -0
- /package/dist/exports/api/{packages/appos/src/web → web}/auth.mjs +0 -0
- /package/dist/exports/api/workflows/{auth-schema.mjs → api/auth-schema.mjs} +0 -0
- /package/dist/exports/api/workflows/{auth.d.mts → api/auth.d.mts} +0 -0
- /package/dist/exports/api/workflows/{cache.d.mts → api/cache.d.mts} +0 -0
- /package/dist/exports/api/workflows/{config.d.mts → api/config.d.mts} +0 -0
- /package/dist/exports/api/workflows/{container.d.mts → api/container.d.mts} +0 -0
- /package/dist/exports/api/workflows/{database.d.mts → api/database.d.mts} +0 -0
- /package/dist/exports/api/workflows/{event.d.mts → api/event.d.mts} +0 -0
- /package/dist/exports/api/workflows/{logger.d.mts → api/logger.d.mts} +0 -0
- /package/dist/exports/api/workflows/{mailer.d.mts → api/mailer.d.mts} +0 -0
- /package/dist/exports/api/workflows/{redis.mjs → api/redis.mjs} +0 -0
- /package/dist/exports/api/workflows/{storage-schema.d.mts → api/storage-schema.d.mts} +0 -0
- /package/dist/exports/api/workflows/{workflow.d.mts → api/workflow.d.mts} +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/app-context.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/auth-schema.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/auth-schema.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/auth.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/cache.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/config.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/container.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/database.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/database.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/event.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/i18n.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/logger.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/mailer.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/error-handler.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/health.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/i18n.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/request-logger.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/request-logger.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/shutdown.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/timeout.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware/youch-handler.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/middleware.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/otel.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/redis.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/redis.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/storage-schema.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/storage.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/workflow.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/workflows/generate-image-variant.d.mts +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/workflows/purge-attachment.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/workflows/purge-audit-logs.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/workflows/purge-unattached-blobs.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/api → api}/workflows/track-db-changes.mjs +0 -0
- /package/dist/exports/tests/{packages/appos/src/instrumentation.d.mts → instrumentation.d.mts} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node --import=appos/instrumentation --no-warnings
|
|
2
|
-
import{n as e}from"./workflow-
|
|
2
|
+
import{n as e}from"./workflow-CsbetKWL.mjs";import t from"zod";const n=e({input:t.object({attachmentIds:t.array(t.string()).min(1)}),async run({container:e,input:{attachmentIds:t},step:n}){let r=await n(`fetch-attachments`,async()=>(await e.storage.primary.getAttachmentsByIds(t)).filter(e=>e.blob!==null).map(e=>({attachmentId:e.id,blobId:e.blob.id})));return await n(`delete-attachments`,async()=>{for(let{attachmentId:t}of r)await e.storage.primary.deleteAttachment(t)}),await n(`delete-blobs`,async()=>{for(let{blobId:t}of r)await e.storage.primary.deleteBlob(t)}),e.logger.info({attachmentIds:t,blobCount:r.length},`Attachments and blobs purged`),{purgedCount:r.length}}});export{n as purgeAttachment};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node --import=appos/instrumentation --no-warnings
|
|
2
|
-
import{t as e}from"./workflow-
|
|
2
|
+
import{t as e}from"./workflow-CsbetKWL.mjs";import{t}from"./auth-schema-7KeUwlcd.mjs";import{lt as n}from"drizzle-orm";const r=t();function i(t=`0 0 * * *`){return e({crontab:t,async run({container:e,step:t,scheduledTime:i}){let a=e.auth.auditLog?.retentionDays??90,o=new Date(i);o.setDate(o.getDate()-a);let s=o.toISOString(),c=await t(`delete-old-logs`,async()=>{let{auditLogs:t}=r.tables;return(await e.db.primary.delete(t).where(n(t.createdAt,s)).returning({id:t.id})).length});e.logger.info({deletedCount:c,retentionDays:a,cutoffDate:s},`Audit log purge completed`)}})}export{i as definePurgeAuditLogs};
|
package/dist/bin/{purge-unattached-blobs-BYv5b9R9.mjs → purge-unattached-blobs-CmLk3lNK.mjs}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node --import=appos/instrumentation --no-warnings
|
|
2
|
-
import{t as e}from"./workflow-
|
|
2
|
+
import{t as e}from"./workflow-CsbetKWL.mjs";function t(t=`0 0 * * *`){return e({crontab:t,async run({container:e,step:t}){let n=new Date(Date.now()-2880*60*1e3).toISOString(),r=await t(`fetch-unattached-blobs`,async()=>e.storage.primary.getUnattachedBlobs({olderThan:n})),i=await t(`fetch-pending-blobs`,async()=>e.storage.primary.getPendingBlobs(n)),a=[...r,...i],o=0;for(let n of a)await t(`delete-blob`,async()=>{await e.storage.primary.deleteBlob(n.id),o++});e.logger.info({purgedCount:o,unattachedCount:r.length,pendingCount:i.length},`Orphaned blobs purged`)}})}export{t as definePurgeUnattachedBlobs};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node --import=appos/instrumentation --no-warnings
|
|
2
|
-
import{t as e}from"./event-
|
|
2
|
+
import{t as e}from"./event-Su-wo96Y.mjs";import{n as t}from"./workflow-CsbetKWL.mjs";import{t as n}from"./auth-schema-7KeUwlcd.mjs";import{z as r}from"zod";const i=n(),a=r.object({changes:r.array(r.object({_table:r.string(),old:r.record(r.string(),r.unknown()).nullable(),new:r.record(r.string(),r.unknown()).nullable()})),dbName:r.string(),organizationId:r.string().nullable(),requestId:r.string(),sessionId:r.string().nullable(),userId:r.string().nullable()});function o(e){return e.old===null?`INSERT`:e.new===null?`DELETE`:`UPDATE`}const s=t({input:a,async run({container:t,step:n,input:r}){let{dbName:a,changes:s,organizationId:c,userId:l,sessionId:u,requestId:d}=r;if(s.length===0)return{processed:0,audited:0,published:0};let f=new Date().toISOString(),p=0,m=0;for(let r of s){let s=r._table,h=o(r),g=`${a}.${s}`;t.auth.shouldAudit(g)&&(await n(`audit:${g}`,async()=>{await t.db.primary.insert(i.tables.auditLogs).values({tableName:g,action:h,oldData:r.old,newData:r.new,organizationId:c,userId:l,sessionId:u,requestId:d,createdAt:f})}),p++),await n(`event:${g}`,async()=>{await e.emit({action:h,oldData:r.old,newData:r.new,organizationId:c,tableName:g,timestamp:f,userId:l})}),m++}return{processed:s.length,audited:p,published:m}}});export{s as trackDbChanges};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node --import=appos/instrumentation --no-warnings
|
|
2
|
+
import{basename as e,join as t}from"node:path";import{glob as n}from"node:fs/promises";import{camelCase as r}from"es-toolkit";const i=`api`,a=`databases`,o=`routes`,s=`events`,c=`commands`,l=`public`,u=process.env.NODE_ENV===`production`?`js`:`ts`;function d(e){let t=null,n=null,r=null,i=null,a=async i=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let a=r,o=a.workflowID;if(!o)throw Error(`DBOS.workflowID is not available in this context`);let s={container:t,workflowId:o,input:i,step:(e,t)=>a.runStep(t,{name:e})};return e.run(s)};return{inputSchema:e.input,get name(){return n},register(o,s,c){t=o,n=s,r=c,i=c.registerWorkflow(a,{name:s,...e.config})},async start(t){if(!i||!n||!r)throw Error(`Workflow not registered. Ensure the worker is started before triggering workflows.`);let a=e.input.parse(t),o=await r.startWorkflow(i)(a);return{workflowId:o.workflowID,getStatus:()=>o.getStatus(),getResult:()=>o.getResult()}}}}function f(e){let t=null,n=null,r=null,i=async(i,a)=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let o=r,s=o.workflowID;if(!s)throw Error(`DBOS.workflowID is not available in this context`);let c={container:t,workflowId:s,scheduledTime:i,step:(e,t)=>o.runStep(t,{name:e})};return e.run(c)};return{crontab:e.crontab,get name(){return n},register(a,o,s){t=a,n=o,r=s,s.registerScheduled(s.registerWorkflow(i,{name:o}),{crontab:e.crontab})}}}function p(t){return r(e(t,`.ts`))}async function m(e){let{container:r,dbos:i}=e,a=e.workflowsDir??t(process.cwd(),`api`,`workflows`),o=(e,t)=>{try{e.register(r,t,i)}catch(e){if(!(e instanceof Error)||!e.message.includes(`already registered`))throw e}},{extractBlobMetadata:s}=await import(`./extract-blob-metadata-CPnQ5z-I.mjs`),{generateImageVariant:c}=await import(`./generate-image-variant-0jPXp8Gu.mjs`),{generatePreview:l}=await import(`./generate-preview-QDAk8NkM.mjs`),{purgeAttachment:d}=await import(`./purge-attachment-BNMcVoEh.mjs`),{trackDbChanges:f}=await import(`./track-db-changes-BUCo-YXD.mjs`),{definePurgeAuditLogs:m}=await import(`./purge-audit-logs-C6bh2l3g.mjs`),{definePurgeUnattachedBlobs:h}=await import(`./purge-unattached-blobs-CmLk3lNK.mjs`);o(s,`extractBlobMetadata`),o(c,`generateImageVariant`),o(l,`generatePreview`),o(d,`purgeAttachment`),o(f,`trackDbChanges`),o(m(r.auth.auditLog?.purgeCron),`purgeAuditLogs`),o(h(r.storage.primary.purgeCron),`purgeUnattachedBlobs`);let g=await Array.fromAsync(n(`${a}/**/*.${u}`,{exclude:[`**/*.test.ts`,`**/*.spec.ts`,`**/*.test.js`,`**/*.spec.js`]}));for(let e of g){let t=await import(e);if(t.default&&typeof t.default==`object`&&`register`in t.default){let n=p(e);o(t.default,n)}}}export{c as a,u as c,i,l,d as n,a as o,m as r,s,f as t,o as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AUTH_BASE_PATH as e,AUTH_BASE_URL as t}from"./
|
|
1
|
+
import{AUTH_BASE_PATH as e,AUTH_BASE_URL as t}from"./web/auth.mjs";import{passkey as n}from"@better-auth/passkey";import{sso as r}from"@better-auth/sso";import{betterAuth as i}from"better-auth";import{drizzleAdapter as a}from"better-auth/adapters/drizzle";import{admin as o,anonymous as s,apiKey as c,emailOTP as l,magicLink as u,multiSession as d,phoneNumber as f,twoFactor as p,username as m}from"better-auth/plugins";import{createAccessControl as h}from"better-auth/plugins/access";import{z as g}from"zod";const _=g.enum([`DELETE`,`LOGIN`,`LOGOUT`,`INSERT`,`PASSWORD_CHANGE`,`TRUNCATE`,`UPDATE`]);function v(h){let{auditLog:g,config:_,appName:v,database:y,hooks:b,oauth:x,session:S,passkey:C}=h,w=[];_.plugins?.admin&&w.push(o({defaultRole:_.plugins.admin.defaultRole,adminRoles:_.plugins.admin.adminRoles})),_.plugins?.apiKey&&w.push(c({defaultPrefix:_.plugins.apiKey.defaultPrefix,defaultKeyLength:_.plugins.apiKey.defaultKeyLength,rateLimit:_.plugins.apiKey.rateLimit?{enabled:!0,maxRequests:_.plugins.apiKey.rateLimit.maxRequests,timeWindow:_.plugins.apiKey.rateLimit.timeWindow}:void 0})),_.plugins?.twoFactor&&w.push(p({issuer:_.plugins.twoFactor.issuer??v,totpOptions:_.plugins.twoFactor.totp?{digits:_.plugins.twoFactor.totp.digits,period:_.plugins.twoFactor.totp.period}:void 0,backupCodeOptions:_.plugins.twoFactor.backupCodes?{amount:_.plugins.twoFactor.backupCodes.amount,length:_.plugins.twoFactor.backupCodes.length}:void 0,otpOptions:_.plugins.twoFactor.otp&&b.send2FAOTP?{sendOTP:async({user:e,otp:t})=>b.send2FAOTP({email:e.email,otp:t})}:void 0})),_.methods?.passkey&&C&&w.push(n({rpName:v,rpID:C.rpID,origin:C.origin})),_.methods?.magicLink&&b.sendMagicLink&&w.push(u({expiresIn:_.methods.magicLink.expiresIn,sendMagicLink:async({email:e,url:t,token:n})=>{await b.sendMagicLink({email:e,url:t,token:n})}})),_.methods?.phoneOtp&&b.sendPhoneOTP&&w.push(f({otpLength:_.methods.phoneOtp.otpLength,expiresIn:_.methods.phoneOtp.expiresIn,sendOTP:async({phoneNumber:e,code:t})=>{await b.sendPhoneOTP({phoneNumber:e,otp:t})}})),_.methods?.emailOtp&&b.sendEmailOTP&&w.push(l({otpLength:_.methods.emailOtp.otpLength,expiresIn:_.methods.emailOtp.expiresIn,sendVerificationOTP:async({email:e,otp:t})=>{await b.sendEmailOTP({email:e,otp:t})}})),_.plugins?.username&&w.push(m({minUsernameLength:_.plugins.username.minUsernameLength,maxUsernameLength:_.plugins.username.maxUsernameLength})),_.plugins?.anonymous&&w.push(s({emailDomainName:_.plugins.anonymous.emailDomainName})),_.plugins?.multiSession&&w.push(d({maximumSessions:_.plugins.multiSession.maximumSessions})),_.plugins?.sso&&w.push(r({providersLimit:_.plugins.sso.providersLimit,trustEmailVerified:_.plugins.sso.trustEmailVerified,domainVerification:_.plugins.sso.domainVerification?{enabled:!0}:void 0}));let T={};_.oauth?.google&&(T.google={clientId:x?.google?.clientId??process.env.GOOGLE_CLIENT_ID??``,clientSecret:x?.google?.clientSecret??process.env.GOOGLE_CLIENT_SECRET??``}),_.oauth?.github&&(T.github={clientId:x?.github?.clientId??process.env.GITHUB_CLIENT_ID??``,clientSecret:x?.github?.clientSecret??process.env.GITHUB_CLIENT_SECRET??``}),_.oauth?.apple&&(T.apple={clientId:x?.apple?.clientId??process.env.APPLE_CLIENT_ID??``,clientSecret:x?.apple?.clientSecret??process.env.APPLE_CLIENT_SECRET??``}),_.oauth?.facebook&&(T.facebook={clientId:x?.facebook?.clientId??process.env.FACEBOOK_CLIENT_ID??``,clientSecret:x?.facebook?.clientSecret??process.env.FACEBOOK_CLIENT_SECRET??``});let E=_.basePath??e,D=_.baseURL??t,O=i({account:{accountLinking:{enabled:!0,trustedProviders:[`email-password`,`google`]}},advanced:{cookiePrefix:v.replace(/\s+/g,`_`).toLowerCase(),database:{generateId:!1},ipAddress:{disableIpTracking:!1,ipAddressHeaders:[`cf-connecting-ip`,`x-client-ip`,`x-forwarded-for`,`x-real-ip`]}},appName:v,baseURL:D||void 0,basePath:E,database:a(y,{provider:`pg`,usePlural:!0}),emailAndPassword:_.methods?.emailPassword?{enabled:!0,requireEmailVerification:_.methods.emailPassword.requireEmailVerification,minPasswordLength:_.methods.emailPassword.minPasswordLength,maxPasswordLength:_.methods.emailPassword.maxPasswordLength,sendVerificationEmail:b.sendVerificationEmail?async({user:e,url:t,token:n})=>b.sendVerificationEmail({email:e.email,url:t,token:n}):void 0,sendResetPassword:b.sendResetPasswordEmail?async({user:e,url:t,token:n})=>b.sendResetPasswordEmail({email:e.email,url:t,token:n}):void 0}:{enabled:!1},plugins:w,socialProviders:Object.keys(T).length>0?T:void 0,session:S?{expiresIn:S.expiresIn,updateAge:S.updateAge,freshAge:S.freshAge}:void 0}),k=new Set(g?.excludeTables??[]);return Object.assign(O,{auditLog:g,shouldAudit(e){return!k.has(e)}})}export{_ as auditActionSchema,h as createAccessControl,v as defineAuth};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=`api`,t=`databases`,n=`routes`,r=`workflows`,i=`events`,a=`public`,o=`locales`,s=process.env.NODE_ENV===`production`?`js`:`ts`;export{e as APPOS_DIR,t as DATABASES_DIR,i as EVENTS_DIR,s as FILE_EXT,o as LOCALES_DIR,a as PUBLIC_DIR,n as ROUTES_DIR,r as WORKFLOWS_DIR};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{APPOS_DIR as e,DATABASES_DIR as t}from"./
|
|
1
|
+
import{APPOS_DIR as e,DATABASES_DIR as t}from"./constants.mjs";import{getTableName as n,sql as r}from"drizzle-orm";import{join as i}from"node:path";import{drizzle as a}from"drizzle-orm/node-postgres";import{migrate as o}from"drizzle-orm/node-postgres/migrator";import{Client as s,Pool as c}from"pg";const l=`public`;function u(n,r=`schema`){let a=r===`schema`?`schema-migrations`:`data-migrations`,o=r===`schema`?`schema-migrations`:`data-migrations`;return{migrationsFolder:`${i(e,t)}/${n}/${a}`,migrationsSchema:l,migrationsTable:o}}var d=class{#e;constructor(e){this.#e=e}logQuery(e,t){this.#e.info(t,e)}};function f(e){let t=n(e);return{_table:r`${r.raw(`'${t}'`)}`.as(`_table`),old:r`to_jsonb(OLD.*)`.as(`old`),new:r`to_jsonb(NEW.*)`.as(`new`)}}async function p(e){return a({client:new c({application_name:`appos`,max:16,...e.poolConfig}),logger:new d(e.logger),relations:e.relations,schema:e.schema})}async function m(e){let t=`test_w${process.env.VITEST_POOL_ID||`0`}_${Date.now()}_${Math.random().toString(36).substring(2,8)}`;await y(e.connectionString,e.name,e.logger);let n=`${e.name}_test_template`,r=_(e.connectionString),i=new s({connectionString:r});await i.connect();try{await i.query(`CREATE DATABASE ${t} WITH TEMPLATE ${n}`)}finally{await i.end()}let o=h(e.connectionString);o.database=t;let l=new c({connectionString:g(o)});return{cleanUp:async()=>{await l.end();let e=new s({connectionString:r});await e.connect();try{await e.query(`SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1`,[t]),await e.query(`DROP DATABASE IF EXISTS ${t}`)}catch(e){console.error(`Could not drop test database:`,e)}finally{await e.end()}},db:a({client:l,logger:e.logger?new d(e.logger):void 0,relations:e.relations,schema:e.schema}),dbName:t}}function h(e){let t=new URL(e);return{database:t.pathname.slice(1)||`postgres`,host:t.hostname,password:decodeURIComponent(t.password),port:Number.parseInt(t.port||`5432`,10),user:decodeURIComponent(t.username)}}function g(e){let{user:t,password:n,host:r,port:i,database:a}=e;return`postgresql://${encodeURIComponent(t)}:${encodeURIComponent(n)}@${r}:${i}/${a}`}function _(e){let t=h(e);return t.database=`postgres`,g(t)}function v(e){let t=0;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);t=(t<<5)-t+r,t&=t}return Math.abs(t)}async function y(e,t,n){let r=`${t}_test_template`,i=new s({connectionString:_(e)});await i.connect();let l=v(r);try{if(await i.query(`SELECT pg_advisory_lock($1)`,[l]),(await i.query(`SELECT 1 FROM pg_database WHERE datname = $1`,[r])).rowCount===0){await i.query(`CREATE DATABASE ${r} WITH IS_TEMPLATE = true`);let s=h(e);s.database=r;let l=new c({connectionString:g(s)});try{await o(a({client:l,logger:n?new d(n):void 0}),u(t))}finally{await l.end()}}}finally{await i.query(`SELECT pg_advisory_unlock($1)`,[l]),await i.end()}}export{f as dbChanges,p as defineDatabase,u as defineMigrationOpts,m as defineTestDatabase,l as migrationsSchema};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineRedisClient as e}from"./redis.mjs";import{APPOS_DIR as t,EVENTS_DIR as n}from"./
|
|
1
|
+
import{defineRedisClient as e}from"./redis.mjs";import{APPOS_DIR as t,EVENTS_DIR as n,FILE_EXT as r}from"./constants.mjs";import{z as i}from"zod";import{basename as a,join as o}from"node:path";import{glob as s}from"node:fs/promises";import{camelCase as c}from"es-toolkit";function l(t){let n=e({logger:t.logger,url:t.dbUrl}),r=null,i=new Map;return{async publish(e,t){await n.publish(e,JSON.stringify(t))},async subscribe(e,a){return r||(r=n.duplicate(),await r.connect()),i.has(e)||(i.set(e,new Set),await r.subscribe(e,n=>{let r=i.get(e);if(r){let i;try{i=JSON.parse(n)}catch(r){t.logger.error({err:r,channel:e,msg:n},`Failed to parse event message`);return}for(let n of r)try{n(i)}catch(n){t.logger.error({err:n,channel:e},`Event handler error`)}}})),i.get(e).add(a),()=>{let t=i.get(e);t&&t.delete(a)}},hasSubscribers(e){let t=i.get(e);return t!==void 0&&t.size>0},async close(){r?.isOpen&&await r.quit(),n.isOpen&&await n.quit()}}}function u(e){let t=null,n=null;return{inputSchema:e.input,get name(){return n},register(e,r){t=e,n=r},async emit(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before emitting events.`);let i=e.input.parse(r),a={container:t,input:i};await e.run(a),t.eventBus.publish(n,i).catch(e=>{t.logger.error({err:e,event:n},`Redis publish failed`)})},async subscribe(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before subscribing.`);return t.eventBus.subscribe(n,async i=>{let a=e.input.parse(i),o={container:t,input:a};try{await r(o)}catch(e){t.logger.error({err:e,event:n},`Event subscription handler error`)}})}}}const d=i.object({action:i.enum([`INSERT`,`UPDATE`,`DELETE`]),newData:i.record(i.string(),i.unknown()).nullable(),oldData:i.record(i.string(),i.unknown()).nullable(),organizationId:i.string().nullable(),tableName:i.string(),timestamp:i.string(),userId:i.string().nullable()}),f=u({input:d,async run(){}});function p(e){return c(a(e,`.ts`))}async function m(e){let{container:i}=e,a=e.eventsDir??o(process.cwd(),t,n);f.register(i,`dbChanges`);let c=await Array.fromAsync(s(`${a}/**/*.${r}`,{exclude:[`**/*.test.ts`,`**/*.spec.ts`,`**/*.test.js`,`**/*.spec.js`]}));for(let e of c){let t=await import(e);if(t.default&&typeof t.default==`object`&&`emit`in t.default&&`subscribe`in t.default){let n=p(e);t.default.register(i,n)}}}export{d as dbChangeInputSchema,f as dbChangesEvent,u as defineEvent,l as defineEventBus,m as loadEvents};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LOCALES_DIR as e,PUBLIC_DIR as t}from"./
|
|
1
|
+
import{LOCALES_DIR as e,PUBLIC_DIR as t}from"./constants.mjs";import{join as n}from"node:path";import{lstatSync as r,readdirSync as i,watch as a}from"node:fs";import{createInstance as o}from"i18next";import s from"i18next-fs-backend";import{initReactI18next as c}from"react-i18next";const l={fallbackLng:`en`,supportedLngs:[`en`],defaultNS:`translation`,ns:[`translation`],interpolation:{escapeValue:!1},react:{useSuspense:!1}};async function u(l){let u=n(t,e),d=o();return process.env.NODE_ENV!==`production`&&!process.env.VITEST&&a(u,{recursive:!0},async(e,t)=>{await d.reloadResources(l.supportedLngs||[])}).unref(),await d.use(s).use(c).init({...l,backend:{loadPath:`${u}/{{lng}}/{{ns}}.json`},initAsync:!1,preload:i(u).filter(e=>r(n(u,e)).isDirectory())}),d}export{l as defaultI18nOptions,u as defineI18n};
|
|
@@ -13,8 +13,8 @@ import { AppContext, DefineAppContextOpts, SessionData, defineAppContext } from
|
|
|
13
13
|
import { defineAuthSchema } from "./auth-schema.mjs";
|
|
14
14
|
import { I18nInitOptions, defaultI18nOptions, defineI18n, i18n } from "./i18n.mjs";
|
|
15
15
|
import { Middleware, defineMiddleware, loadMiddleware } from "./middleware.mjs";
|
|
16
|
-
import { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse,
|
|
16
|
+
import { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineTypedResponses, generateOpenAPIDocument, loadAndRegisterAPIRoutes, registerRoutes, scanAPIRoutes, writeOpenAPISpecs } from "./openapi.mjs";
|
|
17
17
|
import { withOtelSpan } from "./otel.mjs";
|
|
18
18
|
import { DefineRedisClientOptions, RedisClient, defineRedisClient } from "./redis.mjs";
|
|
19
19
|
import { CustomTypeOptions } from "i18next";
|
|
20
|
-
export { AccessControlRoles, AccessController, AppContainer, AppContext, AuditAction, Auth, AuthConfig, AuthPasskeyConfig, AuthSessionConfig, Cache, Config, Container, type CustomTypeOptions, Database, DatabaseWithStorage, DbChangeInput, DefineAppContextOpts, DefineAuthOptions, DefineCacheOptions, DefineDatabaseOptions, DefineEventBusOptions, DefineLoggerOptions, DefineMailerOptions, DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, DefineRedisClientOptions, DefineS3DiskOptions, DefineStorageOptions, DefineTestDatabaseOptions, Event, EventBus, EventContext, HandlerParams, I18nInitOptions, Logger, Mailer, MailerPayload, MailerPayloadHtml, MailerPayloadReact, Middleware, MigrationType, NewStorageAttachment, NewStorageBlob, NewStorageVariantRecord, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, QualifiedTableNames, RedisClient, Role, RouteModule, ScheduledWorkflowContext, ServerConfig, SessionData, Storage, StorageAttachment, StorageBlob, StorageRelations, StorageRelationsConfig, StorageService, StorageTables, StorageVariantRecord, ValidationErrorResponse, WorkerConfig, WorkflowContext, WorkflowHandle,
|
|
20
|
+
export { AccessControlRoles, AccessController, AppContainer, AppContext, AuditAction, Auth, AuthConfig, AuthPasskeyConfig, AuthSessionConfig, Cache, Config, Container, type CustomTypeOptions, Database, DatabaseWithStorage, DbChangeInput, DefineAppContextOpts, DefineAuthOptions, DefineCacheOptions, DefineDatabaseOptions, DefineEventBusOptions, DefineLoggerOptions, DefineMailerOptions, DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, DefineRedisClientOptions, DefineS3DiskOptions, DefineStorageOptions, DefineTestDatabaseOptions, Event, EventBus, EventContext, HandlerParams, I18nInitOptions, Logger, Mailer, MailerPayload, MailerPayloadHtml, MailerPayloadReact, Middleware, MigrationType, NewStorageAttachment, NewStorageBlob, NewStorageVariantRecord, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, QualifiedTableNames, RedisClient, Role, RouteModule, ScheduledWorkflowContext, ServerConfig, SessionData, Storage, StorageAttachment, StorageBlob, StorageRelations, StorageRelationsConfig, StorageService, StorageTables, StorageVariantRecord, ValidationErrorResponse, WorkerConfig, WorkflowContext, WorkflowHandle, auditActionSchema, baseSchema, createAccessControl, dbChangeInputSchema, dbChanges, dbChangesEvent, defaultI18nOptions, defineAppContainer, defineAppContext, defineAuth, defineAuthSchema, defineCache, defineConfig, defineDatabase, defineEvent, defineEventBus, defineI18n, defineLogger, defineMailer, defineMiddleware, defineMigrationOpts, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineRedisClient, defineS3Disk, defineScheduledWorkflow, defineStorage, defineStorageSchema, defineTestDatabase, defineTypedResponses, defineWorkflow, generateOpenAPIDocument, i18n, loadAndRegisterAPIRoutes, loadEvents, loadMiddleware, loadWorkflows, migrationsSchema, registerRoutes, scanAPIRoutes, withOtelSpan, writeOpenAPISpecs };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineAppContext as e}from"./app-context.mjs";import{auditActionSchema as t,createAccessControl as n,defineAuth as r}from"./auth.mjs";import{defineAuthSchema as i}from"./auth-schema.mjs";import{defineRedisClient as a}from"./redis.mjs";import{defineCache as o}from"./cache.mjs";import{baseSchema as s,defineConfig as c}from"./config.mjs";import{defineAppContainer as l}from"./container.mjs";import{dbChanges as u,defineDatabase as d,defineMigrationOpts as f,defineTestDatabase as p,migrationsSchema as m}from"./database.mjs";import{dbChangeInputSchema as h,dbChangesEvent as g,defineEvent as _,defineEventBus as v,loadEvents as y}from"./event.mjs";import{defaultI18nOptions as b,defineI18n as x}from"./i18n.mjs";import{defineLogger as S}from"./logger.mjs";import{defineMailer as C}from"./mailer.mjs";import{defineMiddleware as w,loadMiddleware as T}from"./middleware.mjs";import{
|
|
1
|
+
import{defineAppContext as e}from"./app-context.mjs";import{auditActionSchema as t,createAccessControl as n,defineAuth as r}from"./auth.mjs";import{defineAuthSchema as i}from"./auth-schema.mjs";import{defineRedisClient as a}from"./redis.mjs";import{defineCache as o}from"./cache.mjs";import{baseSchema as s,defineConfig as c}from"./config.mjs";import{defineAppContainer as l}from"./container.mjs";import{dbChanges as u,defineDatabase as d,defineMigrationOpts as f,defineTestDatabase as p,migrationsSchema as m}from"./database.mjs";import{dbChangeInputSchema as h,dbChangesEvent as g,defineEvent as _,defineEventBus as v,loadEvents as y}from"./event.mjs";import{defaultI18nOptions as b,defineI18n as x}from"./i18n.mjs";import{defineLogger as S}from"./logger.mjs";import{defineMailer as C}from"./mailer.mjs";import{defineMiddleware as w,loadMiddleware as T}from"./middleware.mjs";import{defineOpenAPI as E,defineOpenAPIConfig as D,defineOpenAPIEndpoint as O,defineTypedResponses as k,generateOpenAPIDocument as A,loadAndRegisterAPIRoutes as j,registerRoutes as M,scanAPIRoutes as N,writeOpenAPISpecs as P}from"./openapi.mjs";import{withOtelSpan as F}from"./otel.mjs";import{defineScheduledWorkflow as I,defineWorkflow as L,loadWorkflows as R}from"./workflow.mjs";import{StorageService as z,defineS3Disk as B,defineStorage as V}from"./storage.mjs";import{defineStorageSchema as H}from"./storage-schema.mjs";export{z as StorageService,t as auditActionSchema,s as baseSchema,n as createAccessControl,h as dbChangeInputSchema,u as dbChanges,g as dbChangesEvent,b as defaultI18nOptions,l as defineAppContainer,e as defineAppContext,r as defineAuth,i as defineAuthSchema,o as defineCache,c as defineConfig,d as defineDatabase,_ as defineEvent,v as defineEventBus,x as defineI18n,S as defineLogger,C as defineMailer,w as defineMiddleware,f as defineMigrationOpts,E as defineOpenAPI,D as defineOpenAPIConfig,O as defineOpenAPIEndpoint,a as defineRedisClient,B as defineS3Disk,I as defineScheduledWorkflow,V as defineStorage,H as defineStorageSchema,p as defineTestDatabase,k as defineTypedResponses,L as defineWorkflow,A as generateOpenAPIDocument,j as loadAndRegisterAPIRoutes,y as loadEvents,T as loadMiddleware,R as loadWorkflows,m as migrationsSchema,M as registerRoutes,N as scanAPIRoutes,F as withOtelSpan,P as writeOpenAPISpecs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{__reExport as e}from"./_virtual/rolldown_runtime.mjs";import{register as t}from"node:module";import{getNodeAutoInstrumentations as n}from"@opentelemetry/auto-instrumentations-node";import{OTLPTraceExporter as r}from"@opentelemetry/exporter-trace-otlp-http";import{PinoInstrumentation as i}from"@opentelemetry/instrumentation-pino";import{resourceFromAttributes as a}from"@opentelemetry/resources";import{NodeSDK as o}from"@opentelemetry/sdk-node";import{BatchSpanProcessor as s}from"@opentelemetry/sdk-trace-node";import{ATTR_SERVICE_NAME as c,ATTR_SERVICE_VERSION as l}from"@opentelemetry/semantic-conventions";export*from"@opentelemetry/api";var u={};import*as d from"@opentelemetry/api";e(u,d),t(`@opentelemetry/instrumentation/hook.mjs`,import.meta.url);const f={name:process.env.APP_NAME||`appos`,version:process.env.APP_VERSION||`development`};new o({resource:a({[c]:f.name,[l]:f.version}),spanProcessors:[new s(new r({url:process.env.OTEL_EXPORTER_OTLP_ENDPOINT||`http://localhost:4318/v1/traces`,headers:process.env.OTEL_EXPORTER_OTLP_HEADERS?JSON.parse(process.env.OTEL_EXPORTER_OTLP_HEADERS):void 0}))],instrumentations:[n({"@opentelemetry/instrumentation-fs":{enabled:!1},"@opentelemetry/instrumentation-dns":{enabled:!1}}),new i({logHook:(e,t)=>{t[`service.name`]=f.name}})]}).start();export{u as instrumentation_exports};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{FILE_EXT as e}from"./constants.mjs";import{basename as t}from"node:path";import n,{glob as r}from"node:fs/promises";import{camelCase as i}from"es-toolkit";function a(e){return{name:e.name??null,handler:e.handler}}function o(e){return i(t(e,`.ts`).replace(/^\d+_/,``))}async function s(i,a,s){try{await n.access(i)}catch{return}let c=[];for await(let t of r(`${i}/**/*.${e}`))!t.endsWith(`.test.ts`)&&!t.endsWith(`.spec.ts`)&&!t.endsWith(`.test.js`)&&!t.endsWith(`.spec.js`)&&c.push(t);c.sort((e,n)=>t(e).localeCompare(t(n)));for(let e of c)try{let t=(await import(e)).default;if(t&&typeof t.handler==`function`){let n=t.name??o(e);a.logger.debug({name:n,file:e},`Loading user middleware`),s.use(t.handler(a))}else a.logger.warn({file:e},`Middleware file missing default export with handler function`)}catch(t){throw a.logger.error({file:e,error:t instanceof Error?t.message:t},`Failed to load middleware`),t}}export{a as defineMiddleware,s as loadMiddleware};
|
|
@@ -5,7 +5,7 @@ import { Express, Request, RequestHandler } from "ultimate-express";
|
|
|
5
5
|
import * as _node_modules_zod_openapi_dist_components_B1DX_zYv_mjs0 from "#node_modules/zod-openapi/dist/components-B1DX_zYv.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/api/openapi.d.ts
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
/**
|
|
10
10
|
* Utility type to enforce exact type matching (no extra properties).
|
|
11
11
|
* This uses a tuple check to prevent objects with extra keys from being assigned.
|
|
@@ -268,4 +268,4 @@ declare function writeOpenAPISpecs<TContainer extends Container>(container: TCon
|
|
|
268
268
|
*/
|
|
269
269
|
declare function loadAndRegisterAPIRoutes<TContainer extends Container>(app: Express): Promise<void>;
|
|
270
270
|
//#endregion
|
|
271
|
-
export { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse,
|
|
271
|
+
export { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineTypedResponses, generateOpenAPIDocument, loadAndRegisterAPIRoutes, registerRoutes, scanAPIRoutes, writeOpenAPISpecs };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineAppContext as e}from"./app-context.mjs";import{PUBLIC_DIR as
|
|
1
|
+
import{defineAppContext as e}from"./app-context.mjs";import{APPOS_DIR as t,FILE_EXT as n,PUBLIC_DIR as r,ROUTES_DIR as i}from"./constants.mjs";import{z as a}from"zod";import{join as o,resolve as s}from"node:path";import{access as c,mkdir as l,writeFile as u}from"node:fs/promises";import{remixRoutesOptionAdapter as d}from"@react-router/remix-routes-option-adapter";import{isEmpty as f}from"es-toolkit/compat";import{flatRoutes as p}from"remix-flat-routes";import{createDocument as m}from"zod-openapi";const h=s(r,`openapi`);function g(e){let t={};for(let[n,r]of Object.entries(e)){let e=Number(n),i=_(e);i&&(t[i]=t=>{let n=r.schema;if(n instanceof a.ZodNull||t==null)return{__response:!0,status:e,data:t??null};try{let r=n;if(n instanceof a.ZodObject)r=n.strict();else if(n instanceof a.ZodArray){let e=n.element;e instanceof a.ZodObject&&(r=a.array(e.strict()))}return{__response:!0,status:e,data:r.parse(t)}}catch(n){throw n instanceof a.ZodError?Error(`Response validation failed for status ${e}: ${JSON.stringify(n.issues,null,2)}\n\nData provided: ${JSON.stringify(t,null,2)}`):n}})}return t.status=(t,n)=>{let r=Number(t),i=e[t];if(!i)return{__response:!0,status:r,data:n??null};let o=i.schema;if(!o||o instanceof a.ZodNull||n==null)return{__response:!0,status:r,data:n??null};try{let e=o;if(o instanceof a.ZodObject)e=o.strict();else if(o instanceof a.ZodArray){let t=o.element;t instanceof a.ZodObject&&(e=a.array(t.strict()))}return{__response:!0,status:r,data:e.parse(n)}}catch(e){throw e instanceof a.ZodError?Error(`Response validation failed for status ${r}: ${JSON.stringify(e.issues,null,2)}\n\nData provided: ${JSON.stringify(n,null,2)}`):e}},t}function _(e){return{200:`ok`,201:`created`,202:`accepted`,204:`noContent`,400:`badRequest`,401:`unauthorized`,403:`forbidden`,404:`notFound`,409:`conflict`,422:`unprocessableEntity`,500:`internalServerError`}[e]||null}function v(e){return e}function y(e,t){return e?e.parse(t):t}function b(e,t){let n={};for(let[e,r]of t.searchParams.entries()){let t=n[e];t===void 0?n[e]=r:Array.isArray(t)?t.push(r):n[e]=[t,r]}return e?e.parse(n):n}function x(e,t){let n=t.body;return e?e.parse(n):n}function S(e,t){let n=t.headers;return e?e.parse(n):n}function C(e){switch(e){case`params`:case`query`:case`headers`:return 400;case`body`:return 422;default:return 400}}function w(e,t){let n=C(t);return{__response:!0,status:n,data:{error:`validation_error`,status:n,detail:`Request validation failed`,errors:e.issues.map(e=>({field:e.path.join(`.`),message:e.message,received:`received`in e?e.received:e.input}))}}}function T(t,n){return async(r,i,o)=>{try{let n=new URL(r.url||`/`,`http://${r.headers.host}`),a=y(t.params,r.params),o=b(t.query,n),s=x(t.requestBody,r),c=S(t.headers,r),l=g(t.responses),u=await e({apiKey:r.apiKey,container:r.app.locals.container,request:r,fetchSession:!1}),d=await t.handler({ctx:u,body:s,headers:c,params:a,query:o,request:r,response:l});if(d&&typeof d==`object`&&`__response`in d){let e=d;e.data===null||e.data===void 0?i.status(e.status).end():i.status(e.status).json(e.data)}else i.status(200).json(d)}catch(e){if(e instanceof a.ZodError){let t=w(e,n===`GET`||n===`HEAD`?`query`:`body`);i.status(t.status).json(t.data)}else o(e)}}}function E(e){let t=[];for(let n of[`GET`,`HEAD`,`POST`,`PUT`,`PATCH`,`DELETE`]){let r=e[n];if(!r)continue;let i={};r.params&&(i.params=r.params),r.query&&(i.query=r.query),r.requestBody&&(i.body=r.requestBody),r.headers&&(i.headers=r.headers);let a={};for(let[e,t]of Object.entries(r.responses))a[Number(e)]={description:t.description,content:{"application/json":{schema:t.schema}}};t.push({method:n.toLowerCase(),summary:r.summary,description:r.description,request:Object.keys(i).length>0?i:void 0,responses:a})}return t}function D(e){let t={};for(let n of[`GET`,`HEAD`,`POST`,`PUT`,`PATCH`,`DELETE`]){let r=e[n];r&&(t[n]=T(r,n))}return{handlers:t,openAPISpec:E(e)}}function O(e){return t=>{let n=e(t);return{info:n.info,servers:n.servers,openapi:`3.1.0`}}}function k(e){return e.match(/^\/(v\d+)/)?.[1]}function A(e){return e.replace(/:(\w+)/g,`{$1}`)}function j(e,t){let n=A(e),r={summary:t.summary,description:t.description};(t.request?.params||t.request?.query||t.request?.headers)&&(r.requestParams={},t.request.params&&(r.requestParams.path=t.request.params),t.request.query&&(r.requestParams.query=t.request.query),t.request.headers&&(r.requestParams.header=t.request.headers)),t.request?.body&&(r.requestBody={content:{"application/json":{schema:t.request.body}}}),r.responses={};for(let[e,n]of Object.entries(t.responses))r.responses[e]={description:n.description,content:{"application/json":{schema:n.content[`application/json`].schema}}};return{path:n,config:r}}function M(e,t,n){let r={};for(let n of e){if(n.version!==t)continue;let e=n.path.replace(`/${t}`,``)||`/`;for(let t of n.openAPISpec){let{path:n,config:i}=j(e,t);r[n]||(r[n]={}),r[n][t.method]=i}}return m({openapi:`3.1.0`,info:n?.info||{title:`API ${t.toUpperCase()}`,version:t.replace(`v`,``),description:`OpenAPI specification for ${t} API`},servers:n?.servers||[{url:`http://localhost:8000/${t}`,description:process.env.NODE_ENV===`production`?`Production server`:`Development server`}],paths:r})}async function N(e){let n=s(t,i);try{await c(n)}catch(t){return e.logger.error({error:t},`OpenAPI routes directory not found`),[]}let r=await d(e=>p(i,e,{appDir:t,ignoredRouteFiles:[`**/.*`,`**/*.{spec,test}.{ts,tsx}`,`**/*-????????.{js,ts}`]})),a=[];for(let[n,i]of Object.entries(r)){let n=s(t,i.file).replace(/.ts$/,process.env.NODE_ENV===`production`?`.js`:`.ts`);try{let r=(await import(n)).default;if(!r||f(r)||/\/openapi.(j|t)s$/.test(n))continue;if(!r?.handlers&&!r?.openAPISpec){e.logger.warn(`Missing default export with 'defineOpenAPI' for '${t}/${i.file}'`);continue}let o=`/${i.path}`;a.push({path:o,filePath:n,handlers:r.handlers,openAPISpec:r.openAPISpec,version:k(o)})}catch(t){e.logger.error(t,`Error loading route ${i.file}:`)}}return a}function P(e,t){for(let n of t)for(let[t,r]of Object.entries(n.handlers))e[t.toLowerCase()](n.path,r)}async function F(e,r){let a=s(t,i,`${r}+/openapi.${n}`);try{let t=(await import(a)).default;return t?t(e):void 0}catch{return}}async function I(e,t){let n=[...new Set(t.map(e=>e.version).filter(Boolean))];n.length>0&&await l(h,{recursive:!0});for(let r of n){let n=M(t,r,await F(e,r));await u(o(h,`${r}.json`),JSON.stringify(n,null,2),`utf-8`)}}async function L(e){let t=await N(e.locals.container);P(e,t),process.env.NODE_ENV!==`production`&&await I(e.locals.container,t)}export{D as defineOpenAPI,O as defineOpenAPIConfig,v as defineOpenAPIEndpoint,g as defineTypedResponses,M as generateOpenAPIDocument,L as loadAndRegisterAPIRoutes,P as registerRoutes,N as scanAPIRoutes,I as writeOpenAPISpecs};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{instrumentation_exports as e}from"./
|
|
1
|
+
import{instrumentation_exports as e}from"./instrumentation.mjs";import{getCallSites as t}from"node:util";async function n(n,r){let i=t()[1],a=i.scriptName.replace(process.cwd(),``).replace(`file:///`,``),o=i.functionName,s=e.trace.getTracer(a.replace(`build/`,``)).startSpan(o,{attributes:r}),c=e.trace.setSpan(e.context.active(),s);try{let t=await e.context.with(c,()=>n(s));return s.end(),t}catch(e){throw s.recordException(e),s.end(),e}}export{n as withOtelSpan};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{APPOS_DIR as e,WORKFLOWS_DIR as
|
|
1
|
+
import{APPOS_DIR as e,FILE_EXT as t,WORKFLOWS_DIR as n}from"./constants.mjs";import{basename as r,join as i}from"node:path";import{glob as a}from"node:fs/promises";import{camelCase as o}from"es-toolkit";function s(e){let t=null,n=null,r=null,i=null,a=async i=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let a=r,o=a.workflowID;if(!o)throw Error(`DBOS.workflowID is not available in this context`);let s={container:t,workflowId:o,input:i,step:(e,t)=>a.runStep(t,{name:e})};return e.run(s)};return{inputSchema:e.input,get name(){return n},register(o,s,c){t=o,n=s,r=c,i=c.registerWorkflow(a,{name:s,...e.config})},async start(t){if(!i||!n||!r)throw Error(`Workflow not registered. Ensure the worker is started before triggering workflows.`);let a=e.input.parse(t),o=await r.startWorkflow(i)(a);return{workflowId:o.workflowID,getStatus:()=>o.getStatus(),getResult:()=>o.getResult()}}}}function c(e){let t=null,n=null,r=null,i=async(i,a)=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let o=r,s=o.workflowID;if(!s)throw Error(`DBOS.workflowID is not available in this context`);let c={container:t,workflowId:s,scheduledTime:i,step:(e,t)=>o.runStep(t,{name:e})};return e.run(c)};return{crontab:e.crontab,get name(){return n},register(a,o,s){t=a,n=o,r=s,s.registerScheduled(s.registerWorkflow(i,{name:o}),{crontab:e.crontab})}}}function l(e){return o(r(e,`.ts`))}async function u(r){let{container:o,dbos:s}=r,c=r.workflowsDir??i(process.cwd(),e,n),u=(e,t)=>{try{e.register(o,t,s)}catch(e){if(!(e instanceof Error)||!e.message.includes(`already registered`))throw e}},{extractBlobMetadata:d}=await import(`./workflows/extract-blob-metadata.mjs`),{generateImageVariant:f}=await import(`./workflows/generate-image-variant.mjs`),{generatePreview:p}=await import(`./workflows/generate-preview.mjs`),{purgeAttachment:m}=await import(`./workflows/purge-attachment.mjs`),{trackDbChanges:h}=await import(`./workflows/track-db-changes.mjs`),{definePurgeAuditLogs:g}=await import(`./workflows/purge-audit-logs.mjs`),{definePurgeUnattachedBlobs:_}=await import(`./workflows/purge-unattached-blobs.mjs`);u(d,`extractBlobMetadata`),u(f,`generateImageVariant`),u(p,`generatePreview`),u(m,`purgeAttachment`),u(h,`trackDbChanges`),u(g(o.auth.auditLog?.purgeCron),`purgeAuditLogs`),u(_(o.storage.primary.purgeCron),`purgeUnattachedBlobs`);let v=await Array.fromAsync(a(`${c}/**/*.${t}`,{exclude:[`**/*.test.ts`,`**/*.spec.ts`,`**/*.test.js`,`**/*.spec.js`]}));for(let e of v){let t=await import(e);if(t.default&&typeof t.default==`object`&&`register`in t.default){let n=l(e);u(t.default,n)}}}export{c as defineScheduledWorkflow,s as defineWorkflow,u as loadWorkflows};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./redis.mjs";import"../constants.mjs";import{z as e}from"zod";import{join as t}from"node:path";import"es-toolkit";function n(e){let t=null,n=null;return{inputSchema:e.input,get name(){return n},register(e,r){t=e,n=r},async emit(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before emitting events.`);let i=e.input.parse(r),a={container:t,input:i};await e.run(a),t.eventBus.publish(n,i).catch(e=>{t.logger.error({err:e,event:n},`Redis publish failed`)})},async subscribe(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before subscribing.`);return t.eventBus.subscribe(n,async i=>{let a=e.input.parse(i),o={container:t,input:a};try{await r(o)}catch(e){t.logger.error({err:e,event:n},`Event subscription handler error`)}})}}}const r=n({input:e.object({action:e.enum([`INSERT`,`UPDATE`,`DELETE`]),newData:e.record(e.string(),e.unknown()).nullable(),oldData:e.record(e.string(),e.unknown()).nullable(),organizationId:e.string().nullable(),tableName:e.string(),timestamp:e.string(),userId:e.string().nullable()}),async run(){}});export{r as dbChangesEvent};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __export, __reExport } from "
|
|
1
|
+
import { __export, __reExport } from "../_virtual/rolldown_runtime.mjs";
|
|
2
2
|
import { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable as pgTable$1, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas } from "drizzle-orm/pg-core";
|
|
3
3
|
export * from "drizzle-orm";
|
|
4
4
|
export * from "drizzle-seed";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StorageBlob, StorageRelationsConfig, StorageTables } from "./storage-schema.mjs";
|
|
2
|
-
import { ImageTransformations } from "
|
|
2
|
+
import { ImageTransformations } from "../generate-image-variant.mjs";
|
|
3
3
|
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
4
4
|
import { Pool } from "pg";
|
|
5
5
|
import { DriveManager } from "flydrive";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../constants.mjs";import{join as e}from"node:path";import"es-toolkit";function t(e){let t=null,n=null,r=null,i=null,a=async i=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let a=r,o=a.workflowID;if(!o)throw Error(`DBOS.workflowID is not available in this context`);let s={container:t,workflowId:o,input:i,step:(e,t)=>a.runStep(t,{name:e})};return e.run(s)};return{inputSchema:e.input,get name(){return n},register(o,s,c){t=o,n=s,r=c,i=c.registerWorkflow(a,{name:s,...e.config})},async start(t){if(!i||!n||!r)throw Error(`Workflow not registered. Ensure the worker is started before triggering workflows.`);let a=e.input.parse(t),o=await r.startWorkflow(i)(a);return{workflowId:o.workflowID,getStatus:()=>o.getStatus(),getResult:()=>o.getResult()}}}}function n(e){let t=null,n=null,r=null,i=async(i,a)=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let o=r,s=o.workflowID;if(!s)throw Error(`DBOS.workflowID is not available in this context`);let c={container:t,workflowId:s,scheduledTime:i,step:(e,t)=>o.runStep(t,{name:e})};return e.run(c)};return{crontab:e.crontab,get name(){return n},register(a,o,s){t=a,n=o,r=s,s.registerScheduled(s.registerWorkflow(i,{name:o}),{crontab:e.crontab})}}}export{n as defineScheduledWorkflow,t as defineWorkflow};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
process.env.NODE_ENV;export{};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as e}from"
|
|
1
|
+
import{defineWorkflow as e}from"./api/workflow.mjs";import t from"zod";import{join as n}from"node:path";import{ALL_FORMATS as r,BlobSource as i,Input as a}from"mediabunny";const o=e({input:t.object({blobId:t.string()}),async run({container:e,input:{blobId:t},step:o}){let s=await o(`fetch-blob`,async()=>e.storage.primary.getBlob(t));if(!s)throw Error(`Blob ${t} not found`);let c=await o(`download-blob`,async()=>e.storage.primary.downloadBlob(t));if(!c)throw Error(`Failed to download blob ${t}`);let l={};return s.contentType?.startsWith(`image/`)?l=await o(`extract-image-metadata`,async()=>{let e=(await import(`sharp`)).default,t=await e(c).metadata();return{width:t.width,height:t.height,format:t.format,hasAlpha:t.hasAlpha,space:t.space}}):s.contentType?.startsWith(`video/`)||s.contentType?.startsWith(`audio/`)?l=await o(`extract-media-metadata`,async()=>{let e=new Uint8Array(c),t=new a({source:new i(new Blob([e],{type:s.contentType||`video/mp4`})),formats:r}),n=await t.computeDuration(),o=await t.getMetadataTags(),l={},u={},d=!1,f=!1;try{let e=await t.getPrimaryVideoTrack();if(e){d=!0;let t=e.displayWidth&&e.displayHeight?e.displayWidth/e.displayHeight:null;l={width:e.displayWidth,height:e.displayHeight,rotation:e.rotation,angle:e.rotation,displayAspectRatio:t}}}catch{}try{let e=await t.getPrimaryAudioTrack();e&&(f=!0,u={sampleRate:e.sampleRate,channels:e.numberOfChannels})}catch{}return{duration:n,video:d,audio:f,...l,...u,tags:o}}):s.contentType===`application/pdf`&&(l=await o(`extract-pdf-metadata`,async()=>{try{let e=await import(`pdfjs-dist/legacy/build/pdf.mjs`),t=`${n(process.cwd(),`node_modules/pdfjs-dist/standard_fonts`)}/`,r=await e.getDocument({data:new Uint8Array(c),standardFontDataUrl:t}).promise,i=await r.getMetadata(),a=(await r.getPage(1)).getViewport({scale:1}),o=i.info;return{pageCount:r.numPages,width:a.width,height:a.height,title:o?.Title||null,author:o?.Author||null,subject:o?.Subject||null,keywords:o?.Keywords||null,creator:o?.Creator||null,producer:o?.Producer||null,creationDate:o?.CreationDate||null,modificationDate:o?.ModDate||null,pdfVersion:o?.PDFFormatVersion||null}}catch(n){return e.logger.error({error:n,errorMessage:n instanceof Error?n.message:String(n),errorStack:n instanceof Error?n.stack:void 0,errorCode:n?.code,blobId:t},`Failed to extract PDF metadata`),{error:`Failed to extract PDF metadata`,errorMessage:n instanceof Error?n.message:String(n)}}})),await o(`save-metadata`,async()=>{await e.storage.primary.updateBlobMetadata(t,{...l,analyzed:!0})}),e.logger.info({blobId:t,metadata:l},`Metadata extracted`),{...l,analyzed:!0}}});export{o as extractBlobMetadata};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as e}from"
|
|
1
|
+
import{defineWorkflow as e}from"./api/workflow.mjs";import{z as t}from"zod";const n=t.object({width:t.number().optional(),height:t.number().optional(),fit:t.enum([`cover`,`contain`,`fill`,`inside`,`outside`]).optional(),position:t.enum([`top`,`right top`,`right`,`right bottom`,`bottom`,`left bottom`,`left`,`left top`,`centre`]).optional(),kernel:t.enum([`nearest`,`linear`,`cubic`,`mitchell`,`lanczos2`,`lanczos3`]).optional()}),r=t.object({resize:n.optional(),rotate:t.number().optional(),flip:t.boolean().optional(),flop:t.boolean().optional(),sharpen:t.boolean().optional(),blur:t.number().optional(),grayscale:t.boolean().optional(),format:t.enum([`jpeg`,`png`,`webp`,`avif`,`gif`]).optional(),quality:t.number().min(1).max(100).optional(),preview:t.literal(!0).optional()}),i=e({input:t.object({blobId:t.string(),transformations:r}),async run({container:e,input:{blobId:t,transformations:n},step:r}){if(!await r(`fetch-blob`,async()=>e.storage.primary.getBlob(t)))throw Error(`Blob ${t} not found`);let i=await r(`download-blob`,async()=>e.storage.primary.downloadBlob(t));if(!i)throw Error(`Failed to download blob ${t}`);let a=await r(`apply-transformations`,async()=>{let e=(await import(`sharp`)).default,t=e(i);return n.resize&&(t=t.resize({width:n.resize.width,height:n.resize.height,fit:n.resize.fit,position:n.resize.position,kernel:n.resize.kernel})),n.rotate!==void 0&&(t=t.rotate(n.rotate)),n.flip&&(t=t.flip()),n.flop&&(t=t.flop()),n.sharpen&&(t=t.sharpen()),n.blur!==void 0&&(t=t.blur(n.blur)),n.grayscale&&(t=t.grayscale()),n.format&&(t=t.toFormat(n.format,{quality:n.quality})),t.toBuffer()}),o=await r(`store-variant`,async()=>e.storage.primary.createVariant(t,n,a));return e.logger.info({blobId:t,variantId:o.id},`Image variant generated`),o}});export{i as generateImageVariant};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as e}from"
|
|
1
|
+
import{defineWorkflow as e}from"./api/workflow.mjs";import t from"zod";import{join as n}from"node:path";import{spawn as r}from"node:child_process";const i=e({input:t.object({blobId:t.string(),timeInSeconds:t.number().optional()}),async run({container:e,input:{blobId:t,timeInSeconds:i=1},step:a}){let o=await a(`fetch-blob`,async()=>e.storage.primary.getBlob(t));if(!o)throw Error(`Blob ${t} not found`);let s=await a(`download-blob`,async()=>e.storage.primary.downloadBlob(t));if(!s)throw Error(`Failed to download blob ${t}`);let c=null;if(o.contentType?.startsWith(`video/`))c=await a(`generate-video-preview`,async()=>new Promise((n,a)=>{try{let o=r(`ffmpeg`,[`-i`,`pipe:0`,`-ss`,i.toString(),`-frames:v`,`1`,`-f`,`image2pipe`,`-c:v`,`png`,`pipe:1`]),c=[],l=[];o.stdout.on(`data`,e=>{c.push(e)}),o.stderr.on(`data`,e=>{l.push(e)}),o.on(`close`,async r=>{if(r===0)try{let e=Buffer.concat(c),t=(await import(`sharp`)).default;n(await t(e).jpeg({quality:80}).toBuffer())}catch(n){e.logger.error({error:n,blobId:t},`Failed to convert video frame to JPEG`),a(n)}else{let n=Buffer.concat(l).toString(),i=Error(`FFmpeg exited with code ${r}: ${n}`);e.logger.error({error:i,blobId:t,code:r,stderr:n},`Failed to generate video preview`),a(i)}}),o.on(`error`,n=>{e.logger.error({error:n,blobId:t},`Failed to spawn FFmpeg process`),a(n)}),o.stdin.on(`error`,n=>{n.code!==`EPIPE`&&e.logger.error({error:n,blobId:t},`Failed to write to FFmpeg stdin`)}),o.stdin.write(s),o.stdin.end()}catch(n){e.logger.error({error:n,blobId:t},`Failed to generate video preview`),a(n)}}));else if(o.contentType===`application/pdf`)c=await a(`generate-pdf-preview`,async()=>{try{let e=await import(`pdfjs-dist/legacy/build/pdf.mjs`),{createCanvas:t}=await import(`canvas`),r=(await import(`sharp`)).default,i=`${n(process.cwd(),`node_modules/pdfjs-dist/standard_fonts`)}/`,a=await(await e.getDocument({data:new Uint8Array(s),standardFontDataUrl:i}).promise).getPage(1),o=a.getViewport({scale:2}),c=t(o.width,o.height),l=c.getContext(`2d`);return await a.render({canvasContext:l,viewport:o,canvas:c}).promise,await r(c.toBuffer(`image/png`)).resize(800,800,{fit:`inside`,withoutEnlargement:!0}).jpeg({quality:85}).toBuffer()}catch(n){throw e.logger.error({error:n,errorMessage:n instanceof Error?n.message:String(n),errorStack:n instanceof Error?n.stack:void 0,errorCode:n?.code,blobId:t},`Failed to generate PDF preview`),n}});else if(o.contentType?.startsWith(`image/`))c=await a(`generate-image-preview`,async()=>{let e=(await import(`sharp`)).default;return await e(s).resize(800,800,{fit:`inside`,withoutEnlargement:!0}).jpeg({quality:85}).toBuffer()});else throw Error(`Preview generation not supported for content type: ${o.contentType}`);let l=await a(`store-preview`,async()=>await e.storage.primary.createVariant(t,{preview:!0},c));return e.logger.info({blobId:t,previewId:l.id,contentType:o.contentType},`Preview generated`),l}});export{i as generatePreview};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as e}from"
|
|
1
|
+
import{defineWorkflow as e}from"./api/workflow.mjs";import t from"zod";const n=e({input:t.object({attachmentIds:t.array(t.string()).min(1)}),async run({container:e,input:{attachmentIds:t},step:n}){let r=await n(`fetch-attachments`,async()=>(await e.storage.primary.getAttachmentsByIds(t)).filter(e=>e.blob!==null).map(e=>({attachmentId:e.id,blobId:e.blob.id})));return await n(`delete-attachments`,async()=>{for(let{attachmentId:t}of r)await e.storage.primary.deleteAttachment(t)}),await n(`delete-blobs`,async()=>{for(let{blobId:t}of r)await e.storage.primary.deleteBlob(t)}),e.logger.info({attachmentIds:t,blobCount:r.length},`Attachments and blobs purged`),{purgedCount:r.length}}});export{n as purgeAttachment};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineAuthSchema as e}from"
|
|
1
|
+
import{defineAuthSchema as e}from"./api/auth-schema.mjs";import{defineScheduledWorkflow as t}from"./api/workflow.mjs";import{lt as n}from"drizzle-orm";const r=e();function i(e=`0 0 * * *`){return t({crontab:e,async run({container:e,step:t,scheduledTime:i}){let a=e.auth.auditLog?.retentionDays??90,o=new Date(i);o.setDate(o.getDate()-a);let s=o.toISOString(),c=await t(`delete-old-logs`,async()=>{let{auditLogs:t}=r.tables;return(await e.db.primary.delete(t).where(n(t.createdAt,s)).returning({id:t.id})).length});e.logger.info({deletedCount:c,retentionDays:a,cutoffDate:s},`Audit log purge completed`)}})}export{i as definePurgeAuditLogs};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineScheduledWorkflow as e}from"
|
|
1
|
+
import{defineScheduledWorkflow as e}from"./api/workflow.mjs";function t(t=`0 0 * * *`){return e({crontab:t,async run({container:e,step:t}){let n=new Date(Date.now()-2880*60*1e3).toISOString(),r=await t(`fetch-unattached-blobs`,async()=>e.storage.primary.getUnattachedBlobs({olderThan:n})),i=await t(`fetch-pending-blobs`,async()=>e.storage.primary.getPendingBlobs(n)),a=[...r,...i],o=0;for(let n of a)await t(`delete-blob`,async()=>{await e.storage.primary.deleteBlob(n.id),o++});e.logger.info({purgedCount:o,unattachedCount:r.length,pendingCount:i.length},`Orphaned blobs purged`)}})}export{t as definePurgeUnattachedBlobs};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { WorkflowHandle } from "./workflow.mjs";
|
|
2
|
-
import { Container } from "./container.mjs";
|
|
1
|
+
import { WorkflowHandle } from "./api/workflow.mjs";
|
|
2
|
+
import { Container } from "./api/container.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import * as _dbos_inc_dbos_sdk0 from "@dbos-inc/dbos-sdk";
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineAuthSchema as e}from"
|
|
1
|
+
import{defineAuthSchema as e}from"./api/auth-schema.mjs";import{dbChangesEvent as t}from"./api/event.mjs";import{defineWorkflow as n}from"./api/workflow.mjs";import{z as r}from"zod";const i=e(),a=r.object({changes:r.array(r.object({_table:r.string(),old:r.record(r.string(),r.unknown()).nullable(),new:r.record(r.string(),r.unknown()).nullable()})),dbName:r.string(),organizationId:r.string().nullable(),requestId:r.string(),sessionId:r.string().nullable(),userId:r.string().nullable()});function o(e){return e.old===null?`INSERT`:e.new===null?`DELETE`:`UPDATE`}const s=n({input:a,async run({container:e,step:n,input:r}){let{dbName:a,changes:s,organizationId:c,userId:l,sessionId:u,requestId:d}=r;if(s.length===0)return{processed:0,audited:0,published:0};let f=new Date().toISOString(),p=0,m=0;for(let r of s){let s=r._table,h=o(r),g=`${a}.${s}`;e.auth.shouldAudit(g)&&(await n(`audit:${g}`,async()=>{await e.db.primary.insert(i.tables.auditLogs).values({tableName:g,action:h,oldData:r.old,newData:r.new,organizationId:c,userId:l,sessionId:u,requestId:d,createdAt:f})}),p++),await n(`event:${g}`,async()=>{await t.emit({action:h,oldData:r.old,newData:r.new,organizationId:c,tableName:g,timestamp:f,userId:l})}),m++}return{processed:s.length,audited:p,published:m}}});export{s as trackDbChanges};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./redis.mjs";import{join as e}from"node:path";import{z as t}from"zod";import"es-toolkit";function n(e){let t=null,n=null;return{inputSchema:e.input,get name(){return n},register(e,r){t=e,n=r},async emit(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before emitting events.`);let i=e.input.parse(r),a={container:t,input:i};await e.run(a),t.eventBus.publish(n,i).catch(e=>{t.logger.error({err:e,event:n},`Redis publish failed`)})},async subscribe(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before subscribing.`);return t.eventBus.subscribe(n,async i=>{let a=e.input.parse(i),o={container:t,input:a};try{await r(o)}catch(e){t.logger.error({err:e,event:n},`Event subscription handler error`)}})}}}const r=n({input:t.object({action:t.enum([`INSERT`,`UPDATE`,`DELETE`]),newData:t.record(t.string(),t.unknown()).nullable(),oldData:t.record(t.string(),t.unknown()).nullable(),organizationId:t.string().nullable(),tableName:t.string(),timestamp:t.string(),userId:t.string().nullable()}),async run(){}});export{r as dbChangesEvent};
|
|
1
|
+
import"../constants.mjs";import"./redis.mjs";import{join as e}from"node:path";import{z as t}from"zod";import"es-toolkit";function n(e){let t=null,n=null;return{inputSchema:e.input,get name(){return n},register(e,r){t=e,n=r},async emit(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before emitting events.`);let i=e.input.parse(r),a={container:t,input:i};await e.run(a),t.eventBus.publish(n,i).catch(e=>{t.logger.error({err:e,event:n},`Redis publish failed`)})},async subscribe(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before subscribing.`);return t.eventBus.subscribe(n,async i=>{let a=e.input.parse(i),o={container:t,input:a};try{await r(o)}catch(e){t.logger.error({err:e,event:n},`Event subscription handler error`)}})}}}const r=n({input:t.object({action:t.enum([`INSERT`,`UPDATE`,`DELETE`]),newData:t.record(t.string(),t.unknown()).nullable(),oldData:t.record(t.string(),t.unknown()).nullable(),organizationId:t.string().nullable(),tableName:t.string(),timestamp:t.string(),userId:t.string().nullable()}),async run(){}});export{r as dbChangesEvent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as e}from"node:path";import"es-toolkit";function t(e){let t=null,n=null,r=null,i=null,a=async i=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let a=r,o=a.workflowID;if(!o)throw Error(`DBOS.workflowID is not available in this context`);let s={container:t,workflowId:o,input:i,step:(e,t)=>a.runStep(t,{name:e})};return e.run(s)};return{inputSchema:e.input,get name(){return n},register(o,s,c){t=o,n=s,r=c,i=c.registerWorkflow(a,{name:s,...e.config})},async start(t){if(!i||!n||!r)throw Error(`Workflow not registered. Ensure the worker is started before triggering workflows.`);let a=e.input.parse(t),o=await r.startWorkflow(i)(a);return{workflowId:o.workflowID,getStatus:()=>o.getStatus(),getResult:()=>o.getResult()}}}}function n(e){let t=null,n=null,r=null,i=async(i,a)=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let o=r,s=o.workflowID;if(!s)throw Error(`DBOS.workflowID is not available in this context`);let c={container:t,workflowId:s,scheduledTime:i,step:(e,t)=>o.runStep(t,{name:e})};return e.run(c)};return{crontab:e.crontab,get name(){return n},register(a,o,s){t=a,n=o,r=s,s.registerScheduled(s.registerWorkflow(i,{name:o}),{crontab:e.crontab})}}}export{n as defineScheduledWorkflow,t as defineWorkflow};
|
|
1
|
+
import"../constants.mjs";import{join as e}from"node:path";import"es-toolkit";function t(e){let t=null,n=null,r=null,i=null,a=async i=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let a=r,o=a.workflowID;if(!o)throw Error(`DBOS.workflowID is not available in this context`);let s={container:t,workflowId:o,input:i,step:(e,t)=>a.runStep(t,{name:e})};return e.run(s)};return{inputSchema:e.input,get name(){return n},register(o,s,c){t=o,n=s,r=c,i=c.registerWorkflow(a,{name:s,...e.config})},async start(t){if(!i||!n||!r)throw Error(`Workflow not registered. Ensure the worker is started before triggering workflows.`);let a=e.input.parse(t),o=await r.startWorkflow(i)(a);return{workflowId:o.workflowID,getStatus:()=>o.getStatus(),getResult:()=>o.getResult()}}}}function n(e){let t=null,n=null,r=null,i=async(i,a)=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let o=r,s=o.workflowID;if(!s)throw Error(`DBOS.workflowID is not available in this context`);let c={container:t,workflowId:s,scheduledTime:i,step:(e,t)=>o.runStep(t,{name:e})};return e.run(c)};return{crontab:e.crontab,get name(){return n},register(a,o,s){t=a,n=o,r=s,s.registerScheduled(s.registerWorkflow(i,{name:o}),{crontab:e.crontab})}}}export{n as defineScheduledWorkflow,t as defineWorkflow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as e}from"../workflow.mjs";import{join as t}from"node:path";import{ALL_FORMATS as n,BlobSource as r,Input as i}from"mediabunny";import a from"
|
|
1
|
+
import{defineWorkflow as e}from"../workflow.mjs";import{join as t}from"node:path";import{ALL_FORMATS as n,BlobSource as r,Input as i}from"mediabunny";import a from"zod";const o=e({input:a.object({blobId:a.string()}),async run({container:e,input:{blobId:a},step:o}){let s=await o(`fetch-blob`,async()=>e.storage.primary.getBlob(a));if(!s)throw Error(`Blob ${a} not found`);let c=await o(`download-blob`,async()=>e.storage.primary.downloadBlob(a));if(!c)throw Error(`Failed to download blob ${a}`);let l={};return s.contentType?.startsWith(`image/`)?l=await o(`extract-image-metadata`,async()=>{let e=(await import(`sharp`)).default,t=await e(c).metadata();return{width:t.width,height:t.height,format:t.format,hasAlpha:t.hasAlpha,space:t.space}}):s.contentType?.startsWith(`video/`)||s.contentType?.startsWith(`audio/`)?l=await o(`extract-media-metadata`,async()=>{let e=new Uint8Array(c),t=new i({source:new r(new Blob([e],{type:s.contentType||`video/mp4`})),formats:n}),a=await t.computeDuration(),o=await t.getMetadataTags(),l={},u={},d=!1,f=!1;try{let e=await t.getPrimaryVideoTrack();if(e){d=!0;let t=e.displayWidth&&e.displayHeight?e.displayWidth/e.displayHeight:null;l={width:e.displayWidth,height:e.displayHeight,rotation:e.rotation,angle:e.rotation,displayAspectRatio:t}}}catch{}try{let e=await t.getPrimaryAudioTrack();e&&(f=!0,u={sampleRate:e.sampleRate,channels:e.numberOfChannels})}catch{}return{duration:a,video:d,audio:f,...l,...u,tags:o}}):s.contentType===`application/pdf`&&(l=await o(`extract-pdf-metadata`,async()=>{try{let e=await import(`pdfjs-dist/legacy/build/pdf.mjs`),n=`${t(process.cwd(),`node_modules/pdfjs-dist/standard_fonts`)}/`,r=await e.getDocument({data:new Uint8Array(c),standardFontDataUrl:n}).promise,i=await r.getMetadata(),a=(await r.getPage(1)).getViewport({scale:1}),o=i.info;return{pageCount:r.numPages,width:a.width,height:a.height,title:o?.Title||null,author:o?.Author||null,subject:o?.Subject||null,keywords:o?.Keywords||null,creator:o?.Creator||null,producer:o?.Producer||null,creationDate:o?.CreationDate||null,modificationDate:o?.ModDate||null,pdfVersion:o?.PDFFormatVersion||null}}catch(t){return e.logger.error({error:t,errorMessage:t instanceof Error?t.message:String(t),errorStack:t instanceof Error?t.stack:void 0,errorCode:t?.code,blobId:a},`Failed to extract PDF metadata`),{error:`Failed to extract PDF metadata`,errorMessage:t instanceof Error?t.message:String(t)}}})),await o(`save-metadata`,async()=>{await e.storage.primary.updateBlobMetadata(a,{...l,analyzed:!0})}),e.logger.info({blobId:a,metadata:l},`Metadata extracted`),{...l,analyzed:!0}}});export{o as extractBlobMetadata};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as e}from"../workflow.mjs";import
|
|
1
|
+
import{defineWorkflow as e}from"../workflow.mjs";import{z as t}from"zod";const n=t.object({width:t.number().optional(),height:t.number().optional(),fit:t.enum([`cover`,`contain`,`fill`,`inside`,`outside`]).optional(),position:t.enum([`top`,`right top`,`right`,`right bottom`,`bottom`,`left bottom`,`left`,`left top`,`centre`]).optional(),kernel:t.enum([`nearest`,`linear`,`cubic`,`mitchell`,`lanczos2`,`lanczos3`]).optional()}),r=t.object({resize:n.optional(),rotate:t.number().optional(),flip:t.boolean().optional(),flop:t.boolean().optional(),sharpen:t.boolean().optional(),blur:t.number().optional(),grayscale:t.boolean().optional(),format:t.enum([`jpeg`,`png`,`webp`,`avif`,`gif`]).optional(),quality:t.number().min(1).max(100).optional(),preview:t.literal(!0).optional()}),i=e({input:t.object({blobId:t.string(),transformations:r}),async run({container:e,input:{blobId:t,transformations:n},step:r}){if(!await r(`fetch-blob`,async()=>e.storage.primary.getBlob(t)))throw Error(`Blob ${t} not found`);let i=await r(`download-blob`,async()=>e.storage.primary.downloadBlob(t));if(!i)throw Error(`Failed to download blob ${t}`);let a=await r(`apply-transformations`,async()=>{let e=(await import(`sharp`)).default,t=e(i);return n.resize&&(t=t.resize({width:n.resize.width,height:n.resize.height,fit:n.resize.fit,position:n.resize.position,kernel:n.resize.kernel})),n.rotate!==void 0&&(t=t.rotate(n.rotate)),n.flip&&(t=t.flip()),n.flop&&(t=t.flop()),n.sharpen&&(t=t.sharpen()),n.blur!==void 0&&(t=t.blur(n.blur)),n.grayscale&&(t=t.grayscale()),n.format&&(t=t.toFormat(n.format,{quality:n.quality})),t.toBuffer()}),o=await r(`store-variant`,async()=>e.storage.primary.createVariant(t,n,a));return e.logger.info({blobId:t,variantId:o.id},`Image variant generated`),o}});export{i as generateImageVariant};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as e}from"../workflow.mjs";import{join as t}from"node:path";import n from"
|
|
1
|
+
import{defineWorkflow as e}from"../workflow.mjs";import{join as t}from"node:path";import n from"zod";import{spawn as r}from"node:child_process";const i=e({input:n.object({blobId:n.string(),timeInSeconds:n.number().optional()}),async run({container:e,input:{blobId:n,timeInSeconds:i=1},step:a}){let o=await a(`fetch-blob`,async()=>e.storage.primary.getBlob(n));if(!o)throw Error(`Blob ${n} not found`);let s=await a(`download-blob`,async()=>e.storage.primary.downloadBlob(n));if(!s)throw Error(`Failed to download blob ${n}`);let c=null;if(o.contentType?.startsWith(`video/`))c=await a(`generate-video-preview`,async()=>new Promise((t,a)=>{try{let o=r(`ffmpeg`,[`-i`,`pipe:0`,`-ss`,i.toString(),`-frames:v`,`1`,`-f`,`image2pipe`,`-c:v`,`png`,`pipe:1`]),c=[],l=[];o.stdout.on(`data`,e=>{c.push(e)}),o.stderr.on(`data`,e=>{l.push(e)}),o.on(`close`,async r=>{if(r===0)try{let e=Buffer.concat(c),n=(await import(`sharp`)).default;t(await n(e).jpeg({quality:80}).toBuffer())}catch(t){e.logger.error({error:t,blobId:n},`Failed to convert video frame to JPEG`),a(t)}else{let t=Buffer.concat(l).toString(),i=Error(`FFmpeg exited with code ${r}: ${t}`);e.logger.error({error:i,blobId:n,code:r,stderr:t},`Failed to generate video preview`),a(i)}}),o.on(`error`,t=>{e.logger.error({error:t,blobId:n},`Failed to spawn FFmpeg process`),a(t)}),o.stdin.on(`error`,t=>{t.code!==`EPIPE`&&e.logger.error({error:t,blobId:n},`Failed to write to FFmpeg stdin`)}),o.stdin.write(s),o.stdin.end()}catch(t){e.logger.error({error:t,blobId:n},`Failed to generate video preview`),a(t)}}));else if(o.contentType===`application/pdf`)c=await a(`generate-pdf-preview`,async()=>{try{let e=await import(`pdfjs-dist/legacy/build/pdf.mjs`),{createCanvas:n}=await import(`canvas`),r=(await import(`sharp`)).default,i=`${t(process.cwd(),`node_modules/pdfjs-dist/standard_fonts`)}/`,a=await(await e.getDocument({data:new Uint8Array(s),standardFontDataUrl:i}).promise).getPage(1),o=a.getViewport({scale:2}),c=n(o.width,o.height),l=c.getContext(`2d`);return await a.render({canvasContext:l,viewport:o,canvas:c}).promise,await r(c.toBuffer(`image/png`)).resize(800,800,{fit:`inside`,withoutEnlargement:!0}).jpeg({quality:85}).toBuffer()}catch(t){throw e.logger.error({error:t,errorMessage:t instanceof Error?t.message:String(t),errorStack:t instanceof Error?t.stack:void 0,errorCode:t?.code,blobId:n},`Failed to generate PDF preview`),t}});else if(o.contentType?.startsWith(`image/`))c=await a(`generate-image-preview`,async()=>{let e=(await import(`sharp`)).default;return await e(s).resize(800,800,{fit:`inside`,withoutEnlargement:!0}).jpeg({quality:85}).toBuffer()});else throw Error(`Preview generation not supported for content type: ${o.contentType}`);let l=await a(`store-preview`,async()=>await e.storage.primary.createVariant(n,{preview:!0},c));return e.logger.info({blobId:n,previewId:l.id,contentType:o.contentType},`Preview generated`),l}});export{i as generatePreview};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
process.env.NODE_ENV;export{};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"better-auth/node";export{};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../constants.mjs";import"./redis.mjs";import{glob as e}from"node:fs/promises";import{basename as t,join as n}from"node:path";import{camelCase as r}from"es-toolkit";import{z as i}from"zod";function a(e){let t=null,n=null;return{inputSchema:e.input,get name(){return n},register(e,r){t=e,n=r},async emit(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before emitting events.`);let i=e.input.parse(r),a={container:t,input:i};await e.run(a),t.eventBus.publish(n,i).catch(e=>{t.logger.error({err:e,event:n},`Redis publish failed`)})},async subscribe(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before subscribing.`);return t.eventBus.subscribe(n,async i=>{let a=e.input.parse(i),o={container:t,input:a};try{await r(o)}catch(e){t.logger.error({err:e,event:n},`Event subscription handler error`)}})}}}const o=a({input:i.object({action:i.enum([`INSERT`,`UPDATE`,`DELETE`]),newData:i.record(i.string(),i.unknown()).nullable(),oldData:i.record(i.string(),i.unknown()).nullable(),organizationId:i.string().nullable(),tableName:i.string(),timestamp:i.string(),userId:i.string().nullable()}),async run(){}});export{o as dbChangesEvent};
|
|
@@ -13,14 +13,14 @@ import { AppContext, DefineAppContextOpts, SessionData, defineAppContext } from
|
|
|
13
13
|
import { defineAuthSchema } from "./auth-schema.mjs";
|
|
14
14
|
import { I18nInitOptions, defaultI18nOptions, defineI18n, i18n as i18n$1 } from "./i18n.mjs";
|
|
15
15
|
import { Middleware, defineMiddleware, loadMiddleware } from "./middleware.mjs";
|
|
16
|
-
import { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse,
|
|
16
|
+
import { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineTypedResponses, generateOpenAPIDocument, loadAndRegisterAPIRoutes, registerRoutes, scanAPIRoutes, writeOpenAPISpecs } from "./openapi.mjs";
|
|
17
17
|
import { withOtelSpan } from "./otel.mjs";
|
|
18
18
|
import { DefineRedisClientOptions, RedisClient, defineRedisClient } from "./redis.mjs";
|
|
19
19
|
import { CustomTypeOptions } from "i18next";
|
|
20
20
|
|
|
21
21
|
//#region src/api/index.d.ts
|
|
22
22
|
declare namespace index_d_exports {
|
|
23
|
-
export { AccessControlRoles, AccessController, AppContainer, AppContext, AuditAction, Auth, AuthConfig, AuthPasskeyConfig, AuthSessionConfig, Cache, Config, Container, CustomTypeOptions, Database, DatabaseWithStorage, DbChangeInput, DefineAppContextOpts, DefineAuthOptions, DefineCacheOptions, DefineDatabaseOptions, DefineEventBusOptions, DefineLoggerOptions, DefineMailerOptions, DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, DefineRedisClientOptions, DefineS3DiskOptions, DefineStorageOptions, DefineTestDatabaseOptions, Event, EventBus, EventContext, HandlerParams, I18nInitOptions, Logger, Mailer, MailerPayload, MailerPayloadHtml, MailerPayloadReact, Middleware, MigrationType, NewStorageAttachment, NewStorageBlob, NewStorageVariantRecord, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, QualifiedTableNames, RedisClient, Role, RouteModule, ScheduledWorkflowContext, ServerConfig, SessionData, Storage, StorageAttachment, StorageBlob, StorageRelations, StorageRelationsConfig, StorageService, StorageTables, StorageVariantRecord, ValidationErrorResponse, WorkerConfig, WorkflowContext, WorkflowHandle,
|
|
23
|
+
export { AccessControlRoles, AccessController, AppContainer, AppContext, AuditAction, Auth, AuthConfig, AuthPasskeyConfig, AuthSessionConfig, Cache, Config, Container, CustomTypeOptions, Database, DatabaseWithStorage, DbChangeInput, DefineAppContextOpts, DefineAuthOptions, DefineCacheOptions, DefineDatabaseOptions, DefineEventBusOptions, DefineLoggerOptions, DefineMailerOptions, DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, DefineRedisClientOptions, DefineS3DiskOptions, DefineStorageOptions, DefineTestDatabaseOptions, Event, EventBus, EventContext, HandlerParams, I18nInitOptions, Logger, Mailer, MailerPayload, MailerPayloadHtml, MailerPayloadReact, Middleware, MigrationType, NewStorageAttachment, NewStorageBlob, NewStorageVariantRecord, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, QualifiedTableNames, RedisClient, Role, RouteModule, ScheduledWorkflowContext, ServerConfig, SessionData, Storage, StorageAttachment, StorageBlob, StorageRelations, StorageRelationsConfig, StorageService, StorageTables, StorageVariantRecord, ValidationErrorResponse, WorkerConfig, WorkflowContext, WorkflowHandle, auditActionSchema, baseSchema, createAccessControl, dbChangeInputSchema, dbChanges, dbChangesEvent, defaultI18nOptions, defineAppContainer, defineAppContext, defineAuth, defineAuthSchema, defineCache, defineConfig, defineDatabase, defineEvent, defineEventBus, defineI18n, defineLogger, defineMailer, defineMiddleware, defineMigrationOpts, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineRedisClient, defineS3Disk, defineScheduledWorkflow, defineStorage, defineStorageSchema, defineTestDatabase, defineTypedResponses, defineWorkflow, generateOpenAPIDocument, i18n$1 as i18n, loadAndRegisterAPIRoutes, loadEvents, loadMiddleware, loadWorkflows, migrationsSchema, registerRoutes, scanAPIRoutes, withOtelSpan, writeOpenAPISpecs };
|
|
24
24
|
}
|
|
25
25
|
//#endregion
|
|
26
26
|
export { index_d_exports };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{FILE_EXT as e}from"../constants.mjs";import t,{glob as n}from"node:fs/promises";import{basename as r}from"node:path";import{camelCase as i}from"es-toolkit";function a(e){return i(r(e,`.ts`).replace(/^\d+_/,``))}async function o(i,o,s){try{await t.access(i)}catch{return}let c=[];for await(let t of n(`${i}/**/*.${e}`))!t.endsWith(`.test.ts`)&&!t.endsWith(`.spec.ts`)&&!t.endsWith(`.test.js`)&&!t.endsWith(`.spec.js`)&&c.push(t);c.sort((e,t)=>r(e).localeCompare(r(t)));for(let e of c)try{let t=(await import(e)).default;if(t&&typeof t.handler==`function`){let n=t.name??a(e);o.logger.debug({name:n,file:e},`Loading user middleware`),s.use(t.handler(o))}else o.logger.warn({file:e},`Middleware file missing default export with handler function`)}catch(t){throw o.logger.error({file:e,error:t instanceof Error?t.message:t},`Failed to load middleware`),t}}export{o as loadMiddleware};
|
|
@@ -5,7 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
import * as _node_modules_zod_openapi_dist_components_B1DX_zYv_mjs0 from "#node_modules/zod-openapi/dist/components-B1DX_zYv.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/api/openapi.d.ts
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
/**
|
|
10
10
|
* Utility type to enforce exact type matching (no extra properties).
|
|
11
11
|
* This uses a tuple check to prevent objects with extra keys from being assigned.
|
|
@@ -268,4 +268,4 @@ declare function writeOpenAPISpecs<TContainer extends Container>(container: TCon
|
|
|
268
268
|
*/
|
|
269
269
|
declare function loadAndRegisterAPIRoutes<TContainer extends Container>(app: Express): Promise<void>;
|
|
270
270
|
//#endregion
|
|
271
|
-
export { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse,
|
|
271
|
+
export { DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, HandlerParams, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, RouteModule, ValidationErrorResponse, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineTypedResponses, generateOpenAPIDocument, loadAndRegisterAPIRoutes, registerRoutes, scanAPIRoutes, writeOpenAPISpecs };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{APPOS_DIR as e,FILE_EXT as t,PUBLIC_DIR as n,ROUTES_DIR as r}from"../constants.mjs";import"./app-context.mjs";import{access as i,mkdir as a,writeFile as o}from"node:fs/promises";import{join as s,resolve as c}from"node:path";import{remixRoutesOptionAdapter as l}from"@react-router/remix-routes-option-adapter";import{isEmpty as u}from"es-toolkit/compat";import{flatRoutes as d}from"remix-flat-routes";import{z as f}from"zod";import{createDocument as p}from"zod-openapi";const m=c(n,`openapi`);function h(e){return e.match(/^\/(v\d+)/)?.[1]}function g(e){return e.replace(/:(\w+)/g,`{$1}`)}function _(e,t){let n=g(e),r={summary:t.summary,description:t.description};(t.request?.params||t.request?.query||t.request?.headers)&&(r.requestParams={},t.request.params&&(r.requestParams.path=t.request.params),t.request.query&&(r.requestParams.query=t.request.query),t.request.headers&&(r.requestParams.header=t.request.headers)),t.request?.body&&(r.requestBody={content:{"application/json":{schema:t.request.body}}}),r.responses={};for(let[e,n]of Object.entries(t.responses))r.responses[e]={description:n.description,content:{"application/json":{schema:n.content[`application/json`].schema}}};return{path:n,config:r}}function v(e,t,n){let r={};for(let n of e){if(n.version!==t)continue;let e=n.path.replace(`/${t}`,``)||`/`;for(let t of n.openAPISpec){let{path:n,config:i}=_(e,t);r[n]||(r[n]={}),r[n][t.method]=i}}return p({openapi:`3.1.0`,info:n?.info||{title:`API ${t.toUpperCase()}`,version:t.replace(`v`,``),description:`OpenAPI specification for ${t} API`},servers:n?.servers||[{url:`http://localhost:8000/${t}`,description:process.env.NODE_ENV===`production`?`Production server`:`Development server`}],paths:r})}async function y(t){let n=c(e,r);try{await i(n)}catch(e){return t.logger.error({error:e},`OpenAPI routes directory not found`),[]}let a=await l(t=>d(r,t,{appDir:e,ignoredRouteFiles:[`**/.*`,`**/*.{spec,test}.{ts,tsx}`,`**/*-????????.{js,ts}`]})),o=[];for(let[n,r]of Object.entries(a)){let n=c(e,r.file).replace(/.ts$/,process.env.NODE_ENV===`production`?`.js`:`.ts`);try{let i=(await import(n)).default;if(!i||u(i)||/\/openapi.(j|t)s$/.test(n))continue;if(!i?.handlers&&!i?.openAPISpec){t.logger.warn(`Missing default export with 'defineOpenAPI' for '${e}/${r.file}'`);continue}let a=`/${r.path}`;o.push({path:a,filePath:n,handlers:i.handlers,openAPISpec:i.openAPISpec,version:h(a)})}catch(e){t.logger.error(e,`Error loading route ${r.file}:`)}}return o}function b(e,t){for(let n of t)for(let[t,r]of Object.entries(n.handlers))e[t.toLowerCase()](n.path,r)}async function x(n,i){let a=c(e,r,`${i}+/openapi.${t}`);try{let e=(await import(a)).default;return e?e(n):void 0}catch{return}}async function S(e,t){let n=[...new Set(t.map(e=>e.version).filter(Boolean))];n.length>0&&await a(m,{recursive:!0});for(let r of n){let n=v(t,r,await x(e,r));await o(s(m,`${r}.json`),JSON.stringify(n,null,2),`utf-8`)}}async function C(e){let t=await y(e.locals.container);b(e,t),process.env.NODE_ENV!==`production`&&await S(e.locals.container,t)}export{C as loadAndRegisterAPIRoutes};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __export, __reExport } from "
|
|
1
|
+
import { __export, __reExport } from "../_virtual/rolldown_runtime.mjs";
|
|
2
2
|
import { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable as pgTable$1, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas } from "drizzle-orm/pg-core";
|
|
3
3
|
export * from "drizzle-orm";
|
|
4
4
|
export * from "drizzle-seed";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{PUBLIC_DIR as e}from"../constants.mjs";import{defineErrorHandlerMiddleware as t}from"./middleware/error-handler.mjs";import{defineHealthMiddleware as n}from"./middleware/health.mjs";import{defineI18nMiddleware as r}from"./middleware/i18n.mjs";import{defineRequestLoggerMiddleware as i}from"./middleware/request-logger.mjs";import{defineShutdownMiddleware as a}from"./middleware/shutdown.mjs";import{defineTimeoutMiddleware as o}from"./middleware/timeout.mjs";import{loadMiddleware as s}from"./middleware.mjs";import{loadAndRegisterAPIRoutes as c}from"./openapi.mjs";import{join as l,resolve as u}from"node:path";import{toNodeHandler as d}from"better-auth/node";import f from"cors";import{rateLimit as p}from"express-rate-limit";import m from"helmet";import{RedisStore as h}from"rate-limit-redis";import{createClient as g}from"redis";import _ from"ultimate-express";async function v({container:v}){let y=!1,{host:b=`0.0.0.0`,port:x,timeout:S=3e4,bodyLimit:C=`1mb`,healthPath:w=`/health`,cors:T,helmet:E,rateLimit:D,redisUrl:O}=v.server,k=_();k.locals.container=v;let A=null;if(O&&D)try{A=g({url:O}),A.on(`error`,e=>{v.logger.error({error:e.message},`Redis client error`)}),await A.connect(),v.logger.info(`Connected to Redis for rate limiting`)}catch(e){v.logger.error({error:e instanceof Error?e.message:e},`Failed to connect to Redis, falling back to in-memory rate limiting`),A=null}if(k.use(a(v.logger,()=>y),o(v.logger,S),i(v.logger),n(w)),E!==void 0&&k.use(m(E)),T!==void 0&&k.use(f(T)),D)for(let[e,t]of D.entries()){let n=p({windowMs:t.windowMs??60*1e3,limit:t.limit??100,standardHeaders:t.standardHeaders??`draft-8`,legacyHeaders:t.legacyHeaders??!1,skip:t.skip,keyGenerator:t.keyGenerator,handler:t.handler,message:t.message,statusCode:t.statusCode,requestPropertyName:t.requestPropertyName,skipFailedRequests:t.skipFailedRequests,skipSuccessfulRequests:t.skipSuccessfulRequests,requestWasSuccessful:t.requestWasSuccessful,validate:t.validate,store:A?new h({sendCommand:(...e)=>A.sendCommand(e),prefix:`rl:${e}:`}):t.store});k.use(n)}if(k.use(r(v.i18n),_.json({limit:C}),_.urlencoded({extended:!0,limit:C})),await s(l(process.cwd(),`api`,`middleware`),v,k),k.get(`/`,(e,t)=>{t.json({message:`${v.config.APP_NAME} server is running.`})}).all(`${v.auth.options.basePath}/*`,d(v.auth)),await c(k),k.use(_.static(u(e))),process.env.NODE_ENV!==`production`){let{defineYouchErrorHandler:e}=await import(`./middleware/youch-handler.mjs`);k.use(e(v.logger))}else k.use(t(v.logger));return{app:k,host:b,port:x,async start(){await new Promise((e,t)=>{try{k.listen(x,b,()=>{e()})}catch(e){t(e)}})},async close(){if(y=!0,k.uwsApp.close(),A)try{await A.destroy()}catch(e){v.logger.warn({error:e instanceof Error?e.message:e},`Error disconnecting from Redis`)}}}}export{v as defineServer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../constants.mjs";import{glob as e}from"node:fs/promises";import{basename as t,join as n}from"node:path";import{camelCase as r}from"es-toolkit";function i(e){let t=null,n=null,r=null,i=null,a=async i=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let a=r,o=a.workflowID;if(!o)throw Error(`DBOS.workflowID is not available in this context`);let s={container:t,workflowId:o,input:i,step:(e,t)=>a.runStep(t,{name:e})};return e.run(s)};return{inputSchema:e.input,get name(){return n},register(o,s,c){t=o,n=s,r=c,i=c.registerWorkflow(a,{name:s,...e.config})},async start(t){if(!i||!n||!r)throw Error(`Workflow not registered. Ensure the worker is started before triggering workflows.`);let a=e.input.parse(t),o=await r.startWorkflow(i)(a);return{workflowId:o.workflowID,getStatus:()=>o.getStatus(),getResult:()=>o.getResult()}}}}function a(e){let t=null,n=null,r=null,i=async(i,a)=>{if(!t||!r)throw Error(`Workflow "${n}" not registered`);let o=r,s=o.workflowID;if(!s)throw Error(`DBOS.workflowID is not available in this context`);let c={container:t,workflowId:s,scheduledTime:i,step:(e,t)=>o.runStep(t,{name:e})};return e.run(c)};return{crontab:e.crontab,get name(){return n},register(a,o,s){t=a,n=o,r=s,s.registerScheduled(s.registerWorkflow(i,{name:o}),{crontab:e.crontab})}}}export{a as defineScheduledWorkflow,i as defineWorkflow};
|