VS code object rest/spread operator error - javascript

In VS Code editor the JSHint tells me that code below has an error.
const pageSubpartsComponents = {
'page-header': PageHeader,
'page-footer': PageFooter
};
const routes = [{
path: '/',
components: {
default: DefaultLayout,
...pageSubpartsComponents
}
}];
...pageSubpartsComponents has text correction.
The error I get is:
[jshint] Expected '}' to match '{' from line 6 and instead saw
'pageSubpartsComponents'. (E020)
I have .jshintrc file and inside this code:
{
"esversion": 6
}
I know that rest/spread operator is not part of the ES6 but it doesn't allows me to use higher version of ES.
VS Code v 1.25.0-insider
jshint v 0.10.19
What else should I use? Does anyone solve this already?

Related

How to tell a JavaScript formatter to add blank lines between function definitions?

I have some JS files which I want to format nicer with a CLI formatter tool like Prettier. I tried Prettier itself, but I was surprised to find that it doesn't add blank lines between function definitions. I think this would enhance visual structure significantly.
An example might clarify what I'm after. Given the input source code:
import {foo, bar} from "./myfoobar.js"
export var myfirstfunc = function (para) {
...
}
// mysecondfunc does wonderful things
export var mysecondfunc = function (more, para) {
...
}
I would like to see the following output code with blank lines:
import {foo, bar} from "./myfoobar.js"
export var myfirstfunc = function (para) {
...
}
// mysecondfunc does wonderful things
export var mysecondfunc = function (more, para) {
...
}
In my test Prettier doesn't do this. Is there a way to tell Prettier -- or another formatter -- to do this kind of visual structuring?
You can achieve something similar to this by using ESLint's padding-line-between-statements rule. Any sort of STATEMENT_TYPE (such as export, import, var) can be specified to require a blank line between it and another given STATEMENT_TYPE (or wildcard, to match anything).
The following config:
padding-line-between-statements: [
"error",
{ blankLine: "always", prev: "export", next: "*" },
{ blankLine: "always", prev: "import", next: "*" },
{ blankLine: "always", prev: "var", next: "*" },
]
results in automatically fixed code of:
import {foo, bar} from "./myfoobar.js"
export var myfirstfunc = function (para) {
}
// mysecondfunc does wonderful things
export var mysecondfunc = function (more, para) {
}
Demo
Any IDE that supports ESLint's auto-fixing (such as VSCode) should be able to implement this.
Feel free to tweak with the config settings objects to require spaces between different types of statements as desired.

Replacing variable with #rollup/plugin-replace throws error

Problem
I am trying to inject / replace environment variables with #rollup/plugin-replace. Unfortunately, I get this error:
TypeError: can't convert undefined to object
Code
// rollup.config.js
import replace from "#rollup/plugin-replace";
import { config } from "dotenv";
config();
export default {
// ...
plugins: [
replace({
values: { YOUTUBE_API: JSON.stringify(process.env.YOUTUBE_API) },
preventAssignment: true,
}),
// ...
}
And I call it like this:
onMount(() => {
(async function getPopular() {
videos = await axios.get("https://www.googleapis.com/youtube/v3/videos", {
part: "id, snippet, suggestions",
chart: "mostPopular",
key: YOUTUBE_API,
});
})();
});
What I tried
I logged out the variable and so can confirm that it exists. Also, if I remove the stringify function, I get another error:
ReferenceError: blablabblub is not defined
I have done this successfully in other projects. What the heck is wrong here?
So after some digging around with the same issue, I found it was related to object assignment. For example:
export default {
// ...
plugins: [
replace({
values: {
env: {
API_URL: process.env.API_URL,
API_VERSION: process.env.API_VERSION,
}
},
preventAssignment: true,
}),
// ...
}
// in some JS or Svelte file
const config = {
host: env.API_URL,
version: env.API_VERSION
}
// The above will result in a reference error of 'env' not being defined.
// in the same JS or Svelte file..
const envVars = env;
const config = {
host: envVars.API_URL,
version: envVars.API_VERSION
}
// this works just fine!
I haven't had anymore time to investigate, but my gut feeling is that rollup won't replace variable names when they are nested inside an object assignment. It might be nice for an optional flag to allow this, but it might also get very messy hence why they didn't do it.
I hope this helps if it's still an issue for you.

Using Puppeteer&Python on Node.JS to solve captchas

I'm using puppeteer library to access some sites and leach data from their HTML files. for that manner, I've got a Python script that should help me solve each captcha if there is.
now, to run the Python script, I'm using python-shell from npm, and committing this:
let options = {
mode: 'text',
args: [captchas[0].sitekey],
scriptPath: path.resolve('bypass'),
pythonPath: '/usr/bin/python',
}
console.log(`options.scriptPath`, options.scriptPath)
PythonShell.run(
`bypass/bypass.py`,
options,
(err, [, captchaKey]) => {
if (err) throw err
let solutions = [
{
_vendor: captchas[0]._vendor,
id: captchas[0].id,
text: captchaKey,
hasSolution: true,
},
]
resolve({ solutions })
}
)
I've got this error -
Solving captcha...
options.scriptPath MY_PATH/backend/bypass
file:///MY_PATH/backend/bypass/captchaBypasser.js:18
(err, [, captchaKey]) => {
^
TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))
at file:///MY_PATH/backend/bypass/captchaBypasser.js:18
at PythonShell._endCallback (/MY_PATH/backend/node_modules/python-shell/index.js:254:20)
at terminateIfNeeded (/MY_PATH/backend/node_modules/python-shell/index.js:209:39)
at ChildProcess.<anonymous> (/MY_PATH/backend/node_modules/python-shell/index.js:182:13)
I've tried also to use spawn of child_process, like this:
const location = path.resolve('bypass/bypass.py')
console.log(`python ${location} ${captchas[0].sitekey}`)
const run = spawn('python', [location, captchas[0].sitekey])
run.stdout.on('data', ([, captchaKey]) => {
let solutions = [
{
_vendor: captchas[0]._vendor,
id: captchas[0].id,
text: captchaKey,
hasSolution: true,
},
]
resolve({ solutions })
})
and it appears to just crush without even an outcome.
So I've tried to try the actual command line:
python /MY_PATH/backend/bypass/bypass.py ae7317...TOKEN...d0dab8b75
BY THE WAY - I've TRYED ALSO python3 WITH VERSION 3.10.0
And now I've got this error:
from hcapbypass import bypass
File "/MY_PATH/backend/bypass/hcapbypass.py", line 35
def N_Data(req) -> str:
^
So I tried to use the latest version of Python, 3.10.0, that came out like a few weeks ago, and that's the outcome:
File "/MY_PATH/backend/bypass/bypass.py", line 4, in <module>
captcha_solved = bypass(sys.argv[1], 'google.com', True)
TypeError: bypass() missing 1 required positional argument: 's'
For your full understanding, here is the bypass and the solver codes:
bypass.py
from hcapbypass import bypass
import sys
captcha_solved = bypass(sys.argv[1], 'google.com', True)
print(captcha_solved)
hcapbypass
Link to github
Does anyone know what to do?
Thanks a lot!!!
OK, ive got the solution:
inside the hcapbypass.py file, the httpx module isn't presented, so I've created an environment with bin & lib folders to install it locally.
In addition, few functions got an argument that doesn't exist.
And of course, destructuring an array that is null / undefined - throws an error!

Lint imported object destructuring [duplicate]

The rule that I'm looking should show error in this case:
import {MY_CONSTANT1, MY_CONSTANT2, MY_CONSTANT3}
And considered as fine in this case:
import {
MY_CONSTANT1,
MY_CONSTANT2,
MY_CONSTANT3
}
Is there such eslint rule?
I was looking for such a rule for both import and export declaration.
As a result I've made a plugin with autofix.
So plugin transforms the code
import { k1, k2 } from 'something'
into
import {
k1,
k2
} from 'something'
and code
export { name1, name2, nameN }
into
export {
name1,
name2,
nameN
}
Edit:
Anton Antonov made a plugin that enforces this rule better than object-curly-newline can: https://stackoverflow.com/a/60477269/6179417
Old answer
Add the object-curly-newline rule to your .eslintrc.json, where at least ImportDeclaration is set to always (the other settings have no effect for enforcing newlines in import declarations).
Example:
"object-curly-newline": ["error", {
"ObjectExpression": "always",
"ObjectPattern": { "multiline": true },
"ImportDeclaration": "always",
"ExportDeclaration": { "multiline": true, "minProperties": 3 }
}]
This pattern will now result in an error:
While this is valid:
However, there is a catch - this rule only requires newlines after the opening brace and before the closing brace, so you can still double up on imports as long as they have newlines in between the braces:
Update on Anton Antonov answer for eslint 8
Because Anton Antonovs repository has been archived and gives meta.fixable error with eslint 8. I Recommend to use ruudandriessen fork of the project .
How to use fork:
Install fork
npm install eslint-plugin-modules-newlines --save-dev
Change all references inside eslint config file of modules-newline -> modules-newlines
Error:
ESLint: Fixable rules must set the `meta.fixable` property to "code" or "whitespace".
Occurred while linting ... Rule: "modules-newline/import-declaration-newline".
Please see the 'ESLint' output channel for details.
I was looking for the solution and unfortunately have only found your question. I have decided to learn a bit about how eslint works and how to write your own plugins and created mine. If you know the parsed the AST node structure it is really easy to work with. Here is the plugin's main file. Autofix is more tricky though so I do not include it as it biased towards my formatting standards.
module.exports = {
rules: {
'single-import-per-line': {
create (context) {
return {
ImportDeclaration(node) {
if (node.specifiers.length < 2) {
return;
}
let previousImport = node.specifiers[0];
for (let i = 1; i < node.specifiers.length; i++) {
const currentImport = node.specifiers[i];
// Omit the first condition if you want to put default imports on a new line as well
if (previousImport.type !== 'ImportDefaultSpecifier'
&& currentImport.loc.start.line === previousImport.loc.end.line
) {
context.report({ node, message: 'Your message' });
return;
}
previousImport = currentImport;
}
},
};
},
},
},
};
you can try this
"semicolon": [true, "always"]

Find ES6-module in which entity is declared

TL;DR There is some imported entity on ES6-module. Should find original ES module and line number, where this entity has been initially declared - not re-imported / re-exported.
There is some hierarchy of nested imported ES6-modules, some of which are not controlled by library code and had been imported from well-known place - it's some user-side configuration file.
Imagine following files structure:
config.js (not controlled)
import nested from './nested';
export default {
param1: { aaa: 10, bbb: 20 },
param2: nested
}
nested.js (not controlled)
export default {
ccc: 30,
ddd: 40
}
index.js (controlled)
import config from './config'
const ddd = config.ddd;
if(notValid(ddd)) {
const decl = %FIND_DECLARATION%(ddd);
console.log('Config variable "config.ddd" is not valid');
console.log('You declared it here: ', decl);
}
Output should be like following
You declared it here:
File webpack://./nested.js , line 2
ddd: 40
^^^^^^^
Should write function %FIND_DECLARATION%, which can find original ES-module and line number for some object declaration, and retrieve it's source code
Environment is webpack. Any dirty hacks are welcome if can't be solve without it.

Categories