babel-plugin-kea
Advanced tools
Comparing version 0.1.0 to 3.0.0
147
lib/index.js
'use strict'; | ||
function _unsupportedIterableToArray(o, minLen) { | ||
if (!o) return; | ||
if (typeof o === "string") return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
if (n === "Object" && o.constructor) n = o.constructor.name; | ||
if (n === "Map" || n === "Set") return Array.from(n); | ||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | ||
} | ||
function _arrayLikeToArray(arr, len) { | ||
if (len == null || len > arr.length) len = arr.length; | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
function _createForOfIteratorHelperLoose(o) { | ||
var i = 0; | ||
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { | ||
if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) return function () { | ||
if (i >= o.length) return { | ||
done: true | ||
}; | ||
return { | ||
done: false, | ||
value: o[i++] | ||
}; | ||
}; | ||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
i = o[Symbol.iterator](); | ||
return i.next.bind(i); | ||
} | ||
var nodePath = require('path'); | ||
function index (_ref) { | ||
var t = _ref.types, | ||
template = _ref.template; | ||
var t = _ref.types; | ||
@@ -12,16 +48,5 @@ function isKeaCall(node) { | ||
name: 'kea' | ||
}) && node.arguments.length === 1 && t.isObjectExpression(node.arguments[0]); | ||
}) && node.arguments.length === 1 && (t.isObjectExpression(node.arguments[0]) || t.isArrayExpression(node.arguments[0])); | ||
} | ||
function buildPathProperty(node, pathParts) { | ||
var hasKey = node.arguments[0].properties.find(function (property) { | ||
return t.isIdentifier(property.key, { | ||
name: 'key' | ||
}); | ||
}); | ||
var builder = hasKey ? template('const a = { path: (key) => ' + JSON.stringify(pathParts).replace(/\]$/, ', key]') + ' }') : template('const a = { path: () => ' + JSON.stringify(pathParts) + ' }'); | ||
var builtNodes = builder(); | ||
return builtNodes.declarations[0].init.properties[0]; | ||
} | ||
function getLocalPath(state) { | ||
@@ -36,17 +61,37 @@ var root = state.file.opts.root; | ||
} | ||
/** Format: { 'kea': [[importedName, localNAme], ['path', 'keaPath']] }, */ | ||
function hasPathProperty(path) { | ||
return path.node.arguments[0].properties.find(function (property) { | ||
return t.isIdentifier(property.key, { | ||
name: 'path' | ||
}); | ||
}); | ||
} | ||
var imports = {}; | ||
/** Format: { 'kea': ImportDeclaration } */ | ||
var importDeclarations = {}; | ||
var mustImportPath = false; | ||
var KeaVisitor = { | ||
CallExpression: function CallExpression(path) { | ||
if (!isKeaCall(path.node) || hasPathProperty(path)) { | ||
// gather all imports | ||
ImportDeclaration: function ImportDeclaration(path) { | ||
if (t.isStringLiteral(path.node.source)) { | ||
var importFrom = path.node.source.value; | ||
if (!imports[importFrom]) { | ||
imports[importFrom] = []; | ||
} | ||
if (!importDeclarations[importFrom]) { | ||
importDeclarations[importFrom] = path; | ||
} | ||
for (var _iterator = _createForOfIteratorHelperLoose(path.node.specifiers), _step; !(_step = _iterator()).done;) { | ||
var specifier = _step.value; | ||
imports[importFrom].push([specifier.imported.name, specifier.local.name]); | ||
} | ||
} | ||
}, | ||
CallExpression: function CallExpression(path, state) { | ||
// only look at kea calls | ||
if (!isKeaCall(path.node)) { | ||
return; | ||
} | ||
} // unique path | ||
this.counter += 1; | ||
@@ -63,4 +108,40 @@ var pathParts = this.pathParts; | ||
var pathProperty = buildPathProperty(path.node, pathParts); | ||
path.node.arguments[0].properties.push(pathProperty); | ||
if (t.isObjectExpression(path.node.arguments[0])) { | ||
// kea 2.0 object | ||
if (!path.node.arguments[0].properties.find(function (property) { | ||
return t.isIdentifier(property.key, { | ||
name: 'path' | ||
}); | ||
})) { | ||
var pathProperty = t.objectProperty(t.identifier('path'), t.arrayExpression(pathParts.map(function (str) { | ||
return t.stringLiteral(str); | ||
}))); | ||
path.node.arguments[0].properties = [pathProperty].concat(path.node.arguments[0].properties); | ||
} | ||
} else if (t.isArrayExpression(path.node.arguments[0])) { | ||
// kea 3.0 builder | ||
if (!path.node.arguments[0].elements.find(function (element) { | ||
return t.isCallExpression(element) && t.isIdentifier(element.callee, { | ||
name: 'path' | ||
}); | ||
})) { | ||
var _imports$kea; | ||
var _ref2 = ((_imports$kea = imports['kea']) === null || _imports$kea === void 0 ? void 0 : _imports$kea.find(function (_ref3) { | ||
var importedName = _ref3[0]; | ||
return importedName === 'path'; | ||
})) || [], | ||
pathImportedAs = _ref2[1]; | ||
if (!pathImportedAs) { | ||
mustImportPath = true; | ||
pathImportedAs = 'path'; | ||
} | ||
var pathBuilder = t.callExpression(t.identifier(pathImportedAs), [t.arrayExpression(pathParts.map(function (str) { | ||
return t.stringLiteral(str); | ||
}))]); | ||
path.node.arguments[0].elements = [pathBuilder].concat(path.node.arguments[0].elements); | ||
} | ||
} | ||
} | ||
@@ -81,2 +162,16 @@ }; | ||
}); | ||
if (mustImportPath) { | ||
// must add path | ||
if (importDeclarations['kea']) { | ||
// already imports kea | ||
importDeclarations['kea'].node.specifiers = [].concat(importDeclarations['kea'].node.specifiers || [], [t.importSpecifier(t.identifier('path'), t.identifier('path'))]); | ||
} else { | ||
path.node.body = [].concat(path.node.body.filter(function (n) { | ||
return t.isImportDeclaration(n); | ||
}), [t.importDeclaration([t.importSpecifier(t.identifier('path'), t.identifier('path'))], t.stringLiteral('kea'))], path.node.body.filter(function (n) { | ||
return !t.isImportDeclaration(n); | ||
})); | ||
} | ||
} | ||
} | ||
@@ -83,0 +178,0 @@ } |
{ | ||
"name": "babel-plugin-kea", | ||
"version": "0.1.0", | ||
"version": "3.0.0", | ||
"description": "Kea Babel Plugin", | ||
@@ -11,5 +11,5 @@ "main": "lib/index.js", | ||
"lint": "eslint src/**", | ||
"prepublish": "npm run test && npm run build", | ||
"prepublishOnly": "npm run test && npm run build", | ||
"start": "npm run watch", | ||
"test": "echo \"No tests yet\"" | ||
"test": "jest" | ||
}, | ||
@@ -63,2 +63,3 @@ "files": [ | ||
"eslint-plugin-standard": "^4.0.0", | ||
"jest": "^27.5.1", | ||
"rollup": "^1.10.1", | ||
@@ -65,0 +66,0 @@ "rollup-plugin-babel": "^4.0.1", |
@@ -1,2 +0,2 @@ | ||
![NPM Version](https://img.shields.io/npm/v/babel-plugin-kea.svg) | ||
[![NPM Version](https://img.shields.io/npm/v/babel-plugin-kea.svg)](https://www.npmjs.com/package/babel-plugin-kea) | ||
[![Backers on Open Collective](https://opencollective.com/kea/backers/badge.svg)](#backers) | ||
@@ -88,5 +88,5 @@ [![Sponsors on Open Collective](https://opencollective.com/kea/sponsors/badge.svg)](#sponsors) | ||
"plugins": [ | ||
["babel-plugin-kea", { path: './frontend/src' }] | ||
["babel-plugin-kea", { "path": "./frontend/src" }] | ||
] | ||
} | ||
``` |
141
src/index.js
const nodePath = require('path') | ||
export default function ({ types: t, template }) { | ||
export default function ({ types: t }) { | ||
function isKeaCall(node) { | ||
return t.isIdentifier(node.callee, { name: 'kea' }) && | ||
return ( | ||
t.isIdentifier(node.callee, { name: 'kea' }) && | ||
node.arguments.length === 1 && | ||
t.isObjectExpression(node.arguments[0]) | ||
(t.isObjectExpression(node.arguments[0]) || t.isArrayExpression(node.arguments[0])) | ||
) | ||
} | ||
function buildPathProperty(node, pathParts) { | ||
const hasKey = node.arguments[0].properties.find(property => t.isIdentifier(property.key, { name: 'key' })) | ||
const builder = hasKey | ||
? template('const a = { path: (key) => ' + (JSON.stringify(pathParts).replace(/\]$/, ', key]')) + ' }') | ||
: template('const a = { path: () => ' + JSON.stringify(pathParts) + ' }') | ||
const builtNodes = builder() | ||
return builtNodes.declarations[0].init.properties[0] | ||
} | ||
function getLocalPath (state) { | ||
function getLocalPath(state) { | ||
let root = state.file.opts.root | ||
@@ -28,25 +20,64 @@ if (state.opts.path) { | ||
function hasPathProperty (path) { | ||
return path.node.arguments[0].properties.find(property => t.isIdentifier(property.key, { name: 'path' })) | ||
} | ||
/** Format: { 'kea': [[importedName, localNAme], ['path', 'keaPath']] }, */ | ||
const imports = {} | ||
/** Format: { 'kea': ImportDeclaration } */ | ||
const importDeclarations = {} | ||
let mustImportPath = false | ||
const KeaVisitor = { | ||
CallExpression(path) { | ||
if (!isKeaCall(path.node) || hasPathProperty(path)) { | ||
// gather all imports | ||
ImportDeclaration(path) { | ||
if (t.isStringLiteral(path.node.source)) { | ||
const importFrom = path.node.source.value | ||
if (!imports[importFrom]) { | ||
imports[importFrom] = [] | ||
} | ||
if (!importDeclarations[importFrom]) { | ||
importDeclarations[importFrom] = path | ||
} | ||
for (const specifier of path.node.specifiers) { | ||
imports[importFrom].push([specifier.imported.name, specifier.local.name]) | ||
} | ||
} | ||
}, | ||
CallExpression(path, state) { | ||
// only look at kea calls | ||
if (!isKeaCall(path.node)) { | ||
return | ||
} | ||
// unique path | ||
this.counter += 1 | ||
let pathParts = this.pathParts | ||
if (this.counter > 1) { | ||
pathParts = this.pathParts.map(p => p) // make a copy | ||
pathParts = this.pathParts.map((p) => p) // make a copy | ||
pathParts[pathParts.length - 1] = pathParts[pathParts.length - 1] + '/' + this.counter | ||
} | ||
const pathProperty = buildPathProperty(path.node, pathParts) | ||
path.node.arguments[0].properties.push(pathProperty) | ||
} | ||
if (t.isObjectExpression(path.node.arguments[0])) { | ||
// kea 2.0 object | ||
if (!path.node.arguments[0].properties.find((property) => t.isIdentifier(property.key, { name: 'path' }))) { | ||
const pathProperty = t.objectProperty( | ||
t.identifier('path'), | ||
t.arrayExpression(pathParts.map((str) => t.stringLiteral(str))), | ||
) | ||
path.node.arguments[0].properties = [pathProperty, ...path.node.arguments[0].properties] | ||
} | ||
} else if (t.isArrayExpression(path.node.arguments[0])) { | ||
// kea 3.0 builder | ||
if ( | ||
!path.node.arguments[0].elements.find( | ||
(element) => t.isCallExpression(element) && t.isIdentifier(element.callee, { name: 'path' }), | ||
) | ||
) { | ||
let [, pathImportedAs] = imports['kea']?.find(([importedName]) => importedName === 'path') || [] | ||
if (!pathImportedAs) { | ||
mustImportPath = true | ||
pathImportedAs = 'path' | ||
} | ||
const pathBuilder = t.callExpression(t.identifier(pathImportedAs), [ | ||
t.arrayExpression(pathParts.map((str) => t.stringLiteral(str))), | ||
]) | ||
path.node.arguments[0].elements = [pathBuilder, ...path.node.arguments[0].elements] | ||
} | ||
} | ||
}, | ||
} | ||
@@ -57,3 +88,5 @@ | ||
Program(path, state) { | ||
const pathParts = getLocalPath(state).replace(/\.(js|jsx|ts|tsx)$/, '').split(nodePath.sep) | ||
const pathParts = getLocalPath(state) | ||
.replace(/\.(js|jsx|ts|tsx)$/, '') | ||
.split(nodePath.sep) | ||
@@ -66,6 +99,26 @@ if (pathParts[0] === '..') { | ||
pathParts: pathParts.map(toCamelCase), | ||
counter: 0 | ||
}); | ||
counter: 0, | ||
}) | ||
if (mustImportPath) { | ||
// must add path | ||
if (importDeclarations['kea']) { | ||
// already imports kea | ||
importDeclarations['kea'].node.specifiers = [ | ||
...(importDeclarations['kea'].node.specifiers || []), | ||
t.importSpecifier(t.identifier('path'), t.identifier('path')), | ||
] | ||
} else { | ||
path.node.body = [ | ||
...path.node.body.filter((n) => t.isImportDeclaration(n)), | ||
t.importDeclaration( | ||
[t.importSpecifier(t.identifier('path'), t.identifier('path'))], | ||
t.stringLiteral('kea'), | ||
), | ||
...path.node.body.filter((n) => !t.isImportDeclaration(n)), | ||
] | ||
} | ||
} | ||
}, | ||
} | ||
}, | ||
} | ||
@@ -76,12 +129,16 @@ } | ||
// Lower cases the string | ||
return str | ||
// Replaces any - or _ characters with a space | ||
.replace( /[-_]+/g, ' ') | ||
// Removes any non alphanumeric characters | ||
.replace( /[^\w\s]/g, '') | ||
// Uppercases the first character in each group immediately following a space | ||
// (delimited by spaces) | ||
.replace( / (.)/g, function($1) { return $1.toUpperCase(); }) | ||
// Removes spaces | ||
.replace( / /g, '' ); | ||
return ( | ||
str | ||
// Replaces any - or _ characters with a space | ||
.replace(/[-_]+/g, ' ') | ||
// Removes any non alphanumeric characters | ||
.replace(/[^\w\s]/g, '') | ||
// Uppercases the first character in each group immediately following a space | ||
// (delimited by spaces) | ||
.replace(/ (.)/g, function ($1) { | ||
return $1.toUpperCase() | ||
}) | ||
// Removes spaces | ||
.replace(/ /g, '') | ||
) | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
17932
7
343
1
35
1