From 8473880eb1b8b85ec85f3ad6a292babc88d8e777 Mon Sep 17 00:00:00 2001 From: Pau Navarro Date: Mon, 19 Dec 2022 13:21:35 +0100 Subject: [PATCH] refactor model structure to remove boilerplate in the main file, created connection with the floriday staging API --- README.md | 2 +- index.js | 314 +++++++++++++++-------------------------- models/clientConfig.js | 33 +++++ models/index.js | 33 +++++ models/photos.js | 3 + package-lock.json | 146 +++++++++---------- package.json | 2 +- 7 files changed, 251 insertions(+), 282 deletions(-) create mode 100644 models/clientConfig.js create mode 100644 models/index.js diff --git a/README.md b/README.md index 7dd4202..4aa7cbd 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The Floriday service project should perform the following tasks: 1. Create / mantain the table structure to allow the storage of the data provided by the Floriday API. This is done using the [Sequelize](https://sequelize.org/) ORM. 2. Query the Floriday API and store the data in the database. - This is done using the [Axios](https://axios-http.com/) module. + This is done using the [node-fetch](https://www.npmjs.com/package/node-fetch) package. 2.1. The data is requested every minute, but only the data that has changed is stored in the database. This is done using the [Sequelize](https://sequelize.org/) ORM and storing the data as it is received from the API, so it can be compared with the previous data. diff --git a/index.js b/index.js index 13eff3d..68893e4 100644 --- a/index.js +++ b/index.js @@ -1,219 +1,39 @@ -import { Sequelize } from "sequelize"; -import TradeItem from "./models/tradeItem.js"; -import Characteristics from "./models/characteristics.js"; -import SeasonalPeriod from "./models/seasonalPeriod.js"; -import Photos from "./models/photos.js"; -import PackagingConfigurations from "./models/packagingConfigurations.js"; -import Package from "./models/package.js"; -import AdditionalPricePerPiece from "./models/additionalPricePerPiece.js"; -import BotanicalNames from "./models/botanicalNames.js"; -import CountryOfOriginIsoCodes from "./models/countryOfOriginIsoCodes.js"; +import fetch from "node-fetch"; +import moment from "moment"; -let sequelize = new Sequelize("edi", "root", "root", { - host: "localhost", - dialect: "mariadb", - logging: false, -}); +const _accessTokenEndpoint = + "https://idm.staging.floriday.io/oauth2/ausmw6b47z1BnlHkw0h7/v1/token"; -const tradeItemModel = TradeItem(sequelize); -const characteristicsModel = Characteristics(sequelize); -const seasonalPeriodModel = SeasonalPeriod(sequelize); -const photosModel = Photos(sequelize); -const packagingConfigurationsModel = PackagingConfigurations(sequelize); -const packageModel = Package(sequelize); -const additionalPricePerPieceModel = AdditionalPricePerPiece(sequelize); -const botanicalNamesModel = BotanicalNames(sequelize); -const countryOfOriginIsoCodesModel = CountryOfOriginIsoCodes(sequelize); +import models from "./models/index.js"; -try { - // Just there to hide the mock data insertion - characteristicsModel.belongsTo(tradeItemModel, { - foreignKey: "tradeItemFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - seasonalPeriodModel.belongsTo(tradeItemModel, { - foreignKey: "tradeItemFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - photosModel.belongsTo(tradeItemModel, { - foreignKey: "tradeItemFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - photosModel.belongsTo(seasonalPeriodModel, { - foreignKey: "seasonalPeriodFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - packagingConfigurationsModel.belongsTo(tradeItemModel, { - foreignKey: "tradeItemFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - packageModel.belongsTo(packagingConfigurationsModel, { - foreignKey: "packingConfigurationsFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - additionalPricePerPieceModel.belongsTo(packagingConfigurationsModel, { - foreignKey: "packingConfigurationsFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - botanicalNamesModel.belongsTo(tradeItemModel, { - foreignKey: "tradeItemFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - countryOfOriginIsoCodesModel.belongsTo(tradeItemModel, { - foreignKey: "tradeItemFk", - targetKey: "id", - onDelete: "CASCADE", - onUpdate: "CASCADE", - }); - - await sequelize.sync({ - // alter: true, - force: true, - }); - - const tradeItem = await tradeItemModel.create({ - tradeItemId: "123", - supplierOrganizationId: "123", - code: "123", - gtin: "123", - vbnProductCode: "123", - name: "123", - isDeleted: false, - sequenceNumber: 1, - tradeItemVersion: 1, - isCustomerSpecific: false, - isHiddenInCatalog: false, - }); - const characteristics1 = await characteristicsModel.create({ - tradeItemFk: tradeItem.id, - vnbCode: "123", - vnbValueCode: "123", - }); - const characteristics2 = await characteristicsModel.create({ - tradeItemFk: tradeItem.id, - vnbCode: "234", - vnbValueCode: "234", - }); - const seasonalPeriod1 = await seasonalPeriodModel.create({ - tradeItemFk: tradeItem.id, - startWeek: "40", - endWeek: "42", - }); - const seasonalPeriod2 = await seasonalPeriodModel.create({ - tradeItemFk: tradeItem.id, - startWeek: "43", - endWeek: "45", - }); - const photos1 = await photosModel.create({ - tradeItemFk: tradeItem.id, - seasonalPeriodFk: seasonalPeriod1.id, - photoId: "123", - url: "123", - type: "123", - primary: false, - }); - const photos2 = await photosModel.create({ - tradeItemFk: tradeItem.id, - seasonalPeriodFk: seasonalPeriod2.id, - photoId: "234", - url: "234", - type: "234", - primary: false, - }); - const packagingConfigurations1 = await packagingConfigurationsModel.create({ - tradeItemFk: tradeItem.id, - piecesPerPackage: 1, - bunchesPerPackage: 1, - photoUrl: photos1.url, - }); - const packagingConfigurations2 = await packagingConfigurationsModel.create({ - tradeItemFk: tradeItem.id, - piecesPerPackage: 2, - bunchesPerPackage: 2, - photoUrl: photos2.url, - }); - const package1 = await packageModel.create({ - packingConfigurationsFk: packagingConfigurations1.id, - vbnPackageCode: "123", - customPackageId: "123", - }); - const package2 = await packageModel.create({ - packingConfigurationsFk: packagingConfigurations2.id, - vbnPackageCode: "234", - customPackageId: "234", - }); - const additionalPricePerPiece1 = await additionalPricePerPieceModel.create({ - packingConfigurationsFk: packagingConfigurations1.id, - value: 1, - currency: "EUR", - }); - const additionalPricePerPiece2 = await additionalPricePerPieceModel.create({ - packingConfigurationsFk: packagingConfigurations2.id, - value: 2, - currency: "USD", - }); - const botanicalNames1 = await botanicalNamesModel.create({ - tradeItemFk: tradeItem.id, - name: "test123", - }); - const botanicalNames2 = await botanicalNamesModel.create({ - tradeItemFk: tradeItem.id, - name: "test234", - }); - const countryOfOriginIsoCodes1 = await countryOfOriginIsoCodesModel.create({ - tradeItemFk: tradeItem.id, - isoCode: "ES", - }); - const countryOfOriginIsoCodes2 = await countryOfOriginIsoCodesModel.create({ - tradeItemFk: tradeItem.id, - isoCode: "DE", - }); -} catch (error) { - console.log(error); -} +const AccessToken = getClientToken(); try { // Every 30 sec query the database setInterval(async () => { console.log("Querying the API to check for new data..."); - const query = tradeItemModel.findAll({ + const query = models.tradeItem.findAll({ include: [ { - model: characteristicsModel, - association: tradeItemModel.hasMany(characteristicsModel, { + model: models.characteristics, + association: models.tradeItem.hasMany(models.characteristics, { foreignKey: "tradeItemFk", sourceKey: "id", }), as: "characteristics", }, { - model: photosModel, - association: tradeItemModel.hasMany(photosModel, { + model: models.photos, + association: models.tradeItem.hasMany(models.photos, { foreignKey: "tradeItemFk", sourceKey: "id", }), as: "photos", include: [ { - model: seasonalPeriodModel, - association: photosModel.hasOne(seasonalPeriodModel, { + model: models.seasonalPeriod, + association: models.photos.hasOne(models.seasonalPeriod, { foreignKey: "id", sourceKey: "seasonalPeriodFk", }), @@ -222,25 +42,25 @@ try { ], }, { - model: packagingConfigurationsModel, - association: tradeItemModel.hasMany(packagingConfigurationsModel, { + model: models.packagingConfigurations, + association: models.tradeItem.hasMany(models.packagingConfigurations, { foreignKey: "tradeItemFk", sourceKey: "id", }), as: "packagingConfigurations", include: [ { - model: packageModel, - association: packagingConfigurationsModel.hasOne(packageModel, { + model: models.package, + association: models.packagingConfigurations.hasOne(models.package, { foreignKey: "packingConfigurationsFk", sourceKey: "id", }), as: "package", }, { - model: additionalPricePerPieceModel, - association: packagingConfigurationsModel.hasOne( - additionalPricePerPieceModel, + model: models.additionalPricePerPiece, + association: models.packagingConfigurations.hasOne( + models.additionalPricePerPiece, { foreignKey: "packingConfigurationsFk", sourceKey: "id", @@ -251,16 +71,16 @@ try { ], }, { - model: botanicalNamesModel, - association: tradeItemModel.hasMany(botanicalNamesModel, { + model: models.botanicalNames, + association: models.tradeItem.hasMany(models.botanicalNames, { foreignKey: "tradeItemFk", sourceKey: "id", }), as: "botanicalNames", }, { - model: countryOfOriginIsoCodesModel, - association: tradeItemModel.hasMany(countryOfOriginIsoCodesModel, { + model: models.countryOfOriginIsoCodes, + association: models.tradeItem.hasMany(models.countryOfOriginIsoCodes, { foreignKey: "tradeItemFk", sourceKey: "id", }), @@ -276,3 +96,89 @@ try { } catch (error) { console.error("Unable to connect to the database:", error); } + +async function getClientToken() { + + let clientConfigData = await models.clientConfig.findAll(); + + const now = moment().format("YYYY-MM-DD HH:mm:ss"); + const tokenExpirationDate = clientConfigData[0].tokenExpiration; + + console.log("tokenExpirationDate: ", tokenExpirationDate); + + if ( + clientConfigData[0].tokenExpiration == null || + moment(now).isAfter(tokenExpirationDate) + ) { + console.log("Getting a new token..."); + + let clientId = clientConfigData[0].clientId; + let clientSecret = clientConfigData[0].clientSecret; + + const tokenRequest = await fetch(_accessTokenEndpoint, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: `grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}&scope=role:app catalog:read`, + }); + + const tokenResponse = await tokenRequest.json(); + + const accessToken = tokenResponse.access_token; + let now = moment().format("YYYY-MM-DD HH:mm:ss"); + + let tokenExpirationDate = moment(now) + .add(tokenResponse.expires_in, "s") + .format("YYYY-MM-DD HH:mm:ss"); + console.log(tokenResponse); + console.log("now: ", now); + console.log("tokenExpirationDate: ", tokenExpirationDate); + + updateClientConfig( + clientId, + clientSecret, + accessToken, + tokenExpirationDate + ); + + return accessToken; + } else { + console.log("Using the current token..."); + return clientConfigData[0].currentToken; + } +} + +async function updateClientConfig( + clientId, + clientSecret, + accessToken, + tokenExpirationDate +) { + try { + await models.clientConfig.update( + { + clientId: clientId, + clientSecret: clientSecret, + currentToken: accessToken, + tokenExpiration: tokenExpirationDate, + }, + { + where: { + id: 1, + }, + } + ); + console.log("Client config updated, new Token set"); + console.log("New token expiration date: ", tokenExpirationDate ); + } catch (error) { + console.log("There was a error while updating the client config"); + console.log(error); + } +} + +console.log = function () { + var args = Array.prototype.slice.call(arguments); + args.unshift(new moment().format("HH:mm:ss") + " -"); + console.info.apply(console, args); +}; diff --git a/models/clientConfig.js b/models/clientConfig.js new file mode 100644 index 0000000..050b6eb --- /dev/null +++ b/models/clientConfig.js @@ -0,0 +1,33 @@ +import { Sequelize } from "sequelize"; + +const clientConfig = { + id: { + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true, + }, + clientId: { + type: Sequelize.STRING, + }, + clientSecret: { + type: Sequelize.STRING, + }, + currentToken: { + type: Sequelize.STRING, + }, + tokenExpiration: { + type: Sequelize.STRING, + }, +}; + +export default (sequelize) => { + const ClientConfig = sequelize.define( + "FDClientConfig", + clientConfig, + { + timestamps: false, + freezeTableName: true, + } + ); + return ClientConfig; +}; diff --git a/models/index.js b/models/index.js new file mode 100644 index 0000000..7fde677 --- /dev/null +++ b/models/index.js @@ -0,0 +1,33 @@ +import { Sequelize } from "sequelize"; + +let sequelize = new Sequelize("edi", "root", "root", { + host: "localhost", + dialect: "mariadb", + logging: false, +}); + +import additionalPricePerPiece from "./additionalPricePerPiece.js"; +import botanicalNames from "./botanicalNames.js"; +import countryOfOriginIsoCodes from "./countryOfOriginIsoCodes.js"; +import packageModel from "./package.js"; +import packagingConfigurations from "./packagingConfigurations.js"; +import photos from "./photos.js"; +import seasonalPeriod from "./seasonalPeriod.js"; +import tradeItem from "./tradeItem.js"; +import clientConfig from "./clientConfig.js"; +import characteristics from "./characteristics.js"; + +let models = { + additionalPricePerPiece: additionalPricePerPiece(sequelize), + botanicalNames: botanicalNames(sequelize), + countryOfOriginIsoCodes: countryOfOriginIsoCodes(sequelize), + package: packageModel(sequelize), + packagingConfigurations: packagingConfigurations(sequelize), + photos: photos(sequelize), + seasonalPeriod: seasonalPeriod(sequelize), + tradeItem: tradeItem(sequelize), + clientConfig: clientConfig(sequelize), + characteristics: characteristics(sequelize), +}; + +export default models; \ No newline at end of file diff --git a/models/photos.js b/models/photos.js index 9e6fded..5a0731b 100644 --- a/models/photos.js +++ b/models/photos.js @@ -16,6 +16,9 @@ const photos = { primary: { type: Sequelize.BOOLEAN, }, + seasonalPeriodFk: { + type: Sequelize.INTEGER, + }, }; export default (sequelize) => { diff --git a/package-lock.json b/package-lock.json index aff690b..d9b5461 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,9 +6,9 @@ "": { "name": "floriday", "dependencies": { - "axios": "^1.2.0", "mariadb": "^3.0.2", "moment": "^2.29.4", + "node-fetch": "^3.3.0", "sequelize": "^6.26.0" } }, @@ -40,30 +40,12 @@ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.10.tgz", "integrity": "sha512-t1yxFAR2n0+VO6hd/FJ9F2uezAZVWHLmpmlJzm1eX03+H7+HsuTAp7L8QJs+2pQCfWkP1+EXsGK9Z9v7o/qPVQ==" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.0.tgz", - "integrity": "sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", "engines": { - "node": ">= 0.8" + "node": ">= 12" } }, "node_modules/debug": { @@ -82,14 +64,6 @@ } } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -103,36 +77,37 @@ "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", "funding": [ { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" } ], - "engines": { - "node": ">=4.0" + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "engines": { + "node": "^12.20 || >= 14.13" } }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "fetch-blob": "^3.1.2" }, "engines": { - "node": ">= 6" + "node": ">=12.20.0" } }, "node_modules/iconv-lite": { @@ -183,25 +158,6 @@ "node": ">= 12" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -226,16 +182,46 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz", + "integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/pg-connection-string": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "node_modules/retry-as-promised": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-6.1.0.tgz", @@ -361,6 +347,14 @@ "node": ">= 0.10" } }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + }, "node_modules/wkx": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", diff --git a/package.json b/package.json index 2d23928..25b6787 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,9 @@ "start": "node index.js" }, "dependencies": { - "axios": "^1.2.0", "mariadb": "^3.0.2", "moment": "^2.29.4", + "node-fetch": "^3.3.0", "sequelize": "^6.26.0" } }