Commit 4d115fc2 by 蒋勇

d

parent 371e2ec6

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/igirl-web/main.js"
}
]
}
\ No newline at end of file
{
"editor.fontSize": 16
}
\ No newline at end of file
../_element-theme@2.0.1@element-theme/bin/element-theme
\ No newline at end of file
../_element-theme@2.0.1@element-theme/bin/element-theme
\ No newline at end of file
../_pinyin@2.9.0@pinyin/bin/pinyin
\ No newline at end of file
../_sequelize-cli@4.1.1@sequelize-cli/lib/sequelize
\ No newline at end of file
../_uuid@3.3.3@uuid/bin/uuid
\ No newline at end of file
Recently updated (since 2019-11-14)
2019-11-17
→ @alicloud/pop-core@1.7.7 › xml2js@0.4.22 › util.promisify@1.0.0 › object.getownpropertydescriptors@2.0.3 › es-abstract@1.16.0 › has-symbols@^1.0.0(1.0.1) (08:01:00)
../_@alicloud_pop-core@1.7.7@@alicloud/pop-core
\ No newline at end of file
../_@nodelib_fs.scandir@2.1.3@@nodelib/fs.scandir
\ No newline at end of file
../_@nodelib_fs.stat@2.0.3@@nodelib/fs.stat
\ No newline at end of file
../_@nodelib_fs.walk@1.2.4@@nodelib/fs.walk
\ No newline at end of file
../_@sindresorhus_is@0.7.0@@sindresorhus/is
\ No newline at end of file
../_@types_color-name@1.1.1@@types/color-name
\ No newline at end of file
../_@types_events@3.0.0@@types/events
\ No newline at end of file
../_@types_geojson@1.0.6@@types/geojson
\ No newline at end of file
../_@types_glob@7.1.1@@types/glob
\ No newline at end of file
../_@types_minimatch@3.0.3@@types/minimatch
\ No newline at end of file
../_@types_node@12.12.11@@types/node
\ No newline at end of file
../_@types_q@1.5.2@@types/q
\ No newline at end of file
_MD5@1.3.0@MD5
\ No newline at end of file
## 1.0.2 (2017-01-16)
Feature:
- 返回出错的结果,挂载到返回error的data对象上,err.data = resData
\ No newline at end of file
# @alicloud/pop-core
The core SDK of POP API.
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![codecov][cov-image]][cov-url]
[npm-image]: https://img.shields.io/npm/v/@alicloud/pop-core.svg?style=flat-square
[npm-url]: https://npmjs.org/package/@alicloud/pop-core
[travis-image]: https://img.shields.io/travis/aliyun/openapi-core-nodejs-sdk/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/aliyun/openapi-core-nodejs-sdk
[cov-image]: https://codecov.io/gh/aliyun/openapi-core-nodejs-sdk/branch/master/graph/badge.svg
[cov-url]: https://codecov.io/gh/aliyun/openapi-core-nodejs-sdk
## Installation
Install it and write into package.json dependences.
```sh
$ npm install @alicloud/pop-core -S
```
## Prerequisite
Node.js >= 8.x
### Notes
You must know your `AK`(`accessKeyId/accessKeySecret`), and the cloud product's `endpoint` and `apiVersion`.
For example, The ECS OpenAPI(https://help.aliyun.com/document_detail/25490.html), the API version is `2014-05-26`.
And the endpoint list can be found at [here](https://help.aliyun.com/document_detail/25489.html), the center endpoint is ecs.aliyuncs.com. Add http protocol `http` or `https`, should be `http://ecs.aliyuncs.com/`.
## Online Demo
**[API Explorer](https://api.aliyun.com)** provides the ability to call the cloud product OpenAPI online, and dynamically generate SDK Example code and quick retrieval interface, which can significantly reduce the difficulty of using the cloud API. **It is highly recommended**.
<a href="https://api.aliyun.com" target="api_explorer">
<img src="https://img.alicdn.com/tfs/TB12GX6zW6qK1RjSZFmXXX0PFXa-744-122.png" width="180" />
</a>
## Usage
The RPC style client:
```js
var RPCClient = require('@alicloud/pop-core').RPCClient;
var client = new RPCClient({
accessKeyId: '<accessKeyId>',
accessKeySecret: '<accessKeySecret>',
endpoint: '<endpoint>',
apiVersion: '<apiVersion>'
});
// => returns Promise
client.request(action, params);
// co/yield, async/await
// options
client.request(action, params, {
timeout: 3000, // default 3000 ms
formatAction: true, // default true, format the action to Action
formatParams: true, // default true, format the parameter name to first letter upper case
method: 'GET', // set the http method, default is GET
headers: {}, // set the http request headers
});
```
The ROA style client:
```js
var ROAClient = require('@alicloud/pop-core').ROAClient;
var client = new ROAClient({
accessKeyId: '<accessKeyId>',
accessKeySecret: '<secretAccessKey>',
endpoint: '<endpoint>',
apiVersion: '<apiVersion>'
});
// => returns Promise
// request(HTTPMethod, uriPath, queries, body, headers, options);
// options => {timeout}
client.request('GET', '/regions');
// co/yield, async/await
```
### Custom opts
We offer two ways to customize request opts.
One way is passing opts through the Client constructor. You should treat opts passed through the constructor as default custom opts, because all requests will use this opts.
```js
var client = new RPCClient({
accessKeyId: '<accessKeyId>',
accessKeySecret: '<accessKeySecret>',
endpoint: '<endpoint>',
apiVersion: '<apiVersion>',
opts: {
timeout: 3000
}
});
```
Another way is passing opts through the function's parameter. You should use this way when you want to just pass opts in specific functions.
```js
client.request(action, params, {
timeout: 3000
});
```
When both ways are used, opts will be merged. But for the opt with the same key, the opts provided by the function parameter overrides the opts provided by the constructor.
### Http Proxy Support
```js
var tunnel = require('tunnel-agent');
var RPCClient = require('@alicloud/pop-core').RPCClient;
var client = new RPCClient({
accessKeyId: '<accessKeyId>',
accessKeySecret: '<accessKeySecret>',
endpoint: '<endpoint>',
apiVersion: '<apiVersion>'
});
client.request(action, params, {
agent: tunnel.httpOverHttp({
proxy: {
host: 'host',
port: port
}
});
});
```
## License
The MIT License
'use strict';
module.exports = require('./lib/rpc');
module.exports.ROAClient = require('./lib/roa');
module.exports.RPCClient = require('./lib/rpc');
'use strict';
const os = require('os');
const pkg = require('../package.json');
exports.DEFAULT_UA = `AlibabaCloud (${os.platform()}; ${os.arch()}) ` +
`Node.js/${process.version} Core/${pkg.version}`;
exports.DEFAULT_CLIENT = `Node.js(${process.version}), ${pkg.name}: ${pkg.version}`;
'use strict';
const assert = require('assert');
const url = require('url');
const querystring = require('querystring');
const kitx = require('kitx');
const httpx = require('httpx');
const xml2js = require('xml2js');
const JSON = require('json-bigint');
const debug = require('debug')('roa');
const helper = require('./helper');
function filter(value) {
return value.replace(/[\t\n\r\f]/g, ' ');
}
function keyLowerify(headers) {
const keys = Object.keys(headers);
const newHeaders = {};
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
newHeaders[key.toLowerCase()] = headers[key];
}
return newHeaders;
}
function getCanonicalizedHeaders(headers) {
const prefix = 'x-acs-';
const keys = Object.keys(headers);
const canonicalizedKeys = [];
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (key.startsWith(prefix)) {
canonicalizedKeys.push(key);
}
}
canonicalizedKeys.sort();
var result = '';
for (let i = 0; i < canonicalizedKeys.length; i++) {
const key = canonicalizedKeys[i];
result += `${key}:${filter(headers[key]).trim()}\n`;
}
return result;
}
function getCanonicalizedResource(uriPattern, query) {
const keys = Object.keys(query).sort();
if (keys.length === 0) {
return uriPattern;
}
var result = [];
for (var i = 0; i < keys.length; i++) {
const key = keys[i];
result.push(`${key}=${query[key]}`);
}
return `${uriPattern}?${result.join('&')}`;
}
function buildStringToSign(method, uriPattern, headers, query) {
const accept = headers['accept'];
const contentMD5 = headers['content-md5'] || '';
const contentType = headers['content-type'] || '';
const date = headers['date'] || '';
const header = `${method}\n${accept}\n${contentMD5}\n${contentType}\n${date}\n`;
const canonicalizedHeaders = getCanonicalizedHeaders(headers);
const canonicalizedResource = getCanonicalizedResource(uriPattern, query);
return `${header}${canonicalizedHeaders}${canonicalizedResource}`;
}
function parseXML(xml) {
const parser = new xml2js.Parser({
// explicitArray: false
});
return new Promise((resolve, reject) => {
parser.parseString(xml, (err, result) => {
if (err) {
return reject(err);
}
resolve(result);
});
});
}
class ACSError extends Error {
constructor(err) {
const message = err.Message[0];
const code = err.Code[0];
const hostid = err.HostId[0];
const requestid = err.RequestId[0];
super(`${message} hostid: ${hostid}, requestid: ${requestid}`);
this.code = code;
}
}
class ROAClient {
constructor(config) {
assert(config, 'must pass "config"');
assert(config.endpoint, 'must pass "config.endpoint"');
if (!config.endpoint.startsWith('https://') &&
!config.endpoint.startsWith('http://')) {
throw new Error(`"config.endpoint" must starts with 'https://' or 'http://'.`);
}
assert(config.apiVersion, 'must pass "config.apiVersion"');
assert(config.accessKeyId, 'must pass "config.accessKeyId"');
assert(config.accessKeySecret, 'must pass "config.accessKeySecret"');
this.endpoint = config.endpoint;
this.apiVersion = config.apiVersion;
this.accessKeyId = config.accessKeyId;
this.accessKeySecret = config.accessKeySecret;
this.securityToken = config.securityToken;
this.host = url.parse(this.endpoint).hostname;
this.opts = config.opts;
var httpModule = this.endpoint.startsWith('https://') ? require('https') : require('http');
this.keepAliveAgent = new httpModule.Agent({
keepAlive: true,
keepAliveMsecs: 3000
});
}
buildHeaders() {
const now = new Date();
var defaultHeaders = {
accept: 'application/json',
date: now.toGMTString(),
host: this.host,
'x-acs-signature-nonce': kitx.makeNonce(),
'x-acs-signature-method': 'HMAC-SHA1',
'x-acs-signature-version': '1.0',
'x-acs-version': this.apiVersion,
'user-agent': helper.DEFAULT_UA,
'x-sdk-client': helper.DEFAULT_CLIENT
};
if (this.securityToken) {
defaultHeaders['x-acs-accesskey-id'] = this.accessKeyId;
defaultHeaders['x-acs-security-token'] = this.securityToken;
}
return defaultHeaders;
}
signature(stringToSign) {
const utf8Buff = Buffer.from(stringToSign, 'utf8');
return kitx.sha1(utf8Buff, this.accessKeySecret, 'base64');
}
buildAuthorization(stringToSign) {
return `acs ${this.accessKeyId}:${this.signature(stringToSign)}`;
}
request(method, uriPattern, query = {}, body = '', headers = {}, opts = {}) {
var postBody = null;
var mixHeaders = Object.assign(this.buildHeaders(), keyLowerify(headers));
if (body) {
postBody = Buffer.from(body, 'utf8');
mixHeaders['content-md5'] = kitx.md5(postBody, 'base64');
mixHeaders['content-length'] = postBody.length;
}
var url = `${this.endpoint}${uriPattern}`;
if (Object.keys(query).length) {
url += `?${querystring.stringify(query)}`;
}
const stringToSign = buildStringToSign(method, uriPattern, mixHeaders, query);
debug('stringToSign: %s', stringToSign);
mixHeaders['authorization'] = this.buildAuthorization(stringToSign);
const options = Object.assign({
method,
agent: this.keepAliveAgent,
headers: mixHeaders,
data: postBody
}, this.opts, opts);
return httpx.request(url, options).then((response) => {
return httpx.read(response, 'utf8').then((body) => {
// Retrun raw body
if (opts.rawBody) {
return body;
}
const contentType = response.headers['content-type'] || '';
// JSON
if (contentType.startsWith('application/json')) {
const statusCode = response.statusCode;
if (statusCode === 204) {
return body;
}
var result;
try {
result = JSON.parse(body);
} catch (err) {
err.name = 'FormatError';
err.message = 'parse response to json error';
err.body = body;
throw err;
}
if (statusCode >= 400) {
const errorMessage = result.Message || result.errorMsg || '';
const errorCode = result.Code || result.errorCode || '';
const requestId = result.RequestId || '';
var err = new Error(`code: ${statusCode}, ${errorMessage}, requestid: ${requestId}`);
err.name = `${errorCode}Error`;
err.statusCode = statusCode;
err.result = result;
err.code = errorCode;
throw err;
}
return result;
}
if (contentType.startsWith('text/xml')) {
return parseXML(body).then((result) => {
if (result.Error) {
throw new ACSError(result.Error);
}
return result;
});
}
return body;
});
});
}
put(path, query, body, headers, options) {
return this.request('PUT', path, query, body, headers, options);
}
post(path, query, body, headers, options) {
return this.request('POST', path, query, body, headers, options);
}
get(path, query, headers, options) {
return this.request('GET', path, query, '', headers, options);
}
delete(path, query, headers, options) {
return this.request('DELETE', path, query, '', headers, options);
}
}
module.exports = ROAClient;
// Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
// Project: [~THE PROJECT NAME~]
// Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>
/*~ This is the module template file for class modules.
*~ You should rename it to index.d.ts and place it in a folder with the same name as the module.
*~ For example, if you were writing a file for "super-greeter", this
*~ file should be 'super-greeter/index.d.ts'
*/
/*~ Note that ES6 modules cannot directly export class objects.
*~ This file should be imported using the CommonJS-style:
*~ import x = require('someLibrary');
*~
*~ Refer to the documentation to understand common
*~ workarounds for this limitation of ES6 modules.
*/
/*~ This declaration specifies that the class constructor function
*~ is the exported object from the file
*/
export = RPCClient;
/*~ Write your module's methods and properties in this class */
declare class RPCClient {
constructor(config: RPCClient.Config);
request<T>(action: String, params: Object, options?: Object): Promise<T>;
}
/*~ If you want to expose types from your module as well, you can
*~ place them in this block.
*/
declare namespace RPCClient {
export interface Config {
endpoint: string;
apiVersion: string;
accessKeyId: string;
accessKeySecret: string;
codes?: (string | number)[];
opts?: object;
}
}
'use strict';
const assert = require('assert');
const httpx = require('httpx');
const kitx = require('kitx');
const JSON = require('json-bigint');
const helper = require('./helper');
function firstLetterUpper(str) {
return str.slice(0, 1).toUpperCase() + str.slice(1);
}
function formatParams(params) {
var keys = Object.keys(params);
var newParams = {};
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
newParams[firstLetterUpper(key)] = params[key];
}
return newParams;
}
function timestamp() {
var date = new Date();
var YYYY = date.getUTCFullYear();
var MM = kitx.pad2(date.getUTCMonth() + 1);
var DD = kitx.pad2(date.getUTCDate());
var HH = kitx.pad2(date.getUTCHours());
var mm = kitx.pad2(date.getUTCMinutes());
var ss = kitx.pad2(date.getUTCSeconds());
// 删除掉毫秒部分
return `${YYYY}-${MM}-${DD}T${HH}:${mm}:${ss}Z`;
}
function encode(str) {
var result = encodeURIComponent(str);
return result.replace(/\!/g, '%21')
.replace(/\'/g, '%27')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\*/g, '%2A');
}
function replaceRepeatList(target, key, repeat) {
for (var i = 0; i < repeat.length; i++) {
var item = repeat[i];
if (item && typeof item === 'object') {
const keys = Object.keys(item);
for (var j = 0; j < keys.length; j++) {
target[`${key}.${i + 1}.${keys[j]}`] = item[keys[j]];
}
} else {
target[`${key}.${i + 1}`] = item;
}
}
}
function flatParams(params) {
var target = {};
var keys = Object.keys(params);
for (let i = 0; i < keys.length; i++) {
var key = keys[i];
var value = params[key];
if (Array.isArray(value)) {
replaceRepeatList(target, key, value);
} else {
target[key] = value;
}
}
return target;
}
function normalize(params) {
var list = [];
var flated = flatParams(params);
var keys = Object.keys(flated).sort();
for (let i = 0; i < keys.length; i++) {
var key = keys[i];
var value = flated[key];
list.push([encode(key), encode(value)]); //push []
}
return list;
}
function canonicalize(normalized) {
var fields = [];
for (var i = 0; i < normalized.length; i++) {
var [key, value] = normalized[i];
fields.push(key + '=' + value);
}
return fields.join('&');
}
class RPCClient {
constructor(config, verbose) {
assert(config, 'must pass "config"');
assert(config.endpoint, 'must pass "config.endpoint"');
if (!config.endpoint.startsWith('https://') &&
!config.endpoint.startsWith('http://')) {
throw new Error(`"config.endpoint" must starts with 'https://' or 'http://'.`);
}
assert(config.apiVersion, 'must pass "config.apiVersion"');
assert(config.accessKeyId, 'must pass "config.accessKeyId"');
var accessKeySecret = config.secretAccessKey || config.accessKeySecret;
assert(accessKeySecret, 'must pass "config.accessKeySecret"');
if (config.endpoint.endsWith('/')) {
config.endpoint = config.endpoint.slice(0, -1);
}
this.endpoint = config.endpoint;
this.apiVersion = config.apiVersion;
this.accessKeyId = config.accessKeyId;
this.accessKeySecret = accessKeySecret;
this.securityToken = config.securityToken;
this.verbose = verbose === true;
// 非 codes 里的值,将抛出异常
this.codes = new Set([200, '200', 'OK', 'Success']);
if (config.codes) {
// 合并 codes
for (var elem of config.codes) {
this.codes.add(elem);
}
}
this.opts = config.opts || {};
var httpModule = this.endpoint.startsWith('https://')
? require('https') : require('http');
this.keepAliveAgent = new httpModule.Agent({
keepAlive: true,
keepAliveMsecs: 3000
});
}
request(action, params = {}, opts = {}) {
// 1. compose params and opts
opts = Object.assign({
headers: {
'x-sdk-client': helper.DEFAULT_CLIENT,
'user-agent': helper.DEFAULT_UA
}
}, this.opts, opts);
// format action until formatAction is false
if (opts.formatAction !== false) {
action = firstLetterUpper(action);
}
// format params until formatParams is false
if (opts.formatParams !== false) {
params = formatParams(params);
}
var defaults = this._buildParams();
params = Object.assign({Action: action}, defaults, params);
// 2. caculate signature
var method = (opts.method || 'GET').toUpperCase();
var normalized = normalize(params);
var canonicalized = canonicalize(normalized);
// 2.1 get string to sign
var stringToSign = `${method}&${encode('/')}&${encode(canonicalized)}`;
// 2.2 get signature
const key = this.accessKeySecret + '&';
var signature = kitx.sha1(stringToSign, key, 'base64');
// add signature
normalized.push(['Signature', encode(signature)]);
// 3. generate final url
const url = opts.method === 'POST' ? `${this.endpoint}/` : `${this.endpoint}/?${canonicalize(normalized)}`;
// 4. send request
var entry = {
url: url,
request: null,
response: null
};
if (opts && !opts.agent) {
opts.agent = this.keepAliveAgent;
}
if (opts.method === 'POST') {
opts.headers = opts.headers || {};
opts.headers['content-type'] = 'application/x-www-form-urlencoded';
opts.data = canonicalize(normalized);
}
return httpx.request(url, opts).then((response) => {
entry.request = {
headers: response.req._headers
};
entry.response = {
statusCode: response.statusCode,
headers: response.headers
};
return httpx.read(response);
}).then((buffer) => {
var json = JSON.parse(buffer);
if (json.Code && !this.codes.has(json.Code)) {
var err = new Error(`${json.Message}, URL: ${url}`);
err.name = json.Code + 'Error';
err.data = json;
err.code = json.Code;
err.url = url;
err.entry = entry;
return Promise.reject(err);
}
if (this.verbose) {
return [json, entry];
}
return json;
});
}
_buildParams() {
var defaultParams = {
Format: 'JSON',
SignatureMethod: 'HMAC-SHA1',
SignatureNonce: kitx.makeNonce(),
SignatureVersion: '1.0',
Timestamp: timestamp(),
AccessKeyId: this.accessKeyId,
Version: this.apiVersion,
};
if (this.securityToken) {
defaultParams.SecurityToken = this.securityToken;
}
return defaultParams;
}
}
module.exports = RPCClient;
../../../_json-bigint@0.2.3@json-bigint
\ No newline at end of file
../../../_xml2js@0.4.22@xml2js
\ No newline at end of file
{
"name": "@alicloud/pop-core",
"version": "1.7.7",
"description": "AliCloud POP SDK core",
"main": "index.js",
"types": "lib/rpc.d.ts",
"scripts": {
"lint": "eslint --fix lib test",
"test": "mocha -R spec test/*.test.js",
"test-cov": "nyc -r=html -r=text -r=lcov mocha -t 3000 -R spec test/*.test.js",
"test-integration": "mocha -R spec test/*.integration.js",
"ci": "npm run lint && npm run test-cov && codecov"
},
"keywords": [
"Aliyun",
"AliCloud",
"OpenAPI",
"POP",
"SDK",
"Core"
],
"author": "Jackson Tian",
"license": "MIT",
"dependencies": {
"debug": "^3.1.0",
"httpx": "^2.1.2",
"json-bigint": "^0.2.3",
"kitx": "^1.2.1",
"xml2js": "^0.4.17"
},
"files": [
"lib",
"index.js"
],
"devDependencies": {
"codecov": "^3.0.4",
"eslint": "^3.13.0",
"expect.js": "^0.3.1",
"mocha": "^4",
"muk": "^0.5.3",
"nyc": "^12.0.2",
"rewire": "^4.0.1"
},
"directories": {
"test": "test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/aliyun/openapi-core-nodejs-sdk.git"
},
"bugs": {
"url": "https://github.com/aliyun/openapi-core-nodejs-sdk/issues"
},
"homepage": "https://github.com/aliyun/openapi-core-nodejs-sdk#readme",
"__npminstall_done": "Thu Nov 21 2019 15:55:29 GMT+0800 (CST)",
"_from": "@alicloud/pop-core@1.7.7",
"_resolved": "https://registry.npm.taobao.org/@alicloud/pop-core/download/@alicloud/pop-core-1.7.7.tgz"
}
\ No newline at end of file
The MIT License (MIT)
Copyright (c) Denis Malinochkin
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.
# @nodelib/fs.scandir
> List files and directories inside the specified directory.
## :bulb: Highlights
The package is aimed at obtaining information about entries in the directory.
* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional).
* :gear: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type. See [`old` and `modern` mode](#old-and-modern-mode).
* :link: Can safely work with broken symbolic links.
## Install
```console
npm install @nodelib/fs.scandir
```
## Usage
```ts
import * as fsScandir from '@nodelib/fs.scandir';
fsScandir.scandir('path', (error, stats) => { /* … */ });
```
## API
### .scandir(path, [optionsOrSettings], callback)
Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path with standard callback-style.
```ts
fsScandir.scandir('path', (error, entries) => { /* … */ });
fsScandir.scandir('path', {}, (error, entries) => { /* … */ });
fsScandir.scandir('path', new fsScandir.Settings(), (error, entries) => { /* … */ });
```
### .scandirSync(path, [optionsOrSettings])
Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path.
```ts
const entries = fsScandir.scandirSync('path');
const entries = fsScandir.scandirSync('path', {});
const entries = fsScandir.scandirSync(('path', new fsScandir.Settings());
```
#### path
* Required: `true`
* Type: `string | Buffer | URL`
A path to a file. If a URL is provided, it must use the `file:` protocol.
#### optionsOrSettings
* Required: `false`
* Type: `Options | Settings`
* Default: An instance of `Settings` class
An [`Options`](#options) object or an instance of [`Settings`](#settingsoptions) class.
> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.
### Settings([options])
A class of full settings of the package.
```ts
const settings = new fsScandir.Settings({ followSymbolicLinks: false });
const entries = fsScandir.scandirSync('path', settings);
```
## Entry
* `name` — The name of the entry (`unknown.txt`).
* `path` — The path of the entry relative to call directory (`root/unknown.txt`).
* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class. On Node.js below 10.10 will be emulated by [`DirentFromStats`](./src/utils/fs.ts) class.
* `stats` (optional) — An instance of `fs.Stats` class.
For example, the `scandir` call for `tools` directory with one directory inside:
```ts
{
dirent: Dirent { name: 'typedoc', /* … */ },
name: 'typedoc',
path: 'tools/typedoc'
}
```
## Options
### stats
* Type: `boolean`
* Default: `false`
Adds an instance of `fs.Stats` class to the [`Entry`](#entry).
> :book: Always use `fs.readdir` without the `withFileTypes` option. ??TODO??
### followSymbolicLinks
* Type: `boolean`
* Default: `false`
Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`.
### `throwErrorOnBrokenSymbolicLink`
* Type: `boolean`
* Default: `true`
Throw an error when symbolic link is broken if `true` or safely use `lstat` call if `false`.
### `pathSegmentSeparator`
* Type: `string`
* Default: `path.sep`
By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead.
### `fs`
* Type: [`FileSystemAdapter`](./src/adapters/fs.ts)
* Default: A default FS methods
By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.
```ts
interface FileSystemAdapter {
lstat?: typeof fs.lstat;
stat?: typeof fs.stat;
lstatSync?: typeof fs.lstatSync;
statSync?: typeof fs.statSync;
readdir?: typeof fs.readdir;
readdirSync?: typeof fs.readdirSync;
}
const settings = new fsScandir.Settings({
fs: { lstat: fakeLstat }
});
```
## `old` and `modern` mode
This package has two modes that are used depending on the environment and parameters of use.
### old
* Node.js below `10.10` or when the `stats` option is enabled
When working in the old mode, the directory is read first (`fs.readdir`), then the type of entries is determined (`fs.lstat` and/or `fs.stat` for symbolic links).
### modern
* Node.js 10.10+ and the `stats` option is disabled
In the modern mode, reading the directory (`fs.readdir` with the `withFileTypes` option) is combined with obtaining information about its entries. An additional call for symbolic links (`fs.stat`) is still present.
This mode makes fewer calls to the file system. It's faster.
## Changelog
See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.
## License
This software is released under the terms of the MIT license.
../../../../_@nodelib_fs.stat@2.0.3@@nodelib/fs.stat
\ No newline at end of file
../../../_run-parallel@1.1.9@run-parallel
\ No newline at end of file
/// <reference types="node" />
import * as fs from 'fs';
export declare type FileSystemAdapter = {
lstat: typeof fs.lstat;
stat: typeof fs.stat;
lstatSync: typeof fs.lstatSync;
statSync: typeof fs.statSync;
readdir: typeof fs.readdir;
readdirSync: typeof fs.readdirSync;
};
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
export declare function createFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;
//# sourceMappingURL=fs.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
exports.FILE_SYSTEM_ADAPTER = {
lstat: fs.lstat,
stat: fs.stat,
lstatSync: fs.lstatSync,
statSync: fs.statSync,
readdir: fs.readdir,
readdirSync: fs.readdirSync
};
function createFileSystemAdapter(fsMethods) {
if (fsMethods === undefined) {
return exports.FILE_SYSTEM_ADAPTER;
}
return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods);
}
exports.createFileSystemAdapter = createFileSystemAdapter;
/**
* IS `true` for Node.js 10.10 and greater.
*/
export declare const IS_SUPPORT_READDIR_WITH_FILE_TYPES: boolean;
//# sourceMappingURL=constants.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.');
const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10);
const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10);
const SUPPORTED_MAJOR_VERSION = 10;
const SUPPORTED_MINOR_VERSION = 10;
const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION;
const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION;
/**
* IS `true` for Node.js 10.10 and greater.
*/
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR;
import { FileSystemAdapter } from './adapters/fs';
import * as async from './providers/async';
import Settings, { Options } from './settings';
import { Dirent, Entry } from './types';
declare type AsyncCallback = async.AsyncCallback;
declare function scandir(path: string, callback: AsyncCallback): void;
declare function scandir(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
declare namespace scandir {
function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise<Entry[]>;
}
declare function scandirSync(path: string, optionsOrSettings?: Options | Settings): Entry[];
export { scandir, scandirSync, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, Options };
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const async = require("./providers/async");
const sync = require("./providers/sync");
const settings_1 = require("./settings");
exports.Settings = settings_1.default;
function scandir(path, optionsOrSettingsOrCallback, callback) {
if (typeof optionsOrSettingsOrCallback === 'function') {
return async.read(path, getSettings(), optionsOrSettingsOrCallback);
}
async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
}
exports.scandir = scandir;
function scandirSync(path, optionsOrSettings) {
const settings = getSettings(optionsOrSettings);
return sync.read(path, settings);
}
exports.scandirSync = scandirSync;
function getSettings(settingsOrOptions = {}) {
if (settingsOrOptions instanceof settings_1.default) {
return settingsOrOptions;
}
return new settings_1.default(settingsOrOptions);
}
/// <reference types="node" />
import Settings from '../settings';
import { Entry } from '../types';
export declare type AsyncCallback = (err: NodeJS.ErrnoException, entries: Entry[]) => void;
export declare function read(directory: string, settings: Settings, callback: AsyncCallback): void;
export declare function readdirWithFileTypes(directory: string, settings: Settings, callback: AsyncCallback): void;
export declare function readdir(directory: string, settings: Settings, callback: AsyncCallback): void;
//# sourceMappingURL=async.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fsStat = require("@nodelib/fs.stat");
const rpl = require("run-parallel");
const constants_1 = require("../constants");
const utils = require("../utils");
function read(directory, settings, callback) {
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
return readdirWithFileTypes(directory, settings, callback);
}
return readdir(directory, settings, callback);
}
exports.read = read;
function readdirWithFileTypes(directory, settings, callback) {
settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => {
if (readdirError !== null) {
return callFailureCallback(callback, readdirError);
}
const entries = dirents.map((dirent) => ({
dirent,
name: dirent.name,
path: `${directory}${settings.pathSegmentSeparator}${dirent.name}`
}));
if (!settings.followSymbolicLinks) {
return callSuccessCallback(callback, entries);
}
const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings));
rpl(tasks, (rplError, rplEntries) => {
if (rplError !== null) {
return callFailureCallback(callback, rplError);
}
callSuccessCallback(callback, rplEntries);
});
});
}
exports.readdirWithFileTypes = readdirWithFileTypes;
function makeRplTaskEntry(entry, settings) {
return (done) => {
if (!entry.dirent.isSymbolicLink()) {
return done(null, entry);
}
settings.fs.stat(entry.path, (statError, stats) => {
if (statError !== null) {
if (settings.throwErrorOnBrokenSymbolicLink) {
return done(statError);
}
return done(null, entry);
}
entry.dirent = utils.fs.createDirentFromStats(entry.name, stats);
return done(null, entry);
});
};
}
function readdir(directory, settings, callback) {
settings.fs.readdir(directory, (readdirError, names) => {
if (readdirError !== null) {
return callFailureCallback(callback, readdirError);
}
const filepaths = names.map((name) => `${directory}${settings.pathSegmentSeparator}${name}`);
const tasks = filepaths.map((filepath) => {
return (done) => fsStat.stat(filepath, settings.fsStatSettings, done);
});
rpl(tasks, (rplError, results) => {
if (rplError !== null) {
return callFailureCallback(callback, rplError);
}
const entries = [];
names.forEach((name, index) => {
const stats = results[index];
const entry = {
name,
path: filepaths[index],
dirent: utils.fs.createDirentFromStats(name, stats)
};
if (settings.stats) {
entry.stats = stats;
}
entries.push(entry);
});
callSuccessCallback(callback, entries);
});
});
}
exports.readdir = readdir;
function callFailureCallback(callback, error) {
callback(error);
}
function callSuccessCallback(callback, result) {
callback(null, result);
}
import Settings from '../settings';
import { Entry } from '../types';
export declare function read(directory: string, settings: Settings): Entry[];
export declare function readdirWithFileTypes(directory: string, settings: Settings): Entry[];
export declare function readdir(directory: string, settings: Settings): Entry[];
//# sourceMappingURL=sync.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fsStat = require("@nodelib/fs.stat");
const constants_1 = require("../constants");
const utils = require("../utils");
function read(directory, settings) {
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
return readdirWithFileTypes(directory, settings);
}
return readdir(directory, settings);
}
exports.read = read;
function readdirWithFileTypes(directory, settings) {
const dirents = settings.fs.readdirSync(directory, { withFileTypes: true });
return dirents.map((dirent) => {
const entry = {
dirent,
name: dirent.name,
path: `${directory}${settings.pathSegmentSeparator}${dirent.name}`
};
if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) {
try {
const stats = settings.fs.statSync(entry.path);
entry.dirent = utils.fs.createDirentFromStats(entry.name, stats);
}
catch (error) {
if (settings.throwErrorOnBrokenSymbolicLink) {
throw error;
}
}
}
return entry;
});
}
exports.readdirWithFileTypes = readdirWithFileTypes;
function readdir(directory, settings) {
const names = settings.fs.readdirSync(directory);
return names.map((name) => {
const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`;
const stats = fsStat.statSync(entryPath, settings.fsStatSettings);
const entry = {
name,
path: entryPath,
dirent: utils.fs.createDirentFromStats(name, stats)
};
if (settings.stats) {
entry.stats = stats;
}
return entry;
});
}
exports.readdir = readdir;
import * as fsStat from '@nodelib/fs.stat';
import * as fs from './adapters/fs';
export declare type Options = {
followSymbolicLinks?: boolean;
fs?: Partial<fs.FileSystemAdapter>;
pathSegmentSeparator?: string;
stats?: boolean;
throwErrorOnBrokenSymbolicLink?: boolean;
};
export default class Settings {
private readonly _options;
readonly followSymbolicLinks: boolean;
readonly fs: fs.FileSystemAdapter;
readonly pathSegmentSeparator: string;
readonly stats: boolean;
readonly throwErrorOnBrokenSymbolicLink: boolean;
readonly fsStatSettings: fsStat.Settings;
constructor(_options?: Options);
private _getValue;
}
//# sourceMappingURL=settings.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fsStat = require("@nodelib/fs.stat");
const fs = require("./adapters/fs");
class Settings {
constructor(_options = {}) {
this._options = _options;
this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false);
this.fs = fs.createFileSystemAdapter(this._options.fs);
this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep);
this.stats = this._getValue(this._options.stats, false);
this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
this.fsStatSettings = new fsStat.Settings({
followSymbolicLink: this.followSymbolicLinks,
fs: this.fs,
throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink
});
}
_getValue(option, value) {
return option === undefined ? value : option;
}
}
exports.default = Settings;
/// <reference types="node" />
import * as fs from 'fs';
export declare type Entry = {
dirent: Dirent;
name: string;
path: string;
stats?: Stats;
};
export declare type Stats = fs.Stats;
export declare type Dirent = {
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isDirectory(): boolean;
isFIFO(): boolean;
isFile(): boolean;
isSocket(): boolean;
isSymbolicLink(): boolean;
name: string;
};
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
import { Dirent, Stats } from '../types';
export declare function createDirentFromStats(name: string, stats: Stats): Dirent;
//# sourceMappingURL=fs.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class DirentFromStats {
constructor(name, stats) {
this.name = name;
this.isBlockDevice = stats.isBlockDevice.bind(stats);
this.isCharacterDevice = stats.isCharacterDevice.bind(stats);
this.isDirectory = stats.isDirectory.bind(stats);
this.isFIFO = stats.isFIFO.bind(stats);
this.isFile = stats.isFile.bind(stats);
this.isSocket = stats.isSocket.bind(stats);
this.isSymbolicLink = stats.isSymbolicLink.bind(stats);
}
}
function createDirentFromStats(name, stats) {
return new DirentFromStats(name, stats);
}
exports.createDirentFromStats = createDirentFromStats;
import * as fs from './fs';
export { fs };
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("./fs");
exports.fs = fs;
{
"name": "@nodelib/fs.scandir",
"version": "2.1.3",
"description": "List files and directories inside the specified directory",
"license": "MIT",
"repository": "https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.scandir",
"keywords": [
"NodeLib",
"fs",
"FileSystem",
"file system",
"scandir",
"readdir",
"dirent"
],
"engines": {
"node": ">= 8"
},
"main": "out/index.js",
"typings": "out/index.d.ts",
"scripts": {
"clean": "rimraf {tsconfig.tsbuildinfo,out}",
"lint": "eslint \"src/**/*.ts\" --cache",
"compile": "tsc -b .",
"compile:watch": "tsc -p . --watch --sourceMap",
"test": "mocha \"out/**/*.spec.js\" -s 0",
"build": "npm run clean && npm run compile && npm run lint && npm test",
"watch": "npm run clean && npm run compile:watch"
},
"dependencies": {
"@nodelib/fs.stat": "2.0.3",
"run-parallel": "^1.1.9"
},
"gitHead": "3b1ef7554ad7c061b3580858101d483fba847abf",
"__npminstall_done": "Thu Nov 21 2019 11:05:37 GMT+0800 (CST)",
"_from": "@nodelib/fs.scandir@2.1.3",
"_resolved": "https://registry.npm.taobao.org/@nodelib/fs.scandir/download/@nodelib/fs.scandir-2.1.3.tgz"
}
\ No newline at end of file
The MIT License (MIT)
Copyright (c) Denis Malinochkin
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.
# @nodelib/fs.stat
> Get the status of a file with some features.
## :bulb: Highlights
Wrapper around standard method `fs.lstat` and `fs.stat` with some features.
* :beginner: Normally follows symbolic link.
* :gear: Can safely work with broken symbolic link.
## Install
```console
npm install @nodelib/fs.stat
```
## Usage
```ts
import * as fsStat from '@nodelib/fs.stat';
fsStat.stat('path', (error, stats) => { /* … */ });
```
## API
### .stat(path, [optionsOrSettings], callback)
Returns an instance of `fs.Stats` class for provided path with standard callback-style.
```ts
fsStat.stat('path', (error, stats) => { /* … */ });
fsStat.stat('path', {}, (error, stats) => { /* … */ });
fsStat.stat('path', new fsStat.Settings(), (error, stats) => { /* … */ });
```
### .statSync(path, [optionsOrSettings])
Returns an instance of `fs.Stats` class for provided path.
```ts
const stats = fsStat.stat('path');
const stats = fsStat.stat('path', {});
const stats = fsStat.stat('path', new fsStat.Settings());
```
#### path
* Required: `true`
* Type: `string | Buffer | URL`
A path to a file. If a URL is provided, it must use the `file:` protocol.
#### optionsOrSettings
* Required: `false`
* Type: `Options | Settings`
* Default: An instance of `Settings` class
An [`Options`](#options) object or an instance of [`Settings`](#settings) class.
> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.
### Settings([options])
A class of full settings of the package.
```ts
const settings = new fsStat.Settings({ followSymbolicLink: false });
const stats = fsStat.stat('path', settings);
```
## Options
### `followSymbolicLink`
* Type: `boolean`
* Default: `true`
Follow symbolic link or not. Call `fs.stat` on symbolic link if `true`.
### `markSymbolicLink`
* Type: `boolean`
* Default: `false`
Mark symbolic link by setting the return value of `isSymbolicLink` function to always `true` (even after `fs.stat`).
> :book: Can be used if you want to know what is hidden behind a symbolic link, but still continue to know that it is a symbolic link.
### `throwErrorOnBrokenSymbolicLink`
* Type: `boolean`
* Default: `true`
Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`.
### `fs`
* Type: [`FileSystemAdapter`](./src/adapters/fs.ts)
* Default: A default FS methods
By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.
```ts
interface FileSystemAdapter {
lstat?: typeof fs.lstat;
stat?: typeof fs.stat;
lstatSync?: typeof fs.lstatSync;
statSync?: typeof fs.statSync;
}
const settings = new fsStat.Settings({
fs: { lstat: fakeLstat }
});
```
## Changelog
See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.
## License
This software is released under the terms of the MIT license.
/// <reference types="node" />
import * as fs from 'fs';
export declare type FileSystemAdapter = {
lstat: typeof fs.lstat;
stat: typeof fs.stat;
lstatSync: typeof fs.lstatSync;
statSync: typeof fs.statSync;
};
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
export declare function createFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;
//# sourceMappingURL=fs.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
exports.FILE_SYSTEM_ADAPTER = {
lstat: fs.lstat,
stat: fs.stat,
lstatSync: fs.lstatSync,
statSync: fs.statSync
};
function createFileSystemAdapter(fsMethods) {
if (fsMethods === undefined) {
return exports.FILE_SYSTEM_ADAPTER;
}
return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods);
}
exports.createFileSystemAdapter = createFileSystemAdapter;
import { FileSystemAdapter } from './adapters/fs';
import * as async from './providers/async';
import Settings, { Options } from './settings';
import { Stats } from './types';
declare type AsyncCallback = async.AsyncCallback;
declare function stat(path: string, callback: AsyncCallback): void;
declare function stat(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
declare namespace stat {
function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise<Stats>;
}
declare function statSync(path: string, optionsOrSettings?: Options | Settings): Stats;
export { Settings, stat, statSync, AsyncCallback, FileSystemAdapter, Options, Stats };
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const async = require("./providers/async");
const sync = require("./providers/sync");
const settings_1 = require("./settings");
exports.Settings = settings_1.default;
function stat(path, optionsOrSettingsOrCallback, callback) {
if (typeof optionsOrSettingsOrCallback === 'function') {
return async.read(path, getSettings(), optionsOrSettingsOrCallback);
}
async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
}
exports.stat = stat;
function statSync(path, optionsOrSettings) {
const settings = getSettings(optionsOrSettings);
return sync.read(path, settings);
}
exports.statSync = statSync;
function getSettings(settingsOrOptions = {}) {
if (settingsOrOptions instanceof settings_1.default) {
return settingsOrOptions;
}
return new settings_1.default(settingsOrOptions);
}
import Settings from '../settings';
import { ErrnoException, Stats } from '../types';
export declare type AsyncCallback = (err: ErrnoException, stats: Stats) => void;
export declare function read(path: string, settings: Settings, callback: AsyncCallback): void;
//# sourceMappingURL=async.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function read(path, settings, callback) {
settings.fs.lstat(path, (lstatError, lstat) => {
if (lstatError !== null) {
return callFailureCallback(callback, lstatError);
}
if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
return callSuccessCallback(callback, lstat);
}
settings.fs.stat(path, (statError, stat) => {
if (statError !== null) {
if (settings.throwErrorOnBrokenSymbolicLink) {
return callFailureCallback(callback, statError);
}
return callSuccessCallback(callback, lstat);
}
if (settings.markSymbolicLink) {
stat.isSymbolicLink = () => true;
}
callSuccessCallback(callback, stat);
});
});
}
exports.read = read;
function callFailureCallback(callback, error) {
callback(error);
}
function callSuccessCallback(callback, result) {
callback(null, result);
}
import Settings from '../settings';
import { Stats } from '../types';
export declare function read(path: string, settings: Settings): Stats;
//# sourceMappingURL=sync.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function read(path, settings) {
const lstat = settings.fs.lstatSync(path);
if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
return lstat;
}
try {
const stat = settings.fs.statSync(path);
if (settings.markSymbolicLink) {
stat.isSymbolicLink = () => true;
}
return stat;
}
catch (error) {
if (!settings.throwErrorOnBrokenSymbolicLink) {
return lstat;
}
throw error;
}
}
exports.read = read;
import * as fs from './adapters/fs';
export declare type Options = {
followSymbolicLink?: boolean;
fs?: Partial<fs.FileSystemAdapter>;
markSymbolicLink?: boolean;
throwErrorOnBrokenSymbolicLink?: boolean;
};
export default class Settings {
private readonly _options;
readonly followSymbolicLink: boolean;
readonly fs: fs.FileSystemAdapter;
readonly markSymbolicLink: boolean;
readonly throwErrorOnBrokenSymbolicLink: boolean;
constructor(_options?: Options);
private _getValue;
}
//# sourceMappingURL=settings.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("./adapters/fs");
class Settings {
constructor(_options = {}) {
this._options = _options;
this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true);
this.fs = fs.createFileSystemAdapter(this._options.fs);
this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false);
this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
}
_getValue(option, value) {
return option === undefined ? value : option;
}
}
exports.default = Settings;
/// <reference types="node" />
import * as fs from 'fs';
export declare type Stats = fs.Stats;
export declare type ErrnoException = NodeJS.ErrnoException;
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
{
"name": "@nodelib/fs.stat",
"version": "2.0.3",
"description": "Get the status of a file with some features",
"license": "MIT",
"repository": "https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.stat",
"keywords": [
"NodeLib",
"fs",
"FileSystem",
"file system",
"stat"
],
"engines": {
"node": ">= 8"
},
"main": "out/index.js",
"typings": "out/index.d.ts",
"scripts": {
"clean": "rimraf {tsconfig.tsbuildinfo,out}",
"lint": "eslint \"src/**/*.ts\" --cache",
"compile": "tsc -b .",
"compile:watch": "tsc -p . --watch --sourceMap",
"test": "mocha \"out/**/*.spec.js\" -s 0",
"build": "npm run clean && npm run compile && npm run lint && npm test",
"watch": "npm run clean && npm run compile:watch"
},
"gitHead": "3b1ef7554ad7c061b3580858101d483fba847abf",
"__npminstall_done": "Thu Nov 21 2019 11:05:36 GMT+0800 (CST)",
"_from": "@nodelib/fs.stat@2.0.3",
"_resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-2.0.3.tgz"
}
\ No newline at end of file
The MIT License (MIT)
Copyright (c) Denis Malinochkin
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.
# @nodelib/fs.walk
> A library for efficiently walking a directory recursively.
## :bulb: Highlights
* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional).
* :rocket: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type for performance reasons. See [`old` and `modern` mode](https://github.com/nodelib/nodelib/blob/master/packages/fs/fs.scandir/README.md#old-and-modern-mode).
* :gear: Built-in directories/files and error filtering system.
* :link: Can safely work with broken symbolic links.
## Install
```console
npm install @nodelib/fs.walk
```
## Usage
```ts
import * as fsWalk from '@nodelib/fs.walk';
fsWalk.walk('path', (error, entries) => { /* … */ });
```
## API
### .walk(path, [optionsOrSettings], callback)
Reads the directory recursively and asynchronously. Requires a callback function.
> :book: If you want to use the Promise API, use `util.promisify`.
```ts
fsWalk.walk('path', (error, entries) => { /* … */ });
fsWalk.walk('path', {}, (error, entries) => { /* … */ });
fsWalk.walk('path', new fsWalk.Settings(), (error, entries) => { /* … */ });
```
### .walkStream(path, [optionsOrSettings])
Reads the directory recursively and asynchronously. [Readable Stream](https://nodejs.org/dist/latest-v12.x/docs/api/stream.html#stream_readable_streams) is used as a provider.
```ts
const stream = fsWalk.walkStream('path');
const stream = fsWalk.walkStream('path', {});
const stream = fsWalk.walkStream('path', new fsWalk.Settings());
```
### .walkSync(path, [optionsOrSettings])
Reads the directory recursively and synchronously. Returns an array of entries.
```ts
const entries = fsWalk.walkSync('path');
const entries = fsWalk.walkSync('path', {});
const entries = fsWalk.walkSync('path', new fsWalk.Settings());
```
#### path
* Required: `true`
* Type: `string | Buffer | URL`
A path to a file. If a URL is provided, it must use the `file:` protocol.
#### optionsOrSettings
* Required: `false`
* Type: `Options | Settings`
* Default: An instance of `Settings` class
An [`Options`](#options) object or an instance of [`Settings`](#settings) class.
> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.
### Settings([options])
A class of full settings of the package.
```ts
const settings = new fsWalk.Settings({ followSymbolicLinks: true });
const entries = fsWalk.walkSync('path', settings);
```
## Entry
* `name` — The name of the entry (`unknown.txt`).
* `path` — The path of the entry relative to call directory (`root/unknown.txt`).
* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class.
* [`stats`] — An instance of `fs.Stats` class.
## Options
### basePath
* Type: `string`
* Default: `undefined`
By default, all paths are built relative to the root path. You can use this option to set custom root path.
In the example below we read the files from the `root` directory, but in the results the root path will be `custom`.
```ts
fsWalk.walkSync('root'); // → ['root/file.txt']
fsWalk.walkSync('root', { basePath: 'custom' }); // → ['custom/file.txt']
```
### concurrency
* Type: `number`
* Default: `Infinity`
The maximum number of concurrent calls to `fs.readdir`.
> :book: The higher the number, the higher performance and the load on the File System. If you want to read in quiet mode, set the value to `4 * os.cpus().length` (4 is default size of [thread pool work scheduling](http://docs.libuv.org/en/v1.x/threadpool.html#thread-pool-work-scheduling)).
### deepFilter
* Type: [`DeepFilterFunction`](./src/settings.ts)
* Default: `undefined`
A function that indicates whether the directory will be read deep or not.
```ts
// Skip all directories that starts with `node_modules`
const filter: DeepFilterFunction = (entry) => !entry.path.startsWith('node_modules');
```
### entryFilter
* Type: [`EntryFilterFunction`](./src/settings.ts)
* Default: `undefined`
A function that indicates whether the entry will be included to results or not.
```ts
// Exclude all `.js` files from results
const filter: EntryFilterFunction = (entry) => !entry.name.endsWith('.js');
```
### errorFilter
* Type: [`ErrorFilterFunction`](./src/settings.ts)
* Default: `undefined`
A function that allows you to skip errors that occur when reading directories.
For example, you can skip `ENOENT` errors if required:
```ts
// Skip all ENOENT errors
const filter: ErrorFilterFunction = (error) => error.code == 'ENOENT';
```
### stats
* Type: `boolean`
* Default: `false`
Adds an instance of `fs.Stats` class to the [`Entry`](#entry).
> :book: Always use `fs.readdir` with additional `fs.lstat/fs.stat` calls to determine the entry type.
### followSymbolicLinks
* Type: `boolean`
* Default: `false`
Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`.
### `throwErrorOnBrokenSymbolicLink`
* Type: `boolean`
* Default: `true`
Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`.
### `pathSegmentSeparator`
* Type: `string`
* Default: `path.sep`
By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead.
### `fs`
* Type: `FileSystemAdapter`
* Default: A default FS methods
By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.
```ts
interface FileSystemAdapter {
lstat: typeof fs.lstat;
stat: typeof fs.stat;
lstatSync: typeof fs.lstatSync;
statSync: typeof fs.statSync;
readdir: typeof fs.readdir;
readdirSync: typeof fs.readdirSync;
}
const settings = new fsWalk.Settings({
fs: { lstat: fakeLstat }
});
```
## Changelog
See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.
## License
This software is released under the terms of the MIT license.
../../../../_@nodelib_fs.scandir@2.1.3@@nodelib/fs.scandir
\ No newline at end of file
../../../_fastq@1.6.0@fastq
\ No newline at end of file
/// <reference types="node" />
import { Readable } from 'stream';
import { Dirent, FileSystemAdapter } from '@nodelib/fs.scandir';
import { AsyncCallback } from './providers/async';
import Settings, { DeepFilterFunction, EntryFilterFunction, ErrorFilterFunction, Options } from './settings';
import { Entry } from './types';
declare function walk(directory: string, callback: AsyncCallback): void;
declare function walk(directory: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
declare namespace walk {
function __promisify__(directory: string, optionsOrSettings?: Options | Settings): Promise<Entry[]>;
}
declare function walkSync(directory: string, optionsOrSettings?: Options | Settings): Entry[];
declare function walkStream(directory: string, optionsOrSettings?: Options | Settings): Readable;
export { walk, walkSync, walkStream, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, Options, DeepFilterFunction, EntryFilterFunction, ErrorFilterFunction };
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const async_1 = require("./providers/async");
const stream_1 = require("./providers/stream");
const sync_1 = require("./providers/sync");
const settings_1 = require("./settings");
exports.Settings = settings_1.default;
function walk(directory, optionsOrSettingsOrCallback, callback) {
if (typeof optionsOrSettingsOrCallback === 'function') {
return new async_1.default(directory, getSettings()).read(optionsOrSettingsOrCallback);
}
new async_1.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback);
}
exports.walk = walk;
function walkSync(directory, optionsOrSettings) {
const settings = getSettings(optionsOrSettings);
const provider = new sync_1.default(directory, settings);
return provider.read();
}
exports.walkSync = walkSync;
function walkStream(directory, optionsOrSettings) {
const settings = getSettings(optionsOrSettings);
const provider = new stream_1.default(directory, settings);
return provider.read();
}
exports.walkStream = walkStream;
function getSettings(settingsOrOptions = {}) {
if (settingsOrOptions instanceof settings_1.default) {
return settingsOrOptions;
}
return new settings_1.default(settingsOrOptions);
}
import AsyncReader from '../readers/async';
import Settings from '../settings';
import { Entry, Errno } from '../types';
export declare type AsyncCallback = (err: Errno, entries: Entry[]) => void;
export default class AsyncProvider {
private readonly _root;
private readonly _settings;
protected readonly _reader: AsyncReader;
private readonly _storage;
constructor(_root: string, _settings: Settings);
read(callback: AsyncCallback): void;
}
//# sourceMappingURL=async.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const async_1 = require("../readers/async");
class AsyncProvider {
constructor(_root, _settings) {
this._root = _root;
this._settings = _settings;
this._reader = new async_1.default(this._root, this._settings);
this._storage = new Set();
}
read(callback) {
this._reader.onError((error) => {
callFailureCallback(callback, error);
});
this._reader.onEntry((entry) => {
this._storage.add(entry);
});
this._reader.onEnd(() => {
callSuccessCallback(callback, [...this._storage]);
});
this._reader.read();
}
}
exports.default = AsyncProvider;
function callFailureCallback(callback, error) {
callback(error);
}
function callSuccessCallback(callback, entries) {
callback(null, entries);
}
import AsyncProvider from './async';
import StreamProvider from './stream';
import SyncProvider from './sync';
export { AsyncProvider, StreamProvider, SyncProvider };
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const async_1 = require("./async");
exports.AsyncProvider = async_1.default;
const stream_1 = require("./stream");
exports.StreamProvider = stream_1.default;
const sync_1 = require("./sync");
exports.SyncProvider = sync_1.default;
/// <reference types="node" />
import { Readable } from 'stream';
import AsyncReader from '../readers/async';
import Settings from '../settings';
export default class StreamProvider {
private readonly _root;
private readonly _settings;
protected readonly _reader: AsyncReader;
protected readonly _stream: Readable;
constructor(_root: string, _settings: Settings);
read(): Readable;
}
//# sourceMappingURL=stream.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = require("stream");
const async_1 = require("../readers/async");
class StreamProvider {
constructor(_root, _settings) {
this._root = _root;
this._settings = _settings;
this._reader = new async_1.default(this._root, this._settings);
this._stream = new stream_1.Readable({
objectMode: true,
read: () => { },
destroy: this._reader.destroy.bind(this._reader)
});
}
read() {
this._reader.onError((error) => {
this._stream.emit('error', error);
});
this._reader.onEntry((entry) => {
this._stream.push(entry);
});
this._reader.onEnd(() => {
this._stream.push(null);
});
this._reader.read();
return this._stream;
}
}
exports.default = StreamProvider;
import SyncReader from '../readers/sync';
import Settings from '../settings';
import { Entry } from '../types';
export default class SyncProvider {
private readonly _root;
private readonly _settings;
protected readonly _reader: SyncReader;
constructor(_root: string, _settings: Settings);
read(): Entry[];
}
//# sourceMappingURL=sync.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sync_1 = require("../readers/sync");
class SyncProvider {
constructor(_root, _settings) {
this._root = _root;
this._settings = _settings;
this._reader = new sync_1.default(this._root, this._settings);
}
read() {
return this._reader.read();
}
}
exports.default = SyncProvider;
/// <reference types="node" />
import { EventEmitter } from 'events';
import * as fsScandir from '@nodelib/fs.scandir';
import Settings from '../settings';
import { Entry, Errno } from '../types';
import Reader from './reader';
declare type EntryEventCallback = (entry: Entry) => void;
declare type ErrorEventCallback = (error: Errno) => void;
declare type EndEventCallback = () => void;
export default class AsyncReader extends Reader {
protected readonly _settings: Settings;
protected readonly _scandir: typeof fsScandir.scandir;
protected readonly _emitter: EventEmitter;
private readonly _queue;
private _isFatalError;
private _isDestroyed;
constructor(_root: string, _settings: Settings);
read(): EventEmitter;
destroy(): void;
onEntry(callback: EntryEventCallback): void;
onError(callback: ErrorEventCallback): void;
onEnd(callback: EndEventCallback): void;
private _pushToQueue;
private _worker;
private _handleError;
private _handleEntry;
private _emitEntry;
}
export {};
//# sourceMappingURL=async.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const fsScandir = require("@nodelib/fs.scandir");
const fastq = require("fastq");
const common = require("./common");
const reader_1 = require("./reader");
class AsyncReader extends reader_1.default {
constructor(_root, _settings) {
super(_root, _settings);
this._settings = _settings;
this._scandir = fsScandir.scandir;
this._emitter = new events_1.EventEmitter();
this._queue = fastq(this._worker.bind(this), this._settings.concurrency);
this._isFatalError = false;
this._isDestroyed = false;
this._queue.drain = () => {
if (!this._isFatalError) {
this._emitter.emit('end');
}
};
}
read() {
this._isFatalError = false;
this._isDestroyed = false;
setImmediate(() => {
this._pushToQueue(this._root, this._settings.basePath);
});
return this._emitter;
}
destroy() {
if (this._isDestroyed) {
throw new Error('The reader is already destroyed');
}
this._isDestroyed = true;
this._queue.killAndDrain();
}
onEntry(callback) {
this._emitter.on('entry', callback);
}
onError(callback) {
this._emitter.once('error', callback);
}
onEnd(callback) {
this._emitter.once('end', callback);
}
_pushToQueue(directory, base) {
const queueItem = { directory, base };
this._queue.push(queueItem, (error) => {
if (error !== null) {
this._handleError(error);
}
});
}
_worker(item, done) {
this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => {
if (error !== null) {
return done(error, undefined);
}
for (const entry of entries) {
this._handleEntry(entry, item.base);
}
done(null, undefined);
});
}
_handleError(error) {
if (!common.isFatalError(this._settings, error)) {
return;
}
this._isFatalError = true;
this._isDestroyed = true;
this._emitter.emit('error', error);
}
_handleEntry(entry, base) {
if (this._isDestroyed || this._isFatalError) {
return;
}
const fullpath = entry.path;
if (base !== undefined) {
entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator);
}
if (common.isAppliedFilter(this._settings.entryFilter, entry)) {
this._emitEntry(entry);
}
if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) {
this._pushToQueue(fullpath, entry.path);
}
}
_emitEntry(entry) {
this._emitter.emit('entry', entry);
}
}
exports.default = AsyncReader;
import Settings, { FilterFunction } from '../settings';
import { Errno } from '../types';
export declare function isFatalError(settings: Settings, error: Errno): boolean;
export declare function isAppliedFilter<T>(filter: FilterFunction<T> | null, value: T): boolean;
export declare function replacePathSegmentSeparator(filepath: string, separator: string): string;
export declare function joinPathSegments(a: string, b: string, separator: string): string;
//# sourceMappingURL=common.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function isFatalError(settings, error) {
if (settings.errorFilter === null) {
return true;
}
return !settings.errorFilter(error);
}
exports.isFatalError = isFatalError;
function isAppliedFilter(filter, value) {
return filter === null || filter(value);
}
exports.isAppliedFilter = isAppliedFilter;
function replacePathSegmentSeparator(filepath, separator) {
return filepath.split(/[\\/]/).join(separator);
}
exports.replacePathSegmentSeparator = replacePathSegmentSeparator;
function joinPathSegments(a, b, separator) {
if (a === '') {
return b;
}
return a + separator + b;
}
exports.joinPathSegments = joinPathSegments;
import Settings from '../settings';
export default class Reader {
protected readonly _root: string;
protected readonly _settings: Settings;
constructor(_root: string, _settings: Settings);
}
//# sourceMappingURL=reader.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const common = require("./common");
class Reader {
constructor(_root, _settings) {
this._root = _root;
this._settings = _settings;
this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator);
}
}
exports.default = Reader;
import * as fsScandir from '@nodelib/fs.scandir';
import { Entry } from '../types';
import Reader from './reader';
export default class SyncReader extends Reader {
protected readonly _scandir: typeof fsScandir.scandirSync;
private readonly _storage;
private readonly _queue;
read(): Entry[];
private _pushToQueue;
private _handleQueue;
private _handleDirectory;
private _handleError;
private _handleEntry;
private _pushToStorage;
}
//# sourceMappingURL=sync.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fsScandir = require("@nodelib/fs.scandir");
const common = require("./common");
const reader_1 = require("./reader");
class SyncReader extends reader_1.default {
constructor() {
super(...arguments);
this._scandir = fsScandir.scandirSync;
this._storage = new Set();
this._queue = new Set();
}
read() {
this._pushToQueue(this._root, this._settings.basePath);
this._handleQueue();
return [...this._storage];
}
_pushToQueue(directory, base) {
this._queue.add({ directory, base });
}
_handleQueue() {
for (const item of this._queue.values()) {
this._handleDirectory(item.directory, item.base);
}
}
_handleDirectory(directory, base) {
try {
const entries = this._scandir(directory, this._settings.fsScandirSettings);
for (const entry of entries) {
this._handleEntry(entry, base);
}
}
catch (error) {
this._handleError(error);
}
}
_handleError(error) {
if (!common.isFatalError(this._settings, error)) {
return;
}
throw error;
}
_handleEntry(entry, base) {
const fullpath = entry.path;
if (base !== undefined) {
entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator);
}
if (common.isAppliedFilter(this._settings.entryFilter, entry)) {
this._pushToStorage(entry);
}
if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) {
this._pushToQueue(fullpath, entry.path);
}
}
_pushToStorage(entry) {
this._storage.add(entry);
}
}
exports.default = SyncReader;
import * as fsScandir from '@nodelib/fs.scandir';
import { Entry, Errno } from './types';
export declare type FilterFunction<T> = (value: T) => boolean;
export declare type DeepFilterFunction = FilterFunction<Entry>;
export declare type EntryFilterFunction = FilterFunction<Entry>;
export declare type ErrorFilterFunction = FilterFunction<Errno>;
export declare type Options = {
basePath?: string;
concurrency?: number;
deepFilter?: DeepFilterFunction;
entryFilter?: EntryFilterFunction;
errorFilter?: ErrorFilterFunction;
followSymbolicLinks?: boolean;
fs?: Partial<fsScandir.FileSystemAdapter>;
pathSegmentSeparator?: string;
stats?: boolean;
throwErrorOnBrokenSymbolicLink?: boolean;
};
export default class Settings {
private readonly _options;
readonly basePath?: string;
readonly concurrency: number;
readonly deepFilter: DeepFilterFunction | null;
readonly entryFilter: EntryFilterFunction | null;
readonly errorFilter: ErrorFilterFunction | null;
readonly pathSegmentSeparator: string;
readonly fsScandirSettings: fsScandir.Settings;
constructor(_options?: Options);
private _getValue;
}
//# sourceMappingURL=settings.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fsScandir = require("@nodelib/fs.scandir");
class Settings {
constructor(_options = {}) {
this._options = _options;
this.basePath = this._getValue(this._options.basePath, undefined);
this.concurrency = this._getValue(this._options.concurrency, Infinity);
this.deepFilter = this._getValue(this._options.deepFilter, null);
this.entryFilter = this._getValue(this._options.entryFilter, null);
this.errorFilter = this._getValue(this._options.errorFilter, null);
this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep);
this.fsScandirSettings = new fsScandir.Settings({
followSymbolicLinks: this._options.followSymbolicLinks,
fs: this._options.fs,
pathSegmentSeparator: this._options.pathSegmentSeparator,
stats: this._options.stats,
throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink
});
}
_getValue(option, value) {
return option === undefined ? value : option;
}
}
exports.default = Settings;
/// <reference types="node" />
import * as scandir from '@nodelib/fs.scandir';
export declare type Entry = scandir.Entry;
export declare type Errno = NodeJS.ErrnoException;
export declare type QueueItem = {
directory: string;
base?: string;
};
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment