whitelabel-db 1.1.96 → 1.1.98

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 (73) hide show
  1. package/dist/index.d.ts +12 -1
  2. package/dist/index.js +27 -1
  3. package/dist/libs/database.d.ts +1 -1
  4. package/dist/libs/database.js +41 -7
  5. package/dist/libs/liteapiv3.d.ts +17 -5
  6. package/dist/libs/liteapiv3.js +52 -3
  7. package/dist/libs/migration-utils.d.ts +16 -0
  8. package/dist/libs/migration-utils.js +78 -0
  9. package/dist/libs/migration.js +27 -3
  10. package/dist/migrations/010-add-user-resetToken.d.ts +3 -0
  11. package/dist/migrations/010-add-user-resetToken.js +61 -0
  12. package/dist/migrations/011-add-project-resceotToke.d.ts +3 -0
  13. package/dist/migrations/011-add-project-resceotToke.js +47 -0
  14. package/dist/migrations/012-add-otp-expire.d.ts +3 -0
  15. package/dist/migrations/012-add-otp-expire.js +63 -0
  16. package/dist/migrations/013-add-bookings-payment.d.ts +3 -0
  17. package/dist/migrations/013-add-bookings-payment.js +57 -0
  18. package/dist/migrations/014-add-hotel-placeid.d.ts +3 -0
  19. package/dist/migrations/014-add-hotel-placeid.js +43 -0
  20. package/dist/migrations/015-create-facilities-tables.d.ts +3 -0
  21. package/dist/migrations/015-create-facilities-tables.js +119 -0
  22. package/dist/migrations/016-create-amenities-tables.d.ts +3 -0
  23. package/dist/migrations/016-create-amenities-tables.js +119 -0
  24. package/dist/migrations/017-add-upsert-indexes-amenities-facilities.d.ts +3 -0
  25. package/dist/migrations/017-add-upsert-indexes-amenities-facilities.js +56 -0
  26. package/dist/migrations/018-link-room-amenities-to-hotels.d.ts +3 -0
  27. package/dist/migrations/018-link-room-amenities-to-hotels.js +83 -0
  28. package/dist/migrations/019-add-marketsegment-project.d.ts +3 -0
  29. package/dist/migrations/019-add-marketsegment-project.js +45 -0
  30. package/dist/migrations/020-booking-source.d.ts +3 -0
  31. package/dist/migrations/020-booking-source.js +56 -0
  32. package/dist/migrations/021-add-analytics-indexes.d.ts +3 -0
  33. package/dist/migrations/021-add-analytics-indexes.js +91 -0
  34. package/dist/migrations/022-add-project-isactive.d.ts +3 -0
  35. package/dist/migrations/022-add-project-isactive.js +47 -0
  36. package/dist/migrations/023-add-anonymous-user-support.d.ts +3 -0
  37. package/dist/migrations/023-add-anonymous-user-support.js +165 -0
  38. package/dist/migrations/024-add-unique-slug-index-collections.d.ts +3 -0
  39. package/dist/migrations/024-add-unique-slug-index-collections.js +107 -0
  40. package/dist/models/Amenity.d.ts +9 -0
  41. package/dist/models/Amenity.js +47 -0
  42. package/dist/models/AmenityTranslation.d.ts +8 -0
  43. package/dist/models/AmenityTranslation.js +52 -0
  44. package/dist/models/AnalyticsSummary.d.ts +13 -0
  45. package/dist/models/AnalyticsSummary.js +122 -0
  46. package/dist/models/Booking.d.ts +6 -0
  47. package/dist/models/Booking.js +42 -0
  48. package/dist/models/Collection.d.ts +29 -0
  49. package/dist/models/Collection.js +233 -0
  50. package/dist/models/CollectionItem.d.ts +18 -0
  51. package/dist/models/CollectionItem.js +84 -0
  52. package/dist/models/CollectionItemCustomField.d.ts +10 -0
  53. package/dist/models/CollectionItemCustomField.js +67 -0
  54. package/dist/models/Creator.d.ts +12 -0
  55. package/dist/models/Creator.js +82 -0
  56. package/dist/models/Facility.d.ts +11 -0
  57. package/dist/models/{Search.js → Facility.js} +24 -33
  58. package/dist/models/FacilityTranslation.d.ts +8 -0
  59. package/dist/models/FacilityTranslation.js +52 -0
  60. package/dist/models/Guest.d.ts +12 -0
  61. package/dist/models/Guest.js +74 -3
  62. package/dist/models/Hotel.d.ts +7 -0
  63. package/dist/models/Hotel.js +23 -0
  64. package/dist/models/HotelFacility.d.ts +9 -0
  65. package/dist/models/HotelFacility.js +49 -0
  66. package/dist/models/Project.d.ts +7 -0
  67. package/dist/models/Project.js +33 -0
  68. package/dist/models/RoomAmenity.d.ts +11 -0
  69. package/dist/models/RoomAmenity.js +64 -0
  70. package/dist/models/User.d.ts +3 -0
  71. package/dist/models/User.js +21 -0
  72. package/package.json +1 -1
  73. package/dist/models/Search.d.ts +0 -8
package/dist/index.d.ts CHANGED
@@ -14,6 +14,17 @@ export { HotelAccessibility } from './models/HotelAccessibility';
14
14
  export { Referral } from './models/Referral';
15
15
  export { Feedback } from './models/Feedback';
16
16
  export { HotelRate } from './models/HotelRate';
17
+ export { AnalyticsSummary } from './models/AnalyticsSummary';
18
+ export { Facility } from './models/Facility';
19
+ export { HotelFacility } from './models/HotelFacility';
20
+ export { FacilityTranslation } from './models/FacilityTranslation';
21
+ export { Amenity } from './models/Amenity';
22
+ export { RoomAmenity } from './models/RoomAmenity';
23
+ export { AmenityTranslation } from './models/AmenityTranslation';
24
+ export { Creator } from './models/Creator';
25
+ export { Collection, CollectionStatus } from './models/Collection';
26
+ export { CollectionItem, CollectionType } from './models/CollectionItem';
27
+ export { CollectionItemCustomField } from './models/CollectionItemCustomField';
17
28
  export { LiteApiClient, HotelsRequest, AvailabilityResult, FullRateAvailabilityResult, RoomType, Rate, PrebookRateRequest, PrebookRate, CheckoutRequest, BookingInfo, CancelBooking, } from './libs/liteapi';
18
- export { LiteApiClientV3, HotelsRequestV3, AvailabilityResultV3, FullRateAvailabilityResultV3, RoomTypeV3, RateV3, PrebookRateRequestV3, PrebookRateV3, CheckoutRequestV3, BookingInfoV3, CancelBookingV3, BookedRoomV3, OccupancyV3, GuestV3, GuestBookingV3, VoucherRequest, VoucherResponse, EsimplyPackage, Addon, AddonResponse, } from './libs/liteapiv3';
29
+ export { LiteApiClientV3, HotelsRequestV3, AvailabilityResultV3, FullRateAvailabilityResultV3, RoomTypeV3, RateV3, PrebookRateRequestV3, PrebookRateV3, CheckoutRequestV3, BookingInfoV3, CancelBookingV3, BookedRoomV3, OccupancyV3, GuestV3, GuestBookingV3, PromoCodeRequest, PromoCodeResponse, EsimplyPackage, Addon, AddonResponse, } from './libs/liteapiv3';
19
30
  export { LiteApiUser, LiteApiUserRequest } from './libs/liteapiuser';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LiteApiUser = exports.LiteApiClientV3 = exports.LiteApiClient = exports.HotelRate = exports.Feedback = exports.Referral = exports.HotelAccessibility = exports.Guest = exports.HotelTranslation = exports.Role = exports.Booking = exports.Project = exports.User = exports.Hotel = exports.Country = exports.City = exports.Agency = exports.runMigrations = exports.connect = void 0;
3
+ exports.LiteApiUser = exports.LiteApiClientV3 = exports.LiteApiClient = exports.CollectionItemCustomField = exports.CollectionType = exports.CollectionItem = exports.CollectionStatus = exports.Collection = exports.Creator = exports.AmenityTranslation = exports.RoomAmenity = exports.Amenity = exports.FacilityTranslation = exports.HotelFacility = exports.Facility = exports.AnalyticsSummary = exports.HotelRate = exports.Feedback = exports.Referral = exports.HotelAccessibility = exports.Guest = exports.HotelTranslation = exports.Role = exports.Booking = exports.Project = exports.User = exports.Hotel = exports.Country = exports.City = exports.Agency = exports.runMigrations = exports.connect = void 0;
4
4
  var database_1 = require("./libs/database");
5
5
  Object.defineProperty(exports, "connect", { enumerable: true, get: function () { return database_1.connect; } });
6
6
  var migration_1 = require("./libs/migration");
@@ -33,6 +33,32 @@ var Feedback_1 = require("./models/Feedback");
33
33
  Object.defineProperty(exports, "Feedback", { enumerable: true, get: function () { return Feedback_1.Feedback; } });
34
34
  var HotelRate_1 = require("./models/HotelRate");
35
35
  Object.defineProperty(exports, "HotelRate", { enumerable: true, get: function () { return HotelRate_1.HotelRate; } });
36
+ var AnalyticsSummary_1 = require("./models/AnalyticsSummary");
37
+ Object.defineProperty(exports, "AnalyticsSummary", { enumerable: true, get: function () { return AnalyticsSummary_1.AnalyticsSummary; } });
38
+ // New normalized models
39
+ var Facility_1 = require("./models/Facility");
40
+ Object.defineProperty(exports, "Facility", { enumerable: true, get: function () { return Facility_1.Facility; } });
41
+ var HotelFacility_1 = require("./models/HotelFacility");
42
+ Object.defineProperty(exports, "HotelFacility", { enumerable: true, get: function () { return HotelFacility_1.HotelFacility; } });
43
+ var FacilityTranslation_1 = require("./models/FacilityTranslation");
44
+ Object.defineProperty(exports, "FacilityTranslation", { enumerable: true, get: function () { return FacilityTranslation_1.FacilityTranslation; } });
45
+ var Amenity_1 = require("./models/Amenity");
46
+ Object.defineProperty(exports, "Amenity", { enumerable: true, get: function () { return Amenity_1.Amenity; } });
47
+ var RoomAmenity_1 = require("./models/RoomAmenity");
48
+ Object.defineProperty(exports, "RoomAmenity", { enumerable: true, get: function () { return RoomAmenity_1.RoomAmenity; } });
49
+ var AmenityTranslation_1 = require("./models/AmenityTranslation");
50
+ Object.defineProperty(exports, "AmenityTranslation", { enumerable: true, get: function () { return AmenityTranslation_1.AmenityTranslation; } });
51
+ // Collection and Creator models
52
+ var Creator_1 = require("./models/Creator");
53
+ Object.defineProperty(exports, "Creator", { enumerable: true, get: function () { return Creator_1.Creator; } });
54
+ var Collection_1 = require("./models/Collection");
55
+ Object.defineProperty(exports, "Collection", { enumerable: true, get: function () { return Collection_1.Collection; } });
56
+ Object.defineProperty(exports, "CollectionStatus", { enumerable: true, get: function () { return Collection_1.CollectionStatus; } });
57
+ var CollectionItem_1 = require("./models/CollectionItem");
58
+ Object.defineProperty(exports, "CollectionItem", { enumerable: true, get: function () { return CollectionItem_1.CollectionItem; } });
59
+ Object.defineProperty(exports, "CollectionType", { enumerable: true, get: function () { return CollectionItem_1.CollectionType; } });
60
+ var CollectionItemCustomField_1 = require("./models/CollectionItemCustomField");
61
+ Object.defineProperty(exports, "CollectionItemCustomField", { enumerable: true, get: function () { return CollectionItemCustomField_1.CollectionItemCustomField; } });
36
62
  var liteapi_1 = require("./libs/liteapi");
37
63
  Object.defineProperty(exports, "LiteApiClient", { enumerable: true, get: function () { return liteapi_1.LiteApiClient; } });
38
64
  var liteapiv3_1 = require("./libs/liteapiv3");
@@ -5,4 +5,4 @@ export interface ConnectionDetails {
5
5
  password: string;
6
6
  dbname: string;
7
7
  }
8
- export declare const connect: (connectionDetails: ConnectionDetails) => Promise<void | Sequelize>;
8
+ export declare const connect: (connectionDetails: ConnectionDetails) => Promise<Sequelize>;
@@ -25,6 +25,18 @@ const HotelAccessibility_1 = require("../models/HotelAccessibility");
25
25
  const Referral_1 = require("../models/Referral");
26
26
  const Feedback_1 = require("../models/Feedback");
27
27
  const HotelRate_1 = require("../models/HotelRate");
28
+ const Facility_1 = require("../models/Facility");
29
+ const HotelFacility_1 = require("../models/HotelFacility");
30
+ const FacilityTranslation_1 = require("../models/FacilityTranslation");
31
+ const Amenity_1 = require("../models/Amenity");
32
+ const RoomAmenity_1 = require("../models/RoomAmenity");
33
+ const AmenityTranslation_1 = require("../models/AmenityTranslation");
34
+ const AnalyticsSummary_1 = require("../models/AnalyticsSummary");
35
+ const Creator_1 = require("../models/Creator");
36
+ const Collection_1 = require("../models/Collection");
37
+ const CollectionItem_1 = require("../models/CollectionItem");
38
+ const CollectionItemCustomField_1 = require("../models/CollectionItemCustomField");
39
+ const migration_1 = require("./migration");
28
40
  const connect = (connectionDetails) => __awaiter(void 0, void 0, void 0, function* () {
29
41
  const connection = new sequelize_typescript_1.Sequelize({
30
42
  dialect: 'postgres',
@@ -48,16 +60,38 @@ const connect = (connectionDetails) => __awaiter(void 0, void 0, void 0, functio
48
60
  Referral_1.Referral,
49
61
  Feedback_1.Feedback,
50
62
  HotelRate_1.HotelRate,
63
+ Facility_1.Facility,
64
+ HotelFacility_1.HotelFacility,
65
+ FacilityTranslation_1.FacilityTranslation,
66
+ Amenity_1.Amenity,
67
+ RoomAmenity_1.RoomAmenity,
68
+ AmenityTranslation_1.AmenityTranslation,
69
+ AnalyticsSummary_1.AnalyticsSummary,
70
+ Creator_1.Creator,
71
+ Collection_1.Collection,
72
+ CollectionItem_1.CollectionItem,
73
+ CollectionItemCustomField_1.CollectionItemCustomField,
51
74
  ],
52
75
  });
53
- return connection
54
- .authenticate()
55
- .then(() => {
76
+ try {
77
+ yield connection.authenticate();
56
78
  console.log('Database connection has been established successfully.');
57
- return connection.sync();
58
- })
59
- .catch((err) => {
79
+ try {
80
+ console.log('Running migrations');
81
+ yield (0, migration_1.runMigrations)(connection);
82
+ }
83
+ catch (migrationError) {
84
+ console.error('Error running migrations:', migrationError);
85
+ }
86
+ // Only create tables that don't exist, don't alter existing schema
87
+ // This prevents conflicts with migrations
88
+ yield connection.sync({ force: false, alter: false });
89
+ console.log('Database sync completed successfully.');
90
+ return connection;
91
+ }
92
+ catch (err) {
60
93
  console.error('Unable to connect to the database:', err);
61
- });
94
+ throw err;
95
+ }
62
96
  });
63
97
  exports.connect = connect;
@@ -109,6 +109,8 @@ export interface PrebookRateRequestV3 {
109
109
  usePaymentSdk?: boolean;
110
110
  payment: {
111
111
  descriptorSuffix?: string;
112
+ gateway?: string;
113
+ useOwnSecretKey?: boolean;
112
114
  };
113
115
  trackingId?: string;
114
116
  voucherCode?: string;
@@ -154,6 +156,12 @@ export interface PrebookRateV3 {
154
156
  checkin: string;
155
157
  checkout: string;
156
158
  paymentTypes: string[];
159
+ creditLine: {
160
+ remainingCredit: number;
161
+ currency: string;
162
+ };
163
+ secretKey?: string;
164
+ publishableKey?: string;
157
165
  }
158
166
  export interface GuestInfoV3 {
159
167
  guestFirstName: string;
@@ -314,7 +322,7 @@ export interface GuestBookingV3 {
314
322
  updatedAt: string;
315
323
  deletedAt: string;
316
324
  }
317
- export interface VoucherResponse {
325
+ export interface PromoCodeResponse {
318
326
  id: number;
319
327
  voucher_code: string;
320
328
  discount_type: string;
@@ -333,7 +341,7 @@ export interface VoucherResponse {
333
341
  terms_and_conditions: string | null;
334
342
  category?: string;
335
343
  }
336
- export interface VoucherRequest {
344
+ export interface PromoCodeRequest {
337
345
  voucher_code: string;
338
346
  discount_type: string;
339
347
  discount_value: number;
@@ -376,8 +384,12 @@ export declare class LiteApiClientV3 {
376
384
  getGuests(): Promise<GuestV3[]>;
377
385
  getGuest(guestId: number): Promise<GuestV3>;
378
386
  getGuestBookings(guestId: number): Promise<GuestBookingV3[]>;
379
- createVoucher(data: VoucherRequest): Promise<VoucherResponse>;
380
- getVouchers(): Promise<VoucherResponse[]>;
387
+ createPromoCode(data: PromoCodeRequest): Promise<PromoCodeResponse>;
388
+ getPromoCodes(): Promise<PromoCodeResponse[]>;
389
+ updatePromoCode(data: PromoCodeRequest, promoCodeId: number): Promise<string>;
390
+ getPromoCode(promoCodeId: number): Promise<PromoCodeResponse>;
391
+ updatePromoCodeStatus(promoCodeId: number, status: 'active' | 'inactive'): Promise<string>;
392
+ deletePromoCode(promoCodeId: number): Promise<string>;
381
393
  getEsimplyPackages(options: {
382
394
  countryCode: string;
383
395
  }): Promise<EsimplyPackage[]>;
@@ -389,5 +401,5 @@ export declare class LiteApiClientV3 {
389
401
  points: number;
390
402
  currency: string;
391
403
  guestId: number;
392
- }): Promise<VoucherResponse>;
404
+ }): Promise<PromoCodeResponse>;
393
405
  }
@@ -84,7 +84,7 @@ class LiteApiClientV3 {
84
84
  return __awaiter(this, void 0, void 0, function* () {
85
85
  return (yield (0, axios_1.default)({
86
86
  method: 'post',
87
- url: `${this.bookingBaseUrl}/v3.0/rates/prebook`,
87
+ url: `${this.bookingBaseUrl}/v3.0/rates/prebook?includeCreditBalance=true`,
88
88
  data: options,
89
89
  headers: {
90
90
  'X-API-Key': this.apiKey,
@@ -160,7 +160,8 @@ class LiteApiClientV3 {
160
160
  })).data.data;
161
161
  });
162
162
  }
163
- createVoucher(data) {
163
+ // VOUCHERS STARTS HERE
164
+ createPromoCode(data) {
164
165
  return __awaiter(this, void 0, void 0, function* () {
165
166
  return (yield (0, axios_1.default)({
166
167
  method: 'post',
@@ -173,7 +174,7 @@ class LiteApiClientV3 {
173
174
  })).data.voucher;
174
175
  });
175
176
  }
176
- getVouchers() {
177
+ getPromoCodes() {
177
178
  return __awaiter(this, void 0, void 0, function* () {
178
179
  return (yield (0, axios_1.default)({
179
180
  url: `${this.voucherBaseUrl}/vouchers`,
@@ -183,6 +184,54 @@ class LiteApiClientV3 {
183
184
  })).data.vouchers;
184
185
  });
185
186
  }
187
+ updatePromoCode(data, promoCodeId) {
188
+ return __awaiter(this, void 0, void 0, function* () {
189
+ return (yield (0, axios_1.default)({
190
+ method: 'put',
191
+ url: `${this.voucherBaseUrl}/vouchers/${promoCodeId}`,
192
+ data,
193
+ headers: {
194
+ 'X-API-Key': this.apiKey,
195
+ 'content-type': 'application/json',
196
+ },
197
+ })).data.message;
198
+ });
199
+ }
200
+ getPromoCode(promoCodeId) {
201
+ return __awaiter(this, void 0, void 0, function* () {
202
+ return (yield (0, axios_1.default)({
203
+ url: `${this.voucherBaseUrl}/vouchers/${promoCodeId}`,
204
+ headers: {
205
+ 'X-API-Key': this.apiKey,
206
+ },
207
+ })).data.voucher;
208
+ });
209
+ }
210
+ updatePromoCodeStatus(promoCodeId, status) {
211
+ return __awaiter(this, void 0, void 0, function* () {
212
+ return (yield (0, axios_1.default)({
213
+ method: 'put',
214
+ url: `${this.voucherBaseUrl}/vouchers/${promoCodeId}/status`,
215
+ data: { status },
216
+ headers: {
217
+ 'X-API-Key': this.apiKey,
218
+ 'content-type': 'application/json',
219
+ },
220
+ })).data.message;
221
+ });
222
+ }
223
+ deletePromoCode(promoCodeId) {
224
+ return __awaiter(this, void 0, void 0, function* () {
225
+ return (yield (0, axios_1.default)({
226
+ method: 'delete',
227
+ url: `${this.voucherBaseUrl}/vouchers/${promoCodeId}`,
228
+ headers: {
229
+ 'X-API-Key': this.apiKey,
230
+ },
231
+ })).data.message;
232
+ });
233
+ }
234
+ // VOUCHERS ENDS HERE
186
235
  getEsimplyPackages(options) {
187
236
  return __awaiter(this, void 0, void 0, function* () {
188
237
  return (yield (0, axios_1.default)({
@@ -0,0 +1,16 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ /**
3
+ * Safely adds a column to a table, checking if it already exists first
4
+ */
5
+ export declare function safeAddColumn(queryInterface: QueryInterface, tableName: string, columnName: string, columnDefinition: any): Promise<void>;
6
+ /**
7
+ * Safely adds multiple columns to a table
8
+ */
9
+ export declare function safeAddColumns(queryInterface: QueryInterface, tableName: string, columns: Array<{
10
+ name: string;
11
+ definition: any;
12
+ }>): Promise<void>;
13
+ /**
14
+ * Safely adds an index to a table, handling if it already exists
15
+ */
16
+ export declare function safeAddIndex(queryInterface: QueryInterface, tableName: string, indexName: string, columns: string[], options?: any): Promise<void>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.safeAddIndex = exports.safeAddColumns = exports.safeAddColumn = void 0;
13
+ /**
14
+ * Safely adds a column to a table, checking if it already exists first
15
+ */
16
+ function safeAddColumn(queryInterface, tableName, columnName, columnDefinition) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ try {
19
+ const tableDescription = yield queryInterface.describeTable(tableName);
20
+ const existingColumns = Object.keys(tableDescription);
21
+ if (existingColumns.includes(columnName)) {
22
+ console.log(`${columnName} column already exists in ${tableName}, skipping.`);
23
+ return;
24
+ }
25
+ yield queryInterface.addColumn(tableName, columnName, columnDefinition);
26
+ console.log(`${columnName} column added to ${tableName} successfully.`);
27
+ }
28
+ catch (error) {
29
+ console.error(`Error adding ${columnName} column to ${tableName}:`, error.message);
30
+ throw error;
31
+ }
32
+ });
33
+ }
34
+ exports.safeAddColumn = safeAddColumn;
35
+ /**
36
+ * Safely adds multiple columns to a table
37
+ */
38
+ function safeAddColumns(queryInterface, tableName, columns) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ try {
41
+ const tableDescription = yield queryInterface.describeTable(tableName);
42
+ const existingColumns = Object.keys(tableDescription);
43
+ const columnsToAdd = columns.filter((column) => !existingColumns.includes(column.name));
44
+ if (columnsToAdd.length === 0) {
45
+ console.log(`All columns already exist in ${tableName}, skipping migration.`);
46
+ return;
47
+ }
48
+ yield Promise.all(columnsToAdd.map((column) => queryInterface.addColumn(tableName, column.name, column.definition)));
49
+ console.log(`Added ${columnsToAdd.length} columns to ${tableName} successfully.`);
50
+ }
51
+ catch (error) {
52
+ console.error(`Error adding columns to ${tableName}:`, error.message);
53
+ throw error;
54
+ }
55
+ });
56
+ }
57
+ exports.safeAddColumns = safeAddColumns;
58
+ /**
59
+ * Safely adds an index to a table, handling if it already exists
60
+ */
61
+ function safeAddIndex(queryInterface, tableName, indexName, columns, options = {}) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ try {
64
+ yield queryInterface.addIndex(tableName, columns, Object.assign({ name: indexName }, options));
65
+ console.log(`Index ${indexName} added to ${tableName} successfully.`);
66
+ }
67
+ catch (error) {
68
+ if (error.message.includes('already exists')) {
69
+ console.log(`Index ${indexName} already exists on ${tableName}, skipping.`);
70
+ }
71
+ else {
72
+ console.error(`Error adding index ${indexName} to ${tableName}:`, error.message);
73
+ throw error;
74
+ }
75
+ }
76
+ });
77
+ }
78
+ exports.safeAddIndex = safeAddIndex;
@@ -44,14 +44,37 @@ const runMigrations = (sequelize) => __awaiter(void 0, void 0, void 0, function*
44
44
  console.error(`Migrations directory not found at: ${migrationsPath}`);
45
45
  return;
46
46
  }
47
+ // Ensure SequelizeMeta table exists - this handles cases where sync() didn't create it
48
+ try {
49
+ yield sequelize.query(`
50
+ CREATE TABLE IF NOT EXISTS "SequelizeMeta" (
51
+ "name" VARCHAR(255) NOT NULL,
52
+ PRIMARY KEY ("name")
53
+ );
54
+ `);
55
+ console.log('SequelizeMeta table ensured to exist');
56
+ }
57
+ catch (error) {
58
+ console.error('Error creating SequelizeMeta table:', error);
59
+ throw error;
60
+ }
47
61
  // Read and sort migration files
48
62
  const migrationFiles = fs_1.default
49
63
  .readdirSync(migrationsPath)
50
64
  .filter((file) => file.match(/^\d{3}-.+\.ts$/) || file.match(/^\d{3}-.+\.js$/)) // Matches .ts and .js files
51
65
  .filter((file) => !file.endsWith('.d.ts')) // Exclude .d.ts files
52
66
  .sort(); // Sort files by name
53
- const [results] = yield sequelize.query('SELECT name FROM "SequelizeMeta"');
54
- const executedMigrations = results.map((row) => row.name);
67
+ // Get executed migrations - now this should always work since we ensured the table exists
68
+ let executedMigrations = [];
69
+ try {
70
+ const [results] = yield sequelize.query('SELECT name FROM "SequelizeMeta"');
71
+ executedMigrations = results.map((row) => row.name);
72
+ console.log(`Found ${executedMigrations.length} previously executed migrations`);
73
+ }
74
+ catch (error) {
75
+ console.error('Unexpected error fetching executed migrations:', error);
76
+ throw error;
77
+ }
55
78
  for (const file of migrationFiles) {
56
79
  if (!executedMigrations.includes(file)) {
57
80
  const migration = yield Promise.resolve(`${path_1.default.join(migrationsPath, file)}`).then(s => __importStar(require(s)));
@@ -59,10 +82,11 @@ const runMigrations = (sequelize) => __awaiter(void 0, void 0, void 0, function*
59
82
  console.log(`Running migration: ${file}`);
60
83
  yield migration.up(sequelize.getQueryInterface());
61
84
  yield sequelize.query(`INSERT INTO "SequelizeMeta" (name) VALUES ('${file}')`);
85
+ console.log(`Completed migration: ${file}`);
62
86
  }
63
87
  }
64
88
  else {
65
- console.log(`Skipping migration: ${file}`);
89
+ console.log(`Skipping migration: ${file} (already executed)`);
66
90
  }
67
91
  }
68
92
  console.log('Migrations completed.');
@@ -0,0 +1,3 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ export declare const up: (queryInterface: QueryInterface) => Promise<void>;
3
+ export declare const down: (queryInterface: QueryInterface) => Promise<void>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.down = exports.up = void 0;
13
+ // Purpose: Add video column to static_hotels table.
14
+ const sequelize_1 = require("sequelize");
15
+ const up = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
16
+ try {
17
+ // Check which columns already exist
18
+ const tableDescription = yield queryInterface.describeTable('users');
19
+ const existingColumns = Object.keys(tableDescription);
20
+ // Add passwordResetToken if it doesn't exist
21
+ if (!existingColumns.includes('passwordResetToken')) {
22
+ yield queryInterface.addColumn('users', 'passwordResetToken', {
23
+ type: sequelize_1.DataTypes.STRING,
24
+ allowNull: true,
25
+ });
26
+ console.log('passwordResetToken column added successfully.');
27
+ }
28
+ else {
29
+ console.log('passwordResetToken column already exists, skipping.');
30
+ }
31
+ // Add passwordResetTokenExpiresAt if it doesn't exist
32
+ if (!existingColumns.includes('passwordResetTokenExpiresAt')) {
33
+ yield queryInterface.addColumn('users', 'passwordResetTokenExpiresAt', {
34
+ type: sequelize_1.DataTypes.DATE,
35
+ allowNull: true,
36
+ });
37
+ console.log('passwordResetTokenExpiresAt column added successfully.');
38
+ }
39
+ else {
40
+ console.log('passwordResetTokenExpiresAt column already exists, skipping.');
41
+ }
42
+ console.log('Migration completed successfully.');
43
+ }
44
+ catch (error) {
45
+ console.error('Error while adding columns:', error.message);
46
+ throw error;
47
+ }
48
+ });
49
+ exports.up = up;
50
+ const down = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
51
+ try {
52
+ // Remove columns
53
+ yield queryInterface.removeColumn('users', 'passwordResetToken');
54
+ yield queryInterface.removeColumn('users', 'passwordResetTokenExpiresAt');
55
+ console.log('All columns removed successfully.');
56
+ }
57
+ catch (error) {
58
+ console.error('Error while removing columns:', error.message);
59
+ }
60
+ });
61
+ exports.down = down;
@@ -0,0 +1,3 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ export declare const up: (queryInterface: QueryInterface) => Promise<void>;
3
+ export declare const down: (queryInterface: QueryInterface) => Promise<void>;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.down = exports.up = void 0;
13
+ // Purpose: Add video column to static_hotels table.
14
+ const sequelize_1 = require("sequelize");
15
+ const up = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
16
+ try {
17
+ // Check if seo column already exists
18
+ const tableDescription = yield queryInterface.describeTable('projects');
19
+ const existingColumns = Object.keys(tableDescription);
20
+ if (existingColumns.includes('seo')) {
21
+ console.log('seo column already exists, skipping migration.');
22
+ return;
23
+ }
24
+ yield queryInterface.addColumn('projects', 'seo', {
25
+ type: sequelize_1.DataTypes.JSONB,
26
+ allowNull: false,
27
+ defaultValue: {},
28
+ });
29
+ console.log('seo column added successfully.');
30
+ }
31
+ catch (error) {
32
+ console.error('Error while adding seo column:', error.message);
33
+ throw error;
34
+ }
35
+ });
36
+ exports.up = up;
37
+ const down = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
38
+ try {
39
+ // Remove columns
40
+ yield queryInterface.removeColumn('projects', 'seo');
41
+ console.log('column removed successfully.');
42
+ }
43
+ catch (error) {
44
+ console.error('Error while removing columns:', error.message);
45
+ }
46
+ });
47
+ exports.down = down;
@@ -0,0 +1,3 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ export declare const up: (queryInterface: QueryInterface) => Promise<void>;
3
+ export declare const down: (queryInterface: QueryInterface) => Promise<void>;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.down = exports.up = void 0;
13
+ // Purpose: Add video column to static_hotels table.
14
+ const sequelize_1 = require("sequelize");
15
+ const up = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
16
+ try {
17
+ // Check which columns already exist
18
+ const usersTableDescription = yield queryInterface.describeTable('users');
19
+ const bookingsTableDescription = yield queryInterface.describeTable('bookings');
20
+ const existingUsersColumns = Object.keys(usersTableDescription);
21
+ const existingBookingsColumns = Object.keys(bookingsTableDescription);
22
+ // Add otpExpiresAt to users if it doesn't exist
23
+ if (!existingUsersColumns.includes('otpExpiresAt')) {
24
+ yield queryInterface.addColumn('users', 'otpExpiresAt', {
25
+ type: sequelize_1.DataTypes.DATE,
26
+ allowNull: true,
27
+ });
28
+ console.log('otpExpiresAt column added to users table.');
29
+ }
30
+ else {
31
+ console.log('otpExpiresAt column already exists in users table, skipping.');
32
+ }
33
+ // Add otpExpiresAt to bookings if it doesn't exist
34
+ if (!existingBookingsColumns.includes('otpExpiresAt')) {
35
+ yield queryInterface.addColumn('bookings', 'otpExpiresAt', {
36
+ type: sequelize_1.DataTypes.DATE,
37
+ allowNull: true,
38
+ });
39
+ console.log('otpExpiresAt column added to bookings table.');
40
+ }
41
+ else {
42
+ console.log('otpExpiresAt column already exists in bookings table, skipping.');
43
+ }
44
+ console.log('Migration completed successfully.');
45
+ }
46
+ catch (error) {
47
+ console.error('Error while adding columns:', error.message);
48
+ throw error;
49
+ }
50
+ });
51
+ exports.up = up;
52
+ const down = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
53
+ try {
54
+ // Remove columns
55
+ yield queryInterface.removeColumn('users', 'otpExpiresAt');
56
+ yield queryInterface.removeColumn('bookings', 'otpExpiresAt');
57
+ console.log('column removed successfully.');
58
+ }
59
+ catch (error) {
60
+ console.error('Error while removing columns:', error.message);
61
+ }
62
+ });
63
+ exports.down = down;
@@ -0,0 +1,3 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ export declare const up: (queryInterface: QueryInterface) => Promise<void>;
3
+ export declare const down: (queryInterface: QueryInterface) => Promise<void>;