@m5kdev/backend 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +18 -0
  3. package/dist/src/lib/posthog.js +7 -0
  4. package/dist/src/lib/sentry.js +9 -0
  5. package/dist/src/modules/access/access.repository.js +32 -0
  6. package/dist/src/modules/access/access.service.js +51 -0
  7. package/dist/src/modules/access/access.test.js +182 -0
  8. package/dist/src/modules/access/access.utils.js +20 -0
  9. package/dist/src/modules/ai/ai.db.js +39 -0
  10. package/dist/src/modules/ai/ai.prompt.js +30 -0
  11. package/dist/src/modules/ai/ai.repository.js +26 -0
  12. package/dist/src/modules/ai/ai.router.js +132 -0
  13. package/dist/src/modules/ai/ai.service.js +207 -0
  14. package/dist/src/modules/ai/ai.trpc.d.ts +5 -5
  15. package/dist/src/modules/ai/ai.trpc.js +20 -0
  16. package/dist/src/modules/ai/ideogram/ideogram.constants.js +167 -0
  17. package/dist/src/modules/ai/ideogram/ideogram.dto.js +49 -0
  18. package/dist/src/modules/ai/ideogram/ideogram.prompt.js +860 -0
  19. package/dist/src/modules/ai/ideogram/ideogram.repository.js +46 -0
  20. package/dist/src/modules/ai/ideogram/ideogram.service.js +11 -0
  21. package/dist/src/modules/auth/auth.db.js +215 -0
  22. package/dist/src/modules/auth/auth.dto.js +38 -0
  23. package/dist/src/modules/auth/auth.lib.d.ts +4 -4
  24. package/dist/src/modules/auth/auth.lib.js +284 -0
  25. package/dist/src/modules/auth/auth.middleware.js +52 -0
  26. package/dist/src/modules/auth/auth.repository.js +541 -0
  27. package/dist/src/modules/auth/auth.service.js +201 -0
  28. package/dist/src/modules/auth/auth.trpc.d.ts +18 -18
  29. package/dist/src/modules/auth/auth.trpc.js +157 -0
  30. package/dist/src/modules/auth/auth.utils.js +97 -0
  31. package/dist/src/modules/base/base.abstract.js +53 -0
  32. package/dist/src/modules/base/base.dto.js +112 -0
  33. package/dist/src/modules/base/base.grants.js +123 -0
  34. package/dist/src/modules/base/base.grants.test.js +668 -0
  35. package/dist/src/modules/base/base.repository.js +307 -0
  36. package/dist/src/modules/base/base.service.js +109 -0
  37. package/dist/src/modules/base/base.types.js +2 -0
  38. package/dist/src/modules/billing/billing.db.js +29 -0
  39. package/dist/src/modules/billing/billing.repository.js +235 -0
  40. package/dist/src/modules/billing/billing.router.js +56 -0
  41. package/dist/src/modules/billing/billing.service.js +147 -0
  42. package/dist/src/modules/billing/billing.trpc.d.ts +5 -5
  43. package/dist/src/modules/billing/billing.trpc.js +17 -0
  44. package/dist/src/modules/clay/clay.repository.js +26 -0
  45. package/dist/src/modules/clay/clay.service.js +24 -0
  46. package/dist/src/modules/connect/connect.db.js +30 -0
  47. package/dist/src/modules/connect/connect.dto.js +36 -0
  48. package/dist/src/modules/connect/connect.linkedin.js +53 -0
  49. package/dist/src/modules/connect/connect.oauth.js +198 -0
  50. package/dist/src/modules/connect/connect.repository.d.ts +7 -7
  51. package/dist/src/modules/connect/connect.repository.js +54 -0
  52. package/dist/src/modules/connect/connect.router.js +54 -0
  53. package/dist/src/modules/connect/connect.service.d.ts +14 -14
  54. package/dist/src/modules/connect/connect.service.js +114 -0
  55. package/dist/src/modules/connect/connect.trpc.d.ts +10 -10
  56. package/dist/src/modules/connect/connect.trpc.js +21 -0
  57. package/dist/src/modules/connect/connect.types.js +2 -0
  58. package/dist/src/modules/crypto/crypto.db.js +17 -0
  59. package/dist/src/modules/crypto/crypto.repository.js +10 -0
  60. package/dist/src/modules/crypto/crypto.service.js +52 -0
  61. package/dist/src/modules/email/email.service.js +107 -0
  62. package/dist/src/modules/file/file.repository.js +79 -0
  63. package/dist/src/modules/file/file.router.js +99 -0
  64. package/dist/src/modules/file/file.service.js +150 -0
  65. package/dist/src/modules/recurrence/recurrence.db.js +66 -0
  66. package/dist/src/modules/recurrence/recurrence.repository.js +39 -0
  67. package/dist/src/modules/recurrence/recurrence.service.js +70 -0
  68. package/dist/src/modules/recurrence/recurrence.trpc.d.ts +15 -15
  69. package/dist/src/modules/recurrence/recurrence.trpc.js +65 -0
  70. package/dist/src/modules/social/social.dto.js +18 -0
  71. package/dist/src/modules/social/social.linkedin.js +427 -0
  72. package/dist/src/modules/social/social.linkedin.test.js +235 -0
  73. package/dist/src/modules/social/social.service.js +76 -0
  74. package/dist/src/modules/social/social.types.js +2 -0
  75. package/dist/src/modules/tag/tag.db.js +42 -0
  76. package/dist/src/modules/tag/tag.dto.js +9 -0
  77. package/dist/src/modules/tag/tag.repository.js +154 -0
  78. package/dist/src/modules/tag/tag.service.js +31 -0
  79. package/dist/src/modules/tag/tag.trpc.d.ts +5 -5
  80. package/dist/src/modules/tag/tag.trpc.js +47 -0
  81. package/dist/src/modules/utils/applyPagination.js +16 -0
  82. package/dist/src/modules/utils/applySorting.js +18 -0
  83. package/dist/src/modules/utils/getConditionsFromFilters.js +200 -0
  84. package/dist/src/modules/video/video.service.js +84 -0
  85. package/dist/src/modules/webhook/webhook.constants.js +10 -0
  86. package/dist/src/modules/webhook/webhook.db.js +17 -0
  87. package/dist/src/modules/webhook/webhook.dto.js +7 -0
  88. package/dist/src/modules/webhook/webhook.repository.js +56 -0
  89. package/dist/src/modules/webhook/webhook.router.js +30 -0
  90. package/dist/src/modules/webhook/webhook.service.js +68 -0
  91. package/dist/src/modules/workflow/workflow.db.js +30 -0
  92. package/dist/src/modules/workflow/workflow.repository.js +105 -0
  93. package/dist/src/modules/workflow/workflow.service.js +37 -0
  94. package/dist/src/modules/workflow/workflow.trpc.d.ts +5 -5
  95. package/dist/src/modules/workflow/workflow.trpc.js +21 -0
  96. package/dist/src/modules/workflow/workflow.types.js +2 -0
  97. package/dist/src/modules/workflow/workflow.utils.js +173 -0
  98. package/dist/src/test/stubs/utils.js +5 -0
  99. package/dist/src/trpc/context.d.ts +5 -5
  100. package/dist/src/trpc/context.js +17 -0
  101. package/dist/src/trpc/index.js +6 -0
  102. package/dist/src/trpc/procedures.d.ts +56 -56
  103. package/dist/src/trpc/procedures.js +32 -0
  104. package/dist/src/trpc/utils.js +20 -0
  105. package/dist/src/types.d.ts +33 -33
  106. package/dist/src/types.js +13 -0
  107. package/dist/src/utils/errors.js +104 -0
  108. package/dist/src/utils/logger.js +11 -0
  109. package/dist/src/utils/posthog.js +31 -0
  110. package/dist/src/utils/types.js +2 -0
  111. package/dist/tsconfig.tsbuildinfo +1 -1
  112. package/package.json +3 -3
  113. package/tsconfig.json +2 -0
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VideoService = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
7
+ //
8
+ const ffmpeg_ffprobe_static_1 = tslib_1.__importDefault(require("ffmpeg-ffprobe-static"));
9
+ const fluent_ffmpeg_1 = tslib_1.__importDefault(require("fluent-ffmpeg"));
10
+ const neverthrow_1 = require("neverthrow");
11
+ const uuid_1 = require("uuid");
12
+ const base_service_1 = require("#modules/base/base.service");
13
+ if (!ffmpeg_ffprobe_static_1.default.ffmpegPath || !ffmpeg_ffprobe_static_1.default.ffprobePath) {
14
+ throw new Error("FFmpeg or FFprobe not found");
15
+ }
16
+ fluent_ffmpeg_1.default.setFfmpegPath(ffmpeg_ffprobe_static_1.default.ffmpegPath);
17
+ fluent_ffmpeg_1.default.setFfprobePath(ffmpeg_ffprobe_static_1.default.ffprobePath);
18
+ const uploadsDir = node_path_1.default.join(__dirname, "..", "uploads");
19
+ if (!(0, node_fs_1.existsSync)(uploadsDir)) {
20
+ (0, node_fs_1.mkdirSync)(uploadsDir, { recursive: true });
21
+ }
22
+ class VideoService extends base_service_1.BaseService {
23
+ async cut(file, start, end) {
24
+ return this.throwableAsync(async () => {
25
+ const duration = end - start;
26
+ const output = node_path_1.default.join(uploadsDir, `${(0, uuid_1.v4)()}.mp4`);
27
+ if (!(0, node_fs_1.existsSync)(output)) {
28
+ (0, node_fs_1.closeSync)((0, node_fs_1.openSync)(output, "w"));
29
+ }
30
+ await new Promise((resolve, reject) => {
31
+ (0, fluent_ffmpeg_1.default)(file)
32
+ .seekOutput(start)
33
+ .videoCodec("libx264")
34
+ .audioCodec("copy")
35
+ .outputOptions(["-y", "-movflags +faststart"])
36
+ .duration(duration)
37
+ .on("end", () => resolve())
38
+ .on("error", (e, _stdout, _stderr) => reject(e))
39
+ .save(output);
40
+ }).catch((error) => (0, neverthrow_1.err)(this.handleUnknownError(error)));
41
+ return (0, neverthrow_1.ok)(output);
42
+ });
43
+ }
44
+ async webmToWav(input, hz = 48000) {
45
+ return this.throwableAsync(async () => {
46
+ const output = node_path_1.default.join(uploadsDir, `${(0, uuid_1.v4)()}.wav`);
47
+ if (!(0, node_fs_1.existsSync)(output)) {
48
+ (0, node_fs_1.closeSync)((0, node_fs_1.openSync)(output, "w"));
49
+ }
50
+ await new Promise((resolve, reject) => {
51
+ (0, fluent_ffmpeg_1.default)(input)
52
+ .noVideo()
53
+ .audioCodec("pcm_s16le") // WAV PCM 16-bit
54
+ .audioFrequency(hz) // 48000 or 44100
55
+ .audioChannels(2) // down/up-mix as needed
56
+ .format("wav")
57
+ .outputOptions(["-y"])
58
+ .on("end", () => resolve())
59
+ .on("error", reject)
60
+ .save(output);
61
+ }).catch((error) => (0, neverthrow_1.err)(this.handleUnknownError(error)));
62
+ return (0, neverthrow_1.ok)(output);
63
+ });
64
+ }
65
+ async extractAudioMp3(input, kbps = 192, streamIndex = 0) {
66
+ return this.throwableAsync(async () => {
67
+ const output = node_path_1.default.join(uploadsDir, `${(0, uuid_1.v4)()}.mp3`);
68
+ if (!(0, node_fs_1.existsSync)(output)) {
69
+ (0, node_fs_1.closeSync)((0, node_fs_1.openSync)(output, "w"));
70
+ }
71
+ await new Promise((resolve, reject) => {
72
+ (0, fluent_ffmpeg_1.default)(input)
73
+ .outputOptions(["-y", `-map 0:a:${streamIndex}`])
74
+ .audioCodec("libmp3lame")
75
+ .audioBitrate(kbps)
76
+ .on("end", () => resolve())
77
+ .on("error", reject)
78
+ .save(output);
79
+ }).catch((error) => (0, neverthrow_1.err)(this.handleUnknownError(error)));
80
+ return (0, neverthrow_1.ok)(output);
81
+ });
82
+ }
83
+ }
84
+ exports.VideoService = VideoService;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WEBHOOK_STATUS_ENUM = void 0;
4
+ exports.WEBHOOK_STATUS_ENUM = {
5
+ WAITING: "WAITING",
6
+ COMPLETED: "COMPLETED",
7
+ TIMEOUT: "TIMEOUT",
8
+ ERROR_CALLBACK: "ERROR_CALLBACK",
9
+ ERROR_DATA: "ERROR_DATA",
10
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webhook = void 0;
4
+ const sqlite_core_1 = require("drizzle-orm/sqlite-core");
5
+ const uuid_1 = require("uuid");
6
+ const webhook_constants_1 = require("./webhook.constants");
7
+ exports.webhook = (0, sqlite_core_1.sqliteTable)("webhook", {
8
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
9
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
10
+ .notNull()
11
+ .$default(() => new Date()),
12
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" }),
13
+ timeoutSec: (0, sqlite_core_1.integer)("timeout_sec").notNull().default(60),
14
+ status: (0, sqlite_core_1.text)("status").notNull().default(webhook_constants_1.WEBHOOK_STATUS_ENUM.WAITING).$type(),
15
+ error: (0, sqlite_core_1.text)("error"),
16
+ payload: (0, sqlite_core_1.text)("payload"),
17
+ });
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webhookSelectSchema = exports.webhookSelectDTO = void 0;
4
+ const base_dto_1 = require("#modules/base/base.dto");
5
+ const webhook_db_1 = require("./webhook.db");
6
+ exports.webhookSelectDTO = (0, base_dto_1.createSelectDTO)(webhook_db_1.webhook);
7
+ exports.webhookSelectSchema = exports.webhookSelectDTO.schema;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebhookRepository = void 0;
4
+ const neverthrow_1 = require("neverthrow");
5
+ const base_repository_1 = require("#modules/base/base.repository");
6
+ const webhook_constants_1 = require("./webhook.constants");
7
+ const webhook_db_1 = require("./webhook.db");
8
+ const schema = { webhook: webhook_db_1.webhook };
9
+ class WebhookRepository extends base_repository_1.BaseTableRepository {
10
+ async completed(id, payload, tx) {
11
+ return this.throwableAsync(async () => {
12
+ const webhook = await this.findById(id, tx);
13
+ if (webhook.isErr())
14
+ return (0, neverthrow_1.err)(webhook.error);
15
+ if (!webhook.value)
16
+ return this.error("NOT_FOUND");
17
+ await this.update({
18
+ id,
19
+ status: webhook_constants_1.WEBHOOK_STATUS_ENUM.COMPLETED,
20
+ payload: JSON.stringify(payload),
21
+ }, tx);
22
+ return (0, neverthrow_1.ok)();
23
+ });
24
+ }
25
+ async timeout(id, tx) {
26
+ return this.throwableAsync(async () => {
27
+ const webhook = await this.findById(id, tx);
28
+ if (webhook.isErr())
29
+ return (0, neverthrow_1.err)(webhook.error);
30
+ if (!webhook.value)
31
+ return this.error("NOT_FOUND");
32
+ await this.update({
33
+ id,
34
+ status: webhook_constants_1.WEBHOOK_STATUS_ENUM.TIMEOUT,
35
+ error: `Timeout of ${webhook.value.timeoutSec} seconds reached`,
36
+ }, tx);
37
+ return (0, neverthrow_1.ok)();
38
+ });
39
+ }
40
+ async registerError(id, status, error, tx) {
41
+ return this.throwableAsync(async () => {
42
+ const webhook = await this.findById(id, tx);
43
+ if (webhook.isErr())
44
+ return (0, neverthrow_1.err)(webhook.error);
45
+ if (!webhook.value)
46
+ return this.error("NOT_FOUND");
47
+ await this.update({
48
+ id,
49
+ status,
50
+ error,
51
+ }, tx);
52
+ return (0, neverthrow_1.ok)();
53
+ });
54
+ }
55
+ }
56
+ exports.WebhookRepository = WebhookRepository;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createWebhookRouter = createWebhookRouter;
4
+ const tslib_1 = require("tslib");
5
+ const body_parser_1 = tslib_1.__importDefault(require("body-parser"));
6
+ const express_1 = require("express");
7
+ function createWebhookRouter(webhookService) {
8
+ const webhookRouter = (0, express_1.Router)();
9
+ webhookRouter.post("/:id", body_parser_1.default.json(), async (req, res) => {
10
+ const { authorization } = req.headers;
11
+ if (!authorization)
12
+ return res.status(401).json({ message: "Missing authorization header" });
13
+ if (typeof authorization !== "string")
14
+ return res.status(401).json({ message: "Authorization header is not a string" });
15
+ if (!authorization.startsWith("Bearer "))
16
+ return res.status(401).json({ message: "Invalid authorization header" });
17
+ const token = authorization.split(" ")[1];
18
+ if (!token)
19
+ return res.status(401).json({ message: "Missing token" });
20
+ if (token !== process.env.WEBHOOK_SECRET)
21
+ return res.status(401).json({ message: "Invalid token" });
22
+ const result = await webhookService.completed(req.params.id, req.body);
23
+ if (result.isErr())
24
+ return res
25
+ .status(result.error.getHTTPStatusCode() || 500)
26
+ .json({ message: result.error.message });
27
+ return res.status(200).json({ message: "Webhook completed" });
28
+ });
29
+ return webhookRouter;
30
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebhookService = void 0;
4
+ const json_1 = require("@m5kdev/commons/utils/json");
5
+ const neverthrow_1 = require("neverthrow");
6
+ const base_service_1 = require("#modules/base/base.service");
7
+ const webhook_constants_1 = require("./webhook.constants");
8
+ class WebhookService extends base_service_1.BaseService {
9
+ async completed(id, payload) {
10
+ const result = await this.repository.webhook.completed(id, payload);
11
+ if (result.isErr()) {
12
+ await this.repository.webhook.registerError(id, webhook_constants_1.WEBHOOK_STATUS_ENUM.ERROR_DATA, JSON.stringify(result.error));
13
+ return this.error("INTERNAL_SERVER_ERROR", "Webhook completed failed", {
14
+ cause: result.error,
15
+ });
16
+ }
17
+ return (0, neverthrow_1.ok)();
18
+ }
19
+ async waitForRequest(callback, timeoutSec = 60) {
20
+ const webhook = await this.repository.webhook.create({
21
+ timeoutSec,
22
+ });
23
+ if (webhook.isErr())
24
+ return Promise.reject(webhook.error);
25
+ const url = `${process.env.NGROK_LOCALHOST_TUNNEL || process.env.VITE_SERVER_URL}/webhook/${webhook.value.id}`;
26
+ try {
27
+ await callback(url);
28
+ }
29
+ catch (error) {
30
+ await this.repository.webhook.registerError(webhook.value.id, webhook_constants_1.WEBHOOK_STATUS_ENUM.ERROR_CALLBACK, JSON.stringify(error));
31
+ return this.error("INTERNAL_SERVER_ERROR", "Error callback failed", { cause: error });
32
+ }
33
+ const startTime = new Date(webhook.value.createdAt).getTime();
34
+ const endTime = startTime + timeoutSec * 1000;
35
+ const promise = await new Promise((resolve, reject) => {
36
+ const intervalId = setInterval(async () => {
37
+ const currentTime = Date.now();
38
+ // Check if the timeout is reached
39
+ if (currentTime > endTime) {
40
+ await this.repository.webhook.timeout(webhook.value.id);
41
+ clearInterval(intervalId);
42
+ return reject(this.error("TIMEOUT", "Wait for request timeout"));
43
+ }
44
+ const result = await this.repository.webhook.findById(webhook.value.id);
45
+ if (result.isErr()) {
46
+ clearInterval(intervalId);
47
+ return reject((0, neverthrow_1.err)(result.error));
48
+ }
49
+ if (!result.value) {
50
+ clearInterval(intervalId);
51
+ return reject(this.error("NOT_FOUND", "Wait for request failed: cannot find webhook"));
52
+ }
53
+ const { status, payload } = result.value;
54
+ if (status === "COMPLETED") {
55
+ const data = payload ? (0, json_1.safeParseJson)(payload, payload) : payload;
56
+ clearInterval(intervalId);
57
+ return resolve((0, neverthrow_1.ok)(data));
58
+ }
59
+ if (status !== "WAITING") {
60
+ clearInterval(intervalId);
61
+ return reject(this.error("BAD_REQUEST", "Wait for request failed"));
62
+ }
63
+ }, 1000);
64
+ });
65
+ return promise;
66
+ }
67
+ }
68
+ exports.WebhookService = WebhookService;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.workflows = void 0;
4
+ const sqlite_core_1 = require("drizzle-orm/sqlite-core");
5
+ const uuid_1 = require("uuid");
6
+ const auth_db_1 = require("#modules/auth/auth.db");
7
+ exports.workflows = (0, sqlite_core_1.sqliteTable)("workflows", {
8
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
9
+ userId: (0, sqlite_core_1.text)("user_id").references(() => auth_db_1.users.id, { onDelete: "cascade" }),
10
+ jobId: (0, sqlite_core_1.text)("job_id").unique().notNull(),
11
+ jobName: (0, sqlite_core_1.text)("job_name").notNull(),
12
+ queueName: (0, sqlite_core_1.text)("queue_name").notNull(),
13
+ timeout: (0, sqlite_core_1.integer)("timeout"),
14
+ tags: (0, sqlite_core_1.text)("tags", { mode: "json" })
15
+ .$default(() => [])
16
+ .$type(),
17
+ input: (0, sqlite_core_1.text)("input", { mode: "json" }),
18
+ output: (0, sqlite_core_1.text)("output", { mode: "json" }),
19
+ status: (0, sqlite_core_1.text)("status").notNull().$type(),
20
+ error: (0, sqlite_core_1.text)("error"),
21
+ retries: (0, sqlite_core_1.integer)("retries").notNull().default(0),
22
+ finishedAt: (0, sqlite_core_1.integer)("finished_at", { mode: "timestamp" }),
23
+ processedAt: (0, sqlite_core_1.integer)("processed_at", { mode: "timestamp" }),
24
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
25
+ .notNull()
26
+ .$default(() => new Date()),
27
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" })
28
+ .notNull()
29
+ .$default(() => new Date()),
30
+ });
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkflowRepository = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const drizzle_orm_1 = require("drizzle-orm");
6
+ const neverthrow_1 = require("neverthrow");
7
+ const base_repository_1 = require("#modules/base/base.repository");
8
+ const workflow = tslib_1.__importStar(require("#modules/workflow/workflow.db"));
9
+ const schema = { ...workflow };
10
+ class WorkflowRepository extends base_repository_1.BaseRepository {
11
+ async read({ jobId, userId, }) {
12
+ return this.throwableAsync(async () => {
13
+ const [wf] = await this.orm
14
+ .select()
15
+ .from(this.schema.workflows)
16
+ .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(this.schema.workflows.jobId, jobId), (0, drizzle_orm_1.eq)(this.schema.workflows.userId, userId)));
17
+ if (!wf)
18
+ return this.error("NOT_FOUND");
19
+ return (0, neverthrow_1.ok)(wf);
20
+ });
21
+ }
22
+ async list({ userId, status, jobName, }) {
23
+ return this.throwableAsync(async () => {
24
+ const { ConditionBuilder } = this.helpers;
25
+ const condition = new ConditionBuilder([(0, drizzle_orm_1.eq)(this.schema.workflows.userId, userId)]);
26
+ if (status)
27
+ condition.push((0, drizzle_orm_1.inArray)(this.schema.workflows.status, status));
28
+ if (jobName)
29
+ condition.push((0, drizzle_orm_1.eq)(this.schema.workflows.jobName, jobName));
30
+ const workflows = await this.orm.select().from(this.schema.workflows).where(condition.join());
31
+ return (0, neverthrow_1.ok)(workflows);
32
+ });
33
+ }
34
+ async added({ userId, jobId, jobName, queueName, timeout, tags, input, }) {
35
+ return this.throwableAsync(async () => {
36
+ const [wf] = await this.orm
37
+ .insert(this.schema.workflows)
38
+ .values({
39
+ userId,
40
+ jobId,
41
+ jobName,
42
+ input,
43
+ status: "queued",
44
+ queueName,
45
+ timeout,
46
+ tags,
47
+ createdAt: new Date(),
48
+ updatedAt: new Date(),
49
+ })
50
+ .returning();
51
+ return (0, neverthrow_1.ok)(wf);
52
+ });
53
+ }
54
+ async addedMany(data) {
55
+ return this.throwableAsync(async () => {
56
+ const wfs = await this.orm
57
+ .insert(this.schema.workflows)
58
+ .values(data.map((d) => ({
59
+ userId: d.userId,
60
+ jobId: d.jobId,
61
+ jobName: d.jobName,
62
+ queueName: d.queueName,
63
+ timeout: d.timeout,
64
+ tags: d.tags,
65
+ input: d.input,
66
+ status: "queued",
67
+ createdAt: new Date(),
68
+ updatedAt: new Date(),
69
+ })))
70
+ .returning();
71
+ return (0, neverthrow_1.ok)(wfs);
72
+ });
73
+ }
74
+ async started({ jobId }) {
75
+ return this.throwableAsync(async () => {
76
+ const [wf] = await this.orm
77
+ .update(this.schema.workflows)
78
+ .set({ status: "running", updatedAt: new Date(), processedAt: new Date() })
79
+ .where((0, drizzle_orm_1.eq)(this.schema.workflows.jobId, jobId))
80
+ .returning();
81
+ return (0, neverthrow_1.ok)(wf);
82
+ });
83
+ }
84
+ async failed({ jobId, error, }) {
85
+ return this.throwableAsync(async () => {
86
+ const [wf] = await this.orm
87
+ .update(this.schema.workflows)
88
+ .set({ status: "failed", error, updatedAt: new Date(), finishedAt: new Date() })
89
+ .where((0, drizzle_orm_1.eq)(this.schema.workflows.jobId, jobId))
90
+ .returning();
91
+ return (0, neverthrow_1.ok)(wf);
92
+ });
93
+ }
94
+ async completed({ jobId, output, }) {
95
+ return this.throwableAsync(async () => {
96
+ const [wf] = await this.orm
97
+ .update(this.schema.workflows)
98
+ .set({ status: "completed", updatedAt: new Date(), finishedAt: new Date(), output })
99
+ .where((0, drizzle_orm_1.eq)(this.schema.workflows.jobId, jobId))
100
+ .returning();
101
+ return (0, neverthrow_1.ok)(wf);
102
+ });
103
+ }
104
+ }
105
+ exports.WorkflowRepository = WorkflowRepository;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkflowService = void 0;
4
+ const base_service_1 = require("#modules/base/base.service");
5
+ class WorkflowService extends base_service_1.BaseService {
6
+ async read(input, { user }) {
7
+ return await this.repository.workflow.read({ ...input, userId: user.id });
8
+ }
9
+ async list(input, { user }) {
10
+ return await this.repository.workflow.list({ ...input, userId: user.id });
11
+ }
12
+ async added(params) {
13
+ return this.repository.workflow.added(params);
14
+ }
15
+ async addedMany(params) {
16
+ return this.repository.workflow.addedMany(params);
17
+ }
18
+ async started(job) {
19
+ if (!job.id)
20
+ return this.error("INTERNAL_SERVER_ERROR");
21
+ return this.repository.workflow.started({ jobId: job.id });
22
+ }
23
+ async failed(job, error) {
24
+ if (!job?.id)
25
+ return this.error("INTERNAL_SERVER_ERROR");
26
+ return this.repository.workflow.failed({
27
+ jobId: job.id,
28
+ error: error?.message || "Unknown error",
29
+ });
30
+ }
31
+ async completed(job) {
32
+ if (!job.id)
33
+ return this.error("INTERNAL_SERVER_ERROR");
34
+ return this.repository.workflow.completed({ jobId: job.id, output: job.returnvalue });
35
+ }
36
+ }
37
+ exports.WorkflowService = WorkflowService;
@@ -4,9 +4,9 @@ export declare function createWorkflowTRPC(workflowService: WorkflowService): im
4
4
  session: {
5
5
  id: string;
6
6
  userId: string;
7
- expiresAt: Date;
8
- createdAt: Date;
9
7
  updatedAt: Date;
8
+ createdAt: Date;
9
+ expiresAt: Date;
10
10
  token: string;
11
11
  ipAddress: string | null;
12
12
  userAgent: string | null;
@@ -18,13 +18,12 @@ export declare function createWorkflowTRPC(workflowService: WorkflowService): im
18
18
  };
19
19
  user: {
20
20
  name: string;
21
- image: string | null;
22
21
  id: string;
23
- createdAt: Date;
24
22
  updatedAt: Date;
25
23
  email: string;
26
- metadata: Record<string, unknown>;
27
24
  emailVerified: boolean;
25
+ image: string | null;
26
+ createdAt: Date;
28
27
  role: string | null;
29
28
  banned: boolean | null;
30
29
  banReason: string | null;
@@ -34,6 +33,7 @@ export declare function createWorkflowTRPC(workflowService: WorkflowService): im
34
33
  paymentPlanTier: string | null;
35
34
  paymentPlanExpiresAt: Date | null;
36
35
  preferences: string | null;
36
+ metadata: Record<string, unknown>;
37
37
  onboarding: number | null;
38
38
  flags: string | null;
39
39
  };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createWorkflowTRPC = createWorkflowTRPC;
4
+ const workflow_schema_1 = require("@m5kdev/commons/modules/workflow/workflow.schema");
5
+ const _trpc_1 = require("#trpc");
6
+ function createWorkflowTRPC(workflowService) {
7
+ return (0, _trpc_1.router)({
8
+ read: _trpc_1.procedure
9
+ .input(workflow_schema_1.workflowReadInputSchema)
10
+ .output(workflow_schema_1.workflowReadOutputSchema)
11
+ .query(async ({ ctx, input }) => {
12
+ return (0, _trpc_1.handleTRPCResult)(await workflowService.read(input, ctx));
13
+ }),
14
+ list: _trpc_1.procedure
15
+ .input(workflow_schema_1.workflowListInputSchema)
16
+ .output(workflow_schema_1.workflowListOutputSchema)
17
+ .query(async ({ ctx, input }) => {
18
+ return (0, _trpc_1.handleTRPCResult)(await workflowService.list(input, ctx));
19
+ }),
20
+ });
21
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });