first commit
This commit is contained in:
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
# .env file - Environment variables for MangaShelf server
|
||||||
|
# Copy this to .env and modify as needed
|
||||||
|
|
||||||
|
# Server port
|
||||||
|
PORT=3030
|
||||||
|
|
||||||
|
# JWT Secret - CHANGE THIS TO A RANDOM STRING IN PRODUCTION!
|
||||||
|
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
|
||||||
|
|
||||||
|
# Database path (SQLite)
|
||||||
|
DATABASE_PATH=./data/mangashelf.db
|
||||||
|
|
||||||
|
# Upload limits (in MB)
|
||||||
|
MAX_FILE_SIZE=500
|
||||||
|
|
||||||
|
# Library paths
|
||||||
|
LIBRARY_PATH=./library
|
||||||
|
COVERS_PATH=./covers
|
||||||
|
UPLOADS_PATH=./uploads
|
||||||
Binary file not shown.
Vendored
BIN
Binary file not shown.
Binary file not shown.
+1
@@ -0,0 +1 @@
|
|||||||
|
../color-support/bin.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../mime/cli.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../mkdirp/bin/cmd.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../node-gyp/bin/node-gyp.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../which/bin/node-which
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../nodemon/bin/nodemon.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../touch/bin/nodetouch.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../nopt/bin/nopt.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../prebuild-install/bin.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../rc/cli.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../rimraf/bin.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../semver/bin/semver.js
|
||||||
+3439
File diff suppressed because it is too large
Load Diff
+10
@@ -0,0 +1,10 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright © 2020-2022 Michael Garvin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
# @gar/promisify
|
||||||
|
|
||||||
|
### Promisify an entire object or class instance
|
||||||
|
|
||||||
|
This module leverages es6 Proxy and Reflect to promisify every function in an
|
||||||
|
object or class instance.
|
||||||
|
|
||||||
|
It assumes the callback that the function is expecting is the last
|
||||||
|
parameter, and that it is an error-first callback with only one value,
|
||||||
|
i.e. `(err, value) => ...`. This mirrors node's `util.promisify` method.
|
||||||
|
|
||||||
|
In order that you can use it as a one-stop-shop for all your promisify
|
||||||
|
needs, you can also pass it a function. That function will be
|
||||||
|
promisified as normal using node's built-in `util.promisify` method.
|
||||||
|
|
||||||
|
[node's custom promisified
|
||||||
|
functions](https://nodejs.org/api/util.html#util_custom_promisified_functions)
|
||||||
|
will also be mirrored, further allowing this to be a drop-in replacement
|
||||||
|
for the built-in `util.promisify`.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Promisify an entire object
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const promisify = require('@gar/promisify')
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
constructor (attr) {
|
||||||
|
this.attr = attr
|
||||||
|
}
|
||||||
|
|
||||||
|
double (input, cb) {
|
||||||
|
cb(null, input * 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
const foo = new Foo('baz')
|
||||||
|
const promisified = promisify(foo)
|
||||||
|
|
||||||
|
console.log(promisified.attr)
|
||||||
|
console.log(await promisified.double(1024))
|
||||||
|
```
|
||||||
|
|
||||||
|
Promisify a function
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const promisify = require('@gar/promisify')
|
||||||
|
|
||||||
|
function foo (a, cb) {
|
||||||
|
if (a !== 'bad') {
|
||||||
|
return cb(null, 'ok')
|
||||||
|
}
|
||||||
|
return cb('not ok')
|
||||||
|
}
|
||||||
|
|
||||||
|
const promisified = promisify(foo)
|
||||||
|
|
||||||
|
// This will resolve to 'ok'
|
||||||
|
promisified('good')
|
||||||
|
|
||||||
|
// this will reject
|
||||||
|
promisified('bad')
|
||||||
|
```
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const { promisify } = require('util')
|
||||||
|
|
||||||
|
const handler = {
|
||||||
|
get: function (target, prop, receiver) {
|
||||||
|
if (typeof target[prop] !== 'function') {
|
||||||
|
return target[prop]
|
||||||
|
}
|
||||||
|
if (target[prop][promisify.custom]) {
|
||||||
|
return function () {
|
||||||
|
return Reflect.get(target, prop, receiver)[promisify.custom].apply(target, arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return function () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Reflect.get(target, prop, receiver).apply(target, [...arguments, function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
resolve(result)
|
||||||
|
}])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (thingToPromisify) {
|
||||||
|
if (typeof thingToPromisify === 'function') {
|
||||||
|
return promisify(thingToPromisify)
|
||||||
|
}
|
||||||
|
if (typeof thingToPromisify === 'object') {
|
||||||
|
return new Proxy(thingToPromisify, handler)
|
||||||
|
}
|
||||||
|
throw new TypeError('Can only promisify functions or objects')
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "@gar/promisify",
|
||||||
|
"version": "1.1.3",
|
||||||
|
"description": "Promisify an entire class or object",
|
||||||
|
"main": "index.js",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/wraithgar/gar-promisify.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": "standard",
|
||||||
|
"lint:fix": "standard --fix",
|
||||||
|
"test": "lab -a @hapi/code -t 100",
|
||||||
|
"posttest": "npm run lint"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
],
|
||||||
|
"keywords": [
|
||||||
|
"promisify",
|
||||||
|
"all",
|
||||||
|
"class",
|
||||||
|
"object"
|
||||||
|
],
|
||||||
|
"author": "Gar <gar+npm@danger.computer>",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@hapi/code": "^8.0.1",
|
||||||
|
"@hapi/lab": "^24.1.0",
|
||||||
|
"standard": "^16.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isHoge(arg){
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isHoge;
|
||||||
+123
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
可変長引数ではないis関数詰め合わせモジュール
|
||||||
|
略称版メソッドもなし
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 型・インスタンス
|
||||||
|
import isArray from './is-array.mjs';
|
||||||
|
import isBoolean from './is-boolean.mjs';
|
||||||
|
import isBuffer from './is-buffer.mjs';
|
||||||
|
import isArrayBuffer from './is-array-buffer.mjs';
|
||||||
|
import isError from './is-error.mjs';
|
||||||
|
import isFunction from './is-function.mjs';
|
||||||
|
import isAsyncFunction from './is-async-function.mjs';
|
||||||
|
import isAsyncGeneratorFunction from './is-async-generator-function.mjs';
|
||||||
|
import isGeneratorFunction from './is-generator-function.mjs';
|
||||||
|
import isNumber from './is-number.mjs';
|
||||||
|
import isRegExp from './is-reg-exp.mjs';
|
||||||
|
import isStats from './is-stats.mjs';
|
||||||
|
import isString from './is-string.mjs';
|
||||||
|
import isUndefined from './is-undefined.mjs';
|
||||||
|
import isNull from './is-null.mjs';
|
||||||
|
import isNaN from './is-nan.mjs';
|
||||||
|
import isDate from './is-date.mjs';
|
||||||
|
import isEvent from './is-event.mjs';
|
||||||
|
import isEventTarget from './is-event-target.mjs';
|
||||||
|
import isObject from './is-object.mjs';
|
||||||
|
import isPromise from './is-promise.mjs';
|
||||||
|
import isAbortController from './is-abort-controller.mjs';
|
||||||
|
import isAbortSignal from './is-abort-signal.mjs';
|
||||||
|
|
||||||
|
// Number系
|
||||||
|
import isOdd from './is-odd.mjs';
|
||||||
|
import isEven from './is-even.mjs';
|
||||||
|
import isMultiple from './is-multiple.mjs';
|
||||||
|
|
||||||
|
// String系
|
||||||
|
import isLowercase from './is-lowercase.mjs';
|
||||||
|
import isUppercase from './is-uppercase.mjs';
|
||||||
|
import isIPv4 from './is-ipv4.mjs';
|
||||||
|
import isHostname from './is-hostname.mjs';
|
||||||
|
|
||||||
|
// DOM
|
||||||
|
import isNode from './is-node.mjs';
|
||||||
|
import isTextNode from './is-text-node.mjs';
|
||||||
|
import isElement from './is-element.mjs';
|
||||||
|
import isDocumentFragment from './is-document-fragment.mjs';
|
||||||
|
|
||||||
|
|
||||||
|
// 雑多
|
||||||
|
import isTrue from './is-true.mjs';
|
||||||
|
import isFalse from './is-false.mjs';
|
||||||
|
import isTruthy from './is-truthy.mjs';
|
||||||
|
import isFalsy from './is-falsy.mjs';
|
||||||
|
import isInstance from './is-instance.mjs';
|
||||||
|
import isInstanceof from './is-instanceof.mjs';
|
||||||
|
import isInstanceOfClassName from './is-instance-of-classname.mjs';
|
||||||
|
import isNullish from './is-nullish.mjs';
|
||||||
|
import isObjectLiteral from './is-object-literal.mjs';
|
||||||
|
import isArrayLike from './is-array-like.mjs';
|
||||||
|
import isComparisonOperator from './is-comparison-operator.mjs';
|
||||||
|
import isSameDay from './is-same-day.mjs';
|
||||||
|
import isSemVer from './is-sem-ver.mjs';
|
||||||
|
import isVersion from './is-version.mjs';
|
||||||
|
import isEmpty from './is-empty.mjs';
|
||||||
|
import isLeapYear from './is-leap-year.mjs';
|
||||||
|
import isValidDate from './is-valid-date.mjs';
|
||||||
|
|
||||||
|
// 返り値
|
||||||
|
const _is = {
|
||||||
|
isArray,
|
||||||
|
isBoolean,
|
||||||
|
isBuffer,
|
||||||
|
isArrayBuffer,
|
||||||
|
isError,
|
||||||
|
isFunction,
|
||||||
|
isAsyncFunction,
|
||||||
|
isAsyncGeneratorFunction,
|
||||||
|
isGeneratorFunction,
|
||||||
|
isNumber,
|
||||||
|
isRegExp,
|
||||||
|
isStats,
|
||||||
|
isString,
|
||||||
|
isUndefined,
|
||||||
|
isNull,
|
||||||
|
isNaN,
|
||||||
|
isDate,
|
||||||
|
isEvent,
|
||||||
|
isEventTarget,
|
||||||
|
isObject,
|
||||||
|
isPromise,
|
||||||
|
isAbortController,
|
||||||
|
isAbortSignal,
|
||||||
|
isOdd,
|
||||||
|
isEven,
|
||||||
|
isMultiple,
|
||||||
|
isLowercase,
|
||||||
|
isUppercase,
|
||||||
|
isIPv4,
|
||||||
|
isHostname,
|
||||||
|
isNode,
|
||||||
|
isTextNode,
|
||||||
|
isElement,
|
||||||
|
isDocumentFragment,
|
||||||
|
isTrue,
|
||||||
|
isFalse,
|
||||||
|
isTruthy,
|
||||||
|
isFalsy,
|
||||||
|
isInstance,
|
||||||
|
isInstanceof,
|
||||||
|
isInstanceOfClassName,
|
||||||
|
isNullish,
|
||||||
|
isObjectLiteral,
|
||||||
|
isArrayLike,
|
||||||
|
isComparisonOperator,
|
||||||
|
isSameDay,
|
||||||
|
isSemVer,
|
||||||
|
isVersion,
|
||||||
|
isEmpty,
|
||||||
|
isLeapYear,
|
||||||
|
isValidDate
|
||||||
|
}
|
||||||
|
|
||||||
|
export default _is;
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
import isObj from './is-object.mjs';
|
||||||
|
import isFunc from './is-function.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
引数がAbortControllerインスタンスか
|
||||||
|
Polyfillでも機能するようにしている。
|
||||||
|
*/
|
||||||
|
function isAbortController(ac){
|
||||||
|
return isObj(ac)
|
||||||
|
&& isFunc(ac.constructor)
|
||||||
|
&& ac.constructor.name==='AbortController';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isAbortController;
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
import isObj from './is-object.mjs';
|
||||||
|
import isFunc from './is-function.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
引数がAbortSignalインスタンスか
|
||||||
|
Polyfillでも機能するようにしている。
|
||||||
|
*/
|
||||||
|
function isAbortSignal(abortSignal){
|
||||||
|
// const isETExtend = abortSignal instanceof EventTarget;
|
||||||
|
return isObj(abortSignal)
|
||||||
|
&& isFunc(abortSignal.constructor)
|
||||||
|
&& abortSignal.constructor.name==='AbortSignal';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isAbortSignal;
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// Mod
|
||||||
|
import isInstance from './is-instance.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
ArrayBufferインスタンスか
|
||||||
|
|
||||||
|
args
|
||||||
|
1: any
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
function isArrayBuffer(arg){
|
||||||
|
return isInstance(arg, ArrayBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isArrayBuffer;
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
定義: truthyで、.lengthで数値を返すもの
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isArrayLike(arg){
|
||||||
|
return !!arg && typeof arg.length==='number';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default isArrayLike;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
function isArray(arg){
|
||||||
|
return Array.isArray(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isArray;
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
import isInstanceof from './is-instanceof.mjs';
|
||||||
|
|
||||||
|
let AsyncFunction;
|
||||||
|
|
||||||
|
function isAsyncFunction(arg){
|
||||||
|
|
||||||
|
if( !AsyncFunction ){
|
||||||
|
AsyncFunction = (async()=>0).constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isInstanceof(arg, AsyncFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isAsyncFunction;
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
import isInstanceof from './is-instanceof.mjs';
|
||||||
|
|
||||||
|
let AsyncGeneratorFunction;
|
||||||
|
|
||||||
|
function isAsyncGeneratorFunction(arg){
|
||||||
|
|
||||||
|
if( !AsyncGeneratorFunction ){
|
||||||
|
AsyncGeneratorFunction = (async function*(){}).constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isInstanceof(arg, AsyncGeneratorFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isAsyncGeneratorFunction;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
function isBoolean(arg){
|
||||||
|
return typeof arg==='boolean';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isBoolean;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
function isBuffer(arg){
|
||||||
|
return Buffer.isBuffer(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isBuffer;
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
有効な比較演算子の文字列か
|
||||||
|
[比較演算子 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 有効な比較演算子のset
|
||||||
|
const set_co = new Set([
|
||||||
|
'<',
|
||||||
|
'>',
|
||||||
|
'<=',
|
||||||
|
'>=',
|
||||||
|
'==',
|
||||||
|
'!=',
|
||||||
|
'===',
|
||||||
|
'!=='
|
||||||
|
]);
|
||||||
|
|
||||||
|
function isComparisonOperator(arg){
|
||||||
|
return typeof arg==='string' && set_co.has(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isComparisonOperator;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
function isDate(arg){
|
||||||
|
return arg instanceof Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isDate;
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
import isNode from './is-node.mjs';
|
||||||
|
|
||||||
|
function isDocumentFragment(arg){
|
||||||
|
return isNode(arg) && arg.nodeType===11;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isDocumentFragment;
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
function isElement(arg){
|
||||||
|
return arg instanceof Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isElement;
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
引数が空か
|
||||||
|
|
||||||
|
判定基準
|
||||||
|
文字列
|
||||||
|
長さが0の場合
|
||||||
|
配列
|
||||||
|
長さが0の場合
|
||||||
|
オブジェクト
|
||||||
|
keyが存在しない場合
|
||||||
|
それ以外
|
||||||
|
常にfalse
|
||||||
|
*/
|
||||||
|
function isEmpty(arg){
|
||||||
|
if(typeof arg==='string'){
|
||||||
|
return !arg.length;
|
||||||
|
}else if( Array.isArray(arg) ){
|
||||||
|
return !arg.length;
|
||||||
|
}else if(typeof arg==='object' && arg instanceof Object){
|
||||||
|
return !Object.getOwnPropertyNames(arg).length;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isEmpty;
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isError(arg){
|
||||||
|
return arg instanceof Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isError;
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// Mod
|
||||||
|
import isNumber from './is-number.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
偶数判定(0含む)
|
||||||
|
*/
|
||||||
|
function isEven(num){
|
||||||
|
return isNumber(num) && !(num % 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isEven;
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
function isEventTarget(arg){
|
||||||
|
return arg instanceof EventTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isEventTarget;
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
function isEvent(arg){
|
||||||
|
return arg instanceof Event;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isEvent;
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isFalse(arg){
|
||||||
|
return arg===false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isFalse;
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
function isFalsy(arg){
|
||||||
|
return !arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isFalsy;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
function isFunction(arg){
|
||||||
|
return typeof arg==='function';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isFunction;
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
import isInstanceof from './is-instanceof.mjs';
|
||||||
|
|
||||||
|
let GeneratorFunction;
|
||||||
|
|
||||||
|
function isGeneratorFunction(arg){
|
||||||
|
|
||||||
|
if( !GeneratorFunction ){
|
||||||
|
GeneratorFunction = (function*(){}).constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isInstanceof(arg, GeneratorFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isGeneratorFunction;
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// Var
|
||||||
|
const re_label = /[a-z0-9][a-z0-9-]*[a-z0-9]/;
|
||||||
|
const re_tld = /[a-z]{2,}|[a-z]{2}\.[a-z]{2}/;
|
||||||
|
const re_domain = new RegExp(`${re_label.source}\.${re_tld.source}`);
|
||||||
|
const re_hostname = new RegExp(`^(${re_label.source}\\.)*${re_domain.source}$`, 'i');
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
ホスト名文字列か
|
||||||
|
厳密な仕様がよくわからないのでルーズに判定している。
|
||||||
|
大文字・小文字を区別しない。
|
||||||
|
実際には混在しているものがあるため。
|
||||||
|
dotで区切られた半角英数&ハイフン(ラベル)。
|
||||||
|
大文字・小文字は区別しない。
|
||||||
|
ハイフンは先頭・末尾NG.
|
||||||
|
ラベル毎の長さは2-63文字。
|
||||||
|
どこかで3文字以上と見たが、実際は二文字もよく振られている。
|
||||||
|
ドメイン部分は2文字もある。
|
||||||
|
合計255文字まで。
|
||||||
|
|
||||||
|
args
|
||||||
|
1: string
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
function isHostname(str){
|
||||||
|
const isU256 = str.length <= 255;
|
||||||
|
return isU256 && re_hostname.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default isHostname;
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
// mod
|
||||||
|
import isInstance from './is-instance.mjs';
|
||||||
|
import isString from './is-string.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
インスタンスの親クラスが指定した名称か
|
||||||
|
|
||||||
|
args
|
||||||
|
1: instance
|
||||||
|
2: string
|
||||||
|
3: op, object
|
||||||
|
return
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
function isInstanceOfClassName(instance, str_name, options={debug:false}){
|
||||||
|
|
||||||
|
options.debug && console.log('isInstanceOfClassName()', instance, str_name);
|
||||||
|
|
||||||
|
if( !isInstance(instance) ){
|
||||||
|
throw new TypeError('arg1 not instance');
|
||||||
|
}
|
||||||
|
if( !isString(str_name) ){
|
||||||
|
throw new TypeError('arg2 not string');
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance.constructor.name===str_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isInstanceOfClassName;
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
// Mod
|
||||||
|
import isObject from './is-object.mjs';
|
||||||
|
import isFunction from './is-function.mjs';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
args === 2
|
||||||
|
引数なにかのコンストラクタ関数・クラスのインスタンスか
|
||||||
|
true条件
|
||||||
|
オブジェクト
|
||||||
|
.constructorが関数
|
||||||
|
.__proto__が上記関数のprototype
|
||||||
|
|
||||||
|
args
|
||||||
|
1: any
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
function isInstance(any){
|
||||||
|
if( isObject(any) ){
|
||||||
|
const parent = any.constructor;
|
||||||
|
return isFunction(parent) &&
|
||||||
|
Object.getPrototypeOf(any)===parent.prototype;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isInstance;
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
instanceof
|
||||||
|
|
||||||
|
args
|
||||||
|
1: any
|
||||||
|
2: any
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
function isInstanceof(arg, arg2){
|
||||||
|
try{
|
||||||
|
return arg instanceof arg2;
|
||||||
|
}catch(e){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isInstanceof;
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
// Var
|
||||||
|
const re_0to255 = /(\d|[1-9]\d|1\d{2}|2(5[0-5]|[0-4]\d))/;
|
||||||
|
const re_ipv4 = new RegExp(`^(${re_0to255.source}\\.){3}${re_0to255.source}$`);
|
||||||
|
|
||||||
|
/*
|
||||||
|
IPv4アドレス文字列か
|
||||||
|
dotで区切られた0-255が4つ。
|
||||||
|
|
||||||
|
args
|
||||||
|
1: string
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
function isIPv4(str){
|
||||||
|
return re_ipv4.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isIPv4;
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
閏年判定
|
||||||
|
|
||||||
|
引数
|
||||||
|
1: date or number
|
||||||
|
返り値
|
||||||
|
boolean
|
||||||
|
|
||||||
|
参考
|
||||||
|
[うるう年とは - はてなキーワード](http://d.hatena.ne.jp/keyword/%A4%A6%A4%EB%A4%A6%C7%AF)
|
||||||
|
*/
|
||||||
|
import isNumber from './is-number.mjs';
|
||||||
|
import isDate from './is-date.mjs';
|
||||||
|
|
||||||
|
function isLeapYear(arg){
|
||||||
|
if( isNumber(arg) ){
|
||||||
|
return isLeapYear_number(arg)
|
||||||
|
}else if( isDate(arg) ){
|
||||||
|
return isLeapYear_date(arg);
|
||||||
|
}else{
|
||||||
|
throw new TypeError(`Invalid arguments: ${arg}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dateインスタンス用
|
||||||
|
function isLeapYear_date(date){
|
||||||
|
const year = date.getFullYear();
|
||||||
|
return isLeapYear_number(year);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数値(年)用、本体
|
||||||
|
function isLeapYear_number(year){
|
||||||
|
return year % 4 === 0 && (year % 100!==0 || year % 400===0);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isLeapYear;
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// Mod
|
||||||
|
import isString from './is-string.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
引数文字列がすべて半角小文字か
|
||||||
|
*/
|
||||||
|
function isLowercase(arg){
|
||||||
|
|
||||||
|
if( !isString(arg) ){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return /^[a-z]+$/.test(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isLowercase;
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// Mod
|
||||||
|
import isNumber from './is-number.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
倍数判定
|
||||||
|
引数1が引数2の倍数か
|
||||||
|
|
||||||
|
args
|
||||||
|
1: number
|
||||||
|
2: number
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isMultiple(arg1, arg2){
|
||||||
|
|
||||||
|
// validation
|
||||||
|
if( !isNumber(arg1) ){
|
||||||
|
throw TypeError('Invalid arguments 1');
|
||||||
|
}
|
||||||
|
if( !isNumber(arg2) ){
|
||||||
|
throw TypeError('Invalid arguments 1');
|
||||||
|
}
|
||||||
|
|
||||||
|
return !(arg1%arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isMultiple;
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// arg!=argでいい気もするがPolyfill前提のコンセプトのため
|
||||||
|
function isNaN(arg){
|
||||||
|
return Number.isNaN(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isNaN;
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// Mod
|
||||||
|
import isNumber from './is-number.mjs';
|
||||||
|
import isObject from './is-object.mjs';
|
||||||
|
|
||||||
|
function isNode(arg){
|
||||||
|
return arg instanceof Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isNode;
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
function isNull(arg){
|
||||||
|
return arg===null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isNull;
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
null or undef
|
||||||
|
|
||||||
|
args
|
||||||
|
1: any
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
function isNullish(arg){
|
||||||
|
if( arg===null ){
|
||||||
|
return true;
|
||||||
|
}else if( arg===undefined ){
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isNullish;
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
function isNumber(arg){
|
||||||
|
return typeof arg==='number';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isNumber;
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
const obj = {} みたいなの
|
||||||
|
arg.constructor===Object でもよさそう。
|
||||||
|
|
||||||
|
2020.11.08
|
||||||
|
Object#__proto__ => Object.getPrototypeOf()
|
||||||
|
*/
|
||||||
|
function isObjectLiteral(arg){
|
||||||
|
return Object.getPrototypeOf(arg)===Object.prototype;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isObjectLiteral;
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
typeofと違ってnullは弾く
|
||||||
|
|
||||||
|
ChangeLog
|
||||||
|
2020.10.25
|
||||||
|
判定をinstanceofから以前の方法に戻した。
|
||||||
|
Object.create(null) で作られたものを検出できなかったため。
|
||||||
|
*/
|
||||||
|
function isObject(arg){
|
||||||
|
return !!arg && arg===Object(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isObject;
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
奇数判定(0含む)
|
||||||
|
*/
|
||||||
|
import isNumber from './is-number.mjs';
|
||||||
|
|
||||||
|
function isOdd(num){
|
||||||
|
return isNumber(num) && !!(num % 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isOdd;
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
引数がPromiseインスタンスか
|
||||||
|
*/
|
||||||
|
function isPromise(arg){
|
||||||
|
return arg instanceof Promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isPromise;
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
function isRegExp(arg){
|
||||||
|
return arg instanceof RegExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isRegExp;
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
import isDate from './is-date.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
引数のdateインスタンスが同じ日か
|
||||||
|
|
||||||
|
args
|
||||||
|
1...: date
|
||||||
|
result
|
||||||
|
boolean
|
||||||
|
*/
|
||||||
|
function isSameday(...arr_date){
|
||||||
|
let str_baseDateText;
|
||||||
|
|
||||||
|
for(let date of arr_date ){
|
||||||
|
if( !isDate(date) ){
|
||||||
|
throw new TypeError(`Invalid arguments: ${index}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !str_baseDateText ){
|
||||||
|
str_baseDateText = date.toDateString();
|
||||||
|
}else{
|
||||||
|
const str_dateText = date.toDateString();
|
||||||
|
if(str_baseDateText!==str_dateText){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isSameday;
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
SemVerな文字列かどうか
|
||||||
|
regexpを長々と繋げて頑張ると次弄るときに頭痛くなるから極力分割する
|
||||||
|
参考
|
||||||
|
[SemVerのv1.0.0とv2.0.0-rc.1、node-semverを見比べてみた - /var/log/kozy4324](http://kozy4324.github.io/blog/2012/12/19/semver/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isSemVer(arg){
|
||||||
|
if( typeof arg!=='string'){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( /^\d\.\d\.\d$/.test(arg) ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( /^\d\.\d\.\d-[0-9A-Za-z-.]*$/.test(arg) ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isSemVer;
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// Mod
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
function isStats(arg){
|
||||||
|
try{
|
||||||
|
return arg instanceof fs.Stats;
|
||||||
|
}catch(e){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isStats;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
function isString(arg){
|
||||||
|
return typeof arg==='string';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isString;
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
import isNode from './is-node.mjs';
|
||||||
|
|
||||||
|
function isTextNode(arg){
|
||||||
|
return isNode(arg) && arg.nodeType===3;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isTextNode;
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
comment
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isTrue(arg){
|
||||||
|
return arg===true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isTrue;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
function isTruthy(arg){
|
||||||
|
return !!arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isTruthy;
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
function isUndefined(arg){
|
||||||
|
return arg===undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isUndefined;
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// Mod
|
||||||
|
import isString from './is-string.mjs';
|
||||||
|
|
||||||
|
/*
|
||||||
|
引数文字列がすべて大文字か
|
||||||
|
*/
|
||||||
|
function isUppercase(arg){
|
||||||
|
|
||||||
|
if( !isString(arg) ){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return /^[A-Z]+$/.test(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isUppercase;
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
引数の日時が存在するものかをBooleanで返す
|
||||||
|
|
||||||
|
引数
|
||||||
|
1, 2, 3: number
|
||||||
|
返り値
|
||||||
|
boolean
|
||||||
|
|
||||||
|
参考
|
||||||
|
[Vanilla JavaScriptで簡単に日付が有効かどうかチェックする方法 | Rriver](https://parashuto.com/rriver/development/validate-date-using-vanilla-js)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Mod
|
||||||
|
import isNumber from './is-number.mjs';
|
||||||
|
|
||||||
|
function isValidDate(year, month, day){
|
||||||
|
|
||||||
|
if( !isNumber(year, month, day) ){
|
||||||
|
throw new TypeError(`Invalid arguments`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const date = new Date(year, month-1, day);
|
||||||
|
const isSameYear = date.getFullYear()===year;
|
||||||
|
const isSameMonth = date.getMonth()===(month-1);
|
||||||
|
const isSameDay = date.getDate()===day;
|
||||||
|
const result = isSameYear && isSameMonth && isSameDay;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isValidDate;
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
versionを表した数字とdotの文字列か
|
||||||
|
|
||||||
|
セーフ
|
||||||
|
1
|
||||||
|
1.2
|
||||||
|
1.2.3
|
||||||
|
1.2.3.4
|
||||||
|
アウト
|
||||||
|
1.2A
|
||||||
|
其の弐
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isVersion(arg){
|
||||||
|
return typeof arg==='string' && /^\d(|[0-9.]*\d)$/.test(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default isVersion;
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
any
|
||||||
|
引数どれか一つでも適正ならtrueを返す
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Mod
|
||||||
|
import _is from './_is/index.mjs'; // 素の判定モジュール詰め合わせ
|
||||||
|
import config from './config.mjs'; // 設定
|
||||||
|
|
||||||
|
// このモジュール返り値
|
||||||
|
const any = Object.create(null);
|
||||||
|
|
||||||
|
/*
|
||||||
|
_isの関数を元に改名&可変長引数化
|
||||||
|
可変長引数
|
||||||
|
引数があれば判定関数を渡してsome、なければfalseを返す
|
||||||
|
config.variadic.ignoreと一致するメソッド名は無視する
|
||||||
|
改名
|
||||||
|
config.shortのpropertyと一致する名前のメソッドは略称版を作る
|
||||||
|
|
||||||
|
*/
|
||||||
|
for(let [key, func] of Object.entries(_is)){
|
||||||
|
|
||||||
|
|
||||||
|
// 関数名作り isFooBar => FooBar, foobar [, FB, fb]
|
||||||
|
const nameArr = [];
|
||||||
|
const name1 = key.slice(2);
|
||||||
|
const name2 = name1.toLowerCase();
|
||||||
|
nameArr.push(name1, name2);
|
||||||
|
// 略称版があれば作る
|
||||||
|
if( config.short[key] ){
|
||||||
|
const arr_alias = Array.isArray(config.short[key]) ?
|
||||||
|
config.short[key]:
|
||||||
|
[config.short[key]];
|
||||||
|
arr_alias.forEach( (name)=>{
|
||||||
|
// console.log('methodName:', name);
|
||||||
|
const str_Camel = name.slice(2); // "is"をカット
|
||||||
|
const str_lower = str_Camel.toLowerCase(); // "Method" => "method"
|
||||||
|
nameArr.push(str_Camel, str_lower);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可変長引数化
|
||||||
|
const method = (function(){
|
||||||
|
const isVariadic = !config.variadic.ignore.includes(key);
|
||||||
|
// console.log(`isVariadic: ${key} ${isVariadic}`);
|
||||||
|
if( isVariadic ){
|
||||||
|
return (...args)=>{
|
||||||
|
return args.length ?
|
||||||
|
args.some(func):
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
||||||
|
nameArr.forEach( (name)=>{
|
||||||
|
any[name] = method;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default any;
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
設定オブジェクトを返す
|
||||||
|
*/
|
||||||
|
const config = {
|
||||||
|
|
||||||
|
// 可変長引数に関する設定
|
||||||
|
variadic: {
|
||||||
|
ignore: [// 無視する関数名(非対応・元から対応などで)
|
||||||
|
'isInstanceof',
|
||||||
|
'isInstanceOfClassName',
|
||||||
|
'isMultiple',
|
||||||
|
'isValidDate',
|
||||||
|
'isSameDay'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 別名付けるやつ
|
||||||
|
short: {
|
||||||
|
isArray: 'isArr',
|
||||||
|
isBoolean: 'isBool',
|
||||||
|
isBuffer: 'isBuf',
|
||||||
|
isArrayBuffer: 'isArrBuf',
|
||||||
|
isError: 'isErr',
|
||||||
|
isFunction: ['isFunc', 'isFn'],
|
||||||
|
isNumber: 'isNum',
|
||||||
|
isRegExp: 'isRE',
|
||||||
|
isString: 'isStr',
|
||||||
|
isObject: 'isObj',
|
||||||
|
isUndefined: 'isUndef',
|
||||||
|
isElement: 'isElm',
|
||||||
|
isDocumentFragment: 'isDF',
|
||||||
|
isVersion: 'isVer'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config;
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
# document
|
||||||
|
という名の制作メモ。
|
||||||
|
|
||||||
|
|
||||||
|
## 仕様
|
||||||
|
* ESM
|
||||||
|
|
||||||
|
|
||||||
|
## Mod
|
||||||
|
|
||||||
|
### devDependencies
|
||||||
|
* jsdom
|
||||||
|
- DOM関連。
|
||||||
|
|
||||||
|
|
||||||
|
## dir構成
|
||||||
|
|
||||||
|
### ./
|
||||||
|
* index.mjs
|
||||||
|
- is.mjs, not.mjs, any.mjsをまとめて返すだけ。
|
||||||
|
* is.mjs
|
||||||
|
- ./\_is/index.mjsを可変長引数化する。
|
||||||
|
* not.mjs
|
||||||
|
- is.mjsを元にnot関数を作成する。
|
||||||
|
* any.mjs
|
||||||
|
- ./\_is/index.mjsを元にany関数を作成する。
|
||||||
|
* config.mjs
|
||||||
|
- 設定オブジェクトを返すモジュール。
|
||||||
|
|
||||||
|
### ./\_is.
|
||||||
|
素の判定関数詰め合わせモジュールを返すディレクトリ。
|
||||||
|
* index.mjs
|
||||||
|
- 本体。
|
||||||
|
* ^is-[a-z-]+\.mjs$
|
||||||
|
- 個別の判定関数を返すモジュール。
|
||||||
|
|
||||||
|
### ./test
|
||||||
|
* index.mjs
|
||||||
|
- npm tで呼び出されるテストスクリプト。
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
まとめるだけ
|
||||||
|
もっとスマートな書き方がありそう。
|
||||||
|
*/
|
||||||
|
|
||||||
|
import _is from './is.mjs';
|
||||||
|
import _not from './not.mjs';
|
||||||
|
import _any from './any.mjs';
|
||||||
|
|
||||||
|
export const is = _is;
|
||||||
|
export const not = _not;
|
||||||
|
export const any = _any;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
is, not, any
|
||||||
|
}
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
可変長引数化
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 素の判定モジュール詰め合わせ
|
||||||
|
import _is from './_is/index.mjs';
|
||||||
|
|
||||||
|
// 設定
|
||||||
|
import config from './config.mjs';
|
||||||
|
|
||||||
|
// このモジュール返り値
|
||||||
|
const is = Object.create(null);
|
||||||
|
|
||||||
|
/*
|
||||||
|
_isの関数を元に改名&可変長引数化
|
||||||
|
可変長引数
|
||||||
|
引数があれば判定関数を渡してevery、なければfalseを返す
|
||||||
|
config.variadic.ignoreと一致するメソッド名は無視する
|
||||||
|
改名
|
||||||
|
config.shortのpropertyと一致する名前のメソッドは略称版を作る
|
||||||
|
|
||||||
|
*/
|
||||||
|
for(let [key, func] of Object.entries(_is)){
|
||||||
|
|
||||||
|
|
||||||
|
// 関数名作り isFooBar => FooBar, foobar [, FB, fb]
|
||||||
|
const nameArr = [];
|
||||||
|
const name1 = key.slice(2);
|
||||||
|
const name2 = name1.toLowerCase();
|
||||||
|
nameArr.push(name1, name2);
|
||||||
|
// 略称版があれば作る
|
||||||
|
if( config.short[key] ){
|
||||||
|
const arr_alias = Array.isArray(config.short[key]) ?
|
||||||
|
config.short[key]:
|
||||||
|
[config.short[key]];
|
||||||
|
arr_alias.forEach( (name)=>{
|
||||||
|
// console.log('methodName:', name);
|
||||||
|
const str_Camel = name.slice(2); // "is"をカット
|
||||||
|
const str_lower = str_Camel.toLowerCase(); // "Method" => "method"
|
||||||
|
nameArr.push(str_Camel, str_lower);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可変長引数化
|
||||||
|
const method = (function(){
|
||||||
|
const isVariadic = !config.variadic.ignore.includes(key);
|
||||||
|
// console.log(`isVariadic: ${key} ${isVariadic}`);
|
||||||
|
if( isVariadic ){
|
||||||
|
return (...args)=>{
|
||||||
|
return args.length ?
|
||||||
|
args.every(func):
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
||||||
|
nameArr.forEach( (name)=>{
|
||||||
|
is[name] = method;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default is;
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
isを元にnot作成
|
||||||
|
*/
|
||||||
|
import is from './is.mjs';
|
||||||
|
|
||||||
|
const not = Object.create(null);
|
||||||
|
|
||||||
|
for(let [key, func] of Object.entries(is) ){
|
||||||
|
not[key] = (...args)=>{
|
||||||
|
return !func(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default not;
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "@honeo/check",
|
||||||
|
"version": "2.9.0",
|
||||||
|
"description": "型・インスタンスなどの確認",
|
||||||
|
"main": "index.mjs",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node ./test/index.mjs"
|
||||||
|
},
|
||||||
|
"author": "honeo",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@azure/abort-controller": "^1.0.4",
|
||||||
|
"jsdom": "^16.5.0",
|
||||||
|
"node-abort-controller": "^3.0.0"
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"test": "test"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/honeo/check.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"check",
|
||||||
|
"type",
|
||||||
|
"instance"
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/honeo/check/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/honeo/check#readme"
|
||||||
|
}
|
||||||
+271
@@ -0,0 +1,271 @@
|
|||||||
|
# check
|
||||||
|
* [honeo/check](https://github.com/honeo/check)
|
||||||
|
* [@honeo/check](https://www.npmjs.com/package/@honeo/check)
|
||||||
|
|
||||||
|
|
||||||
|
## なにこれ
|
||||||
|
型・インスタンス等をチェックするやつ。
|
||||||
|
|
||||||
|
|
||||||
|
## 使い方
|
||||||
|
```bash
|
||||||
|
$ npm i @honeo/check
|
||||||
|
```
|
||||||
|
```js
|
||||||
|
import {is, not, any} from '@honeo/check';
|
||||||
|
|
||||||
|
is.arr([]); // true
|
||||||
|
|
||||||
|
is.arr([], {}); // false
|
||||||
|
not.arr([], {}); // false
|
||||||
|
any.arr([], {}); // true
|
||||||
|
|
||||||
|
|
||||||
|
// single
|
||||||
|
import is from '@honeo/check/is.mjs'; // or not.mjs, any.mjs
|
||||||
|
|
||||||
|
// default export
|
||||||
|
import check from '@honeo/check';
|
||||||
|
check.is.foobar();
|
||||||
|
```
|
||||||
|
```js
|
||||||
|
// webpack v4~ webpack.config.js
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
fs: 'empty'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## API
|
||||||
|
is, not, any共用。
|
||||||
|
|
||||||
|
### Alias
|
||||||
|
```js
|
||||||
|
is.FooBar===is.foobar; // true
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Type, Instance
|
||||||
|
```js
|
||||||
|
is.array([]); // true
|
||||||
|
is.arr([], []); // true
|
||||||
|
|
||||||
|
is.boolean(false); // true
|
||||||
|
is.bool(true, false); // true
|
||||||
|
|
||||||
|
is.buffer(new Buffer('foobar')); // true
|
||||||
|
is.arraybuffer( new ArrayBuffer(0)); // true
|
||||||
|
|
||||||
|
is.error(new Error('hoge')); // true
|
||||||
|
|
||||||
|
is.function(function(){}); // true
|
||||||
|
is.func(()=>{}); // true
|
||||||
|
is.fn(_=>_); // true
|
||||||
|
|
||||||
|
is.asyncfunction(async()=>{}); // true
|
||||||
|
is.asyncgeneratorfunction(async function*(){}); // true
|
||||||
|
is.generatorfunction(function*(){}); // true
|
||||||
|
|
||||||
|
is.number(1); // true
|
||||||
|
is.num(0, 1); // true
|
||||||
|
|
||||||
|
is.regexp(/hoge/); // true
|
||||||
|
is.re(/foo/, /bar/); // true
|
||||||
|
|
||||||
|
is.string('hoge'); // true
|
||||||
|
is.str('fuga', 'piyo'); // true
|
||||||
|
|
||||||
|
is.undefined(undefined); // true
|
||||||
|
is.undef(null); // false
|
||||||
|
|
||||||
|
is.null(null); // true
|
||||||
|
|
||||||
|
is.nan(NaN); // true
|
||||||
|
|
||||||
|
is.date(new Date()); // true
|
||||||
|
|
||||||
|
is.object({}); // true
|
||||||
|
is.obj(null); // false
|
||||||
|
|
||||||
|
is.promise(new Promise(_=>_)); // true
|
||||||
|
|
||||||
|
is.stats( fs.statSync('./') ); // true
|
||||||
|
|
||||||
|
is.abortcontroller(new AbortController() ); // true
|
||||||
|
is.abortsignal(new AbortController().signal); // true
|
||||||
|
```
|
||||||
|
|
||||||
|
| name | type | varargs | description |
|
||||||
|
|:---------------------------------------------- |:---- |:-------:|:------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Array, Arr, array, arr | any | ○ | |
|
||||||
|
| Boolean, Bool, boolean, bool | any | ○ | |
|
||||||
|
| Buffer, Buf, buffer, buf | any | ○ | |
|
||||||
|
| Error, Err, error, err | any | ○ | |
|
||||||
|
| Function, Func, Fn, function, func, fn | any | ○ | |
|
||||||
|
| AsyncFunction, asyncfunction | any | ○ | |
|
||||||
|
| AsyncGeneratorFunction, asyncgeneratorfunction | any | ○ | |
|
||||||
|
| GeneratorFunction, generatorfunction | any | ○ | |
|
||||||
|
| Number, Num, number, num | any | ○ | |
|
||||||
|
| RegExp, RE, regexp, re | any | ○ | |
|
||||||
|
| String, Str, string, str | any | ○ | |
|
||||||
|
| Undefined, Undef, undefined, undef | any | ○ | |
|
||||||
|
| Null, null | any | ○ | |
|
||||||
|
| NaN, nan | any | ○ | |
|
||||||
|
| Date, date | any | ○ | |
|
||||||
|
| Object, Obj, object, obj | any | ○ | |
|
||||||
|
| Promise, promise | any | ○ | |
|
||||||
|
| Stats, stats | any | ○ | |
|
||||||
|
| ArrayBuffer, ArrBuf, arraybuffer, arrbuf | any | ○ | |
|
||||||
|
| AbortController, abortcontroller | any | ○ | [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)インスタンスか(Polyfill対応)。 |
|
||||||
|
| AbortSignal, abortsignal | any | ○ | [AbortSignal](https://developer.mozilla.org/ja/docs/Web/API/AbortSignal)インスタンスか(Polyfill対応)。 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Number
|
||||||
|
|
||||||
|
```js
|
||||||
|
is.even(2); // true
|
||||||
|
|
||||||
|
is.odd(3); // true
|
||||||
|
|
||||||
|
is.multiple(8080, 80); // true
|
||||||
|
```
|
||||||
|
|
||||||
|
| name | type | varargs | description |
|
||||||
|
|:------------------ |:------ |:-------:|:---------------------- |
|
||||||
|
| Odd, odd | number | ○ | 引数がすべて奇数か。 |
|
||||||
|
| Even, even | number | ○ | 引数がすべて偶数か。 |
|
||||||
|
| Multiple, multiple | number | ✗ | 引数1が引数2の倍数か。 |
|
||||||
|
|
||||||
|
### String
|
||||||
|
```js
|
||||||
|
is.ipv4('192.168.1.1'); // true
|
||||||
|
|
||||||
|
is.hostname('www.example.com'); // true
|
||||||
|
|
||||||
|
is.lowercase('hoge'); // true
|
||||||
|
|
||||||
|
is.uppercase('FOO', 'BAR'); // true
|
||||||
|
```
|
||||||
|
|
||||||
|
| name | type | varargs | description |
|
||||||
|
|:-------------------- |:------ |:-------:|:-------------- |
|
||||||
|
| IPv4, ipv4 | string | ○ | |
|
||||||
|
| Hostname, hostname | string | ○ | やっつけ実装。 |
|
||||||
|
| Lowercase, lowercase | string | ○ | |
|
||||||
|
| Uppercase, uppercase | string | ○ | |
|
||||||
|
|
||||||
|
### DOM
|
||||||
|
|
||||||
|
```js
|
||||||
|
is.node(document.body, document.createTextNode('hoge')); // true
|
||||||
|
|
||||||
|
is.textnode(document.createTextNode('hoge')); // true
|
||||||
|
|
||||||
|
is.element(document.head, document.body); // true
|
||||||
|
|
||||||
|
is.df(document.createDocumentFragment()); // true
|
||||||
|
|
||||||
|
is.event( new Event("hoge") ); // true
|
||||||
|
|
||||||
|
is.eventtarget(document, window); // true
|
||||||
|
```
|
||||||
|
|
||||||
|
| name | type | varargs | description |
|
||||||
|
|:------------------------------------------ |:---- |:-------:|:----------- |
|
||||||
|
| Node, node | any | ○ | |
|
||||||
|
| TextNode, textnode | any | ○ | |
|
||||||
|
| Element, Elm, element, elm | any | ○ | |
|
||||||
|
| DocumentFragment, DF, documentfragment, df | any | ○ | |
|
||||||
|
| Event, event | any | ○ | |
|
||||||
|
| EventTarget, eventtarget | any | ○ | |
|
||||||
|
|
||||||
|
|
||||||
|
### その他
|
||||||
|
|
||||||
|
```js
|
||||||
|
is.true(true, !0); // true
|
||||||
|
|
||||||
|
is.false(false !1); // true
|
||||||
|
|
||||||
|
is.truthy(true, "hoge", 1, [], {}); // true
|
||||||
|
|
||||||
|
is.falsy(null, undefined, "", 0, NaN); // true
|
||||||
|
|
||||||
|
is.instance([], {}); // true
|
||||||
|
is.instance("hoge"); // false
|
||||||
|
|
||||||
|
is.instanceof(new Date(), Date); //true
|
||||||
|
|
||||||
|
is.instanceOfClassName([], "Array"); // true
|
||||||
|
|
||||||
|
is.objectliteral({}); // true
|
||||||
|
not.objectliteral([], new function(){}); // true
|
||||||
|
|
||||||
|
is.arraylike([], 'hoge'); // true
|
||||||
|
|
||||||
|
is.comparisonoperator('<='); // true
|
||||||
|
|
||||||
|
is.sameDay(new Date(), new Date()); // true
|
||||||
|
|
||||||
|
is.semver('1.2.3'); // true
|
||||||
|
is.semver('1.0.0-foo.bar'); // true
|
||||||
|
|
||||||
|
is.version('7.7.4', '2.5.0.1') // true
|
||||||
|
is.version('1.2A', 1.0); // false
|
||||||
|
|
||||||
|
is.empty('', [], {}) // true
|
||||||
|
is.empty(0, null); // false
|
||||||
|
|
||||||
|
is.leapyear(2020, new Date('2024'));
|
||||||
|
|
||||||
|
is.validdate(2019, 4, 17); // true
|
||||||
|
is.validdate(2020, 12, 32); // false
|
||||||
|
```
|
||||||
|
|
||||||
|
| name | type | varargs | description |
|
||||||
|
|:-------------------------------------------- |:------------ |:-------:|:------------------------------------------------- |
|
||||||
|
| ArrayLike(), arraylike() | any | ○ | |
|
||||||
|
| True(), true() | any | ○ | |
|
||||||
|
| False(), false() | any | ○ | |
|
||||||
|
| Truthy(), truthy() | any | ○ | |
|
||||||
|
| Falsy(), falsy() | any | ○ | |
|
||||||
|
| Empty(), empty() | any | ○ | 要素が空か。 |
|
||||||
|
| Instance(), instance() | any | ○ | 何らかのインスタンスであるオブジェクトか。 |
|
||||||
|
| Instanceof(), instanceof() | any | ✗ | 引数1が引数2のConstructor/Classのインスタンスか。 |
|
||||||
|
| InstanceOfClassName(), instanceofclassname() | instance, string | ✗ | 引数1が引数2の名称を持つClassのインスタンスか。 |
|
||||||
|
| Nullish(), nullish() | any | ○ | null or undefined |
|
||||||
|
| ObjectLiteral(), objectliteral() | any | ○ | 未継承の素のオブジェクトか。 |
|
||||||
|
| ComparisonOperator(), comparisonoperator() | any | ○ | 有効な比較演算子の文字列か。 |
|
||||||
|
| SameDay(), sameday() | date | ○ | 同じ日か |
|
||||||
|
| SemVer(), semver() | any | ○ | 有効なSemVer文字列か。 |
|
||||||
|
| Version(), Ver(), versiom(), ver() | any | ○ | 有効な数字, dotのバージョン文字列か。 |
|
||||||
|
| LeapYear(), leapyear() | number, date | ○ | 閏年か。 |
|
||||||
|
| ValidDate(year, mon, day), validdate() | number | ✗ | 存在する日付か。 |
|
||||||
|
|
||||||
|
|
||||||
|
## Breaking Changes
|
||||||
|
|
||||||
|
### v2.0.0
|
||||||
|
|
||||||
|
#### CommonJS => ES Modules
|
||||||
|
```js
|
||||||
|
// before CJS
|
||||||
|
const {is, not, any} = require('@honeo/check');
|
||||||
|
|
||||||
|
|
||||||
|
// after ESM
|
||||||
|
import {is, not, any} from '@honeo/check';
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### rename: instance() => instanceof()
|
||||||
|
```js
|
||||||
|
// before
|
||||||
|
is.instance([], Array);
|
||||||
|
|
||||||
|
// after
|
||||||
|
is.instanceof([], Array);
|
||||||
|
```
|
||||||
+759
@@ -0,0 +1,759 @@
|
|||||||
|
// Mod: core
|
||||||
|
import assert from 'assert';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import url from 'url';
|
||||||
|
// Mod: npm
|
||||||
|
import JSDOM from 'jsdom';
|
||||||
|
// Mod: local
|
||||||
|
import check from '../index.mjs';
|
||||||
|
import {is, not, any} from '../index.mjs';
|
||||||
|
import _is from '../is.mjs';
|
||||||
|
|
||||||
|
|
||||||
|
// jsdom set
|
||||||
|
global.document = JSDOM.jsdom('hogehoge');
|
||||||
|
global.head = document.head;
|
||||||
|
global.window = document.defaultView;
|
||||||
|
global.Node = window.Node;
|
||||||
|
global.Element = window.Element;
|
||||||
|
global.Event = window.Event;
|
||||||
|
|
||||||
|
// Var
|
||||||
|
//const {is, not, any} = check;
|
||||||
|
const cases = {}
|
||||||
|
const __filename = url.fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
|
|
||||||
|
// Main
|
||||||
|
assert(is===check.is, 'Hybrid export failed')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log('.arraybuffer');
|
||||||
|
if( !is.arraybuffer(new ArrayBuffer(0)) ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
if( !not.arrbuf('hoge') ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log('.abortcontroller');
|
||||||
|
{
|
||||||
|
const ac = new AbortController();
|
||||||
|
if( is.abortcontroller(ac) ){
|
||||||
|
}else{
|
||||||
|
throw new Error('native: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const {AbortController} = await import('@azure/abort-controller');
|
||||||
|
const ac = new AbortController();
|
||||||
|
if( is.abortcontroller(ac) ){
|
||||||
|
}else{
|
||||||
|
throw new Error('@azure/abort-controller: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const {AbortController} = await import('node-abort-controller');
|
||||||
|
const ac = new AbortController();
|
||||||
|
if( is.abortcontroller(ac) ){
|
||||||
|
}else{
|
||||||
|
throw new Error('node-abort-controller: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('.abortsignal');
|
||||||
|
{
|
||||||
|
const as = new AbortController().signal;
|
||||||
|
if( is.abortsignal(as) ){
|
||||||
|
}else{
|
||||||
|
throw new Error('native: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const {AbortController} = await import('@azure/abort-controller');
|
||||||
|
const as = new AbortController().signal;
|
||||||
|
if( is.abortsignal(as) ){
|
||||||
|
}else{
|
||||||
|
throw new Error('@azure/abort-controller: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const {AbortController} = await import('node-abort-controller');
|
||||||
|
const as = new AbortController().signal;
|
||||||
|
if( is.abortsignal(as) ){
|
||||||
|
}else{
|
||||||
|
throw new Error('node-abort-controller: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log('.asyncfunction');
|
||||||
|
{
|
||||||
|
const asyncFunc = async()=>{}
|
||||||
|
const bool = is.asyncfunction(asyncFunc);
|
||||||
|
if( !bool ){
|
||||||
|
throw new Error('case async: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const bool = is.asyncfunction(_=>{});
|
||||||
|
if( bool ){
|
||||||
|
throw new Error('case sync: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const asyncFunc = async()=>{}
|
||||||
|
const bool = is.asyncfunction(asyncFunc, asyncFunc);
|
||||||
|
if( !bool ){
|
||||||
|
throw new Error('case async2: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const asyncFunc = async()=>{}
|
||||||
|
const bool = is.asyncfunction(asyncFunc, _=>{});
|
||||||
|
if( bool ){
|
||||||
|
throw new Error('case async, sync: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log('.asyncgeneratorfunction');
|
||||||
|
{
|
||||||
|
const asyncGeneFunc = async function*(){}
|
||||||
|
|
||||||
|
{
|
||||||
|
const bool = is.asyncgeneratorfunction(asyncGeneFunc);
|
||||||
|
if( !bool ){
|
||||||
|
throw new Error('case asyncGene: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const bool = is.asyncgeneratorfunction(_=>{});
|
||||||
|
if( bool ){
|
||||||
|
throw new Error('case sync: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const bool = is.asyncgeneratorfunction(asyncGeneFunc, asyncGeneFunc);
|
||||||
|
if( !bool ){
|
||||||
|
throw new Error('case asyncGene2: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const bool = is.asyncgeneratorfunction(asyncGeneFunc, _=>{});
|
||||||
|
if( bool ){
|
||||||
|
throw new Error('case asyncGene, sync: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log('.generatorfunction');
|
||||||
|
{
|
||||||
|
const geneFunc = function*(){}
|
||||||
|
const bool = is.generatorfunction(geneFunc);
|
||||||
|
if( !bool ){
|
||||||
|
throw new Error('case gene: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const bool = is.generatorfunction(_=>{});
|
||||||
|
if( bool ){
|
||||||
|
throw new Error('case func: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const geneFunc = function*(){}
|
||||||
|
const bool = is.generatorfunction(geneFunc, geneFunc);
|
||||||
|
if( !bool ){
|
||||||
|
throw new Error('case gene2: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const geneFunc = function*(){}
|
||||||
|
const bool = is.generatorfunction(_=>{}, geneFunc);
|
||||||
|
if( bool ){
|
||||||
|
throw new Error('case func, gene: failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log('isInstanceOfClassName');
|
||||||
|
{
|
||||||
|
let bool;
|
||||||
|
try{
|
||||||
|
is.instanceofclassname();
|
||||||
|
bool = false;
|
||||||
|
}catch(e){
|
||||||
|
bool = true;
|
||||||
|
}
|
||||||
|
assert(bool, 'case none arg: failed');
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const bool = is.instanceofclassname(new Date(), 'Date');
|
||||||
|
assert(bool, 'case success: failed');
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const bool = is.instanceofclassname({}, 'Array');
|
||||||
|
assert(!bool, 'case invalid classname: failed');
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let bool;
|
||||||
|
try{
|
||||||
|
is.instanceofclassname(true, false);
|
||||||
|
bool = false;
|
||||||
|
}catch(e){
|
||||||
|
bool = true;
|
||||||
|
}
|
||||||
|
assert(bool, 'case invalid arg: failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log('.hostname');
|
||||||
|
if(
|
||||||
|
!is.hostname('example.com') &&
|
||||||
|
!is.hostname('www.example.com') &&
|
||||||
|
!is.hostname('foo-bar-2000.example.com') &&
|
||||||
|
!is.hostname('hoge-1234.fu.ga.pi.yo') &&
|
||||||
|
!is.hostname('Hoge.example.com') &&
|
||||||
|
not.hostname('-invalid-hostname.example.com') &&
|
||||||
|
not.hostname('very-long-hostnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaame.example.com')
|
||||||
|
){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('.ipv4');
|
||||||
|
if(
|
||||||
|
!is.ipv4('192.168.1.1') &&
|
||||||
|
!is.ipv4('0.0.0.0') &&
|
||||||
|
!is.ipv4('255.255.255.255') &&
|
||||||
|
!not.ipv4('32.64.128.256') &&
|
||||||
|
!not.ipv4('123.123.123') &&
|
||||||
|
!not.ipv4('123.123.123.123.123')
|
||||||
|
){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiple
|
||||||
|
console.log('.multiple');
|
||||||
|
{
|
||||||
|
assert(is.Multiple(4, 2), 'is 4, 2');
|
||||||
|
assert(is.Multiple(8080, 80), 'is 8080, 80');
|
||||||
|
assert(not.Multiple(151, 50), 'not 151, 50');
|
||||||
|
assert(is.Multiple(0, 5), '0が全ての数の倍数になっていない');
|
||||||
|
assert(is.Multiple(0, 0), '0が0の倍数になっていない');
|
||||||
|
|
||||||
|
let bool;
|
||||||
|
try{
|
||||||
|
is.Multiple('multiple!');
|
||||||
|
bool = false;
|
||||||
|
}catch(e){
|
||||||
|
bool = true;
|
||||||
|
}
|
||||||
|
assert(bool, 'validation failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log('.nullish');
|
||||||
|
if( !is.nullish(null) ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
if( !is.nullish(undefined) ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
if( !is.nullish(null, undefined) ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
if( !not.nullish(true, "", []) ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
if( not.nullish(null) ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
if( !any.nullish(null, true) ){
|
||||||
|
throw new Error('failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('.sameday');
|
||||||
|
{
|
||||||
|
if( !is.sameday(new Date(), new Date()) ){
|
||||||
|
throw new Error('failed1');
|
||||||
|
}
|
||||||
|
const bool2 = is.sameday(
|
||||||
|
new Date(),
|
||||||
|
new Date('1999')
|
||||||
|
);
|
||||||
|
if( bool2 ){
|
||||||
|
throw new Error('failed2');
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool3 = is.sameday(
|
||||||
|
new Date(),
|
||||||
|
new Date(),
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
|
if( !bool3 ){
|
||||||
|
throw new Error('failed3');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// type
|
||||||
|
|
||||||
|
// array, arr
|
||||||
|
cases.array = (arg)=>{
|
||||||
|
return !is.Array()
|
||||||
|
&& is.array([])
|
||||||
|
&& is.Arr([])
|
||||||
|
&& is.arr([], [])
|
||||||
|
&& !is.arr('array!')
|
||||||
|
&& !is.arr([], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// boolean, bool
|
||||||
|
cases.boolean = (arg)=>{
|
||||||
|
return !is.Boolean()
|
||||||
|
&& is.boolean(true)
|
||||||
|
&& is.Bool(false)
|
||||||
|
&& is.bool(true, false)
|
||||||
|
&& !is.bool('boolean!')
|
||||||
|
&& !is.bool(true, 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
// error, err
|
||||||
|
cases.error = (arg)=>{
|
||||||
|
return !is.Error()
|
||||||
|
&& is.error(new Error())
|
||||||
|
&& is.Err(new Error())
|
||||||
|
&& is.err(new Error(), new Error())
|
||||||
|
&& !is.err('error')
|
||||||
|
&& !is.err(new Error(), 'error');
|
||||||
|
}
|
||||||
|
|
||||||
|
// function, func, fn
|
||||||
|
cases.function = (arg)=>{
|
||||||
|
const f = function(){};
|
||||||
|
return !is.Function()
|
||||||
|
&& is.function(f)
|
||||||
|
&& is.Func(f)
|
||||||
|
&& is.func(f, f)
|
||||||
|
&& is.fn(f)
|
||||||
|
&& !is.func('function!')
|
||||||
|
&& !is.func(f, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// number, num
|
||||||
|
cases.number = (arg)=>{
|
||||||
|
return !is.Number()
|
||||||
|
&& is.number(123)
|
||||||
|
&& is.Num(45)
|
||||||
|
&& is.num(22, 80, 443)
|
||||||
|
&& !is.num('number!')
|
||||||
|
&& !is.num(1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// regexp, re
|
||||||
|
cases.regexp = (arg)=>{
|
||||||
|
const r = /hoge/;
|
||||||
|
return !is.RegExp()
|
||||||
|
&& is.regexp(r)
|
||||||
|
&& is.RE(r)
|
||||||
|
&& is.re(r, r)
|
||||||
|
&& !is.re('rexexp!')
|
||||||
|
&& !is.re(r, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// string, str
|
||||||
|
cases.string = (arg)=>{
|
||||||
|
return !is.String()
|
||||||
|
&& is.string('hoge')
|
||||||
|
&& is.Str('fuga')
|
||||||
|
&& is.str('foo', 'bar')
|
||||||
|
&& !is.str(123)
|
||||||
|
&& !is.str('piyo', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// undefined
|
||||||
|
cases.undefined = (arg)=>{
|
||||||
|
return !is.Undefined()
|
||||||
|
&& is.undefined(undefined)
|
||||||
|
&& is.undefined(undefined, undefined)
|
||||||
|
&& !is.undefined(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// null
|
||||||
|
cases.null = (arg)=>{
|
||||||
|
return !is.Null()
|
||||||
|
&& is.null(null)
|
||||||
|
&& is.null(null, null)
|
||||||
|
&& !is.null(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NaN
|
||||||
|
cases.nan = (arg)=>{
|
||||||
|
return !is.NaN()
|
||||||
|
&& is.nan(NaN)
|
||||||
|
&& is.nan(NaN, NaN)
|
||||||
|
&& !is.nan(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// instance
|
||||||
|
|
||||||
|
|
||||||
|
// buffer
|
||||||
|
cases.buffer = ()=>{
|
||||||
|
const buffer = Buffer.from('hoge');
|
||||||
|
return is.Buffer(buffer)
|
||||||
|
&& is.Buf(buffer)
|
||||||
|
&& is.buffer(buffer)
|
||||||
|
&& is.buf(buffer)
|
||||||
|
&& !is.Buffer('hoge')
|
||||||
|
&& !is.Buffer()
|
||||||
|
&& !is.Buffer(true)
|
||||||
|
&& !is.Buffer({});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// date
|
||||||
|
cases.date = (arg)=>{
|
||||||
|
return !is.Date()
|
||||||
|
&& !is.date({})
|
||||||
|
&& !is.date('date object')
|
||||||
|
&& is.date(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
// event
|
||||||
|
cases.event = (arg)=>{
|
||||||
|
return !is.Event()
|
||||||
|
&& !is.event({})
|
||||||
|
&& !is.event('event')
|
||||||
|
&& is.event( new Event('hoge') );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// jsdomではEventTargetがfunctionではなくobjectなためinstanceofで判定ができないから省略
|
||||||
|
// // eventtarget
|
||||||
|
// cases.eventtarget = (arg)=>{
|
||||||
|
// return !is.eventtarget()
|
||||||
|
// && !is.eventtarget({})
|
||||||
|
// && !is.eventtarget('eventtarget')
|
||||||
|
// && is.eventtarget(window);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// eventtarget
|
||||||
|
|
||||||
|
// object, obj
|
||||||
|
cases.object = (arg)=>{
|
||||||
|
return !is.Object()
|
||||||
|
&& is.object({})
|
||||||
|
&& is.Obj({})
|
||||||
|
&& is.obj( Object.create(null) )
|
||||||
|
&& is.obj({}, {})
|
||||||
|
&& !is.obj('object!')
|
||||||
|
&& !is.obj({}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stats
|
||||||
|
cases.stats = (arg)=>{
|
||||||
|
const stats_dir = fs.statSync('./');
|
||||||
|
const stats_file = fs.statSync(__filename);
|
||||||
|
return !is.stats()
|
||||||
|
&& is.stats(stats_dir)
|
||||||
|
&& is.stats(stats_dir, stats_file)
|
||||||
|
&& !is.stats({}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// promise
|
||||||
|
cases.promise = (arg)=>{
|
||||||
|
const p = new Promise(_=>_);
|
||||||
|
return !is.Promise()
|
||||||
|
&& is.promise(p)
|
||||||
|
&& is.promise(p, p)
|
||||||
|
&& !is.promise('promise!')
|
||||||
|
&& !is.promise(p, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Number
|
||||||
|
*/
|
||||||
|
|
||||||
|
// even
|
||||||
|
cases.even = (arg)=>{
|
||||||
|
return is.Even(0)
|
||||||
|
&& is.even(2)
|
||||||
|
&& is.even(4, 6)
|
||||||
|
&& !is.even(8, 9)
|
||||||
|
&& !is.even('evennumber!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// odd
|
||||||
|
cases.odd = (arg)=>{
|
||||||
|
return is.Odd(1)
|
||||||
|
&& is.odd(3)
|
||||||
|
&& is.odd(5, 7)
|
||||||
|
&& !is.odd(9, 10)
|
||||||
|
&& !is.odd('oddnumber!');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
String系
|
||||||
|
*/
|
||||||
|
cases.lowercase = (arg)=>{
|
||||||
|
return is.Lowercase('hoge')
|
||||||
|
&& is.lowercase('foo', 'bar')
|
||||||
|
&& !is.lowercase('Fuga')
|
||||||
|
&& !is.lowercase(true);
|
||||||
|
}
|
||||||
|
cases.uppercase = (arg)=>{
|
||||||
|
return is.Uppercase('HOGE')
|
||||||
|
&& is.uppercase('FOO', 'BAR')
|
||||||
|
&& !is.uppercase('Fuga')
|
||||||
|
&& !is.uppercase(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// DOM
|
||||||
|
const textnode = document.createTextNode('');
|
||||||
|
const element = document.createElement('div');
|
||||||
|
|
||||||
|
// node
|
||||||
|
cases.node = (arg)=>{
|
||||||
|
return !is.Node()
|
||||||
|
&& is.node(textnode)
|
||||||
|
&& is.node(element)
|
||||||
|
&& is.node(textnode, element)
|
||||||
|
&& !is.node('node!')
|
||||||
|
&& !is.node(textnode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// textnode
|
||||||
|
cases.textnode = (arg)=>{
|
||||||
|
return !is.TextNode()
|
||||||
|
&& is.textnode(textnode)
|
||||||
|
&& is.textnode(textnode, textnode)
|
||||||
|
&& !is.textnode('textnode!')
|
||||||
|
&& !is.textnode(textnode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// element
|
||||||
|
cases.element = (arg)=>{
|
||||||
|
return !is.Element()
|
||||||
|
&& is.Elm(element)
|
||||||
|
&& is.element(element, element)
|
||||||
|
&& !is.elm('element!')
|
||||||
|
&& !is.element(element, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentfragment, df
|
||||||
|
cases.documentfragment = (arg)=>{
|
||||||
|
const df = document.createDocumentFragment();
|
||||||
|
return !is.DocumentFragment()
|
||||||
|
&& is.documentfragment(df)
|
||||||
|
&& is.DF(df)
|
||||||
|
&& is.df(df, df)
|
||||||
|
&& !is.df('documentfragment!')
|
||||||
|
&& !is.df(df, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Other
|
||||||
|
*/
|
||||||
|
|
||||||
|
// true
|
||||||
|
cases.true = (arg)=>{
|
||||||
|
return !is.True()
|
||||||
|
&& is.true(true)
|
||||||
|
&& is.true(true, true)
|
||||||
|
&& !is.true('true!')
|
||||||
|
&& !is.true(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// false
|
||||||
|
cases.false = (arg)=>{
|
||||||
|
return !is.False()
|
||||||
|
&& is.false(false)
|
||||||
|
&& is.false(false, false)
|
||||||
|
&& !is.false('false!')
|
||||||
|
&& !is.false(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// truthy
|
||||||
|
cases.truthy = (arg)=>{
|
||||||
|
return !is.Truthy()
|
||||||
|
&& is.truthy(true)
|
||||||
|
&& is.truthy("hoge", 123, [], {})
|
||||||
|
&& !is.truthy(null, undefined)
|
||||||
|
&& !is.truthy(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// falsy
|
||||||
|
cases.falsy = (arg)=>{
|
||||||
|
return !is.Falsy()
|
||||||
|
&& is.falsy(false)
|
||||||
|
&& is.falsy("", 0, null, undefined, NaN)
|
||||||
|
&& !is.falsy(true, "hoge", 123)
|
||||||
|
&& !is.falsy(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// isInstanceof
|
||||||
|
cases.instanceof = (arg)=>{
|
||||||
|
return !is.instanceof()
|
||||||
|
&& is.instanceof(new Date, Date)
|
||||||
|
&& !is.instanceof({}, Array)
|
||||||
|
&& !is.instanceof(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// objectliteral
|
||||||
|
cases.objectliteral = (arg)=>{
|
||||||
|
return !is.ObjectLiteral()
|
||||||
|
&& is.objectliteral({})
|
||||||
|
&& is.objectliteral({}, new Object({}))
|
||||||
|
&& !is.objectliteral( new function(){} )
|
||||||
|
&& !is.objectliteral({}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
// arraylike
|
||||||
|
cases.arraylike = (arg)=>{
|
||||||
|
return !is.ArrayLike()
|
||||||
|
&& is.arraylike([])
|
||||||
|
&& is.arraylike('hoge', {length: 0})
|
||||||
|
&& !is.arraylike(12345)
|
||||||
|
&& !is.arraylike([], undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// isComparisonOperator
|
||||||
|
cases.comparisonoperator = (arg)=>{
|
||||||
|
return !is.ComparisonOperator()
|
||||||
|
&& is.comparisonoperator('<')
|
||||||
|
&& is.comparisonoperator('!==')
|
||||||
|
&& !is.comparisonoperator('&&')
|
||||||
|
&& !is.comparisonoperator(true, '>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// isSemVer
|
||||||
|
cases.semver = (arg)=>{
|
||||||
|
return !is.SemVer()
|
||||||
|
&& is.semver('1.2.3')
|
||||||
|
&& is.semver('1.0.0-foo.bar', '2.2.2')
|
||||||
|
&& !is.semver('1.2.3.4')
|
||||||
|
&& !is.semver(1.0)
|
||||||
|
&& !is.semver(true, '1.0.0')
|
||||||
|
}
|
||||||
|
|
||||||
|
// isVersion
|
||||||
|
cases.version = (arg)=>{
|
||||||
|
return !is.Version()
|
||||||
|
&& is.Ver('1.2.3')
|
||||||
|
&& is.version('1.0.0.0', '7.7.7.7.7.7.7')
|
||||||
|
&& !is.ver('1.2.3.4.')
|
||||||
|
&& !is.version(1.0)
|
||||||
|
&& !is.version(true, '1.0.0A')
|
||||||
|
}
|
||||||
|
|
||||||
|
// isEmpty
|
||||||
|
cases.empty = (arg)=>{
|
||||||
|
return is.Empty({})
|
||||||
|
&& is.empty([])
|
||||||
|
&& is.empty('')
|
||||||
|
&& !is.empty()
|
||||||
|
&& !is.empty(null)
|
||||||
|
&& !is.empty({a: 1})
|
||||||
|
&& !is.empty([1])
|
||||||
|
&& !is.empty('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
// isLeapYear
|
||||||
|
cases.leapyear = (arg)=>{
|
||||||
|
return is.LeapYear(2020)
|
||||||
|
&& is.leapyear(new Date('2016'))
|
||||||
|
&& !is.leapyear(2019)
|
||||||
|
&& !is.leapyear(new Date('2018'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// isValidDate
|
||||||
|
cases.isvaliddate = (arg)=>{
|
||||||
|
return is.ValidDate(2020, 11, 11)
|
||||||
|
&& is.validdate(2019, 4, 17)
|
||||||
|
&& !is.validdate(1995, 13, 1)
|
||||||
|
&& !is.validdate(2010, 4, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本体
|
||||||
|
for(let [key, method] of Object.entries(cases)){
|
||||||
|
if( method() ){
|
||||||
|
console.log(`${key}: success`);
|
||||||
|
}else{
|
||||||
|
throw new Error(`${key}: failed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
not
|
||||||
|
中身はほぼ一緒だから適当
|
||||||
|
*/
|
||||||
|
const resultArr = [
|
||||||
|
// string
|
||||||
|
not.String(),
|
||||||
|
!not.string('hoge'),
|
||||||
|
!not.Str('fuga'),
|
||||||
|
!not.str('foo', 'bar'),
|
||||||
|
not.str(123),
|
||||||
|
not.str(true, false),
|
||||||
|
not.str('piyo', true),
|
||||||
|
|
||||||
|
// element
|
||||||
|
not.Element(true),
|
||||||
|
!not.element(element),
|
||||||
|
|
||||||
|
// 読み込みチェック
|
||||||
|
(is===_is)
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
resultArr.forEach( (bool, index, arr)=>{
|
||||||
|
if( bool ){
|
||||||
|
console.log(`not: ${index+1}/${arr.length} success`);
|
||||||
|
}else{
|
||||||
|
throw new Error(`not: ${index}/${arr.length} failed`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
any
|
||||||
|
*/
|
||||||
|
const resultArr_any = [
|
||||||
|
any.true(false, true),
|
||||||
|
any.True(false, true),
|
||||||
|
!any.Number('123', true),
|
||||||
|
!any.number('123', true),
|
||||||
|
!any.Num('123', true),
|
||||||
|
!any.num('123', true)
|
||||||
|
];
|
||||||
|
|
||||||
|
resultArr_any.forEach( (bool, index, arr)=>{
|
||||||
|
if( bool ){
|
||||||
|
console.log(`any: ${index+1}/${arr.length} success`);
|
||||||
|
}else{
|
||||||
|
throw new Error(`any: ${index}/${arr.length} failed`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('test: done');
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
<!-- This file is automatically added by @npmcli/template-oss. Do not edit. -->
|
||||||
|
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright npm, Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this
|
||||||
|
software for any purpose with or without fee is hereby
|
||||||
|
granted, provided that the above copyright notice and this
|
||||||
|
permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL
|
||||||
|
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||||
|
EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
|
||||||
|
USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
# @npmcli/fs
|
||||||
|
|
||||||
|
polyfills, and extensions, of the core `fs` module.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- all exposed functions return promises
|
||||||
|
- `fs.rm` polyfill for node versions < 14.14.0
|
||||||
|
- `fs.mkdir` polyfill adding support for the `recursive` and `force` options in node versions < 10.12.0
|
||||||
|
- `fs.copyFile` extended to accept an `owner` option
|
||||||
|
- `fs.mkdir` extended to accept an `owner` option
|
||||||
|
- `fs.mkdtemp` extended to accept an `owner` option
|
||||||
|
- `fs.writeFile` extended to accept an `owner` option
|
||||||
|
- `fs.withTempDir` added
|
||||||
|
- `fs.cp` polyfill for node < 16.7.0
|
||||||
|
|
||||||
|
## The `owner` option
|
||||||
|
|
||||||
|
The `copyFile`, `mkdir`, `mkdtemp`, `writeFile`, and `withTempDir` functions
|
||||||
|
all accept a new `owner` property in their options. It can be used in two ways:
|
||||||
|
|
||||||
|
- `{ owner: { uid: 100, gid: 100 } }` - set the `uid` and `gid` explicitly
|
||||||
|
- `{ owner: 100 }` - use one value, will set both `uid` and `gid` the same
|
||||||
|
|
||||||
|
The special string `'inherit'` may be passed instead of a number, which will
|
||||||
|
cause this module to automatically determine the correct `uid` and/or `gid`
|
||||||
|
from the nearest existing parent directory of the target.
|
||||||
|
|
||||||
|
## `fs.withTempDir(root, fn, options) -> Promise`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
- `root`: the directory in which to create the temporary directory
|
||||||
|
- `fn`: a function that will be called with the path to the temporary directory
|
||||||
|
- `options`
|
||||||
|
- `tmpPrefix`: a prefix to be used in the generated directory name
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
The `withTempDir` function creates a temporary directory, runs the provided
|
||||||
|
function (`fn`), then removes the temporary directory and resolves or rejects
|
||||||
|
based on the result of `fn`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const fs = require('@npmcli/fs')
|
||||||
|
const os = require('os')
|
||||||
|
|
||||||
|
// this function will be called with the full path to the temporary directory
|
||||||
|
// it is called with `await` behind the scenes, so can be async if desired.
|
||||||
|
const myFunction = async (tempPath) => {
|
||||||
|
return 'done!'
|
||||||
|
}
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
const result = await fs.withTempDir(os.tmpdir(), myFunction)
|
||||||
|
// result === 'done!'
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
```
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
const url = require('url')
|
||||||
|
|
||||||
|
const node = require('../node.js')
|
||||||
|
const polyfill = require('./polyfill.js')
|
||||||
|
|
||||||
|
const useNative = node.satisfies('>=10.12.0')
|
||||||
|
|
||||||
|
const fileURLToPath = (path) => {
|
||||||
|
// the polyfill is tested separately from this module, no need to hack
|
||||||
|
// process.version to try to trigger it just for coverage
|
||||||
|
// istanbul ignore next
|
||||||
|
return useNative
|
||||||
|
? url.fileURLToPath(path)
|
||||||
|
: polyfill(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = fileURLToPath
|
||||||
Generated
Vendored
+121
@@ -0,0 +1,121 @@
|
|||||||
|
const { URL, domainToUnicode } = require('url')
|
||||||
|
|
||||||
|
const CHAR_LOWERCASE_A = 97
|
||||||
|
const CHAR_LOWERCASE_Z = 122
|
||||||
|
|
||||||
|
const isWindows = process.platform === 'win32'
|
||||||
|
|
||||||
|
class ERR_INVALID_FILE_URL_HOST extends TypeError {
|
||||||
|
constructor (platform) {
|
||||||
|
super(`File URL host must be "localhost" or empty on ${platform}`)
|
||||||
|
this.code = 'ERR_INVALID_FILE_URL_HOST'
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
return `${this.name} [${this.code}]: ${this.message}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ERR_INVALID_FILE_URL_PATH extends TypeError {
|
||||||
|
constructor (msg) {
|
||||||
|
super(`File URL path ${msg}`)
|
||||||
|
this.code = 'ERR_INVALID_FILE_URL_PATH'
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
return `${this.name} [${this.code}]: ${this.message}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ERR_INVALID_ARG_TYPE extends TypeError {
|
||||||
|
constructor (name, actual) {
|
||||||
|
super(`The "${name}" argument must be one of type string or an instance ` +
|
||||||
|
`of URL. Received type ${typeof actual} ${actual}`)
|
||||||
|
this.code = 'ERR_INVALID_ARG_TYPE'
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
return `${this.name} [${this.code}]: ${this.message}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ERR_INVALID_URL_SCHEME extends TypeError {
|
||||||
|
constructor (expected) {
|
||||||
|
super(`The URL must be of scheme ${expected}`)
|
||||||
|
this.code = 'ERR_INVALID_URL_SCHEME'
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
return `${this.name} [${this.code}]: ${this.message}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isURLInstance = (input) => {
|
||||||
|
return input != null && input.href && input.origin
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPathFromURLWin32 = (url) => {
|
||||||
|
const hostname = url.hostname
|
||||||
|
let pathname = url.pathname
|
||||||
|
for (let n = 0; n < pathname.length; n++) {
|
||||||
|
if (pathname[n] === '%') {
|
||||||
|
const third = pathname.codePointAt(n + 2) | 0x20
|
||||||
|
if ((pathname[n + 1] === '2' && third === 102) ||
|
||||||
|
(pathname[n + 1] === '5' && third === 99)) {
|
||||||
|
throw new ERR_INVALID_FILE_URL_PATH('must not include encoded \\ or / characters')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pathname = pathname.replace(/\//g, '\\')
|
||||||
|
pathname = decodeURIComponent(pathname)
|
||||||
|
if (hostname !== '') {
|
||||||
|
return `\\\\${domainToUnicode(hostname)}${pathname}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const letter = pathname.codePointAt(1) | 0x20
|
||||||
|
const sep = pathname[2]
|
||||||
|
if (letter < CHAR_LOWERCASE_A || letter > CHAR_LOWERCASE_Z ||
|
||||||
|
(sep !== ':')) {
|
||||||
|
throw new ERR_INVALID_FILE_URL_PATH('must be absolute')
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathname.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPathFromURLPosix = (url) => {
|
||||||
|
if (url.hostname !== '') {
|
||||||
|
throw new ERR_INVALID_FILE_URL_HOST(process.platform)
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathname = url.pathname
|
||||||
|
|
||||||
|
for (let n = 0; n < pathname.length; n++) {
|
||||||
|
if (pathname[n] === '%') {
|
||||||
|
const third = pathname.codePointAt(n + 2) | 0x20
|
||||||
|
if (pathname[n + 1] === '2' && third === 102) {
|
||||||
|
throw new ERR_INVALID_FILE_URL_PATH('must not include encoded / characters')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return decodeURIComponent(pathname)
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileURLToPath = (path) => {
|
||||||
|
if (typeof path === 'string') {
|
||||||
|
path = new URL(path)
|
||||||
|
} else if (!isURLInstance(path)) {
|
||||||
|
throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.protocol !== 'file:') {
|
||||||
|
throw new ERR_INVALID_URL_SCHEME('file')
|
||||||
|
}
|
||||||
|
|
||||||
|
return isWindows
|
||||||
|
? getPathFromURLWin32(path)
|
||||||
|
: getPathFromURLPosix(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = fileURLToPath
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// given an input that may or may not be an object, return an object that has
|
||||||
|
// a copy of every defined property listed in 'copy'. if the input is not an
|
||||||
|
// object, assign it to the property named by 'wrap'
|
||||||
|
const getOptions = (input, { copy, wrap }) => {
|
||||||
|
const result = {}
|
||||||
|
|
||||||
|
if (input && typeof input === 'object') {
|
||||||
|
for (const prop of copy) {
|
||||||
|
if (input[prop] !== undefined) {
|
||||||
|
result[prop] = input[prop]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result[wrap] = input
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = getOptions
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
const semver = require('semver')
|
||||||
|
|
||||||
|
const satisfies = (range) => {
|
||||||
|
return semver.satisfies(process.version, range, { includePrerelease: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
satisfies,
|
||||||
|
}
|
||||||
+92
@@ -0,0 +1,92 @@
|
|||||||
|
const { dirname, resolve } = require('path')
|
||||||
|
|
||||||
|
const fileURLToPath = require('./file-url-to-path/index.js')
|
||||||
|
const fs = require('../fs.js')
|
||||||
|
|
||||||
|
// given a path, find the owner of the nearest parent
|
||||||
|
const find = async (path) => {
|
||||||
|
// if we have no getuid, permissions are irrelevant on this platform
|
||||||
|
if (!process.getuid) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fs methods accept URL objects with a scheme of file: so we need to unwrap
|
||||||
|
// those into an actual path string before we can resolve it
|
||||||
|
const resolved = path != null && path.href && path.origin
|
||||||
|
? resolve(fileURLToPath(path))
|
||||||
|
: resolve(path)
|
||||||
|
|
||||||
|
let stat
|
||||||
|
|
||||||
|
try {
|
||||||
|
stat = await fs.lstat(resolved)
|
||||||
|
} finally {
|
||||||
|
// if we got a stat, return its contents
|
||||||
|
if (stat) {
|
||||||
|
return { uid: stat.uid, gid: stat.gid }
|
||||||
|
}
|
||||||
|
|
||||||
|
// try the parent directory
|
||||||
|
if (resolved !== dirname(resolved)) {
|
||||||
|
return find(dirname(resolved))
|
||||||
|
}
|
||||||
|
|
||||||
|
// no more parents, never got a stat, just return an empty object
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// given a path, uid, and gid update the ownership of the path if necessary
|
||||||
|
const update = async (path, uid, gid) => {
|
||||||
|
// nothing to update, just exit
|
||||||
|
if (uid === undefined && gid === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// see if the permissions are already the same, if they are we don't
|
||||||
|
// need to do anything, so return early
|
||||||
|
const stat = await fs.stat(path)
|
||||||
|
if (uid === stat.uid && gid === stat.gid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.chown(path, uid, gid)
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// accepts a `path` and the `owner` property of an options object and normalizes
|
||||||
|
// it into an object with numerical `uid` and `gid`
|
||||||
|
const validate = async (path, input) => {
|
||||||
|
let uid
|
||||||
|
let gid
|
||||||
|
|
||||||
|
if (typeof input === 'string' || typeof input === 'number') {
|
||||||
|
uid = input
|
||||||
|
gid = input
|
||||||
|
} else if (input && typeof input === 'object') {
|
||||||
|
uid = input.uid
|
||||||
|
gid = input.gid
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uid === 'inherit' || gid === 'inherit') {
|
||||||
|
const owner = await find(path)
|
||||||
|
if (uid === 'inherit') {
|
||||||
|
uid = owner.uid
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gid === 'inherit') {
|
||||||
|
gid = owner.gid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { uid, gid }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
find,
|
||||||
|
update,
|
||||||
|
validate,
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
const fs = require('./fs.js')
|
||||||
|
const getOptions = require('./common/get-options.js')
|
||||||
|
const owner = require('./common/owner.js')
|
||||||
|
|
||||||
|
const copyFile = async (src, dest, opts) => {
|
||||||
|
const options = getOptions(opts, {
|
||||||
|
copy: ['mode', 'owner'],
|
||||||
|
wrap: 'mode',
|
||||||
|
})
|
||||||
|
|
||||||
|
const { uid, gid } = await owner.validate(dest, options.owner)
|
||||||
|
|
||||||
|
// the node core method as of 16.5.0 does not support the mode being in an
|
||||||
|
// object, so we have to pass the mode value directly
|
||||||
|
const result = await fs.copyFile(src, dest, options.mode)
|
||||||
|
|
||||||
|
await owner.update(dest, uid, gid)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = copyFile
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2011-2017 JP Richardson
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
|
||||||
|
(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
|
||||||
|
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||||
|
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
const fs = require('../fs.js')
|
||||||
|
const getOptions = require('../common/get-options.js')
|
||||||
|
const node = require('../common/node.js')
|
||||||
|
const polyfill = require('./polyfill.js')
|
||||||
|
|
||||||
|
// node 16.7.0 added fs.cp
|
||||||
|
const useNative = node.satisfies('>=16.7.0')
|
||||||
|
|
||||||
|
const cp = async (src, dest, opts) => {
|
||||||
|
const options = getOptions(opts, {
|
||||||
|
copy: ['dereference', 'errorOnExist', 'filter', 'force', 'preserveTimestamps', 'recursive'],
|
||||||
|
})
|
||||||
|
|
||||||
|
// the polyfill is tested separately from this module, no need to hack
|
||||||
|
// process.version to try to trigger it just for coverage
|
||||||
|
// istanbul ignore next
|
||||||
|
return useNative
|
||||||
|
? fs.cp(src, dest, options)
|
||||||
|
: polyfill(src, dest, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = cp
|
||||||
+428
@@ -0,0 +1,428 @@
|
|||||||
|
// this file is a modified version of the code in node 17.2.0
|
||||||
|
// which is, in turn, a modified version of the fs-extra module on npm
|
||||||
|
// node core changes:
|
||||||
|
// - Use of the assert module has been replaced with core's error system.
|
||||||
|
// - All code related to the glob dependency has been removed.
|
||||||
|
// - Bring your own custom fs module is not currently supported.
|
||||||
|
// - Some basic code cleanup.
|
||||||
|
// changes here:
|
||||||
|
// - remove all callback related code
|
||||||
|
// - drop sync support
|
||||||
|
// - change assertions back to non-internal methods (see options.js)
|
||||||
|
// - throws ENOTDIR when rmdir gets an ENOENT for a path that exists in Windows
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const {
|
||||||
|
ERR_FS_CP_DIR_TO_NON_DIR,
|
||||||
|
ERR_FS_CP_EEXIST,
|
||||||
|
ERR_FS_CP_EINVAL,
|
||||||
|
ERR_FS_CP_FIFO_PIPE,
|
||||||
|
ERR_FS_CP_NON_DIR_TO_DIR,
|
||||||
|
ERR_FS_CP_SOCKET,
|
||||||
|
ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY,
|
||||||
|
ERR_FS_CP_UNKNOWN,
|
||||||
|
ERR_FS_EISDIR,
|
||||||
|
ERR_INVALID_ARG_TYPE,
|
||||||
|
} = require('../errors.js')
|
||||||
|
const {
|
||||||
|
constants: {
|
||||||
|
errno: {
|
||||||
|
EEXIST,
|
||||||
|
EISDIR,
|
||||||
|
EINVAL,
|
||||||
|
ENOTDIR,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} = require('os')
|
||||||
|
const {
|
||||||
|
chmod,
|
||||||
|
copyFile,
|
||||||
|
lstat,
|
||||||
|
mkdir,
|
||||||
|
readdir,
|
||||||
|
readlink,
|
||||||
|
stat,
|
||||||
|
symlink,
|
||||||
|
unlink,
|
||||||
|
utimes,
|
||||||
|
} = require('../fs.js')
|
||||||
|
const {
|
||||||
|
dirname,
|
||||||
|
isAbsolute,
|
||||||
|
join,
|
||||||
|
parse,
|
||||||
|
resolve,
|
||||||
|
sep,
|
||||||
|
toNamespacedPath,
|
||||||
|
} = require('path')
|
||||||
|
const { fileURLToPath } = require('url')
|
||||||
|
|
||||||
|
const defaultOptions = {
|
||||||
|
dereference: false,
|
||||||
|
errorOnExist: false,
|
||||||
|
filter: undefined,
|
||||||
|
force: true,
|
||||||
|
preserveTimestamps: false,
|
||||||
|
recursive: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cp (src, dest, opts) {
|
||||||
|
if (opts != null && typeof opts !== 'object') {
|
||||||
|
throw new ERR_INVALID_ARG_TYPE('options', ['Object'], opts)
|
||||||
|
}
|
||||||
|
return cpFn(
|
||||||
|
toNamespacedPath(getValidatedPath(src)),
|
||||||
|
toNamespacedPath(getValidatedPath(dest)),
|
||||||
|
{ ...defaultOptions, ...opts })
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValidatedPath (fileURLOrPath) {
|
||||||
|
const path = fileURLOrPath != null && fileURLOrPath.href
|
||||||
|
&& fileURLOrPath.origin
|
||||||
|
? fileURLToPath(fileURLOrPath)
|
||||||
|
: fileURLOrPath
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cpFn (src, dest, opts) {
|
||||||
|
// Warn about using preserveTimestamps on 32-bit node
|
||||||
|
// istanbul ignore next
|
||||||
|
if (opts.preserveTimestamps && process.arch === 'ia32') {
|
||||||
|
const warning = 'Using the preserveTimestamps option in 32-bit ' +
|
||||||
|
'node is not recommended'
|
||||||
|
process.emitWarning(warning, 'TimestampPrecisionWarning')
|
||||||
|
}
|
||||||
|
const stats = await checkPaths(src, dest, opts)
|
||||||
|
const { srcStat, destStat } = stats
|
||||||
|
await checkParentPaths(src, srcStat, dest)
|
||||||
|
if (opts.filter) {
|
||||||
|
return handleFilter(checkParentDir, destStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
return checkParentDir(destStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkPaths (src, dest, opts) {
|
||||||
|
const { 0: srcStat, 1: destStat } = await getStats(src, dest, opts)
|
||||||
|
if (destStat) {
|
||||||
|
if (areIdentical(srcStat, destStat)) {
|
||||||
|
throw new ERR_FS_CP_EINVAL({
|
||||||
|
message: 'src and dest cannot be the same',
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (srcStat.isDirectory() && !destStat.isDirectory()) {
|
||||||
|
throw new ERR_FS_CP_DIR_TO_NON_DIR({
|
||||||
|
message: `cannot overwrite directory ${src} ` +
|
||||||
|
`with non-directory ${dest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EISDIR,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (!srcStat.isDirectory() && destStat.isDirectory()) {
|
||||||
|
throw new ERR_FS_CP_NON_DIR_TO_DIR({
|
||||||
|
message: `cannot overwrite non-directory ${src} ` +
|
||||||
|
`with directory ${dest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: ENOTDIR,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
|
||||||
|
throw new ERR_FS_CP_EINVAL({
|
||||||
|
message: `cannot copy ${src} to a subdirectory of self ${dest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return { srcStat, destStat }
|
||||||
|
}
|
||||||
|
|
||||||
|
function areIdentical (srcStat, destStat) {
|
||||||
|
return destStat.ino && destStat.dev && destStat.ino === srcStat.ino &&
|
||||||
|
destStat.dev === srcStat.dev
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStats (src, dest, opts) {
|
||||||
|
const statFunc = opts.dereference ?
|
||||||
|
(file) => stat(file, { bigint: true }) :
|
||||||
|
(file) => lstat(file, { bigint: true })
|
||||||
|
return Promise.all([
|
||||||
|
statFunc(src),
|
||||||
|
statFunc(dest).catch((err) => {
|
||||||
|
// istanbul ignore next: unsure how to cover.
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
// istanbul ignore next: unsure how to cover.
|
||||||
|
throw err
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkParentDir (destStat, src, dest, opts) {
|
||||||
|
const destParent = dirname(dest)
|
||||||
|
const dirExists = await pathExists(destParent)
|
||||||
|
if (dirExists) {
|
||||||
|
return getStatsForCopy(destStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
await mkdir(destParent, { recursive: true })
|
||||||
|
return getStatsForCopy(destStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
function pathExists (dest) {
|
||||||
|
return stat(dest).then(
|
||||||
|
() => true,
|
||||||
|
// istanbul ignore next: not sure when this would occur
|
||||||
|
(err) => (err.code === 'ENOENT' ? false : Promise.reject(err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively check if dest parent is a subdirectory of src.
|
||||||
|
// It works for all file types including symlinks since it
|
||||||
|
// checks the src and dest inodes. It starts from the deepest
|
||||||
|
// parent and stops once it reaches the src parent or the root path.
|
||||||
|
async function checkParentPaths (src, srcStat, dest) {
|
||||||
|
const srcParent = resolve(dirname(src))
|
||||||
|
const destParent = resolve(dirname(dest))
|
||||||
|
if (destParent === srcParent || destParent === parse(destParent).root) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let destStat
|
||||||
|
try {
|
||||||
|
destStat = await stat(destParent, { bigint: true })
|
||||||
|
} catch (err) {
|
||||||
|
// istanbul ignore else: not sure when this would occur
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// istanbul ignore next: not sure when this would occur
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
if (areIdentical(srcStat, destStat)) {
|
||||||
|
throw new ERR_FS_CP_EINVAL({
|
||||||
|
message: `cannot copy ${src} to a subdirectory of self ${dest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return checkParentPaths(src, srcStat, destParent)
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizePathToArray = (path) =>
|
||||||
|
resolve(path).split(sep).filter(Boolean)
|
||||||
|
|
||||||
|
// Return true if dest is a subdir of src, otherwise false.
|
||||||
|
// It only checks the path strings.
|
||||||
|
function isSrcSubdir (src, dest) {
|
||||||
|
const srcArr = normalizePathToArray(src)
|
||||||
|
const destArr = normalizePathToArray(dest)
|
||||||
|
return srcArr.every((cur, i) => destArr[i] === cur)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleFilter (onInclude, destStat, src, dest, opts, cb) {
|
||||||
|
const include = await opts.filter(src, dest)
|
||||||
|
if (include) {
|
||||||
|
return onInclude(destStat, src, dest, opts, cb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startCopy (destStat, src, dest, opts) {
|
||||||
|
if (opts.filter) {
|
||||||
|
return handleFilter(getStatsForCopy, destStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
return getStatsForCopy(destStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getStatsForCopy (destStat, src, dest, opts) {
|
||||||
|
const statFn = opts.dereference ? stat : lstat
|
||||||
|
const srcStat = await statFn(src)
|
||||||
|
// istanbul ignore else: can't portably test FIFO
|
||||||
|
if (srcStat.isDirectory() && opts.recursive) {
|
||||||
|
return onDir(srcStat, destStat, src, dest, opts)
|
||||||
|
} else if (srcStat.isDirectory()) {
|
||||||
|
throw new ERR_FS_EISDIR({
|
||||||
|
message: `${src} is a directory (not copied)`,
|
||||||
|
path: src,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
} else if (srcStat.isFile() ||
|
||||||
|
srcStat.isCharacterDevice() ||
|
||||||
|
srcStat.isBlockDevice()) {
|
||||||
|
return onFile(srcStat, destStat, src, dest, opts)
|
||||||
|
} else if (srcStat.isSymbolicLink()) {
|
||||||
|
return onLink(destStat, src, dest)
|
||||||
|
} else if (srcStat.isSocket()) {
|
||||||
|
throw new ERR_FS_CP_SOCKET({
|
||||||
|
message: `cannot copy a socket file: ${dest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
} else if (srcStat.isFIFO()) {
|
||||||
|
throw new ERR_FS_CP_FIFO_PIPE({
|
||||||
|
message: `cannot copy a FIFO pipe: ${dest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// istanbul ignore next: should be unreachable
|
||||||
|
throw new ERR_FS_CP_UNKNOWN({
|
||||||
|
message: `cannot copy an unknown file type: ${dest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFile (srcStat, destStat, src, dest, opts) {
|
||||||
|
if (!destStat) {
|
||||||
|
return _copyFile(srcStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
return mayCopyFile(srcStat, src, dest, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mayCopyFile (srcStat, src, dest, opts) {
|
||||||
|
if (opts.force) {
|
||||||
|
await unlink(dest)
|
||||||
|
return _copyFile(srcStat, src, dest, opts)
|
||||||
|
} else if (opts.errorOnExist) {
|
||||||
|
throw new ERR_FS_CP_EEXIST({
|
||||||
|
message: `${dest} already exists`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EEXIST,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _copyFile (srcStat, src, dest, opts) {
|
||||||
|
await copyFile(src, dest)
|
||||||
|
if (opts.preserveTimestamps) {
|
||||||
|
return handleTimestampsAndMode(srcStat.mode, src, dest)
|
||||||
|
}
|
||||||
|
return setDestMode(dest, srcStat.mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleTimestampsAndMode (srcMode, src, dest) {
|
||||||
|
// Make sure the file is writable before setting the timestamp
|
||||||
|
// otherwise open fails with EPERM when invoked with 'r+'
|
||||||
|
// (through utimes call)
|
||||||
|
if (fileIsNotWritable(srcMode)) {
|
||||||
|
await makeFileWritable(dest, srcMode)
|
||||||
|
return setDestTimestampsAndMode(srcMode, src, dest)
|
||||||
|
}
|
||||||
|
return setDestTimestampsAndMode(srcMode, src, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileIsNotWritable (srcMode) {
|
||||||
|
return (srcMode & 0o200) === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeFileWritable (dest, srcMode) {
|
||||||
|
return setDestMode(dest, srcMode | 0o200)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setDestTimestampsAndMode (srcMode, src, dest) {
|
||||||
|
await setDestTimestamps(src, dest)
|
||||||
|
return setDestMode(dest, srcMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDestMode (dest, srcMode) {
|
||||||
|
return chmod(dest, srcMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setDestTimestamps (src, dest) {
|
||||||
|
// The initial srcStat.atime cannot be trusted
|
||||||
|
// because it is modified by the read(2) system call
|
||||||
|
// (See https://nodejs.org/api/fs.html#fs_stat_time_values)
|
||||||
|
const updatedSrcStat = await stat(src)
|
||||||
|
return utimes(dest, updatedSrcStat.atime, updatedSrcStat.mtime)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDir (srcStat, destStat, src, dest, opts) {
|
||||||
|
if (!destStat) {
|
||||||
|
return mkDirAndCopy(srcStat.mode, src, dest, opts)
|
||||||
|
}
|
||||||
|
return copyDir(src, dest, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mkDirAndCopy (srcMode, src, dest, opts) {
|
||||||
|
await mkdir(dest)
|
||||||
|
await copyDir(src, dest, opts)
|
||||||
|
return setDestMode(dest, srcMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copyDir (src, dest, opts) {
|
||||||
|
const dir = await readdir(src)
|
||||||
|
for (let i = 0; i < dir.length; i++) {
|
||||||
|
const item = dir[i]
|
||||||
|
const srcItem = join(src, item)
|
||||||
|
const destItem = join(dest, item)
|
||||||
|
const { destStat } = await checkPaths(srcItem, destItem, opts)
|
||||||
|
await startCopy(destStat, srcItem, destItem, opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onLink (destStat, src, dest) {
|
||||||
|
let resolvedSrc = await readlink(src)
|
||||||
|
if (!isAbsolute(resolvedSrc)) {
|
||||||
|
resolvedSrc = resolve(dirname(src), resolvedSrc)
|
||||||
|
}
|
||||||
|
if (!destStat) {
|
||||||
|
return symlink(resolvedSrc, dest)
|
||||||
|
}
|
||||||
|
let resolvedDest
|
||||||
|
try {
|
||||||
|
resolvedDest = await readlink(dest)
|
||||||
|
} catch (err) {
|
||||||
|
// Dest exists and is a regular file or directory,
|
||||||
|
// Windows may throw UNKNOWN error. If dest already exists,
|
||||||
|
// fs throws error anyway, so no need to guard against it here.
|
||||||
|
// istanbul ignore next: can only test on windows
|
||||||
|
if (err.code === 'EINVAL' || err.code === 'UNKNOWN') {
|
||||||
|
return symlink(resolvedSrc, dest)
|
||||||
|
}
|
||||||
|
// istanbul ignore next: should not be possible
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
if (!isAbsolute(resolvedDest)) {
|
||||||
|
resolvedDest = resolve(dirname(dest), resolvedDest)
|
||||||
|
}
|
||||||
|
if (isSrcSubdir(resolvedSrc, resolvedDest)) {
|
||||||
|
throw new ERR_FS_CP_EINVAL({
|
||||||
|
message: `cannot copy ${resolvedSrc} to a subdirectory of self ` +
|
||||||
|
`${resolvedDest}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Do not copy if src is a subdir of dest since unlinking
|
||||||
|
// dest in this case would result in removing src contents
|
||||||
|
// and therefore a broken symlink would be created.
|
||||||
|
const srcStat = await stat(src)
|
||||||
|
if (srcStat.isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) {
|
||||||
|
throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({
|
||||||
|
message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`,
|
||||||
|
path: dest,
|
||||||
|
syscall: 'cp',
|
||||||
|
errno: EINVAL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return copyLink(resolvedSrc, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copyLink (resolvedSrc, dest) {
|
||||||
|
await unlink(dest)
|
||||||
|
return symlink(resolvedSrc, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = cp
|
||||||
+129
@@ -0,0 +1,129 @@
|
|||||||
|
'use strict'
|
||||||
|
const { inspect } = require('util')
|
||||||
|
|
||||||
|
// adapted from node's internal/errors
|
||||||
|
// https://github.com/nodejs/node/blob/c8a04049/lib/internal/errors.js
|
||||||
|
|
||||||
|
// close copy of node's internal SystemError class.
|
||||||
|
class SystemError {
|
||||||
|
constructor (code, prefix, context) {
|
||||||
|
// XXX context.code is undefined in all constructors used in cp/polyfill
|
||||||
|
// that may be a bug copied from node, maybe the constructor should use
|
||||||
|
// `code` not `errno`? nodejs/node#41104
|
||||||
|
let message = `${prefix}: ${context.syscall} returned ` +
|
||||||
|
`${context.code} (${context.message})`
|
||||||
|
|
||||||
|
if (context.path !== undefined) {
|
||||||
|
message += ` ${context.path}`
|
||||||
|
}
|
||||||
|
if (context.dest !== undefined) {
|
||||||
|
message += ` => ${context.dest}`
|
||||||
|
}
|
||||||
|
|
||||||
|
this.code = code
|
||||||
|
Object.defineProperties(this, {
|
||||||
|
name: {
|
||||||
|
value: 'SystemError',
|
||||||
|
enumerable: false,
|
||||||
|
writable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
value: message,
|
||||||
|
enumerable: false,
|
||||||
|
writable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
value: context,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: false,
|
||||||
|
},
|
||||||
|
errno: {
|
||||||
|
get () {
|
||||||
|
return context.errno
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
context.errno = value
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
syscall: {
|
||||||
|
get () {
|
||||||
|
return context.syscall
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
context.syscall = value
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (context.path !== undefined) {
|
||||||
|
Object.defineProperty(this, 'path', {
|
||||||
|
get () {
|
||||||
|
return context.path
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
context.path = value
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.dest !== undefined) {
|
||||||
|
Object.defineProperty(this, 'dest', {
|
||||||
|
get () {
|
||||||
|
return context.dest
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
context.dest = value
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
return `${this.name} [${this.code}]: ${this.message}`
|
||||||
|
}
|
||||||
|
|
||||||
|
[Symbol.for('nodejs.util.inspect.custom')] (_recurseTimes, ctx) {
|
||||||
|
return inspect(this, {
|
||||||
|
...ctx,
|
||||||
|
getters: true,
|
||||||
|
customInspect: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function E (code, message) {
|
||||||
|
module.exports[code] = class NodeError extends SystemError {
|
||||||
|
constructor (ctx) {
|
||||||
|
super(code, message, ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
E('ERR_FS_CP_DIR_TO_NON_DIR', 'Cannot overwrite directory with non-directory')
|
||||||
|
E('ERR_FS_CP_EEXIST', 'Target already exists')
|
||||||
|
E('ERR_FS_CP_EINVAL', 'Invalid src or dest')
|
||||||
|
E('ERR_FS_CP_FIFO_PIPE', 'Cannot copy a FIFO pipe')
|
||||||
|
E('ERR_FS_CP_NON_DIR_TO_DIR', 'Cannot overwrite non-directory with directory')
|
||||||
|
E('ERR_FS_CP_SOCKET', 'Cannot copy a socket file')
|
||||||
|
E('ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY', 'Cannot overwrite symlink in subdirectory of self')
|
||||||
|
E('ERR_FS_CP_UNKNOWN', 'Cannot copy an unknown file type')
|
||||||
|
E('ERR_FS_EISDIR', 'Path is a directory')
|
||||||
|
|
||||||
|
module.exports.ERR_INVALID_ARG_TYPE = class ERR_INVALID_ARG_TYPE extends Error {
|
||||||
|
constructor (name, expected, actual) {
|
||||||
|
super()
|
||||||
|
this.code = 'ERR_INVALID_ARG_TYPE'
|
||||||
|
this.message = `The ${name} argument must be ${expected}. Received ${typeof actual}`
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
const promisify = require('@gar/promisify')
|
||||||
|
|
||||||
|
// this module returns the core fs module wrapped in a proxy that promisifies
|
||||||
|
// method calls within the getter. we keep it in a separate module so that the
|
||||||
|
// overridden methods have a consistent way to get to promisified fs methods
|
||||||
|
// without creating a circular dependency
|
||||||
|
module.exports = promisify(fs)
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
...require('./fs.js'),
|
||||||
|
copyFile: require('./copy-file.js'),
|
||||||
|
cp: require('./cp/index.js'),
|
||||||
|
mkdir: require('./mkdir/index.js'),
|
||||||
|
mkdtemp: require('./mkdtemp.js'),
|
||||||
|
rm: require('./rm/index.js'),
|
||||||
|
withTempDir: require('./with-temp-dir.js'),
|
||||||
|
writeFile: require('./write-file.js'),
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
const fs = require('../fs.js')
|
||||||
|
const getOptions = require('../common/get-options.js')
|
||||||
|
const node = require('../common/node.js')
|
||||||
|
const owner = require('../common/owner.js')
|
||||||
|
|
||||||
|
const polyfill = require('./polyfill.js')
|
||||||
|
|
||||||
|
// node 10.12.0 added the options parameter, which allows recursive and mode
|
||||||
|
// properties to be passed
|
||||||
|
const useNative = node.satisfies('>=10.12.0')
|
||||||
|
|
||||||
|
// extends mkdir with the ability to specify an owner of the new dir
|
||||||
|
const mkdir = async (path, opts) => {
|
||||||
|
const options = getOptions(opts, {
|
||||||
|
copy: ['mode', 'recursive', 'owner'],
|
||||||
|
wrap: 'mode',
|
||||||
|
})
|
||||||
|
const { uid, gid } = await owner.validate(path, options.owner)
|
||||||
|
|
||||||
|
// the polyfill is tested separately from this module, no need to hack
|
||||||
|
// process.version to try to trigger it just for coverage
|
||||||
|
// istanbul ignore next
|
||||||
|
const result = useNative
|
||||||
|
? await fs.mkdir(path, options)
|
||||||
|
: await polyfill(path, options)
|
||||||
|
|
||||||
|
await owner.update(path, uid, gid)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = mkdir
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user