Node - Migrate postgres DB programmatically using jest globalsetup.js file - jestjs

I am trying to use testcontainers(https://github.com/testcontainers/testcontainers-node/tree/master/src/modules/postgresql) to spin up a postgres db and use that to run my jest tests.
I used globalsetup.js file to run the container spinup code. The container is spinning successfully, no problem in that, but the issue arises when i try to migrate the db. For Migrating i use typeorm's connection.runMigrations function. Somehow the migration is not working.
All my files, except globalsetup.js is a typescript file.
My connection string looks like this:
createConnection({
url: `postgres://${username}:${encodeURIComponent(password)}#${host}:${port}/${database}`
entities: process.env.TYPEORM_ENTITIES.split(‘,’),
migrations: process.env.TYPEORM_MIGRATIONS?.split(‘,’),
type: 'postgres,
});
TYPEORM_ENTITIES=src/db/entities/**/.ts
TYPEORM_MIGRATIONS=src/db/migrations/.ts
and in my jest.globalSetup.js:
const {createConnection} = require('typeorm')
module.exports = async () => {
/* Code for Container Startup */
process.env.NODE_ENV = ‘test’;
const connection = await createConnection({
url: `postgres://uno-test:dia#localhost:${process.env.TYPEORM_PORT}/cart-test?sslmode=disable`,
entities: process.env.TYPEORM_ENTITIES.split(‘,’),
migrations: process.env.TYPEORM_MIGRATIONS?.split(‘,’),
type: ‘postgres’,
});
await connection
.runMigrations()
.then((value) => console.log(‘Migration Done’, value))
.catch((e) => console.log(e));
await connection
.close()
};
Error Message is:
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from ‘typeorm’;
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1033:15)
at Module._compile (node:internal/modules/cjs/loader:1069:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at /Users/webmaster/CART/cart-portal-service/node_modules/typeorm/util/ImportUtils.js:29:52
at step (/Users/webmaster/CART/cart-portal-service/node_modules/tslib/tslib.js:144:27)
I tried changing the entities and migrations constants to
TYPEORM_ENTITIES=src/db/entities/**/.{ts,js}
TYPEORM_MIGRATIONS=src/db/migrations/.{ts,js}
If i do above chagne, I no longer see the error, but my db is empty as in no tables are created.
Versions:
Node - 16.6.0
Typeorm - 0.2.45
typescript: 4.7.4
jest: 28.1.3

Related

Serving an svg within JSON using NodeJS and ExpressJS

I have a small reactJS app that rendered objects with svg in them:
import { ReactComponent as F01 } from "./F01.svg";
export const toRender = {
title:"Render this",
text:"Test",
SVGFile: F01
}
I would import this into a component and render it as a component <SVGFile />. All was working 100%.
Now the app got bigger and it became inefficient to store the objects in the frontend. I am trying to send the object from an ExpressJS server. I get an error importing the SVG file.
Here is the route I am using, which works well without SVG files:
import {testObject} from "./testObject";
export const getTestObject= {
path: "/api/render",
method: "get",
handler: (req: Request, res: Response) => {
return res.json(testObject);
},
};
And here is the testObject I am sending:
import { F01 } from "./F01.svg";
export const testObject = {
title:"Render this",
text:"Test",
SVGFile: F01
}
But I get an error right after starting tsnode:
SyntaxError: Unexpected token '<'
at Object.compileFunction (node:vm:360:18)
at wrapSafe (node:internal/modules/cjs/loader:1084:15)
at Module._compile (node:internal/modules/cjs/loader:1119:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1209:10)
at Object.require.extensions.<computed> [as .js] (D:\desktop\codebases\360ExamPrep\backend\node_modules\ts-node\src\index.ts:1608:43)
at Module.load (node:internal/modules/cjs/loader:1033:32)
at Function.Module._load (node:internal/modules/cjs/loader:868:12)
at Module.require (node:internal/modules/cjs/loader:1057:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> ....
I am not using webpack on the backend.
I tried using const F01 = require('./F01.svg) but that did not help.
Any help is highly appreciated

I'm dealing with an issue in Axios (in my code). What do I do?

So, I was trying to create a simple web scraper to extract data from Wikipedia using Node.js, and I used Axios & JSDOM to do it.
When I tried to run it, this was the message I received on my Terminal:
Timothy#Arthurs-MacBook-Air-2 ~ % node scraper.js
/Users/Timothy/scraper.js:1
import axios from 'axios';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
For reference, I'm using Visual Studio Code on macOS Big Sur, and this is the full reference code for my web scraper (in case it's necessary):
import axios from 'axios';
let jsdom;
jsdom = require('jsdom');
({ jsdom } = jsdom);
axios
.get('https://en.wikipedia.org/wiki/Fauna_of_Scotland');
.then(function ({ data: html }) {
const { document } = new jsdom(html).window;
const nickname = document.querySelector('.mammal');
if (nickname)
console.log(nickname.textContent);
});
.catch(e => {
console.log(e)
});
The Axios documentation doesn't seem to provide any guidance on these error messages, and neither does the JSDOM readme either.
I'd love some help on how to remove the error message, please, as well as where to look further into the matter! Thanks!
i don't have enough reputation to comment
seems the problem is not with axios, check if this can solve your problem: "Uncaught SyntaxError: Cannot use import statement outside a module" when importing ECMAScript 6

Knex: How to fix "Cannot read property 'prototype' of undefined" on ARM for initial-setup

I am trying to initialize a sqlite3 database with knex on an ARM-Device, but getting the error:
Knex: run
$ npm install sqlite3 --save
TypeError: Cannot read property 'prototype' of undefined
at inherits (/home/user/node_modules/sqlite3/lib/sqlite3.js:27:16)
at Object.<anonymous> (/home/user/node_modules/sqlite3/lib/sqlite3.js:66:1)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Client_SQLite3._driver (/home/user/sWave-Gateway/node_modules/knex/lib/dialects/sqlite3/index.js:79:12)
at Client_SQLite3.initializeDriver (/home/user/sWave-Gateway/node_modules/knex/lib/client.js:254:26)
at Client_SQLite3.Client (/home/user/sWave-Gateway/node_modules/knex/lib/client.js:115:10)
at new Client_SQLite3 (/home/user/sWave-Gateway/node_modules/knex/lib/dialects/sqlite3/index.js:62:20)
at Knex (/home/user/node_modules/knex/lib/index.js:60:34)
at Object.<anonymous> (/home/user/dist/db/knex-data-access-layer/index.js:28:28)
at Module._compile (module.js:653:30)
I already tried to set the NODE_ENV in different ways set the rights of the files with chmod to 777 but nothing worked so far. I am kind of despaired because i have not changed anything on this part for a long time and it suddenly stopped working.
The Command i use:
NODE_ENV=production node dist/initial-setup.js
It executes the following code:
import * as config from 'config';
import * as crypto from 'crypto';
import * as fs from 'fs';
import * as mkdirp from 'mkdirp';
import * as path from 'path';
import { boot } from './boot';
import * as constants from './constants';
import { dataAccessLayer } from './db';
import * as shell from 'shelljs';
// tslint:disable:no-console
boot();
let logPath: string = config.get(constants.CONFIG_LOG_DIR);
if (!fs.existsSync(logPath)) {
console.log(`Creating logs directory at ${logPath} ...`);
mkdirp.sync(logPath);
}
let secretDirPath: string = config.get(constants.CONFIG_SECRET_DIR);
if (!fs.existsSync(secretDirPath)) {
console.log(`Creating secret directory at ${secretDirPath} ...`);
mkdirp.sync(secretDirPath);
}
let jwtSecret: string = crypto.randomBytes(config.get(constants.CONFIG_JWT_RANDOM_BYTES)).toString('hex');
let jwtSecretPath: string = path.join(secretDirPath, config.get(constants.CONFIG_JWT_SECRET_FILE));
fs.writeFileSync(jwtSecretPath, jwtSecret, 'utf8');
async function setupDb(): Promise<void> {
await dataAccessLayer.migrate();
try {
await dataAccessLayer.seed();
} catch (e) {
// ignore missing production seeds, rethrow otherwise
if (e.toString().indexOf('volatile-seeds/production') === -1) {
throw e;
}
}
}
setupDb().catch(e => console.log(e))
.then(()=> {
shell.exec('tskill node');
});
The problem was that the newest sqlite3 4.0.8 version will not work correctly on this ARM-processor. I downgraded it to 4.0.6 and now it works flawless.
I also had this problem when upgrading from sqlite3 version 4.0.4 to version 4.1.0. Pinning my dependency to 4.0.4 got it working again. You can also see some other workarounds here and here, and discussion of usage in browser environments here.

Extend SchemaDirectiveVisitor To Use Apollo Server Schema Directives in NodeJS

I'm trying to extend SchemaDirectiveVisitor in order to make a custom directive in Apollo Server 2. I'm specifically using the 2.2.6 hapi node module.
Here's my server.js code:
const { ApolloServer } = require('apollo-server-hapi');
const { SchemaDirectiveVisitor } = ApolloServer;
class ViewTemplateGroup extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
console.log('Im calling this directive!');
return;
}
}
When I start up my server I immediately get the following error:
TypeError: Class extends value undefined is not a constructor or null
at Object.<anonymous> (/Users/garrett.kim/Desktop/Projects/Test Web/poc-graphQL-forms-gyk/server.js:36:33)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Function.Module.runMain (module.js:701:10)
at startup (bootstrap_node.js:193:16)
at bootstrap_node.js:617:3
To my knowledge, I'm following the Apollo Server 2 example very closely.
https://www.apollographql.com/docs/apollo-server/features/creating-directives.html
Any help getting directives working would be appreciated.
The ApolloServer class does not have a SchemaDirectiveVisitor property on it; therefore, calling ApolloServer.SchemaDirectiveVisitor results in undefined and a class cannot extend undefined as the error indicates. Just import SchemaDirectiveVisitor directly from the apollo-server-hapi module:
const { ApolloServer, SchemaDirectiveVisitor } = require('apollo-server-hapi')

Vuex without Vue?

I'd like to use Vuex to power a server-side application that doesn't use Vue. Is this possible?
const Vuex = require('vuex');
const store = new Vuex.Store({
state: {
potatoes: 1,
},
getters: {
doublePotatoes(state) {
return state.potatoes * 2;
},
},
mutations: {
addPotato(state) {
state.potatoes += 1;
},
}
});
store.watch((state, getters) => getters.doublePotatoes, console.log);
store.commit("addPotato");
Here's the error I get:
$ node index.js
/private/tmp/vtest/node_modules/vuex/dist/vuex.common.js:99
if (!condition) { throw new Error(("[vuex] " + msg)) }
^
Error: [vuex] must call Vue.use(Vuex) before creating a store instance.
at assert (/private/tmp/vtest/node_modules/vuex/dist/vuex.common.js:99:27)
at new Store (/private/tmp/vtest/node_modules/vuex/dist/vuex.common.js:279:5)
at Object.<anonymous> (/private/tmp/vtest/index.js:3:15)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
I wound up adding Vue without creating a Vue app:
const Vue = require('vue');
Vue.use(Vuex);
My tiny test store works now. I don't know if Vue.use(Vuex) without creating a Vue app will cause any problems.
Of note for server-side use cases, Vuex doesn't call my watcher for every commit; it batches changes and calls the watcher once. I don't see this documented.

Resources