Related
I am allowing my users to create different roles for themselves within my svelteKit application.
I have a text input with a button that adds that value to an array and shows in the div below.
I need to convert the array into a tiered JSON object so I can add it to my Postgres database role_permissions column as JSONB. I have tried JSON.stringify() and JSON.parse() but I cannot get it to work.
Ideally formatted like this:
{
"role_name"{
"permission": true,
"permission": true,
...
}
"role_name_2"{
"permission": true,
"permission": false,
...
}
}
While my users can create roles with custom names the permissions available are all the same e.g.:
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
can_delete_roles: false,
can_edit_roles: false,
can_assign_roles: false,
can_create_projects: false,
can_delete_projects: false,
can_edit_projects: false,
can_publish_projects: false,
can_view_projects: false,
can_assign_members_to_projects: false,
I can't figure out how to convert the object into a tiered JSON format. I know I need some sort of key outside of each object but I do not know how to do that.
This is how they appear in console.log()
{name: "Partner", can_add_members: false, can_delete_members: false, can_edit_members: false, can_create_roles: false, …}
{name: "Associate Partner", can_add_members: false, can_delete_members: false, can_edit_members: false, can_create_roles: false, …}
The actual code:
let newItem = '';
// An array of the roles names that will also be saved to the database as is.
let roleList = [];
// The array that needs to be converted to JSON
let roleListWithPermissions = [],
function addToList() {
roleList = [...roleList, {text: newItem,}];
roleListWithPermissions = [...roleListWithPermissions, {
"name": newItem,
"can_add_members": false,
"can_delete_members": false,
"can_edit_members": false,
"can_create_roles": false,
"can_delete_roles": false,
"can_edit_roles": false,
"can_assign_roles": false,
"can_create_projects": false,
"can_delete_projects": false,
"can_edit_projects": false,
"can_publish_projects": false,
"can_view_projects": false,
"can_assign_members_to_projects": false
}];
newItem = '';
console.log("ROLE LIST",roleList)
console.log("PERMISSIONS LIST",roleListWithPermissions)
}
One approach is below, with explanatory comments in the code:
// the original Object as described/shown in the question:
let source = [{
name: "Partner",
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
},
{
name: "Associate Partner",
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
}
],
// here we use Array.prototype.map() to iterate over the Array of Objects:
rolePermissions = source.map(
// using destructuring assignment to retrieve the 'name'
// property from the Array-element (the Object),
// and assigning all remaining property-value pairs
// to the 'rest' variable:
({
name,
...rest
}) => {
// here we return a new Object, with the computed value of the
// 'name' variable to set the property equal to the value of the
// variable rather than the String of 'name':
return {
// and the property-value equal to the Object containing the
// rest of the key-value pairs:
[name]: rest
};
}),
// converting the Array of Objects into a JSON string:
jsonRolePermissions = JSON.stringify(rolePermissions);
// logging that JSON string to the console:
console.log(jsonRolePermissions);
Reference:
Array.prototype.map().
Destructuring assignment.
JSON.stringify().
Object initializer.
you can transform roleListWithPermissions array to an object.
const finalResult =
roleListWithPermissions.reduce((result, current) => {
result[current.name]= {...current};
delete result[current.name].name;
return result;
}, {})
I am using Nuxt 2.15.7 in VS Code, using Node version 14.17.1 and the eslint extension.
The problem
I started seeing a red squiggly line under the 1st character of every file. When hovering over it, this is the error I see:
require() of ES modules is not supported.
require() of C:\Users\SR Gears\Documents\work\my-website\node_modules\eslint\node_modules\eslint-scope\lib\definition.js
from C:\Users\SR Gears\Documents\work\my-website\node_modules\babel-eslint\lib\require-from-eslint.js
is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename definition.js to end in .cjs,
change the requiring code to use import(),
or remove "type": "module" from
C:\Users\SR Gears\Documents\work\my-website\node_modules\eslint\node_modules\eslint-scope\package.json.eslint
What I have tried so far
First, I tried renaming the appropriate files as listed above in the error, and restarting the eslint server, but the error remains.
So, I went over to the eslint extension in VS Code and read the following:
The approval flow to allow the execution of a ESLint library got reworked. Its initial experience is now as follows:
- no modal dialog is shown when the ESLint extension tries to load an ESLint library for the first time and an approval is necessary. Instead the ESLint status bar item changes to ESLint status icon indicating that the execution is currently block.
- if the active text editor content would be validated using ESLint, a problem at the top of the file is shown in addition.
The execution of the ESLint library can be denied or approved using the following gestures:
- clicking on the status bar icon
- using the quick fix for the corresponding ESLint problem
- executing the command ESLint: Manage Library Execution from the command palette
Okay, so I tried the above suggestions:
clicking on the status bar icon (it isn't there in my status bar)
using the quick fix for the corresponding ESLint problem (shows no quick fix available)
executing the command ESLint: Manage Library Execution from the command palette (I get a message that this request is unknown)
Potential Fix with error
So, I navigated over to eslintrc.js I hovered over module.exports = { on line 1, and got the lightbulb icon show. The Quick Fix says Convert to ES6 module. When I click this, the file is updated. All variable keys within the options are updated to have export in front of them. This does remove the error line at the top of the files, but gives a new error for export const extends: [] variable:
'extends' is not allowed as a variable declaration name.. My eslintrc.js file (before updating to ES6 module) is here:
eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
parser: 'babel-eslint'
},
extends: [
'plugin:nuxt/recommended',
'plugin:vue/recommended',
'eslint:recommended',
// 'prettier/vue',
'plugin:prettier/recommended'
],
globals: {
$nuxt: true,
page: true,
browser: true,
context: true,
jestPuppeteer: true
},
plugins: ['nuxt', 'vue', 'prettier'],
rules: {
'new-cap': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'vue/component-name-in-template-casing': ['off', 'PascalCase'],
'vue/attribute-hyphenation': ['warn'],
'vue/no-unused-components': ['warn'],
'vue/html-self-closing': [
'error',
{
html: {
void: 'any',
normal: 'always',
component: 'always'
},
svg: 'always',
math: 'always'
}
],
'vue/max-attributes-per-line': 'off',
'vue/no-v-html': 'off',
'no-unused-vars': ['warn'],
eqeqeq: ['warn'],
'no-lonely-if': ['warn'],
'require-await': ['warn'],
'handle-callback-err': ['warn'],
'space-before-function-paren': 0
}
}
One other potential fix - but not for me
For anyone else with the same errors, there is a fix here, (that also worked for me): ESlint - Error: Must use import to load ES Module `
I cannot use this fix though, as my team suggested that adjusting babel settings can create errors elsewhere.
As that cannot be my solution, would anyone else know how to manage this error? Here is my nuxt.config file. If you need to see something else, I can update it here too.
nuxt.config
import { storyblokConfig, localeMessages } from './config'
export default {
// Target: https://go.nuxtjs.dev/config-target
target: 'server',
ssr: true,
dev: false,
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: '',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' }
],
link: [
{
rel: 'icon',
sizes: '192x192',
href: '/favicon/android-chrome-192x192.png'
},
{
rel: 'icon',
sizes: '512x512',
href: '/favicon/android-chrome-512x512.png'
},
{
rel: 'apple-touch-icon',
sizes: '180x180',
href: '/favicon/apple-touch-icon.png'
},
{ rel: 'icon', sizes: '16x16', href: '/favicon/favicon-16x16.png' },
{ rel: 'icon', sizes: '32x32', href: '/favicon/favicon-32x32.png' },
{ rel: 'icon', type: 'image/x-icon', href: '/favicon/favicon.ico' },
{ rel: 'manifest', href: '/favicon/site.webmanifest' }
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
'~assets/styles/main.css',
'~assets/fonts/fabrikat/stylesheet.css',
'~assets/fonts/pangram/stylesheet.css'
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{ src: '~/plugins/logger.js' },
{ src: '~/plugins/nujek-ui.js' },
{ src: '~/plugins/validation.js' },
{ src: '~/plugins/utils.js' },
{ src: '~/plugins/vue-tailwind.js' },
{ src: '~/plugins/rich-text-renderer.js' },
{ src: '~/plugins/defaultButton.js' }
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: [{ path: '~/components', pathPrefix: false, prefix: '' }],
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/eslint
'#nuxtjs/eslint-module',
// https://go.nuxtjs.dev/tailwindcss
'#nuxtjs/tailwindcss',
'#nuxtjs/composition-api/module',
'#nuxtjs/tailwindcss',
[
'#nujek/ui',
{
withConsole: true,
storeTemplates: {
nav: true
}
}
],
['#nujek/storyblok']
],
nujekStoryblok: {
storyblokConfig,
withConsole: false,
debug: true
},
// Modules: https://go.nuxtjs.dev/config-modules
modules: ['nuxt-i18n', '~/modules/nuxt-storyblok-queries/lib/module.js'],
storyblokQueries: storyblokConfig,
i18n: {
locales: [
{
code: 'en',
iso: 'en-US'
},
{
code: 'de',
iso: 'de-DE'
}
],
defaultLocale: 'de',
strategy: 'prefix_except_default',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root'
},
vueI18n: {
fallbackLocale: 'de',
silentTranslationWarn: true,
messages: localeMessages
},
vuex: {
syncLocale: true,
syncMessages: true
}
},
// publicRuntimeConfig: {
// accessToken: process.env.SB_CLIENT_ACCESS_TOKEN
// },
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
transpile: ['vee-validate', '#marvr/storyblok-rich-text-vue-renderer']
}
}
c:/users/user/AppData/Roaming/Code/User/settings.json
{
"workbench.colorTheme": "Default Dark+",
"terminal.integrated.defaultProfile.windows": "Git Bash",
"editor.wordWrap": "on",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": ["javascript"]
}
I met this error today on a fresh installation of nuxt.
It would npm run dev fine on the first time, but whenever I changed a file, the hot reloading would give an eslint error, as if trying to lint my eslint files.
I solved it by updating Nodejs and npm to their latest version and creating a new nuxt app.
It's probably not the answer you've been looking for, but maybe it will help others.
I am using gulp and I get an error on startup...
How do I fix this?
The returned value is not a function.
I've been trying to fix this for hours now, but I don't understand what's wrong.
Maybe this is somehow possible using this plugin? vinyl-source-stream
const htmlMinify = require('html-minifier').minify
function html() {
const postcssPlugins = [
autoprefixer({
overrideBrowserslist: [
'>0.25%',
'not ie 11',
'not op_mini all'
]
}),
pxtorem({
rootValue: 16,
unitPrecision: 5,
propList: ['font', 'font-size', 'line-height', 'letter-spacing'],
replace: false,
mediaQuery: false,
minPixelValue: 0,
})
];
const postcssOptions = { from: undefined }
const filterType = /^text\/css$/
const plugins = [
posthtmlPostcss(postcssPlugins, postcssOptions, filterType)
];
const options = {
includeAutoGeneratedTags: true,
removeAttributeQuotes: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortClassName: true,
useShortDoctype: true
}
return src(config.app.html)
.pipe(include({ prefix: '##' }))
.pipe(posthtml(plugins))
.pipe(htmlMinify(options))
.pipe(dest(config.build.html))
}
exports.stream = series(clear, html, stream)
If using plugin "vinyl-source-stream".
The solution to this question would be the following code.
In this code, I used plugins that work with streams.
But this code only converts one file!
You can read more details about each plugin on npmjs.
html-minifier, vinyl-fs, vinyl-source-stream, map-stream
const { src, dest, series } = require('gulp');
const htmlMinify = require('html-minifier');
const vfs = require('vinyl-fs');
const source = require('vinyl-source-stream');
const map = require('map-stream');
const options = {
includeAutoGeneratedTags: true,
removeAttributeQuotes: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortClassName: true,
useShortDoctype: true,
collapseWhitespace: true
};
function sol() {
let minify = function(file, cb) {
cb(null, htmlMinify.minify(file.contents.toString(), options));
};
return vfs
.src(['app/index.html'])
.pipe(map(minify))
.pipe(source('index.html'))
.pipe(vfs.dest('build'));
}
exports.sol = series(sol);
This was the answer to this particular question.
There is a more elegant solution to this problem.
No third party plugins required. I described it in this post.
I'm using #nuxtjs/markdownit to parse markdown files, I want to enable creating permanent links feature in 'markdown-it-anchor' plugin, I used following code in nuxt.config.js but not working:
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
'#nuxtjs/markdownit'
],
markdownit: {
preset: 'default',
linkify: true,
breaks: true,
typographer: true,
html: false,
use: [
'markdown-it-anchor',
'markdown-it-attrs',
'markdown-it-div',
'markdown-it-toc-done-right',
'markdown-it-emoji'
]
},
'markdown-it-anchor': {
level: 1,
// slugify: string => string,
permalink: true,
// renderPermalink: (slug, opts, state, permalink) => {},
permalinkClass: 'header-anchor',
permalinkSymbol: '¶',
permalinkBefore: true
},
Self answering: I found the syntax in this post
markdownit: {
preset: 'default',
linkify: true,
breaks: true,
typographer: true,
html: false,
use: [
[
'markdown-it-anchor',
{
level: 1,
// slugify: string => string,
permalink: true,
// renderPermalink: (slug, opts, state, permalink) => {},
permalinkClass: 'header-anchor',
permalinkSymbol: '¶',
permalinkBefore: true
}
],
'markdown-it-attrs',
'markdown-it-div',
'markdown-it-toc-done-right',
'markdown-it-emoji'
]
},
Consider this:
const a = BigInt(2);
const b = BigInt(2);
const c = a ** b;
Babel will convert this to:
var a = BigInt(2);
var b = BigInt(2);
var c = Math.pow(a, b);
However, Math.pow doesn't work with BigInt. As far as I know, it's impossible to get Babel to ignore a certain line. I found babel-plugin-transform-bigint, but I don't want to load a polyfill for this. If BigInt isn't supported, then I'll just set an upper limit for the input.
My options are to override Math.pow or manually implement exponentiation. Is it impossible to use the native ** operator with BigInt and Babel at the moment?
Also, just confirming, ** would be a syntax error if it isn't supported right?
Edit: babel.config.js:
module.exports = {
presets: [
['#babel/preset-env', {
useBuiltIns: 'usage',
corejs: '2',
exclude: [
'babel-plugin-transform-async-to-generator',
'babel-plugin-transform-regenerator',
],
}],
],
plugins: [
'#babel/plugin-syntax-dynamic-import',
['#babel/plugin-transform-react-jsx', { pragma: 'h' }],
'#babel/plugin-proposal-do-expressions',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-optional-chaining',
/*
Async/await increases file size by a lot.
['module:fast-async', {
'compiler': { 'promises': true, 'generators': false, 'useRuntimeModule': true },
}],
['#babel/plugin-transform-modules-commonjs', {
'strictMode': false,
}],
*/
],
env: {
production: {
plugins: ['transform-react-remove-prop-types'],
},
},
sourceType: 'unambiguous',
};
For those of you getting this problem in Create React App. See the following thread and solutions:
https://github.com/0xs34n/starknet.js/issues/37#issuecomment-955797303
and
https://github.com/babel/babel/issues/13109#issuecomment-826287089
Basically you can change the browserlist of your package.json in order to prevent babel from running its transform-exponentiation-operator plugin like so:
"browserslist": {
"production": [
"chrome >= 67",
"edge >= 79",
"firefox >= 68",
"opera >= 54",
"safari >= 14"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
For non-browser react environments such as react-native-macos, react-native-windows, electron, see the gist here for a way to create your own babel.config.js to choose which plugins/transforms to run:
https://gist.github.com/karanjthakkar/3241808022a75d8068f35a33b57e90c5
There's a twitter thread explaining the problem:
https://twitter.com/geekykaran/status/1082218546799755266
An example of babel.config.js without the babel-plugin-transform-exponentiation-operator applied:
const lazyImports = require('metro-react-native-babel-preset/src/configs/lazy-imports');
module.exports = (api) => {
api.cache(true);
return {
comments: false,
compact: true,
plugins: [
'#babel/plugin-transform-flow-strip-types',
'#babel/plugin-proposal-optional-catch-binding',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-block-scoping',
['#babel/plugin-proposal-class-properties', {
loose: true,
}],
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-syntax-export-default-from',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-computed-properties',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-destructuring',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-function-name',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-literals',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-parameters',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-shorthand-properties',
'#babel/plugin-transform-react-jsx',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-regenerator',
'#babel/plugin-transform-sticky-regex',
'#babel/plugin-transform-unicode-regex',
'#babel/plugin-proposal-export-default-from',
[
'#babel/plugin-transform-modules-commonjs',
{
strict: false,
strictMode: false, // prevent "use strict" injections
lazy: importSpecifier => lazyImports.has(importSpecifier),
allowTopLevelThis: true, // dont rewrite global `this` -> `undefined`
},
],
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-classes',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-arrow-functions'
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-spread',
'#babel/plugin-proposal-object-rest-spread',
// SUPPORTED BY DEFAULT: [
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-template-literals',
// SUPPORTED BY DEFAULT: {loose: true}, // dont 'a'.concat('b'), just use 'a'+'b'
// SUPPORTED BY DEFAULT: ],
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-exponentiation-operator',
// SUPPORTED BY DEFAULT: '#babel/plugin-transform-object-assign',
// SUPPORTED BY DEFAULT: ['#babel/plugin-transform-for-of', {loose: true}],
// 'metro-react-native-babel-preset/src/transforms/transform-symbol-member',
'#babel/plugin-transform-react-display-name',
'#babel/plugin-proposal-optional-chaining',
'#babel/plugin-proposal-nullish-coalescing-operator',
['#babel/plugin-transform-runtime', {
helpers: true,
regenerator: true,
}],
],
};
};
Remember to reset the cache when restarting the bundler with npm/yarn
npm start -- --reset-cache