mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 06:27:49 +00:00
wip: migrate to bun
This commit is contained in:
29
.commitlintrc.js
Normal file
29
.commitlintrc.js
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
extends: [
|
||||
'@commitlint/config-conventional', // scoped packages are not prefixed
|
||||
],
|
||||
rules: {
|
||||
'type-enum': [
|
||||
2,
|
||||
'always',
|
||||
[
|
||||
'build',
|
||||
'chore',
|
||||
'ci',
|
||||
'docs',
|
||||
'feat',
|
||||
'fix',
|
||||
'perf',
|
||||
'proposal',
|
||||
'refactor',
|
||||
'release',
|
||||
'revert',
|
||||
'style',
|
||||
'test',
|
||||
'wip',
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
5
.eslintignore
Normal file
5
.eslintignore
Normal file
@@ -0,0 +1,5 @@
|
||||
coverage/
|
||||
coverage-merged/
|
||||
dist/
|
||||
node_modules/
|
||||
types/
|
||||
98
.eslintrc
Normal file
98
.eslintrc
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"extends": ["airbnb-base", "prettier"],
|
||||
"root": true,
|
||||
"env": {
|
||||
"amd": true,
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"jest": true,
|
||||
"node": true
|
||||
},
|
||||
"globals": {
|
||||
"BigInt": "readonly",
|
||||
"BigInt64Array": "readonly",
|
||||
"BigUint64Array": "readonly",
|
||||
"globalThis": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"prettier"
|
||||
],
|
||||
"rules": {
|
||||
"prettier/prettier": "error",
|
||||
// Overridden
|
||||
"no-eval": "off",
|
||||
"camelcase": ["error", { "properties": "never", "allow": [ "W[0-9]+_"] }],
|
||||
"import/extensions": "off",
|
||||
// @TODO: Fix the following rules progressively.
|
||||
"arrow-body-style": "warn",
|
||||
"prefer-arrow-callback": "warn",
|
||||
"prefer-object-spread": "off",
|
||||
"max-classes-per-file": "off",
|
||||
"dot-notation": "off",
|
||||
"object-shorthand": "off",
|
||||
"no-param-reassign": "off",
|
||||
"no-cond-assign": "off",
|
||||
"prefer-destructuring": "off",
|
||||
"func-names": "off",
|
||||
"no-nested-ternary": "off",
|
||||
"no-plusplus": "off",
|
||||
"strict": "off",
|
||||
"no-restricted-syntax": "off",
|
||||
"import/no-mutable-exports": "off",
|
||||
"guard-for-in": "off",
|
||||
"import/prefer-default-export": "off",
|
||||
"prefer-rest-params": "off",
|
||||
"one-var": "off",
|
||||
"prefer-spread": "off",
|
||||
"no-lonely-if": "off",
|
||||
"no-prototype-builtins": "off",
|
||||
"no-continue": "off",
|
||||
"no-shadow": "off",
|
||||
// Rules up for discussion.
|
||||
"no-multi-assign": "off",
|
||||
"new-cap": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.ts"],
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"extends": [
|
||||
"airbnb-typescript/base",
|
||||
"prettier"
|
||||
],
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true,
|
||||
"argsIgnorePattern": "^_" // For tsc compatibility.
|
||||
}
|
||||
],
|
||||
"comma-dangle": "off",
|
||||
"implicit-arrow-linebreak": "off", // Conflicts with prettier.
|
||||
"import/extensions": "off",
|
||||
"import/prefer-default-export": "off",
|
||||
"operator-linebreak": "off",
|
||||
"object-curly-newline": "off",
|
||||
"prefer-rest-params": "off", // We need to use params.
|
||||
"prettier/prettier": "error",
|
||||
"@typescript-eslint/no-shadow": "warn",
|
||||
"@typescript-eslint/no-use-before-define": ["warn", { "functions": false }],
|
||||
"import/no-cycle": "warn",
|
||||
"no-bitwise": "off",
|
||||
"no-unsafe-finally": "warn",
|
||||
"no-param-reassign": "off",
|
||||
"no-shadow": "warn"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
125
.eslintrc.js
125
.eslintrc.js
@@ -1,125 +0,0 @@
|
||||
module.exports = {
|
||||
'extends': ['plugin:import/errors'],
|
||||
'plugins': ['import'],
|
||||
'env': {
|
||||
'es6': true,
|
||||
'node': true
|
||||
},
|
||||
'parserOptions': {
|
||||
'ecmaVersion': 6,
|
||||
'sourceType': 'module',
|
||||
'ecmaFeatures': {
|
||||
'impliedStrict': true,
|
||||
'objectLiteralDuplicateProperties': false
|
||||
}
|
||||
},
|
||||
'rules': {
|
||||
'array-bracket-spacing': ['error', 'never'],
|
||||
|
||||
'camelcase': ['error', {
|
||||
'properties': 'never'
|
||||
}],
|
||||
|
||||
'comma-dangle': ['error', 'never'],
|
||||
|
||||
'curly': ['error', 'all'],
|
||||
|
||||
'eol-last': ['error'],
|
||||
|
||||
'indent': ['error', 2, {
|
||||
'SwitchCase': 1
|
||||
}],
|
||||
|
||||
'keyword-spacing': ['error'],
|
||||
|
||||
'max-len': ['error', {
|
||||
'code': 180,
|
||||
'ignoreComments': true,
|
||||
'ignoreRegExpLiterals': true
|
||||
}],
|
||||
|
||||
'no-else-return': ['error'],
|
||||
|
||||
'no-mixed-spaces-and-tabs': ['error'],
|
||||
|
||||
'no-multiple-empty-lines': ['error'],
|
||||
|
||||
'no-spaced-func': ['error'],
|
||||
|
||||
'no-trailing-spaces': ['error'],
|
||||
|
||||
'no-undef': ['error'],
|
||||
|
||||
'no-unexpected-multiline': ['error'],
|
||||
|
||||
'no-unused-vars': ['error', {
|
||||
'args': 'none',
|
||||
'vars': 'all'
|
||||
}],
|
||||
|
||||
'quotes': ['error', 'single', {
|
||||
'allowTemplateLiterals': true,
|
||||
'avoidEscape': true
|
||||
}],
|
||||
|
||||
'semi': ['error', 'never'],
|
||||
|
||||
'space-before-blocks': ['error', 'always'],
|
||||
|
||||
'space-before-function-paren': ['error', 'never'],
|
||||
|
||||
'space-in-parens': ['error', 'never'],
|
||||
|
||||
'space-unary-ops': ['error', {
|
||||
'nonwords': false,
|
||||
'overrides': {}
|
||||
}],
|
||||
|
||||
// 'valid-jsdoc': ['error']
|
||||
|
||||
// ECMAScript 6 rules
|
||||
|
||||
'arrow-body-style': ['error', 'as-needed', {
|
||||
'requireReturnForObjectLiteral': false
|
||||
}],
|
||||
|
||||
'arrow-parens': ['error', 'always'],
|
||||
|
||||
'arrow-spacing': ['error', {
|
||||
'after': true,
|
||||
'before': true
|
||||
}],
|
||||
|
||||
'no-class-assign': ['error'],
|
||||
|
||||
'no-const-assign': ['error'],
|
||||
|
||||
'no-dupe-class-members': ['error'],
|
||||
|
||||
'no-duplicate-imports': ['error'],
|
||||
|
||||
'no-new-symbol': ['error'],
|
||||
|
||||
'no-useless-rename': ['error'],
|
||||
|
||||
'no-var': ['error'],
|
||||
|
||||
'object-shorthand': ['error', 'always', {
|
||||
'avoidQuotes': true,
|
||||
'ignoreConstructors': false
|
||||
}],
|
||||
|
||||
'prefer-arrow-callback': ['error', {
|
||||
'allowNamedFunctions': false,
|
||||
'allowUnboundThis': true
|
||||
}],
|
||||
|
||||
'prefer-const': ['error'],
|
||||
|
||||
'prefer-rest-params': ['error'],
|
||||
|
||||
'prefer-template': ['error'],
|
||||
|
||||
'template-curly-spacing': ['error', 'never']
|
||||
}
|
||||
};
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +1,2 @@
|
||||
* text=auto
|
||||
*.lockb binary diff=lockb
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,7 +1,8 @@
|
||||
.DS_Store
|
||||
*.log*
|
||||
doc/*.html
|
||||
node_modules
|
||||
dist/
|
||||
node_modules/
|
||||
*.code-workspace
|
||||
*.lockb
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
_
|
||||
4
.husky/commit-msg
Executable file
4
.husky/commit-msg
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
bun run commitlint --edit "$1"
|
||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
bun run lint-staged
|
||||
5
.prettierignore
Normal file
5
.prettierignore
Normal file
@@ -0,0 +1,5 @@
|
||||
coverage/
|
||||
coverage-merged/
|
||||
dist/
|
||||
node_modules/
|
||||
types/
|
||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"useTabs": false,
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true
|
||||
}
|
||||
18
README.md
18
README.md
@@ -2,18 +2,14 @@
|
||||
|
||||
[Site](https://lodash.com/) |
|
||||
[Docs](https://lodash.com/docs) |
|
||||
[FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide) |
|
||||
[Contributing](https://github.com/lodash/lodash/blob/master/.github/CONTRIBUTING.md) |
|
||||
[Wiki](https://github.com/lodash/lodash/wiki "Changelog, Roadmap, etc.") |
|
||||
[Code of Conduct](https://code-of-conduct.openjsf.org) |
|
||||
[Twitter](https://twitter.com/bestiejs) |
|
||||
[Chat](https://gitter.im/lodash/lodash)
|
||||
[Code of Conduct](https://code-of-conduct.openjsf.org)
|
||||
|
||||
The [Lodash](https://lodash.com/) library exported as a [UMD](https://github.com/umdjs/umd) module.
|
||||
|
||||
Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
|
||||
```shell
|
||||
$ npm run build
|
||||
$ bun run build
|
||||
$ lodash -o ./dist/lodash.js
|
||||
$ lodash core -o ./dist/lodash.core.js
|
||||
```
|
||||
@@ -34,14 +30,12 @@ In a browser:
|
||||
<script src="lodash.js"></script>
|
||||
```
|
||||
|
||||
Using npm:
|
||||
Using bun:
|
||||
```shell
|
||||
$ npm i -g npm
|
||||
$ npm i lodash
|
||||
$ bun i lodash
|
||||
```
|
||||
Note: add `--save` if you are using npm < 5.0.0
|
||||
|
||||
In Node.js:
|
||||
In [Bun](https://bun.sh):
|
||||
```js
|
||||
// Load the full build.
|
||||
var _ = require('lodash');
|
||||
@@ -76,5 +70,3 @@ Lodash is available in a [variety of builds](https://lodash.com/custom-builds) &
|
||||
|
||||
* [lodash](https://www.npmjs.com/package/lodash) & [per method packages](https://www.npmjs.com/search?q=keywords:lodash-modularized)
|
||||
* [lodash-es](https://www.npmjs.com/package/lodash-es), [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash), & [lodash-webpack-plugin](https://www.npmjs.com/package/lodash-webpack-plugin)
|
||||
* [lodash/fp](https://github.com/lodash/lodash/tree/npm/fp)
|
||||
* [lodash-amd](https://www.npmjs.com/package/lodash-amd)
|
||||
|
||||
2
bunfig.toml
Normal file
2
bunfig.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[install.lockfile]
|
||||
print = "yarn"
|
||||
213
debounce.js
213
debounce.js
@@ -1,213 +0,0 @@
|
||||
import isObject from './isObject.js'
|
||||
import root from './.internal/root.js'
|
||||
|
||||
/**
|
||||
* Creates a debounced function that delays invoking `func` until after `wait`
|
||||
* milliseconds have elapsed since the last time the debounced function was
|
||||
* invoked, or until the next browser frame is drawn. The debounced function
|
||||
* comes with a `cancel` method to cancel delayed `func` invocations and a
|
||||
* `flush` method to immediately invoke them. Provide `options` to indicate
|
||||
* whether `func` should be invoked on the leading and/or trailing edge of the
|
||||
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
||||
* debounced function. Subsequent calls to the debounced function return the
|
||||
* result of the last `func` invocation.
|
||||
*
|
||||
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
||||
* invoked on the trailing edge of the timeout only if the debounced function
|
||||
* is invoked more than once during the `wait` timeout.
|
||||
*
|
||||
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
||||
* until the next tick, similar to `setTimeout` with a timeout of `0`.
|
||||
*
|
||||
* If `wait` is omitted in an environment with `requestAnimationFrame`, `func`
|
||||
* invocation will be deferred until the next frame is drawn (typically about
|
||||
* 16ms).
|
||||
*
|
||||
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
||||
* for details over the differences between `debounce` and `throttle`.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @category Function
|
||||
* @param {Function} func The function to debounce.
|
||||
* @param {number} [wait=0]
|
||||
* The number of milliseconds to delay; if omitted, `requestAnimationFrame` is
|
||||
* used (if available).
|
||||
* @param {Object} [options={}] The options object.
|
||||
* @param {boolean} [options.leading=false]
|
||||
* Specify invoking on the leading edge of the timeout.
|
||||
* @param {number} [options.maxWait]
|
||||
* The maximum time `func` is allowed to be delayed before it's invoked.
|
||||
* @param {boolean} [options.trailing=true]
|
||||
* Specify invoking on the trailing edge of the timeout.
|
||||
* @returns {Function} Returns the new debounced function.
|
||||
* @example
|
||||
*
|
||||
* // Avoid costly calculations while the window size is in flux.
|
||||
* jQuery(window).on('resize', debounce(calculateLayout, 150))
|
||||
*
|
||||
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
||||
* jQuery(element).on('click', debounce(sendMail, 300, {
|
||||
* 'leading': true,
|
||||
* 'trailing': false
|
||||
* }))
|
||||
*
|
||||
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
||||
* const debounced = debounce(batchLog, 250, { 'maxWait': 1000 })
|
||||
* const source = new EventSource('/stream')
|
||||
* jQuery(source).on('message', debounced)
|
||||
*
|
||||
* // Cancel the trailing debounced invocation.
|
||||
* jQuery(window).on('popstate', debounced.cancel)
|
||||
*
|
||||
* // Check for pending invocations.
|
||||
* const status = debounced.pending() ? "Pending..." : "Ready"
|
||||
*/
|
||||
function debounce(func, wait, options) {
|
||||
let lastArgs,
|
||||
lastThis,
|
||||
maxWait,
|
||||
result,
|
||||
timerId,
|
||||
lastCallTime
|
||||
|
||||
let lastInvokeTime = 0
|
||||
let leading = false
|
||||
let maxing = false
|
||||
let trailing = true
|
||||
|
||||
// Bypass `requestAnimationFrame` by explicitly setting `wait=0`.
|
||||
const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')
|
||||
|
||||
if (typeof func !== 'function') {
|
||||
throw new TypeError('Expected a function')
|
||||
}
|
||||
wait = +wait || 0
|
||||
if (isObject(options)) {
|
||||
leading = !!options.leading
|
||||
maxing = 'maxWait' in options
|
||||
maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait
|
||||
trailing = 'trailing' in options ? !!options.trailing : trailing
|
||||
}
|
||||
|
||||
function invokeFunc(time) {
|
||||
const args = lastArgs
|
||||
const thisArg = lastThis
|
||||
|
||||
lastArgs = lastThis = undefined
|
||||
lastInvokeTime = time
|
||||
result = func.apply(thisArg, args)
|
||||
return result
|
||||
}
|
||||
|
||||
function startTimer(pendingFunc, wait) {
|
||||
if (useRAF) {
|
||||
root.cancelAnimationFrame(timerId)
|
||||
return root.requestAnimationFrame(pendingFunc)
|
||||
}
|
||||
return setTimeout(pendingFunc, wait)
|
||||
}
|
||||
|
||||
function cancelTimer(id) {
|
||||
if (useRAF) {
|
||||
return root.cancelAnimationFrame(id)
|
||||
}
|
||||
clearTimeout(id)
|
||||
}
|
||||
|
||||
function leadingEdge(time) {
|
||||
// Reset any `maxWait` timer.
|
||||
lastInvokeTime = time
|
||||
// Start the timer for the trailing edge.
|
||||
timerId = startTimer(timerExpired, wait)
|
||||
// Invoke the leading edge.
|
||||
return leading ? invokeFunc(time) : result
|
||||
}
|
||||
|
||||
function remainingWait(time) {
|
||||
const timeSinceLastCall = time - lastCallTime
|
||||
const timeSinceLastInvoke = time - lastInvokeTime
|
||||
const timeWaiting = wait - timeSinceLastCall
|
||||
|
||||
return maxing
|
||||
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
|
||||
: timeWaiting
|
||||
}
|
||||
|
||||
function shouldInvoke(time) {
|
||||
const timeSinceLastCall = time - lastCallTime
|
||||
const timeSinceLastInvoke = time - lastInvokeTime
|
||||
|
||||
// Either this is the first call, activity has stopped and we're at the
|
||||
// trailing edge, the system time has gone backwards and we're treating
|
||||
// it as the trailing edge, or we've hit the `maxWait` limit.
|
||||
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
||||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
|
||||
}
|
||||
|
||||
function timerExpired() {
|
||||
const time = Date.now()
|
||||
if (shouldInvoke(time)) {
|
||||
return trailingEdge(time)
|
||||
}
|
||||
// Restart the timer.
|
||||
timerId = startTimer(timerExpired, remainingWait(time))
|
||||
}
|
||||
|
||||
function trailingEdge(time) {
|
||||
timerId = undefined
|
||||
|
||||
// Only invoke if we have `lastArgs` which means `func` has been
|
||||
// debounced at least once.
|
||||
if (trailing && lastArgs) {
|
||||
return invokeFunc(time)
|
||||
}
|
||||
lastArgs = lastThis = undefined
|
||||
return result
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (timerId !== undefined) {
|
||||
cancelTimer(timerId)
|
||||
}
|
||||
lastInvokeTime = 0
|
||||
lastArgs = lastCallTime = lastThis = timerId = undefined
|
||||
}
|
||||
|
||||
function flush() {
|
||||
return timerId === undefined ? result : trailingEdge(Date.now())
|
||||
}
|
||||
|
||||
function pending() {
|
||||
return timerId !== undefined
|
||||
}
|
||||
|
||||
function debounced(...args) {
|
||||
const time = Date.now()
|
||||
const isInvoking = shouldInvoke(time)
|
||||
|
||||
lastArgs = args
|
||||
lastThis = this
|
||||
lastCallTime = time
|
||||
|
||||
if (isInvoking) {
|
||||
if (timerId === undefined) {
|
||||
return leadingEdge(lastCallTime)
|
||||
}
|
||||
if (maxing) {
|
||||
// Handle invocations in a tight loop.
|
||||
timerId = startTimer(timerExpired, wait)
|
||||
return invokeFunc(lastCallTime)
|
||||
}
|
||||
}
|
||||
if (timerId === undefined) {
|
||||
timerId = startTimer(timerExpired, wait)
|
||||
}
|
||||
return result
|
||||
}
|
||||
debounced.cancel = cancel
|
||||
debounced.flush = flush
|
||||
debounced.pending = pending
|
||||
return debounced
|
||||
}
|
||||
|
||||
export default debounce
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './forEachRight.js'
|
||||
53
hasPath.js
53
hasPath.js
@@ -1,53 +0,0 @@
|
||||
import castPath from './.internal/castPath.js'
|
||||
import isArguments from './isArguments.js'
|
||||
import isIndex from './.internal/isIndex.js'
|
||||
import isLength from './isLength.js'
|
||||
import toKey from './.internal/toKey.js'
|
||||
|
||||
/** Used to check objects for own properties. */
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
/**
|
||||
* Checks if `path` is a direct property of `object`.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @category Object
|
||||
* @param {Object} object The object to query.
|
||||
* @param {Array|string} path The path to check.
|
||||
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||||
* @see has, hasIn, hasPathIn
|
||||
* @example
|
||||
*
|
||||
* const object = { 'a': { 'b': 2 } }
|
||||
* const other = create({ 'a': create({ 'b': 2 }) })
|
||||
*
|
||||
* hasPath(object, 'a.b')
|
||||
* // => true
|
||||
*
|
||||
* hasPath(object, ['a', 'b'])
|
||||
* // => true
|
||||
*/
|
||||
function hasPath(object, path) {
|
||||
path = castPath(path, object)
|
||||
|
||||
let index = -1
|
||||
let { length } = path
|
||||
let result = false
|
||||
let key
|
||||
|
||||
while (++index < length) {
|
||||
key = toKey(path[index])
|
||||
if (!(result = object != null && hasOwnProperty.call(object, key))) {
|
||||
break
|
||||
}
|
||||
object = object[key]
|
||||
}
|
||||
if (result || ++index != length) {
|
||||
return result
|
||||
}
|
||||
length = object == null ? 0 : object.length
|
||||
return !!length && isLength(length) && isIndex(key, length) &&
|
||||
(Array.isArray(object) || isArguments(object))
|
||||
}
|
||||
|
||||
export default hasPath
|
||||
50
hasPathIn.js
50
hasPathIn.js
@@ -1,50 +0,0 @@
|
||||
import castPath from './.internal/castPath.js'
|
||||
import isArguments from './isArguments.js'
|
||||
import isIndex from './.internal/isIndex.js'
|
||||
import isLength from './isLength.js'
|
||||
import toKey from './.internal/toKey.js'
|
||||
|
||||
/**
|
||||
* Checks if `path` is a direct property of `object`.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @category Object
|
||||
* @param {Object} object The object to query.
|
||||
* @param {Array|string} path The path to check.
|
||||
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||||
* @see has, hasIn hasPath
|
||||
* @example
|
||||
*
|
||||
* const object = { 'a': { 'b': 2 } }
|
||||
* const other = create({ 'a': create({ 'b': 2 }) })
|
||||
*
|
||||
* hasPathIn(object, 'a.b')
|
||||
* // => true
|
||||
*
|
||||
* hasPathIn(object, ['a', 'b'])
|
||||
* // => true
|
||||
*/
|
||||
function hasPathIn(object, path) {
|
||||
path = castPath(path, object)
|
||||
|
||||
let index = -1
|
||||
let { length } = path
|
||||
let result = false
|
||||
let key
|
||||
|
||||
while (++index < length) {
|
||||
key = toKey(path[index])
|
||||
if (!(result = object != null && key in Object(object))) {
|
||||
break
|
||||
}
|
||||
object = object[key]
|
||||
}
|
||||
if (result || ++index != length) {
|
||||
return result
|
||||
}
|
||||
length = object == null ? 0 : object.length
|
||||
return !!length && isLength(length) && isIndex(key, length) &&
|
||||
(Array.isArray(object) || isArguments(object))
|
||||
}
|
||||
|
||||
export default hasPathIn
|
||||
35
isBuffer.js
35
isBuffer.js
@@ -1,35 +0,0 @@
|
||||
import root from './.internal/root.js'
|
||||
|
||||
/** Detect free variable `exports`. */
|
||||
const freeExports = typeof exports === 'object' && exports !== null && !exports.nodeType && exports
|
||||
|
||||
/** Detect free variable `module`. */
|
||||
const freeModule = freeExports && typeof module === 'object' && module !== null && !module.nodeType && module
|
||||
|
||||
/** Detect the popular CommonJS extension `module.exports`. */
|
||||
const moduleExports = freeModule && freeModule.exports === freeExports
|
||||
|
||||
/** Built-in value references. */
|
||||
const Buffer = moduleExports ? root.Buffer : undefined
|
||||
|
||||
/* Built-in method references for those with the same name as other `lodash` methods. */
|
||||
const nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined
|
||||
|
||||
/**
|
||||
* Checks if `value` is a buffer.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @category Lang
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
||||
* @example
|
||||
*
|
||||
* isBuffer(new Buffer(2))
|
||||
* // => true
|
||||
*
|
||||
* isBuffer(new Uint8Array(2))
|
||||
* // => false
|
||||
*/
|
||||
const isBuffer = nativeIsBuffer || (() => false)
|
||||
|
||||
export default isBuffer
|
||||
69
isEmpty.js
69
isEmpty.js
@@ -1,69 +0,0 @@
|
||||
import getTag from './.internal/getTag.js'
|
||||
import isArguments from './isArguments.js'
|
||||
import isArrayLike from './isArrayLike.js'
|
||||
import isBuffer from './isBuffer.js'
|
||||
import isPrototype from './.internal/isPrototype.js'
|
||||
import isTypedArray from './isTypedArray.js'
|
||||
|
||||
/** Used to check objects for own properties. */
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
/**
|
||||
* Checks if `value` is an empty object, collection, map, or set.
|
||||
*
|
||||
* Objects are considered empty if they have no own enumerable string keyed
|
||||
* properties.
|
||||
*
|
||||
* Array-like values such as `arguments` objects, arrays, buffers, strings, or
|
||||
* jQuery-like collections are considered empty if they have a `length` of `0`.
|
||||
* Similarly, maps and sets are considered empty if they have a `size` of `0`.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @category Lang
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
|
||||
* @example
|
||||
*
|
||||
* isEmpty(null)
|
||||
* // => true
|
||||
*
|
||||
* isEmpty(true)
|
||||
* // => true
|
||||
*
|
||||
* isEmpty(1)
|
||||
* // => true
|
||||
*
|
||||
* isEmpty([1, 2, 3])
|
||||
* // => false
|
||||
*
|
||||
* isEmpty('abc')
|
||||
* // => false
|
||||
*
|
||||
* isEmpty({ 'a': 1 })
|
||||
* // => false
|
||||
*/
|
||||
function isEmpty(value) {
|
||||
if (value == null) {
|
||||
return true
|
||||
}
|
||||
if (isArrayLike(value) &&
|
||||
(Array.isArray(value) || typeof value === 'string' || typeof value.splice === 'function' ||
|
||||
isBuffer(value) || isTypedArray(value) || isArguments(value))) {
|
||||
return !value.length
|
||||
}
|
||||
const tag = getTag(value)
|
||||
if (tag == '[object Map]' || tag == '[object Set]') {
|
||||
return !value.size
|
||||
}
|
||||
if (isPrototype(value)) {
|
||||
return !Object.keys(value).length
|
||||
}
|
||||
for (const key in value) {
|
||||
if (hasOwnProperty.call(value, key)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export default isEmpty
|
||||
30
isError.js
30
isError.js
@@ -1,30 +0,0 @@
|
||||
import getTag from './.internal/getTag.js'
|
||||
import isObjectLike from './isObjectLike.js'
|
||||
import isPlainObject from './isPlainObject.js'
|
||||
|
||||
/**
|
||||
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
|
||||
* `SyntaxError`, `TypeError`, or `URIError` object.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @category Lang
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is an error object, else `false`.
|
||||
* @example
|
||||
*
|
||||
* isError(new Error)
|
||||
* // => true
|
||||
*
|
||||
* isError(Error)
|
||||
* // => false
|
||||
*/
|
||||
function isError(value) {
|
||||
if (!isObjectLike(value)) {
|
||||
return false
|
||||
}
|
||||
const tag = getTag(value)
|
||||
return tag == '[object Error]' || tag == '[object DOMException]' ||
|
||||
(typeof value.message === 'string' && typeof value.name === 'string' && !isPlainObject(value))
|
||||
}
|
||||
|
||||
export default isError
|
||||
1697
package-lock.json
generated
1697
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
53
package.json
53
package.json
@@ -3,21 +3,48 @@
|
||||
"version": "5.0.0",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"main": "lodash.js",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"main": "dist/lodash.js",
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"style": "eslint *.js .internal/**/*.js",
|
||||
"test": "mocha -r esm test/*.test.js",
|
||||
"validate": "npm run style && npm run test"
|
||||
"prepare": "husky install",
|
||||
"lint": "eslint ./src/**/*.ts ./test/**/*.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^5.2.0",
|
||||
"eslint": "^7.16.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"lodash": "4.17.20",
|
||||
"esm": "^3.2.25"
|
||||
}
|
||||
"@commitlint/cli": "17.7.1",
|
||||
"@commitlint/config-conventional": "17.7.0",
|
||||
"@types/eslint": "8.44.2",
|
||||
"@types/jest": "29.5.5",
|
||||
"@typescript-eslint/eslint-plugin": "6.7.0",
|
||||
"@typescript-eslint/parser": "6.7.0",
|
||||
"eslint": "8.49.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-airbnb-typescript": "17.1.0",
|
||||
"eslint-config-prettier": "9.0.0",
|
||||
"eslint-plugin-import": "2.28.1",
|
||||
"eslint-plugin-prettier": "5.0.0",
|
||||
"husky": "8.0.3",
|
||||
"lint-staged": "14.0.1",
|
||||
"lodash": "4.17.21",
|
||||
"prettier": "3.0.3"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{ts}": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged",
|
||||
"commit-msg": "bun run commitlint --edit $1"
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1",
|
||||
"yarn": "^1.22.19"
|
||||
},
|
||||
"volta": {
|
||||
"node": "18.17.1",
|
||||
"yarn": "1.22.19"
|
||||
},
|
||||
"engineStrict": true
|
||||
}
|
||||
|
||||
40
repeat.js
40
repeat.js
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* Repeats the given string `n` times.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @category String
|
||||
* @param {string} [string=''] The string to repeat.
|
||||
* @param {number} [n=1] The number of times to repeat the string.
|
||||
* @returns {string} Returns the repeated string.
|
||||
* @example
|
||||
*
|
||||
* repeat('*', 3)
|
||||
* // => '***'
|
||||
*
|
||||
* repeat('abc', 2)
|
||||
* // => 'abcabc'
|
||||
*
|
||||
* repeat('abc', 0)
|
||||
* // => ''
|
||||
*/
|
||||
function repeat(string, n) {
|
||||
let result = ''
|
||||
if (!string || n < 1 || n > Number.MAX_SAFE_INTEGER) {
|
||||
return result
|
||||
}
|
||||
// Leverage the exponentiation by squaring algorithm for a faster repeat.
|
||||
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
|
||||
do {
|
||||
if (n % 2) {
|
||||
result += string
|
||||
}
|
||||
n = Math.floor(n / 2)
|
||||
if (n) {
|
||||
string += string
|
||||
}
|
||||
} while (n)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export default repeat
|
||||
@@ -1,40 +0,0 @@
|
||||
import copyArray from './.internal/copyArray.js'
|
||||
import slice from './slice.js'
|
||||
|
||||
/**
|
||||
* Gets `n` random elements at unique keys from `array` up to the
|
||||
* size of `array`.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @category Array
|
||||
* @param {Array} array The array to sample.
|
||||
* @param {number} [n=1] The number of elements to sample.
|
||||
* @returns {Array} Returns the random elements.
|
||||
* @example
|
||||
*
|
||||
* sampleSize([1, 2, 3], 2)
|
||||
* // => [3, 1]
|
||||
*
|
||||
* sampleSize([1, 2, 3], 4)
|
||||
* // => [2, 3, 1]
|
||||
*/
|
||||
function sampleSize(array, n) {
|
||||
n = n == null ? 1 : n
|
||||
const length = array == null ? 0 : array.length
|
||||
if (!length || n < 1) {
|
||||
return []
|
||||
}
|
||||
n = n > length ? length : n
|
||||
let index = -1
|
||||
const lastIndex = length - 1
|
||||
const result = copyArray(array)
|
||||
while (++index < n) {
|
||||
const rand = index + Math.floor(Math.random() * (lastIndex - index + 1))
|
||||
const value = result[rand]
|
||||
result[rand] = result[index]
|
||||
result[index] = value
|
||||
}
|
||||
return slice(result, 0, n)
|
||||
}
|
||||
|
||||
export default sampleSize
|
||||
33
shuffle.js
33
shuffle.js
@@ -1,33 +0,0 @@
|
||||
import copyArray from './.internal/copyArray.js'
|
||||
|
||||
/**
|
||||
* Creates an array of shuffled values, using a version of the
|
||||
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @category Array
|
||||
* @param {Array} array The array to shuffle.
|
||||
* @returns {Array} Returns the new shuffled array.
|
||||
* @example
|
||||
*
|
||||
* shuffle([1, 2, 3, 4])
|
||||
* // => [4, 1, 3, 2]
|
||||
*/
|
||||
function shuffle(array) {
|
||||
const length = array == null ? 0 : array.length
|
||||
if (!length) {
|
||||
return []
|
||||
}
|
||||
let index = -1
|
||||
const lastIndex = length - 1
|
||||
const result = copyArray(array)
|
||||
while (++index < length) {
|
||||
const rand = index + Math.floor(Math.random() * (lastIndex - index + 1))
|
||||
const value = result[rand]
|
||||
result[rand] = result[index]
|
||||
result[index] = value
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default shuffle
|
||||
43
size.js
43
size.js
@@ -1,43 +0,0 @@
|
||||
import getTag from './.internal/getTag.js'
|
||||
import isArrayLike from './isArrayLike.js'
|
||||
import isString from './isString.js'
|
||||
import stringSize from './.internal/stringSize.js'
|
||||
|
||||
/** `Object#toString` result references. */
|
||||
const mapTag = '[object Map]'
|
||||
const setTag = '[object Set]'
|
||||
|
||||
/**
|
||||
* Gets the size of `collection` by returning its length for array-like
|
||||
* values or the number of own enumerable string keyed properties for objects.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @category Collection
|
||||
* @param {Array|Object|string} collection The collection to inspect.
|
||||
* @returns {number} Returns the collection size.
|
||||
* @example
|
||||
*
|
||||
* size([1, 2, 3])
|
||||
* // => 3
|
||||
*
|
||||
* size({ 'a': 1, 'b': 2 })
|
||||
* // => 2
|
||||
*
|
||||
* size('pebbles')
|
||||
* // => 7
|
||||
*/
|
||||
function size(collection) {
|
||||
if (collection == null) {
|
||||
return 0
|
||||
}
|
||||
if (isArrayLike(collection)) {
|
||||
return isString(collection) ? stringSize(collection) : collection.length
|
||||
}
|
||||
const tag = getTag(collection)
|
||||
if (tag == mapTag || tag == setTag) {
|
||||
return collection.size
|
||||
}
|
||||
return Object.keys(collection).length
|
||||
}
|
||||
|
||||
export default size
|
||||
42
split.js
42
split.js
@@ -1,42 +0,0 @@
|
||||
import castSlice from './.internal/castSlice.js'
|
||||
import hasUnicode from './.internal/hasUnicode.js'
|
||||
import isRegExp from './isRegExp.js'
|
||||
import stringToArray from './.internal/stringToArray.js'
|
||||
|
||||
/** Used as references for the maximum length and index of an array. */
|
||||
const MAX_ARRAY_LENGTH = 4294967295
|
||||
|
||||
/**
|
||||
* Splits `string` by `separator`.
|
||||
*
|
||||
* **Note:** This method is based on
|
||||
* [`String#split`](https://mdn.io/String/split).
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @category String
|
||||
* @param {string} [string=''] The string to split.
|
||||
* @param {RegExp|string} separator The separator pattern to split by.
|
||||
* @param {number} [limit] The length to truncate results to.
|
||||
* @returns {Array} Returns the string segments.
|
||||
* @example
|
||||
*
|
||||
* split('a-b-c', '-', 2)
|
||||
* // => ['a', 'b']
|
||||
*/
|
||||
function split(string, separator, limit) {
|
||||
limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0
|
||||
if (!limit) {
|
||||
return []
|
||||
}
|
||||
if (string && (
|
||||
typeof separator === 'string' ||
|
||||
(separator != null && !isRegExp(separator))
|
||||
)) {
|
||||
if (!separator && hasUnicode(string)) {
|
||||
return castSlice(stringToArray(string), 0, limit)
|
||||
}
|
||||
}
|
||||
return string.split(separator, limit)
|
||||
}
|
||||
|
||||
export default split
|
||||
18
src/.eslintrc.cjs
Normal file
18
src/.eslintrc.cjs
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('node:path');
|
||||
|
||||
module.exports = {
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.{ts}'],
|
||||
rules: {
|
||||
'import/no-extraneous-dependencies': [
|
||||
'error',
|
||||
// Use package.json from both this package folder and root.
|
||||
{ packageDir: [__dirname, path.join(__dirname, '../')] },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user