@deallony/shared 1.2.50 → 1.2.52
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/cjs/constants/ad/AdMedia.d.ts +8 -0
- package/dist/cjs/constants/ad/AdMedia.js +16 -0
- package/dist/cjs/constants/ad/index.d.ts +1 -0
- package/dist/cjs/constants/ad/index.js +1 -0
- package/dist/cjs/dto/addresses/addresses.dto.d.ts +7 -0
- package/dist/cjs/dto/addresses/addresses.dto.js +2 -0
- package/dist/cjs/dto/index.d.ts +1 -0
- package/dist/cjs/dto/index.js +2 -1
- package/dist/cjs/schema/ad/save-ad.schema.d.ts +5 -0
- package/dist/cjs/schema/ad/save-ad.schema.js +39 -2
- package/dist/cjs/schema/addresses/addresses.schema.d.ts +19 -0
- package/dist/cjs/schema/addresses/addresses.schema.js +18 -0
- package/dist/cjs/schema/index.d.ts +1 -0
- package/dist/cjs/schema/index.js +2 -1
- package/dist/cjs/types/ad/Ad.d.ts +1 -0
- package/dist/cjs/types/ad/Ad.js +1 -0
- package/dist/cjs/types/addresses/Address.d.ts +14 -0
- package/dist/cjs/types/addresses/Address.js +2 -0
- package/dist/cjs/types/communication/Chat.d.ts +8 -1
- package/dist/cjs/types/communication/Chat.js +1 -0
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/cjs/types/index.js +3 -2
- package/dist/cjs/utils/adMedia.d.ts +5 -0
- package/dist/cjs/utils/adMedia.js +27 -0
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +1 -0
- package/dist/esm/constants/ad/AdMedia.js +13 -0
- package/dist/esm/constants/ad/index.js +1 -0
- package/dist/esm/dto/addresses/addresses.dto.js +1 -0
- package/dist/esm/dto/index.js +1 -0
- package/dist/esm/schema/ad/save-ad.schema.js +38 -1
- package/dist/esm/schema/addresses/addresses.schema.js +15 -0
- package/dist/esm/schema/index.js +1 -0
- package/dist/esm/types/ad/Ad.js +1 -0
- package/dist/esm/types/addresses/Address.js +1 -0
- package/dist/esm/types/communication/Chat.js +1 -0
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/utils/adMedia.js +22 -0
- package/dist/esm/utils/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const MAX_AD_IMAGES = 30;
|
|
2
|
+
export declare const MAX_AD_VIDEOS = 1;
|
|
3
|
+
export declare const MAX_AD_VIDEO_BYTES: number;
|
|
4
|
+
export declare enum AdMediaIssueCode {
|
|
5
|
+
TOO_MANY_IMAGES = "too_many_images",
|
|
6
|
+
TOO_MANY_VIDEOS = "too_many_videos",
|
|
7
|
+
VIDEO_TOO_LARGE = "video_too_large"
|
|
8
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdMediaIssueCode = exports.MAX_AD_VIDEO_BYTES = exports.MAX_AD_VIDEOS = exports.MAX_AD_IMAGES = void 0;
|
|
4
|
+
// Media is optional on every ad. These are the only limits, shared by every
|
|
5
|
+
// client and the API so they can never drift apart.
|
|
6
|
+
exports.MAX_AD_IMAGES = 30;
|
|
7
|
+
exports.MAX_AD_VIDEOS = 1;
|
|
8
|
+
exports.MAX_AD_VIDEO_BYTES = 50 * 1024 * 1024;
|
|
9
|
+
// Stable codes carried in `params.code` of adMediaSchema issues, so clients can
|
|
10
|
+
// show localized messages without re-implementing the rules.
|
|
11
|
+
var AdMediaIssueCode;
|
|
12
|
+
(function (AdMediaIssueCode) {
|
|
13
|
+
AdMediaIssueCode["TOO_MANY_IMAGES"] = "too_many_images";
|
|
14
|
+
AdMediaIssueCode["TOO_MANY_VIDEOS"] = "too_many_videos";
|
|
15
|
+
AdMediaIssueCode["VIDEO_TOO_LARGE"] = "video_too_large";
|
|
16
|
+
})(AdMediaIssueCode || (exports.AdMediaIssueCode = AdMediaIssueCode = {}));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { createAddressSchema, updateAddressSchema } from "../../schema/addresses/addresses.schema";
|
|
3
|
+
import type { IAddress } from "../../types/addresses/Address";
|
|
4
|
+
export type CreateAddressDto = z.infer<typeof createAddressSchema>;
|
|
5
|
+
export type UpdateAddressDto = z.infer<typeof updateAddressSchema>;
|
|
6
|
+
export type AddressResponse = IAddress;
|
|
7
|
+
export type AddressListResponse = IAddress[];
|
package/dist/cjs/dto/index.d.ts
CHANGED
package/dist/cjs/dto/index.js
CHANGED
|
@@ -33,10 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.PAYMENTS = exports.Ai = exports.EVENTS = exports.AD = exports.AdDto = void 0;
|
|
36
|
+
exports.ADDRESSES = exports.PAYMENTS = exports.Ai = exports.EVENTS = exports.AD = exports.AdDto = void 0;
|
|
37
37
|
var Ad_dto_1 = require("./ad/Ad.dto");
|
|
38
38
|
Object.defineProperty(exports, "AdDto", { enumerable: true, get: function () { return Ad_dto_1.AdDto; } });
|
|
39
39
|
exports.AD = __importStar(require("./ad/Ad.dto"));
|
|
40
40
|
exports.EVENTS = __importStar(require("./events"));
|
|
41
41
|
exports.Ai = __importStar(require("./ai/Ai.dto"));
|
|
42
42
|
exports.PAYMENTS = __importStar(require("./payments"));
|
|
43
|
+
exports.ADDRESSES = __importStar(require("./addresses/addresses.dto"));
|
|
@@ -5,6 +5,7 @@ export declare const subjectTypeSchema: z.ZodEnum<{
|
|
|
5
5
|
motors: "motors";
|
|
6
6
|
used_products: "used_products";
|
|
7
7
|
}>;
|
|
8
|
+
export declare const adMediaSchema: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodAny>>>;
|
|
8
9
|
export declare const createAdSchema: z.ZodObject<{
|
|
9
10
|
motor: z.ZodNullable<z.ZodOptional<z.ZodObject<{
|
|
10
11
|
ad_id: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
@@ -75,6 +76,7 @@ export declare const createAdSchema: z.ZodObject<{
|
|
|
75
76
|
negotiable: z.ZodNullable<z.ZodOptional<z.ZodCoercedBoolean<unknown>>>;
|
|
76
77
|
latitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
77
78
|
longitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
79
|
+
saved_address_id: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
78
80
|
baseAdminBoundaryId: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>>;
|
|
79
81
|
media: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodAny>>>;
|
|
80
82
|
subject_type: z.ZodOptional<z.ZodEnum<{
|
|
@@ -172,6 +174,7 @@ export declare const updateAdSchema: z.ZodObject<{
|
|
|
172
174
|
negotiable: z.ZodNullable<z.ZodOptional<z.ZodCoercedBoolean<unknown>>>;
|
|
173
175
|
latitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
174
176
|
longitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
177
|
+
saved_address_id: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
175
178
|
baseAdminBoundaryId: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>>;
|
|
176
179
|
media: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodAny>>>;
|
|
177
180
|
subject_type: z.ZodOptional<z.ZodEnum<{
|
|
@@ -264,6 +267,7 @@ export declare const saveAdSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
264
267
|
negotiable: z.ZodNullable<z.ZodOptional<z.ZodCoercedBoolean<unknown>>>;
|
|
265
268
|
latitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
266
269
|
longitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
270
|
+
saved_address_id: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
267
271
|
baseAdminBoundaryId: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>>;
|
|
268
272
|
media: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodAny>>>;
|
|
269
273
|
subject_type: z.ZodOptional<z.ZodEnum<{
|
|
@@ -360,6 +364,7 @@ export declare const saveAdSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
360
364
|
negotiable: z.ZodNullable<z.ZodOptional<z.ZodCoercedBoolean<unknown>>>;
|
|
361
365
|
latitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
362
366
|
longitude: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
367
|
+
saved_address_id: z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
363
368
|
baseAdminBoundaryId: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNullable<z.ZodOptional<z.ZodCoercedNumber<unknown>>>>;
|
|
364
369
|
media: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodAny>>>;
|
|
365
370
|
subject_type: z.ZodOptional<z.ZodEnum<{
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.saveAdSchema = exports.updateAdSchema = exports.createAdSchema = exports.subjectTypeSchema = void 0;
|
|
3
|
+
exports.saveAdSchema = exports.updateAdSchema = exports.createAdSchema = exports.adMediaSchema = exports.subjectTypeSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
+
const AdMedia_1 = require("../../constants/ad/AdMedia");
|
|
6
|
+
const adMedia_1 = require("../../utils/adMedia");
|
|
5
7
|
exports.subjectTypeSchema = zod_1.z.enum([
|
|
6
8
|
"properties",
|
|
7
9
|
"services",
|
|
@@ -130,6 +132,40 @@ const createServiceSchema = baseServiceSchema;
|
|
|
130
132
|
const updateServiceSchema = baseServiceSchema.extend({
|
|
131
133
|
id: zod_1.z.coerce.number().int().positive().optional(),
|
|
132
134
|
});
|
|
135
|
+
// Media is optional: an ad may have no media, only one video, or only images.
|
|
136
|
+
exports.adMediaSchema = zod_1.z
|
|
137
|
+
.array(zod_1.z.any())
|
|
138
|
+
.superRefine((media, ctx) => {
|
|
139
|
+
const { images, videos } = (0, adMedia_1.countAdMedia)(media);
|
|
140
|
+
if (images > AdMedia_1.MAX_AD_IMAGES) {
|
|
141
|
+
ctx.addIssue({
|
|
142
|
+
code: "custom",
|
|
143
|
+
message: `An ad can contain up to ${AdMedia_1.MAX_AD_IMAGES} images`,
|
|
144
|
+
params: { code: AdMedia_1.AdMediaIssueCode.TOO_MANY_IMAGES, max: AdMedia_1.MAX_AD_IMAGES },
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (videos > AdMedia_1.MAX_AD_VIDEOS) {
|
|
148
|
+
ctx.addIssue({
|
|
149
|
+
code: "custom",
|
|
150
|
+
message: `An ad can contain up to ${AdMedia_1.MAX_AD_VIDEOS} video`,
|
|
151
|
+
params: { code: AdMedia_1.AdMediaIssueCode.TOO_MANY_VIDEOS, max: AdMedia_1.MAX_AD_VIDEOS },
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
media.forEach((item, index) => {
|
|
155
|
+
if ((0, adMedia_1.isAdVideoMedia)(item) &&
|
|
156
|
+
typeof (item === null || item === void 0 ? void 0 : item.size) === "number" &&
|
|
157
|
+
item.size > AdMedia_1.MAX_AD_VIDEO_BYTES) {
|
|
158
|
+
ctx.addIssue({
|
|
159
|
+
code: "custom",
|
|
160
|
+
path: [index],
|
|
161
|
+
message: `An ad video cannot exceed ${AdMedia_1.MAX_AD_VIDEO_BYTES / (1024 * 1024)} MB`,
|
|
162
|
+
params: { code: AdMedia_1.AdMediaIssueCode.VIDEO_TOO_LARGE, max: AdMedia_1.MAX_AD_VIDEO_BYTES },
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
})
|
|
167
|
+
.optional()
|
|
168
|
+
.nullable();
|
|
133
169
|
const baseAdCommon = zod_1.z.object({
|
|
134
170
|
title: zod_1.z.string().trim().optional(),
|
|
135
171
|
status_id: zod_1.z.coerce.number().int().positive().optional(),
|
|
@@ -140,12 +176,13 @@ const baseAdCommon = zod_1.z.object({
|
|
|
140
176
|
negotiable: zod_1.z.coerce.boolean().optional().nullable(),
|
|
141
177
|
latitude: zod_1.z.coerce.number().optional().nullable(),
|
|
142
178
|
longitude: zod_1.z.coerce.number().optional().nullable(),
|
|
179
|
+
saved_address_id: zod_1.z.coerce.number().int().positive().optional().nullable(),
|
|
143
180
|
baseAdminBoundaryId: zod_1.z.preprocess((value) => {
|
|
144
181
|
if (value === 0 || value === "0")
|
|
145
182
|
return undefined;
|
|
146
183
|
return value;
|
|
147
184
|
}, zod_1.z.coerce.number().optional().nullable()),
|
|
148
|
-
media:
|
|
185
|
+
media: exports.adMediaSchema,
|
|
149
186
|
subject_type: exports.subjectTypeSchema.optional(),
|
|
150
187
|
base_price: zod_1.z.coerce.number().optional().nullable(),
|
|
151
188
|
contact_methods: zod_1.z
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const createAddressSchema: z.ZodObject<{
|
|
3
|
+
label: z.ZodString;
|
|
4
|
+
location_description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
5
|
+
formatted_address: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
6
|
+
latitude: z.ZodCoercedNumber<unknown>;
|
|
7
|
+
longitude: z.ZodCoercedNumber<unknown>;
|
|
8
|
+
admin_boundary_id: z.ZodCoercedNumber<unknown>;
|
|
9
|
+
is_default: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export declare const updateAddressSchema: z.ZodObject<{
|
|
12
|
+
label: z.ZodOptional<z.ZodString>;
|
|
13
|
+
location_description: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
14
|
+
formatted_address: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
15
|
+
latitude: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
16
|
+
longitude: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
17
|
+
admin_boundary_id: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
18
|
+
is_default: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
19
|
+
}, z.core.$strip>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateAddressSchema = exports.createAddressSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.createAddressSchema = zod_1.z.object({
|
|
6
|
+
label: zod_1.z.string().trim().min(1).max(100),
|
|
7
|
+
location_description: zod_1.z.string().trim().max(500).nullable().optional(),
|
|
8
|
+
formatted_address: zod_1.z.string().trim().max(1000).nullable().optional(),
|
|
9
|
+
latitude: zod_1.z.coerce.number().finite().min(-90).max(90),
|
|
10
|
+
longitude: zod_1.z.coerce.number().finite().min(-180).max(180),
|
|
11
|
+
admin_boundary_id: zod_1.z.coerce.number().int().positive(),
|
|
12
|
+
is_default: zod_1.z.boolean().optional(),
|
|
13
|
+
});
|
|
14
|
+
exports.updateAddressSchema = exports.createAddressSchema
|
|
15
|
+
.partial()
|
|
16
|
+
.refine((value) => Object.keys(value).length > 0, {
|
|
17
|
+
message: "At least one field is required",
|
|
18
|
+
});
|
package/dist/cjs/schema/index.js
CHANGED
|
@@ -33,10 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.COMMUNICATION = exports.PAYMENTS = exports.EVENTS = exports.COMMON = exports.AI = exports.AD = void 0;
|
|
36
|
+
exports.ADDRESSES = exports.COMMUNICATION = exports.PAYMENTS = exports.EVENTS = exports.COMMON = exports.AI = exports.AD = void 0;
|
|
37
37
|
exports.AD = __importStar(require("./ad"));
|
|
38
38
|
exports.AI = __importStar(require("./ai"));
|
|
39
39
|
exports.COMMON = __importStar(require("./common"));
|
|
40
40
|
exports.EVENTS = __importStar(require("./events"));
|
|
41
41
|
exports.PAYMENTS = __importStar(require("./payments"));
|
|
42
42
|
exports.COMMUNICATION = __importStar(require("./communication"));
|
|
43
|
+
exports.ADDRESSES = __importStar(require("./addresses/addresses.schema"));
|
package/dist/cjs/types/ad/Ad.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Reusable, private address owned by a user. */
|
|
2
|
+
export interface IAddress {
|
|
3
|
+
id: number;
|
|
4
|
+
user_id: number;
|
|
5
|
+
label: string;
|
|
6
|
+
location_description: string | null;
|
|
7
|
+
formatted_address: string | null;
|
|
8
|
+
latitude: number;
|
|
9
|
+
longitude: number;
|
|
10
|
+
admin_boundary_id: number;
|
|
11
|
+
is_default: boolean;
|
|
12
|
+
created_at: string;
|
|
13
|
+
updated_at: string;
|
|
14
|
+
}
|
|
@@ -40,9 +40,16 @@ export type IChatMessage = {
|
|
|
40
40
|
};
|
|
41
41
|
export declare enum MessageTypeEnum {
|
|
42
42
|
TEXT = 1,
|
|
43
|
-
PRICE_OFFER = 2
|
|
43
|
+
PRICE_OFFER = 2,
|
|
44
|
+
CONTACT_INVITATION = 3
|
|
44
45
|
}
|
|
45
46
|
export { MessageTypeEnum as MessageTypeType };
|
|
47
|
+
export type ContactInvitationPayload = {
|
|
48
|
+
version: 1;
|
|
49
|
+
phone_e164: string;
|
|
50
|
+
can_call: boolean;
|
|
51
|
+
can_whatsapp: boolean;
|
|
52
|
+
};
|
|
46
53
|
export type SendMessageDto = {
|
|
47
54
|
chat_room_id: number;
|
|
48
55
|
requester_id: number;
|
|
@@ -5,4 +5,5 @@ var MessageTypeEnum;
|
|
|
5
5
|
(function (MessageTypeEnum) {
|
|
6
6
|
MessageTypeEnum[MessageTypeEnum["TEXT"] = 1] = "TEXT";
|
|
7
7
|
MessageTypeEnum[MessageTypeEnum["PRICE_OFFER"] = 2] = "PRICE_OFFER";
|
|
8
|
+
MessageTypeEnum[MessageTypeEnum["CONTACT_INVITATION"] = 3] = "CONTACT_INVITATION";
|
|
8
9
|
})(MessageTypeEnum || (exports.MessageTypeType = exports.MessageTypeEnum = MessageTypeEnum = {}));
|
|
@@ -6,6 +6,7 @@ export * as Config from "./common/Config";
|
|
|
6
6
|
export * as FilterParams from "./common/FilterParams";
|
|
7
7
|
export * as Ad from "./ad/Ad";
|
|
8
8
|
export * as AdLocation from "./ad/AdLocation";
|
|
9
|
+
export * as Addresses from "./addresses/Address";
|
|
9
10
|
export * as AdPromotion from "./ad/AdPromotion";
|
|
10
11
|
export * as Motor from "./motor/Motor";
|
|
11
12
|
export * as MotorTrim from "./motor/MotorTrim";
|
package/dist/cjs/types/index.js
CHANGED
|
@@ -36,8 +36,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
40
|
-
exports.Payment = exports.Analysis = exports.Google = exports.Kyc = exports.SocialMediaProfile = exports.SocialMediaPlatform = exports.Image = exports.Media = exports.File = exports.NotificationToken = exports.MessageTemplate = exports.Device = exports.Chat = exports.AppStartScreen = exports.MetaData = void 0;
|
|
39
|
+
exports.PotentialUser = exports.Loyalty = exports.Favorite = exports.Wallet = exports.Permission = exports.Role = exports.User = exports.EventVenue = exports.EventWedding = exports.EventTimeline = exports.EventRsvp = exports.Event = exports.District = exports.City = exports.AdminBoundary = exports.WorkType = exports.UsedProductCondition = exports.UsedProductAge = exports.Unit = exports.Transmission = exports.RegionalSpec = exports.PublisherType = exports.PropertyStatus = exports.PriceType = exports.OfferType = exports.LicenseType = exports.FuelType = exports.Feature = exports.Facility = exports.Currency = exports.Color = exports.CategoryWorkType = exports.Category = exports.CarBody = exports.UsedProduct = exports.Service = exports.PropertySubType = exports.Property = exports.MotorTrim = exports.Motor = exports.AdPromotion = exports.Addresses = exports.AdLocation = exports.Ad = exports.FilterParams = exports.Config = exports.AccessType = exports.Status = exports.Response = exports.LocalizedName = void 0;
|
|
40
|
+
exports.Payment = exports.Analysis = exports.Google = exports.Kyc = exports.SocialMediaProfile = exports.SocialMediaPlatform = exports.Image = exports.Media = exports.File = exports.NotificationToken = exports.MessageTemplate = exports.Device = exports.Chat = exports.AppStartScreen = exports.MetaData = exports.Company = void 0;
|
|
41
41
|
// common
|
|
42
42
|
exports.LocalizedName = __importStar(require("./common/LocalizedName"));
|
|
43
43
|
exports.Response = __importStar(require("./common/Response"));
|
|
@@ -48,6 +48,7 @@ exports.FilterParams = __importStar(require("./common/FilterParams"));
|
|
|
48
48
|
// listings
|
|
49
49
|
exports.Ad = __importStar(require("./ad/Ad"));
|
|
50
50
|
exports.AdLocation = __importStar(require("./ad/AdLocation"));
|
|
51
|
+
exports.Addresses = __importStar(require("./addresses/Address"));
|
|
51
52
|
exports.AdPromotion = __importStar(require("./ad/AdPromotion"));
|
|
52
53
|
exports.Motor = __importStar(require("./motor/Motor"));
|
|
53
54
|
exports.MotorTrim = __importStar(require("./motor/MotorTrim"));
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countAdMedia = exports.isAdVideoMedia = void 0;
|
|
4
|
+
const VIDEO_EXTENSION = /\.(mp4|mov|webm|m4v|ogv)(?:[?#]|$)/i;
|
|
5
|
+
// Older records can omit mimetype: fall back to the URL extension, and count
|
|
6
|
+
// anything unknown as an image rather than accepting unlimited untyped media.
|
|
7
|
+
const isAdVideoMedia = (media) => {
|
|
8
|
+
if (!media || typeof media !== "object")
|
|
9
|
+
return false;
|
|
10
|
+
const item = media;
|
|
11
|
+
const mimetype = typeof item.mimetype === "string" ? item.mimetype.toLowerCase() : "";
|
|
12
|
+
if (mimetype.startsWith("video/"))
|
|
13
|
+
return true;
|
|
14
|
+
if (mimetype.startsWith("image/"))
|
|
15
|
+
return false;
|
|
16
|
+
const source = typeof item.url === "string" && item.url
|
|
17
|
+
? item.url
|
|
18
|
+
: typeof item.path === "string" ? item.path : "";
|
|
19
|
+
return VIDEO_EXTENSION.test(source);
|
|
20
|
+
};
|
|
21
|
+
exports.isAdVideoMedia = isAdVideoMedia;
|
|
22
|
+
const countAdMedia = (media) => {
|
|
23
|
+
const items = Array.isArray(media) ? media : [];
|
|
24
|
+
const videos = items.filter(exports.isAdVideoMedia).length;
|
|
25
|
+
return { images: items.length - videos, videos };
|
|
26
|
+
};
|
|
27
|
+
exports.countAdMedia = countAdMedia;
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./converter"), exports);
|
|
18
18
|
__exportStar(require("./routes"), exports);
|
|
19
|
+
__exportStar(require("./adMedia"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Media is optional on every ad. These are the only limits, shared by every
|
|
2
|
+
// client and the API so they can never drift apart.
|
|
3
|
+
export const MAX_AD_IMAGES = 30;
|
|
4
|
+
export const MAX_AD_VIDEOS = 1;
|
|
5
|
+
export const MAX_AD_VIDEO_BYTES = 50 * 1024 * 1024;
|
|
6
|
+
// Stable codes carried in `params.code` of adMediaSchema issues, so clients can
|
|
7
|
+
// show localized messages without re-implementing the rules.
|
|
8
|
+
export var AdMediaIssueCode;
|
|
9
|
+
(function (AdMediaIssueCode) {
|
|
10
|
+
AdMediaIssueCode["TOO_MANY_IMAGES"] = "too_many_images";
|
|
11
|
+
AdMediaIssueCode["TOO_MANY_VIDEOS"] = "too_many_videos";
|
|
12
|
+
AdMediaIssueCode["VIDEO_TOO_LARGE"] = "video_too_large";
|
|
13
|
+
})(AdMediaIssueCode || (AdMediaIssueCode = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/dto/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { AdMediaIssueCode, MAX_AD_IMAGES, MAX_AD_VIDEO_BYTES, MAX_AD_VIDEOS, } from "../../constants/ad/AdMedia.js";
|
|
3
|
+
import { countAdMedia, isAdVideoMedia } from "../../utils/adMedia.js";
|
|
2
4
|
export const subjectTypeSchema = z.enum([
|
|
3
5
|
"properties",
|
|
4
6
|
"services",
|
|
@@ -127,6 +129,40 @@ const createServiceSchema = baseServiceSchema;
|
|
|
127
129
|
const updateServiceSchema = baseServiceSchema.extend({
|
|
128
130
|
id: z.coerce.number().int().positive().optional(),
|
|
129
131
|
});
|
|
132
|
+
// Media is optional: an ad may have no media, only one video, or only images.
|
|
133
|
+
export const adMediaSchema = z
|
|
134
|
+
.array(z.any())
|
|
135
|
+
.superRefine((media, ctx) => {
|
|
136
|
+
const { images, videos } = countAdMedia(media);
|
|
137
|
+
if (images > MAX_AD_IMAGES) {
|
|
138
|
+
ctx.addIssue({
|
|
139
|
+
code: "custom",
|
|
140
|
+
message: `An ad can contain up to ${MAX_AD_IMAGES} images`,
|
|
141
|
+
params: { code: AdMediaIssueCode.TOO_MANY_IMAGES, max: MAX_AD_IMAGES },
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (videos > MAX_AD_VIDEOS) {
|
|
145
|
+
ctx.addIssue({
|
|
146
|
+
code: "custom",
|
|
147
|
+
message: `An ad can contain up to ${MAX_AD_VIDEOS} video`,
|
|
148
|
+
params: { code: AdMediaIssueCode.TOO_MANY_VIDEOS, max: MAX_AD_VIDEOS },
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
media.forEach((item, index) => {
|
|
152
|
+
if (isAdVideoMedia(item) &&
|
|
153
|
+
typeof (item === null || item === void 0 ? void 0 : item.size) === "number" &&
|
|
154
|
+
item.size > MAX_AD_VIDEO_BYTES) {
|
|
155
|
+
ctx.addIssue({
|
|
156
|
+
code: "custom",
|
|
157
|
+
path: [index],
|
|
158
|
+
message: `An ad video cannot exceed ${MAX_AD_VIDEO_BYTES / (1024 * 1024)} MB`,
|
|
159
|
+
params: { code: AdMediaIssueCode.VIDEO_TOO_LARGE, max: MAX_AD_VIDEO_BYTES },
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
})
|
|
164
|
+
.optional()
|
|
165
|
+
.nullable();
|
|
130
166
|
const baseAdCommon = z.object({
|
|
131
167
|
title: z.string().trim().optional(),
|
|
132
168
|
status_id: z.coerce.number().int().positive().optional(),
|
|
@@ -137,12 +173,13 @@ const baseAdCommon = z.object({
|
|
|
137
173
|
negotiable: z.coerce.boolean().optional().nullable(),
|
|
138
174
|
latitude: z.coerce.number().optional().nullable(),
|
|
139
175
|
longitude: z.coerce.number().optional().nullable(),
|
|
176
|
+
saved_address_id: z.coerce.number().int().positive().optional().nullable(),
|
|
140
177
|
baseAdminBoundaryId: z.preprocess((value) => {
|
|
141
178
|
if (value === 0 || value === "0")
|
|
142
179
|
return undefined;
|
|
143
180
|
return value;
|
|
144
181
|
}, z.coerce.number().optional().nullable()),
|
|
145
|
-
media:
|
|
182
|
+
media: adMediaSchema,
|
|
146
183
|
subject_type: subjectTypeSchema.optional(),
|
|
147
184
|
base_price: z.coerce.number().optional().nullable(),
|
|
148
185
|
contact_methods: z
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const createAddressSchema = z.object({
|
|
3
|
+
label: z.string().trim().min(1).max(100),
|
|
4
|
+
location_description: z.string().trim().max(500).nullable().optional(),
|
|
5
|
+
formatted_address: z.string().trim().max(1000).nullable().optional(),
|
|
6
|
+
latitude: z.coerce.number().finite().min(-90).max(90),
|
|
7
|
+
longitude: z.coerce.number().finite().min(-180).max(180),
|
|
8
|
+
admin_boundary_id: z.coerce.number().int().positive(),
|
|
9
|
+
is_default: z.boolean().optional(),
|
|
10
|
+
});
|
|
11
|
+
export const updateAddressSchema = createAddressSchema
|
|
12
|
+
.partial()
|
|
13
|
+
.refine((value) => Object.keys(value).length > 0, {
|
|
14
|
+
message: "At least one field is required",
|
|
15
|
+
});
|
package/dist/esm/schema/index.js
CHANGED
package/dist/esm/types/ad/Ad.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,5 +2,6 @@ export var MessageTypeEnum;
|
|
|
2
2
|
(function (MessageTypeEnum) {
|
|
3
3
|
MessageTypeEnum[MessageTypeEnum["TEXT"] = 1] = "TEXT";
|
|
4
4
|
MessageTypeEnum[MessageTypeEnum["PRICE_OFFER"] = 2] = "PRICE_OFFER";
|
|
5
|
+
MessageTypeEnum[MessageTypeEnum["CONTACT_INVITATION"] = 3] = "CONTACT_INVITATION";
|
|
5
6
|
})(MessageTypeEnum || (MessageTypeEnum = {}));
|
|
6
7
|
export { MessageTypeEnum as MessageTypeType };
|
package/dist/esm/types/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export * as FilterParams from "./common/FilterParams.js";
|
|
|
11
11
|
// listings
|
|
12
12
|
export * as Ad from "./ad/Ad.js";
|
|
13
13
|
export * as AdLocation from "./ad/AdLocation.js";
|
|
14
|
+
export * as Addresses from "./addresses/Address.js";
|
|
14
15
|
export * as AdPromotion from "./ad/AdPromotion.js";
|
|
15
16
|
export * as Motor from "./motor/Motor.js";
|
|
16
17
|
export * as MotorTrim from "./motor/MotorTrim.js";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const VIDEO_EXTENSION = /\.(mp4|mov|webm|m4v|ogv)(?:[?#]|$)/i;
|
|
2
|
+
// Older records can omit mimetype: fall back to the URL extension, and count
|
|
3
|
+
// anything unknown as an image rather than accepting unlimited untyped media.
|
|
4
|
+
export const isAdVideoMedia = (media) => {
|
|
5
|
+
if (!media || typeof media !== "object")
|
|
6
|
+
return false;
|
|
7
|
+
const item = media;
|
|
8
|
+
const mimetype = typeof item.mimetype === "string" ? item.mimetype.toLowerCase() : "";
|
|
9
|
+
if (mimetype.startsWith("video/"))
|
|
10
|
+
return true;
|
|
11
|
+
if (mimetype.startsWith("image/"))
|
|
12
|
+
return false;
|
|
13
|
+
const source = typeof item.url === "string" && item.url
|
|
14
|
+
? item.url
|
|
15
|
+
: typeof item.path === "string" ? item.path : "";
|
|
16
|
+
return VIDEO_EXTENSION.test(source);
|
|
17
|
+
};
|
|
18
|
+
export const countAdMedia = (media) => {
|
|
19
|
+
const items = Array.isArray(media) ? media : [];
|
|
20
|
+
const videos = items.filter(isAdVideoMedia).length;
|
|
21
|
+
return { images: items.length - videos, videos };
|
|
22
|
+
};
|
package/dist/esm/utils/index.js
CHANGED