agrs-sequelize-sdk 1.2.10 → 1.2.12

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 (53) hide show
  1. package/controllers/campaignCreationLogsController.js +264 -0
  2. package/models/CampaignCreationLogNew.js +141 -0
  3. package/models/RSOCFeedCampaign.js +1 -1
  4. package/package.json +1 -1
  5. package/routes/api.js +18 -0
  6. package/utils/loggerUtils.js +497 -0
  7. package/agrs-sequelize/LICENSE +0 -21
  8. package/agrs-sequelize/README.md +0 -179
  9. package/agrs-sequelize/index.js +0 -169
  10. package/agrs-sequelize/jq.exe +0 -0
  11. package/agrs-sequelize/models/ActivityHistory.js +0 -73
  12. package/agrs-sequelize/models/Ad.js +0 -209
  13. package/agrs-sequelize/models/AdAccount.js +0 -91
  14. package/agrs-sequelize/models/AdAccountValues.js +0 -26
  15. package/agrs-sequelize/models/AdHistory.js +0 -30
  16. package/agrs-sequelize/models/AdPerformance.js +0 -84
  17. package/agrs-sequelize/models/AdPerformanceHourly.js +0 -66
  18. package/agrs-sequelize/models/AdSet.js +0 -140
  19. package/agrs-sequelize/models/AdSetHistory.js +0 -30
  20. package/agrs-sequelize/models/AdsetPerformance.js +0 -116
  21. package/agrs-sequelize/models/Article.js +0 -156
  22. package/agrs-sequelize/models/Buyers.js +0 -26
  23. package/agrs-sequelize/models/Campaign.js +0 -136
  24. package/agrs-sequelize/models/CampaignCreationLog.js +0 -86
  25. package/agrs-sequelize/models/CampaignHistory.js +0 -33
  26. package/agrs-sequelize/models/Channel.js +0 -55
  27. package/agrs-sequelize/models/CodefuelCampaign.js +0 -159
  28. package/agrs-sequelize/models/CodefuelCampaignKWHistory.js +0 -41
  29. package/agrs-sequelize/models/CodefuelKeywords.js +0 -35
  30. package/agrs-sequelize/models/CurrencyRate.js +0 -27
  31. package/agrs-sequelize/models/Domain.js +0 -26
  32. package/agrs-sequelize/models/ExplorAdsChannel.js +0 -62
  33. package/agrs-sequelize/models/Feed.js +0 -34
  34. package/agrs-sequelize/models/Files.js +0 -73
  35. package/agrs-sequelize/models/Folders.js +0 -133
  36. package/agrs-sequelize/models/KeywordPerformance.js +0 -99
  37. package/agrs-sequelize/models/KeywordRotationState.js +0 -51
  38. package/agrs-sequelize/models/Pages.js +0 -74
  39. package/agrs-sequelize/models/PipelineExecution.js +0 -46
  40. package/agrs-sequelize/models/RSOCFeedCampaign.js +0 -307
  41. package/agrs-sequelize/models/RsocKeywordPerformance.js +0 -111
  42. package/agrs-sequelize/models/Rule.js +0 -39
  43. package/agrs-sequelize/models/RulesValues.js +0 -56
  44. package/agrs-sequelize/models/SupportedLocale.js +0 -24
  45. package/agrs-sequelize/models/TonicCampaign.js +0 -97
  46. package/agrs-sequelize/models/Users.js +0 -111
  47. package/agrs-sequelize/models/Vertical.js +0 -26
  48. package/agrs-sequelize/models/newFiles.js +0 -68
  49. package/agrs-sequelize/models/pixels.js +0 -33
  50. package/agrs-sequelize/package-lock.json +0 -405
  51. package/agrs-sequelize/package.json +0 -19
  52. package/agrs-sequelize/run.ps1 +0 -98
  53. package/agrs-sequelize/run.sh +0 -214
@@ -0,0 +1,497 @@
1
+ /**
2
+ * Create logs in both old and new campaign creation log models
3
+ * @param {Object} oldLogData Data for the original CampaignCreationLog model
4
+ * @param {Object} newLogData Data for the new CampaignCreationLogNew model
5
+ * @returns {Promise<Object>} Object containing both created logs
6
+ */
7
+ async function createDualLogs(oldLogData, newLogData) {
8
+ const { CampaignCreationLog, CampaignCreationLogNew } = require("../db");
9
+
10
+ try {
11
+ // Create log in original model
12
+ const oldLog = await CampaignCreationLog.create(oldLogData);
13
+
14
+ // Create log in new model with extended data
15
+ const newLog = await CampaignCreationLogNew.create({
16
+ ...newLogData,
17
+ // Ensure we have the original data as well
18
+ process_id: oldLogData.process_id,
19
+ country: oldLogData.country,
20
+ feed_campaign_id: oldLogData.feed_campaign_id,
21
+ facebook_campaign_id: oldLogData.facebook_campaign_id,
22
+ error_message: oldLogData.error_message,
23
+ });
24
+
25
+ return { oldLog, newLog };
26
+ } catch (error) {
27
+ console.error("Error creating logs:", error);
28
+ // Always try to create the original log even if the new one fails
29
+ try {
30
+ const oldLog = await CampaignCreationLog.create(oldLogData);
31
+ return { oldLog, newLog: null };
32
+ } catch (oldLogError) {
33
+ console.error("Failed to create old log as well:", oldLogError);
34
+ throw error; // Re-throw original error
35
+ }
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Log campaign creation stage - with support for hierarchy
41
+ * @param {Object} data Log data
42
+ * @returns {Promise<Object>} Created logs
43
+ */
44
+ async function logCampaignCreationStage(data) {
45
+ const {
46
+ process_id,
47
+ stage,
48
+ status,
49
+ country,
50
+ facebook_campaign_id,
51
+ feed_campaign_id,
52
+ facebook_adset_id,
53
+ facebook_ad_id,
54
+ parent_id,
55
+ entity_name,
56
+ entity_index,
57
+ details,
58
+ error_message,
59
+ } = data;
60
+
61
+ // Format data for old log model
62
+ const oldLogData = {
63
+ process_id,
64
+ status,
65
+ country,
66
+ feed_campaign_id,
67
+ facebook_campaign_id,
68
+ details: {
69
+ step: stage,
70
+ ...(facebook_adset_id && { adsetId: facebook_adset_id }),
71
+ ...(facebook_ad_id && { adId: facebook_ad_id }),
72
+ ...(entity_name && { name: entity_name }),
73
+ ...(details && { ...details }),
74
+ },
75
+ error_message,
76
+ };
77
+
78
+ // Format data for new log model
79
+ const newLogData = {
80
+ process_id,
81
+ stage,
82
+ status,
83
+ country,
84
+ feed_campaign_id,
85
+ facebook_campaign_id,
86
+ facebook_adset_id,
87
+ facebook_ad_id,
88
+ parent_id,
89
+ entity_name,
90
+ entity_index,
91
+ details,
92
+ error_message,
93
+ };
94
+
95
+ return createDualLogs(oldLogData, newLogData);
96
+ }
97
+
98
+ /**
99
+ * Log campaign creation with multiple adsets and ads
100
+ * @param {Object} data Campaign data
101
+ * @returns {Promise<Array>} Created logs
102
+ */
103
+ async function logCampaignWithChildEntities(data) {
104
+ const {
105
+ process_id,
106
+ country,
107
+ campaign_id,
108
+ campaign_name,
109
+ adsets = [],
110
+ campaign_details,
111
+ status = "COMPLETED",
112
+ error_message,
113
+ } = data;
114
+
115
+ const logs = [];
116
+
117
+ // Log the campaign creation
118
+ const campaignLog = await logCampaignCreationStage({
119
+ process_id,
120
+ stage: "CAMPAIGN_CREATION",
121
+ status,
122
+ country,
123
+ facebook_campaign_id: campaign_id,
124
+ entity_name: campaign_name,
125
+ details: {
126
+ campaign_data: campaign_details || { campaign_name },
127
+ planned_adsets: adsets.map((adset) => ({
128
+ adset_name: adset.name,
129
+ targeting: adset.targeting,
130
+ })),
131
+ },
132
+ error_message,
133
+ });
134
+
135
+ logs.push(campaignLog);
136
+
137
+ // If campaign was successful and we have adsets, log each adset
138
+ if (status === "COMPLETED" && adsets.length > 0) {
139
+ for (const [index, adset] of adsets.entries()) {
140
+ // Log adset creation
141
+ const adsetLog = await logCampaignCreationStage({
142
+ process_id,
143
+ stage: "ADSET_CREATION",
144
+ status: adset.status || "COMPLETED",
145
+ country,
146
+ facebook_campaign_id: campaign_id,
147
+ facebook_adset_id: adset.id,
148
+ parent_id: campaign_id,
149
+ entity_name: adset.name,
150
+ entity_index: index,
151
+ details: {
152
+ adset_data: {
153
+ adset_name: adset.name,
154
+ targeting: adset.targeting,
155
+ budget: adset.budget,
156
+ },
157
+ planned_ads: adset.ads?.map((ad) => ({
158
+ ad_name: ad.name,
159
+ creative: ad.creative,
160
+ })),
161
+ },
162
+ error_message: adset.error_message,
163
+ });
164
+
165
+ logs.push(adsetLog);
166
+
167
+ // If adset was successful and we have ads, log each ad
168
+ if (adset.status !== "FAILED" && adset.ads && adset.ads.length > 0) {
169
+ for (const [adIndex, ad] of adset.ads.entries()) {
170
+ // Log ad creation
171
+ const adLog = await logCampaignCreationStage({
172
+ process_id,
173
+ stage: "AD_CREATION",
174
+ status: ad.status || "COMPLETED",
175
+ country,
176
+ facebook_campaign_id: campaign_id,
177
+ facebook_adset_id: adset.id,
178
+ facebook_ad_id: ad.id,
179
+ parent_id: adset.id,
180
+ entity_name: ad.name,
181
+ entity_index: adIndex,
182
+ details: {
183
+ ad_data: {
184
+ ad_name: ad.name,
185
+ creative: ad.creative,
186
+ },
187
+ },
188
+ error_message: ad.error_message,
189
+ });
190
+
191
+ logs.push(adLog);
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ return logs;
198
+ }
199
+
200
+ /**
201
+ * Determine error stage based on error message or context
202
+ * @param {Error} error Error object
203
+ * @returns {String} Stage name where the error occurred
204
+ */
205
+ function determineErrorStage(error) {
206
+ if (!error) return "PROCESS_STARTED";
207
+
208
+ // Check if stage is explicitly set
209
+ if (error.stage) return error.stage;
210
+
211
+ // Try to infer from error message
212
+ const message = error.message ? error.message.toLowerCase() : "";
213
+
214
+ if (message.includes("campaign")) return "CAMPAIGN_CREATION";
215
+ if (message.includes("adset")) return "ADSET_CREATION";
216
+ if (message.includes("ad ") || message.includes("creative"))
217
+ return "AD_CREATION";
218
+
219
+ return "PROCESS_STARTED"; // Default
220
+ }
221
+
222
+ /**
223
+ * Get summary statistics for a campaign creation process
224
+ * @param {String} processId UUID of the process
225
+ * @returns {Promise<Object>} Object with stats about the process
226
+ */
227
+ async function getProcessStats(processId) {
228
+ const { CampaignCreationLogNew, sequelize } = require("../db");
229
+ const { Op } = require("sequelize");
230
+
231
+ // Count successful countries (completed campaign stage with adsets and ads)
232
+ const successfulCampaigns = await CampaignCreationLogNew.count({
233
+ where: {
234
+ process_id: processId,
235
+ stage: "CAMPAIGN_CREATION",
236
+ status: "COMPLETED",
237
+ },
238
+ });
239
+
240
+ // Count successful adsets
241
+ const successfulAdsets = await CampaignCreationLogNew.count({
242
+ where: {
243
+ process_id: processId,
244
+ stage: "ADSET_CREATION",
245
+ status: "COMPLETED",
246
+ },
247
+ });
248
+
249
+ // Count successful ads
250
+ const successfulAds = await CampaignCreationLogNew.count({
251
+ where: {
252
+ process_id: processId,
253
+ stage: "AD_CREATION",
254
+ status: "COMPLETED",
255
+ },
256
+ });
257
+
258
+ // Count failed entities at each level
259
+ const failedCampaigns = await CampaignCreationLogNew.count({
260
+ where: {
261
+ process_id: processId,
262
+ stage: "CAMPAIGN_CREATION",
263
+ status: "FAILED",
264
+ },
265
+ });
266
+
267
+ const failedAdsets = await CampaignCreationLogNew.count({
268
+ where: {
269
+ process_id: processId,
270
+ stage: "ADSET_CREATION",
271
+ status: "FAILED",
272
+ },
273
+ });
274
+
275
+ const failedAds = await CampaignCreationLogNew.count({
276
+ where: {
277
+ process_id: processId,
278
+ stage: "AD_CREATION",
279
+ status: "FAILED",
280
+ },
281
+ });
282
+
283
+ // Count countries
284
+ const successfulCountries = await CampaignCreationLogNew.count({
285
+ where: {
286
+ process_id: processId,
287
+ stage: "CAMPAIGN_CREATION",
288
+ status: "COMPLETED",
289
+ },
290
+ distinct: true,
291
+ col: "country",
292
+ });
293
+
294
+ const failedCountries = await CampaignCreationLogNew.count({
295
+ where: {
296
+ process_id: processId,
297
+ stage: "CAMPAIGN_CREATION",
298
+ status: "FAILED",
299
+ },
300
+ distinct: true,
301
+ col: "country",
302
+ });
303
+
304
+ // Get all countries in the process
305
+ const allCountries = await CampaignCreationLogNew.count({
306
+ where: {
307
+ process_id: processId,
308
+ country: { [Op.ne]: null },
309
+ },
310
+ distinct: true,
311
+ col: "country",
312
+ });
313
+
314
+ return {
315
+ total_countries: allCountries,
316
+ successful_countries: successfulCountries,
317
+ failed_countries: failedCountries,
318
+ in_progress_countries: allCountries - successfulCountries - failedCountries,
319
+ entity_stats: {
320
+ campaigns: {
321
+ successful: successfulCampaigns,
322
+ failed: failedCampaigns,
323
+ },
324
+ adsets: {
325
+ successful: successfulAdsets,
326
+ failed: failedAdsets,
327
+ },
328
+ ads: {
329
+ successful: successfulAds,
330
+ failed: failedAds,
331
+ },
332
+ },
333
+ };
334
+ }
335
+
336
+ /**
337
+ * Get hierarchical view of a campaign creation process
338
+ * @param {String} processId Process ID
339
+ * @returns {Promise<Object>} Hierarchical view of the process
340
+ */
341
+ async function getProcessHierarchy(processId) {
342
+ const { CampaignCreationLogNew } = require("../db");
343
+
344
+ // Get initial process log
345
+ const processLog = await CampaignCreationLogNew.findOne({
346
+ where: {
347
+ process_id: processId,
348
+ stage: "PROCESS_STARTED",
349
+ },
350
+ order: [["createdAt", "ASC"]],
351
+ });
352
+
353
+ if (!processLog) {
354
+ return null;
355
+ }
356
+
357
+ // Get all campaign logs
358
+ const campaignLogs = await CampaignCreationLogNew.findAll({
359
+ where: {
360
+ process_id: processId,
361
+ stage: "CAMPAIGN_CREATION",
362
+ },
363
+ order: [
364
+ ["country", "ASC"],
365
+ ["createdAt", "DESC"],
366
+ ],
367
+ });
368
+
369
+ // Group campaigns by country
370
+ const campaignsByCountry = {};
371
+
372
+ for (const log of campaignLogs) {
373
+ const country = log.country || "unknown";
374
+
375
+ if (!campaignsByCountry[country]) {
376
+ campaignsByCountry[country] = {
377
+ country,
378
+ status: log.status,
379
+ campaign_id: log.facebook_campaign_id,
380
+ campaign_name: log.entity_name,
381
+ details: log.details,
382
+ error: log.error_message,
383
+ adsets: [],
384
+ createdAt: log.createdAt,
385
+ };
386
+ }
387
+ }
388
+
389
+ // For each campaign, get its adsets
390
+ for (const country in campaignsByCountry) {
391
+ const campaign = campaignsByCountry[country];
392
+
393
+ if (campaign.campaign_id) {
394
+ // Get adsets for this campaign
395
+ const adsetLogs = await CampaignCreationLogNew.findAll({
396
+ where: {
397
+ process_id: processId,
398
+ stage: "ADSET_CREATION",
399
+ parent_id: campaign.campaign_id,
400
+ },
401
+ order: [
402
+ ["entity_index", "ASC"],
403
+ ["createdAt", "DESC"],
404
+ ],
405
+ });
406
+
407
+ // Process adsets
408
+ for (const adsetLog of adsetLogs) {
409
+ const adset = {
410
+ adset_id: adsetLog.facebook_adset_id,
411
+ adset_name: adsetLog.entity_name,
412
+ status: adsetLog.status,
413
+ details: adsetLog.details,
414
+ error: adsetLog.error_message,
415
+ ads: [],
416
+ createdAt: adsetLog.createdAt,
417
+ };
418
+
419
+ // Get ads for this adset
420
+ if (adsetLog.facebook_adset_id) {
421
+ const adLogs = await CampaignCreationLogNew.findAll({
422
+ where: {
423
+ process_id: processId,
424
+ stage: "AD_CREATION",
425
+ parent_id: adsetLog.facebook_adset_id,
426
+ },
427
+ order: [
428
+ ["entity_index", "ASC"],
429
+ ["createdAt", "DESC"],
430
+ ],
431
+ });
432
+
433
+ // Process ads
434
+ for (const adLog of adLogs) {
435
+ adset.ads.push({
436
+ ad_id: adLog.facebook_ad_id,
437
+ ad_name: adLog.entity_name,
438
+ status: adLog.status,
439
+ details: adLog.details,
440
+ error: adLog.error_message,
441
+ createdAt: adLog.createdAt,
442
+ });
443
+ }
444
+ }
445
+
446
+ campaign.adsets.push(adset);
447
+ }
448
+ }
449
+ }
450
+
451
+ // Return hierarchical view
452
+ return {
453
+ process_id: processId,
454
+ status: processLog.status,
455
+ original_request: processLog.details?.original_request,
456
+ created_at: processLog.createdAt,
457
+ campaigns_by_country: campaignsByCountry,
458
+ statistics: await getProcessStats(processId),
459
+ };
460
+ }
461
+
462
+ /**
463
+ * Determine the final status of a process based on its logs
464
+ * @param {String} processId UUID of the process
465
+ * @returns {Promise<String>} Final status (COMPLETED, FAILED, etc.)
466
+ */
467
+ async function determineFinalStatus(processId) {
468
+ const stats = await getProcessStats(processId);
469
+
470
+ // If all countries failed
471
+ if (stats.failed_countries > 0 && stats.successful_countries === 0) {
472
+ return "FAILED";
473
+ }
474
+
475
+ // If some countries succeeded and some failed
476
+ if (stats.failed_countries > 0 && stats.successful_countries > 0) {
477
+ return "COMPLETED"; // Could also be "PARTIALLY_COMPLETED" if you want to add this status
478
+ }
479
+
480
+ // If all countries succeeded
481
+ if (stats.successful_countries > 0 && stats.failed_countries === 0) {
482
+ return "COMPLETED";
483
+ }
484
+
485
+ // If no countries completed or failed yet
486
+ return "IN_PROGRESS";
487
+ }
488
+
489
+ module.exports = {
490
+ createDualLogs,
491
+ logCampaignCreationStage,
492
+ logCampaignWithChildEntities,
493
+ determineErrorStage,
494
+ getProcessStats,
495
+ getProcessHierarchy,
496
+ determineFinalStatus,
497
+ };
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Agressive Scale LTD
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,179 +0,0 @@
1
- # agrs-sequelize SDK
2
-
3
- The `agrs-sequelize` SDK provides a structured way to manage your database models using Sequelize ORM. It allows you to easily add, update, and manage models, with support for publishing updates to NPM and pushing changes to GitHub.
4
-
5
- ## Table of Contents
6
-
7
- - [Prerequisites](#prerequisites)
8
- - [Installation](#installation)
9
- - [Usage](#usage)
10
- - [Adding or Modifying Models](#adding-or-modifying-models)
11
- - [Model Loading](#model-loading)
12
- - [Publishing Changes](#publishing-changes)
13
- - [Using PowerShell (Windows)](#using-powershell-windows)
14
- - [Using Bash (Linux/macOS)](#using-bash-linuxmacos)
15
- - [Script Details](#script-details)
16
- - [run.ps1 (PowerShell Script for Windows)](#runps1-powershell-script-for-windows)
17
- - [run.sh (Bash Script for Linux/macOS)](#runsh-bash-script-for-linuxmacos)
18
- - [Example Model File](#example-model-file)
19
- - [Versioning](#versioning)
20
- - [Troubleshooting](#troubleshooting)
21
- - [License](#license)
22
-
23
- ## Prerequisites
24
-
25
- Ensure the following dependencies are installed on your system:
26
-
27
- - **Node.js**: [Download Node.js](https://nodejs.org/)
28
- - **Sequelize**: Used for database interaction.
29
- - **Git**: Required for version control and publishing changes to GitHub.
30
- - **npm**: For managing and publishing packages.
31
- - **PowerShell** (Windows) or **Bash** (Linux/macOS): For running automation scripts.
32
-
33
- ## Installation
34
-
35
- 1. **Clone the Repository:**
36
-
37
- ```bash
38
- git clone https://github.com/your-repo/agrs-sequelize.git
39
- cd agrs-sequelize
40
- ```
41
-
42
- 2. **Install Dependencies:**
43
-
44
- ```bash
45
- npm install
46
- ```
47
-
48
-
49
- # Usage
50
-
51
- ## Adding or Modifying Models
52
- To add or modify models in the agrs-sequelize SDK:
53
-
54
- 1. **Create or Edit a Model:**
55
-
56
- - Add a new model file inside the models directory or edit an existing one.
57
- - Each model file should export a function that initializes the model with Sequelize.
58
-
59
- ```javascript
60
- // models/YourModel.js
61
- module.exports = (sequelize, DataTypes) => {
62
- const YourModel = sequelize.define('YourModel', {
63
- fieldName: {
64
- type: DataTypes.STRING,
65
- allowNull: false,
66
- },
67
- });
68
-
69
- // Define associations (optional)
70
- YourModel.associate = (models) => {
71
- YourModel.hasMany(models.OtherModel);
72
- };
73
-
74
- return YourModel;
75
- };
76
- ```
77
-
78
- 2. **Define Associations (if required):**
79
-
80
- Use the associate method to define relationships with other models.
81
- Associations like hasMany, belongsTo, etc., are supported.
82
- ### Model Loading
83
- Models are automatically loaded when initializing Sequelize.
84
- The index.js file ensures all models in the models directory are properly loaded and associated.
85
-
86
- ## Publishing Changes
87
- After modifying or adding models, publish the changes to NPM and GitHub.
88
-
89
- ### Using PowerShell (Windows)
90
- Open PowerShell as Administrator.
91
-
92
- Run the Script:
93
-
94
- ```powershell
95
- ./run.ps1
96
- ```
97
- The script will:
98
-
99
- - Check for jq installation.
100
- - Bump the version in package.json.
101
- - Publish to NPM.
102
- - Commit and push changes to GitHub.
103
-
104
- ### Using Bash (Linux/macOS)
105
- Open a Bash Terminal.
106
-
107
- Run the Script:
108
-
109
- ```bash
110
- ./run.sh
111
- ```
112
- The script performs the same tasks as the PowerShell script, tailored for Bash environments.
113
-
114
- ## Script Details
115
- ### run.ps1 (PowerShell Script for Windows)
116
- Automates the publishing process:
117
-
118
- - Ensures jq is installed.
119
- - Increments the version in package.json.
120
- - Publishes the package to NPM.
121
- - Commits and pushes changes to GitHub.
122
-
123
- ### run.sh (Bash Script for Linux/macOS)
124
- Provides similar functionality:
125
-
126
- - Checks for jq installation.
127
- - Bumps the package version.
128
- = Publishes to NPM.
129
- = Commits and pushes to GitHub.
130
-
131
- ## Example Model File
132
- ```javascript
133
- Copy code
134
- // models/YourModel.js
135
- module.exports = (sequelize, DataTypes) => {
136
- const YourModel = sequelize.define('YourModel', {
137
- name: {
138
- type: DataTypes.STRING,
139
- allowNull: false,
140
- },
141
- });
142
-
143
- // Define associations (optional)
144
- YourModel.associate = (models) => {
145
- YourModel.hasMany(models.OtherModel);
146
- };
147
-
148
- return YourModel;
149
- };
150
- ```
151
- In this example:
152
-
153
- YourModel has a name field.
154
- It has a hasMany association with OtherModel.
155
- ## Versioning
156
- Versioning is handled automatically:
157
-
158
- - The scripts increment the version in package.json.
159
- - Follows semantic versioning (major, minor, patch).
160
- - Updated versions are published to NPM and committed to the repository.
161
-
162
- ## Troubleshooting
163
- - ### Permission Issues:
164
-
165
- - Linux/macOS: Ensure scripts have execute permissions (chmod +x run.sh).
166
- - ### NPM Login Errors:
167
-
168
- - The script will prompt for NPM login if not already logged in.
169
- - Verify NPM account credentials.
170
-
171
- - ### Missing Dependencies:
172
-
173
- - The script checks for jq and installs it if missing.
174
- ## License
175
- This project is licensed under the MIT License. See the LICENSE file for details.
176
-
177
-
178
-
179
-