@deallony/shared 1.2.64 → 1.2.69
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/company/Company.d.ts +12 -0
- package/dist/cjs/constants/company/Company.js +13 -1
- package/dist/cjs/constants/events/Event.js +3 -0
- package/dist/cjs/constants/events/EventPricing.d.ts +44 -0
- package/dist/cjs/constants/events/EventPricing.js +18 -0
- package/dist/cjs/constants/events/index.d.ts +1 -0
- package/dist/cjs/constants/events/index.js +1 -0
- package/dist/cjs/constants/routes/app.d.ts +30 -1
- package/dist/cjs/constants/routes/app.js +7 -1
- package/dist/cjs/dto/ai/gemini-api-key.dto.d.ts +4 -1
- package/dist/cjs/dto/analysis/Analysis.dto.d.ts +4 -0
- package/dist/cjs/dto/analysis/Analysis.dto.js +2 -0
- package/dist/cjs/dto/events/Event.dto.d.ts +3 -1
- 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 +35 -0
- package/dist/cjs/schema/ad/save-ad.schema.js +23 -1
- package/dist/cjs/schema/ai/gemini-api-key.schema.d.ts +46 -3
- package/dist/cjs/schema/ai/gemini-api-key.schema.js +36 -9
- package/dist/cjs/schema/analysis/analysis-report.schema.d.ts +17 -0
- package/dist/cjs/schema/analysis/analysis-report.schema.js +29 -0
- package/dist/cjs/schema/analysis/index.d.ts +1 -0
- package/dist/cjs/schema/analysis/index.js +17 -0
- package/dist/cjs/schema/communication/index.d.ts +1 -0
- package/dist/cjs/schema/communication/index.js +1 -0
- package/dist/cjs/schema/communication/offer.schema.d.ts +49 -0
- package/dist/cjs/schema/communication/offer.schema.js +31 -0
- package/dist/cjs/schema/communication/support-ticket.schema.d.ts +3 -3
- package/dist/cjs/schema/events/Event.schema.d.ts +20 -0
- package/dist/cjs/schema/events/Event.schema.js +11 -1
- 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 +27 -1
- package/dist/cjs/types/ad-common/PriceType.d.ts +2 -0
- package/dist/cjs/types/analysis/AnalysisDailySnapshot.d.ts +98 -0
- package/dist/cjs/types/common/MetaData.d.ts +3 -0
- package/dist/cjs/types/communication/Chat.d.ts +30 -1
- package/dist/cjs/types/communication/Chat.js +10 -1
- package/dist/cjs/types/company/Company.d.ts +26 -0
- package/dist/cjs/types/events/Event.d.ts +8 -0
- package/dist/cjs/types/integrations/GeminiApiKey.d.ts +11 -2
- package/dist/cjs/utils/analysis.d.ts +7 -0
- package/dist/cjs/utils/analysis.js +14 -0
- package/dist/cjs/utils/index.d.ts +2 -0
- package/dist/cjs/utils/index.js +2 -0
- package/dist/cjs/utils/rentPrices.d.ts +8 -0
- package/dist/cjs/utils/rentPrices.js +33 -0
- package/dist/esm/constants/company/Company.js +12 -0
- package/dist/esm/constants/events/Event.js +3 -0
- package/dist/esm/constants/events/EventPricing.js +15 -0
- package/dist/esm/constants/events/index.js +1 -0
- package/dist/esm/constants/routes/app.js +7 -1
- package/dist/esm/dto/analysis/Analysis.dto.js +1 -0
- package/dist/esm/dto/index.js +1 -0
- package/dist/esm/schema/ad/save-ad.schema.js +22 -0
- package/dist/esm/schema/ai/gemini-api-key.schema.js +35 -8
- package/dist/esm/schema/analysis/analysis-report.schema.js +26 -0
- package/dist/esm/schema/analysis/index.js +1 -0
- package/dist/esm/schema/communication/index.js +1 -0
- package/dist/esm/schema/communication/offer.schema.js +28 -0
- package/dist/esm/schema/events/Event.schema.js +11 -1
- package/dist/esm/schema/index.js +1 -0
- package/dist/esm/types/communication/Chat.js +9 -0
- package/dist/esm/utils/analysis.js +10 -0
- package/dist/esm/utils/index.js +2 -0
- package/dist/esm/utils/rentPrices.js +26 -0
- package/package.json +58 -58
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rentOfferTotal = exports.sortRentPrices = exports.getDisplayRentPrice = exports.getMainRentPrice = void 0;
|
|
4
|
+
/** The rent price shown on cards: the one marked main, else the first listed. */
|
|
5
|
+
const getMainRentPrice = (ad) => {
|
|
6
|
+
var _a, _b, _c;
|
|
7
|
+
const prices = (_a = ad === null || ad === void 0 ? void 0 : ad.rent_prices) !== null && _a !== void 0 ? _a : [];
|
|
8
|
+
return (_c = (_b = prices.find((item) => item.is_main)) !== null && _b !== void 0 ? _b : prices[0]) !== null && _c !== void 0 ? _c : null;
|
|
9
|
+
};
|
|
10
|
+
exports.getMainRentPrice = getMainRentPrice;
|
|
11
|
+
/** The price to show for an ad in a list: the filtered period, else the main rent price. */
|
|
12
|
+
const getDisplayRentPrice = (ad, priceTypeId) => {
|
|
13
|
+
var _a;
|
|
14
|
+
if (ad === null || ad === void 0 ? void 0 : ad.matched_rent_price)
|
|
15
|
+
return ad.matched_rent_price;
|
|
16
|
+
if (priceTypeId) {
|
|
17
|
+
const match = (_a = ad === null || ad === void 0 ? void 0 : ad.rent_prices) === null || _a === void 0 ? void 0 : _a.find((item) => item.price_type_id === Number(priceTypeId));
|
|
18
|
+
if (match)
|
|
19
|
+
return match;
|
|
20
|
+
}
|
|
21
|
+
return (0, exports.getMainRentPrice)(ad);
|
|
22
|
+
};
|
|
23
|
+
exports.getDisplayRentPrice = getDisplayRentPrice;
|
|
24
|
+
/** Rent prices ordered from the shortest period to the longest. */
|
|
25
|
+
const sortRentPrices = (prices) => [...(prices !== null && prices !== void 0 ? prices : [])].sort((a, b) => {
|
|
26
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
27
|
+
return ((_b = (_a = a.price_type) === null || _a === void 0 ? void 0 : _a.period_days) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER) -
|
|
28
|
+
((_d = (_c = b.price_type) === null || _c === void 0 ? void 0 : _c.period_days) !== null && _d !== void 0 ? _d : Number.MAX_SAFE_INTEGER) ||
|
|
29
|
+
((_f = (_e = a.price_type) === null || _e === void 0 ? void 0 : _e.display_order) !== null && _f !== void 0 ? _f : 0) - ((_h = (_g = b.price_type) === null || _g === void 0 ? void 0 : _g.display_order) !== null && _h !== void 0 ? _h : 0);
|
|
30
|
+
});
|
|
31
|
+
exports.sortRentPrices = sortRentPrices;
|
|
32
|
+
const rentOfferTotal = (pricePerPeriod, duration) => Math.max(0, Number(pricePerPeriod) || 0) * Math.max(0, Math.floor(Number(duration) || 0));
|
|
33
|
+
exports.rentOfferTotal = rentOfferTotal;
|
|
@@ -7,3 +7,15 @@ export const CompanyStatusOptions = Object.values(COMPANY_STATUS).map((status) =
|
|
|
7
7
|
value: status,
|
|
8
8
|
label: status.charAt(0).toUpperCase() + status.slice(1),
|
|
9
9
|
}));
|
|
10
|
+
/** A user's role inside a company; a company has exactly one owner */
|
|
11
|
+
export const COMPANY_MEMBER_ROLE = {
|
|
12
|
+
OWNER: 'owner',
|
|
13
|
+
ADMIN: 'admin',
|
|
14
|
+
MEMBER: 'member',
|
|
15
|
+
};
|
|
16
|
+
/** What the account represents; all three behave the same */
|
|
17
|
+
export const COMPANY_TYPE = {
|
|
18
|
+
COMPANY: 'company',
|
|
19
|
+
TEAM: 'team',
|
|
20
|
+
OTHER: 'other',
|
|
21
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const EVENT_CREATION_PRICE_SETTING = "event_creation_price";
|
|
2
|
+
export const EventOwnerTypes = {
|
|
3
|
+
COMPANY: { value: "company", name: { en: "Company", ar: "شركة" } },
|
|
4
|
+
USER: { value: "user", name: { en: "Personal", ar: "شخصي" } },
|
|
5
|
+
};
|
|
6
|
+
export const EventOwnerTypeValues = ["company", "user"];
|
|
7
|
+
export const EventOwnerTypeOptions = Object.values(EventOwnerTypes).map((t) => ({
|
|
8
|
+
value: t.value,
|
|
9
|
+
name: t.name,
|
|
10
|
+
}));
|
|
11
|
+
export const EventPublishPaymentMethodValues = [
|
|
12
|
+
"balance",
|
|
13
|
+
"loyalty",
|
|
14
|
+
"combined",
|
|
15
|
+
];
|
|
@@ -135,6 +135,7 @@ export const APP_ROUTES = {
|
|
|
135
135
|
by_whatsapp: props.by_whatsapp,
|
|
136
136
|
phone: props.phone,
|
|
137
137
|
ad_price: props.ad_price,
|
|
138
|
+
rent_prices: props.rent_prices,
|
|
138
139
|
},
|
|
139
140
|
}),
|
|
140
141
|
},
|
|
@@ -165,6 +166,8 @@ export const APP_ROUTES = {
|
|
|
165
166
|
new: () => ({ pathname: "/company/new" }),
|
|
166
167
|
edit: (id) => ({ pathname: "/company/new", params: { id } }),
|
|
167
168
|
details: (id) => ({ pathname: "/company/details/[id]", params: { id } }),
|
|
169
|
+
/** Public profile with the company's ads */
|
|
170
|
+
profile: (id) => ({ pathname: "/company/profile/[id]", params: { id } }),
|
|
168
171
|
},
|
|
169
172
|
venue: {
|
|
170
173
|
new: (companyId) => ({ pathname: "/venue/new", params: { company_id: companyId } }),
|
|
@@ -172,7 +175,10 @@ export const APP_ROUTES = {
|
|
|
172
175
|
details: (id) => ({ pathname: "/venue/details/[id]", params: { id } }),
|
|
173
176
|
},
|
|
174
177
|
event: {
|
|
175
|
-
new: (venueId) =>
|
|
178
|
+
new: (venueId) => venueId ? { pathname: "/event/new", params: { venue_id: venueId } } : { pathname: "/event/new", params: { personal: "1" } },
|
|
179
|
+
start: () => ({ pathname: "/event/start" }),
|
|
180
|
+
mine: () => ({ pathname: "/event/mine" }),
|
|
181
|
+
publish: (id) => ({ pathname: "/event/publish/[id]", params: { id } }),
|
|
176
182
|
edit: (id) => ({ pathname: "/event/new", params: { id } }),
|
|
177
183
|
details: (id) => ({ pathname: "/event/details/[id]", params: { id } }),
|
|
178
184
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/dto/index.js
CHANGED
|
@@ -6,3 +6,4 @@ export * as GEMINI_API_KEYS from './ai/gemini-api-key.dto.js';
|
|
|
6
6
|
export * as PAYMENTS from './payments/index.js';
|
|
7
7
|
export * as ADDRESSES from './addresses/addresses.dto.js';
|
|
8
8
|
export * as POTENTIAL_USERS from './potential-users/potential-user-import.dto.js';
|
|
9
|
+
export * as ANALYSIS from './analysis/Analysis.dto.js';
|
|
@@ -163,6 +163,26 @@ export const adMediaSchema = z
|
|
|
163
163
|
})
|
|
164
164
|
.optional()
|
|
165
165
|
.nullable();
|
|
166
|
+
/** One rent price per period. Backend checks the period belongs to "For Rent". */
|
|
167
|
+
export const adRentPriceSchema = z.object({
|
|
168
|
+
price_type_id: z.coerce.number().int().positive(),
|
|
169
|
+
price: z.coerce.number().positive(),
|
|
170
|
+
is_main: z.coerce.boolean().optional(),
|
|
171
|
+
});
|
|
172
|
+
export const adRentPricesSchema = z
|
|
173
|
+
.array(adRentPriceSchema)
|
|
174
|
+
.max(10)
|
|
175
|
+
.superRefine((prices, ctx) => {
|
|
176
|
+
const ids = prices.map((item) => item.price_type_id);
|
|
177
|
+
if (new Set(ids).size !== ids.length) {
|
|
178
|
+
ctx.addIssue({ code: "custom", message: "Each rent period can be listed once" });
|
|
179
|
+
}
|
|
180
|
+
if (prices.filter((item) => item.is_main).length > 1) {
|
|
181
|
+
ctx.addIssue({ code: "custom", message: "Only one rent price can be the main price" });
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
.optional()
|
|
185
|
+
.nullable();
|
|
166
186
|
const baseAdCommon = z.object({
|
|
167
187
|
title: z.string().trim().optional(),
|
|
168
188
|
status_id: z.coerce.number().int().positive().optional(),
|
|
@@ -191,8 +211,10 @@ const baseAdCommon = z.object({
|
|
|
191
211
|
.optional()
|
|
192
212
|
.nullable(),
|
|
193
213
|
selected_phone: z.string().trim().optional().nullable(),
|
|
214
|
+
company_id: z.coerce.number().int().positive().optional().nullable(),
|
|
194
215
|
expires_at: z.iso.datetime().optional().nullable(),
|
|
195
216
|
adLocations: z.array(adLocationSchema).optional().nullable(),
|
|
217
|
+
rent_prices: adRentPricesSchema,
|
|
196
218
|
});
|
|
197
219
|
export const createAdSchema = z.object({
|
|
198
220
|
user_id: z.coerce.number().int().positive(),
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* The dashboard manages them through the admin schemas; other services lease a
|
|
5
|
-
* the tokens they used through the internal schemas.
|
|
3
|
+
* AI API keys (Gemini and Claude) are stored in backend-core (one table) and shared by every
|
|
4
|
+
* Deallony service. The dashboard manages them through the admin schemas; other services lease a
|
|
5
|
+
* key and report the tokens they used through the internal schemas.
|
|
6
6
|
*/
|
|
7
7
|
const geminiApiKeyIdSchema = z.coerce.number().int().positive();
|
|
8
|
-
/** Gemini
|
|
8
|
+
/** Which company's API a key belongs to: Google Gemini or Anthropic Claude */
|
|
9
|
+
export const AI_PROVIDERS = ['gemini', 'anthropic'];
|
|
10
|
+
export const aiProviderSchema = z.enum(AI_PROVIDERS);
|
|
11
|
+
/** Models offered in the dashboard for each provider; any other model ID can still be typed */
|
|
12
|
+
export const AI_PROVIDER_MODELS = {
|
|
13
|
+
gemini: ['gemini-3.5-flash-lite', 'gemini-3.1-flash-lite'],
|
|
14
|
+
anthropic: ['claude-haiku-5-5', 'claude-sonnet-5-5', 'claude-opus-5-5'],
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* How backend-core picks a key: `priority` always takes the first available key in the dashboard
|
|
18
|
+
* order, `balanced` takes the key with the fewest tokens used today.
|
|
19
|
+
*/
|
|
20
|
+
export const AI_KEY_SELECTION_MODES = ['priority', 'balanced'];
|
|
21
|
+
export const aiKeySelectionModeSchema = z.enum(AI_KEY_SELECTION_MODES);
|
|
22
|
+
/** Default model ID of a key, e.g. gemini-3.1-flash-lite or claude-haiku-5-5 */
|
|
9
23
|
export const geminiModelNameSchema = z.string().trim().min(1).max(100);
|
|
10
24
|
// ---------- Admin (dashboard) ----------
|
|
11
25
|
export const createGeminiApiKeySchema = z.object({
|
|
12
26
|
name: z.string().trim().min(1).max(255),
|
|
27
|
+
provider: aiProviderSchema.default('gemini'),
|
|
13
28
|
api_key: z.string().trim().min(20).max(512),
|
|
14
29
|
model_name: geminiModelNameSchema,
|
|
15
30
|
is_active: z.boolean().default(true),
|
|
@@ -18,6 +33,7 @@ export const createGeminiApiKeySchema = z.object({
|
|
|
18
33
|
export const updateGeminiApiKeySchema = z.object({
|
|
19
34
|
id: geminiApiKeyIdSchema,
|
|
20
35
|
name: z.string().trim().min(1).max(255).optional(),
|
|
36
|
+
provider: aiProviderSchema.optional(),
|
|
21
37
|
api_key: z.string().trim().min(20).max(512).optional(),
|
|
22
38
|
model_name: geminiModelNameSchema.optional(),
|
|
23
39
|
is_active: z.boolean().optional(),
|
|
@@ -29,23 +45,34 @@ export const geminiApiKeyIdBodySchema = z.object({
|
|
|
29
45
|
export const reorderGeminiApiKeysSchema = z.object({
|
|
30
46
|
ids: z.array(geminiApiKeyIdSchema).min(1),
|
|
31
47
|
});
|
|
48
|
+
export const aiKeySettingsSchema = z.object({
|
|
49
|
+
selection_mode: aiKeySelectionModeSchema,
|
|
50
|
+
});
|
|
32
51
|
// ---------- Internal (other services) ----------
|
|
33
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Ask backend-core for the next available key. `exclude_ids` are keys that already failed for
|
|
54
|
+
* this call, so a retry moves on to the next key in the order.
|
|
55
|
+
*/
|
|
34
56
|
export const leaseGeminiApiKeySchema = z.object({
|
|
57
|
+
/** Only keys whose default model is this one */
|
|
35
58
|
model_name: geminiModelNameSchema.optional(),
|
|
59
|
+
/** Only keys of these providers; all providers when left out */
|
|
60
|
+
providers: z.array(aiProviderSchema).min(1).optional(),
|
|
61
|
+
exclude_ids: z.array(geminiApiKeyIdSchema).optional(),
|
|
36
62
|
});
|
|
37
63
|
export const leasedGeminiApiKeySchema = z.object({
|
|
38
64
|
id: z.number().int().positive(),
|
|
65
|
+
provider: aiProviderSchema,
|
|
39
66
|
api_key: z.string(),
|
|
40
67
|
model_name: z.string(),
|
|
41
68
|
});
|
|
42
|
-
/** Sent after every
|
|
69
|
+
/** Sent after every AI call made with a leased key. */
|
|
43
70
|
export const reportGeminiApiKeyUsageSchema = z.object({
|
|
44
71
|
id: geminiApiKeyIdSchema,
|
|
45
|
-
/**
|
|
72
|
+
/** Total tokens of the response (input + output); 0 when the call failed */
|
|
46
73
|
total_tokens: z.coerce.number().int().min(0).default(0),
|
|
47
74
|
success: z.boolean().default(true),
|
|
48
|
-
/** HTTP status
|
|
75
|
+
/** HTTP status the provider answered with, e.g. 429 */
|
|
49
76
|
error_code: z.coerce.number().int().optional(),
|
|
50
77
|
error_message: z.string().trim().max(2000).optional(),
|
|
51
78
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** `metrics_version` of snapshots holding daily views (older snapshots held all-time totals) */
|
|
3
|
+
export const ANALYSIS_METRICS_VERSION = 2;
|
|
4
|
+
/** Longest period one analysis report covers */
|
|
5
|
+
export const ANALYSIS_REPORT_MAX_DAYS = 366;
|
|
6
|
+
/** Longest period rebuilt in one request; daily view records older than 180 days are deleted anyway */
|
|
7
|
+
export const ANALYSIS_REBUILD_MAX_DAYS = 180;
|
|
8
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
9
|
+
const day = z
|
|
10
|
+
.string()
|
|
11
|
+
.trim()
|
|
12
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, 'Use YYYY-MM-DD')
|
|
13
|
+
.refine((value) => !Number.isNaN(Date.parse(`${value}T00:00:00Z`)), 'Invalid date');
|
|
14
|
+
/** Days in `from`..`to`, both included */
|
|
15
|
+
const spanDays = ({ from, to }) => Math.round((Date.parse(`${to}T00:00:00Z`) - Date.parse(`${from}T00:00:00Z`)) / DAY_MS) + 1;
|
|
16
|
+
const period = (maxDays) => z
|
|
17
|
+
.object({ from: day, to: day })
|
|
18
|
+
.refine((value) => value.from <= value.to, { message: '`from` must not be after `to`', path: ['to'] })
|
|
19
|
+
.refine((value) => spanDays(value) <= maxDays, {
|
|
20
|
+
message: `The period can be at most ${maxDays} days`,
|
|
21
|
+
path: ['from'],
|
|
22
|
+
});
|
|
23
|
+
/** Body of `POST admin/analysis/snapshots/report`: one day when `from` equals `to` */
|
|
24
|
+
export const analysisReportSchema = period(ANALYSIS_REPORT_MAX_DAYS);
|
|
25
|
+
/** Body of `POST admin/analysis/snapshots/rebuild`: recalculates the snapshots of these days */
|
|
26
|
+
export const analysisRebuildSchema = period(ANALYSIS_REBUILD_MAX_DAYS);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './analysis-report.schema.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const offerStatusSchema = z.enum(["pending", "accepted", "countered", "declined"]);
|
|
3
|
+
// The seller's side can be 0 when the ad has no price; the backend requires a positive buyer price
|
|
4
|
+
const offerSideSchema = z.object({
|
|
5
|
+
offered_price: z.coerce.number().min(0),
|
|
6
|
+
currency_id: z.coerce.number().int().positive().optional(),
|
|
7
|
+
});
|
|
8
|
+
/** PRICE_OFFER payload. Replies (accept, counter, decline) point at the offer they answer. */
|
|
9
|
+
export const priceOfferPayloadSchema = z.object({
|
|
10
|
+
provider: offerSideSchema,
|
|
11
|
+
requester: offerSideSchema,
|
|
12
|
+
status: offerStatusSchema.optional(),
|
|
13
|
+
reply_to_message_id: z.coerce.number().int().positive().optional().nullable(),
|
|
14
|
+
/** Free text the sender added; the message text itself is a readable summary for older apps */
|
|
15
|
+
note: z.string().trim().max(1000).optional().nullable(),
|
|
16
|
+
});
|
|
17
|
+
/** RENT_OFFER payload: prices are per period, duration counts periods. */
|
|
18
|
+
export const rentOfferPayloadSchema = priceOfferPayloadSchema.extend({
|
|
19
|
+
price_type_id: z.coerce.number().int().positive(),
|
|
20
|
+
currency_id: z.coerce.number().int().positive(),
|
|
21
|
+
duration: z.coerce.number().int().min(1).max(1000),
|
|
22
|
+
start_date: z
|
|
23
|
+
.string()
|
|
24
|
+
.trim()
|
|
25
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
26
|
+
.optional()
|
|
27
|
+
.nullable(),
|
|
28
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { saveEventTimelineSchema } from "./EventTimeline.schema.js";
|
|
3
3
|
import { saveEventWeddingSchema } from "./EventWedding.schema.js";
|
|
4
|
-
import { EventInvitationScanTypeValues } from "../../constants/events/index.js";
|
|
4
|
+
import { EventInvitationScanTypeValues, EventPublishPaymentMethodValues, } from "../../constants/events/index.js";
|
|
5
5
|
export const eventBaseSchema = z.object({
|
|
6
6
|
lat: z.coerce.number().optional().nullable(),
|
|
7
7
|
long: z.coerce.number().optional().nullable(),
|
|
@@ -14,6 +14,8 @@ export const eventBaseSchema = z.object({
|
|
|
14
14
|
event_type: z.string().trim().max(255).nullable().optional(),
|
|
15
15
|
event_template: z.string().trim().max(255).nullable().optional(),
|
|
16
16
|
venue_id: z.coerce.number().int().positive().nullable().optional(),
|
|
17
|
+
venue_name: z.string().trim().max(255).nullable().optional(),
|
|
18
|
+
location_label: z.string().trim().nullable().optional(),
|
|
17
19
|
invitation_scan_type: z.enum(EventInvitationScanTypeValues).optional(),
|
|
18
20
|
});
|
|
19
21
|
export const createEventSchema = eventBaseSchema;
|
|
@@ -23,6 +25,14 @@ export const updateEventSchema = eventBaseSchema.extend({
|
|
|
23
25
|
export const saveEventSchema = eventBaseSchema.extend({
|
|
24
26
|
id: z.coerce.number().int().positive().optional(),
|
|
25
27
|
});
|
|
28
|
+
export const publishEventSchema = z.object({
|
|
29
|
+
id: z.coerce.number().int().positive(),
|
|
30
|
+
method: z.enum(EventPublishPaymentMethodValues),
|
|
31
|
+
points_used: z.coerce.number().int().nonnegative().optional(),
|
|
32
|
+
});
|
|
33
|
+
export const eventIdSchema = z.object({
|
|
34
|
+
id: z.coerce.number().int().positive(),
|
|
35
|
+
});
|
|
26
36
|
export const getEventsFilterSchema = z.object({
|
|
27
37
|
is_published: z.boolean().optional(),
|
|
28
38
|
search: z.string().trim().optional(),
|
package/dist/esm/schema/index.js
CHANGED
|
@@ -6,3 +6,4 @@ export * as PAYMENTS from './payments/index.js';
|
|
|
6
6
|
export * as COMMUNICATION from './communication/index.js';
|
|
7
7
|
export * as ADDRESSES from './addresses/addresses.schema.js';
|
|
8
8
|
export * as POTENTIAL_USERS from './potential-users/index.js';
|
|
9
|
+
export * as ANALYSIS from './analysis/index.js';
|
|
@@ -3,5 +3,14 @@ export var MessageTypeEnum;
|
|
|
3
3
|
MessageTypeEnum[MessageTypeEnum["TEXT"] = 1] = "TEXT";
|
|
4
4
|
MessageTypeEnum[MessageTypeEnum["PRICE_OFFER"] = 2] = "PRICE_OFFER";
|
|
5
5
|
MessageTypeEnum[MessageTypeEnum["CONTACT_INVITATION"] = 3] = "CONTACT_INVITATION";
|
|
6
|
+
MessageTypeEnum[MessageTypeEnum["RENT_OFFER"] = 4] = "RENT_OFFER";
|
|
6
7
|
})(MessageTypeEnum || (MessageTypeEnum = {}));
|
|
8
|
+
/** Lifecycle of a price or rent offer. A reply is a new message pointing at the offer it answers. */
|
|
9
|
+
export var OfferStatusEnum;
|
|
10
|
+
(function (OfferStatusEnum) {
|
|
11
|
+
OfferStatusEnum["PENDING"] = "pending";
|
|
12
|
+
OfferStatusEnum["ACCEPTED"] = "accepted";
|
|
13
|
+
OfferStatusEnum["COUNTERED"] = "countered";
|
|
14
|
+
OfferStatusEnum["DECLINED"] = "declined";
|
|
15
|
+
})(OfferStatusEnum || (OfferStatusEnum = {}));
|
|
7
16
|
export { MessageTypeEnum as MessageTypeType };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Engagement of a day: WhatsApp, call and chat clicks, shares, chat messages and new chat rooms */
|
|
2
|
+
export const analysisEngagementTotal = ({ ad_interactions: a, app_metrics: m }) => {
|
|
3
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4
|
+
return ((_a = a === null || a === void 0 ? void 0 : a.whatsapp_clicks) !== null && _a !== void 0 ? _a : 0) +
|
|
5
|
+
((_b = a === null || a === void 0 ? void 0 : a.call_clicks) !== null && _b !== void 0 ? _b : 0) +
|
|
6
|
+
((_c = a === null || a === void 0 ? void 0 : a.chat_clicks) !== null && _c !== void 0 ? _c : 0) +
|
|
7
|
+
((_d = a === null || a === void 0 ? void 0 : a.shares) !== null && _d !== void 0 ? _d : 0) +
|
|
8
|
+
((_e = m === null || m === void 0 ? void 0 : m.chat_messages_count) !== null && _e !== void 0 ? _e : 0) +
|
|
9
|
+
((_f = m === null || m === void 0 ? void 0 : m.chat_rooms_count) !== null && _f !== void 0 ? _f : 0);
|
|
10
|
+
};
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** The rent price shown on cards: the one marked main, else the first listed. */
|
|
2
|
+
export const getMainRentPrice = (ad) => {
|
|
3
|
+
var _a, _b, _c;
|
|
4
|
+
const prices = (_a = ad === null || ad === void 0 ? void 0 : ad.rent_prices) !== null && _a !== void 0 ? _a : [];
|
|
5
|
+
return (_c = (_b = prices.find((item) => item.is_main)) !== null && _b !== void 0 ? _b : prices[0]) !== null && _c !== void 0 ? _c : null;
|
|
6
|
+
};
|
|
7
|
+
/** The price to show for an ad in a list: the filtered period, else the main rent price. */
|
|
8
|
+
export const getDisplayRentPrice = (ad, priceTypeId) => {
|
|
9
|
+
var _a;
|
|
10
|
+
if (ad === null || ad === void 0 ? void 0 : ad.matched_rent_price)
|
|
11
|
+
return ad.matched_rent_price;
|
|
12
|
+
if (priceTypeId) {
|
|
13
|
+
const match = (_a = ad === null || ad === void 0 ? void 0 : ad.rent_prices) === null || _a === void 0 ? void 0 : _a.find((item) => item.price_type_id === Number(priceTypeId));
|
|
14
|
+
if (match)
|
|
15
|
+
return match;
|
|
16
|
+
}
|
|
17
|
+
return getMainRentPrice(ad);
|
|
18
|
+
};
|
|
19
|
+
/** Rent prices ordered from the shortest period to the longest. */
|
|
20
|
+
export const sortRentPrices = (prices) => [...(prices !== null && prices !== void 0 ? prices : [])].sort((a, b) => {
|
|
21
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
22
|
+
return ((_b = (_a = a.price_type) === null || _a === void 0 ? void 0 : _a.period_days) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER) -
|
|
23
|
+
((_d = (_c = b.price_type) === null || _c === void 0 ? void 0 : _c.period_days) !== null && _d !== void 0 ? _d : Number.MAX_SAFE_INTEGER) ||
|
|
24
|
+
((_f = (_e = a.price_type) === null || _e === void 0 ? void 0 : _e.display_order) !== null && _f !== void 0 ? _f : 0) - ((_h = (_g = b.price_type) === null || _g === void 0 ? void 0 : _g.display_order) !== null && _h !== void 0 ? _h : 0);
|
|
25
|
+
});
|
|
26
|
+
export const rentOfferTotal = (pricePerPeriod, duration) => Math.max(0, Number(pricePerPeriod) || 0) * Math.max(0, Math.floor(Number(duration) || 0));
|
package/package.json
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@deallony/shared",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"private": false,
|
|
5
|
-
"main": "dist/cjs/index.js",
|
|
6
|
-
"module": "dist/esm/index.js",
|
|
7
|
-
"react-native": "dist/esm/index.js",
|
|
8
|
-
"types": "dist/cjs/index.d.ts",
|
|
9
|
-
"sideEffects": false,
|
|
10
|
-
"exports": {
|
|
11
|
-
".": {
|
|
12
|
-
"require": "./dist/cjs/index.js",
|
|
13
|
-
"import": "./dist/esm/index.js",
|
|
14
|
-
"types": "./dist/cjs/index.d.ts"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"dist"
|
|
19
|
-
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"deploy": "node ./scripts/publish.js npm patch",
|
|
22
|
-
"=========": "============= UPDATE APPS LIBRARY =============",
|
|
23
|
-
"all:update": "npm run mobile:update && npm run backend:update && npm run dashboard:update && npm run whatsapp:update && npm run collect:update",
|
|
24
|
-
"mobile:update": "cd ../app && npm run upgrade:deallony:shared",
|
|
25
|
-
"backend:update": "cd ../backend-service-marketplace && pnpm run upgrade:deallony:shared",
|
|
26
|
-
"dashboard:update": "cd ../frontend-react-aloo && pnpm run upgrade:deallony:shared",
|
|
27
|
-
"whatsapp:update": "cd ../backend-nest-whatsapp-service-aloo && pnpm run upgrade:deallony:shared",
|
|
28
|
-
"collect:update": "cd ../qatayef-collect/backend && npm run upgrade:deallony:shared",
|
|
29
|
-
"current": "node -p \"require('./package.json').version\"",
|
|
30
|
-
"============================= Links with project =============================": "",
|
|
31
|
-
"link:backend": "cd ../backend-service-marketplace && pnpm add @deallony/shared@file:../shared-deallony",
|
|
32
|
-
"link:dashboard": "cd ../frontend-react-aloo && pnpm add @deallony/shared@file:../shared-deallony",
|
|
33
|
-
"link:mobile": "cd ../app && npm install ../shared-deallony",
|
|
34
|
-
"========": "============ DEFAULT ============",
|
|
35
|
-
"build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && node ./scripts/fix-esm-imports.mjs",
|
|
36
|
-
"watch": "tsc -p tsconfig.cjs.json --watch",
|
|
37
|
-
"deploy:patch": "node ./scripts/publish.js npm patch",
|
|
38
|
-
"deploy:minor": "node ./scripts/publish.js npm minor",
|
|
39
|
-
"deploy:major": "node ./scripts/publish.js npm major",
|
|
40
|
-
"deploy:dry-run": "node ./scripts/publish.js npm patch --dry-run",
|
|
41
|
-
"deploy:git": "node ./scripts/publish.js git patch",
|
|
42
|
-
"deploy:git:minor": "node ./scripts/publish.js git minor",
|
|
43
|
-
"deploy:git:major": "node ./scripts/publish.js git major",
|
|
44
|
-
"deploy:git:dry-run": "node ./scripts/publish.js git patch --dry-run",
|
|
45
|
-
"prepublishOnly": "npm run build"
|
|
46
|
-
},
|
|
47
|
-
"dependencies": {
|
|
48
|
-
"zod": "^4.2.1"
|
|
49
|
-
},
|
|
50
|
-
"devDependencies": {
|
|
51
|
-
"@types/node": "^25.0.3",
|
|
52
|
-
"typescript": "^5.9.3"
|
|
53
|
-
},
|
|
54
|
-
"publishConfig": {
|
|
55
|
-
"registry": "https://registry.npmjs.org/",
|
|
56
|
-
"access": "public"
|
|
57
|
-
}
|
|
58
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@deallony/shared",
|
|
3
|
+
"version": "1.2.69",
|
|
4
|
+
"private": false,
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"react-native": "dist/esm/index.js",
|
|
8
|
+
"types": "dist/cjs/index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"require": "./dist/cjs/index.js",
|
|
13
|
+
"import": "./dist/esm/index.js",
|
|
14
|
+
"types": "./dist/cjs/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"deploy": "node ./scripts/publish.js npm patch",
|
|
22
|
+
"=========": "============= UPDATE APPS LIBRARY =============",
|
|
23
|
+
"all:update": "npm run mobile:update && npm run backend:update && npm run dashboard:update && npm run whatsapp:update && npm run collect:update",
|
|
24
|
+
"mobile:update": "cd ../app && npm run upgrade:deallony:shared",
|
|
25
|
+
"backend:update": "cd ../backend-service-marketplace && pnpm run upgrade:deallony:shared",
|
|
26
|
+
"dashboard:update": "cd ../frontend-react-aloo && pnpm run upgrade:deallony:shared",
|
|
27
|
+
"whatsapp:update": "cd ../backend-nest-whatsapp-service-aloo && pnpm run upgrade:deallony:shared",
|
|
28
|
+
"collect:update": "cd ../qatayef-collect/backend && npm run upgrade:deallony:shared",
|
|
29
|
+
"current": "node -p \"require('./package.json').version\"",
|
|
30
|
+
"============================= Links with project =============================": "",
|
|
31
|
+
"link:backend": "cd ../backend-service-marketplace && pnpm add @deallony/shared@file:../shared-deallony",
|
|
32
|
+
"link:dashboard": "cd ../frontend-react-aloo && pnpm add @deallony/shared@file:../shared-deallony",
|
|
33
|
+
"link:mobile": "cd ../app && npm install ../shared-deallony",
|
|
34
|
+
"========": "============ DEFAULT ============",
|
|
35
|
+
"build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && node ./scripts/fix-esm-imports.mjs",
|
|
36
|
+
"watch": "tsc -p tsconfig.cjs.json --watch",
|
|
37
|
+
"deploy:patch": "node ./scripts/publish.js npm patch",
|
|
38
|
+
"deploy:minor": "node ./scripts/publish.js npm minor",
|
|
39
|
+
"deploy:major": "node ./scripts/publish.js npm major",
|
|
40
|
+
"deploy:dry-run": "node ./scripts/publish.js npm patch --dry-run",
|
|
41
|
+
"deploy:git": "node ./scripts/publish.js git patch",
|
|
42
|
+
"deploy:git:minor": "node ./scripts/publish.js git minor",
|
|
43
|
+
"deploy:git:major": "node ./scripts/publish.js git major",
|
|
44
|
+
"deploy:git:dry-run": "node ./scripts/publish.js git patch --dry-run",
|
|
45
|
+
"prepublishOnly": "npm run build"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"zod": "^4.2.1"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^25.0.3",
|
|
52
|
+
"typescript": "^5.9.3"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"registry": "https://registry.npmjs.org/",
|
|
56
|
+
"access": "public"
|
|
57
|
+
}
|
|
58
|
+
}
|