svelte-i18n
Advanced tools
Comparing version 3.2.5 to 3.2.6
@@ -0,1 +1,6 @@ | ||
## [3.2.6](https://github.com/kaisermann/svelte-i18n/compare/v3.2.5...v3.2.6) (2020-11-20) | ||
### Changed | ||
- Don't minify CLI for better debugging. | ||
## [3.2.5](https://github.com/kaisermann/svelte-i18n/compare/v3.2.4...v3.2.5) (2020-11-08) | ||
@@ -2,0 +7,0 @@ |
274
dist/cli.js
#!/usr/bin/env node | ||
"use strict";var e=require("fs"),t=require("path"),r=require("sade"),n=require("tiny-glob"),i=require("svelte/compiler"),o=require("estree-walker"),a=require("dlv");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function s(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var c=l(e),u=l(r),f=l(n),p=l(a); | ||
'use strict'; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var sade = require('sade'); | ||
var glob = require('tiny-glob'); | ||
var compiler = require('svelte/compiler'); | ||
var estreeWalker = require('estree-walker'); | ||
var dlv = require('dlv'); | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
function _interopNamespace(e) { | ||
if (e && e.__esModule) return e; | ||
var n = Object.create(null); | ||
if (e) { | ||
Object.keys(e).forEach(function (k) { | ||
if (k !== 'default') { | ||
var d = Object.getOwnPropertyDescriptor(e, k); | ||
Object.defineProperty(n, k, d.get ? d : { | ||
enumerable: true, | ||
get: function () { | ||
return e[k]; | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
n['default'] = e; | ||
return Object.freeze(n); | ||
} | ||
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); | ||
var sade__default = /*#__PURE__*/_interopDefaultLegacy(sade); | ||
var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob); | ||
var dlv__default = /*#__PURE__*/_interopDefaultLegacy(dlv); | ||
/*! ***************************************************************************** | ||
@@ -17,2 +53,236 @@ Copyright (c) Microsoft Corporation. | ||
***************************************************************************** */ | ||
function d(e){var t="function"==typeof Symbol&&Symbol.iterator,r=t&&e[t],n=0;if(r)return r.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&n>=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function m(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,r=e[Symbol.asyncIterator];return r?r.call(e):(e=d(e),t={},n("next"),n("throw"),n("return"),t[Symbol.asyncIterator]=function(){return this},t);function n(r){t[r]=e[r]&&function(t){return new Promise((function(n,i){(function(e,t,r,n){Promise.resolve(n).then((function(t){e({value:t,done:r})}),t)})(n,i,(t=e[r](t)).done,t.value)}))}}}function v(e,t,r){const n=t.replace(/\[(\w+)\]/gi,".$1").split(".");return n.reduce(((e,t,i)=>{return t in e?e[t]:i<n.length-1?(o=n[i+1],Number.isNaN(parseInt(o,10))?e[t]={}:e[t]=[]):e[t]=r;var o}),e)}function h(e){return e.properties.reduce(((e,t)=>{if("Literal"===t.value.type&&t.value.value!==Object(t.value.value)){e[t.key.name]=t.value.value}return e}),{})}const y=new Set(["format","_","t"]);function w(e){return e.instance?e.instance.content.body.filter((e=>"ImportDeclaration"===e.type&&"svelte-i18n"===e.source.value)):[]}function b(e){return e.specifiers.find((e=>"imported"in e&&"defineMessages"===e.imported.name))}function g(e){const t=w(e);if(0===t.length)return[];const r=new Set(t.flatMap((e=>function(e){return e.specifiers.filter((e=>"imported"in e&&y.has(e.imported.name)))}(e).map((e=>e.local.name)))));if(0===r.size)return[];const n=[];function i(e){(function(e,t){if("CallExpression"!==e.type)return!1;let r;if("Identifier"===e.callee.type&&(r=e.callee),!r||"Identifier"!==r.type)return!1;const n=r.name.slice(1);return t.has(n)})(e,r)&&(n.push(e),this.skip())}return o.walk(e.instance,{enter:i}),o.walk(e.html,{enter:i}),n}function j(e){const t=i.parse(e),r=g(t);return[...function(e){const t=[],r=w(e).find(b);if(null==r)return[];const n=b(r).local.name;return o.walk(e.instance,{enter(e){if(!1===function(e,t){return"CallExpression"===e.type&&e.callee&&"Identifier"===e.callee.type&&e.callee.name===t}(e,n))return;const[r]=e.arguments;"ObjectExpression"===r.type&&(t.push(r),this.skip())}}),t.flatMap((e=>e.properties.map((e=>{if("Property"!==e.type)throw new Error(`Found invalid '${e.type}' at L${e.loc.start.line}:${e.loc.start.column}`);return e.value}))))}(t).map((e=>h(e))),...r.map((e=>{const[t,r]=e.arguments;let n;if("ObjectExpression"===t.type)n=h(t);else{const e=t.value;r&&"ObjectExpression"===r.type?(n=h(r),n.id=e):n={id:e}}return null==(null==n?void 0:n.id)?null:n}))].filter(Boolean)}function O(e,{accumulator:t={},shallow:r=!1,overwrite:n=!1}={}){return j(e).forEach((e=>{let i=e.default;if(void 0===i&&(i=""),r){if(!1===n&&e.id in t)return;t[e.id]=i}else{if(!1===n&&void 0!==p.default(t,e.id))return;v(t,e.id,i)}})),t}const{readFile:S,writeFile:x,mkdir:E,access:k}=c.default.promises,I=u.default("svelte-i18n");I.command("extract <glob> [output]").describe("extract all message definitions from files to a json").option("-s, --shallow","extract to a shallow dictionary (ids with dots interpreted as strings, not paths)",!1).option("--overwrite","overwrite the content of the output file instead of just appending new properties",!1).option("-c, --config <dir>",'path to the "svelte.config.js" file',process.cwd()).action((async(e,r,{shallow:n,overwrite:o,config:a})=>{var l,c;const u=(await f.default(e)).filter((e=>e.match(/\.html|svelte$/i))),p=await Promise.resolve().then((function(){return s(require(t.resolve(a,"svelte.config.js")))})).catch((()=>null));let d={};null!=r&&!1===o&&await(e=>k(e).then((()=>!0)).catch((()=>!1)))(r)&&(d=await S(r).then((e=>JSON.parse(e.toString()))).catch((e=>{console.warn(e),d={}})));try{for(var v,h=m(u);!(v=await h.next()).done;){const e=v.value;let t=(await S(e)).toString();if(null==p?void 0:p.preprocess){t=(await i.preprocess(t,p.preprocess,{filename:e})).code}O(t,{filePath:e,accumulator:d,shallow:n})}}catch(e){l={error:e}}finally{try{v&&!v.done&&(c=h.return)&&await c.call(h)}finally{if(l)throw l.error}}const y=JSON.stringify(d,null," ");if(null==r)return console.log(y);await E(t.dirname(r),{recursive:!0}),await x(r,y)})),I.parse(process.argv); | ||
function __values(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
} | ||
function __asyncValues(o) { | ||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); | ||
var m = o[Symbol.asyncIterator], i; | ||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); | ||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } | ||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } | ||
} | ||
/* eslint-disable no-multi-assign */ | ||
/* eslint-disable no-return-assign */ | ||
const isNumberString = (n) => !Number.isNaN(parseInt(n, 10)); | ||
function deepSet(obj, path, value) { | ||
const parts = path.replace(/\[(\w+)\]/gi, '.$1').split('.'); | ||
return parts.reduce((ref, part, i) => { | ||
if (part in ref) | ||
return (ref = ref[part]); | ||
if (i < parts.length - 1) { | ||
if (isNumberString(parts[i + 1])) { | ||
return (ref = ref[part] = []); | ||
} | ||
return (ref = ref[part] = {}); | ||
} | ||
return (ref[part] = value); | ||
}, obj); | ||
} | ||
function getObjFromExpression(exprNode) { | ||
return exprNode.properties.reduce((acc, prop) => { | ||
// we only want primitives | ||
if (prop.value.type === 'Literal' && | ||
prop.value.value !== Object(prop.value.value)) { | ||
const key = prop.key.name; | ||
acc[key] = prop.value.value; | ||
} | ||
return acc; | ||
}, {}); | ||
} | ||
const LIB_NAME = 'svelte-i18n'; | ||
const DEFINE_MESSAGES_METHOD_NAME = 'defineMessages'; | ||
const FORMAT_METHOD_NAMES = new Set(['format', '_', 't']); | ||
function isFormatCall(node, imports) { | ||
if (node.type !== 'CallExpression') | ||
return false; | ||
let identifier; | ||
if (node.callee.type === 'Identifier') { | ||
identifier = node.callee; | ||
} | ||
if (!identifier || identifier.type !== 'Identifier') { | ||
return false; | ||
} | ||
const methodName = identifier.name.slice(1); | ||
return imports.has(methodName); | ||
} | ||
function isMessagesDefinitionCall(node, methodName) { | ||
if (node.type !== 'CallExpression') | ||
return false; | ||
return (node.callee && | ||
node.callee.type === 'Identifier' && | ||
node.callee.name === methodName); | ||
} | ||
function getLibImportDeclarations(ast) { | ||
return (ast.instance | ||
? ast.instance.content.body.filter((node) => node.type === 'ImportDeclaration' && node.source.value === LIB_NAME) | ||
: []); | ||
} | ||
function getDefineMessagesSpecifier(decl) { | ||
return decl.specifiers.find((spec) => 'imported' in spec && spec.imported.name === DEFINE_MESSAGES_METHOD_NAME); | ||
} | ||
function getFormatSpecifiers(decl) { | ||
return decl.specifiers.filter((spec) => 'imported' in spec && FORMAT_METHOD_NAMES.has(spec.imported.name)); | ||
} | ||
function collectFormatCalls(ast) { | ||
const importDecls = getLibImportDeclarations(ast); | ||
if (importDecls.length === 0) | ||
return []; | ||
const imports = new Set(importDecls.flatMap((decl) => getFormatSpecifiers(decl).map((n) => n.local.name))); | ||
if (imports.size === 0) | ||
return []; | ||
const calls = []; | ||
function enter(node) { | ||
if (isFormatCall(node, imports)) { | ||
calls.push(node); | ||
this.skip(); | ||
} | ||
} | ||
estreeWalker.walk(ast.instance, { enter }); | ||
estreeWalker.walk(ast.html, { enter }); | ||
return calls; | ||
} | ||
function collectMessageDefinitions(ast) { | ||
const definitions = []; | ||
const defineImportDecl = getLibImportDeclarations(ast).find(getDefineMessagesSpecifier); | ||
if (defineImportDecl == null) | ||
return []; | ||
const defineMethodName = getDefineMessagesSpecifier(defineImportDecl).local | ||
.name; | ||
estreeWalker.walk(ast.instance, { | ||
enter(node) { | ||
if (isMessagesDefinitionCall(node, defineMethodName) === false) | ||
return; | ||
const [arg] = node.arguments; | ||
if (arg.type === 'ObjectExpression') { | ||
definitions.push(arg); | ||
this.skip(); | ||
} | ||
}, | ||
}); | ||
return definitions.flatMap((definitionDict) => definitionDict.properties.map((propNode) => { | ||
if (propNode.type !== 'Property') { | ||
throw new Error(`Found invalid '${propNode.type}' at L${propNode.loc.start.line}:${propNode.loc.start.column}`); | ||
} | ||
return propNode.value; | ||
})); | ||
} | ||
function collectMessages(markup) { | ||
const ast = compiler.parse(markup); | ||
const calls = collectFormatCalls(ast); | ||
const definitions = collectMessageDefinitions(ast); | ||
return [ | ||
...definitions.map((definition) => getObjFromExpression(definition)), | ||
...calls.map((call) => { | ||
const [pathNode, options] = call.arguments; | ||
let messageObj; | ||
if (pathNode.type === 'ObjectExpression') { | ||
// _({ ...opts }) | ||
messageObj = getObjFromExpression(pathNode); | ||
} | ||
else { | ||
const node = pathNode; | ||
const id = node.value; | ||
if (options && options.type === 'ObjectExpression') { | ||
// _(id, { ...opts }) | ||
messageObj = getObjFromExpression(options); | ||
messageObj.id = id; | ||
} | ||
else { | ||
// _(id) | ||
messageObj = { id }; | ||
} | ||
} | ||
if ((messageObj === null || messageObj === void 0 ? void 0 : messageObj.id) == null) | ||
return null; | ||
return messageObj; | ||
}), | ||
].filter(Boolean); | ||
} | ||
function extractMessages(markup, { accumulator = {}, shallow = false, overwrite = false } = {}) { | ||
collectMessages(markup).forEach((messageObj) => { | ||
let defaultValue = messageObj.default; | ||
if (typeof defaultValue === 'undefined') { | ||
defaultValue = ''; | ||
} | ||
if (shallow) { | ||
if (overwrite === false && messageObj.id in accumulator) { | ||
return; | ||
} | ||
accumulator[messageObj.id] = defaultValue; | ||
} | ||
else { | ||
if (overwrite === false && | ||
typeof dlv__default['default'](accumulator, messageObj.id) !== 'undefined') { | ||
return; | ||
} | ||
deepSet(accumulator, messageObj.id, defaultValue); | ||
} | ||
}); | ||
return accumulator; | ||
} | ||
const { readFile, writeFile, mkdir, access } = fs__default['default'].promises; | ||
const fileExists = (path) => access(path) | ||
.then(() => true) | ||
.catch(() => false); | ||
const program = sade__default['default']('svelte-i18n'); | ||
program | ||
.command('extract <glob> [output]') | ||
.describe('extract all message definitions from files to a json') | ||
.option('-s, --shallow', 'extract to a shallow dictionary (ids with dots interpreted as strings, not paths)', false) | ||
.option('--overwrite', 'overwrite the content of the output file instead of just appending new properties', false) | ||
.option('-c, --config <dir>', 'path to the "svelte.config.js" file', process.cwd()) | ||
.action(async (globStr, output, { shallow, overwrite, config }) => { | ||
var e_1, _a; | ||
const filesToExtract = (await glob__default['default'](globStr)).filter((file) => file.match(/\.html|svelte$/i)); | ||
const svelteConfig = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(path.resolve(config, 'svelte.config.js'))); }).catch(() => null); | ||
let accumulator = {}; | ||
if (output != null && overwrite === false && (await fileExists(output))) { | ||
accumulator = await readFile(output) | ||
.then((file) => JSON.parse(file.toString())) | ||
.catch((e) => { | ||
console.warn(e); | ||
accumulator = {}; | ||
}); | ||
} | ||
try { | ||
for (var filesToExtract_1 = __asyncValues(filesToExtract), filesToExtract_1_1; filesToExtract_1_1 = await filesToExtract_1.next(), !filesToExtract_1_1.done;) { | ||
const filePath = filesToExtract_1_1.value; | ||
const buffer = await readFile(filePath); | ||
let content = buffer.toString(); | ||
if (svelteConfig === null || svelteConfig === void 0 ? void 0 : svelteConfig.preprocess) { | ||
const processed = await compiler.preprocess(content, svelteConfig.preprocess, { | ||
filename: filePath, | ||
}); | ||
content = processed.code; | ||
} | ||
extractMessages(content, { filePath, accumulator, shallow }); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (filesToExtract_1_1 && !filesToExtract_1_1.done && (_a = filesToExtract_1.return)) await _a.call(filesToExtract_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
const jsonDictionary = JSON.stringify(accumulator, null, ' '); | ||
if (output == null) | ||
return console.log(jsonDictionary); | ||
await mkdir(path.dirname(output), { recursive: true }); | ||
await writeFile(output, jsonDictionary); | ||
}); | ||
program.parse(process.argv); |
{ | ||
"name": "svelte-i18n", | ||
"version": "3.2.5", | ||
"version": "3.2.6", | ||
"main": "dist/runtime.cjs.js", | ||
@@ -5,0 +5,0 @@ "module": "dist/runtime.esm.js", |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
49136
456
2