英文:
How to get object argument from npm script (NodeJS + TypeScript)
问题
我想通过NPM脚本传递一个对象,如下所示:
"update-user-roles": "ts-node user-roles.ts {PAID_USER: true, VIP: true}"
我的函数接收到对象,但会不断添加额外的逗号,因此无法正确更新用户。我该如何接收原样的对象?
async function updateUserRoles(roles: any) {
const userID = await getAuth().then((res) => res.uid);
updateUser({
userID: userID,
fields: {
roles: {
roles
},
}
})
console.log(`User roles successfully added: ${roles}`)
}
const rolesString = JSON.stringify(process.argv.slice(2))
updateUserRoles(JSON.parse(rolesString))
我收到以下消息:
User roles successfully added: {PAID_USER:,true,,VIP:,true}
英文:
I want to pass an object via NPM script like
"update-user-roles": "ts-node user-roles.ts {PAID_USER: true, VIP: true}"
My function picks up the object but keeps adding additional commas so it's not updating the user correctly. How do I receive the object as is?
async function updateUserRoles(roles: any) {
const userID = await getAuth().then((res) => res.uid);
updateUser({
userID: userID,
fields: {
roles: {
roles
},
}
})
console.log(`User roles successfully added: ${roles}`)
}
const rolesString = JSON.stringify(process.argv.slice(2))
updateUserRoles(JSON.parse(rolesString))
I get the following message:
User roles successfully added: {PAID_USER:,true,,VIP:,true}
答案1
得分: 1
以下是翻译好的部分:
原因是Node.js会在空格处拆分命令行参数,所以你得到逗号,
。process.argv
数组会像这样:
process.argv
属性返回一个包含在启动Node.js进程时传递的命令行参数的数组。
选项1. 传递JSON字符串
$ npx ts-node ./index.ts '{ "PAID_USER": true, "VIP": true }'
index.ts
console.log(process.argv);
console.log(JSON.parse(process.argv.slice(2)[0]));
输出:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{ "PAID_USER": true, "VIP": true }'
]
{ PAID_USER: true, VIP: true }
选项2. 传递字符串并将其解析为JSON字符串。
npx ts-node ./index.ts '{PAID_USER: true, VIP: true}'
index.ts
:
console.log(process.argv);
const arg = process.argv.slice(2)[0];
const obj = JSON.parse(JSON.stringify(eval('('+arg+')')));
console.log(obj, typeof obj, obj.PAID_USER, obj.VIP);
输出:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{PAID_USER: true, VIP: true}'
]
{ PAID_USER: true, VIP: true } object true true
选项3. 使用 minimistjs 包。
英文:
The reason why you got comma ,
is because Nodejs will split command-line arguments at whitespace. The process.argv
array will be like this:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{PAID_USER:',
'true,',
'VIP:',
'true}'
]
> The process.argv
property returns an array containing the command-line arguments passed when the Node.js process was launched.
Option 1. Pass a JSON string
$ npx ts-node ./index.ts '{"PAID_USER": true, "VIP": true}'
index.ts
console.log(process.argv);
console.log(JSON.parse(process.argv.slice(2)[0]));
Output:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{"PAID_USER": true, "VIP": true}'
]
{ PAID_USER: true, VIP: true }
Option 2. Pass a string and parse it to a JSON string.
npx ts-node ./index.ts '{PAID_USER: true, VIP: true}'
index.ts
:
console.log(process.argv);
const arg = process.argv.slice(2)[0];
const obj = JSON.parse(JSON.stringify(eval('(' + arg + ')')));
console.log(obj, typeof obj, obj.PAID_USER, obj.VIP);
Output:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{PAID_USER: true, VIP: true}'
]
{ PAID_USER: true, VIP: true } object true true
Option 3. Use minimistjs package.
答案2
得分: 0
我们可以使用双引号来包裹这个对象。
"update-user-roles": "ts-node user-roles.ts \"{\\\"PAID_USER\\\": true, \\\"VIP\\\": true}\""
之后:
async function updateUserRoles(rolesString: string) {
const roles = JSON.parse(rolesString);
const userID = await getAuth().then((res) => res.uid);
updateUser({
userID: userID,
fields: {
roles: roles
}
});
console.log(`用户角色已成功添加:${JSON.stringify(roles)}`);
}
它应该能正常工作。
英文:
We can use double quotes to wrap the object.
"update-user-roles": "ts-node user-roles.ts \"{\\\"PAID_USER\\\": true, \\\"VIP\\\": true}\""
After that:
async function updateUserRoles(rolesString: string) {
const roles = JSON.parse(rolesString);
const userID = await getAuth().then((res) => res.uid);
updateUser({
userID: userID,
fields: {
roles: roles
}
});
console.log(`User roles successfully added: ${JSON.stringify(roles)}`);
}
It should work.
答案3
得分: 0
如您可能已经注意到,您并未传递一个真实的对象作为参数,而是一个不是有效的 JSON 的字符串。
首先,参数必须包装和转义(\"{...}\"),以防止它被空格分割。
接下来是两个辅助函数。一个用于使用键来读取参数(myObject)。第二个用于将字符串转换为对象(伪 JSON)。
"update-user-roles": "ts-node user-roles.ts myObject=\"{PAID_USER: true, VIP: true}\""
以下是最小的 JavaScript 功能。
const args = process.argv.slice(2).reduce((acc, arg) => {
let [k, v = true] = arg.split('=');
acc[k] = v;
return acc;
}, {});
console.log(args) // { myObject: '{PAID_USER: true, VIP: true}' }
const parseJSON = obj => Function('"use strict";return (' + obj + ')')();
const myObject = parseJSON(args.myObject); // { PAID_USER: true, VIP: true }
然后,您的函数调用将是:
updateUserRoles(myObject);
英文:
As you may have noticed, you are not passing in a real object as a parameter, but a string that is not a valid json.
First, the parameter must be wrapped and escaped (\"{...}\") so that it is not split up by the blanks.
Here then come two helper functions. One to read out the parameter using a key (myObject). And the second to make an object out of the string (fake json).
"update-user-roles": "ts-node user-roles.ts myObject=\"{PAID_USER: true, VIP: true}\""
And here is the minimal JavaScript functionality.
const args = process.argv.slice(2).reduce((acc, arg) => {
let [k, v = true] = arg.split('=');
acc[k] = v;
return acc;
}, {});
console.log(args) // { myObject: '{PAID_USER: true, VIP: true}' }
const parseJSON = obj => Function('"use strict";return (' + obj + ')')();
const myObject = parseJSON(args.myObject); // { PAID_USER: true, VIP: true }
Your function call would then be
updateUserRoles(myObject);
答案4
得分: 0
我无法让这些答案中的任何一个起作用,最终使用以下方法找到了解决方案:
脚本:
"ts-node user-roles.ts '{\"PAID_USER\": true, \"VIP\": true}'"
使用JSON.parse将对象字符串解析回对象并传递给函数:
const objArgStr = process.argv[2];
if (!objArgStr) {
console.error('未提供参数。');
process.exit(1);
}
const objArg = JSON.parse(objArgStr);
console.log('对象参数:', objArg);
updateUserRoles(objArg);
英文:
I couldn't get any of these answers to work, finally got a solution using the following:
The script:
"ts-node user-roles.ts '{\"PAID_USER\": true, \"VIP\": true}'"
Parse the object string back into an object using JSON.parse and pass to function:
const objArgStr = process.argv[2];
if (!objArgStr) {
console.error('No argument provided.');
process.exit(1);
}
const objArg = JSON.parse(objArgStr);
console.log('Object argument: ', objArg);
updateUserRoles(objArg)
答案5
得分: 0
问题在于Node.js将参数视为字符串,并按空格拆分它们,所以roles
看起来像这样:
[
"{PAID_USER:",
"true,",
"VIP:",
"true}"
]
此外,这不是JSON字符串。您必须将其转换为JSON并用引号括起来,以便Node.js将整个内容视为一个参数:
ts-node user-roles.ts "{\"PAID_USER\": true, \"VIP\": true}"
不要忘记在字符串中转义引号!!
在user-roles.ts
中:
const rolesString = process.argv.slice(2)[0]
updateUserRoles(JSON.parse(rolesString))
因为process.argv.slice(2)
返回一个数组,所以您需要获取第一个参数。您也不需要使用JSON.stringify()
。可以简化为:
updateUserRoles(JSON.parse(process.argv.slice[2]))
英文:
The problem is that Node.js treats arguments as string and splits them by whitespace, so roles
looks something like this:
[
"{PAID_USER:",
"true,",
"VIP:",
"true}"
]
Also, it's not a JSON string. You have to turn that to JSON and wrap in quotes so Node.js will count the entire thing as one argument:
ts-node user-roles.ts "{\"PAID_USER\": true, \"VIP\": true}"
Don't forget to escape quotes in string!!
In user-roles.ts
:
const rolesString = process.argv.slice(2)[0]
updateUserRoles(JSON.parse(rolesString))
Because process.argv.slice(2)
returns an Array, you'll need to get the first argument. You also don't need JSON.stringify()
.
It can be simplified like this:
updateUserRoles(JSON.parse(process.argv.slice[2]))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论