Problem with app update yml files is not generated in electron? - node.js

I have a problem with the auto-update of electron app,
After I finished all the app parts and I am trying to push it to my custom update server , I found this error message in my logger :
Error unknown ENOENT: no such file or directory, open
'C:\{appPath}\{appName}\resources\app-update.yml'
and here is my package.json build configuration
"build": {
"appId": "com.server.app",
"copyright": "Copyright company name",
"generateUpdatesFilesForAllChannels": true,
"win": {
"target": "nsis",
"icon": "build/icon.ico"
},
"mac": {
"target": "dmg",
"artifactName": "appName.dmg",
"icon": "build/icon.icns"
},
"dmg": {
"background": "build/i-bg.tif",
"icon": "build/setup.icns",
"iconSize": 80,
"title": "${productName}-${version}",
"window": {
"width": 540,
"height": 380
}
},
"nsis": {
"artifactName": "${productName}-Setup-${version}.${ext}",
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": true,
"installerIcon": "build/setup.ico",
"uninstallerIcon": "build/setup.ico",
"installerHeader": "build/installerHeader.bmp",
"installerSidebar": "build/installerSidebar.bmp",
"runAfterFinish": true,
"deleteAppDataOnUninstall": true,
"createDesktopShortcut": "always",
"createStartMenuShortcut": true,
"shortcutName": "AppName",
"publish": [{
"provider": "generic",
"url": "https://my-update-server/path"
}]
},
"extraFiles": [
"data",
"templates"
]
},
"publish": [{
"provider": "generic",
"url": "https://my-update-server/path"
}],
and here is the code for triggering the auto-update
//-----------------------------------------------
// Auto-Update event listening
//-----------------------------------------------
autoUpdater.on('checking-for-update', () => {
splashLoadingStatus(`Checking for ${appName} update ...`);
})
autoUpdater.on('update-available',(info) => {
splashLoadingStatus(`${appName} new update available.`);
})
autoUpdater.on('update-progress',(progInfo) => {
splashLoadingStatus(`Download speed: ${progInfo.bytesPerSecond} - Download ${progInfo.percent}% (${progInfo.transferred}/${progInfo.total})`);
})
autoUpdater.on('error' , (error) => {
dialog.showErrorBox('Error', error.message);
})
autoUpdater.on('update-downloaded', (info) => {
const message = {
type: 'info',
buttons: ['Restart', 'Update'],
title: `${appName} Update`,
detail: `A new version has been downloaded. Restart ${appName} to apply the updates.`
}
dialog.showMessageBox(message, (res) => {
if(res === 0) {
autoUpdater.quitAndInstall();
}
})
})
.....
autoUpdater.setFeedURL('https://my-update-server/path');
autoUpdater.checkForUpdatesAndNotify();
.....
then when I am pushing the build it will do everything correct with the latest.yml file generating but after installing I found the app-update.yml is not there ...

If you have a problem with missing app-update.yml and dev-app-update.yml then paste the following code into index.js:
import path from "path"
import fs from "fs"
const feed = 'your_site/update/windows_64'
let yaml = '';
yaml += "provider: generic\n"
yaml += "url: your_site/update/windows_64\n"
yaml += "useMultipleRangeRequest: false\n"
yaml += "channel: latest\n"
yaml += "updaterCacheDirName: " + app.getName()
let update_file = [path.join(process.resourcesPath, 'app-update.yml'), yaml]
let dev_update_file = [path.join(process.resourcesPath, 'dev-app-update.yml'), yaml]
let chechFiles = [update_file, dev_update_file]
for (let file of chechFiles) {
if (!fs.existsSync(file[0])) {
fs.writeFileSync(file[0], file[1], () => { })
}
}

I fixed it by using autoUpdater.setFeedURL() before autoUpdater.checkForUpdates(). Below is the code snippet that works for github releases. Also, please make sure there is existing release in Github before running this code.
import { autoUpdater } from "electron-updater";
// ...
autoUpdater.setFeedURL({
provider: "github",
owner: "org",
repo: "repo",
});

Related

NG0203 error for deployed microfrontend project

I am working on microfrontend. using module federation. shell and the remote projects have different repositories and are deployed on different servers. below are the code
shell project : calling the remote project through routing
{
path: 'analytics',
loadChildren: () => loadRemoteModule({
remoteEntry: `${environment.analyticsServerUrl}/remoteEntry.js`,
type: 'module',
exposedModule: './AnalyticsModule' })
.then(m => m.AppModule)
},
shell project : webpack.config.js
const webpack = require('webpack');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
output: {
publicPath: 'http://localhost:4200/',
uniqueName: 'o360',
scriptType: 'text/javascript',
},
optimization: {
runtimeChunk: false,
},
plugins: [
new ModuleFederationPlugin({
remotes: {
analytics: 'http://localhost:4201',
},
shared: {
'#angular/core': {
eager: true,
singleton: true
},
'#angular/common': {
eager: true,
singleton: true
},
'#angular/router': {
eager: true,
singleton: true
},
'#ngxs/store': {
singleton: true,
eager: true
},
'social-login': {
singleton: true,
eager: true
},
},
}),
],
};
remote project :
webpack.config.js :
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("#angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
path.join(__dirname, 'tsconfig.json'), [ /* mapped paths to share */ ]);
module.exports = {
output: {
uniqueName: "analytics",
publicPath: 'http://localhost:4201/'
},
optimization: {
runtimeChunk: false
},
resolve: {
alias: {
...sharedMappings.getAliases(),
}
},
experiments: {
outputModule: true
},
plugins: [
new ModuleFederationPlugin({
library: {
type: "module"
},
name: "analytics",
filename: "remoteEntry.js",
exposes: {
'./AnalyticsModule': './src/app/app.module.ts',
},
shared: share({
"#angular/core": {
singleton: true,
eager: true
},
"#angular/common": {
singleton: true,
eager: true
},
"#angular/common/http": {
singleton: true,
eager: true
},
"#angular/router": {
singleton: true,
eager: true
},
"shared-lib": {
singleton: true,
eager: true
},
...sharedMappings.getDescriptors()
})
}),
sharedMappings.getPlugin()
],
};
individually they are working fine after deployment to their respective servers but when I am trying to open the remote project through the shell project then below error is seen in the console.
Error: Uncaught (in promise): Error: NG0203
Error: NG0203
at Fy (remoteEntry.js:1:109371)
at Nt (remoteEntry.js:1:109522)
at e.ɵfac [as factory] (remoteEntry.js:1:256984)
at R1.hydrate (vendor.c5829c2ac166cc04.js:1:4138001)
at R1.get (vendor.c5829c2ac166cc04.js:1:4135925)
at vendor.c5829c2ac166cc04.js:1:4136752
at Set.forEach (<anonymous>)
at R1._resolveInjectorDefTypes (vendor.c5829c2ac166cc04.js:1:4136736)
at new Fx (vendor.c5829c2ac166cc04.js:1:4174507)
at db.create (vendor.c5829c2ac166cc04.js:1:4175218)
at z (polyfills.b96b59aa4b290638.js:1:15990)
at z (polyfills.b96b59aa4b290638.js:1:15525)
at polyfills.b96b59aa4b290638.js:1:16838
at v.invokeTask (polyfills.b96b59aa4b290638.js:1:7185)
at Object.onInvokeTask (vendor.c5829c2ac166cc04.js:1:4191629)
at v.invokeTask (polyfills.b96b59aa4b290638.js:1:7106)
at M.runTask (polyfills.b96b59aa4b290638.js:1:2580)
at _ (polyfills.b96b59aa4b290638.js:1:9200)
as NG0203 is an error related inject() function which I am not using anywhere in both applications but still getting this error so seems something is getting injected post loading of the module. I was exposing specific module analyticsModule before but later exposed the root module appModule but still the same error. tried using preloading and other solutions give on the internet but still the same error.

unhandledRejection The "path" argument must be of type string or an instance of Buffer or URL. Received undefined - Nuxtjs

When I try to build or run nuxi dev to start my application for development this error comes up and application don't work properly.
I deleted all lock files, removed module folder and run yarn install but this is still there,
This is the exception trace info from compiler.
at readFileSync (node:fs:453:35)
at extractMeta (node_modules\nuxt-route-meta\dist\index.js:52:51)
at parseRoutes (node_modules\nuxt-route-meta\dist\index.js:149:57)
at /D:/Frontend/nuxt2/node_modules/#nuxt/kit/dist/index.mjs:477:37
at /D:/Frontend/nuxt2/node_modules/hookable/dist/index.mjs:39:70
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Object.getContents (/D:/Frontend/nuxt2/node_modules/nuxt3/dist/chunks/index.mjs:348:9)
at async /D:/Frontend/nuxt2/node_modules/nuxt3/dist/chunks/index.mjs:1338:22
at async Promise.all (index 16)
Here is the .env file
BASE_URL=http://localhost:8000
ECHO_PORT=
HOSTNAME=http://localhost:3000
STRIPE_KEY=x
ALGOLIA_APP_ID=y
ALGOLIA_API_KEY=z
And here is the nuxt.config.ts file content.
import getSiteMeta from './utils/getSiteMeta'
import { cloneDeep } from 'lodash'
const meta = getSiteMeta()
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
ssr: false,
// server: {
// host: process.env.HOST || 'localhost' // default: localhost
// },
sitemap: [
{
hostname: process.env.BASE_URL || 'http://localhost:3000',
path: '/sitemap.xml',
gzip: true,
},
],
// Global page headers (https://go.nuxtjs.dev/config-head)
head: {
htmlAttrs: {
lang: 'en-GB',
},
title:
'Family Tree 365 - Start your family tree today - free! Your first tree is 100% free. Sign-up to begin your genealogy journey today!',
meta: [
...meta,
{ charset: 'utf-8' },
{ name: 'HandheldFriendly', content: 'True' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ property: 'og:site_name', content: 'Family Tree 365' },
{
hid: 'description',
name: 'description',
content:
'Our user-friendly yet powerful platform lets you create your own family tree the quick and easy way. No technical knowledge is required. Start your family tree today - free!',
},
{ property: 'og:image:width', content: '2500' },
{ property: 'og:image:height', content: '780' },
{ name: 'twitter:site', content: '#familytree365' },
{ name: 'twitter:card', content: 'summary_large_image' },
],
link: [
{ rel: 'icon', href: '/favicon.ico' },
{
hid: 'canonical',
rel: 'canonical',
href: process.env.BASE_URL,
},
],
},
// Global CSS: https://go.nuxtjs.dev/config-css
// css: ["~/assets/style/enso.scss", "animate.css/animate.compat.css"],
css: [
'animate.css/animate.compat.css',
'~/assets/css/base.css',
'~/assets/style/enso.scss',
'~/assets/css/fontawesome.min.css',
],
router: {
middleware: 'auth'
},
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
'~/plugins/bootEnums.js',
'~/plugins/i18n.js',
'~/plugins/pRoute.js',
'~/plugins/filters.js',
'~/plugins/numberFormat.js',
'~/plugins/shortNumber.js',
'~/plugins/toastr.js',
'~/plugins/fontawesome.js',
'~/plugins/themesSettingRegister.js',
'~/plugins/bookmarksSettingRegister.js',
'~/plugins/tutorialSettingRegister.js',
'~/plugins/notificationsRegister.js',
'~/plugins/localisationRegister.js',
'~/plugins/ioRegister.js',
'~/plugins/tasksNavbarRegister.js',
'~/plugins/usersRegister.js',
'~/plugins/Validator.js',
'~/plugins/date-fns/format.js',
'~/plugins/date-fns/formatDistance.js',
'~/plugins/vue-select.js',
'~/plugins/vuelidate.js',
'~/plugins/vue-gtag.client.js',
//'~/plugins/echo.js',
"~/plugins/vue-fb-customer-chat.js",
{src: '~/plugins/vue-stripe.js', ssr: false},
],
// Auto import components: https://go.nuxtjs.dev/config-components
// components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/eslint
// "#nuxtjs/eslint-module",
'#nuxtjs/fontawesome',
'#nuxtjs/router-extras',
'#nuxtjs/vuetify',
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
'nuxt-vuex-router-sync',
'nuxt-route-meta',
],
fontawesome: {
icons: {
solid: true,
brands: true,
},
},
nuxtContentAlgolia: {
appId: process.env.ALGOLIA_APP_ID,
apiKey: process.env.ALGOLIA_API_KEY,
paths: [
{
name: 'articles',
index: 'articles',
fields: ['title', 'description', 'bodyPlainText'],
},
],
},
publicRuntimeConfig: {
axios: {
browserBaseURL: process.env.BASE_URL || 'http://localhost:3000',
proxyHeaders: false,
},
appEnv: process.env.APP_ENV || 'production',
},
env: {
STRIPE_PK: process.env.STRIPE_KEY,
baseUrl: process.env.BASE_URL ||'http://localhost:3000',
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
proxyHeaders: false,
proxy: true,
credentials: true,
},
proxy: {
'/api/': process.env.BASE_URL || 'http://localhost:8000',
'/broadcasting/': process.env.BASE_URL || 'http://localhost:8000',
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
filenames: {
app: ({ isDev }) => (isDev ? '[name].js' : '[chunkhash].js'),
chunk: ({ isDev }) => (isDev ? '[name].js' : '[chunkhash].js'),
css: ({ isDev }) => (isDev ? '[name].css' : '[contenthash].css'),
img: ({ isDev }) => (isDev ? '[path][name].[ext]' : 'img/[hash:7].[ext]'),
font: ({ isDev }) =>
isDev ? '[path][name].[ext]' : 'fonts/[hash:7].[ext]',
video: ({ isDev }) =>
isDev ? '[path][name].[ext]' : 'videos/[hash:7].[ext]',
},
transpile: [
'#enso-ui/strings',
'vee-validate/dist/rules',
'#enso-ui/enums',
'#sentry/browser',
'#sentry/integrations',
'#enso-ui/sentry',
'#enso-ui/route-mapper',
'd3-dag',
],
extend(config) {
const isScssRule = (rule) => rule.test.toString() === '/\\.scss$/i'
config.module.rules.forEach((rule) => {
if (isScssRule(rule)) {
const normalRule = rule.oneOf.find(
({ resourceQuery, test }) =>
resourceQuery === undefined && test === undefined
)
const lazyRule = cloneDeep(normalRule)
lazyRule.test = /\.lazy\.scss$/
const idx = lazyRule.use.findIndex(({ loader }) =>
loader.includes('vue-style-loader')
)
if (idx > -1) {
lazyRule.use.splice(idx, 1, {
loader: 'style-loader',
options: {
injectType: 'lazyStyleTag',
insert: function insertAtTop(element) {
const parent = document.querySelector('head')
parent.insertBefore(element, parent.firstChild)
},
},
})
}
rule.oneOf.push(lazyRule)
}
})
// const scssRules = config.module.rules.find('scss').oneOfs;
// const normalRule = scssRules.store.get('normal');
// const lazyRule = config.module.rules.find('scss').oneOf('scss-lazy');
// normalRule.uses.values().forEach(use => {
// if (use.name !== 'vue-style-loader') {
// lazyRule.use(use.name).merge(use.entries());
// return;
// }
// lazyRule.use('style-loader')
// .loader('style-loader')
// .options({
// injectType: 'lazyStyleTag',
// insert: function insertAtTop(element) {
// const parent = document.querySelector('head');
// parent.insertBefore(element, parent.firstChild);
// },
// });
// });
// lazyRule.test(/\.lazy\.scss$/);
// scssRules.store.delete('normal', 'scss-lazy');
// scssRules.store.set('scss-lazy', lazyRule);
// scssRules.store.set('normal', normalRule);
},
},
})
Have a look at my package.json file
{
"private": true,
"scripts": {
"dev": "nuxi dev",
"build": "nuxi build",
"start": "node .output/server/index.mjs"
},
"devDependencies": {
"#fortawesome/free-brands-svg-icons": "^6.0.0",
"#nuxtjs/fontawesome": "^1.1.2",
"#nuxtjs/vuetify": "^1.12.3",
"nuxt3": "^3.0.0-27444169.120ee4f"
},
"dependencies": {
"#enso-ui/bulma": "^5.0.7",
"#enso-ui/charts": "^4.0.0",
"#enso-ui/laravel-validation": "^2.0.6",
"#enso-ui/transitions": "^2.0.11",
"#fortawesome/fontawesome-svg-core": "^1.3.0",
"#fortawesome/free-solid-svg-icons": "^6.0.0",
"#nuxtjs/axios": "^5.13.6",
"#nuxtjs/router-extras": "^1.1.1",
"#nuxtjs/style-resources": "^1.2.1",
"chart": "^0.1.2",
"chart.js": "^2.9.4",
"node-sass": "^7.0.1",
"nuxt-route-meta": "^2.3.4",
"nuxt-vuex-router-sync": "^0.0.3",
"postcss": "^8.2.15",
"resolve": "1.20.0",
"vue": "^3.2.31",
"vue-chartjs": "^3.5.1",
"vue-gtag-next": "^1.14.0",
"vue-loading-overlay": "5.0",
"vuex": "^4.0.2"
}
}

node-loader not handling node_modules file

When running
npm run electron:serve
I get this error:
in ./node_modules/msnodesqlv8/build/Release/sqlserverv8.node
Module parse failed: Unexpected character '�' (1:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
I think I understand the error. My webpack doesn't know how to handle the .node file in this dependency ("msnodesqlv8": "^2.2.0")
I have tried adding node-loader but I've not had any success with it. I have tried configuring it in my vue.config.js like this:
module.exports = {
transpileDependencies: [
'vuetify'
],
configureWebpack: {
devtool: 'source-map'
},
pluginOptions: {
electronBuilder: {
preload: 'preload/preload.js',
"directories": {
"buildResources": "build"
},
mainProcessWatch:['src/services/background/**'],
"files": [
"build/**/*",
"!node_modules"
],
"win": {
"asar": false,
"target": "nsis",
"icon": "build/icon.ico"
},
"nsis": {
"installerIcon": "build/icon.ico",
"installerHeaderIcon": "build/icon.ico",
"deleteAppDataOnUninstall": true
}
}
},
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = "Configuration Utility";
return args;
});
config.module
.rule('node')
.test(/\.node$/)
.use('node-loader')
.loader('node-loader')
.end();
config.module
.rule('pug')
.test(/\.pug$/)
.use('pug-plain-loader')
.loader('pug-plain-loader')
.end();
}
}
I also tried adding a separate webpack.config.js with no success:
module.exports = {
target: "node",
node: {
__dirname: false,
},
module: {
rules: [
{
test: /\.node$/,
loader: "node-loader",
},
],
},
};
How can I get this working?
You need to move the node loader into the chainWebpack of the electron builder for this to work.
module.exports = {
transpileDependencies: [
'vuetify'
],
configureWebpack: {
devtool: 'source-map'
},
pluginOptions: {
electronBuilder: {
preload: 'preload/preload.js',
"directories": {
"buildResources": "build"
},
// THESE NEXT 3 LINES HERE:
chainWebpackMainProcess: config => {
config.module.rule('node').test(/\.node$/).use('node-loader').loader('node-loader').end()
},
mainProcessWatch:['src/services/background/**'],
"files": [
"build/**/*",
"!node_modules"
],
"win": {
"asar": false,
"target": "nsis",
"icon": "build/icon.ico"
},
"nsis": {
"installerIcon": "build/icon.ico",
"installerHeaderIcon": "build/icon.ico",
"deleteAppDataOnUninstall": true
}
}
},
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = "Configuration Utility";
return args;
});
config.module
.rule('pug')
.test(/\.pug$/)
.use('pug-plain-loader')
.loader('pug-plain-loader')
.end();
}
}

Jest's globalSetup make my tests to not being recognized

So I was following this example to make a test with mongodb on jest, but after configuring everything I just get this when running jest:
If I remove globalSetup from jest.config.js, the tests appear although with errors because of mongo-enviroment and teardown configs been dependents on globalSetup:
If I run jest --debug I get this:
{
"configs": [
{
"automock": false,
"browser": false,
"cache": true,
"cacheDirectory": "/tmp/jest_rs",
"clearMocks": false,
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"detectLeaks": false,
"detectOpenHandles": false,
"errorOnDeprecated": false,
"filter": null,
"forceCoverageMatch": [],
"globals": {},
"haste": {
"providesModuleNodeModules": []
},
"moduleDirectories": [
"node_modules"
],
"moduleFileExtensions": [
"js",
"json",
"jsx",
"node"
],
"moduleNameMapper": {},
"modulePathIgnorePatterns": [],
"name": "9f5155d702743ad8d949d6d219c1bc22",
"prettierPath": null,
"resetMocks": false,
"resetModules": false,
"resolver": null,
"restoreMocks": false,
"rootDir": "/home/mauricio/work/growthbond/gbnd1",
"roots": [
"/home/mauricio/work/growthbond/gbnd1"
],
"runner": "jest-runner",
"setupFiles": [
"/home/mauricio/work/growthbond/gbnd1/node_modules/regenerator-runtime/runtime.js"
],
"setupTestFrameworkScriptFile": "/home/mauricio/work/growthbond/gbnd1/testConfig/setupScript.js",
"skipFilter": false,
"snapshotSerializers": [],
"testEnvironment": "/home/mauricio/work/growthbond/gbnd1/testConfig/mongo-environment.js",
"testEnvironmentOptions": {},
"testLocationInResults": false,
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)+(spec|test).js?(x)"
],
"testPathIgnorePatterns": [
"/node_modules/"
],
"testRegex": "",
"testRunner": "/home/mauricio/work/growthbond/gbnd1/node_modules/jest-jasmine2/build/index.js",
"testURL": "http://localhost",
"timers": "real",
"transform": [
[
"^.+\\.jsx?$",
"/home/mauricio/work/growthbond/gbnd1/node_modules/babel-jest/build/index.js"
]
],
"transformIgnorePatterns": [
"/node_modules/"
],
"watchPathIgnorePatterns": []
}
],
"globalConfig": {
"bail": false,
"changedFilesWithAncestor": false,
"collectCoverage": false,
"collectCoverageFrom": null,
"coverageDirectory": "/home/mauricio/work/growthbond/gbnd1/coverage",
"coverageReporters": [
"json",
"text",
"lcov",
"clover"
],
"coverageThreshold": null,
"detectLeaks": false,
"detectOpenHandles": false,
"errorOnDeprecated": false,
"expand": false,
"filter": null,
"globalSetup": "/home/mauricio/work/growthbond/gbnd1/testConfig/setup.js",
"globalTeardown": "/home/mauricio/work/growthbond/gbnd1/testConfig/teardown.js",
"listTests": false,
"maxWorkers": 3,
"noStackTrace": false,
"nonFlagArgs": [],
"notify": false,
"notifyMode": "always",
"passWithNoTests": false,
"projects": null,
"rootDir": "/home/mauricio/work/growthbond/gbnd1",
"runTestsByPath": false,
"skipFilter": false,
"testFailureExitCode": 1,
"testPathPattern": "",
"testResultsProcessor": null,
"updateSnapshot": "new",
"useStderr": false,
"verbose": true,
"watch": false,
"watchman": true
},
"version": "23.6.0"
}
Note that
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)+(spec|test).js?(x)"
],
looks perfectly fine.
Related files
jest.config.js:
module.exports = {
globalSetup: './testConfig/setup.js',
globalTeardown: './testConfig/teardown.js',
testEnvironment: './testConfig/mongo-environment.js',
setupTestFrameworkScriptFile: './testConfig/setupScript.js',
verbose: true
}
setup.js (globalSetup):
const path = require('path');
const fs = require('fs');
const MongodbMemoryServer = require('mongodb-memory-server');
const globalConfigPath = path.join(__dirname, 'globalConfig.json');
const mongod = new MongodbMemoryServer.default({
instance: {
dbName: 'jest'
},
binary: {
version: '3.2.18'
},
autoStart: false,
});
module.exports = async () => {
if (!mongod.isRunning) {
await mongod.start();
}
const mongoConfig = {
mongoDBName: 'jest',
mongoUri: await mongod.getConnectionString()
};
// Write global config to disk because all tests run in different contexts.
fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig));
console.log('Config is written');
// Set reference to mongod in order to close the server during teardown.
global.__MONGOD__ = mongod;
process.env.MONGO_URL = mongoConfig.mongoUri;
};
teardown.js:
module.exports = async function() {
await global.__MONGOD__.stop();
};
mongo-environment.js:
const NodeEnvironment = require('jest-environment-node');
const path = require('path');
const fs = require('fs');
const globalConfigPath = path.join(__dirname, 'globalConfig.json');
module.exports = class MongoEnvironment extends NodeEnvironment {
constructor(config) {
super(config);
}
async setup() {
console.log('Setup MongoDB Test Environment');
const globalConfig = JSON.parse(fs.readFileSync(globalConfigPath, 'utf-8'));
this.global.__MONGO_URI__ = globalConfig.mongoUri;
this.global.__MONGO_DB_NAME__ = globalConfig.mongoDBName;
await super.setup();
}
async teardown() {
console.log('Teardown MongoDB Test Environment');
await super.teardown();
}
runScript(script) {
return super.runScript(script);
}
};
user.test.js (mongodb related test):
const MongoClient= require('mongodb');
const User = require('../../db/models/user');
let connection;
let db;
beforeAll(async () => {
connection = await MongoClient.connect(global.__MONGO_URI__);
db = await connection.db(global.__MONGO_DB_NAME__);
});
afterAll(async () => {
await connection.close();
await db.close();
});
describe('Password Encription', async () => {
const uEmail = 'test#a.com';
const uPass = '123test';
var testUser = new User({
email:uEmail ,
password: uPass
});
await testUser.save()
test('Encripted password string is different to plain password', async () => {
user = await User.findOne({ email: uEmail });
expect(user.password).not.toEqual(uPass);
});
test('ComparePassword method verify that plain password is the same that encrypted password', async () => {
rightPassword = await user.comparePassword(uPass);
expect(rightPassword).toBeTrue();
});
test('ComparePassword method verify that altered plain password is not the same that encrypted password', async () => {
wrongPassword = await user.comparePassword(uPass+'random');
expect(rightPassword).not.toBeTrue();
});
});
authService.test.js:
require('dotenv').config()
const authS = require('../../services/authService');
const jwt = require('jsonwebtoken');
describe('Auth Services',()=>{
const payload = {test:'This is a test'}
const user = {id:101}
const mockSecret = 'SECRET123HAAJAHJSoafdafda'
const token = authS.jwtSign(user,payload)
test('JWT sign', () => {
expect(authS.jwtSign(user,payload)).toBeString();
});
test('JWT verify different secret', ()=>{
badToken = jwt.sign(
payload,
mockSecret,
{ subject:String(user.id),
expiresIn:'1h'
}
);
expect(()=>authS.jwtVerify(badToken)).toThrowError(jwt.JsonWebTokenError)
})
test('JWT verify payload', ()=>{
expect(authS.jwtVerify(authS.jwtSign(user,payload))).toMatchObject(payload)
})
})
My environment:
node v11.0.0
jest 23.6.0
As a matter of fact I know that my test non mongodb related run if I comment
globalSetup: './testConfig/setup.js',
globalTeardown: './testConfig/teardown.js',
testEnvironment: './testConfig/mongo-environment.js',
from jest.config.js :
My problem was that I had another GlobalSetup file and they were conflicting. In my custom GlobalSetup I imported the #Shelf/jest-mongodb/setup and add it to mine.
const jestMongoSetup = require("#shelf/jest-mongodb/setup")
module.exports = async () => {
process.env.TZ = "UTC" //My config
await jestMongoSetup()
}

Gulp is not generate js file from ts

here is my Gulp task:
var gulp = require('gulp');
var typescript = require('gulp-typescript');
var sourcemaps = require('gulp-sourcemaps');
var tsProject = typescript.createProject('tsconfig.json');
var tsSources = [
'./typings/**/*.ts',
'server/**/*.ts'
];
module.exports = function () {
var tsResult = gulp.src(tsSources)
.pipe(sourcemaps.init())
.pipe(typescript(tsProject));
return tsResult.js
.pipe(sourcemaps.write())
.pipe(gulp.dest('server/'));
};
here is my tsconfig
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"watch": true,
"removeComments": true,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"declaration": false,
"noImplicitAny": false,
"noLib": false
},
"exclude": [
"fonts",
"images",
"img",
"libs",
"navigation",
"node_modules",
"pagehtmls",
"typings"
]
}
here is my ts file:
/// <reference path="../typings/_all.d.ts" />
'use strict';
import {Request, Response} from 'express';
var config = require('../../config/environment'),
auth = require('../../auth/auth.service');
var mongodb = require('mongodb');
var MongoClient = mongodb.MongoClient;
exports.getBooking = (req: Request, res: Response) => {
MongoClient.connect(config.mongoERP.uri, (err, db) => {
if (err) { return res.send(err); }
db.getCollection('customers').find({ email1: req.params.email }).toArray((err, customer) => {
if (err) { return res.send(err); }
return res.send(customer);
});
});
}
here is my tsd.json
{
"version": "v4",
"repo": "borisyankov/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/_all.d.ts",
"installed": {
"angularjs/angular.d.ts": {
"commit": "2d4c4679bc2b509f27435a4f9da5e2de11258571"
},
"angular-ui-router/angular-ui-router.d.ts": {
"commit": "c50b111ded0a3a18b87b5abffea3150d6aca94da"
},
"jquery/jquery.d.ts": {
"commit": "2d4c4679bc2b509f27435a4f9da5e2de11258571"
},
"lodash/lodash.d.ts": {
"commit": "2d4c4679bc2b509f27435a4f9da5e2de11258571"
},
"node/node.d.ts": {
"commit": "2d4c4679bc2b509f27435a4f9da5e2de11258571"
},
"socket.io-client/socket.io-client.d.ts": {
"commit": "2d4c4679bc2b509f27435a4f9da5e2de11258571"
},
"serve-static/serve-static.d.ts": {
"commit": "b57c33fec0be3cba8f5e9cec642db873565923d0"
},
"mime/mime.d.ts": {
"commit": "b57c33fec0be3cba8f5e9cec642db873565923d0"
},
"express/express.d.ts": {
"commit": "470954c4f427e0805a2d633636a7c6aa7170def8"
},
"es6-shim/es6-shim.d.ts": {
"commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7"
},
"mongoose/mongoose.d.ts": {
"commit": "6766ed1d0faf02ede9e2edf2e66bbb2388c825ec"
}
}
}
I am using gulp cli version 3.9.0 and local 3.9.1
its gives the error error TS1128: Declaration or statement expected
for the import
If i remove './typings/**/*.ts', from gulp task and
path="../../server.d.ts" />
import {Request, Response} from 'express';
from my ts file its work fine but give diff error messages while compilation.
I have lot of ts file so i cant remove it.
You should not exclude all typings folder in your tsconfig as it contains definitions for the compiler, including the ones of express. Most likely you want to only exclude typings\browser for example.
Also I can recommend to use tsProject.src() instead of gulp.src so that structure of your projects is defined only in one place - tsconfig.
Hope this helps.
I faced the the Problem..
Just update your Gulp Typescript.
This worked for me.

Resources