@m5kdev/backend 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +621 -0
  2. package/README.md +22 -0
  3. package/package.json +205 -0
  4. package/src/lib/posthog.ts +5 -0
  5. package/src/lib/sentry.ts +8 -0
  6. package/src/modules/access/access.repository.ts +36 -0
  7. package/src/modules/access/access.service.ts +81 -0
  8. package/src/modules/access/access.test.ts +216 -0
  9. package/src/modules/access/access.utils.ts +46 -0
  10. package/src/modules/ai/ai.db.ts +38 -0
  11. package/src/modules/ai/ai.prompt.ts +47 -0
  12. package/src/modules/ai/ai.repository.ts +53 -0
  13. package/src/modules/ai/ai.router.ts +148 -0
  14. package/src/modules/ai/ai.service.ts +310 -0
  15. package/src/modules/ai/ai.trpc.ts +22 -0
  16. package/src/modules/ai/ideogram/ideogram.constants.ts +170 -0
  17. package/src/modules/ai/ideogram/ideogram.dto.ts +64 -0
  18. package/src/modules/ai/ideogram/ideogram.prompt.ts +858 -0
  19. package/src/modules/ai/ideogram/ideogram.repository.ts +39 -0
  20. package/src/modules/ai/ideogram/ideogram.service.ts +14 -0
  21. package/src/modules/auth/auth.db.ts +224 -0
  22. package/src/modules/auth/auth.dto.ts +47 -0
  23. package/src/modules/auth/auth.lib.ts +349 -0
  24. package/src/modules/auth/auth.middleware.ts +62 -0
  25. package/src/modules/auth/auth.repository.ts +672 -0
  26. package/src/modules/auth/auth.service.ts +261 -0
  27. package/src/modules/auth/auth.trpc.ts +208 -0
  28. package/src/modules/auth/auth.utils.ts +117 -0
  29. package/src/modules/base/base.abstract.ts +62 -0
  30. package/src/modules/base/base.dto.ts +206 -0
  31. package/src/modules/base/base.grants.test.ts +861 -0
  32. package/src/modules/base/base.grants.ts +199 -0
  33. package/src/modules/base/base.repository.ts +433 -0
  34. package/src/modules/base/base.service.ts +154 -0
  35. package/src/modules/base/base.types.ts +7 -0
  36. package/src/modules/billing/billing.db.ts +27 -0
  37. package/src/modules/billing/billing.repository.ts +328 -0
  38. package/src/modules/billing/billing.router.ts +77 -0
  39. package/src/modules/billing/billing.service.ts +177 -0
  40. package/src/modules/billing/billing.trpc.ts +17 -0
  41. package/src/modules/clay/clay.repository.ts +29 -0
  42. package/src/modules/clay/clay.service.ts +61 -0
  43. package/src/modules/connect/connect.db.ts +32 -0
  44. package/src/modules/connect/connect.dto.ts +44 -0
  45. package/src/modules/connect/connect.linkedin.ts +70 -0
  46. package/src/modules/connect/connect.oauth.ts +288 -0
  47. package/src/modules/connect/connect.repository.ts +65 -0
  48. package/src/modules/connect/connect.router.ts +76 -0
  49. package/src/modules/connect/connect.service.ts +171 -0
  50. package/src/modules/connect/connect.trpc.ts +26 -0
  51. package/src/modules/connect/connect.types.ts +27 -0
  52. package/src/modules/crypto/crypto.db.ts +15 -0
  53. package/src/modules/crypto/crypto.repository.ts +13 -0
  54. package/src/modules/crypto/crypto.service.ts +57 -0
  55. package/src/modules/email/email.service.ts +222 -0
  56. package/src/modules/file/file.repository.ts +95 -0
  57. package/src/modules/file/file.router.ts +108 -0
  58. package/src/modules/file/file.service.ts +186 -0
  59. package/src/modules/recurrence/recurrence.db.ts +79 -0
  60. package/src/modules/recurrence/recurrence.repository.ts +70 -0
  61. package/src/modules/recurrence/recurrence.service.ts +105 -0
  62. package/src/modules/recurrence/recurrence.trpc.ts +82 -0
  63. package/src/modules/social/social.dto.ts +22 -0
  64. package/src/modules/social/social.linkedin.test.ts +277 -0
  65. package/src/modules/social/social.linkedin.ts +593 -0
  66. package/src/modules/social/social.service.ts +112 -0
  67. package/src/modules/social/social.types.ts +43 -0
  68. package/src/modules/tag/tag.db.ts +41 -0
  69. package/src/modules/tag/tag.dto.ts +18 -0
  70. package/src/modules/tag/tag.repository.ts +222 -0
  71. package/src/modules/tag/tag.service.ts +48 -0
  72. package/src/modules/tag/tag.trpc.ts +62 -0
  73. package/src/modules/uploads/0581796b-8845-420d-bd95-cd7de79f6d37.webm +0 -0
  74. package/src/modules/uploads/33b1e649-6727-4bd0-94d0-a0b363646865.webm +0 -0
  75. package/src/modules/uploads/49a8c4c0-54d7-4c94-bef4-c93c029f9ed0.webm +0 -0
  76. package/src/modules/uploads/50e31e38-a2f0-47ca-8b7d-2d7fcad9267d.webm +0 -0
  77. package/src/modules/uploads/72ac8cf9-c3a7-4cd8-8a78-6d8e137a4c7e.webm +0 -0
  78. package/src/modules/uploads/75293649-d966-46cd-a675-67518958ae9c.png +0 -0
  79. package/src/modules/uploads/88b7b867-ce15-4891-bf73-81305a7de1f7.wav +0 -0
  80. package/src/modules/uploads/a5d6fee8-6a59-42c6-9d4a-ac8a3c5e7245.webm +0 -0
  81. package/src/modules/uploads/c13a9785-ca5a-4983-af30-b338ed76d370.webm +0 -0
  82. package/src/modules/uploads/caa1a5a7-71ba-4381-902d-7e2cafdf6dcb.webm +0 -0
  83. package/src/modules/uploads/cbeb0b81-374d-445b-914b-40ace7c8e031.webm +0 -0
  84. package/src/modules/uploads/d626aa82-b10f-493f-aee7-87bfb3361dfc.webm +0 -0
  85. package/src/modules/uploads/d7de4c16-de0c-495d-9612-e72260a6ecca.png +0 -0
  86. package/src/modules/uploads/e532e38a-6421-400e-8a5f-8e7bc8ce411b.wav +0 -0
  87. package/src/modules/uploads/e86ec867-6adf-4c51-84e0-00b0836625e8.webm +0 -0
  88. package/src/modules/utils/applyPagination.ts +13 -0
  89. package/src/modules/utils/applySorting.ts +21 -0
  90. package/src/modules/utils/getConditionsFromFilters.ts +216 -0
  91. package/src/modules/video/video.service.ts +89 -0
  92. package/src/modules/webhook/webhook.constants.ts +9 -0
  93. package/src/modules/webhook/webhook.db.ts +15 -0
  94. package/src/modules/webhook/webhook.dto.ts +9 -0
  95. package/src/modules/webhook/webhook.repository.ts +68 -0
  96. package/src/modules/webhook/webhook.router.ts +29 -0
  97. package/src/modules/webhook/webhook.service.ts +78 -0
  98. package/src/modules/workflow/workflow.db.ts +29 -0
  99. package/src/modules/workflow/workflow.repository.ts +171 -0
  100. package/src/modules/workflow/workflow.service.ts +56 -0
  101. package/src/modules/workflow/workflow.trpc.ts +26 -0
  102. package/src/modules/workflow/workflow.types.ts +30 -0
  103. package/src/modules/workflow/workflow.utils.ts +259 -0
  104. package/src/test/stubs/utils.ts +2 -0
  105. package/src/trpc/context.ts +21 -0
  106. package/src/trpc/index.ts +3 -0
  107. package/src/trpc/procedures.ts +43 -0
  108. package/src/trpc/utils.ts +20 -0
  109. package/src/types.ts +22 -0
  110. package/src/utils/errors.ts +148 -0
  111. package/src/utils/logger.ts +8 -0
  112. package/src/utils/posthog.ts +43 -0
  113. package/src/utils/types.ts +5 -0
@@ -0,0 +1,206 @@
1
+ import { getTableColumns, type InferSelectModel, type Table } from "drizzle-orm";
2
+ import { createSelectSchema } from "drizzle-zod";
3
+ import type { Result } from "neverthrow";
4
+ import { z } from "zod";
5
+ import type { ServerError } from "#utils/errors";
6
+
7
+ type Simplify<T> = { [K in keyof T]: T[K] } & {};
8
+ type StringKeys<T> = Extract<keyof T, string>;
9
+
10
+ export type ServerResult<T> = Result<T, ServerError>;
11
+ export type ServerResultAsync<T> = Promise<ServerResult<T>>;
12
+
13
+ // Wrapper to force the drizzle-zod overload to the Table version
14
+ export const createTableSelectSchema = <T extends Table>(table: T) => createSelectSchema(table);
15
+
16
+ export type ExtractColumnTypes<T extends Table, C extends Record<string, unknown>> = Simplify<
17
+ Pick<InferSelectModel<T>, Extract<keyof C, keyof InferSelectModel<T>>>
18
+ >;
19
+
20
+ export function toZodFilter<const T extends readonly string[]>(array: T): Record<T[number], true> {
21
+ return array.reduce(
22
+ (acc, column) => {
23
+ acc[column as T[number]] = true;
24
+ return acc;
25
+ },
26
+ {} as Record<T[number], true>
27
+ );
28
+ }
29
+
30
+ export function pickSchema<
31
+ Shape extends z.ZodRawShape,
32
+ const Keys extends readonly StringKeys<Shape>[],
33
+ >(schema: z.ZodObject<Shape>, keys: Keys): z.ZodObject<Pick<Shape, Keys[number]>> {
34
+ const mask: Record<keyof Shape, true> = {} as Record<keyof Shape, true>;
35
+ for (const k of keys) {
36
+ mask[k] = true;
37
+ }
38
+ return schema.pick(mask) as z.ZodObject<Pick<Shape, Keys[number]>>;
39
+ }
40
+
41
+ export function pickTableSchema<T extends Table, K extends keyof InferSelectModel<T>>(
42
+ table: T,
43
+ columns: readonly K[]
44
+ ) {
45
+ return pickSchema(createSelectSchema(table), columns);
46
+ }
47
+
48
+ export function omitSchema<
49
+ Shape extends z.ZodRawShape,
50
+ const Keys extends readonly StringKeys<Shape>[],
51
+ >(schema: z.ZodObject<Shape>, keys: Keys): z.ZodObject<Omit<Shape, Keys[number]>> {
52
+ const mask: Record<keyof Shape, true> = {} as Record<keyof Shape, true>;
53
+ for (const k of keys) {
54
+ mask[k] = true;
55
+ }
56
+ return schema.omit(mask) as z.ZodObject<Omit<Shape, Keys[number]>>;
57
+ }
58
+
59
+ export function omitTableSchema<T extends Table, K extends keyof InferSelectModel<T>>(
60
+ table: T,
61
+ columns: readonly K[]
62
+ ) {
63
+ return omitSchema(createSelectSchema(table), columns);
64
+ }
65
+
66
+ export { getTableColumns };
67
+
68
+ export function pickColumns<T extends Table, Shape extends z.ZodRawShape>(
69
+ table: T,
70
+ schema: z.ZodObject<Shape>
71
+ ): Pick<ReturnType<typeof getTableColumns<T>>, Extract<keyof Shape, string>> {
72
+ const allColumns = getTableColumns(table);
73
+ const schemaKeys = Object.keys(schema.shape) as Array<Extract<keyof Shape, string>>;
74
+
75
+ const result = {} as Pick<typeof allColumns, Extract<keyof Shape, string>>;
76
+ for (const key of schemaKeys) {
77
+ if (key in allColumns) {
78
+ (result as any)[key] = allColumns[key as keyof typeof allColumns];
79
+ }
80
+ }
81
+
82
+ return result;
83
+ }
84
+
85
+ export function pickTableColumns<T extends Table, K extends keyof InferSelectModel<T>>(
86
+ table: T,
87
+ columns: readonly K[]
88
+ ): Pick<ReturnType<typeof getTableColumns<T>>, K> {
89
+ const allColumns = getTableColumns(table);
90
+ const result = {} as Pick<typeof allColumns, K>;
91
+ for (const key of columns) {
92
+ if (key in allColumns) {
93
+ result[key] = allColumns[key];
94
+ }
95
+ }
96
+ return result;
97
+ }
98
+
99
+ export function omitTableColumns<T extends Table, K extends keyof InferSelectModel<T>>(
100
+ table: T,
101
+ columns: readonly K[]
102
+ ): Omit<ReturnType<typeof getTableColumns<T>>, K> {
103
+ const allColumns = getTableColumns(table);
104
+ const columnsToOmit = new Set(columns as readonly string[]);
105
+ const filteredEntries = Object.entries(allColumns).filter(([key]) => !columnsToOmit.has(key));
106
+ return Object.fromEntries(filteredEntries) as Omit<typeof allColumns, K>;
107
+ }
108
+
109
+ // Overloads to narrow return type based on provided partial
110
+ export function createSelectDTO<T extends Table>(
111
+ table: T
112
+ ): {
113
+ columns: ReturnType<typeof getTableColumns<T>>;
114
+ schema: ReturnType<typeof createTableSelectSchema<T>>;
115
+ };
116
+ export function createSelectDTO<
117
+ T extends Table,
118
+ K extends Extract<keyof InferSelectModel<T>, string>,
119
+ >(
120
+ table: T,
121
+ partial: { omit: readonly K[] }
122
+ ): {
123
+ columns: ReturnType<typeof omitTableColumns<T, K>>;
124
+ schema: ReturnType<typeof omitTableSchema<T, K>>;
125
+ };
126
+ export function createSelectDTO<
127
+ T extends Table,
128
+ K extends Extract<keyof InferSelectModel<T>, string>,
129
+ >(
130
+ table: T,
131
+ partial: { pick: readonly K[] }
132
+ ): {
133
+ columns: ReturnType<typeof pickTableColumns<T, K>>;
134
+ schema: ReturnType<typeof pickTableSchema<T, K>>;
135
+ };
136
+
137
+ // Implementation
138
+ export function createSelectDTO<T extends Table>(
139
+ table: T,
140
+ partial?:
141
+ | { omit: readonly (keyof InferSelectModel<T>)[] }
142
+ | { pick: readonly (keyof InferSelectModel<T>)[] }
143
+ ): { columns: unknown; schema: unknown } {
144
+ if (partial) {
145
+ if ("omit" in partial && partial.omit) {
146
+ return {
147
+ columns: omitTableColumns(table, partial.omit),
148
+ schema: omitTableSchema(table, partial.omit),
149
+ };
150
+ }
151
+ if ("pick" in partial && partial.pick) {
152
+ return {
153
+ columns: pickTableColumns(table, partial.pick),
154
+ schema: pickTableSchema(table, partial.pick),
155
+ };
156
+ }
157
+ }
158
+ return { columns: getTableColumns(table), schema: createTableSelectSchema(table) };
159
+ }
160
+
161
+ export function createSelectUtils<
162
+ T extends Record<
163
+ string,
164
+ {
165
+ columns: unknown;
166
+ schema: z.ZodTypeAny;
167
+ }
168
+ >,
169
+ S extends z.ZodTypeAny,
170
+ >(
171
+ dtos: T,
172
+ output: S,
173
+ transformer: (rows: Array<{ [K in keyof T]: z.infer<T[K]["schema"]> }>) => z.infer<S>
174
+ ): {
175
+ select: { [K in keyof T]: T[K]["columns"] };
176
+ output: S;
177
+ transformer: (rows: Array<{ [K in keyof T]: z.infer<T[K]["schema"]> }>) => z.infer<S>;
178
+ } {
179
+ return {
180
+ select: Object.fromEntries(Object.entries(dtos).map(([key, dto]) => [key, dto.columns])) as {
181
+ [K in keyof T]: T[K]["columns"];
182
+ },
183
+ output,
184
+ transformer,
185
+ };
186
+ }
187
+
188
+ export const uuidOutput = z.object({
189
+ id: z.uuid(),
190
+ });
191
+
192
+ export const uuidManyOutput = z.object({
193
+ ids: z.array(z.uuid()),
194
+ });
195
+
196
+ export const scheduleOutput = z.object({
197
+ jobId: z.string(),
198
+ });
199
+
200
+ export const scheduleManyOutput = z.object({
201
+ jobIds: z.array(z.string()),
202
+ });
203
+
204
+ export const deleteOutput = uuidOutput;
205
+
206
+ export const deleteManyOutput = uuidManyOutput;