@b2y/ecommerce-common 1.0.2 → 1.0.3

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.
@@ -13,9 +13,6 @@ const initializeModels = (sequelize) => {
13
13
  User,
14
14
  Customer,
15
15
  Address,
16
- City,
17
- State,
18
- Country,
19
16
  Product,
20
17
  ProductVariant,
21
18
  Category,
@@ -60,31 +57,7 @@ const initializeModels = (sequelize) => {
60
57
  as: "parentCategory",
61
58
  });
62
59
 
63
- User.belongsTo(City, {
64
- foreignKey: "CityID",
65
- as: "City", // Alias for the association
66
- });
67
-
68
- // User associations
69
- User.belongsTo(State, {
70
- foreignKey: "StateID",
71
- as: "State", // Alias for the association
72
- });
73
-
74
- User.belongsTo(Country, {
75
- foreignKey: "CountryID",
76
- as: "Country", // Alias for the association
77
- });
78
-
79
- // In Store model
80
- Store.belongsTo(City, { foreignKey: "CityID", as: "City" });
81
-
82
- // In Store model
83
- Store.belongsTo(State, { foreignKey: "StateID", as: "State" });
84
-
85
- // Store.js
86
- Store.belongsTo(Country, { foreignKey: "CountryID", as: "Country" });
87
-
60
+
88
61
  Store.belongsToMany(User, {
89
62
  through: StoreUserMapping,
90
63
  foreignKey: "StoreID",
@@ -131,17 +104,6 @@ const initializeModels = (sequelize) => {
131
104
  Address.belongsTo(Customer, { foreignKey: "CustomerID", as: "Customer" });
132
105
  Customer.hasMany(Address, { foreignKey: "CustomerID", as: "Address" });
133
106
 
134
- // Address belongs to City
135
- Address.belongsTo(City, { foreignKey: "CityID", as: "City" });
136
- City.hasMany(Address, { foreignKey: "CityID", as: "Address" });
137
-
138
- // Address belongs to State
139
- Address.belongsTo(State, { foreignKey: "StateID", as: "State" });
140
- State.hasMany(Address, { foreignKey: "StateID", as: "Address" });
141
-
142
- // Address belongs to Country
143
- Address.belongsTo(Country, { foreignKey: "CountryID", as: "Country" });
144
- Country.hasMany(Address, { foreignKey: "CountryID", as: "Address" });
145
107
 
146
108
  /*---- product related associations -----*/
147
109
  // Product and ProductVariant Associations
package/model/Address.js CHANGED
@@ -35,38 +35,20 @@ module.exports = (sequelize) => {
35
35
  AddressLine2: {
36
36
  type: DataTypes.STRING(255)
37
37
  },
38
- CityID: {
39
- type: DataTypes.INTEGER,
38
+ CityName: {
39
+ type: DataTypes.STRING(100),
40
40
  allowNull: false,
41
- references: {
42
- model: 'City',
43
- key: 'CityID'
44
- },
45
- onDelete: 'RESTRICT',
46
- onUpdate: 'CASCADE'
47
41
  },
48
- StateID: {
49
- type: DataTypes.INTEGER,
50
- allowNull: false,
51
- references: {
52
- model: 'State',
53
- key: 'StateID'
54
- },
55
- onDelete: 'RESTRICT',
56
- onUpdate: 'CASCADE'
42
+ StateCode: {
43
+ type:DataTypes.CHAR(3),
44
+ allowNull:false
57
45
  },
58
- CountryID: {
59
- type: DataTypes.INTEGER,
60
- allowNull: false,
61
- references: {
62
- model: 'Country',
63
- key: 'CountryID'
64
- },
65
- onDelete: 'RESTRICT',
66
- onUpdate: 'CASCADE'
46
+ CountryCode:{
47
+ type:DataTypes.CHAR(2),
48
+ allowNull:false
67
49
  },
68
50
  Zipcode: {
69
- type: DataTypes.STRING(10),
51
+ type: DataTypes.STRING(20),
70
52
  allowNull: false
71
53
  },
72
54
  AddressType: {
package/model/Customer.js CHANGED
@@ -34,7 +34,7 @@ module.exports = (sequelize) => {
34
34
  Password: {
35
35
  type: DataTypes.STRING(255)
36
36
  },
37
- CountryCode: {
37
+ CountryCallingCode: {
38
38
  type: DataTypes.STRING(5),
39
39
  allowNull: false
40
40
  },
@@ -88,7 +88,7 @@ module.exports = (sequelize) => {
88
88
  {
89
89
  name: "UQ_Customer_Tenant_Phone",
90
90
  unique: true,
91
- fields: ["TenantID", "CountryCode", "PhoneNumber"],
91
+ fields: ["TenantID", "CountryCallingCode", "PhoneNumber"],
92
92
  },
93
93
  ],
94
94
  });
package/model/Order.js CHANGED
@@ -55,7 +55,7 @@ module.exports = (sequelize) => {
55
55
  type: DataTypes.STRING(255),
56
56
  allowNull: false
57
57
  },
58
- CountryCode: {
58
+ CountryCallingCode: {
59
59
  type: DataTypes.STRING(5),
60
60
  allowNull: false
61
61
  },
package/model/Store.js CHANGED
@@ -25,7 +25,7 @@ module.exports = (sequelize) => {
25
25
  type: DataTypes.STRING(100),
26
26
  allowNull: false,
27
27
  },
28
- CountryCode: {
28
+ CountryCallingCode: {
29
29
  type: DataTypes.STRING(5),
30
30
  allowNull: false
31
31
  },
@@ -40,38 +40,20 @@ module.exports = (sequelize) => {
40
40
  AddressLine2: {
41
41
  type: DataTypes.STRING(255),
42
42
  },
43
- CountryID: {
44
- type: DataTypes.INTEGER,
45
- allowNull: false,
46
- references: {
47
- model: 'Country',
48
- key: 'CountryID'
49
- },
50
- onDelete: 'RESTRICT',
51
- onUpdate: 'CASCADE'
43
+ CountryCode:{
44
+ type:DataTypes.CHAR(2),
45
+ allowNull:false
52
46
  },
53
- StateID: {
54
- type: DataTypes.INTEGER,
55
- allowNull: false,
56
- references: {
57
- model: 'State',
58
- key: 'StateID'
59
- },
60
- onDelete: 'RESTRICT',
61
- onUpdate: 'CASCADE'
47
+ StateCode: {
48
+ type:DataTypes.CHAR(3),
49
+ allowNull:false
62
50
  },
63
- CityID: {
64
- type: DataTypes.INTEGER,
51
+ CityName: {
52
+ type: DataTypes.STRING(100),
65
53
  allowNull: false,
66
- references: {
67
- model: 'City',
68
- key: 'CityID'
69
- },
70
- onDelete: 'RESTRICT',
71
- onUpdate: 'CASCADE'
72
54
  },
73
55
  Zipcode: {
74
- type: DataTypes.STRING(10),
56
+ type: DataTypes.STRING(20),
75
57
  allowNull: false,
76
58
  },
77
59
  IsActive: {
@@ -106,7 +88,7 @@ module.exports = (sequelize) => {
106
88
  {
107
89
  name: "UQ_Store_Tenant_Phone",
108
90
  unique: true,
109
- fields: ["TenantID", "CountryCode", "PhoneNumber"],
91
+ fields: ["TenantID", "CountryCallingCode", "PhoneNumber"],
110
92
  },
111
93
  ],
112
94
  });
package/model/Tenant.js CHANGED
@@ -28,7 +28,7 @@ module.exports = (sequelize) => {
28
28
  allowNull: false,
29
29
  unique: true
30
30
  },
31
- CountryCode: {
31
+ CountryCallingCode: {
32
32
  type: DataTypes.STRING(5),
33
33
  allowNull: false
34
34
  },
@@ -50,20 +50,20 @@ module.exports = (sequelize) => {
50
50
  type: DataTypes.STRING(500),
51
51
  allowNull: false
52
52
  },
53
- City: {
53
+ CityName: {
54
54
  type: DataTypes.STRING(100),
55
55
  allowNull: false
56
56
  },
57
- State: {
58
- type: DataTypes.STRING(100),
57
+ StateCode: {
58
+ type: DataTypes.CHAR(3),
59
59
  allowNull: false
60
60
  },
61
- Country: {
62
- type: DataTypes.STRING(100),
61
+ CountryCode: {
62
+ type: DataTypes.CHAR(2),
63
63
  allowNull: false
64
64
  },
65
65
  Zipcode: {
66
- type: DataTypes.STRING(10),
66
+ type: DataTypes.STRING(20),
67
67
  allowNull: false
68
68
  },
69
69
  CreatedBy: {
package/model/User.js CHANGED
@@ -39,7 +39,7 @@ module.exports = (sequelize) => {
39
39
  type: DataTypes.STRING(255),
40
40
  allowNull: false
41
41
  },
42
- CountryCode: {
42
+ CountryCallingCode: {
43
43
  type: DataTypes.STRING(5),
44
44
  allowNull: false
45
45
  },
@@ -65,38 +65,20 @@ module.exports = (sequelize) => {
65
65
  type: DataTypes.STRING(500),
66
66
  allowNull: false
67
67
  },
68
- CityID: {
69
- type: DataTypes.INTEGER,
68
+ CityName: {
69
+ type: DataTypes.STRING(100),
70
70
  allowNull: false,
71
- references: {
72
- model: 'City',
73
- key: 'CityID'
74
- },
75
- onDelete: 'RESTRICT',
76
- onUpdate: 'CASCADE'
77
71
  },
78
- StateID: {
79
- type: DataTypes.INTEGER,
80
- allowNull: false,
81
- references: {
82
- model: 'State',
83
- key: 'StateID'
84
- },
85
- onDelete: 'RESTRICT',
86
- onUpdate: 'CASCADE'
72
+ StateCode: {
73
+ type:DataTypes.CHAR(3),
74
+ allowNull:false
87
75
  },
88
- CountryID: {
89
- type: DataTypes.INTEGER,
90
- allowNull: false,
91
- references: {
92
- model: 'Country',
93
- key: 'CountryID'
94
- },
95
- onDelete: 'RESTRICT',
96
- onUpdate: 'CASCADE'
76
+ CountryCode:{
77
+ type:DataTypes.CHAR(2),
78
+ allowNull:false
97
79
  },
98
80
  Zipcode: {
99
- type: DataTypes.STRING(10),
81
+ type: DataTypes.STRING(20),
100
82
  allowNull: false
101
83
  },
102
84
  OTP: {
@@ -141,7 +123,7 @@ module.exports = (sequelize) => {
141
123
  {
142
124
  name: "UQ_User_Tenant_Phone",
143
125
  unique: true,
144
- fields: ["TenantID", "CountryCode", "PhoneNumber"],
126
+ fields: ["TenantID", "CountryCallingCode", "PhoneNumber"],
145
127
  },
146
128
  ],
147
129
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b2y/ecommerce-common",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "E-commerce common library",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,6 +22,7 @@
22
22
  "peerDependencies": {
23
23
  "exceljs": "^4.4.0",
24
24
  "luxon": "^3.7.2",
25
- "sequelize": "^6.37.5"
25
+ "sequelize": "^6.37.5",
26
+ "@countrystatecity/countries": "^1.0.4"
26
27
  }
27
28
  }
@@ -0,0 +1,131 @@
1
+ const { getCountries, getStatesOfCountry, getCitiesOfState } = require('@countrystatecity/countries');
2
+
3
+ // Helper to resolve country and state names from codes
4
+ async function resolveCountryAndState(countryCode, stateCode, logger) {
5
+ // eslint-disable-next-line no-useless-catch
6
+ try {
7
+ const trimmedCountry = countryCode ? String(countryCode).trim() : "";
8
+ const trimmedState = stateCode ? String(stateCode).trim() : "";
9
+
10
+ let countryName = trimmedCountry;
11
+ let stateName = trimmedState;
12
+
13
+ if (trimmedCountry) {
14
+ try {
15
+ const countries = await getCountries();
16
+ const country = countries.find(
17
+ (c) =>
18
+ c.iso2 === trimmedCountry || c.iso2 === trimmedCountry.toUpperCase()
19
+ );
20
+ if (country) countryName = country.name;
21
+ } catch (err) {
22
+ logger.error("Error resolving country name:", err);
23
+ }
24
+ }
25
+
26
+ if (trimmedState) {
27
+ try {
28
+ const states = await getStatesOfCountry(trimmedCountry);
29
+ const state = states.find(
30
+ (s) =>
31
+ s.iso2 === trimmedState ||
32
+ s.state_code === trimmedState ||
33
+ s.state_code === trimmedState.toUpperCase()
34
+ );
35
+ if (state) stateName = state.name;
36
+ } catch (err) {
37
+ logger.error("Error resolving state name:", err);
38
+ }
39
+ }
40
+
41
+ return { countryName, stateName };
42
+ } catch (err) {
43
+ throw err;
44
+ }
45
+ }
46
+
47
+ // Helper to validate country and state codes
48
+ async function validateCountryAndState(countryCode, stateCode, cityName, countryCallingCode, logger) {
49
+ try {
50
+ const trimmedCountryCode = countryCode ? String(countryCode).trim() : "";
51
+ const trimmedStateCode = stateCode ? String(stateCode).trim() : "";
52
+ const trimmedCityName = cityName ? cityName.trim().toLowerCase() : "";
53
+ const trimmedCountryCallingCode = countryCallingCode ? countryCallingCode.replace('+', '').trim() : "";
54
+ // Validate country code exists
55
+ if (trimmedCountryCode) {
56
+ const countries = await getCountries();
57
+ const validCountry = countries.find(
58
+ (c) =>
59
+ c.iso2 === trimmedCountryCode ||
60
+ c.iso2 === trimmedCountryCode.toUpperCase()
61
+ );
62
+
63
+ if (!validCountry) {
64
+ return {
65
+ isValid: false,
66
+ error: `Invalid country code: ${countryCode}`,
67
+ };
68
+ }
69
+
70
+ // Validate state code if provided
71
+ if (trimmedStateCode) {
72
+ const states = await getStatesOfCountry(trimmedCountryCode);
73
+ const validState = states.find(
74
+ (s) =>
75
+ s.iso2 === trimmedStateCode ||
76
+ s.state_code === trimmedStateCode ||
77
+ s.state_code === trimmedStateCode.toUpperCase()
78
+ );
79
+
80
+ if (!validState) {
81
+ return {
82
+ isValid: false,
83
+ error: `Invalid state code: ${stateCode} for country: ${countryCode}`,
84
+ };
85
+ }
86
+ }
87
+ if (trimmedCityName) {
88
+ const cities = await getCitiesOfState(
89
+ trimmedCountryCode,
90
+ trimmedStateCode
91
+ );
92
+ const cityFound = cities.some(
93
+ (city) => city.name.trim().toLowerCase() === trimmedCityName
94
+ );
95
+ if (!cityFound) {
96
+ return {
97
+ isValid: false,
98
+ error: `Invalid city name for state code ${stateCode} and country code ${countryCode}`,
99
+ };
100
+ }
101
+ }
102
+ if (trimmedCountryCallingCode) {
103
+ const countries = await getCountries();
104
+ const validCallingCode = countries.find(
105
+ (country) =>
106
+ country.iso2 === trimmedCountryCode &&
107
+ country.phonecode === trimmedCountryCallingCode
108
+ );
109
+ if (!validCallingCode) {
110
+ return {
111
+ isValid: false,
112
+ error: `Invalid country calling code for country code ${trimmedCountryCode}`,
113
+ };
114
+ }
115
+ }
116
+ }
117
+
118
+ return { isValid: true };
119
+ } catch (err) {
120
+ logger.error("Error during country/state/city validation:", err);
121
+ return {
122
+ isValid: false,
123
+ error: "Error validating country code, state code and city name",
124
+ };
125
+ }
126
+ }
127
+
128
+ module.exports = {
129
+ resolveCountryAndState,
130
+ validateCountryAndState
131
+ };
package/model/City.js DELETED
@@ -1,49 +0,0 @@
1
- const { DataTypes } = require('sequelize');
2
-
3
- module.exports = (sequelize) => {
4
- return sequelize.define('City', {
5
- CityID: {
6
- type: DataTypes.INTEGER,
7
- primaryKey: true,
8
- autoIncrement: true,
9
- allowNull: false
10
- },
11
- CityName: {
12
- type: DataTypes.STRING(100),
13
- allowNull: false
14
- },
15
- CityCode: {
16
- type: DataTypes.STRING(100)
17
- },
18
- StateID: {
19
- type: DataTypes.INTEGER,
20
- references: {
21
- model: 'State',
22
- key: 'StateID'
23
- },
24
- onDelete: 'RESTRICT',
25
- onUpdate: 'CASCADE'
26
- },
27
- CreatedBy: {
28
- type: DataTypes.UUID,
29
- allowNull: false
30
- },
31
- CreatedAt: {
32
- type: DataTypes.DATE,
33
- allowNull: false,
34
- defaultValue: DataTypes.NOW
35
- },
36
- UpdatedBy: {
37
- type: DataTypes.UUID,
38
- allowNull: false
39
- },
40
- UpdatedAt: {
41
- type: DataTypes.DATE,
42
- allowNull: false,
43
- defaultValue: DataTypes.NOW
44
- }
45
- }, {
46
- tableName: 'City',
47
- timestamps: false
48
- });
49
- };
package/model/Country.js DELETED
@@ -1,47 +0,0 @@
1
- const { DataTypes } = require('sequelize');
2
-
3
- module.exports = (sequelize) => {
4
- return sequelize.define('Country', {
5
- CountryID: {
6
- type: DataTypes.INTEGER,
7
- primaryKey: true,
8
- autoIncrement: true,
9
- allowNull: false
10
- },
11
- CountryName: {
12
- type: DataTypes.STRING(100),
13
- allowNull: false
14
- },
15
- CountryCode: {
16
- type: DataTypes.STRING(5),
17
- allowNull: false
18
- },
19
- CreatedBy: {
20
- type: DataTypes.UUID,
21
- allowNull: false
22
- },
23
- CreatedAt: {
24
- type: DataTypes.DATE,
25
- allowNull: false,
26
- defaultValue: DataTypes.NOW
27
- },
28
- UpdatedBy: {
29
- type: DataTypes.UUID,
30
- allowNull: false
31
- },
32
- UpdatedAt: {
33
- type: DataTypes.DATE,
34
- allowNull: false,
35
- defaultValue: DataTypes.NOW
36
- }
37
- }, {
38
- tableName: 'Country',
39
- timestamps: false,
40
- indexes: [
41
- {
42
- unique: true,
43
- fields: ['CountryCode', 'CountryName']
44
- }
45
- ]
46
- });
47
- };
package/model/State.js DELETED
@@ -1,56 +0,0 @@
1
- const { DataTypes } = require('sequelize');
2
-
3
- module.exports = (sequelize) => {
4
- return sequelize.define('State', {
5
- StateID: {
6
- type: DataTypes.INTEGER,
7
- primaryKey: true,
8
- autoIncrement: true,
9
- allowNull: false
10
- },
11
- StateName: {
12
- type: DataTypes.STRING(100),
13
- allowNull: false
14
- },
15
- StateCode: {
16
- type: DataTypes.STRING(100),
17
- allowNull: false
18
- },
19
- CountryID: {
20
- type: DataTypes.INTEGER,
21
- references: {
22
- model: 'Country',
23
- key: 'CountryID'
24
- },
25
- onDelete: 'RESTRICT',
26
- onUpdate: 'CASCADE'
27
- },
28
- CreatedBy: {
29
- type: DataTypes.UUID,
30
- allowNull: false
31
- },
32
- CreatedAt: {
33
- type: DataTypes.DATE,
34
- allowNull: false,
35
- defaultValue: DataTypes.NOW
36
- },
37
- UpdatedBy: {
38
- type: DataTypes.UUID,
39
- allowNull: false
40
- },
41
- UpdatedAt: {
42
- type: DataTypes.DATE,
43
- allowNull: false,
44
- defaultValue: DataTypes.NOW
45
- }
46
- }, {
47
- tableName: 'State',
48
- timestamps: false,
49
- indexes: [
50
- {
51
- unique: true,
52
- fields: ['StateCode', 'StateName']
53
- }
54
- ]
55
- });
56
- };