I tried to run this code with npm start on terminal
//index.js
const api = require('./api');
console.log('Iniciando monitoramento!');
setInterval(async () => {
//console.log(await api.time());
console.log(await api.depth());
}, process.env.CRAWLER_INTERVAL);
//api.js
const axios = require('axios');
const queryString = require('querystring');
async function publicCall(path, data, method = 'GET', headers = {}) {
try {
const qs = data ? `?${queryString.stringify(data)}` : '';
const result = await axios({
method,
url: `${process.env.API_URL}${path}${qs}`
});
return result.data;
} catch (err) {
console.error(err);
}
}
async function time() {
return publicCall('/v3/time');
}
async function depth(symbol = 'BTCBRL', limit = 5) {
return publicCall('/v3/depth', { symbol, limit });
}
and my terminal display this error:
console.log(await api.depth());
^
TypeError: api.depth is not a function
at Timeout._onTimeout (C:\Users\mikae\Desktop\bot-criptomoedas\bot\index.js:6:27)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
I just want to run my aplication to send me informations about cryptocoins market. I'm using API from Binance.
You need to export the function.
export async function depth(symbol = 'BTCBRL', limit = 5) {
return publicCall('/v3/depth', { symbol, limit });
}
and then
import { depth } from '/.api'
Also update your package.json file to include.
"type": "module"
In the tutorial you linked you missed the 25th line:
module.exports = { time, depth }
Paste this in your app.js file and use this as import in index.js
const api = require('./api.js');
Related
Im trying to dynamically load modules from a nitro server in a nuxt app, but I get the following error:
Cannot find module projectpath/.nuxt/services/listing imported from projectpath/.nuxt/dev/index.mjs
This is the snippet of code Im using for the handler where the dynamic import should take place:
export default defineEventHandler(async (event) => {
const { method, resource, paramValue } = parseRequestResource(event.node.req)
let ServiceInstance = services[resource]
if (ServiceInstance) {
return callResourceMethod(ServiceInstance, method, paramValue, event)
} else {
try {
ServiceInstance = await import(`../services/${resource}`)
} catch (error) {
const Proto = Object.assign({}, Service.prototype, { tableName: resource })
ServiceInstance = Object.create(Proto)
services[resource] = ServiceInstance
}
return callResourceMethod(ServiceInstance, method, paramValue, event)
}
})
How can I this to work? Is there some feature that nitro/nuxt have where I can do this?
I was able to achieve this functionality by using a nitro plugin. However the files being imported need to be *.mjs.
import fs from 'fs'
import { resolve } from 'path'
export default defineNitroPlugin(async (nitroApp) => {
const __dirname = resolve()
const servicesFolderPath = `${__dirname}/server/services`
const serviceFiles = fs.readdirSync(servicesFolderPath)
const services = {}
for (const fileName of serviceFiles) {
if (fileName == '__proto__.mjs') continue
try {
const moduleName = fileName.split('.')[0]
const module = await import(`${servicesFolderPath}/${fileName}`)
services[moduleName] = module.default
} catch (error) {
console.log(error);
}
}
nitroApp.$services = services
})
I'm creating a generator that uses your google catchall domain to generate a list of email accounts and how I'm going about it, is that a function will generate a random first & last name from an array and merges it together with the catchall domain. Essentially the result would be fname + lname + domain = johndoe#domain.com, but for some reason I'm getting an error. The terminal says "Fetch is not defined" but when I define it by either the node-fetch package (const fetch = require('node-fetch');, it then says "fetch is not a function". I was attempting to use the built in Fetch API to fetch the data because the script I'm basing it off of instructed to do so, after the terminal said it wasn't defined, I tried using the node-fetch package to define the variable fetch in hopes of it fixing it, but no luck either. Does anyone have a solution on why I'm getting both fetch is not a function and fetch is not defined?
const prompt = require("prompt-sync") ({sigint: true });
const fs = require("fs").promises;
const request = require('request');
// const fetch = require('node-fetch');
const random_useragent = require('random-useragent');
const { Webhook, MessageBuilder } = require('discord-webhook-node');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
( async () => {
const browser = await puppeteer.launch({
headless: false,
executablePath: `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`,
userDataDir: `/Users/bran_d0_n/Library/Application Support/Google/Chrome/Default`,
ignoreHTTPSErrors: true,
ignoreDefaultArgs: ['--enable-automation'],
args: [
`--disable-blink-features=AutomationControlled`,
`--enable-blink-feautres=IdleDetection`,
`--window-size=1920,1080`,
`--disable-features=IsolateOrigins,site-per-process`,
`--blink-settings=imagesEnabled=true`
]
});
//------------------ Random Password Generator Function ------------------//
function generatePassword() {
let pass = '';
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz0123456789##$';
for ( let i = 1; i <= 8; i++) {
var char = Math.floor(Math.random() * str.length + 1);
pass += str.charAt(char)
}
return pass;
}
//------------------ First & Last Name Generator Function ------------------//
async function fetchData(url) {
const response = await fetch(url);
return response.json();
}
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network Response Invalid');
}
return response.json();
} catch (error) {
console.error('Unable To Fetch Data:', error)
}
}
function fetchNames(nameType) {
return fetchData(`https://www.randomlists.com/data/names-${nameType}.json`);
}
function pickRandom(list) {
return list[Math.floor(Math.random() * list.length)];
}
async function generateName(gender) {
try {
const response = await Promise.all ([
fetchNames(gender || pickRandom(['male', 'female'])),
fetchNames('surnames')
]);
const [ firstNames, lastNames] = response;
const firstName = pickRandom(firstNames.data);
const lastName = pickRandom(lastNames.data);
return `${firstName} ${lastName}`;
} catch (error) {
console.error('Unable To Generate Name:', error);
}
}
console.log('Loading Browser...');
// Account Values
var bDayval = '01/05/22' + (Math.floor((Math.random() * ( 99-55 )) + 55 )).toString();
var passwordVal = generatePassword();
var fnameVal = generateName();
var lnameVal = generateName();
var info;
var themessage;
var phoneNum;
var userpass;
Loading and configuring the module
node-fetch from v3 is an ESM-only module - you are not able to import it with require().
If you cannot switch to ESM, please use v2 which remains compatible with CommonJS. Critical bug fixes will continue to be published for v2.
You should either use
import fetch from 'node-fetch';
(Remember to add "type": "module" to the package.json)
Or install the older version
npm install node-fetch#2
i am initializing a node js app with crucial data for the app to work from a database in index.js.
index.ts
import {getInitialData} from 'initData.ts';
export let APP_DATA: AppData;
export const initializeAppData = async () => {
try {
APP_DATA = (await getInitialData()) as AppData;
if (process.env.NODE_ENV !== 'test') {
initializeMongoose();
startServer();
}
} catch (error) {
console.log(error);
}
};
initData.ts
let dbName: string = 'initialData';
if (process.env.NODE_ENV === 'test') {
dbName = 'testDb';
}
const uri = `${process.env.MONGODB_URI}/?maxPoolSize=20&w=majority`;
export async function getInitialData() {
const client = new MongoClient(uri);
try {
await client.connect();
const database = client.db(dbName);
const configCursor = database
.collection('config')
.find({}, { projection: { _id: 0 } });
const config = await configCursor.toArray();
const aaoCursor = database
.collection('aao')
.find({}, { projection: { _id: 0 } });
const aao = await aaoCursor.toArray();
return { config, aao };
} catch {
(err: Error) => console.log(err);
} finally {
await client.close();
}
}
I'm using this array in another file and import it there.
missionCreateHandler
import { APP_DATA } from '../index';
export const addMissionResources = (
alarmKeyword: AlarmKeyword,
newMission: MissionDocument
) => {
const alarmKeywordObject = APP_DATA?.aao.find(
(el) => Object.keys(el)[0] === alarmKeyword
);
const resourceCommand = Object.values(alarmKeywordObject!);
resourceCommand.forEach((el) => {
Object.entries(el).forEach(([key, value]) => {
for (let ii = 1; ii <= value; ii++) {
newMission.resources?.push({
initialType: key,
status: 'unarranged',
});
}
});
});
};
I'm setting up a mongodb-memory-server in globalSetup.ts for Jest and copy the relevant data to the database from json-files.
globalSetup.ts
export = async function globalSetup() {
const instance = await MongoMemoryServer.create({
instance: { dbName: 'testDb' },
});
const uri = instance.getUri();
(global as any).__MONGOINSTANCE = instance;
process.env.MONGODB_URI = uri.slice(0, uri.lastIndexOf('/'));
process.env.JWT_SECRET = 'testSECRET';
const client = new MongoClient(
`${process.env.MONGODB_URI}/?maxPoolSize=20&w=majority`
);
try {
await client.connect();
const database = client.db('testDb');
database.createCollection('aao');
//#ts-ignore
await database.collection('aao').insertMany(aao['default']);
} catch (error) {
console.log(error);
} finally {
await client.close();
}
};
missionCreateHandler.test.ts
test('it adds the correct mission resources to the array', async () => {
const newMission = await Mission.create({
address: {
street: 'test',
houseNr: 23,
},
alarmKeyword: 'R1',
});
const expected = {
initialType: 'rtw',
status: 'unarranged',
};
addMissionResources('R1', newMission);
expect(newMission.resources[0].initialType).toEqual(expected.initialType);
expect(newMission.resources[0].status).toEqual(expected.status);
});
When runing the test, i get an 'TypeError: Cannot convert undefined or null to object at Function.values ()'. So it seems that the APP_DATA object is not set. I checked that the mongodb-memory-server is set up correctly and feed with the needed data.
When i hardcode the content of APP_DATA in index.ts, the test runs without problems.
So my questions are: How is the best practice to set up initial data in a node js app and where to store it (global object, simple variable and import it in the files where needed)? How can the test successfully run, or is my code just untestable?
Thank you!
I keep running into an issue where one of my curried functions is not a function when mocked out according to jest. I made a set of util httpRequest functions in a file called httpRequest.js that looks like this:
const httpRequest = (method) => {
return (headers) => {
return (data) => {
return async (url) => {
try {
const result = await axios({ method, url, data, headers });
const { data: axiosResult } = result;
return axiosResult;
} catch (err) {
console.log(`${method}Data: `, err);
throw err;
}
};
};
};
};
const getData = httpRequest('get')()();
const postData = httpRequest('post')();
const putData = httpRequest('put')();
const patchData = httpRequest('patch')();
const deleteData = httpRequest('delete')()();
const preBuiltGetRequest = httpRequest('get');
const preBuiltPostRequest = httpRequest('post');
const preBuiltPutRequest = httpRequest('put');
const preBuiltPatchRequest = httpRequest('patch');
const preBuiltDeleteRequest = httpRequest('delete');
module.exports = {
httpRequest,
getData,
postData,
putData,
patchData,
deleteData,
preBuiltGetRequest,
preBuiltPostRequest,
preBuiltPutRequest,
preBuiltPatchRequest,
preBuiltDeleteRequest,
};
When I mock out this file in a test and then use a function such as preBuiltGetRequest I get an error on jest saying TypeError: preBuiltGetRequest(...) is not a function. Here is an example of implementation of this.
Here is the function in my codebase I am testing:
queryUser: async (accessToken, email) => {
const query = `
{
getUsersByCriteria(criteria: Email, values: "${email}") {
id
groups {
id
name
entitlements {
id
code
}
members {
total
}
}
}
}
`;
const newUrl = new URL(`${BaseUrl}/v3/graphql`);
newUrl.searchParams.append('query', papiQuery);
console.log('From the Api ', preBuiltGetRequest);
const getAuthenticatedData = preBuiltGetRequest({
Authorization: `Bearer ${accessToken}`,
})();
const response = await getAuthenticatedData(newUrl.toString());
const graphQlResult = response.data?.getUsersByCriteria;
if (!graphQlResult || graphQlResult.length === 0) {
throw new Error(`Could not find user with email=${email}`);
}
return graphQlResult[0];
},
When I then run the test code mocking out preBuiltGetRequest using this code:
jest.mock('/opt/httpRequest');
const { preBuiltGetRequest } = require('/opt/httpRequest');
I receive this error:
The preBuiltGetRequest function has a signature that can be typed as
declare const prebuiltGetRequest: (header: object) => (data: object) => (url: String) => Promise<never>;
You need to mock it accordingly,
jest.mock('/opt/httpRequest');
const { preBuiltGetRequest } = require('/opt/httpRequest');
const mockSig = jest.fn().mockReturnValue(
jest.fn().mockResolvedValueOnce(error)
)
preBuiltGetRequest.mockReturnValue(mockSig)
No matter what I try, I cannot get my data to print as it comes in. I tried this tutorial:
https://jakearchibald.com/2016/streams-ftw/
This SO post: How to handle streaming data using fetch?
(and a several other SO posts I can't recall)
And, tried reading the docs: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams
test.py
import time
import sys
for i in range(1,10):
print('test', i)
time.sleep(.5)
sys.stdout.flush()
server.js
firmwareRouter.get('/run_test', (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-control': 'no-cache' });
const pathToExample = '/server/path/to/test.py';
const { spawn } = require('child_process');
const pythonProcess = spawn('python', [pathToExample]);
pythonProcess.stdout.on('data', (data) => {
// console.log(data.toString());
res.write(data);
});
pythonProcess.on('close', (code) => {
res.end('Process has ended');
});
});
Firmware.js (Version 1)
export default function Firmware(props) {
const [data, setData] = useState('');
async function runTest() {
try {
const url = 'api/firmware/run_test'
const request = {
method: 'GET',
headers: {
'Content-Type': 'text/event-stream'
},
}
const res = await fetch(url, request);
const reader = res.body.getReader();
const chunks = [];
const decoder = new TextDecoder('utf-8');
let done, value;
while (!done) {
({ value, done } = await reader.read());
value = decoder.decode(value);
if (done) {
return chunks;
}
console.log(value);
chunks.push(value);
setData(value);
}
} catch (err) {
console.log('frontend:Firmware', err);
}
}
return (
<Fragment>
{data}
<button onClick={() => runTest()}>Run Test </button>
</Fragment >
)
}
Firmware.js (Version 2)
export default function Firmware(props) {
const [data, setData] = useState('');
async function runTest() {
const url = 'api/firmware/run_test'
const request = {
method: 'GET',
headers: {
'Content-Type': 'text/event-stream'
},
}
fetch(url, request).then((res) => {
let reader = res.body.getReader();
let decoder = new TextDecoder();
reader.read().then(function processResult(result) {
if (result.done) return;
console.log(decoder.decode(result.value, { stream: true }))
return reader.read().then(processResult);
})
})
}
// return ()
No matter what, it only prints to the browser once the process has finished. I need it to print as the python script prints. What am I missing here?
Okay... So, one "solution" is to build it. After I built the app (npm run build), it worked.
Note: I am serving my app from express/node.
It seems to be a webpack or middleware issue between the backend and frontend and using a Proxy. I am going to try to use CORS, turn off React's proxy and go from there.