How to make testcafe work with absolute imports? - javascript

I have a create react app 3 project,
so I have in my src folders some js scripts using like:
import { Foo } from 'components/layout/Foo
Unfortunately, the testcafe compiler complains about it by default.
I read that maybe the solution was to create specify a custom tsconfig.json in which I declare
{
"compilerOptions": {
"baseUrl: "src"
}
}
But it does not work, apparently.
Thanks.

Sorry, indeed it is not a component file, but a utils one in the src directory.
in my foo_test.js I have
import { ROOT_PATH } from '../src/utils/config'
fixture("00 Home | Arriving to the Home").page(ROOT_PATH)
test('Default | leads to the home page', async t => {
const location = await t.eval(() => window.location)
await t.expect(location.pathname).eql('/home')
})
where utils/config is
import { getMobileOperatingSystem } from 'utils/mobile'
export const MOBILE_OS = getMobileOperatingSystem()
let CALC_ROOT_PATH
if (MOBILE_OS === 'ios') {
document.body.className += ' cordova-ios'
CALC_ROOT_PATH = window.location.href.match(/file:\/\/(.*)\/www/)[0]
}
export const ROOT_PATH = CALC_ROOT_PATH || 'http://localhost:3000/'

Related

SvelteKit Maintenance Mode

Is there a good way to do display a maintenance page when visiting any route of my SvelteKit website?
My app is hosted on Vercel, for those who want to know.
What I've tried so far:
Set an environment variable called MAINTENANCE_MODE with a value 1 in Vercel.
For development purposes I've set this in my .env file to VITE_MAINTENANCE_MODE and called with import.meta.env.VITE_MAINTENANCE_MODE.
Then inside +layout.server.js I have the following code to redirect to /maintenance route
import { redirect } from "#sveltejs/kit";
export async function load({ url }) {
const { pathname } = url;
// Replace import.meta.env.VITE_MAINTENANCE_MODE with process.env.MAINTENANCE_MODE in Production
if (import.meta.env.VITE_MAINTENANCE_MODE == 1) {
if (pathname == "/maintenance") return;
throw redirect(307, "/maintenance");
  } else {
if (pathname == "/maintenance") {
throw redirect(307, "/");
    };
  };
};
What I've also tried is just throwing an error in +layout.server.js with the following:
import { error } from "#sveltejs/kit";
export async function load() {
if (import.meta.env.VITE_MAINTENANCE_MODE == 1) {
throw error(503, "Scheduled for maintenance");
  };
};
However this just uses SvelteKit's static fallback error page and not +error.svelte. I've tried creating src/error.html in the hope to create a custom error page for +layout.svelte but couldn't get it to work.
I would like to use a custom page to display "Down for maintenance", but I don't want to create an endpoint for every route in my app to check if the MAINTENANCE_MODE is set to 1.
Any help is appreciated
You could use a handle server hook, e.g. src/hooks.server.ts:
import { env } from '$env/dynamic/private';
import type { Handle } from '#sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
if (env.MAINTENANCE_MODE == '1' && event.routeId != '/maintenance')
return new Response(undefined, { status: 302, headers: { location: '/maintenance' } });
// <other logic>
// Default response
return await resolve(event);
}
And on the maintenance page you can prevent all further navigation:
import { beforeNavigate } from '$app/navigation';
beforeNavigate(async ({ cancel }) => {
cancel();
});
(Possibly add some periodic checks via fetch calls to navigate elsewhere once the site is back online.)
You can also use +layout.ts to hook up for the maintenance mode. You can even make this conditional for some parts of the site (have frontpage still up and running).
Here is the trick we use:
import type { LayoutLoad } from './$types';
import { chainsUnderMaintenance } from '$lib/config';
import { error } from '#sveltejs/kit';
export const load: LayoutLoad = ({ params }) => {
// Check chain maintenance status; if under maintenance, trigger error (see +error.svelte)
const chainName = chainsUnderMaintenance[<string>params.chain];
if (chainName) {
throw error(503, `Chain under maintenance: ${chainName}`);
}
};

How do I access environment variables in Strapi v4?

Strapi Version: 4.3.0
Operating System: Ubuntu 20.04
Database: SQLite
Node Version: 16.16
NPM Version: 8.11.0
Yarn Version: 1.22.19
I have created Preview button for an article collection type. I'm using the Strapi blog template. I managed to make the Preview button appear in the Content Manager. I hard coded the link to be opened when you click the Preview button and it works. Now, I want the plugin to use a link with environment variables instead of a hard coded link. I don't know how I can access the environment variables in the source code for the plugin.
My objective:
I want to replace
href={`http://localhost:3000?secret=abc&slug=${initialData.slug}`}
with
href={${CLIENT_FRONTEND_URL}?secret=${CLIENT_SECRET}&slug=${initialData.slug}`}
in ./src/plugins/previewbtn/admin/src/components/PreviewLink/index.js
where CLIENT_FRONTEND_URL and CLIENT_SECRET are environment variables declared like so in .env:
CLIENT_FRONTEND_URL=http://localhost:3000
CLIENT_PREVIEW_SECRET=abc
Here's a rundown of the code I used:
First, I created a strapi app using the blog template, then created a plugin.
// Create strapi app named backend with a blog template
$ yarn create strapi-app backend --quickstart --template #strapi/template-blog#1.0.0 blog && cd backend
// Create plugin
$ yarn strapi generate
Next, I created a PreviewLink file to provide a link for the Preview button
// ./src/plugins/previewbtn/admin/src/components/PreviewLink/index.js
import React from 'react';
import { useCMEditViewDataManager } from '#strapi/helper-plugin';
import Eye from '#strapi/icons/Eye';
import { LinkButton } from '#strapi/design-system/LinkButton';
const PreviewLink = () => {
const {initialData} = useCMEditViewDataManager();
if (!initialData.slug) {
return null;
}
return (
<LinkButton
size="S"
startIcon={<Eye/>}
style={{width: '100%'}}
href={`http://localhost:3000?secret=abc&slug=${initialData.slug}`}
variant="secondary"
target="_blank"
rel="noopener noreferrer"
title="page preview"
>Preview
</LinkButton>
);
};
export default PreviewLink;
Then I edited this pregenerated file in the bootstrap(app) { ... } section only
// ./src/plugins/previewbtn/admin/src/index.js
import { prefixPluginTranslations } from '#strapi/helper-plugin';
import pluginPkg from '../../package.json';
import pluginId from './pluginId';
import Initializer from './components/Initializer';
import PreviewLink from './components/PreviewLink';
import PluginIcon from './components/PluginIcon';
const name = pluginPkg.strapi.name;
export default {
register(app) {
app.addMenuLink({
to: `/plugins/${pluginId}`,
icon: PluginIcon,
intlLabel: {
id: `${pluginId}.plugin.name`,
defaultMessage: name,
},
Component: async () => {
const component = await import(/* webpackChunkName: "[request]" */ './pages/App');
return component;
},
permissions: [
// Uncomment to set the permissions of the plugin here
// {
// action: '', // the action name should be plugin::plugin-name.actionType
// subject: null,
// },
],
});
app.registerPlugin({
id: pluginId,
initializer: Initializer,
isReady: false,
name,
});
},
bootstrap(app) {
app.injectContentManagerComponent('editView', 'right-links', {
name: 'preview-link',
Component: PreviewLink
});
},
async registerTrads({ locales }) {
const importedTrads = await Promise.all(
locales.map(locale => {
return import(
/* webpackChunkName: "translation-[request]" */ `./translations/${locale}.json`
)
.then(({ default: data }) => {
return {
data: prefixPluginTranslations(data, pluginId),
locale,
};
})
.catch(() => {
return {
data: {},
locale,
};
});
})
);
return Promise.resolve(importedTrads);
},
};
And lastly this created this file to enable the plugin Reference
// ./config/plugins.js
module.exports = {
// ...
'preview-btn': {
enabled: true,
resolve: './src/plugins/previewbtn' // path to plugin folder
},
// ...
}
I solved this by adding a custom webpack configuration to enable Strapi's admin frontend to access the environment variables as global variables.
I renamed ./src/admin/webpack.example.config.js to ./src/admin/webpack.config.js. Refer to the v4 code migration: Updating the webpack configuration from the Official Strapi v4 Documentation.
I then inserted the following code, with help from Official webpack docs: DefinePlugin | webpack :
// ./src/admin/webpack.config.js
'use strict';
/* eslint-disable no-unused-vars */
module.exports = (config, webpack) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
// Important: return the modified config
config.plugins.push(
new webpack.DefinePlugin({
CLIENT_FRONTEND_URL: JSON.stringify(process.env.CLIENT_FRONTEND_URL),
CLIENT_PREVIEW_SECRET: JSON.stringify(process.env.CLIENT_PREVIEW_SECRET),
})
)
return config;
};
I rebuilt my app afterwards and it worked.
You shouldn't have to change the webpack config just find .env file in the root directory
add
AWS_ACCESS_KEY_ID = your key here
then just import by
accessKeyId: env('AWS_ACCESS_KEY_ID')

How to extend core modules of Vue Storefront

I want to override an action from cart module store. I am trying to extend this CartModule by following this link
Extending and Overriding Modules Doc
I have created a file /src/modules/cart/index.ts with following code
import { VueStorefrontModuleConfig, extendModule, VueStorefrontModule } from '#vue-storefront/core/lib/module'
import { CartModule } from '#vue-storefront/core/modules/cart'
import { cartModule } from './store'
const cartExtend: VueStorefrontModuleConfig = {
key: 'cart',
store: {modules: [{key: 'cart', module: cartModule}]},
afterRegistration: function () {
console.log('Cart module extended')
}
}
extendModule(cartExtend)
export const registerModules: VueStorefrontModule[] = [CartModule]
I am getting error that CarModule type does not match with VueStorefrontModule
Also I don't know what to do next in order to make it effective. Docs are not clear about it. Please help. Thanks
If you want to overwrite action of module you don't want to extend module but store.
Here is example:
Vuestorefront has CartModule (in core) and you need to change code of action refreshTotals.
Code your in file /src/modules/cart/index.ts:
import {StorefrontModule} from '#vue-storefront/core/lib/modules';
import {extendStore} from '#vue-storefront/core/helpers';
const cartModule = {
action: {
async refreshTotals({dispatch}, payload) {
//
// your new (and better!) code ;-)
//
}
},
}
export const MyAwesomeCart: StorefrontModule = function () {
extendStore('cart', cartModule);
}
In last step register this your new module under /src/modules/client.ts:
..
...
import {CartModule} from '#vue-storefront/core/modules/cart';
import {MyAwesomeCart} from "modules/cart/index";
export function registerClientModules() {
registerModule(CartModule); // original module
registerModule(MyAwesomeCart); // your new overwiritng module
...
..

NextJS import images in MDX

I tried a official NextJS MDX-Blog example.
https://github.com/mdx-js/mdx/tree/master/examples/next
But what I'm not able to figure out is how do I setup the NextJS config to load images via webpack?
import img from "./image.jpg"
## Hallo Blogwelt
![My own Image]({img})
You can also use the /public directory to hold your images. For example, if you add an image at /public/image.jpg, you can reference the image in your blog post like this:
![Alt Text](/image.jpg)
Edit: https://nextjs.org/docs/basic-features/image-optimization#local-images
Imagine your next.config.js as something to append to an existing webpack.config behind the scenes. You won't have direct access to the webpack but you can extend it.
So in order to load images you'll need an appropriate image loader.
I found next-images easiest to use:
const withImages = require('next-images')
module.exports = withImages({
webpack(config, options) {
return config
}
})
then you can import:
import Img from "./image.jpg"
Hey thanks for the tip!
It's been a while since June and a gave it another try today and now it's working like expected from me.
I took the MDX/Next Example
Edited the next.config.js like so:
const withPlugins = require('next-compose-plugins');
const images = require('remark-images');
const emoji = require('remark-emoji');
const optimizedImages = require('next-optimized-images');
const withMDX = require('#zeit/next-mdx')({
extension: /\.mdx?$/,
options: {
mdPlugins: [images, emoji]
}
});
module.exports = withPlugins([
[
withMDX,
{
pageExtensions: ['js', 'jsx', 'md', 'mdx']
}
],
[optimizedImages]
]);
Now it works exactly like expected and in a Markdown file within the pages folder I'm able to do something like this:
import Layout from '../../components/Layout'
import Image from './catimage.jpg'
# Hey guys this is the heading of my post!
<img src={Image} alt="Image of a cat" />
Sorry I'm late, but with Next v11 you can directly import images.
That being said, you can add custom loaders for Webpack to modify your mdx files and use a custom component to process the image. e.g.:
// save this somewhere such as mdxLoader and
// add it to your webpack configuration
const replaceAll = require("string.prototype.replaceall");
module.exports = function (content, map, meta) {
return replaceAll(
map
content,
/\!\[(.*)\]\((.+)\)/g,
`<NextImage alt="$1" src={require('$2').default} />`
);
};
and process it:
// and reference this in your MDX provider
const components = {
NextImage: (props: any) => {
return <Image alt={props.alt || "Image"} {...props} />;
},
};
Now you can use markdown flavored images in your posts!
![my image](./image.png)
Include the ./ relative prefix, however.
I'm building a Next.js blog with MDX-Bundler. It allows you to use a remark plugin called remark-mdx-images which converts markdown flavored images into JSX images.
Below is an example configuration to get it to work
const {code} = await bundleMDX(source, {
cwd: '/posts/directory/on/disk',
xdmOptions: options => {
options.remarkPlugins = [...(options.remarkPlugins ?? []), remarkMdxImages]
return options
},
esbuildOptions: options => {
options.outdir = '/public/directory/on/disk/img'
options.loader = {
...options.loader,
'.jpg': 'file'
}
options.publicPath = '/img/'
options.write = true
return options
}
})
You can check out the following resources for detailed explanation on how to do it.
Images with MDX-Bundler
How I built the new notjust.dev platform with NextJS
If you installed the #next/mdx package you can use the <Image /> component Next.js provides:
// pages/cute-cat.mdx
import Image from "next/image";
import cuteCat from "./cute-cat.jpg";
# Cute cat
This is a picture of a cute cat
<Image src={cuteCat} />

Angular2 / Electron application using electron API within the angular2 ts files

I have setup an angular2 / Electron app similar to the explanation in this video : https://www.youtube.com/watch?v=pLPCuFFeKOU. The project I am basing my code on can be found here : https://github.com/rajayogan/angular2-desktop
I am getting the error:
app.ts:16Uncaught TypeError: Cannot read property 'on' of undefined
When I try to run this code:
import { bootstrap } from '#angular/platform-browser-dynamic';
import { Component } from '#angular/core';
import { MenuComponent} from './menu';
import { ConfigEditorComponent } from './config-editor';
import { remote, ipcRenderer} from 'electron';
let {dialog} = remote;
//Functions used for select server xml callbacks.
const ipc = require('electron').ipcMain
const xml2js = require('xml2js')
const fs = require('fs')
var parser = new xml2js.Parser();
ipc.on('open-file-dialog', function (event) {
dialog.showOpenDialog({
title:"Select zOS Connect server.xml",
properties: ['openFile', 'openDirectory'],
filters: [
{name: 'XML', extensions: ['xml']},
{name: 'All Files', extensions: ['*']}
]
}, function (files) {
if (files){
fs.readFile(files[0], function(err, data) {
parser.parseString(data, function (err, result) {
console.dir(result);
process_server_xml(event,result);
})
})
}
})
})
function process_server_xml(event,json){
console.log("oh hello!")
event.sender.send('selected-directory', json)
console.log("oh im done!")
}
#Component({
selector: 'connect-toolkit',
templateUrl: 'app.component.html',
directives: [ MenuComponent, ConfigEditorComponent ]
})
export class AppComponent {
constructor() {
var menu = remote.Menu.buildFromTemplate([{
label: 'Raja',
submenu: [
{
label: 'open',
click: function(){
dialog.showOpenDialog((cb) => {
})
}
},
{
label: 'opencustom',
click: function(){
ipcRenderer.send('open-custom');
let notification = new Notification('Customdialog', {
body: 'This is a custom window created by us'
})
}
}
]
}])
remote.Menu.setApplicationMenu(menu);
}
}
bootstrap(AppComponent);
I think the problem may be:
const ipc = require('electron').ipcMain
const xml2js = require('xml2js')
const fs = require('fs')
var parser = new xml2js.Parser();
Is it possible require doesn't work here, and somehow I need to use import statements instead from my ts files? If this is the case how do I use the import in order to get the ipcMain object and my xml2js etc?
Why would that be the case? How can I make require work within the ts files if this is the problem.
Note that if I remove the require lines, and all the ipc.on code everything runs as expected and works fine (other than the fact that the ipc event is never received ;)
Calling ipcMain doesn't work because you're not on main (i.e., the electron side code, which is on electron index.js file), your are on renderer (web page). Therefore you must use ipcRenderer instead, which is already imported using es6 import syntax on top of your app.ts file. And if you want to make something using electron ipcMain, it have to be done from the electron code side.
import {remote, ipcRenderer} from 'electron';
Electron ipc notes:
ipcMain Communicate asynchronously from the main process to renderer processes.
ipcRenderer Communicate asynchronously from a renderer process to the main process.

Categories

Resources