@m5kdev/backend 0.8.6 → 0.8.8
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/_virtual/_rolldown/runtime.cjs +33 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/api/index.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/factory.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/get-field-attributes.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/get-id-field.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/index.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/types.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/get-tables.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/index.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/account.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/rate-limit.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/session.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/shared.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/user.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/verification.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/index.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/social-providers/index.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/context.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/helper.d.cts +7 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/init-options.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/plugin-client.d.cts +1 -0
- package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/plugin.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/dialect-adapter-base.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/dialect-adapter.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/dialect.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mssql/mssql-adapter.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mssql/mssql-dialect.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mssql/mssql-introspector.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mysql/mysql-adapter.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mysql/mysql-dialect.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mysql/mysql-introspector.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-adapter.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-dialect.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-introspector.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/expression/expression-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/index.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/kysely.d.cts +38 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/migration/file-migration-provider.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/migration/migrator.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/binary-operation-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/delete-from-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/expression-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/group-by-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/insert-values-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/join-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/merge-into-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/reference-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/returning-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/select-from-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/select-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/set-operation-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/tuple-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/unary-operation-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/update-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/update-set-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/value-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/with-parser.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/case-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/delete-query-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/having-interface.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/insert-query-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/join-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/merge-query-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/on-conflict-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/output-interface.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/returning-interface.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/select-query-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/update-query-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/where-interface.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-creator.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/default-query-executor.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/noop-query-executor.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/query-executor-base.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/query-executor-provider.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/query-executor.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/raw-builder/raw-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/raw-builder/sql.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-add-foreign-key-constraint-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-add-index-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-drop-constraint-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-executor.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-index-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-schema-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-table-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-type-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-view-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-index-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-schema-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-table-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-type-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-view-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/refresh-materialized-view-builder.d.cts +1 -0
- package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/schema.d.cts +1 -0
- package/dist/src/lib/posthog.cjs +8 -0
- package/dist/src/lib/posthog.cjs.map +1 -0
- package/dist/src/lib/posthog.d.cts +7 -0
- package/dist/src/lib/sentry.cjs +11 -0
- package/dist/src/lib/sentry.cjs.map +1 -0
- package/dist/src/lib/sentry.d.cts +1 -0
- package/dist/src/modules/access/access.repository.cjs +26 -0
- package/dist/src/modules/access/access.repository.cjs.map +1 -0
- package/dist/src/modules/access/access.repository.d.cts +2352 -0
- package/dist/src/modules/access/access.service.cjs +42 -0
- package/dist/src/modules/access/access.service.cjs.map +1 -0
- package/dist/src/modules/access/access.service.d.cts +25 -0
- package/dist/src/modules/access/access.utils.cjs +23 -0
- package/dist/src/modules/access/access.utils.cjs.map +1 -0
- package/dist/src/modules/access/access.utils.d.cts +19 -0
- package/dist/src/modules/ai/ai.db.cjs +46 -0
- package/dist/src/modules/ai/ai.db.cjs.map +1 -0
- package/dist/src/modules/ai/ai.db.d.cts +401 -0
- package/dist/src/modules/ai/ai.prompt.cjs +33 -0
- package/dist/src/modules/ai/ai.prompt.cjs.map +1 -0
- package/dist/src/modules/ai/ai.prompt.d.cts +30 -0
- package/dist/src/modules/ai/ai.prompts.cjs +18 -0
- package/dist/src/modules/ai/ai.prompts.cjs.map +1 -0
- package/dist/src/modules/ai/ai.prompts.d.cts +10 -0
- package/dist/src/modules/ai/ai.repository.cjs +25 -0
- package/dist/src/modules/ai/ai.repository.cjs.map +1 -0
- package/dist/src/modules/ai/ai.repository.d.cts +428 -0
- package/dist/src/modules/ai/ai.router.cjs +0 -0
- package/dist/src/modules/ai/ai.router.d.cts +1 -0
- package/dist/src/modules/ai/ai.service.cjs +312 -0
- package/dist/src/modules/ai/ai.service.cjs.map +1 -0
- package/dist/src/modules/ai/ai.service.d.cts +141 -0
- package/dist/src/modules/ai/ai.trpc.cjs +19 -0
- package/dist/src/modules/ai/ai.trpc.cjs.map +1 -0
- package/dist/src/modules/ai/ai.trpc.d.cts +31 -0
- package/dist/src/modules/ai/ideogram/ideogram.constants.cjs +191 -0
- package/dist/src/modules/ai/ideogram/ideogram.constants.cjs.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.constants.d.cts +11 -0
- package/dist/src/modules/ai/ideogram/ideogram.dto.cjs +49 -0
- package/dist/src/modules/ai/ideogram/ideogram.dto.cjs.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.dto.d.cts +234 -0
- package/dist/src/modules/ai/ideogram/ideogram.prompt.cjs +862 -0
- package/dist/src/modules/ai/ideogram/ideogram.prompt.cjs.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.prompt.d.cts +7 -0
- package/dist/src/modules/ai/ideogram/ideogram.repository.cjs +34 -0
- package/dist/src/modules/ai/ideogram/ideogram.repository.cjs.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.repository.d.cts +11 -0
- package/dist/src/modules/ai/ideogram/ideogram.service.cjs +12 -0
- package/dist/src/modules/ai/ideogram/ideogram.service.cjs.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.service.d.cts +14 -0
- package/dist/src/modules/auth/auth.db.cjs +187 -0
- package/dist/src/modules/auth/auth.db.cjs.map +1 -0
- package/dist/src/modules/auth/auth.db.d.cts +2341 -0
- package/dist/src/modules/auth/auth.dto.cjs +50 -0
- package/dist/src/modules/auth/auth.dto.cjs.map +1 -0
- package/dist/src/modules/auth/auth.dto.d.cts +70 -0
- package/dist/src/modules/auth/auth.lib.cjs +234 -0
- package/dist/src/modules/auth/auth.lib.cjs.map +1 -0
- package/dist/src/modules/auth/auth.lib.d.cts +4894 -0
- package/dist/src/modules/auth/auth.middleware.cjs +41 -0
- package/dist/src/modules/auth/auth.middleware.cjs.map +1 -0
- package/dist/src/modules/auth/auth.middleware.d.cts +619 -0
- package/dist/src/modules/auth/auth.repository.cjs +403 -0
- package/dist/src/modules/auth/auth.repository.cjs.map +1 -0
- package/dist/src/modules/auth/auth.repository.d.cts +2453 -0
- package/dist/src/modules/auth/auth.service.cjs +229 -0
- package/dist/src/modules/auth/auth.service.cjs.map +1 -0
- package/dist/src/modules/auth/auth.service.d.cts +105 -0
- package/dist/src/modules/auth/auth.trpc.cjs +110 -0
- package/dist/src/modules/auth/auth.trpc.cjs.map +1 -0
- package/dist/src/modules/auth/auth.trpc.d.cts +303 -0
- package/dist/src/modules/auth/auth.utils.cjs +80 -0
- package/dist/src/modules/auth/auth.utils.cjs.map +1 -0
- package/dist/src/modules/auth/auth.utils.d.cts +2356 -0
- package/dist/src/modules/base/base.abstract.cjs +62 -0
- package/dist/src/modules/base/base.abstract.cjs.map +1 -0
- package/dist/src/modules/base/base.abstract.d.cts +29 -0
- package/dist/src/modules/base/base.actor.cjs +83 -0
- package/dist/src/modules/base/base.actor.cjs.map +1 -0
- package/dist/src/modules/base/base.actor.d.cts +73 -0
- package/dist/src/modules/base/base.dto.cjs +98 -0
- package/dist/src/modules/base/base.dto.cjs.map +1 -0
- package/dist/src/modules/base/base.dto.d.cts +67 -0
- package/dist/src/modules/base/base.grants.cjs +107 -0
- package/dist/src/modules/base/base.grants.cjs.map +1 -0
- package/dist/src/modules/base/base.grants.d.cts +28 -0
- package/dist/src/modules/base/base.procedure.cjs +255 -0
- package/dist/src/modules/base/base.procedure.cjs.map +1 -0
- package/dist/src/modules/base/base.procedure.d.cts +111 -0
- package/dist/src/modules/base/base.repository.cjs +269 -0
- package/dist/src/modules/base/base.repository.cjs.map +1 -0
- package/dist/src/modules/base/base.repository.d.cts +125 -0
- package/dist/src/modules/base/base.repository.d.mts +2 -0
- package/dist/src/modules/base/base.repository.mjs +12 -0
- package/dist/src/modules/base/base.repository.mjs.map +1 -1
- package/dist/src/modules/base/base.service.cjs +119 -0
- package/dist/src/modules/base/base.service.cjs.map +1 -0
- package/dist/src/modules/base/base.service.d.cts +44 -0
- package/dist/src/modules/base/base.types.cjs +0 -0
- package/dist/src/modules/base/base.types.d.cts +5 -0
- package/dist/src/modules/billing/billing.db.cjs +38 -0
- package/dist/src/modules/billing/billing.db.cjs.map +1 -0
- package/dist/src/modules/billing/billing.db.d.cts +371 -0
- package/dist/src/modules/billing/billing.repository.cjs +190 -0
- package/dist/src/modules/billing/billing.repository.cjs.map +1 -0
- package/dist/src/modules/billing/billing.repository.d.cts +2787 -0
- package/dist/src/modules/billing/billing.repository.d.mts +11 -11
- package/dist/src/modules/billing/billing.router.cjs +43 -0
- package/dist/src/modules/billing/billing.router.cjs.map +1 -0
- package/dist/src/modules/billing/billing.router.d.cts +9 -0
- package/dist/src/modules/billing/billing.service.cjs +127 -0
- package/dist/src/modules/billing/billing.service.cjs.map +1 -0
- package/dist/src/modules/billing/billing.service.d.cts +53 -0
- package/dist/src/modules/billing/billing.service.d.mts +7 -7
- package/dist/src/modules/billing/billing.trpc.cjs +19 -0
- package/dist/src/modules/billing/billing.trpc.cjs.map +1 -0
- package/dist/src/modules/billing/billing.trpc.d.cts +48 -0
- package/dist/src/modules/clay/clay.repository.cjs +29 -0
- package/dist/src/modules/clay/clay.repository.cjs.map +1 -0
- package/dist/src/modules/clay/clay.repository.d.cts +10 -0
- package/dist/src/modules/clay/clay.service.cjs +24 -0
- package/dist/src/modules/clay/clay.service.cjs.map +1 -0
- package/dist/src/modules/clay/clay.service.d.cts +32 -0
- package/dist/src/modules/connect/connect.db.cjs +37 -0
- package/dist/src/modules/connect/connect.db.cjs.map +1 -0
- package/dist/src/modules/connect/connect.db.d.cts +362 -0
- package/dist/src/modules/connect/connect.dto.cjs +45 -0
- package/dist/src/modules/connect/connect.dto.cjs.map +1 -0
- package/dist/src/modules/connect/connect.dto.d.cts +79 -0
- package/dist/src/modules/connect/connect.linkedin.cjs +48 -0
- package/dist/src/modules/connect/connect.linkedin.cjs.map +1 -0
- package/dist/src/modules/connect/connect.linkedin.d.cts +7 -0
- package/dist/src/modules/connect/connect.oauth.cjs +153 -0
- package/dist/src/modules/connect/connect.oauth.cjs.map +1 -0
- package/dist/src/modules/connect/connect.oauth.d.cts +32 -0
- package/dist/src/modules/connect/connect.repository.cjs +42 -0
- package/dist/src/modules/connect/connect.repository.cjs.map +1 -0
- package/dist/src/modules/connect/connect.repository.d.cts +419 -0
- package/dist/src/modules/connect/connect.router.cjs +48 -0
- package/dist/src/modules/connect/connect.router.cjs.map +1 -0
- package/dist/src/modules/connect/connect.router.d.cts +9 -0
- package/dist/src/modules/connect/connect.service.cjs +90 -0
- package/dist/src/modules/connect/connect.service.cjs.map +1 -0
- package/dist/src/modules/connect/connect.service.d.cts +103 -0
- package/dist/src/modules/connect/connect.trpc.cjs +18 -0
- package/dist/src/modules/connect/connect.trpc.cjs.map +1 -0
- package/dist/src/modules/connect/connect.trpc.d.cts +53 -0
- package/dist/src/modules/connect/connect.types.cjs +0 -0
- package/dist/src/modules/connect/connect.types.d.cts +29 -0
- package/dist/src/modules/crypto/crypto.db.cjs +26 -0
- package/dist/src/modules/crypto/crypto.db.cjs.map +1 -0
- package/dist/src/modules/crypto/crypto.db.d.cts +157 -0
- package/dist/src/modules/crypto/crypto.repository.cjs +9 -0
- package/dist/src/modules/crypto/crypto.repository.cjs.map +1 -0
- package/dist/src/modules/crypto/crypto.repository.d.cts +163 -0
- package/dist/src/modules/crypto/crypto.service.cjs +46 -0
- package/dist/src/modules/crypto/crypto.service.cjs.map +1 -0
- package/dist/src/modules/crypto/crypto.service.d.cts +15 -0
- package/dist/src/modules/email/email.service.cjs +107 -0
- package/dist/src/modules/email/email.service.cjs.map +1 -0
- package/dist/src/modules/email/email.service.d.cts +62 -0
- package/dist/src/modules/file/file.repository.cjs +74 -0
- package/dist/src/modules/file/file.repository.cjs.map +1 -0
- package/dist/src/modules/file/file.repository.d.cts +17 -0
- package/dist/src/modules/file/file.router.cjs +94 -0
- package/dist/src/modules/file/file.router.cjs.map +1 -0
- package/dist/src/modules/file/file.router.d.cts +7 -0
- package/dist/src/modules/file/file.service.cjs +120 -0
- package/dist/src/modules/file/file.service.cjs.map +1 -0
- package/dist/src/modules/file/file.service.d.cts +30 -0
- package/dist/src/modules/recurrence/recurrence.db.cjs +55 -0
- package/dist/src/modules/recurrence/recurrence.db.cjs.map +1 -0
- package/dist/src/modules/recurrence/recurrence.db.d.cts +568 -0
- package/dist/src/modules/recurrence/recurrence.repository.cjs +31 -0
- package/dist/src/modules/recurrence/recurrence.repository.cjs.map +1 -0
- package/dist/src/modules/recurrence/recurrence.repository.d.cts +588 -0
- package/dist/src/modules/recurrence/recurrence.service.cjs +66 -0
- package/dist/src/modules/recurrence/recurrence.service.cjs.map +1 -0
- package/dist/src/modules/recurrence/recurrence.service.d.cts +88 -0
- package/dist/src/modules/recurrence/recurrence.service.d.mts +2 -1
- package/dist/src/modules/recurrence/recurrence.service.mjs +1 -1
- package/dist/src/modules/recurrence/recurrence.service.mjs.map +1 -1
- package/dist/src/modules/recurrence/recurrence.trpc.cjs +46 -0
- package/dist/src/modules/recurrence/recurrence.trpc.cjs.map +1 -0
- package/dist/src/modules/recurrence/recurrence.trpc.d.cts +216 -0
- package/dist/src/modules/recurrence/recurrence.trpc.d.mts +2 -1
- package/dist/src/modules/social/social.dto.cjs +26 -0
- package/dist/src/modules/social/social.dto.cjs.map +1 -0
- package/dist/src/modules/social/social.dto.d.cts +39 -0
- package/dist/src/modules/social/social.linkedin.cjs +349 -0
- package/dist/src/modules/social/social.linkedin.cjs.map +1 -0
- package/dist/src/modules/social/social.linkedin.d.cts +15 -0
- package/dist/src/modules/social/social.service.cjs +57 -0
- package/dist/src/modules/social/social.service.cjs.map +1 -0
- package/dist/src/modules/social/social.service.d.cts +34 -0
- package/dist/src/modules/social/social.types.cjs +0 -0
- package/dist/src/modules/social/social.types.d.cts +40 -0
- package/dist/src/modules/tag/tag.db.cjs +43 -0
- package/dist/src/modules/tag/tag.db.cjs.map +1 -0
- package/dist/src/modules/tag/tag.db.d.cts +352 -0
- package/dist/src/modules/tag/tag.dto.cjs +15 -0
- package/dist/src/modules/tag/tag.dto.cjs.map +1 -0
- package/dist/src/modules/tag/tag.dto.d.cts +1025 -0
- package/dist/src/modules/tag/tag.repository.cjs +116 -0
- package/dist/src/modules/tag/tag.repository.cjs.map +1 -0
- package/dist/src/modules/tag/tag.repository.d.cts +394 -0
- package/dist/src/modules/tag/tag.service.cjs +48 -0
- package/dist/src/modules/tag/tag.service.cjs.map +1 -0
- package/dist/src/modules/tag/tag.service.d.cts +120 -0
- package/dist/src/modules/tag/tag.trpc.cjs +32 -0
- package/dist/src/modules/tag/tag.trpc.cjs.map +1 -0
- package/dist/src/modules/tag/tag.trpc.d.cts +174 -0
- package/dist/src/modules/tag/tag.trpc.d.mts +3 -2
- package/dist/src/modules/utils/applyPagination.cjs +16 -0
- package/dist/src/modules/utils/applyPagination.cjs.map +1 -0
- package/dist/src/modules/utils/applyPagination.d.cts +10 -0
- package/dist/src/modules/utils/applySorting.cjs +20 -0
- package/dist/src/modules/utils/applySorting.cjs.map +1 -0
- package/dist/src/modules/utils/applySorting.d.cts +13 -0
- package/dist/src/modules/utils/getConditionsFromFilters.cjs +152 -0
- package/dist/src/modules/utils/getConditionsFromFilters.cjs.map +1 -0
- package/dist/src/modules/utils/getConditionsFromFilters.d.cts +9 -0
- package/dist/src/modules/utils/getGlobalSearchCondition.cjs +30 -0
- package/dist/src/modules/utils/getGlobalSearchCondition.cjs.map +1 -0
- package/dist/src/modules/utils/getGlobalSearchCondition.d.cts +18 -0
- package/dist/src/modules/utils/getGlobalSearchCondition.d.mts +18 -0
- package/dist/src/modules/utils/getGlobalSearchCondition.mjs +26 -0
- package/dist/src/modules/utils/getGlobalSearchCondition.mjs.map +1 -0
- package/dist/src/modules/video/video.service.cjs +114 -0
- package/dist/src/modules/video/video.service.cjs.map +1 -0
- package/dist/src/modules/video/video.service.d.cts +12 -0
- package/dist/src/modules/video/video.service.mjs +73 -13
- package/dist/src/modules/video/video.service.mjs.map +1 -1
- package/dist/src/modules/webhook/webhook.constants.cjs +13 -0
- package/dist/src/modules/webhook/webhook.constants.cjs.map +1 -0
- package/dist/src/modules/webhook/webhook.constants.d.cts +12 -0
- package/dist/src/modules/webhook/webhook.db.cjs +19 -0
- package/dist/src/modules/webhook/webhook.db.cjs.map +1 -0
- package/dist/src/modules/webhook/webhook.db.d.cts +142 -0
- package/dist/src/modules/webhook/webhook.dto.cjs +11 -0
- package/dist/src/modules/webhook/webhook.dto.cjs.map +1 -0
- package/dist/src/modules/webhook/webhook.dto.d.cts +402 -0
- package/dist/src/modules/webhook/webhook.repository.cjs +52 -0
- package/dist/src/modules/webhook/webhook.repository.cjs.map +1 -0
- package/dist/src/modules/webhook/webhook.repository.d.cts +154 -0
- package/dist/src/modules/webhook/webhook.router.cjs +26 -0
- package/dist/src/modules/webhook/webhook.router.cjs.map +1 -0
- package/dist/src/modules/webhook/webhook.router.d.cts +8 -0
- package/dist/src/modules/webhook/webhook.service.cjs +61 -0
- package/dist/src/modules/webhook/webhook.service.cjs.map +1 -0
- package/dist/src/modules/webhook/webhook.service.d.cts +14 -0
- package/dist/src/modules/workflow/workflow.db.cjs +35 -0
- package/dist/src/modules/workflow/workflow.db.cjs.map +1 -0
- package/dist/src/modules/workflow/workflow.db.d.cts +302 -0
- package/dist/src/modules/workflow/workflow.repository.cjs +95 -0
- package/dist/src/modules/workflow/workflow.repository.cjs.map +1 -0
- package/dist/src/modules/workflow/workflow.repository.d.cts +371 -0
- package/dist/src/modules/workflow/workflow.service.cjs +41 -0
- package/dist/src/modules/workflow/workflow.service.cjs.map +1 -0
- package/dist/src/modules/workflow/workflow.service.d.cts +68 -0
- package/dist/src/modules/workflow/workflow.trpc.cjs +19 -0
- package/dist/src/modules/workflow/workflow.trpc.cjs.map +1 -0
- package/dist/src/modules/workflow/workflow.trpc.d.cts +65 -0
- package/dist/src/modules/workflow/workflow.types.cjs +0 -0
- package/dist/src/modules/workflow/workflow.types.d.cts +25 -0
- package/dist/src/modules/workflow/workflow.utils.cjs +185 -0
- package/dist/src/modules/workflow/workflow.utils.cjs.map +1 -0
- package/dist/src/modules/workflow/workflow.utils.d.cts +36 -0
- package/dist/src/types.cjs +12 -0
- package/dist/src/types.cjs.map +1 -0
- package/dist/src/types.d.cts +344 -0
- package/dist/src/utils/errors.cjs +101 -0
- package/dist/src/utils/errors.cjs.map +1 -0
- package/dist/src/utils/errors.d.cts +62 -0
- package/dist/src/utils/logger.cjs +13 -0
- package/dist/src/utils/logger.cjs.map +1 -0
- package/dist/src/utils/logger.d.cts +7 -0
- package/dist/src/utils/posthog.cjs +31 -0
- package/dist/src/utils/posthog.cjs.map +1 -0
- package/dist/src/utils/posthog.d.cts +17 -0
- package/dist/src/utils/trpc.cjs +156 -0
- package/dist/src/utils/trpc.cjs.map +1 -0
- package/dist/src/utils/trpc.d.cts +54 -0
- package/dist/src/utils/types.cjs +0 -0
- package/dist/src/utils/types.d.cts +9 -0
- package/package.json +171 -47
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_modules_base_base_service = require("../base/base.service.cjs");
|
|
4
|
+
let neverthrow = require("neverthrow");
|
|
5
|
+
let react = require("react");
|
|
6
|
+
let resend = require("resend");
|
|
7
|
+
//#region src/modules/email/email.service.ts
|
|
8
|
+
var EmailService = class extends require_src_modules_base_base_service.BaseService {
|
|
9
|
+
client;
|
|
10
|
+
brand;
|
|
11
|
+
noReplyFrom;
|
|
12
|
+
templates;
|
|
13
|
+
systemNotificationEmail;
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(void 0, void 0);
|
|
16
|
+
this.client = new resend.Resend(props.resendApiKey || process.env.RESEND_API_KEY);
|
|
17
|
+
this.brand = props.brand;
|
|
18
|
+
this.noReplyFrom = props.noReplyFrom;
|
|
19
|
+
this.templates = props.templates;
|
|
20
|
+
this.systemNotificationEmail = props.systemNotificationEmail;
|
|
21
|
+
}
|
|
22
|
+
async sendTemplate(to, templateKey, templateProps, options) {
|
|
23
|
+
const template = this.templates[templateKey];
|
|
24
|
+
if (!template) return this.error("NOT_FOUND", `Email template not found: ${String(templateKey)}`);
|
|
25
|
+
const from = options?.from || this.noReplyFrom;
|
|
26
|
+
const subject = options?.subject || template.subject || String(templateKey);
|
|
27
|
+
const previewText = options?.previewText || template.previewText || subject;
|
|
28
|
+
const { error } = await this.client.emails.send({
|
|
29
|
+
to,
|
|
30
|
+
subject,
|
|
31
|
+
from,
|
|
32
|
+
react: (0, react.createElement)(template.react, {
|
|
33
|
+
...templateProps,
|
|
34
|
+
previewText
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
if (error) return this.error("INTERNAL_SERVER_ERROR", `Failed to send email: ${templateKey}`, { cause: error });
|
|
38
|
+
return (0, neverthrow.ok)();
|
|
39
|
+
}
|
|
40
|
+
async sendBrandTemplate(to, templateKey, templateProps, options) {
|
|
41
|
+
return this.sendTemplate(to, templateKey, {
|
|
42
|
+
brand: this.brand,
|
|
43
|
+
...templateProps
|
|
44
|
+
}, options);
|
|
45
|
+
}
|
|
46
|
+
async sendWaitlistConfirmation(email, overrideOptions) {
|
|
47
|
+
return this.sendTemplate(email, "waitlistConfirmation", {
|
|
48
|
+
email,
|
|
49
|
+
brand: this.brand
|
|
50
|
+
}, overrideOptions);
|
|
51
|
+
}
|
|
52
|
+
async sendWaitlistInvite(email, code, overrideOptions) {
|
|
53
|
+
const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;
|
|
54
|
+
return this.sendTemplate(email, "waitlistInvite", {
|
|
55
|
+
url,
|
|
56
|
+
brand: this.brand
|
|
57
|
+
}, overrideOptions);
|
|
58
|
+
}
|
|
59
|
+
async sendWaitlistUserInvite(email, code, inviter, name, overrideOptions) {
|
|
60
|
+
const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;
|
|
61
|
+
return this.sendTemplate(email, "waitlistUserInvite", {
|
|
62
|
+
url,
|
|
63
|
+
brand: this.brand,
|
|
64
|
+
inviter,
|
|
65
|
+
name
|
|
66
|
+
}, {
|
|
67
|
+
previewText: `Create your ${this.brand.name} account today!`,
|
|
68
|
+
subject: `${inviter} has invited you to join ${this.brand.name}!`,
|
|
69
|
+
...overrideOptions
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async sendOrganizationInvite(email, organizationName, inviterName, role, url, overrideOptions) {
|
|
73
|
+
return this.sendTemplate(email, "organizationInvite", {
|
|
74
|
+
url,
|
|
75
|
+
brand: this.brand,
|
|
76
|
+
organizationName,
|
|
77
|
+
inviterName,
|
|
78
|
+
role
|
|
79
|
+
}, {
|
|
80
|
+
previewText: `${inviterName} invited you to ${organizationName}`,
|
|
81
|
+
subject: `${inviterName} invited you to join ${organizationName}`,
|
|
82
|
+
...overrideOptions
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async sendVerification(email, url, overrideOptions) {
|
|
86
|
+
return this.sendTemplate(email, "verification", {
|
|
87
|
+
url,
|
|
88
|
+
brand: this.brand
|
|
89
|
+
}, overrideOptions);
|
|
90
|
+
}
|
|
91
|
+
async sendResetPassword(email, url, overrideOptions) {
|
|
92
|
+
return this.sendTemplate(email, "passwordReset", {
|
|
93
|
+
url,
|
|
94
|
+
brand: this.brand
|
|
95
|
+
}, overrideOptions);
|
|
96
|
+
}
|
|
97
|
+
async sendDeleteAccountVerification(email, url, overrideOptions) {
|
|
98
|
+
return this.sendTemplate(email, "accountDeletion", {
|
|
99
|
+
url,
|
|
100
|
+
brand: this.brand
|
|
101
|
+
}, overrideOptions);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
exports.EmailService = EmailService;
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=email.service.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.service.cjs","names":["BaseService","Resend"],"sources":["../../../../src/modules/email/email.service.ts"],"sourcesContent":["import { ok } from \"neverthrow\";\r\nimport { createElement, type FunctionComponent } from \"react\";\r\nimport { Resend } from \"resend\";\r\nimport { BaseService } from \"../base/base.service\";\r\n\r\ntype Brand = {\r\n name: string;\r\n logo: string;\r\n tagline: string;\r\n};\r\n\r\ntype OverrideOptions = {\r\n from?: string;\r\n subject?: string;\r\n previewText?: string;\r\n};\r\n\r\ntype EmailTemplate = {\r\n id: string;\r\n subject?: string;\r\n previewText?: string;\r\n from?: string;\r\n react: FunctionComponent<Record<string, unknown>>;\r\n};\r\n\r\ntype EmailTemplates = {\r\n accountDeletion: EmailTemplate;\r\n verification: EmailTemplate;\r\n waitlistConfirmation: EmailTemplate;\r\n passwordReset: EmailTemplate;\r\n systemWaitlistNotification: EmailTemplate;\r\n waitlistInvite: EmailTemplate;\r\n waitlistUserInvite: EmailTemplate;\r\n organizationInvite: EmailTemplate;\r\n [key: string]: EmailTemplate;\r\n};\r\n\r\ntype EmailServiceProps = {\r\n resendApiKey?: string;\r\n brand: Brand;\r\n noReplyFrom: string;\r\n systemNotificationEmail: string;\r\n templates: EmailTemplates;\r\n};\r\n\r\nexport class EmailService extends BaseService<never, never> {\r\n public client: Resend;\r\n public brand: Brand;\r\n public noReplyFrom: string;\r\n public templates: EmailTemplates;\r\n public systemNotificationEmail: string;\r\n\r\n constructor(props: EmailServiceProps) {\r\n super(undefined, undefined);\r\n this.client = new Resend(props.resendApiKey || process.env.RESEND_API_KEY);\r\n this.brand = props.brand;\r\n this.noReplyFrom = props.noReplyFrom;\r\n this.templates = props.templates;\r\n this.systemNotificationEmail = props.systemNotificationEmail;\r\n }\r\n\r\n async sendTemplate(\r\n to: string | string[],\r\n templateKey: keyof EmailTemplates,\r\n templateProps: Record<string, unknown>,\r\n options?: OverrideOptions\r\n ) {\r\n const template = this.templates[templateKey];\r\n if (!template) {\r\n return this.error(\"NOT_FOUND\", `Email template not found: ${String(templateKey)}`);\r\n }\r\n const from = options?.from || this.noReplyFrom;\r\n const subject = options?.subject || template.subject || String(templateKey);\r\n const previewText = options?.previewText || template.previewText || subject;\r\n\r\n const { error } = await this.client.emails.send({\r\n to,\r\n subject,\r\n from,\r\n react: createElement(template.react, { ...templateProps, previewText }),\r\n });\r\n if (error)\r\n return this.error(\"INTERNAL_SERVER_ERROR\", `Failed to send email: ${templateKey}`, {\r\n cause: error,\r\n });\r\n return ok();\r\n }\r\n\r\n async sendBrandTemplate(\r\n to: string | string[],\r\n templateKey: keyof EmailTemplates,\r\n templateProps: Record<string, unknown>,\r\n options?: OverrideOptions\r\n ) {\r\n return this.sendTemplate(\r\n to,\r\n templateKey,\r\n {\r\n brand: this.brand,\r\n ...templateProps,\r\n },\r\n options\r\n );\r\n }\r\n\r\n async sendWaitlistConfirmation(email: string, overrideOptions?: OverrideOptions) {\r\n return this.sendTemplate(\r\n email,\r\n \"waitlistConfirmation\",\r\n {\r\n email,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendWaitlistInvite(email: string, code: string, overrideOptions?: OverrideOptions) {\r\n const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;\r\n return this.sendTemplate(\r\n email,\r\n \"waitlistInvite\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendWaitlistUserInvite(\r\n email: string,\r\n code: string,\r\n inviter: string,\r\n name?: string,\r\n overrideOptions?: OverrideOptions\r\n ) {\r\n const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;\r\n return this.sendTemplate(\r\n email,\r\n \"waitlistUserInvite\",\r\n {\r\n url,\r\n brand: this.brand,\r\n inviter,\r\n name,\r\n },\r\n {\r\n previewText: `Create your ${this.brand.name} account today!`,\r\n subject: `${inviter} has invited you to join ${this.brand.name}!`,\r\n ...overrideOptions,\r\n }\r\n );\r\n }\r\n\r\n async sendOrganizationInvite(\r\n email: string,\r\n organizationName: string,\r\n inviterName: string,\r\n role: string,\r\n url: string,\r\n overrideOptions?: OverrideOptions\r\n ) {\r\n return this.sendTemplate(\r\n email,\r\n \"organizationInvite\",\r\n {\r\n url,\r\n brand: this.brand,\r\n organizationName,\r\n inviterName,\r\n role,\r\n },\r\n {\r\n previewText: `${inviterName} invited you to ${organizationName}`,\r\n subject: `${inviterName} invited you to join ${organizationName}`,\r\n ...overrideOptions,\r\n }\r\n );\r\n }\r\n\r\n async sendVerification(email: string, url: string, overrideOptions?: OverrideOptions) {\r\n return this.sendTemplate(\r\n email,\r\n \"verification\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendResetPassword(email: string, url: string, overrideOptions?: OverrideOptions) {\r\n return this.sendTemplate(\r\n email,\r\n \"passwordReset\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendDeleteAccountVerification(\r\n email: string,\r\n url: string,\r\n overrideOptions?: OverrideOptions\r\n ) {\r\n return this.sendTemplate(\r\n email,\r\n \"accountDeletion\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n}\r\n"],"mappings":";;;;;;;AA6CA,IAAa,eAAb,cAAkCA,sCAAAA,YAA0B;CAC1D;CACA;CACA;CACA;CACA;CAEA,YAAY,OAA0B;AACpC,QAAM,KAAA,GAAW,KAAA,EAAU;AAC3B,OAAK,SAAS,IAAIC,OAAAA,OAAO,MAAM,gBAAgB,QAAQ,IAAI,eAAe;AAC1E,OAAK,QAAQ,MAAM;AACnB,OAAK,cAAc,MAAM;AACzB,OAAK,YAAY,MAAM;AACvB,OAAK,0BAA0B,MAAM;;CAGvC,MAAM,aACJ,IACA,aACA,eACA,SACA;EACA,MAAM,WAAW,KAAK,UAAU;AAChC,MAAI,CAAC,SACH,QAAO,KAAK,MAAM,aAAa,6BAA6B,OAAO,YAAY,GAAG;EAEpF,MAAM,OAAO,SAAS,QAAQ,KAAK;EACnC,MAAM,UAAU,SAAS,WAAW,SAAS,WAAW,OAAO,YAAY;EAC3E,MAAM,cAAc,SAAS,eAAe,SAAS,eAAe;EAEpE,MAAM,EAAE,UAAU,MAAM,KAAK,OAAO,OAAO,KAAK;GAC9C;GACA;GACA;GACA,QAAA,GAAA,MAAA,eAAqB,SAAS,OAAO;IAAE,GAAG;IAAe;IAAa,CAAC;GACxE,CAAC;AACF,MAAI,MACF,QAAO,KAAK,MAAM,yBAAyB,yBAAyB,eAAe,EACjF,OAAO,OACR,CAAC;AACJ,UAAA,GAAA,WAAA,KAAW;;CAGb,MAAM,kBACJ,IACA,aACA,eACA,SACA;AACA,SAAO,KAAK,aACV,IACA,aACA;GACE,OAAO,KAAK;GACZ,GAAG;GACJ,EACD,QACD;;CAGH,MAAM,yBAAyB,OAAe,iBAAmC;AAC/E,SAAO,KAAK,aACV,OACA,wBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,mBAAmB,OAAe,MAAc,iBAAmC;EACvF,MAAM,MAAM,GAAG,QAAQ,IAAI,aAAa,eAAe,KAAK,SAAS;AACrE,SAAO,KAAK,aACV,OACA,kBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,uBACJ,OACA,MACA,SACA,MACA,iBACA;EACA,MAAM,MAAM,GAAG,QAAQ,IAAI,aAAa,eAAe,KAAK,SAAS;AACrE,SAAO,KAAK,aACV,OACA,sBACA;GACE;GACA,OAAO,KAAK;GACZ;GACA;GACD,EACD;GACE,aAAa,eAAe,KAAK,MAAM,KAAK;GAC5C,SAAS,GAAG,QAAQ,2BAA2B,KAAK,MAAM,KAAK;GAC/D,GAAG;GACJ,CACF;;CAGH,MAAM,uBACJ,OACA,kBACA,aACA,MACA,KACA,iBACA;AACA,SAAO,KAAK,aACV,OACA,sBACA;GACE;GACA,OAAO,KAAK;GACZ;GACA;GACA;GACD,EACD;GACE,aAAa,GAAG,YAAY,kBAAkB;GAC9C,SAAS,GAAG,YAAY,uBAAuB;GAC/C,GAAG;GACJ,CACF;;CAGH,MAAM,iBAAiB,OAAe,KAAa,iBAAmC;AACpF,SAAO,KAAK,aACV,OACA,gBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,kBAAkB,OAAe,KAAa,iBAAmC;AACrF,SAAO,KAAK,aACV,OACA,iBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,8BACJ,OACA,KACA,iBACA;AACA,SAAO,KAAK,aACV,OACA,mBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ServerError } from "../../utils/errors.cjs";
|
|
2
|
+
import { BaseService } from "../base/base.service.cjs";
|
|
3
|
+
import * as _$neverthrow from "neverthrow";
|
|
4
|
+
import { FunctionComponent } from "react";
|
|
5
|
+
import { Resend } from "resend";
|
|
6
|
+
|
|
7
|
+
//#region src/modules/email/email.service.d.ts
|
|
8
|
+
type Brand = {
|
|
9
|
+
name: string;
|
|
10
|
+
logo: string;
|
|
11
|
+
tagline: string;
|
|
12
|
+
};
|
|
13
|
+
type OverrideOptions = {
|
|
14
|
+
from?: string;
|
|
15
|
+
subject?: string;
|
|
16
|
+
previewText?: string;
|
|
17
|
+
};
|
|
18
|
+
type EmailTemplate = {
|
|
19
|
+
id: string;
|
|
20
|
+
subject?: string;
|
|
21
|
+
previewText?: string;
|
|
22
|
+
from?: string;
|
|
23
|
+
react: FunctionComponent<Record<string, unknown>>;
|
|
24
|
+
};
|
|
25
|
+
type EmailTemplates = {
|
|
26
|
+
accountDeletion: EmailTemplate;
|
|
27
|
+
verification: EmailTemplate;
|
|
28
|
+
waitlistConfirmation: EmailTemplate;
|
|
29
|
+
passwordReset: EmailTemplate;
|
|
30
|
+
systemWaitlistNotification: EmailTemplate;
|
|
31
|
+
waitlistInvite: EmailTemplate;
|
|
32
|
+
waitlistUserInvite: EmailTemplate;
|
|
33
|
+
organizationInvite: EmailTemplate;
|
|
34
|
+
[key: string]: EmailTemplate;
|
|
35
|
+
};
|
|
36
|
+
type EmailServiceProps = {
|
|
37
|
+
resendApiKey?: string;
|
|
38
|
+
brand: Brand;
|
|
39
|
+
noReplyFrom: string;
|
|
40
|
+
systemNotificationEmail: string;
|
|
41
|
+
templates: EmailTemplates;
|
|
42
|
+
};
|
|
43
|
+
declare class EmailService extends BaseService<never, never> {
|
|
44
|
+
client: Resend;
|
|
45
|
+
brand: Brand;
|
|
46
|
+
noReplyFrom: string;
|
|
47
|
+
templates: EmailTemplates;
|
|
48
|
+
systemNotificationEmail: string;
|
|
49
|
+
constructor(props: EmailServiceProps);
|
|
50
|
+
sendTemplate(to: string | string[], templateKey: keyof EmailTemplates, templateProps: Record<string, unknown>, options?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
51
|
+
sendBrandTemplate(to: string | string[], templateKey: keyof EmailTemplates, templateProps: Record<string, unknown>, options?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
52
|
+
sendWaitlistConfirmation(email: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
53
|
+
sendWaitlistInvite(email: string, code: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
54
|
+
sendWaitlistUserInvite(email: string, code: string, inviter: string, name?: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
55
|
+
sendOrganizationInvite(email: string, organizationName: string, inviterName: string, role: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
56
|
+
sendVerification(email: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
57
|
+
sendResetPassword(email: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
58
|
+
sendDeleteAccountVerification(email: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { EmailService };
|
|
62
|
+
//# sourceMappingURL=email.service.d.cts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_modules_base_base_repository = require("../base/base.repository.cjs");
|
|
4
|
+
let neverthrow = require("neverthrow");
|
|
5
|
+
let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
|
|
6
|
+
let _aws_sdk_s3_request_presigner = require("@aws-sdk/s3-request-presigner");
|
|
7
|
+
//#region src/modules/file/file.repository.ts
|
|
8
|
+
var FileRepository = class extends require_src_modules_base_base_repository.BaseExternaRepository {
|
|
9
|
+
s3;
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
if (!process.env.AWS_REGION || !process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) throw new Error("Missing AWS environment variables");
|
|
13
|
+
this.s3 = new _aws_sdk_client_s3.S3Client({
|
|
14
|
+
region: process.env.AWS_REGION,
|
|
15
|
+
credentials: {
|
|
16
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
17
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
|
|
18
|
+
},
|
|
19
|
+
...process.env.AWS_S3_ENDPOINT ? { endpoint: process.env.AWS_S3_ENDPOINT } : {},
|
|
20
|
+
forcePathStyle: !!process.env.AWS_S3_ENDPOINT
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async getS3UploadUrl(filename, filetype, expiresIn = 300) {
|
|
24
|
+
return this.throwableAsync(async () => {
|
|
25
|
+
const command = new _aws_sdk_client_s3.PutObjectCommand({
|
|
26
|
+
Bucket: process.env.AWS_S3_BUCKET,
|
|
27
|
+
Key: filename,
|
|
28
|
+
ContentType: filetype
|
|
29
|
+
});
|
|
30
|
+
return (0, neverthrow.ok)(await (0, _aws_sdk_s3_request_presigner.getSignedUrl)(this.s3, command, { expiresIn }));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async getS3DownloadUrl(path, expiresIn = 300) {
|
|
34
|
+
return this.throwableAsync(async () => {
|
|
35
|
+
const command = new _aws_sdk_client_s3.GetObjectCommand({
|
|
36
|
+
Bucket: process.env.AWS_S3_BUCKET,
|
|
37
|
+
Key: path
|
|
38
|
+
});
|
|
39
|
+
return (0, neverthrow.ok)(await (0, _aws_sdk_s3_request_presigner.getSignedUrl)(this.s3, command, { expiresIn }));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async getS3Object(path) {
|
|
43
|
+
return this.throwableAsync(async () => {
|
|
44
|
+
const command = new _aws_sdk_client_s3.GetObjectCommand({
|
|
45
|
+
Bucket: process.env.AWS_S3_BUCKET,
|
|
46
|
+
Key: path
|
|
47
|
+
});
|
|
48
|
+
return (0, neverthrow.ok)(await this.s3.send(command));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async getS3ObjectT(path) {
|
|
52
|
+
return this.throwableAsync(async () => {
|
|
53
|
+
const command = new _aws_sdk_client_s3.GetObjectCommand({
|
|
54
|
+
Bucket: process.env.AWS_S3_BUCKET,
|
|
55
|
+
Key: path
|
|
56
|
+
});
|
|
57
|
+
return (0, neverthrow.ok)(await this.s3.send(command));
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async deleteS3Object(path) {
|
|
61
|
+
return this.throwableAsync(async () => {
|
|
62
|
+
const command = new _aws_sdk_client_s3.DeleteObjectCommand({
|
|
63
|
+
Bucket: process.env.AWS_S3_BUCKET,
|
|
64
|
+
Key: path
|
|
65
|
+
});
|
|
66
|
+
await this.s3.send(command);
|
|
67
|
+
return (0, neverthrow.ok)(void 0);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
exports.FileRepository = FileRepository;
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=file.repository.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.repository.cjs","names":["BaseExternaRepository","S3Client","PutObjectCommand","GetObjectCommand","DeleteObjectCommand"],"sources":["../../../../src/modules/file/file.repository.ts"],"sourcesContent":["import {\r\n DeleteObjectCommand,\r\n GetObjectCommand,\r\n type GetObjectCommandOutput,\r\n PutObjectCommand,\r\n S3Client,\r\n} from \"@aws-sdk/client-s3\";\r\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\r\nimport { ok } from \"neverthrow\";\r\nimport type { ServerResultAsync } from \"../base/base.dto\";\r\nimport { BaseExternaRepository } from \"../base/base.repository\";\r\n\r\nexport class FileRepository extends BaseExternaRepository {\r\n private readonly s3: S3Client;\r\n constructor() {\r\n super();\r\n\r\n if (\r\n !process.env.AWS_REGION ||\r\n !process.env.AWS_ACCESS_KEY_ID ||\r\n !process.env.AWS_SECRET_ACCESS_KEY\r\n ) {\r\n throw new Error(\"Missing AWS environment variables\");\r\n }\r\n\r\n this.s3 = new S3Client({\r\n region: process.env.AWS_REGION,\r\n credentials: {\r\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\r\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\r\n },\r\n ...(process.env.AWS_S3_ENDPOINT ? { endpoint: process.env.AWS_S3_ENDPOINT } : {}),\r\n forcePathStyle: !!process.env.AWS_S3_ENDPOINT, // Path style is often required for non-AWS S3 providers\r\n });\r\n }\r\n async getS3UploadUrl(\r\n filename: string,\r\n filetype: string,\r\n expiresIn = 60 * 5\r\n ): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const command = new PutObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: filename,\r\n ContentType: filetype,\r\n });\r\n const url = await getSignedUrl(this.s3, command, { expiresIn });\r\n return ok(url);\r\n });\r\n }\r\n\r\n async getS3DownloadUrl(path: string, expiresIn = 60 * 5): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const command = new GetObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n const url = await getSignedUrl(this.s3, command, { expiresIn });\r\n return ok(url);\r\n });\r\n }\r\n\r\n async getS3Object(path: string): ServerResultAsync<GetObjectCommandOutput> {\r\n return this.throwableAsync(async () => {\r\n const command = new GetObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n const data = await this.s3.send(command);\r\n return ok(data);\r\n });\r\n }\r\n\r\n async getS3ObjectT(path: string): ServerResultAsync<GetObjectCommandOutput> {\r\n return this.throwableAsync(async () => {\r\n const command = new GetObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n const data = await this.s3.send(command);\r\n return ok(data);\r\n });\r\n }\r\n\r\n async deleteS3Object(path: string): ServerResultAsync<void> {\r\n return this.throwableAsync(async () => {\r\n const command = new DeleteObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n await this.s3.send(command);\r\n return ok(undefined);\r\n });\r\n }\r\n}\r\n"],"mappings":";;;;;;;AAYA,IAAa,iBAAb,cAAoCA,yCAAAA,sBAAsB;CACxD;CACA,cAAc;AACZ,SAAO;AAEP,MACE,CAAC,QAAQ,IAAI,cACb,CAAC,QAAQ,IAAI,qBACb,CAAC,QAAQ,IAAI,sBAEb,OAAM,IAAI,MAAM,oCAAoC;AAGtD,OAAK,KAAK,IAAIC,mBAAAA,SAAS;GACrB,QAAQ,QAAQ,IAAI;GACpB,aAAa;IACX,aAAa,QAAQ,IAAI;IACzB,iBAAiB,QAAQ,IAAI;IAC9B;GACD,GAAI,QAAQ,IAAI,kBAAkB,EAAE,UAAU,QAAQ,IAAI,iBAAiB,GAAG,EAAE;GAChF,gBAAgB,CAAC,CAAC,QAAQ,IAAI;GAC/B,CAAC;;CAEJ,MAAM,eACJ,UACA,UACA,YAAY,KACe;AAC3B,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIC,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACL,aAAa;IACd,CAAC;AAEF,WAAA,GAAA,WAAA,IADY,OAAA,GAAA,8BAAA,cAAmB,KAAK,IAAI,SAAS,EAAE,WAAW,CAAC,CACjD;IACd;;CAGJ,MAAM,iBAAiB,MAAc,YAAY,KAAmC;AAClF,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIC,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AAEF,WAAA,GAAA,WAAA,IADY,OAAA,GAAA,8BAAA,cAAmB,KAAK,IAAI,SAAS,EAAE,WAAW,CAAC,CACjD;IACd;;CAGJ,MAAM,YAAY,MAAyD;AACzE,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIA,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AAEF,WAAA,GAAA,WAAA,IADa,MAAM,KAAK,GAAG,KAAK,QAAQ,CACzB;IACf;;CAGJ,MAAM,aAAa,MAAyD;AAC1E,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIA,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AAEF,WAAA,GAAA,WAAA,IADa,MAAM,KAAK,GAAG,KAAK,QAAQ,CACzB;IACf;;CAGJ,MAAM,eAAe,MAAuC;AAC1D,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIC,mBAAAA,oBAAoB;IACtC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AACF,SAAM,KAAK,GAAG,KAAK,QAAQ;AAC3B,WAAA,GAAA,WAAA,IAAU,KAAA,EAAU;IACpB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ServerResultAsync } from "../base/base.dto.cjs";
|
|
2
|
+
import { BaseExternaRepository } from "../base/base.repository.cjs";
|
|
3
|
+
import { GetObjectCommandOutput } from "@aws-sdk/client-s3";
|
|
4
|
+
|
|
5
|
+
//#region src/modules/file/file.repository.d.ts
|
|
6
|
+
declare class FileRepository extends BaseExternaRepository {
|
|
7
|
+
private readonly s3;
|
|
8
|
+
constructor();
|
|
9
|
+
getS3UploadUrl(filename: string, filetype: string, expiresIn?: number): ServerResultAsync<string>;
|
|
10
|
+
getS3DownloadUrl(path: string, expiresIn?: number): ServerResultAsync<string>;
|
|
11
|
+
getS3Object(path: string): ServerResultAsync<GetObjectCommandOutput>;
|
|
12
|
+
getS3ObjectT(path: string): ServerResultAsync<GetObjectCommandOutput>;
|
|
13
|
+
deleteS3Object(path: string): ServerResultAsync<void>;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { FileRepository };
|
|
17
|
+
//# sourceMappingURL=file.repository.d.cts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_modules_file_file_repository = require("./file.repository.cjs");
|
|
4
|
+
const require_src_modules_file_file_service = require("./file.service.cjs");
|
|
5
|
+
let uuid = require("uuid");
|
|
6
|
+
let body_parser = require("body-parser");
|
|
7
|
+
body_parser = require_runtime.__toESM(body_parser);
|
|
8
|
+
let express = require("express");
|
|
9
|
+
express = require_runtime.__toESM(express);
|
|
10
|
+
let node_path = require("node:path");
|
|
11
|
+
node_path = require_runtime.__toESM(node_path);
|
|
12
|
+
let _m5kdev_commons_modules_file_file_constants = require("@m5kdev/commons/modules/file/file.constants");
|
|
13
|
+
let multer = require("multer");
|
|
14
|
+
multer = require_runtime.__toESM(multer);
|
|
15
|
+
//#region src/modules/file/file.router.ts
|
|
16
|
+
const fileService = new require_src_modules_file_file_service.FileService({ file: new require_src_modules_file_file_repository.FileRepository() });
|
|
17
|
+
function validateMimeType(type, file) {
|
|
18
|
+
return _m5kdev_commons_modules_file_file_constants.fileTypes[type]?.mimetypes.includes(file.mimetype);
|
|
19
|
+
}
|
|
20
|
+
function getFileExtension(file) {
|
|
21
|
+
return file.originalname.split(".").pop();
|
|
22
|
+
}
|
|
23
|
+
const storage = multer.default.diskStorage({
|
|
24
|
+
destination: (_req, _file, cb) => {
|
|
25
|
+
cb(null, node_path.default.join(__dirname, "..", "uploads"));
|
|
26
|
+
},
|
|
27
|
+
filename: (_req, file, cb) => {
|
|
28
|
+
cb(null, `${(0, uuid.v4)()}.${getFileExtension(file)}`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const fileFilter = (req, file, cb) => {
|
|
32
|
+
const { type } = req.params;
|
|
33
|
+
if (type && validateMimeType(type, file)) cb(null, true);
|
|
34
|
+
else cb(/* @__PURE__ */ new Error("Invalid file type"));
|
|
35
|
+
};
|
|
36
|
+
const upload = (0, multer.default)({
|
|
37
|
+
storage,
|
|
38
|
+
fileFilter
|
|
39
|
+
});
|
|
40
|
+
const uploadRouter = express.default.Router();
|
|
41
|
+
uploadRouter.post("/file/:type", upload.single("file"), (req, res) => {
|
|
42
|
+
const { file } = req;
|
|
43
|
+
if (!file) return res.status(400).json({ error: "No file uploaded" });
|
|
44
|
+
return res.json({
|
|
45
|
+
url: `${process.env.VITE_SERVER_URL}/upload/file/${file.filename}`,
|
|
46
|
+
mimetype: file.mimetype,
|
|
47
|
+
size: file.size
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
uploadRouter.get("/file/:filename", (req, res) => {
|
|
51
|
+
res.sendFile(node_path.default.join(__dirname, "..", "uploads", req.params.filename));
|
|
52
|
+
});
|
|
53
|
+
uploadRouter.get("/files/:path", async (req, res) => {
|
|
54
|
+
try {
|
|
55
|
+
const url = await fileService.getS3DownloadUrl(req.params.path);
|
|
56
|
+
if (url.isErr()) {
|
|
57
|
+
console.error(url.error);
|
|
58
|
+
return res.status(500).json({ error: url.error.message });
|
|
59
|
+
}
|
|
60
|
+
return res.json({ url: url.value });
|
|
61
|
+
} catch (err) {
|
|
62
|
+
console.error(err);
|
|
63
|
+
return res.status(500).json({ error: err.message || "Failed to generate presigned URL" });
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
uploadRouter.post("/s3-presigned-url", body_parser.default.json(), async (req, res) => {
|
|
67
|
+
const { filename, filetype } = req.body;
|
|
68
|
+
if (!filename || !filetype) return res.status(400).json({ error: "Missing filename or filetype" });
|
|
69
|
+
try {
|
|
70
|
+
const url = await fileService.getS3UploadUrl(filename, filetype);
|
|
71
|
+
if (url.isErr()) return res.status(500).json({ error: url.error.message });
|
|
72
|
+
return res.json({ url: url.value });
|
|
73
|
+
} catch (err) {
|
|
74
|
+
console.error(err);
|
|
75
|
+
return res.status(500).json({ error: err.message || "Failed to generate presigned URL" });
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
uploadRouter.delete("/files/:path(*)", async (req, res) => {
|
|
79
|
+
try {
|
|
80
|
+
const result = await fileService.deleteS3Object(req.params.path);
|
|
81
|
+
if (result.isErr()) {
|
|
82
|
+
console.error(result.error);
|
|
83
|
+
return res.status(500).json({ error: result.error.message });
|
|
84
|
+
}
|
|
85
|
+
return res.json({ success: true });
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.error(err);
|
|
88
|
+
return res.status(500).json({ error: err.message || "Failed to delete S3 object" });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
//#endregion
|
|
92
|
+
exports.uploadRouter = uploadRouter;
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=file.router.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.router.cjs","names":["FileService","FileRepository","fileTypes","path","bodyParser"],"sources":["../../../../src/modules/file/file.router.ts"],"sourcesContent":["import path from \"node:path\";\r\nimport { fileTypes } from \"@m5kdev/commons/modules/file/file.constants\";\r\nimport bodyParser from \"body-parser\";\r\nimport express, { type Request, type Response } from \"express\";\r\nimport multer from \"multer\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport { FileRepository } from \"./file.repository\";\r\nimport { FileService } from \"./file.service\";\r\n\r\nconst fileRepository = new FileRepository();\r\nconst fileService = new FileService({ file: fileRepository });\r\n\r\nfunction validateMimeType(type: string, file: Express.Multer.File): boolean {\r\n return fileTypes[type]?.mimetypes.includes(file.mimetype);\r\n}\r\n\r\nfunction getFileExtension(file: Express.Multer.File): string | undefined {\r\n return file.originalname.split(\".\").pop();\r\n}\r\n\r\nconst storage = multer.diskStorage({\r\n destination: (_req, _file, cb) => {\r\n cb(null, path.join(__dirname, \"..\", \"uploads\"));\r\n },\r\n filename: (_req, file, cb) => {\r\n cb(null, `${uuidv4()}.${getFileExtension(file)}`);\r\n },\r\n});\r\n\r\nconst fileFilter = (\r\n req: Request,\r\n file: Express.Multer.File,\r\n cb: multer.FileFilterCallback\r\n): void => {\r\n const { type } = req.params;\r\n if (type && validateMimeType(type, file)) {\r\n cb(null, true);\r\n } else {\r\n cb(new Error(\"Invalid file type\"));\r\n }\r\n};\r\n\r\nconst upload = multer({ storage, fileFilter });\r\nconst uploadRouter: express.Router = express.Router();\r\n\r\nuploadRouter.post(\"/file/:type\", upload.single(\"file\"), (req: Request, res: Response) => {\r\n const { file } = req;\r\n if (!file) {\r\n return res.status(400).json({ error: \"No file uploaded\" });\r\n }\r\n return res.json({\r\n url: `${process.env.VITE_SERVER_URL}/upload/file/${file.filename}`,\r\n mimetype: file.mimetype,\r\n size: file.size,\r\n });\r\n});\r\n\r\nuploadRouter.get(\"/file/:filename\", (req: Request, res: Response) => {\r\n res.sendFile(path.join(__dirname, \"..\", \"uploads\", req.params.filename!));\r\n});\r\n\r\nuploadRouter.get(\"/files/:path\", async (req: Request, res: Response) => {\r\n try {\r\n const url = await fileService.getS3DownloadUrl(req.params.path!);\r\n if (url.isErr()) {\r\n console.error(url.error);\r\n return res.status(500).json({ error: url.error.message });\r\n }\r\n return res.json({ url: url.value });\r\n } catch (err: any) {\r\n console.error(err);\r\n return res.status(500).json({ error: err.message || \"Failed to generate presigned URL\" });\r\n }\r\n});\r\n\r\nuploadRouter.post(\"/s3-presigned-url\", bodyParser.json(), async (req: Request, res: Response) => {\r\n const { filename, filetype } = req.body;\r\n\r\n if (!filename || !filetype) {\r\n return res.status(400).json({ error: \"Missing filename or filetype\" });\r\n }\r\n try {\r\n const url = await fileService.getS3UploadUrl(filename, filetype);\r\n if (url.isErr()) {\r\n return res.status(500).json({ error: url.error.message });\r\n }\r\n return res.json({ url: url.value });\r\n } catch (err: any) {\r\n console.error(err);\r\n return res.status(500).json({ error: err.message || \"Failed to generate presigned URL\" });\r\n }\r\n});\r\n\r\nuploadRouter.delete(\"/files/:path(*)\", async (req: Request, res: Response) => {\r\n try {\r\n const result = await fileService.deleteS3Object(req.params.path!);\r\n if (result.isErr()) {\r\n console.error(result.error);\r\n return res.status(500).json({ error: result.error.message });\r\n }\r\n return res.json({ success: true });\r\n } catch (err: any) {\r\n console.error(err);\r\n return res.status(500).json({ error: err.message || \"Failed to delete S3 object\" });\r\n }\r\n});\r\n\r\nexport { uploadRouter };\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_modules_base_base_service = require("../base/base.service.cjs");
|
|
4
|
+
let neverthrow = require("neverthrow");
|
|
5
|
+
let uuid = require("uuid");
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
node_path = require_runtime.__toESM(node_path);
|
|
8
|
+
let _m5kdev_commons_modules_file_file_constants = require("@m5kdev/commons/modules/file/file.constants");
|
|
9
|
+
let node_fs = require("node:fs");
|
|
10
|
+
let node_fs_promises = require("node:fs/promises");
|
|
11
|
+
let node_os = require("node:os");
|
|
12
|
+
let node_stream = require("node:stream");
|
|
13
|
+
let node_stream_promises = require("node:stream/promises");
|
|
14
|
+
//#region src/modules/file/file.service.ts
|
|
15
|
+
var FileService = class extends require_src_modules_base_base_service.BaseService {
|
|
16
|
+
isS3Path(path) {
|
|
17
|
+
return path.startsWith("s3::");
|
|
18
|
+
}
|
|
19
|
+
parseS3Path(S3Path) {
|
|
20
|
+
if (!this.isS3Path(S3Path)) return this.error("BAD_REQUEST", "Invalid S3 path");
|
|
21
|
+
const [bucket, path] = S3Path.split("s3::")[1].split("//");
|
|
22
|
+
return (0, neverthrow.ok)({
|
|
23
|
+
bucket,
|
|
24
|
+
path
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
wrapS3Path(path, bucket) {
|
|
28
|
+
return `s3::${bucket}//${path}`;
|
|
29
|
+
}
|
|
30
|
+
getS3UploadUrl(filename, filetype, expiresIn = 300) {
|
|
31
|
+
return this.repository.file.getS3UploadUrl(filename, filetype, expiresIn);
|
|
32
|
+
}
|
|
33
|
+
getS3DownloadUrl(path, expiresIn = 300) {
|
|
34
|
+
return this.repository.file.getS3DownloadUrl(path, expiresIn);
|
|
35
|
+
}
|
|
36
|
+
getS3Object(path) {
|
|
37
|
+
return this.repository.file.getS3Object(path);
|
|
38
|
+
}
|
|
39
|
+
deleteS3Object(path) {
|
|
40
|
+
return this.repository.file.deleteS3Object(path);
|
|
41
|
+
}
|
|
42
|
+
async uploadFileToS3(localPath, returnDownloadUrl = false) {
|
|
43
|
+
return this.throwableAsync(async () => {
|
|
44
|
+
const extension = localPath.split(".").pop()?.toLowerCase();
|
|
45
|
+
const filename = `${(0, uuid.v4)()}${extension ? `.${extension}` : ""}`;
|
|
46
|
+
const filetype = extension && {
|
|
47
|
+
jpg: "image/jpeg",
|
|
48
|
+
jpeg: "image/jpeg",
|
|
49
|
+
png: "image/png",
|
|
50
|
+
webp: "image/webp",
|
|
51
|
+
mp4: "video/mp4",
|
|
52
|
+
mov: "video/mov",
|
|
53
|
+
avi: "video/avi",
|
|
54
|
+
mkv: "video/mkv",
|
|
55
|
+
webm: "video/webm",
|
|
56
|
+
mp3: "audio/mp3",
|
|
57
|
+
wav: "audio/wav",
|
|
58
|
+
m4a: "audio/m4a"
|
|
59
|
+
}[extension] || "application/octet-stream";
|
|
60
|
+
const presigned = await this.getS3UploadUrl(filename, filetype);
|
|
61
|
+
if (presigned.isErr()) return (0, neverthrow.err)(presigned.error);
|
|
62
|
+
const file = await (0, node_fs_promises.readFile)(localPath);
|
|
63
|
+
const res = await fetch(presigned.value, {
|
|
64
|
+
method: "PUT",
|
|
65
|
+
body: file,
|
|
66
|
+
headers: { "Content-Type": filetype }
|
|
67
|
+
});
|
|
68
|
+
if (!res.ok) return this.error("INTERNAL_SERVER_ERROR", `Failed to upload to S3: ${res.status}`);
|
|
69
|
+
if (returnDownloadUrl) {
|
|
70
|
+
const downloadUrl = await this.getS3DownloadUrl(filename);
|
|
71
|
+
if (downloadUrl.isErr()) return (0, neverthrow.err)(downloadUrl.error);
|
|
72
|
+
return (0, neverthrow.ok)(downloadUrl.value);
|
|
73
|
+
}
|
|
74
|
+
return (0, neverthrow.ok)(filename);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async downloadS3ToFile(s3Path) {
|
|
78
|
+
return this.throwableAsync(async () => {
|
|
79
|
+
const extension = s3Path.split(".").pop();
|
|
80
|
+
const destinationPath = node_path.default.join((0, node_os.tmpdir)(), "s3-downloads", `${(0, uuid.v4)()}${extension ? `.${extension}` : ""}`);
|
|
81
|
+
const result = await this.repository.file.getS3Object(s3Path);
|
|
82
|
+
if (result.isErr()) return (0, neverthrow.err)(result.error);
|
|
83
|
+
const body = result.value.Body;
|
|
84
|
+
if (!body) return this.error("NOT_FOUND", "S3 object body is empty");
|
|
85
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(destinationPath), { recursive: true });
|
|
86
|
+
if (typeof body === "object" && "transformToByteArray" in body && typeof body.transformToByteArray === "function") {
|
|
87
|
+
await (0, node_fs_promises.writeFile)(destinationPath, await body.transformToByteArray());
|
|
88
|
+
return (0, neverthrow.ok)(destinationPath);
|
|
89
|
+
}
|
|
90
|
+
const writeStream = (0, node_fs.createWriteStream)(destinationPath);
|
|
91
|
+
let input = null;
|
|
92
|
+
const unknownBody = body;
|
|
93
|
+
if (typeof unknownBody === "object" && unknownBody !== null && "pipe" in unknownBody && typeof unknownBody.pipe === "function") input = unknownBody;
|
|
94
|
+
else if (typeof unknownBody === "object" && unknownBody !== null && "getReader" in unknownBody && typeof unknownBody.getReader === "function") input = node_stream.Readable.fromWeb(unknownBody);
|
|
95
|
+
else if (typeof unknownBody === "object" && unknownBody !== null && "stream" in unknownBody && typeof unknownBody.stream === "function") input = node_stream.Readable.fromWeb(unknownBody.stream());
|
|
96
|
+
if (input) {
|
|
97
|
+
await (0, node_stream_promises.pipeline)(input, writeStream);
|
|
98
|
+
return (0, neverthrow.ok)(destinationPath);
|
|
99
|
+
}
|
|
100
|
+
if (typeof unknownBody === "object" && unknownBody !== null && "arrayBuffer" in unknownBody && typeof unknownBody.arrayBuffer === "function") {
|
|
101
|
+
const buffer = Buffer.from(await unknownBody.arrayBuffer());
|
|
102
|
+
await (0, node_stream_promises.pipeline)(node_stream.Readable.from(buffer), writeStream);
|
|
103
|
+
return (0, neverthrow.ok)(destinationPath);
|
|
104
|
+
}
|
|
105
|
+
return this.error("INTERNAL_SERVER_ERROR", "Unsupported S3 body type");
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
getFileType(path) {
|
|
109
|
+
const extension = path.split(".").pop();
|
|
110
|
+
if (!extension) return void 0;
|
|
111
|
+
for (const [key, value] of Object.entries(_m5kdev_commons_modules_file_file_constants.fileTypes)) if (value.extensions.includes(extension)) return {
|
|
112
|
+
fileType: key,
|
|
113
|
+
extension
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
//#endregion
|
|
118
|
+
exports.FileService = FileService;
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=file.service.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.service.cjs","names":["BaseService","path","Readable","fileTypes"],"sources":["../../../../src/modules/file/file.service.ts"],"sourcesContent":["import { createWriteStream } from \"node:fs\";\r\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\r\nimport { tmpdir } from \"node:os\";\r\nimport path, { dirname } from \"node:path\";\r\nimport { Readable } from \"node:stream\";\r\nimport { pipeline } from \"node:stream/promises\";\r\nimport { fileTypes } from \"@m5kdev/commons/modules/file/file.constants\";\r\nimport { err, ok } from \"neverthrow\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport type { ServerResult, ServerResultAsync } from \"../base/base.dto\";\r\nimport { BaseService } from \"../base/base.service\";\r\nimport type { FileRepository } from \"./file.repository\";\r\n\r\nexport class FileService extends BaseService<{ file: FileRepository }, never> {\r\n isS3Path(path: string): boolean {\r\n return path.startsWith(\"s3::\");\r\n }\r\n\r\n parseS3Path(S3Path: string): ServerResult<{ bucket: string; path: string }> {\r\n if (!this.isS3Path(S3Path)) {\r\n return this.error(\"BAD_REQUEST\", \"Invalid S3 path\");\r\n }\r\n const [bucket, path] = S3Path.split(\"s3::\")[1].split(\"//\");\r\n return ok({ bucket, path });\r\n }\r\n\r\n wrapS3Path(path: string, bucket: string): string {\r\n return `s3::${bucket}//${path}`;\r\n }\r\n\r\n getS3UploadUrl(\r\n filename: string,\r\n filetype: string,\r\n expiresIn = 60 * 5\r\n ): ServerResultAsync<string> {\r\n return this.repository.file.getS3UploadUrl(filename, filetype, expiresIn);\r\n }\r\n\r\n getS3DownloadUrl(path: string, expiresIn = 60 * 5): ServerResultAsync<string> {\r\n return this.repository.file.getS3DownloadUrl(path, expiresIn);\r\n }\r\n\r\n getS3Object(path: string) {\r\n return this.repository.file.getS3Object(path);\r\n }\r\n\r\n deleteS3Object(path: string) {\r\n return this.repository.file.deleteS3Object(path);\r\n }\r\n\r\n async uploadFileToS3(localPath: string, returnDownloadUrl = false): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const extension = localPath.split(\".\").pop()?.toLowerCase();\r\n const filename = `${uuidv4()}${extension ? `.${extension}` : \"\"}`;\r\n\r\n const mimeByExt: Record<string, string> = {\r\n jpg: \"image/jpeg\",\r\n jpeg: \"image/jpeg\",\r\n png: \"image/png\",\r\n webp: \"image/webp\",\r\n mp4: \"video/mp4\",\r\n mov: \"video/mov\",\r\n avi: \"video/avi\",\r\n mkv: \"video/mkv\",\r\n webm: \"video/webm\",\r\n mp3: \"audio/mp3\",\r\n wav: \"audio/wav\",\r\n m4a: \"audio/m4a\",\r\n };\r\n const filetype = (extension && mimeByExt[extension]) || \"application/octet-stream\";\r\n\r\n const presigned = await this.getS3UploadUrl(filename, filetype);\r\n if (presigned.isErr()) return err(presigned.error);\r\n\r\n const file = await readFile(localPath);\r\n const res = await fetch(presigned.value, {\r\n method: \"PUT\",\r\n body: file,\r\n headers: { \"Content-Type\": filetype },\r\n });\r\n if (!res.ok) {\r\n return this.error(\"INTERNAL_SERVER_ERROR\", `Failed to upload to S3: ${res.status}`);\r\n }\r\n if (returnDownloadUrl) {\r\n const downloadUrl = await this.getS3DownloadUrl(filename);\r\n if (downloadUrl.isErr()) return err(downloadUrl.error);\r\n return ok(downloadUrl.value);\r\n }\r\n\r\n return ok(filename);\r\n });\r\n }\r\n\r\n async downloadS3ToFile(s3Path: string): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const extension = s3Path.split(\".\").pop();\r\n const destinationPath = path.join(\r\n tmpdir(),\r\n \"s3-downloads\",\r\n `${uuidv4()}${extension ? `.${extension}` : \"\"}`\r\n );\r\n\r\n const result = await this.repository.file.getS3Object(s3Path);\r\n if (result.isErr()) return err(result.error);\r\n\r\n const body = result.value.Body;\r\n if (!body) return this.error(\"NOT_FOUND\", \"S3 object body is empty\");\r\n\r\n await mkdir(dirname(destinationPath), { recursive: true });\r\n\r\n // AWS SDK v3 SdkStream has transformToByteArray method - use it for reliable handling\r\n if (\r\n typeof body === \"object\" &&\r\n \"transformToByteArray\" in body &&\r\n typeof body.transformToByteArray === \"function\"\r\n ) {\r\n const bytes = await body.transformToByteArray();\r\n await writeFile(destinationPath, bytes);\r\n return ok(destinationPath);\r\n }\r\n\r\n // Fallback: try streaming approaches\r\n const writeStream = createWriteStream(destinationPath);\r\n let input: NodeJS.ReadableStream | null = null;\r\n const unknownBody: unknown = body;\r\n\r\n if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"pipe\" in unknownBody &&\r\n typeof (unknownBody as { pipe?: unknown }).pipe === \"function\"\r\n ) {\r\n input = unknownBody as NodeJS.ReadableStream;\r\n } else if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"getReader\" in unknownBody &&\r\n typeof (unknownBody as { getReader?: unknown }).getReader === \"function\"\r\n ) {\r\n input = Readable.fromWeb(unknownBody as unknown as globalThis.ReadableStream);\r\n } else if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"stream\" in unknownBody &&\r\n typeof (unknownBody as { stream?: unknown }).stream === \"function\"\r\n ) {\r\n input = Readable.fromWeb(\r\n (unknownBody as { stream: () => globalThis.ReadableStream }).stream()\r\n );\r\n }\r\n\r\n if (input) {\r\n await pipeline(input, writeStream);\r\n return ok(destinationPath);\r\n }\r\n\r\n if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"arrayBuffer\" in unknownBody &&\r\n typeof (unknownBody as { arrayBuffer?: unknown }).arrayBuffer === \"function\"\r\n ) {\r\n const buffer = Buffer.from(\r\n await (unknownBody as { arrayBuffer: () => Promise<ArrayBuffer> }).arrayBuffer()\r\n );\r\n await pipeline(Readable.from(buffer), writeStream);\r\n return ok(destinationPath);\r\n }\r\n\r\n return this.error(\"INTERNAL_SERVER_ERROR\", \"Unsupported S3 body type\");\r\n });\r\n }\r\n\r\n getFileType(path: string): { fileType: keyof typeof fileTypes; extension: string } | undefined {\r\n // determine the type of the file\r\n const extension = path.split(\".\").pop();\r\n if (!extension) return undefined;\r\n\r\n for (const [key, value] of Object.entries(fileTypes)) {\r\n if (value.extensions.includes(extension)) {\r\n return { fileType: key, extension };\r\n }\r\n }\r\n return undefined;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;AAaA,IAAa,cAAb,cAAiCA,sCAAAA,YAA6C;CAC5E,SAAS,MAAuB;AAC9B,SAAO,KAAK,WAAW,OAAO;;CAGhC,YAAY,QAAgE;AAC1E,MAAI,CAAC,KAAK,SAAS,OAAO,CACxB,QAAO,KAAK,MAAM,eAAe,kBAAkB;EAErD,MAAM,CAAC,QAAQ,QAAQ,OAAO,MAAM,OAAO,CAAC,GAAG,MAAM,KAAK;AAC1D,UAAA,GAAA,WAAA,IAAU;GAAE;GAAQ;GAAM,CAAC;;CAG7B,WAAW,MAAc,QAAwB;AAC/C,SAAO,OAAO,OAAO,IAAI;;CAG3B,eACE,UACA,UACA,YAAY,KACe;AAC3B,SAAO,KAAK,WAAW,KAAK,eAAe,UAAU,UAAU,UAAU;;CAG3E,iBAAiB,MAAc,YAAY,KAAmC;AAC5E,SAAO,KAAK,WAAW,KAAK,iBAAiB,MAAM,UAAU;;CAG/D,YAAY,MAAc;AACxB,SAAO,KAAK,WAAW,KAAK,YAAY,KAAK;;CAG/C,eAAe,MAAc;AAC3B,SAAO,KAAK,WAAW,KAAK,eAAe,KAAK;;CAGlD,MAAM,eAAe,WAAmB,oBAAoB,OAAkC;AAC5F,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,YAAY,UAAU,MAAM,IAAI,CAAC,KAAK,EAAE,aAAa;GAC3D,MAAM,WAAW,IAAA,GAAA,KAAA,KAAW,GAAG,YAAY,IAAI,cAAc;GAgB7D,MAAM,WAAY,aAdwB;IACxC,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACN,CACwC,cAAe;GAExD,MAAM,YAAY,MAAM,KAAK,eAAe,UAAU,SAAS;AAC/D,OAAI,UAAU,OAAO,CAAE,SAAA,GAAA,WAAA,KAAW,UAAU,MAAM;GAElD,MAAM,OAAO,OAAA,GAAA,iBAAA,UAAe,UAAU;GACtC,MAAM,MAAM,MAAM,MAAM,UAAU,OAAO;IACvC,QAAQ;IACR,MAAM;IACN,SAAS,EAAE,gBAAgB,UAAU;IACtC,CAAC;AACF,OAAI,CAAC,IAAI,GACP,QAAO,KAAK,MAAM,yBAAyB,2BAA2B,IAAI,SAAS;AAErF,OAAI,mBAAmB;IACrB,MAAM,cAAc,MAAM,KAAK,iBAAiB,SAAS;AACzD,QAAI,YAAY,OAAO,CAAE,SAAA,GAAA,WAAA,KAAW,YAAY,MAAM;AACtD,YAAA,GAAA,WAAA,IAAU,YAAY,MAAM;;AAG9B,WAAA,GAAA,WAAA,IAAU,SAAS;IACnB;;CAGJ,MAAM,iBAAiB,QAA2C;AAChE,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,YAAY,OAAO,MAAM,IAAI,CAAC,KAAK;GACzC,MAAM,kBAAkBC,UAAAA,QAAK,MAAA,GAAA,QAAA,SACnB,EACR,gBACA,IAAA,GAAA,KAAA,KAAW,GAAG,YAAY,IAAI,cAAc,KAC7C;GAED,MAAM,SAAS,MAAM,KAAK,WAAW,KAAK,YAAY,OAAO;AAC7D,OAAI,OAAO,OAAO,CAAE,SAAA,GAAA,WAAA,KAAW,OAAO,MAAM;GAE5C,MAAM,OAAO,OAAO,MAAM;AAC1B,OAAI,CAAC,KAAM,QAAO,KAAK,MAAM,aAAa,0BAA0B;AAEpE,UAAA,GAAA,iBAAA,QAAA,GAAA,UAAA,SAAoB,gBAAgB,EAAE,EAAE,WAAW,MAAM,CAAC;AAG1D,OACE,OAAO,SAAS,YAChB,0BAA0B,QAC1B,OAAO,KAAK,yBAAyB,YACrC;AAEA,WAAA,GAAA,iBAAA,WAAgB,iBADF,MAAM,KAAK,sBAAsB,CACR;AACvC,YAAA,GAAA,WAAA,IAAU,gBAAgB;;GAI5B,MAAM,eAAA,GAAA,QAAA,mBAAgC,gBAAgB;GACtD,IAAI,QAAsC;GAC1C,MAAM,cAAuB;AAE7B,OACE,OAAO,gBAAgB,YACvB,gBAAgB,QAChB,UAAU,eACV,OAAQ,YAAmC,SAAS,WAEpD,SAAQ;YAER,OAAO,gBAAgB,YACvB,gBAAgB,QAChB,eAAe,eACf,OAAQ,YAAwC,cAAc,WAE9D,SAAQC,YAAAA,SAAS,QAAQ,YAAoD;YAE7E,OAAO,gBAAgB,YACvB,gBAAgB,QAChB,YAAY,eACZ,OAAQ,YAAqC,WAAW,WAExD,SAAQA,YAAAA,SAAS,QACd,YAA4D,QAAQ,CACtE;AAGH,OAAI,OAAO;AACT,WAAA,GAAA,qBAAA,UAAe,OAAO,YAAY;AAClC,YAAA,GAAA,WAAA,IAAU,gBAAgB;;AAG5B,OACE,OAAO,gBAAgB,YACvB,gBAAgB,QAChB,iBAAiB,eACjB,OAAQ,YAA0C,gBAAgB,YAClE;IACA,MAAM,SAAS,OAAO,KACpB,MAAO,YAA4D,aAAa,CACjF;AACD,WAAA,GAAA,qBAAA,UAAeA,YAAAA,SAAS,KAAK,OAAO,EAAE,YAAY;AAClD,YAAA,GAAA,WAAA,IAAU,gBAAgB;;AAG5B,UAAO,KAAK,MAAM,yBAAyB,2BAA2B;IACtE;;CAGJ,YAAY,MAAmF;EAE7F,MAAM,YAAY,KAAK,MAAM,IAAI,CAAC,KAAK;AACvC,MAAI,CAAC,UAAW,QAAO,KAAA;AAEvB,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQC,4CAAAA,UAAU,CAClD,KAAI,MAAM,WAAW,SAAS,UAAU,CACtC,QAAO;GAAE,UAAU;GAAK;GAAW"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ServerResult, ServerResultAsync } from "../base/base.dto.cjs";
|
|
2
|
+
import { BaseService } from "../base/base.service.cjs";
|
|
3
|
+
import { FileRepository } from "./file.repository.cjs";
|
|
4
|
+
import * as _$_aws_sdk_client_s30 from "@aws-sdk/client-s3";
|
|
5
|
+
import { fileTypes } from "@m5kdev/commons/modules/file/file.constants";
|
|
6
|
+
|
|
7
|
+
//#region src/modules/file/file.service.d.ts
|
|
8
|
+
declare class FileService extends BaseService<{
|
|
9
|
+
file: FileRepository;
|
|
10
|
+
}, never> {
|
|
11
|
+
isS3Path(path: string): boolean;
|
|
12
|
+
parseS3Path(S3Path: string): ServerResult<{
|
|
13
|
+
bucket: string;
|
|
14
|
+
path: string;
|
|
15
|
+
}>;
|
|
16
|
+
wrapS3Path(path: string, bucket: string): string;
|
|
17
|
+
getS3UploadUrl(filename: string, filetype: string, expiresIn?: number): ServerResultAsync<string>;
|
|
18
|
+
getS3DownloadUrl(path: string, expiresIn?: number): ServerResultAsync<string>;
|
|
19
|
+
getS3Object(path: string): ServerResultAsync<_$_aws_sdk_client_s30.GetObjectCommandOutput>;
|
|
20
|
+
deleteS3Object(path: string): ServerResultAsync<void>;
|
|
21
|
+
uploadFileToS3(localPath: string, returnDownloadUrl?: boolean): ServerResultAsync<string>;
|
|
22
|
+
downloadS3ToFile(s3Path: string): ServerResultAsync<string>;
|
|
23
|
+
getFileType(path: string): {
|
|
24
|
+
fileType: keyof typeof fileTypes;
|
|
25
|
+
extension: string;
|
|
26
|
+
} | undefined;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { FileService };
|
|
30
|
+
//# sourceMappingURL=file.service.d.cts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_modules_auth_auth_db = require("../auth/auth.db.cjs");
|
|
4
|
+
let drizzle_orm_sqlite_core = require("drizzle-orm/sqlite-core");
|
|
5
|
+
let uuid = require("uuid");
|
|
6
|
+
//#region src/modules/recurrence/recurrence.db.ts
|
|
7
|
+
var recurrence_db_exports = /* @__PURE__ */ require_runtime.__exportAll({
|
|
8
|
+
recurrence: () => recurrence,
|
|
9
|
+
recurrenceRules: () => recurrenceRules
|
|
10
|
+
});
|
|
11
|
+
const recurrence = (0, drizzle_orm_sqlite_core.sqliteTable)("recurrence", {
|
|
12
|
+
id: (0, drizzle_orm_sqlite_core.text)("id").primaryKey().$default(uuid.v4),
|
|
13
|
+
userId: (0, drizzle_orm_sqlite_core.text)("user_id").references(() => require_src_modules_auth_auth_db.users.id, { onDelete: "cascade" }),
|
|
14
|
+
organizationId: (0, drizzle_orm_sqlite_core.text)("organization_id").references(() => require_src_modules_auth_auth_db.organizations.id, { onDelete: "cascade" }),
|
|
15
|
+
teamId: (0, drizzle_orm_sqlite_core.text)("team_id").references(() => require_src_modules_auth_auth_db.teams.id, { onDelete: "cascade" }),
|
|
16
|
+
name: (0, drizzle_orm_sqlite_core.text)("name"),
|
|
17
|
+
kind: (0, drizzle_orm_sqlite_core.text)("kind"),
|
|
18
|
+
enabled: (0, drizzle_orm_sqlite_core.integer)("enabled", { mode: "boolean" }).notNull().default(true),
|
|
19
|
+
createdAt: (0, drizzle_orm_sqlite_core.integer)("created_at", { mode: "timestamp" }).notNull().$default(() => /* @__PURE__ */ new Date()),
|
|
20
|
+
updatedAt: (0, drizzle_orm_sqlite_core.integer)("updated_at", { mode: "timestamp" }).notNull().$default(() => /* @__PURE__ */ new Date()),
|
|
21
|
+
metadata: (0, drizzle_orm_sqlite_core.text)("metadata", { mode: "json" }).$type()
|
|
22
|
+
});
|
|
23
|
+
const recurrenceRules = (0, drizzle_orm_sqlite_core.sqliteTable)("recurrence_rules", {
|
|
24
|
+
id: (0, drizzle_orm_sqlite_core.text)("id").primaryKey().$default(uuid.v4),
|
|
25
|
+
createdAt: (0, drizzle_orm_sqlite_core.integer)("created_at", { mode: "timestamp" }).notNull().$default(() => /* @__PURE__ */ new Date()),
|
|
26
|
+
updatedAt: (0, drizzle_orm_sqlite_core.integer)("updated_at", { mode: "timestamp" }).notNull().$default(() => /* @__PURE__ */ new Date()),
|
|
27
|
+
recurrenceId: (0, drizzle_orm_sqlite_core.text)("recurrence_id").references(() => recurrence.id, { onDelete: "cascade" }),
|
|
28
|
+
freq: (0, drizzle_orm_sqlite_core.integer)("freq").notNull(),
|
|
29
|
+
dtstart: (0, drizzle_orm_sqlite_core.integer)("dtstart", { mode: "timestamp" }),
|
|
30
|
+
interval: (0, drizzle_orm_sqlite_core.integer)("interval").notNull().default(1),
|
|
31
|
+
wkst: (0, drizzle_orm_sqlite_core.integer)("wkst"),
|
|
32
|
+
count: (0, drizzle_orm_sqlite_core.integer)("count"),
|
|
33
|
+
until: (0, drizzle_orm_sqlite_core.integer)("until", { mode: "timestamp" }),
|
|
34
|
+
tzid: (0, drizzle_orm_sqlite_core.text)("tzid"),
|
|
35
|
+
bysetpos: (0, drizzle_orm_sqlite_core.text)("bysetpos", { mode: "json" }).$type(),
|
|
36
|
+
bymonth: (0, drizzle_orm_sqlite_core.text)("bymonth", { mode: "json" }).$type(),
|
|
37
|
+
bymonthday: (0, drizzle_orm_sqlite_core.text)("bymonthday", { mode: "json" }).$type(),
|
|
38
|
+
byyearday: (0, drizzle_orm_sqlite_core.text)("byyearday", { mode: "json" }).$type(),
|
|
39
|
+
byweekno: (0, drizzle_orm_sqlite_core.text)("byweekno", { mode: "json" }).$type(),
|
|
40
|
+
byweekday: (0, drizzle_orm_sqlite_core.text)("byweekday", { mode: "json" }).$type(),
|
|
41
|
+
byhour: (0, drizzle_orm_sqlite_core.text)("byhour", { mode: "json" }).$type(),
|
|
42
|
+
byminute: (0, drizzle_orm_sqlite_core.text)("byminute", { mode: "json" }).$type(),
|
|
43
|
+
bysecond: (0, drizzle_orm_sqlite_core.text)("bysecond", { mode: "json" }).$type()
|
|
44
|
+
});
|
|
45
|
+
//#endregion
|
|
46
|
+
exports.recurrence = recurrence;
|
|
47
|
+
exports.recurrenceRules = recurrenceRules;
|
|
48
|
+
Object.defineProperty(exports, "recurrence_db_exports", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function() {
|
|
51
|
+
return recurrence_db_exports;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=recurrence.db.cjs.map
|