@m5kdev/backend 0.8.6 → 0.8.7
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/src/modules/auth/auth.dto.d.mts +2 -2
- package/dist/src/modules/auth/auth.lib.d.mts +1 -1
- package/dist/src/modules/auth/auth.trpc.d.mts +6 -6
- package/dist/src/modules/billing/billing.repository.d.mts +11 -11
- package/dist/src/modules/billing/billing.service.d.mts +7 -7
- package/dist/src/modules/connect/connect.dto.d.mts +2 -2
- package/dist/src/modules/connect/connect.repository.d.mts +1 -1
- package/dist/src/modules/connect/connect.service.d.mts +2 -2
- package/dist/src/modules/recurrence/recurrence.service.d.mts +3 -3
- package/dist/src/modules/recurrence/recurrence.trpc.d.mts +1 -1
- package/dist/src/modules/tag/tag.trpc.d.mts +2 -2
- package/dist/src/modules/video/video.service.mjs +73 -13
- package/dist/src/modules/video/video.service.mjs.map +1 -1
- package/package.json +3 -5
|
@@ -12,8 +12,8 @@ declare const waitlistSchema: z.ZodObject<{
|
|
|
12
12
|
expiresAt: z.ZodNullable<z.ZodDate>;
|
|
13
13
|
}, z.core.$strip>;
|
|
14
14
|
declare const waitlistOutputSchema: z.ZodObject<{
|
|
15
|
-
name: z.ZodNullable<z.ZodString>;
|
|
16
15
|
id: z.ZodString;
|
|
16
|
+
name: z.ZodNullable<z.ZodString>;
|
|
17
17
|
email: z.ZodNullable<z.ZodString>;
|
|
18
18
|
createdAt: z.ZodDate;
|
|
19
19
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
@@ -36,8 +36,8 @@ declare const accountClaimOutputSchema: z.ZodObject<{
|
|
|
36
36
|
id: z.ZodString;
|
|
37
37
|
createdAt: z.ZodDate;
|
|
38
38
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
39
|
-
status: z.ZodString;
|
|
40
39
|
expiresAt: z.ZodNullable<z.ZodDate>;
|
|
40
|
+
status: z.ZodString;
|
|
41
41
|
claimUserId: z.ZodNullable<z.ZodString>;
|
|
42
42
|
claimedAt: z.ZodNullable<z.ZodDate>;
|
|
43
43
|
claimedEmail: z.ZodNullable<z.ZodString>;
|
|
@@ -4830,7 +4830,7 @@ declare function createBetterAuth<O extends Orm, S extends Schema, E extends Ema
|
|
|
4830
4830
|
} | undefined;
|
|
4831
4831
|
verification?: {
|
|
4832
4832
|
modelName?: string;
|
|
4833
|
-
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "
|
|
4833
|
+
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "identifier" | "value", string>>;
|
|
4834
4834
|
additionalFields?: {
|
|
4835
4835
|
[key: string]: _$better_auth0.DBFieldAttribute;
|
|
4836
4836
|
};
|
|
@@ -59,8 +59,8 @@ declare function createAuthTRPC({
|
|
|
59
59
|
id: string;
|
|
60
60
|
createdAt: Date;
|
|
61
61
|
updatedAt: Date | null;
|
|
62
|
-
status: string;
|
|
63
62
|
expiresAt: Date | null;
|
|
63
|
+
status: string;
|
|
64
64
|
claimUserId: string | null;
|
|
65
65
|
claimedAt: Date | null;
|
|
66
66
|
claimedEmail: string | null;
|
|
@@ -146,8 +146,8 @@ declare function createAuthTRPC({
|
|
|
146
146
|
listAdminWaitlist: _$_trpc_server0.TRPCQueryProcedure<{
|
|
147
147
|
input: void;
|
|
148
148
|
output: {
|
|
149
|
-
name: string | null;
|
|
150
149
|
id: string;
|
|
150
|
+
name: string | null;
|
|
151
151
|
email: string | null;
|
|
152
152
|
createdAt: Date;
|
|
153
153
|
updatedAt: Date | null;
|
|
@@ -160,8 +160,8 @@ declare function createAuthTRPC({
|
|
|
160
160
|
email: string;
|
|
161
161
|
};
|
|
162
162
|
output: {
|
|
163
|
-
name: string | null;
|
|
164
163
|
id: string;
|
|
164
|
+
name: string | null;
|
|
165
165
|
email: string | null;
|
|
166
166
|
createdAt: Date;
|
|
167
167
|
updatedAt: Date | null;
|
|
@@ -191,8 +191,8 @@ declare function createAuthTRPC({
|
|
|
191
191
|
id: string;
|
|
192
192
|
};
|
|
193
193
|
output: {
|
|
194
|
-
name: string | null;
|
|
195
194
|
id: string;
|
|
195
|
+
name: string | null;
|
|
196
196
|
email: string | null;
|
|
197
197
|
createdAt: Date;
|
|
198
198
|
updatedAt: Date | null;
|
|
@@ -205,8 +205,8 @@ declare function createAuthTRPC({
|
|
|
205
205
|
id: string;
|
|
206
206
|
};
|
|
207
207
|
output: {
|
|
208
|
-
name: string | null;
|
|
209
208
|
id: string;
|
|
209
|
+
name: string | null;
|
|
210
210
|
email: string | null;
|
|
211
211
|
createdAt: Date;
|
|
212
212
|
updatedAt: Date | null;
|
|
@@ -219,8 +219,8 @@ declare function createAuthTRPC({
|
|
|
219
219
|
email: string;
|
|
220
220
|
};
|
|
221
221
|
output: {
|
|
222
|
-
name: string | null;
|
|
223
222
|
id: string;
|
|
223
|
+
name: string | null;
|
|
224
224
|
email: string | null;
|
|
225
225
|
createdAt: Date;
|
|
226
226
|
updatedAt: Date | null;
|
|
@@ -4,7 +4,7 @@ import { BillingSchema } from "@m5kdev/commons/modules/billing/billing.schema";
|
|
|
4
4
|
import { InferSelectModel } from "drizzle-orm";
|
|
5
5
|
import * as _$drizzle_orm_sqlite_core0 from "drizzle-orm/sqlite-core";
|
|
6
6
|
import { LibSQLDatabase } from "drizzle-orm/libsql";
|
|
7
|
-
import { Stripe
|
|
7
|
+
import { Stripe } from "stripe";
|
|
8
8
|
import { StripePlan } from "@m5kdev/commons/modules/billing/billing.types";
|
|
9
9
|
|
|
10
10
|
//#region src/modules/billing/billing.repository.d.ts
|
|
@@ -2713,7 +2713,7 @@ declare const schema: {
|
|
|
2713
2713
|
type Schema = typeof schema;
|
|
2714
2714
|
type Orm = LibSQLDatabase<Schema>;
|
|
2715
2715
|
declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<string, never>, Schema["subscriptions"]> {
|
|
2716
|
-
stripe: Stripe
|
|
2716
|
+
stripe: Stripe;
|
|
2717
2717
|
plans: StripePlan[];
|
|
2718
2718
|
trial?: StripePlan;
|
|
2719
2719
|
constructor(options: {
|
|
@@ -2721,7 +2721,7 @@ declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
2721
2721
|
schema: Schema;
|
|
2722
2722
|
table: Schema["subscriptions"];
|
|
2723
2723
|
libs: {
|
|
2724
|
-
stripe: Stripe
|
|
2724
|
+
stripe: Stripe;
|
|
2725
2725
|
};
|
|
2726
2726
|
config: {
|
|
2727
2727
|
trial?: StripePlan;
|
|
@@ -2730,7 +2730,7 @@ declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
2730
2730
|
});
|
|
2731
2731
|
hasTrial(): boolean;
|
|
2732
2732
|
getPlanByPriceId(priceId: string): StripePlan | undefined;
|
|
2733
|
-
getCustomerByEmail(email: string): ServerResultAsync<Stripe
|
|
2733
|
+
getCustomerByEmail(email: string): ServerResultAsync<Stripe.Customer | null>;
|
|
2734
2734
|
getUserByCustomerId(customerId: string): ServerResultAsync<InferSelectModel<Schema["users"]> | null>;
|
|
2735
2735
|
createCustomer({
|
|
2736
2736
|
email,
|
|
@@ -2740,8 +2740,8 @@ declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
2740
2740
|
email: string;
|
|
2741
2741
|
name?: string;
|
|
2742
2742
|
userId: string;
|
|
2743
|
-
}): ServerResultAsync<Stripe
|
|
2744
|
-
createTrialSubscription(customerId: string): ServerResultAsync<Stripe
|
|
2743
|
+
}): ServerResultAsync<Stripe.Customer>;
|
|
2744
|
+
createTrialSubscription(customerId: string): ServerResultAsync<Stripe.Subscription>;
|
|
2745
2745
|
createSubscription({
|
|
2746
2746
|
customerId,
|
|
2747
2747
|
priceId,
|
|
@@ -2752,7 +2752,7 @@ declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
2752
2752
|
priceId: string;
|
|
2753
2753
|
quantity?: number;
|
|
2754
2754
|
trialDays?: number;
|
|
2755
|
-
}): ServerResultAsync<Stripe
|
|
2755
|
+
}): ServerResultAsync<Stripe.Subscription>;
|
|
2756
2756
|
updateUserCustomerId({
|
|
2757
2757
|
userId,
|
|
2758
2758
|
customerId
|
|
@@ -2762,7 +2762,7 @@ declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
2762
2762
|
}): ServerResultAsync<InferSelectModel<Schema["users"]>>;
|
|
2763
2763
|
getLatestSubscription(referenceId: string): ServerResultAsync<BillingSchema | null>;
|
|
2764
2764
|
getActiveSubscription(referenceId: string): ServerResultAsync<BillingSchema | null>;
|
|
2765
|
-
listInvoices(customerId: string): ServerResultAsync<Stripe
|
|
2765
|
+
listInvoices(customerId: string): ServerResultAsync<Stripe.Invoice[]>;
|
|
2766
2766
|
createCheckoutSession({
|
|
2767
2767
|
customerId,
|
|
2768
2768
|
priceId,
|
|
@@ -2771,8 +2771,8 @@ declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
2771
2771
|
customerId: string;
|
|
2772
2772
|
priceId: string;
|
|
2773
2773
|
userId: string;
|
|
2774
|
-
}): ServerResultAsync<Stripe
|
|
2775
|
-
createBillingPortalSession(customerId: string): ServerResultAsync<Stripe
|
|
2774
|
+
}): ServerResultAsync<Stripe.Checkout.Session>;
|
|
2775
|
+
createBillingPortalSession(customerId: string): ServerResultAsync<Stripe.BillingPortal.Session>;
|
|
2776
2776
|
syncStripeData({
|
|
2777
2777
|
customerId,
|
|
2778
2778
|
userId
|
|
@@ -2780,7 +2780,7 @@ declare class BillingRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
2780
2780
|
customerId: string;
|
|
2781
2781
|
userId: string;
|
|
2782
2782
|
}): ServerResultAsync<boolean>;
|
|
2783
|
-
constructEvent(body: Buffer | string, signature: string, secret: string): ServerResult<Stripe
|
|
2783
|
+
constructEvent(body: Buffer | string, signature: string, secret: string): ServerResult<Stripe.Event>;
|
|
2784
2784
|
}
|
|
2785
2785
|
//#endregion
|
|
2786
2786
|
export { BillingRepository };
|
|
@@ -4,7 +4,7 @@ import { BillingRepository } from "./billing.repository.mjs";
|
|
|
4
4
|
import { User } from "../auth/auth.lib.mjs";
|
|
5
5
|
import { BaseService } from "../base/base.service.mjs";
|
|
6
6
|
import { BillingSchema } from "@m5kdev/commons/modules/billing/billing.schema";
|
|
7
|
-
import Stripe from "stripe";
|
|
7
|
+
import Stripe$1 from "stripe";
|
|
8
8
|
|
|
9
9
|
//#region src/modules/billing/billing.service.d.ts
|
|
10
10
|
declare class BillingService extends BaseService<{
|
|
@@ -18,7 +18,7 @@ declare class BillingService extends BaseService<{
|
|
|
18
18
|
email: string;
|
|
19
19
|
name?: string;
|
|
20
20
|
};
|
|
21
|
-
}): ServerResultAsync<Stripe.Customer>;
|
|
21
|
+
}): ServerResultAsync<Stripe$1.Customer>;
|
|
22
22
|
createUserHook({
|
|
23
23
|
user
|
|
24
24
|
}: {
|
|
@@ -29,7 +29,7 @@ declare class BillingService extends BaseService<{
|
|
|
29
29
|
};
|
|
30
30
|
}): ServerResultAsync<boolean>;
|
|
31
31
|
getActiveSubscription(ctx: Context): ServerResultAsync<BillingSchema | null>;
|
|
32
|
-
listInvoices(ctx: Context): ServerResultAsync<Stripe.Invoice[]>;
|
|
32
|
+
listInvoices(ctx: Context): ServerResultAsync<Stripe$1.Invoice[]>;
|
|
33
33
|
createCheckoutSession({
|
|
34
34
|
priceId
|
|
35
35
|
}: {
|
|
@@ -38,15 +38,15 @@ declare class BillingService extends BaseService<{
|
|
|
38
38
|
user
|
|
39
39
|
}: {
|
|
40
40
|
user: User;
|
|
41
|
-
}): ServerResultAsync<Stripe.Checkout.Session>;
|
|
41
|
+
}): ServerResultAsync<Stripe$1.Checkout.Session>;
|
|
42
42
|
createBillingPortalSession({
|
|
43
43
|
user
|
|
44
44
|
}: {
|
|
45
45
|
user: User;
|
|
46
|
-
}): ServerResultAsync<Stripe.BillingPortal.Session>;
|
|
47
|
-
constructEvent(body: Buffer | string, signature: string): ServerResult<Stripe.Event>;
|
|
46
|
+
}): ServerResultAsync<Stripe$1.BillingPortal.Session>;
|
|
47
|
+
constructEvent(body: Buffer | string, signature: string): ServerResult<Stripe$1.Event>;
|
|
48
48
|
syncStripeData(customerId: string, eventType?: string): ServerResultAsync<boolean>;
|
|
49
|
-
processEvent(event: Stripe.Event): ServerResultAsync<boolean>;
|
|
49
|
+
processEvent(event: Stripe$1.Event): ServerResultAsync<boolean>;
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
52
52
|
export { BillingService };
|
|
@@ -29,8 +29,8 @@ declare const connectSelectOutputSchema: z.ZodObject<{
|
|
|
29
29
|
updatedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
30
30
|
expiresAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
31
31
|
userId: z.ZodString;
|
|
32
|
-
provider: z.ZodString;
|
|
33
32
|
scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
33
|
+
provider: z.ZodString;
|
|
34
34
|
accountType: z.ZodString;
|
|
35
35
|
providerAccountId: z.ZodString;
|
|
36
36
|
handle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -53,8 +53,8 @@ declare const connectListOutputSchema: z.ZodArray<z.ZodObject<{
|
|
|
53
53
|
updatedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
54
54
|
expiresAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
55
55
|
userId: z.ZodString;
|
|
56
|
-
provider: z.ZodString;
|
|
57
56
|
scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
57
|
+
provider: z.ZodString;
|
|
58
58
|
accountType: z.ZodString;
|
|
59
59
|
providerAccountId: z.ZodString;
|
|
60
60
|
handle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -398,10 +398,10 @@ declare class ConnectRepository extends BaseTableRepository<Orm, Schema, Record<
|
|
|
398
398
|
updatedAt: Date | null;
|
|
399
399
|
expiresAt: Date | null;
|
|
400
400
|
userId: string;
|
|
401
|
-
provider: string;
|
|
402
401
|
accessToken: string;
|
|
403
402
|
refreshToken: string | null;
|
|
404
403
|
scope: string | null;
|
|
404
|
+
provider: string;
|
|
405
405
|
accountType: string;
|
|
406
406
|
providerAccountId: string;
|
|
407
407
|
handle: string | null;
|
|
@@ -24,10 +24,10 @@ declare class ConnectService extends BaseService<{
|
|
|
24
24
|
updatedAt: Date | null;
|
|
25
25
|
expiresAt: Date | null;
|
|
26
26
|
userId: string;
|
|
27
|
-
provider: string;
|
|
28
27
|
accessToken: string;
|
|
29
28
|
refreshToken: string | null;
|
|
30
29
|
scope: string | null;
|
|
30
|
+
provider: string;
|
|
31
31
|
accountType: string;
|
|
32
32
|
providerAccountId: string;
|
|
33
33
|
handle: string | null;
|
|
@@ -45,10 +45,10 @@ declare class ConnectService extends BaseService<{
|
|
|
45
45
|
updatedAt: Date | null;
|
|
46
46
|
expiresAt: Date | null;
|
|
47
47
|
userId: string;
|
|
48
|
-
provider: string;
|
|
49
48
|
accessToken: string;
|
|
50
49
|
refreshToken: string | null;
|
|
51
50
|
scope: string | null;
|
|
51
|
+
provider: string;
|
|
52
52
|
accountType: string;
|
|
53
53
|
providerAccountId: string;
|
|
54
54
|
handle: string | null;
|
|
@@ -18,7 +18,7 @@ declare class RecurrenceService extends BaseService<{
|
|
|
18
18
|
filters?: {
|
|
19
19
|
columnId: string;
|
|
20
20
|
type: "string" | "number" | "boolean" | "date" | "enum";
|
|
21
|
-
method: "contains" | "
|
|
21
|
+
method: "contains" | "starts_with" | "ends_with" | "intersect" | "on" | "equals" | "greater_than" | "less_than" | "between" | "before" | "after" | "oneOf" | "isEmpty" | "isNotEmpty" | "is_null" | "is_not_null";
|
|
22
22
|
value: string | number | boolean | string[];
|
|
23
23
|
valueTo?: string | undefined;
|
|
24
24
|
endColumnId?: string | undefined;
|
|
@@ -29,12 +29,12 @@ declare class RecurrenceService extends BaseService<{
|
|
|
29
29
|
actor: UserActor;
|
|
30
30
|
}, {
|
|
31
31
|
rows: {
|
|
32
|
-
name: string | null;
|
|
33
32
|
id: string;
|
|
33
|
+
name: string | null;
|
|
34
34
|
createdAt: Date;
|
|
35
35
|
updatedAt: Date;
|
|
36
|
-
userId: string | null;
|
|
37
36
|
metadata: Record<string, any> | null;
|
|
37
|
+
userId: string | null;
|
|
38
38
|
organizationId: string | null;
|
|
39
39
|
teamId: string | null;
|
|
40
40
|
enabled: boolean;
|
|
@@ -21,7 +21,7 @@ declare function createRecurrenceTRPC({
|
|
|
21
21
|
filters?: {
|
|
22
22
|
columnId: string;
|
|
23
23
|
type: "string" | "number" | "boolean" | "date" | "enum";
|
|
24
|
-
method: "contains" | "
|
|
24
|
+
method: "contains" | "starts_with" | "ends_with" | "intersect" | "on" | "equals" | "greater_than" | "less_than" | "between" | "before" | "after" | "oneOf" | "isEmpty" | "isNotEmpty" | "is_null" | "is_not_null";
|
|
25
25
|
value: string | number | boolean | string[];
|
|
26
26
|
valueTo?: string | undefined;
|
|
27
27
|
endColumnId?: string | undefined;
|
|
@@ -21,7 +21,7 @@ declare function createTagTRPC({
|
|
|
21
21
|
filters?: {
|
|
22
22
|
columnId: string;
|
|
23
23
|
type: "string" | "number" | "boolean" | "date" | "enum";
|
|
24
|
-
method: "contains" | "
|
|
24
|
+
method: "contains" | "starts_with" | "ends_with" | "intersect" | "on" | "equals" | "greater_than" | "less_than" | "between" | "before" | "after" | "oneOf" | "isEmpty" | "isNotEmpty" | "is_null" | "is_not_null";
|
|
25
25
|
value: string | number | boolean | string[];
|
|
26
26
|
valueTo?: string | undefined;
|
|
27
27
|
endColumnId?: string | undefined;
|
|
@@ -54,7 +54,7 @@ declare function createTagTRPC({
|
|
|
54
54
|
resourceIds?: {
|
|
55
55
|
columnId: string;
|
|
56
56
|
type: "string" | "number" | "boolean" | "date" | "enum";
|
|
57
|
-
method: "contains" | "
|
|
57
|
+
method: "contains" | "starts_with" | "ends_with" | "intersect" | "on" | "equals" | "greater_than" | "less_than" | "between" | "before" | "after" | "oneOf" | "isEmpty" | "isNotEmpty" | "is_null" | "is_not_null";
|
|
58
58
|
value: string | number | boolean | string[];
|
|
59
59
|
valueTo?: string | undefined;
|
|
60
60
|
endColumnId?: string | undefined;
|
|
@@ -1,25 +1,60 @@
|
|
|
1
1
|
import { BaseService } from "../base/base.service.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { ok } from "neverthrow";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { closeSync, existsSync, mkdirSync, openSync } from "node:fs";
|
|
6
|
+
import { spawn } from "node:child_process";
|
|
6
7
|
import ffbin from "ffmpeg-ffprobe-static";
|
|
7
|
-
import ffmpeg from "fluent-ffmpeg";
|
|
8
8
|
//#region src/modules/video/video.service.ts
|
|
9
9
|
if (!ffbin.ffmpegPath || !ffbin.ffprobePath) throw new Error("FFmpeg or FFprobe not found");
|
|
10
|
-
ffmpeg.setFfmpegPath(ffbin.ffmpegPath);
|
|
11
|
-
ffmpeg.setFfprobePath(ffbin.ffprobePath);
|
|
12
10
|
const uploadsDir = path.join(__dirname, "..", "uploads");
|
|
13
11
|
if (!existsSync(uploadsDir)) mkdirSync(uploadsDir, { recursive: true });
|
|
12
|
+
const runFfmpeg = async (args) => {
|
|
13
|
+
await new Promise((resolve, reject) => {
|
|
14
|
+
const child = spawn(ffbin.ffmpegPath, [...args], { stdio: [
|
|
15
|
+
"ignore",
|
|
16
|
+
"ignore",
|
|
17
|
+
"pipe"
|
|
18
|
+
] });
|
|
19
|
+
let stderr = "";
|
|
20
|
+
child.stderr?.setEncoding("utf8");
|
|
21
|
+
child.stderr?.on("data", (chunk) => {
|
|
22
|
+
stderr += chunk;
|
|
23
|
+
});
|
|
24
|
+
child.on("error", (error) => reject(error));
|
|
25
|
+
child.on("close", (code) => {
|
|
26
|
+
if (code === 0) {
|
|
27
|
+
resolve();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
reject(new Error(stderr || `ffmpeg exited with code ${code ?? "unknown"}`));
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
};
|
|
14
34
|
var VideoService = class extends BaseService {
|
|
15
35
|
async cut(file, start, end) {
|
|
16
36
|
return this.throwableAsync(async () => {
|
|
17
37
|
const duration = end - start;
|
|
18
38
|
const output = path.join(uploadsDir, `${v4()}.mp4`);
|
|
19
39
|
if (!existsSync(output)) closeSync(openSync(output, "w"));
|
|
20
|
-
await
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
await runFfmpeg([
|
|
41
|
+
"-i",
|
|
42
|
+
file,
|
|
43
|
+
"-ss",
|
|
44
|
+
String(start),
|
|
45
|
+
"-t",
|
|
46
|
+
String(duration),
|
|
47
|
+
"-c:v",
|
|
48
|
+
"libx264",
|
|
49
|
+
"-c:a",
|
|
50
|
+
"copy",
|
|
51
|
+
"-movflags",
|
|
52
|
+
"+faststart",
|
|
53
|
+
"-y",
|
|
54
|
+
output
|
|
55
|
+
]).catch((error) => {
|
|
56
|
+
throw this.handleUnknownError(error);
|
|
57
|
+
});
|
|
23
58
|
return ok(output);
|
|
24
59
|
});
|
|
25
60
|
}
|
|
@@ -27,9 +62,23 @@ var VideoService = class extends BaseService {
|
|
|
27
62
|
return this.throwableAsync(async () => {
|
|
28
63
|
const output = path.join(uploadsDir, `${v4()}.wav`);
|
|
29
64
|
if (!existsSync(output)) closeSync(openSync(output, "w"));
|
|
30
|
-
await
|
|
31
|
-
|
|
32
|
-
|
|
65
|
+
await runFfmpeg([
|
|
66
|
+
"-i",
|
|
67
|
+
input,
|
|
68
|
+
"-vn",
|
|
69
|
+
"-c:a",
|
|
70
|
+
"pcm_s16le",
|
|
71
|
+
"-ar",
|
|
72
|
+
String(hz),
|
|
73
|
+
"-ac",
|
|
74
|
+
"2",
|
|
75
|
+
"-f",
|
|
76
|
+
"wav",
|
|
77
|
+
"-y",
|
|
78
|
+
output
|
|
79
|
+
]).catch((error) => {
|
|
80
|
+
throw this.handleUnknownError(error);
|
|
81
|
+
});
|
|
33
82
|
return ok(output);
|
|
34
83
|
});
|
|
35
84
|
}
|
|
@@ -37,9 +86,20 @@ var VideoService = class extends BaseService {
|
|
|
37
86
|
return this.throwableAsync(async () => {
|
|
38
87
|
const output = path.join(uploadsDir, `${v4()}.mp3`);
|
|
39
88
|
if (!existsSync(output)) closeSync(openSync(output, "w"));
|
|
40
|
-
await
|
|
41
|
-
|
|
42
|
-
|
|
89
|
+
await runFfmpeg([
|
|
90
|
+
"-i",
|
|
91
|
+
input,
|
|
92
|
+
"-map",
|
|
93
|
+
`0:a:${streamIndex}`,
|
|
94
|
+
"-c:a",
|
|
95
|
+
"libmp3lame",
|
|
96
|
+
"-b:a",
|
|
97
|
+
`${kbps}k`,
|
|
98
|
+
"-y",
|
|
99
|
+
output
|
|
100
|
+
]).catch((error) => {
|
|
101
|
+
throw this.handleUnknownError(error);
|
|
102
|
+
});
|
|
43
103
|
return ok(output);
|
|
44
104
|
});
|
|
45
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video.service.mjs","names":["uuidv4"],"sources":["../../../../src/modules/video/video.service.ts"],"sourcesContent":["import { closeSync, existsSync, mkdirSync, openSync } from \"node:fs\";\r\nimport path from \"node:path\";\r\
|
|
1
|
+
{"version":3,"file":"video.service.mjs","names":["uuidv4"],"sources":["../../../../src/modules/video/video.service.ts"],"sourcesContent":["import { closeSync, existsSync, mkdirSync, openSync } from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { spawn } from \"node:child_process\";\r\n//\r\nimport ffbin from \"ffmpeg-ffprobe-static\";\r\nimport { err, ok } from \"neverthrow\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport type { ServerResultAsync } from \"../base/base.dto\";\r\nimport { BaseService } from \"../base/base.service\";\r\n\r\nif (!ffbin.ffmpegPath || !ffbin.ffprobePath) {\r\n throw new Error(\"FFmpeg or FFprobe not found\");\r\n}\r\n\r\nconst uploadsDir = path.join(__dirname, \"..\", \"uploads\");\r\nif (!existsSync(uploadsDir)) {\r\n mkdirSync(uploadsDir, { recursive: true });\r\n}\r\n\r\nconst runFfmpeg = async (args: readonly string[]): Promise<void> => {\r\n await new Promise<void>((resolve, reject) => {\r\n const child = spawn(ffbin.ffmpegPath as string, [...args], {\r\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\r\n });\r\n\r\n let stderr = \"\";\r\n child.stderr?.setEncoding(\"utf8\");\r\n child.stderr?.on(\"data\", (chunk: string) => {\r\n stderr += chunk;\r\n });\r\n\r\n child.on(\"error\", (error) => reject(error));\r\n child.on(\"close\", (code) => {\r\n if (code === 0) {\r\n resolve();\r\n return;\r\n }\r\n reject(new Error(stderr || `ffmpeg exited with code ${code ?? \"unknown\"}`));\r\n });\r\n });\r\n};\r\n\r\nexport class VideoService extends BaseService<never, never> {\r\n async cut(file: string, start: number, end: number): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const duration = end - start;\r\n const output = path.join(uploadsDir, `${uuidv4()}.mp4`);\r\n if (!existsSync(output)) {\r\n closeSync(openSync(output, \"w\"));\r\n }\r\n\r\n await runFfmpeg([\r\n \"-i\",\r\n file,\r\n \"-ss\",\r\n String(start),\r\n \"-t\",\r\n String(duration),\r\n \"-c:v\",\r\n \"libx264\",\r\n \"-c:a\",\r\n \"copy\",\r\n \"-movflags\",\r\n \"+faststart\",\r\n \"-y\",\r\n output,\r\n ]).catch((error) => {\r\n throw this.handleUnknownError(error);\r\n });\r\n\r\n return ok(output);\r\n });\r\n }\r\n\r\n async webmToWav(input: string, hz = 48000): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const output = path.join(uploadsDir, `${uuidv4()}.wav`);\r\n if (!existsSync(output)) {\r\n closeSync(openSync(output, \"w\"));\r\n }\r\n\r\n await runFfmpeg([\r\n \"-i\",\r\n input,\r\n \"-vn\",\r\n \"-c:a\",\r\n \"pcm_s16le\",\r\n \"-ar\",\r\n String(hz),\r\n \"-ac\",\r\n \"2\",\r\n \"-f\",\r\n \"wav\",\r\n \"-y\",\r\n output,\r\n ]).catch((error) => {\r\n throw this.handleUnknownError(error);\r\n });\r\n return ok(output);\r\n });\r\n }\r\n\r\n async extractAudioMp3(input: string, kbps = 192, streamIndex = 0): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const output = path.join(uploadsDir, `${uuidv4()}.mp3`);\r\n if (!existsSync(output)) {\r\n closeSync(openSync(output, \"w\"));\r\n }\r\n await runFfmpeg([\r\n \"-i\",\r\n input,\r\n \"-map\",\r\n `0:a:${streamIndex}`,\r\n \"-c:a\",\r\n \"libmp3lame\",\r\n \"-b:a\",\r\n `${kbps}k`,\r\n \"-y\",\r\n output,\r\n ]).catch((error) => {\r\n throw this.handleUnknownError(error);\r\n });\r\n\r\n return ok(output);\r\n });\r\n }\r\n}\r\n"],"mappings":";;;;;;;;AAUA,IAAI,CAAC,MAAM,cAAc,CAAC,MAAM,YAC9B,OAAM,IAAI,MAAM,8BAA8B;AAGhD,MAAM,aAAa,KAAK,KAAK,WAAW,MAAM,UAAU;AACxD,IAAI,CAAC,WAAW,WAAW,CACzB,WAAU,YAAY,EAAE,WAAW,MAAM,CAAC;AAG5C,MAAM,YAAY,OAAO,SAA2C;AAClE,OAAM,IAAI,SAAe,SAAS,WAAW;EAC3C,MAAM,QAAQ,MAAM,MAAM,YAAsB,CAAC,GAAG,KAAK,EAAE,EACzD,OAAO;GAAC;GAAU;GAAU;GAAO,EACpC,CAAC;EAEF,IAAI,SAAS;AACb,QAAM,QAAQ,YAAY,OAAO;AACjC,QAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,aAAU;IACV;AAEF,QAAM,GAAG,UAAU,UAAU,OAAO,MAAM,CAAC;AAC3C,QAAM,GAAG,UAAU,SAAS;AAC1B,OAAI,SAAS,GAAG;AACd,aAAS;AACT;;AAEF,UAAO,IAAI,MAAM,UAAU,2BAA2B,QAAQ,YAAY,CAAC;IAC3E;GACF;;AAGJ,IAAa,eAAb,cAAkC,YAA0B;CAC1D,MAAM,IAAI,MAAc,OAAe,KAAwC;AAC7E,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,WAAW,MAAM;GACvB,MAAM,SAAS,KAAK,KAAK,YAAY,GAAGA,IAAQ,CAAC,MAAM;AACvD,OAAI,CAAC,WAAW,OAAO,CACrB,WAAU,SAAS,QAAQ,IAAI,CAAC;AAGlC,SAAM,UAAU;IACd;IACA;IACA;IACA,OAAO,MAAM;IACb;IACA,OAAO,SAAS;IAChB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,CAAC,OAAO,UAAU;AAClB,UAAM,KAAK,mBAAmB,MAAM;KACpC;AAEF,UAAO,GAAG,OAAO;IACjB;;CAGJ,MAAM,UAAU,OAAe,KAAK,MAAkC;AACpE,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,SAAS,KAAK,KAAK,YAAY,GAAGA,IAAQ,CAAC,MAAM;AACvD,OAAI,CAAC,WAAW,OAAO,CACrB,WAAU,SAAS,QAAQ,IAAI,CAAC;AAGlC,SAAM,UAAU;IACd;IACA;IACA;IACA;IACA;IACA;IACA,OAAO,GAAG;IACV;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,CAAC,OAAO,UAAU;AAClB,UAAM,KAAK,mBAAmB,MAAM;KACpC;AACF,UAAO,GAAG,OAAO;IACjB;;CAGJ,MAAM,gBAAgB,OAAe,OAAO,KAAK,cAAc,GAA8B;AAC3F,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,SAAS,KAAK,KAAK,YAAY,GAAGA,IAAQ,CAAC,MAAM;AACvD,OAAI,CAAC,WAAW,OAAO,CACrB,WAAU,SAAS,QAAQ,IAAI,CAAC;AAElC,SAAM,UAAU;IACd;IACA;IACA;IACA,OAAO;IACP;IACA;IACA;IACA,GAAG,KAAK;IACR;IACA;IACD,CAAC,CAAC,OAAO,UAAU;AAClB,UAAM,KAAK,mBAAmB,MAAM;KACpC;AAEF,UAAO,GAAG,OAAO;IACjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m5kdev/backend",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "Composable Express server stack with Drizzle ORM and tRPC.",
|
|
5
5
|
"license": "GPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"drizzle-zod": "0.8.2",
|
|
38
38
|
"express": "4.21.2",
|
|
39
39
|
"ffmpeg-ffprobe-static": "6.1.2-rc.1",
|
|
40
|
-
"fluent-ffmpeg": "2.1.3",
|
|
41
40
|
"ioredis": "5.7.0",
|
|
42
41
|
"jsonrepair": "^3.13.3",
|
|
43
42
|
"luxon": "3.7.1",
|
|
@@ -59,15 +58,14 @@
|
|
|
59
58
|
"trpc-to-openapi": "2.3.0",
|
|
60
59
|
"uuid": "11.0.5",
|
|
61
60
|
"zod": "4.2.1",
|
|
62
|
-
"@m5kdev/commons": "0.8.
|
|
63
|
-
"@m5kdev/config": "0.8.
|
|
61
|
+
"@m5kdev/commons": "0.8.7",
|
|
62
|
+
"@m5kdev/config": "0.8.7"
|
|
64
63
|
},
|
|
65
64
|
"devDependencies": {
|
|
66
65
|
"@jest/globals": "30.2.0",
|
|
67
66
|
"@types/body-parser": "1.19.5",
|
|
68
67
|
"@types/cors": "2.8.17",
|
|
69
68
|
"@types/express": "4.17.21",
|
|
70
|
-
"@types/fluent-ffmpeg": "2.1.27",
|
|
71
69
|
"@types/jest": "30.0.0",
|
|
72
70
|
"@types/luxon": "3.7.1",
|
|
73
71
|
"@types/mustache": "4.2.6",
|