refactor model structure to remove boilerplate in the main file, created connection with the floriday staging API
This commit is contained in:
parent
9d20ba5314
commit
8473880eb1
|
@ -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.
|
||||
|
|
314
index.js
314
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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
|
@ -16,6 +16,9 @@ const photos = {
|
|||
primary: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
},
|
||||
seasonalPeriodFk: {
|
||||
type: Sequelize.INTEGER,
|
||||
},
|
||||
};
|
||||
|
||||
export default (sequelize) => {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue