diff --git a/README.md b/README.md index 5c5cea7..20897a0 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,6 @@ This is a part of [Node3D](https://github.com/node-3d) project. npm i addon-tools-raub ``` -This module contains helpers for Node.js **NAPI** addons and dependency packages. -On this page, helper scripts are described. For details on **addon-tools.hpp** and some -additional snippets follow the links below. - ## include/addon-tools.hpp @@ -36,42 +32,42 @@ DBG_EXPORT JS_METHOD(doSomething) { NAPI_ENV; ## index.js -Main exports for cross-platform addon configuration. +JavaScript helpers for Node.js addon development. The short list of helpers: +``` + 'getBin', 'getPlatform', 'getInclude', 'getPaths', + 'install', 'cpbin', 'download', 'read', 'write', 'copy', 'exists', + 'mkdir', 'stat', 'isDir', 'isFile', 'dirUp', 'ensuredir', 'copysafe', + 'readdir', 'subdirs', 'subfiles', 'traverse', 'copyall', + 'rmdir', 'rm', 'WritableBuffer', 'actionVersion', 'actionZip', +``` + + See the [TypeScript definitions](/index.d.ts) with comments. -> NOTE: the peer dependency `node-addon-api` is used by this helper. -Example for an ADDON's **index.js**: +### Example for an ADDON's **index.js**: ``` - const { bin } = require('addon-tools-raub'); - const core = require(`./${bin}/ADDON`); // uses the platform-specific ADDON.node + const { getBin } = require('addon-tools-raub'); + const core = require(`./${getBin()}/ADDON`); // uses the platform-specific ADDON.node ``` -Example for **binding.gyp**: + +### Example for **binding.gyp**: ``` 'include_dirs': [ - ' NOTE: the optional `node-addon-api` dependency is used by the `getInclude()` helper. If not found, + the **napi.h** include path won't be a part of the returned string. -## utils.js -JS utils for Node.js modules and addons. +### Example of `cpbin` usage in **package.json :: scripts**: ``` -const utils = require('addon-tools-raub/utils'); + "build-all": "cd src && node-gyp rebuild -j max --silent && node -e \"require('addon-tools-raub').cpbin('segfault')\" && cd ..", + "build-only": "cd src && node-gyp build -j max --silent && node -e \"require('addon-tools-raub').cpbin('segfault')\" && cd ..", ``` - - -Example of `cpbin` usage in **package.json :: scripts**: - -``` - "build-all": "cd src && node-gyp rebuild -j max --silent && node -e \"require('addon-tools-raub/utils').cpbin('segfault')\" && cd ..", - "build-only": "cd src && node-gyp build -j max --silent && node -e \"require('addon-tools-raub/utils').cpbin('segfault')\" && cd ..", -``` - - -See the [TypeScript definitions](/utils.d.ts) with comments. diff --git a/include/index.test.js b/include/index.test.js index d6e3385..c3bff19 100644 --- a/include/index.test.js +++ b/include/index.test.js @@ -3,31 +3,36 @@ const tools = require('.'); -describe('index.js', () => { - describe( - 'Properties', - () => ['bin', 'platform', 'include'].forEach( - (m) => it(`#${m} is a string`, () => { - expect(typeof tools[m]).toBe('string'); - }) - ) - ); +describe('AT / include', () => { + const stringMethods = ['getBin', 'getPlatform', 'getInclude']; - describe('#paths()', () => { + stringMethods.forEach((name) => { + describe(`#${name}()`, () => { + it('is a function', () => { + expect(typeof tools[name]).toBe('function'); + }); + + it('returns an object', () => { + expect(typeof tools[name]()).toBe('string'); + }); + }); + }); + + describe('#getPaths()', () => { it('is a function', () => { - expect(typeof tools.paths).toBe('function'); + expect(typeof tools.getPaths).toBe('function'); }); it('returns an object', () => { - expect(typeof tools.paths(__dirname)).toBe('object'); + expect(typeof tools.getPaths(__dirname)).toBe('object'); }); it('has "include" string', () => { - expect(typeof tools.paths(__dirname).include).toBe('string'); + expect(typeof tools.getPaths(__dirname).include).toBe('string'); }); it('has "bin" string', () => { - expect(typeof tools.paths(__dirname).include).toBe('string'); + expect(typeof tools.getPaths(__dirname).include).toBe('string'); }); }); }); diff --git a/include/snippets.md b/include/snippets.md index 326a0d0..7090f33 100644 --- a/include/snippets.md +++ b/include/snippets.md @@ -2,38 +2,11 @@ ## C++ Addon building -**NAPI** addons are built separately from the installation, so we shouldn't -put the file **binding.gyp** to the module root anymore. It is better to have a -separate folder with a separate **package.json**, **binding.gyp** and the sources. - -A snippet for **src/package.json**: - -``` -{ - "name": "build", - "version": "0.0.0", - "private": true, - "scripts": { - "build-all": "cd src && node-gyp rebuild -j max --silent && node -e \"require('addon-tools-raub/utils').cpbin('ADDON')\" && cd ..", - "build-only": "cd src && node-gyp build -j max --silent && node -e \"require('addon-tools-raub/utils').cpbin('ADDON')\" && cd ..", - }, - "dependencies": { - "addon-tools-raub": "6.2.0", - "DEPS": "1.0.0" - } -} -``` - -* `ADDON` - the name of this addon (and subsequently of its binary). -* `DEPS` - dependency package(s). - - - ### Binary distribution In **package.json** use the `"postinstall"` script to download the libraries. For example the following structure might work. Note that **Addon Tools** will -append any given URL with `/${platform}.zip` +append any given URL with `/${getPlatform()}.zip` In **package.json**: @@ -42,44 +15,35 @@ In **package.json**: "postinstall": "node install", }, "dependencies": { - "addon-tools-raub": "^6.2.0", + "addon-tools-raub": "^7.0.0", }, "devDependencies": { "node-addon-api": "^5.0.0" } ``` -Create the **install.js** file: - -``` -'use strict'; -const { install } = require('addon-tools-raub/utils'); -const prefix = 'https://github.com/node-3d/glfw-raub/releases/download'; -const tag = '4.8.0'; -install(`${prefix}/${tag}`); -``` - -**Addon Tools** will unzip (using **adm-zip**) the downloaded file into the platform binary +Create the **install.js** file, see `install` in [index.d.ts](/index.d.ts). +**Addon Tools** will unzip (using **tar**) the downloaded file into the platform binary directory. E.g. on Windows it will be **bin-windows**. * For a dependency package: - Place the following piece of code in the `index.js` without changes. Method `paths()` - is described [here](../README.md). + Place the following piece of code into the `index.js` without changes. + ``` - module.exports = require('addon-tools-raub').paths(__dirname); + module.exports = require('addon-tools-raub').getPaths(__dirname); ``` * For a compiled addon: - Require it in your **index.js** from the platform-specific directory. + Require the `ADDON.node` in your **index.js** from the platform-specific directory. ``` - const { bin } = require('addon-tools-raub'); - const core = require(`./${bin}/ADDON`); + const { getBin } = require('addon-tools-raub'); + const core = require(`./${getBin()}/ADDON`); ``` -Publishing binaries is done by attaching a zipped platform folder to the GitHub +Publishing binaries is done by attaching a zipped platform folder to a GitHub release. Zip file must NOT contain platform folder as a subfolder, but rather contain the final binaries. The tag of the release should be the same as in **install.js**. @@ -114,75 +78,4 @@ from **Addon Tools** is that it should be a zipped set of files/folders. ], ``` -The former contains both the path to include **Addon Tools** and the one for -**Napi** (which is preinstalled with Addon Tools). The latter can be any other -dependency include path(s). - - -
- -See a snipped for src/binding.gyp here - -* Assume `DEPS` is the name of an Addon Tools compliant dependency module. -* Assume `ADDON` is the name of this addon's resulting binary. -* Assume C++ code goes to `cpp` subdirectory. - -``` -{ - 'variables': { - 'bin' : ' +See example of a working [**binding.gyp** here](/test-addon/binding.gyp) diff --git a/index.d.ts b/index.d.ts index 546376b..4704c81 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,17 +1,17 @@ declare module "addon-tools-raub" { /** - * Addon paths - * Returns a set of platform dependent paths depending on input dir + * Get the internal paths for an addon + * Returns a set of platform dependent paths depending on the input dir */ - export const paths: (dir: string) => Readonly<{ + export const getPaths: (dir: string) => Readonly<{ /** - * Path to binaries - * Platform binary directory absolute path for this `dir` + * Path to binaries + * Platform binary directory absolute path for this `dir` */ bin: string; /** - * Path to include - * Include directory for this `dir` + * Path to include + * Include directory for this `dir` */ include: string; }>; @@ -20,16 +20,231 @@ declare module "addon-tools-raub" { type TPlatformDir = `bin-${TPlatformName}`; /** - * Platform-dependent binary directory name + * Get the platform-specific binary directory name */ - export const bin: TPlatformDir; - - export const platform: TPlatformName; + export const getBin: () => TPlatformDir; /** - * Main include directories - * Both 'addon-tools-raub' and 'node-addon-api' include paths. - * For binding.gyp: `' TPlatformName; + + /** + * Get the include directories for **binding.gyp** + * Both 'addon-tools-raub' and 'node-addon-api' include paths. + * In binding.gyp: `' string; + + /** + * Install binaries + * Downloads and unzips the platform specific binary for the calling package. + * To use it, create a new script for your package, which may as well be named + * **install.js**, with the following content: + * + * ``` + * 'use strict'; + * const { install } = require('addon-tools-raub'); + * const prefix = 'https://github.com/USER/ADDON-NAME/releases/download'; + * const tag = '1.0.0'; + * install(`${prefix}/${tag}`); + * ``` + * + * * `prefix` - the constant base part of the download url. + * * `tag` - the version-dependent part of the url. + * + * ``` + * "scripts": { + * "postinstall": "node install" + * }, + * ``` + */ + export const install: (folder: string) => void; + + + /** + * Copy binary + * Copies the addon binary from `src/build/Release` to the platform-specific folder. + * + * ``` + * "scripts": { + * * "build": "node-gyp rebuild && node -e \"require('addon-tools-raub').cpbin('ADDON')\"" + * }, + * ``` + * + * Here ADDON should be replaced with the name of your addon, without `.node` extension. + */ + export const cpbin: (name: string) => Promise; + + + /** + * Package version for GitHub Actions + * Example of `actionVersion` usage in **Github Actions**: + * + * ``` + * - name: Get Package Version + * id: package-version + * run: node -e \"require('addon-tools-raub').actionVersion()\" >> $GITHUB_OUTPUT + * - name: Create Release + * uses: softprops/action-gh-release@v1 + * with: + * tag_name: ${{ steps.package-version.outputs.version }} + * ``` + */ + export const actionVersion: () => void; + + + /** + * Package version for GitHub Actions + * Example of `actionZip` usage in **Github Actions**: + * + * ``` + * - name: Zip Files + * id: zip-files + * run: node action-zip >> $GITHUB_OUTPUT + * - name: Store Binaries + * uses: softprops/action-gh-release@v1 + * with: + * files: ${{ steps.zip-files.outputs.zip }} + * ``` + */ + export const actionZip: () => void; + + + /** + * Download to memory + * Accepts an **URL**, and returns an in-memory file Buffer, + * when the file is loaded. Use for small files, as the whole + * file will be loaded into memory at once. + * + * ``` + * download(srcUrl).then(data => useData(data), err => emit('error', err)); + * ``` + * or + * ``` + * const data = await download(srcUrl); + * useData(data); + * ``` + */ + export const download: (url: string) => Promise; + + /** + * (async) Read a file + * Reads a whole file to string, NOT A Buffer + */ + + + /** + * WritableBuffer + * A [Writable](https://nodejs.org/api/stream.html#stream_writable_streams) + * stream buffer, that is stored in-memory and can be fully + * obtained when writing was finished. It is equivalent to stream-writing + * a temporary file and then reading it into a `Buffer`. + */ + export class WritableBuffer extends Writable { + constructor(); + /** + * Get the downloaded data + * Use `stream.get()` to obtain the data when writing was finished + */ + get(): Buffer; + } + + + export const read: (name: string) => Promise; + + /** + * (async) Write a file + */ + export const write: (name: string, text: string) => Promise; + + /** + * (async) Copy a file + */ + export const copy: (src: string, dest: string) => Promise; + + /** + * (async) Check if a file/folder exists + */ + export const exists: (name: string) => Promise; + + /** + * (async) Create an empty folder + */ + export const mkdir: (name: string) => Promise; + + /** + * (async) Get status on a file + */ + export const stat: (name: string) => Promise; + + /** + * (async) Check if the path is a folder + */ + export const isDir: (name: string) => Promise; + + /** + * (async) Check if the path is a file + */ + export const isFile: (name: string) => Promise; + + /** + * Cut the path one folder up + */ + export const dirUp: (dir: string) => string; + + /** + * (async) Create a directory + * Like `mkdir -p`, makes sure a directory exists + */ + export const ensuredir: (dir: string) => Promise; + + /** + * (async) Copy a file + * Copy a file, `dest` folder is created if needed + */ + export const copysafe: (src: string, dest: string) => Promise; + + /** + * (async) Read a directory + * Get file/folder names of the 1st level + */ + export const readdir: (src: string, dest: string) => Promise>; + + /** + * (async) List subdirectories + * Get folder paths (concatenated with input) of the 1st level + */ + export const subdirs: (name: string) => Promise>; + + /** + * (async) List nested files + * Get file paths (concatenated with input) of the 1st level + */ + export const subfiles: (name: string) => Promise>; + + /** + * (async) Get all nested files recursively + * Folder paths are omitted by default. + * Order is: shallow-to-deep, each subdirectory lists dirs-then-files. + */ + export const traverse: (name: string, showDirs?: boolean) => Promise>; + + /** + * (async) Copy a directory + * Copy a folder with all the contained files + */ + export const copyall: (src: string, dest: string) => Promise; + + /** + * (async) Remove a directory + * Like `rm -rf`, removes everything recursively + */ + export const rmdir: (name: string) => Promise; + + /** + * (async) Remove a file + * Must be a file, not a folder. Just `fs.unlink`. + */ + export const rm: (name: string) => Promise; } diff --git a/index.js b/index.js index 400038f..65f6a68 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ 'use strict'; module.exports = { - ...require('./include/index'), + ...require('./include'), + ...require('./utils'), }; diff --git a/test-addon/hpp-arg-array-str.test.js b/test-addon/hpp-arg-array-str.test.js index e98f8f3..49c9f82 100644 --- a/test-addon/hpp-arg-array-str.test.js +++ b/test-addon/hpp-arg-array-str.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const arrayArgMsg = 'Argument 0 must be of type `Array`'; -describe('addon-tools.hpp: LET_ARRAY_ARG', () => { +describe('AT / addon-tools.hpp / LET_ARRAY_ARG', () => { it('exports letArrayStrArg', () => { expect(typeof test.letArrayStrArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-array.test.js b/test-addon/hpp-arg-array.test.js index c8d843e..e854d56 100644 --- a/test-addon/hpp-arg-array.test.js +++ b/test-addon/hpp-arg-array.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const arrayArgMsg = 'Argument 0 must be of type `Array`'; -describe('addon-tools.hpp: REQ_ARRAY_ARG', () => { +describe('AT / addon-tools.hpp / REQ_ARRAY_ARG', () => { it('exports reqArrayArg', () => { expect(typeof test.reqArrayArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-bool.test.js b/test-addon/hpp-arg-bool.test.js index 30338cd..4a24f82 100644 --- a/test-addon/hpp-arg-bool.test.js +++ b/test-addon/hpp-arg-bool.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const boolArgMsg = 'Argument 0 must be of type `Bool`'; -describe('addon-tools.hpp: REQ_BOOL_ARG', () => { +describe('AT / addon-tools.hpp / REQ_BOOL_ARG', () => { it('exports reqBoolArg', () => { expect(typeof test.reqBoolArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-double.test.js b/test-addon/hpp-arg-double.test.js index d017bf6..f7870d8 100644 --- a/test-addon/hpp-arg-double.test.js +++ b/test-addon/hpp-arg-double.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const numArgMsg = 'Argument 0 must be of type `Number`'; -describe('addon-tools.hpp: REQ_DOUBLE_ARG', () => { +describe('AT / addon-tools.hpp / REQ_DOUBLE_ARG', () => { it('exports reqDoubleArg', () => { expect(typeof test.reqDoubleArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-ext.test.js b/test-addon/hpp-arg-ext.test.js index 4eaca45..be7d2f2 100644 --- a/test-addon/hpp-arg-ext.test.js +++ b/test-addon/hpp-arg-ext.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const extArgMsg = 'Argument 0 must be of type `Pointer`'; -describe('addon-tools.hpp: REQ_EXT_ARG', () => { +describe('AT / addon-tools.hpp / REQ_EXT_ARG', () => { it('exports reqExtArg', () => { expect(typeof test.reqExtArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-float.test.js b/test-addon/hpp-arg-float.test.js index d34c1ba..6c51a0b 100644 --- a/test-addon/hpp-arg-float.test.js +++ b/test-addon/hpp-arg-float.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const numArgMsg = 'Argument 0 must be of type `Number`'; -describe('addon-tools.hpp: REQ_FLOAT_ARG', () => { +describe('AT / addon-tools.hpp / REQ_FLOAT_ARG', () => { it('exports reqFloatArg', () => { expect(typeof test.reqFloatArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-int.test.js b/test-addon/hpp-arg-int.test.js index c0d94f7..7716985 100644 --- a/test-addon/hpp-arg-int.test.js +++ b/test-addon/hpp-arg-int.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const intArgMsg = 'Argument 0 must be of type `Int32`'; -describe('addon-tools.hpp: REQ_INT_ARG / REQ_INT32_ARG', () => { +describe('AT / addon-tools.hpp / REQ_INT_ARG, REQ_INT32_ARG', () => { it('exports reqIntArg', () => { expect(typeof test.reqIntArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-obj.test.js b/test-addon/hpp-arg-obj.test.js index 4b78d3d..a014c34 100644 --- a/test-addon/hpp-arg-obj.test.js +++ b/test-addon/hpp-arg-obj.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const objArgMsg = 'Argument 0 must be of type `Object`'; -describe('addon-tools.hpp: REQ_OBJ_ARG', () => { +describe('AT / addon-tools.hpp / REQ_OBJ_ARG', () => { it('exports reqObjArg', () => { expect(typeof test.reqObjArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-offs.test.js b/test-addon/hpp-arg-offs.test.js index 27097bd..6f9b83f 100644 --- a/test-addon/hpp-arg-offs.test.js +++ b/test-addon/hpp-arg-offs.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const numArgMsg = 'Argument 0 must be of type `Number`'; -describe('addon-tools.hpp: REQ_OFFS_ARG', () => { +describe('AT / addon-tools.hpp / REQ_OFFS_ARG', () => { it('exports reqOffsArg', () => { expect(typeof test.reqOffsArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-str.test.js b/test-addon/hpp-arg-str.test.js index 6f0fbfd..cce489c 100644 --- a/test-addon/hpp-arg-str.test.js +++ b/test-addon/hpp-arg-str.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const strArgMsg = 'Argument 0 must be of type `String`'; -describe('addon-tools.hpp: REQ_STR_ARG', () => { +describe('AT / addon-tools.hpp / REQ_STR_ARG', () => { it('exports reqStrArg', () => { expect(typeof test.reqStrArg).toBe('function'); }); diff --git a/test-addon/hpp-arg-uint.test.js b/test-addon/hpp-arg-uint.test.js index 5601e2e..d7366e5 100644 --- a/test-addon/hpp-arg-uint.test.js +++ b/test-addon/hpp-arg-uint.test.js @@ -5,7 +5,7 @@ const test = require('./build/Release/test.node'); const uintArgMsg = 'Argument 0 must be of type `Uint32`'; -describe('addon-tools.hpp: REQ_UINT_ARG / REQ_UINT32_ARG', () => { +describe('AT / addon-tools.hpp / REQ_UINT_ARG, REQ_UINT32_ARG', () => { it('exports reqUintArg', () => { expect(typeof test.reqUintArg).toBe('function'); }); diff --git a/test-addon/hpp-arg.test.js b/test-addon/hpp-arg.test.js index 110e8fb..4b6bae2 100644 --- a/test-addon/hpp-arg.test.js +++ b/test-addon/hpp-arg.test.js @@ -3,8 +3,7 @@ const test = require('./build/Release/test.node'); -describe('addon-tools.hpp: Function arguments', () => { - +describe('AT / addon-tools.hpp / Function arguments', () => { describe('REQ_ARGS', () => { it('exports reqArgs3', () => { expect(typeof test.reqArgs3).toBe('function'); @@ -203,5 +202,4 @@ describe('addon-tools.hpp: Function arguments', () => { expect(test.reqTypedArg(typed)).toEqual(typed); }); }); - }); diff --git a/utils.d.ts b/utils.d.ts deleted file mode 100644 index fe95a76..0000000 --- a/utils.d.ts +++ /dev/null @@ -1,215 +0,0 @@ -import type { Writable } from 'stream'; - -declare module "addon-tools-raub/utils" { - /** - * Install binaries - * Downloads and unzips the platform specific binary for the calling package. - * To use it, create a new script for your package, which may as well be named - * **install.js**, with the following content: - * ``` - * 'use strict'; - * const install = require('addon-tools-raub/install'); - * const prefix = 'https://github.com/USER/ADDON-NAME/releases/download'; - * const tag = 'v1.0.0'; - * install(`${prefix}/${tag}`); - * ``` - * * `prefix` - the constant base part of the download url. - * * `tag` - the version-dependent part of the url. - * ``` - * "scripts": { - * "postinstall": "node install" - * }, - * ``` - */ - export const install: (folder: string) => void; - - - /** - * Copy binary - * Copies the addon binary from `src/build/Release` to the platform folder. - * ``` - * declare const cpbin: (name: string) => Promise; - * export default cpbin; - * ``` - * It is useful for development builds. Use it in your **src/package.json**: - * ``` - * "scripts": { - * * "build": "node-gyp rebuild && node -e \"require('addon-tools-raub/cpbin')('ADDON')\"" - * }, - * ``` - * Here ADDON should be replaced with the name of your addon, without `.node` extension. - */ - export const cpbin: (name: string) => Promise; - - - /** - * Package version for GitHub Actions - * Example of `actionVersion` usage in **Github Actions**: - * - * ``` - * - name: Get Package Version - * id: package-version - * run: node -e \"require('addon-tools-raub/utils').actionVersion()\" >> $GITHUB_OUTPUT - * - name: Create Release - * uses: softprops/action-gh-release@v1 - * with: - * tag_name: ${{ steps.package-version.outputs.version }} - * ``` - */ - export const actionVersion: () => void; - - - /** - * Package version for GitHub Actions - * Example of `actionZip` usage in **Github Actions**: - * - * ``` - * - name: Zip Files - * id: zip-files - * run: node action-zip >> $GITHUB_OUTPUT - * - name: Store Binaries - * uses: softprops/action-gh-release@v1 - * with: - * files: ${{ steps.zip-files.outputs.zip }} - * ``` - */ - export const actionZip: () => void; - - - /** - * Download to memory - * Accepts an **URL**, and returns an in-memory file Buffer, - * when the file is loaded. Use for small files, as the whole - * file will be loaded into memory at once. - * - * ``` - * download(srcUrl).then(data => useData(data), err => emit('error', err)); - * ``` - * or - * ``` - * const data = await download(srcUrl); - * useData(data); - * ``` - */ - export const download: (url: string) => Promise; - - /** - * (async) Read a file - * Reads a whole file to string, NOT A Buffer - */ - - - /** - * WritableBuffer - * A [Writable](https://nodejs.org/api/stream.html#stream_writable_streams) - * stream buffer, that is stored in-memory and can be fully - * obtained when writing was finished. It is equivalent to stream-writing - * a temporary file and then reading it into a `Buffer`. - */ - export class WritableBuffer extends Writable { - constructor(); - /** - * Get the downloaded data - * Use `stream.get()` to obtain the data when writing was finished - */ - get(): Buffer; - } - - - export const read: (name: string) => Promise; - - /** - * (async) Write a file - */ - export const write: (name: string, text: string) => Promise; - - /** - * (async) Copy a file - */ - export const copy: (src: string, dest: string) => Promise; - - /** - * (async) Check if a file/folder exists - */ - export const exists: (name: string) => Promise; - - /** - * (async) Create an empty folder - */ - export const mkdir: (name: string) => Promise; - - /** - * (async) Get status on a file - */ - export const stat: (name: string) => Promise; - - /** - * (async) Check if the path is a folder - */ - export const isDir: (name: string) => Promise; - - /** - * (async) Check if the path is a file - */ - export const isFile: (name: string) => Promise; - - /** - * Cut the path one folder up - */ - export const dirUp: (dir: string) => string; - - /** - * (async) Create a directory - * Like `mkdir -p`, makes sure a directory exists - */ - export const ensuredir: (dir: string) => Promise; - - /** - * (async) Copy a file - * Copy a file, `dest` folder is created if needed - */ - export const copysafe: (src: string, dest: string) => Promise; - - /** - * (async) Read a directory - * Get file/folder names of the 1st level - */ - export const readdir: (src: string, dest: string) => Promise>; - - /** - * (async) List subdirectories - * Get folder paths (concatenated with input) of the 1st level - */ - export const subdirs: (name: string) => Promise>; - - /** - * (async) List nested files - * Get file paths (concatenated with input) of the 1st level - */ - export const subfiles: (name: string) => Promise>; - - /** - * (async) Get all nested files recursively - * Folder paths are omitted by default. - * Order is: shallow-to-deep, each subdirectory lists dirs-then-files. - */ - export const traverse: (name: string, showDirs?: boolean) => Promise>; - - /** - * (async) Copy a directory - * Copy a folder with all the contained files - */ - export const copyall: (src: string, dest: string) => Promise; - - /** - * (async) Remove a directory - * Like `rm -rf`, removes everything recursively - */ - export const rmdir: (name: string) => Promise; - - /** - * (async) Remove a file - * Must be a file, not a folder. Just `fs.unlink`. - */ - export const rm: (name: string) => Promise; -} diff --git a/utils.js b/utils.js deleted file mode 100644 index 6e44069..0000000 --- a/utils.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = { - ...require('./utils/index'), -}; diff --git a/utils/utils.test.js b/utils/utils.test.js index f72b727..2289a71 100644 --- a/utils/utils.test.js +++ b/utils/utils.test.js @@ -7,7 +7,7 @@ const utils = require('.'); const packageJson = require('../package.json'); -describe('utils.js', () => { +describe('AT / utils', () => { const methods = [ 'install', 'cpbin', 'download', 'read', 'write', 'copy', 'exists', 'mkdir', 'stat', 'isDir', 'isFile', 'dirUp', 'ensuredir', 'copysafe',