pax_global_header 0000666 0000000 0000000 00000000064 13533654047 0014524 g ustar 00root root 0000000 0000000 52 comment=9f48d0e87242f05ae9db716c239c4b52866a2e3f
add-filename-increment-1.0.0/ 0000775 0000000 0000000 00000000000 13533654047 0016012 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/.editorconfig 0000664 0000000 0000000 00000000327 13533654047 0020471 0 ustar 00root root 0000000 0000000 # http://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
add-filename-increment-1.0.0/.eslintrc.json 0000664 0000000 0000000 00000007325 13533654047 0020615 0 ustar 00root root 0000000 0000000 {
"extends": [
"eslint:recommended"
],
"env": {
"browser": false,
"es6": true,
"node": true,
"mocha": true
},
"parserOptions":{
"ecmaVersion": 9,
"sourceType": "module",
"ecmaFeatures": {
"modules": true,
"experimentalObjectRestSpread": true
}
},
"globals": {
"document": false,
"navigator": false,
"window": false
},
"rules": {
"accessor-pairs": 2,
"arrow-spacing": [2, { "before": true, "after": true }],
"block-spacing": [2, "always"],
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
"comma-dangle": [2, "never"],
"comma-spacing": [2, { "before": false, "after": true }],
"comma-style": [2, "last"],
"constructor-super": 2,
"curly": [2, "multi-line"],
"dot-location": [2, "property"],
"eol-last": 2,
"eqeqeq": [2, "allow-null"],
"generator-star-spacing": [2, { "before": true, "after": true }],
"handle-callback-err": [2, "^(err|error)$" ],
"indent": [2, 2, { "SwitchCase": 1 }],
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
"keyword-spacing": [2, { "before": true, "after": true }],
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
"new-parens": 2,
"no-array-constructor": 2,
"no-caller": 2,
"no-class-assign": 2,
"no-cond-assign": 2,
"no-const-assign": 2,
"no-control-regex": 2,
"no-debugger": 2,
"no-delete-var": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-empty-character-class": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": [2, "functions"],
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-implied-eval": 2,
"no-inner-declarations": [2, "functions"],
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-mixed-spaces-and-tabs": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-multiple-empty-lines": [2, { "max": 1 }],
"no-native-reassign": 0,
"no-negated-in-lhs": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-require": 2,
"no-new-wrappers": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 2,
"no-proto": 0,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-return-assign": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-sparse-arrays": 2,
"no-this-before-super": 2,
"no-throw-literal": 2,
"no-trailing-spaces": 0,
"no-undef": 2,
"no-undef-init": 2,
"no-unexpected-multiline": 2,
"no-unneeded-ternary": [2, { "defaultAssignment": false }],
"no-unreachable": 2,
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
"no-useless-call": 0,
"no-with": 2,
"one-var": [0, { "initialized": "never" }],
"operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }],
"padded-blocks": [0, "never"],
"quotes": [2, "single", "avoid-escape"],
"radix": 2,
"semi": [2, "always"],
"semi-spacing": [2, { "before": false, "after": true }],
"space-before-blocks": [2, "always"],
"space-before-function-paren": [2, "never"],
"space-in-parens": [2, "never"],
"space-infix-ops": 2,
"space-unary-ops": [2, { "words": true, "nonwords": false }],
"spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
"use-isnan": 2,
"valid-typeof": 2,
"wrap-iife": [2, "any"],
"yoda": [2, "never"]
}
}
add-filename-increment-1.0.0/.gitattributes 0000664 0000000 0000000 00000000046 13533654047 0020705 0 ustar 00root root 0000000 0000000 # Enforce Unix newlines
* text eol=lf
add-filename-increment-1.0.0/.github/ 0000775 0000000 0000000 00000000000 13533654047 0017352 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/.github/contributing.md 0000664 0000000 0000000 00000015776 13533654047 0022423 0 ustar 00root root 0000000 0000000 # Contributing to increment-filename
First and foremost, thank you! We appreciate that you want to contribute to `increment-filename`, your time is valuable, and your contributions mean a lot to us!
Please keep in mind that increment-filename is Free and Open-Source Software, build by people like you who spend their free time creating and maintaing tools for the rest of the community to use.
## Important!
By contributing to this project, you agree that:
1. _You have authored 100% of the content_
1. _You have the necessary rights to the content_
1. _You have received the necessary permissions from your employer to make the contributions (if applicable)_
1. _The content you contribute may be provided under the Project license(s)_
## Why you should contribute
Please consider contributing to this project if any of the following is true:
- You have (or want to gain) expertise in community development, communication, or education
- You want open source communities to be more collaborative and inclusive
- You want to help lower the burden to first time contributors
- You know how to improve the quality of this project or its documentation
## Getting started
**What does "contributing" mean?**
Creating an issue is the simplest form of contributing to a project. But there are many ways to contribute, including the following:
- Adding, updating or correcting documentation
- Significantly improving code performance, quality or readability
- Making feature requests on the [issue tracker](../../issues)
- Submiting a [bug report](../../issues)
- Star the project on Github
- Tweet a simple "thank you" to the project's author (`twitter.com/@jonschlinkert`)
**Showing support for increment-filename**
Don't have time to contribute? No worries! There are other ways to show your :heart: and support (and motivate the current maintainers to keep up the great work!):
- star the [project](https://github.com/jonschlinkert/increment-filename)
- follow the [project's author on GitHub](https://github.com/jonschlinkert)
- follow the [project's author on twitter](https://twitter.com/jonschlinkert)
- connect with the [project's author on LinkedIn](https://twitter.com/jonschlinkert)
- tweet your support! `thanks for creating https://github.com/jonschlinkert/increment-filename @jonschlinkert! #nodejs #github #javascript`
If you'd like to learn more about contributing in general, please see the [Guide to Idiomatic Contributing](https://github.com/jonschlinkert/idiomatic-contributing).
## Issues
### Before creating an issue
**TLDR;**
- Make sure you're using the latest version of `increment-filename`
- Make sure the issue is in this library, and not a dependency
- Search google, [GitHub]() and [stackoverflow.com]() for solutions
- Search existing issues, open and closed, for a solution before creating a new issue
- Use [stackoverflow.com][so] if you need implementation help or have general questions
**Make sure you are using the latest version**
It's common for users to create issues before checking the version they're using, only to find that their problem has been solved in a recently published version.
**Create the issue in the appropriate repository**
Please try to determine if the issue is caused by an underlying library, and if so, create the issue there. Sometimes this is difficult to know. We only ask that you give a reasonable attempt to find out first.
**Investigate the issue**
Check to see if any existing issues (open or closed) have been created about the same thing, or something similar.
If you find an open issue about the same or similar problem, and you can shed light on the problem, please add a comment to the existing issue (pull requests are also encouraged and very much appreciated).
**Avoid creating issues for implementation help**
Help us keep the issue tracker focused on bugs and feature requests by asking implementation-related questions on [stackoverflow.com][so]. StackOverflow was created for this purpose, and both you and the person that answers your question will get reputation points for answering the question.
**Avoid creating issues to bump dependency versions**
This is a time-wasting
- **Check the readme** - oftentimes you will find notes about creating issues, and where to go depending on the type of issue.
Please check the readme to see if there is additional advice about creating issues.
### Creating an issue
Please be as descriptive as possible when creating an issue. Give us the information we need to successfully answer your question or address your issue by answering the following in your issue:
- **operating system**: what OS are you using?
- **version**: what version of `increment-filename` are you using?
- **node version**: what version of `node.js` are you using?
- **extensions (plugins, helpers, middleware etc)**: if applicable, please list any extensions you're using.
- **error messages**: please paste any error messages, with as much detail as possible, into the issue itself or a [gist](https://gist.github.com/) if you prefer.
### Closing issues
The original poster or the maintainer's of `increment-filename` may close an issue at any time. Typically, but not exclusively, issues are closed when:
- The issue is resolved
- The project's maintainers have determined the issue is out of scope
- An issue is clearly a duplicate of another issue, in which case the duplicate issue will be linked.
- A discussion has clearly run its course
## Next steps
**Tips for creating idiomatic issues**
Spending just a little extra time to review best practices and brush up on your contributing skills will, at minimum, make your issue easier to read, easier to resolve, and more likely to be found by others who have the same or similar issue in the future. At best, it will open up doors and potential career opportunities by helping you be at your best.
The following resources were hand-picked to help you be the most effective contributor you can be:
- The [Guide to Idiomatic Contributing](https://github.com/jonschlinkert/idiomatic-contributing) is a great place for newcomers to start, but there is also information for experienced contributors there.
- Take some time to learn basic markdown. We can't stress this enough. Don't start pasting code into GitHub issues before you've taken a moment to review this [markdown cheatsheet](https://gist.github.com/jonschlinkert/5854601)
- The GitHub guide to [basic markdown](https://help.github.com/articles/markdown-basics/) is another great markdown resource.
- Learn about [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/). And if you want to really go above and beyond, read [mastering markdown](https://guides.github.com/features/mastering-markdown/).
At the very least, please try to:
- Use backticks to wrap code. This ensures that it retains its formatting and isn't modified when it's rendered by GitHub, and makes the code more readable to others
- When applicable, use syntax highlighting by adding the correct language name after the first "code fence"
[so]: http://stackoverflow.com/questions/tagged/increment-filename
add-filename-increment-1.0.0/.gitignore 0000664 0000000 0000000 00000000446 13533654047 0020006 0 ustar 00root root 0000000 0000000 # always ignore files
*.DS_Store
.idea
*.sublime-*
# test related, or directories generated by tests
test/actual
actual
coverage
.nyc*
# npm
node_modules
npm-debug.log
# yarn
yarn.lock
yarn-error.log
# misc
_gh_pages
_draft
_drafts
bower_components
vendor
temp
tmp
TODO.md
package-lock.json add-filename-increment-1.0.0/.npmrc 0000664 0000000 0000000 00000000023 13533654047 0017125 0 ustar 00root root 0000000 0000000 package-lock=false
add-filename-increment-1.0.0/.travis.yml 0000664 0000000 0000000 00000000164 13533654047 0020124 0 ustar 00root root 0000000 0000000 sudo: false
os:
- linux
- osx
- windows
language: node_js
node_js:
- node
- '11'
- '10'
- '9'
- '8'
add-filename-increment-1.0.0/.verb.md 0000664 0000000 0000000 00000011025 13533654047 0017347 0 ustar 00root root 0000000 0000000 ## What does this do?
When copying files, it's common for operating systems to append a numerical increment or the word 'copy' to a file name to prevent the existing file from being overwritten.
This library allows you to do the same thing in your Node.js application, using the correct conventions for the most commonly used [operating systems](#operating-systems).
## Usage
All methods automatically detect the platform to use, unless `platform` is defined on the [options](#options).
```js
const increment = require('{%= name %}');
```
## API
{%= apidocs("index.js") %}
## Options
### options.fs
**Description**: Check the file system, and automatically increment the file based on existing files. Thus, if the file name is `foo.txt`, and `foo (2).txt` already exists, the file will automatically be renamed to `foo (3).txt`.
Also uses the correct conventions for Linux, Windows (win32), and MacOS (darwin).
**Type**: `boolean`
**Default**: `undefined`
### options.increment
**Description**: Custom function to handling incrementing a file name. This is mostly useful when `options.fs` is also defined, since this function will only be called if a file name needs to be incremented, allowing you to control how incrementing is done.
**Type**: `function`
**Default**: `undefined`
### options.platform
**Description**: Specify the platform conventions to use.
**Type**: `string`
**Default**: Uses `process.platform`. Valid values are `linux`, `win32`, and `darwin`.
## Operating Systems
- [Linux](#linux)
- [MacOS](#macos)
- [Windows](#windows)
**Supported Operating Systems**
Currently Windows, Darwin (MacOS), and Linux are supported. This library attempts to automatically use the correct conventions for each operating system. Please [create an issue](../../issues/new) if you ecounter a bug.
If you use an operating system with different conventions, and you would like for this library to add support, please [create an issue](../../issues/new) with a detailed description of those conventions, or feel free to do a [pull request](.github/contributing.md).
### Linux
When a file is copied or moved, and the destination file path already exists, Linux uses the following conventions for incrementing the file name.
| **Source path** | **Destination path** | **Type** | **Directory1** |
| --- | --- | --- | --- |
| `foo.txt` | `foo (copy).txt`, `foo (another copy).txt`, `foo (3rd copy).txt`, ... | file | Same directory as source |
| `foo` | `foo (copy)`, `foo (another copy)`, `foo (3rd copy)`, ... | directory | Same directory as source |
1 _On Linux, when a file or folder is copied or moved to a different directory and another file or folder with the same name exists in that directory, you are prompted to choose a new name for the file or folder, or to cancel or skip the operation._
### MacOS
When a file is copied or moved, and the destination file path already exists, MacOS uses the following conventions for incrementing the file name.
| **Source path** | **Destination path** | **Type** | **Directory1** |
| --- | --- | --- | --- |
| `foo.txt` | `foo copy.txt`, `foo copy 2.txt`, ... | file | Same directory as source |
| `foo.txt` | `foo 2.txt`, `foo 3.txt`, ... | file | Different directory than source |
| `foo` | `foo copy`, `foo copy 2`, ... | directory | Same directory as source |
1 _MacOS uses different conventions for incrementing file names when the source file is copied, moved or renamed to a different directory, versus when the file is copied into the same directory._
### Windows
When a file is copied or moved, and the destination file path already exists, Windows uses the following conventions for incrementing the file name.
| **Source path** | **Destination path** | **Type** | **Directory1** |
| --- | --- | --- | --- |
| `foo.txt` | `foo - Copy.txt` | file | Same directory as source |
| `foo.txt` | `foo (2).txt` | file | Different directory than source |
| `foo (2).txt` | `foo (3).txt` | file | Different directory than source |
| `foo` | `foo - Copy` | directory | Same directory as source |
| `foo - Copy` | `foo - Copy (2)` | directory | Same directory as source |
1 _Windows uses different conventions for incrementing file names when the source file is copied, moved or renamed to a different directory, versus when the file is copied into the same directory. Also, when a folder is copied to a new directory, and the new directory already has a folder with the same name, Windows just merges the folders automatically._
add-filename-increment-1.0.0/LICENSE 0000664 0000000 0000000 00000002103 13533654047 0017013 0 ustar 00root root 0000000 0000000 The MIT License (MIT)
Copyright (c) 2017-present, Jon Schlinkert.
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.
add-filename-increment-1.0.0/README.md 0000664 0000000 0000000 00000026447 13533654047 0017306 0 ustar 00root root 0000000 0000000 # add-filename-increment [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [](https://www.npmjs.com/package/add-filename-increment) [](https://npmjs.org/package/add-filename-increment) [](https://npmjs.org/package/add-filename-increment) [](https://travis-ci.org/jonschlinkert/add-filename-increment)
> When copying or moving files, it's common for operating systems to automatically add an increment or 'copy' to duplicate file names. This does that for Node.js applications, with automatic platform detection and support for Linux, MacOs, and Windows conventions.
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
## Install
Install with [npm](https://www.npmjs.com/) (requires [Node.js](https://nodejs.org/en/) >=8):
```sh
$ npm install --save add-filename-increment
```
## What does this do?
When copying files, it's common for operating systems to append a numerical increment or the word 'copy' to a file name to prevent the existing file from being overwritten.
This library allows you to do the same thing in your Node.js application, using the correct conventions for the most commonly used [operating systems](#operating-systems).
## Usage
All methods automatically detect the platform to use, unless `platform` is defined on the [options](#options).
```js
const increment = require('add-filename-increment');
```
## API
### [increment](index.js#L54)
The main export is a function that adds a trailing increment to
the `stem` (basename without extension) of the given file path or object.
**Params**
* `file` **{String|Object}**: If the file is an object, it must have a `path` property.
* `options` **{Object}**: See [available options](#options).
* `returns` **{String|Object}**: Returns a file of the same type that was given, with an increment added to the file name.
**Example**
```js
console.log(increment('foo/bar.txt', { platform: 'darwin' }));
//=> foo/bar copy.txt
console.log(increment('foo/bar.txt', { platform: 'linux' }));
//=> foo/bar (copy).txt
console.log(increment('foo/bar.txt', { platform: 'win32' }));
//=> foo/bar (2).txt
```
### [.path](index.js#L76)
Add a trailing increment to the given `filepath`.
**Params**
* `filepath` **{String}**
* `options` **{Object}**: See [available options](#options).
* `returns` **{String}**
**Example**
```js
console.log(increment.path('foo/bar.txt', { platform: 'darwin' }));
//=> foo/bar copy.txt
console.log(increment.path('foo/bar.txt', { platform: 'linux' }));
//=> foo/bar (copy).txt
console.log(increment.path('foo/bar.txt', { platform: 'win32' }));
//=> foo/bar (2).txt
```
### [.file](index.js#L98)
Add a trailing increment to the `file.base` of the given file object.
**Params**
* `file` **{String|Object}**: If passed as a string, the path will be parsed to create an object using `path.parse()`.
* `options` **{Object}**: See [available options](#options).
* `returns` **{Object}**: Returns an object.
**Example**
```js
console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'darwin' }));
//=> { path: 'foo/bar copy.txt', base: 'bar copy.txt' }
console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'linux' }));
//=> { path: 'foo/bar (copy).txt', base: 'bar (copy).txt' }
console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'win32' }));
//=> { path: 'foo/bar (2).txt', base: 'bar (2).txt' }
```
### [.ordinal](index.js#L166)
Returns an ordinal-suffix for the given number. This is used when creating increments for files on Linux.
**Params**
* `num` **{Number}**
* `returns` **{String}**
**Example**
```js
const { ordinal } = require('add-filename-increment');
console.log(ordinal(1)); //=> 'st'
console.log(ordinal(2)); //=> 'nd'
console.log(ordinal(3)); //=> 'rd'
console.log(ordinal(110)); //=> 'th'
```
### [.toOrdinal](index.js#L184)
Returns an ordinal for the given number.
**Params**
* `num` **{Number}**
* `returns` **{String}**
**Example**
```js
const { toOrdinal } = require('add-filename-increment');
console.log(toOrdinal(1)); //=> '1st'
console.log(toOrdinal(2)); //=> '2nd'
console.log(toOrdinal(3)); //=> '3rd'
console.log(toOrdinal(110)); //=> '110th'
```
## Options
### options.fs
**Description**: Check the file system, and automatically increment the file based on existing files. Thus, if the file name is `foo.txt`, and `foo (2).txt` already exists, the file will automatically be renamed to `foo (3).txt`.
Also uses the correct conventions for Linux, Windows (win32), and MacOS (darwin).
**Type**: `boolean`
**Default**: `undefined`
### options.increment
**Description**: Custom function to handling incrementing a file name. This is mostly useful when `options.fs` is also defined, since this function will only be called if a file name needs to be incremented, allowing you to control how incrementing is done.
**Type**: `function`
**Default**: `undefined`
### options.platform
**Description**: Specify the platform conventions to use.
**Type**: `string`
**Default**: Uses `process.platform`. Valid values are `linux`, `win32`, and `darwin`.
## Operating Systems
* [Linux](#linux)
* [MacOS](#macos)
* [Windows](#windows)
**Supported Operating Systems**
Currently Windows, Darwin (MacOS), and Linux are supported. This library attempts to automatically use the correct conventions for each operating system. Please [create an issue](../../issues/new) if you ecounter a bug.
If you use an operating system with different conventions, and you would like for this library to add support, please [create an issue](../../issues/new) with a detailed description of those conventions, or feel free to do a [pull request](.github/contributing.md).
### Linux
When a file is copied or moved, and the destination file path already exists, Linux uses the following conventions for incrementing the file name.
| **Source path** | **Destination path** | **Type** | **Directory1** |
| --- | --- | --- | --- |
| `foo.txt` | `foo (copy).txt`, `foo (another copy).txt`, `foo (3rd copy).txt`, ... | file | Same directory as source |
| `foo` | `foo (copy)`, `foo (another copy)`, `foo (3rd copy)`, ... | directory | Same directory as source |
1 _On Linux, when a file or folder is copied or moved to a different directory and another file or folder with the same name exists in that directory, you are prompted to choose a new name for the file or folder, or to cancel or skip the operation._
### MacOS
When a file is copied or moved, and the destination file path already exists, MacOS uses the following conventions for incrementing the file name.
| **Source path** | **Destination path** | **Type** | **Directory1** |
| --- | --- | --- | --- |
| `foo.txt` | `foo copy.txt`, `foo copy 2.txt`, ... | file | Same directory as source |
| `foo.txt` | `foo 2.txt`, `foo 3.txt`, ... | file | Different directory than source |
| `foo` | `foo copy`, `foo copy 2`, ... | directory | Same directory as source |
1 _MacOS uses different conventions for incrementing file names when the source file is copied, moved or renamed to a different directory, versus when the file is copied into the same directory._
### Windows
When a file is copied or moved, and the destination file path already exists, Windows uses the following conventions for incrementing the file name.
| **Source path** | **Destination path** | **Type** | **Directory1** |
| --- | --- | --- | --- |
| `foo.txt` | `foo - Copy.txt` | file | Same directory as source |
| `foo.txt` | `foo (2).txt` | file | Different directory than source |
| `foo (2).txt` | `foo (3).txt` | file | Different directory than source |
| `foo` | `foo - Copy` | directory | Same directory as source |
| `foo - Copy` | `foo - Copy (2)` | directory | Same directory as source |
1 _Windows uses different conventions for incrementing file names when the source file is copied, moved or renamed to a different directory, versus when the file is copied into the same directory. Also, when a folder is copied to a new directory, and the new directory already has a folder with the same name, Windows just merges the folders automatically._
## About
Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards.
Running Tests
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
```sh
$ npm install && npm test
```
Building docs
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
To generate the readme, run the following command:
```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```
### Related projects
You might also be interested in these projects:
* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/micromatch/micromatch "Glob matching for javascript/node.js. A replacement and faster alternative to minimatch and multimatch.")
* [strip-filename-increment](https://www.npmjs.com/package/strip-filename-increment): Operating systems commonly add a trailing increment, or the word 'copy', or something similar to… [more](https://github.com/jonschlinkert/strip-filename-increment) | [homepage](https://github.com/jonschlinkert/strip-filename-increment "Operating systems commonly add a trailing increment, or the word 'copy', or something similar to duplicate files. This strips those increments. Tested on Windows, MacOS, and Linux.")
* [write](https://www.npmjs.com/package/write): Write data to a file, replacing the file if it already exists and creating any… [more](https://github.com/jonschlinkert/write) | [homepage](https://github.com/jonschlinkert/write "Write data to a file, replacing the file if it already exists and creating any intermediate directories if they don't already exist. Thin wrapper around node's native fs methods.")
### Author
**Jon Schlinkert**
* [GitHub Profile](https://github.com/jonschlinkert)
* [Twitter Profile](https://twitter.com/jonschlinkert)
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
### License
Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).
***
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on September 04, 2019._ add-filename-increment-1.0.0/examples.js 0000664 0000000 0000000 00000002475 13533654047 0020176 0 ustar 00root root 0000000 0000000 const increment = require('.');
console.log(increment('foo/bar.txt', { platform: 'darwin' })); //=> foo/bar copy.txt
console.log(increment('foo/bar.txt', { platform: 'linux' })); //=> foo/bar (copy).txt
console.log(increment('foo/bar.txt', { platform: 'win32' })); //=> foo/bar (2).txt
console.log(increment.path('foo/bar.txt', { platform: 'darwin' })); //=> foo/bar copy.txt
console.log(increment.path('foo/bar.txt', { platform: 'linux' })); //=> foo/bar (copy).txt
console.log(increment.path('foo/bar.txt', { platform: 'win32' })); //=> foo/bar (2).txt
console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'darwin' }));
//=> { path: 'foo/bar copy.txt', base: 'bar copy.txt' }
console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'linux' }));
//=> { path: 'foo/bar (copy).txt', base: 'bar (copy).txt' }
console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'win32' }));
//=> { path: 'foo/bar (2).txt', base: 'bar (2).txt' }
console.log(increment.ordinal(1)); //=> 'st'
console.log(increment.ordinal(2)); //=> 'nd'
console.log(increment.ordinal(3)); //=> 'rd'
console.log(increment.ordinal(110)); //=> 'th'
console.log(increment.toOrdinal(1)); //=> '1st'
console.log(increment.toOrdinal(2)); //=> '2nd'
console.log(increment.toOrdinal(3)); //=> '3rd'
console.log(increment.toOrdinal(110)); //=> '110th'
add-filename-increment-1.0.0/index.js 0000664 0000000 0000000 00000012474 13533654047 0017467 0 ustar 00root root 0000000 0000000 'use strict';
const fs = require('fs');
const path = require('path');
const strip = require('strip-filename-increment');
const ordinals = ['th', 'st', 'nd', 'rd'];
const ordinal = n => {
if (isNaN(n)) {
throw new TypeError('expected a number');
}
return ordinals[((n % 100) - 20) % 10] || ordinals[n % 100] || ordinals[0];
};
const toOrdinal = number => {
return `${Number(number)}${ordinal(Math.abs(number))}`;
};
const format = {
darwin(stem, n) {
if (n === 1) return `${stem} copy`;
if (n > 1) return `${stem} copy ${n}`;
return stem;
},
default: (stem, n) => n > 1 ? `${stem} (${n})` : stem,
win32: (stem, n) => n > 1 ? `${stem} (${n})` : stem,
windows: (stem, n) => format.win32(stem, n),
linux(stem, n) {
if (n === 0) return stem;
if (n === 1) return `${stem} (copy)`;
if (n === 2) return `${stem} (another copy)`;
return `${stem} (${toOrdinal(n)} copy)`;
}
};
/**
* The main export is a function that adds a trailing increment to
* the `stem` (basename without extension) of the given file path or object.
* ```js
* console.log(increment('foo/bar.txt', { platform: 'darwin' }));
* //=> foo/bar copy.txt
* console.log(increment('foo/bar.txt', { platform: 'linux' }));
* //=> foo/bar (copy).txt
* console.log(increment('foo/bar.txt', { platform: 'win32' }));
* //=> foo/bar (2).txt
* ```
* @name increment
* @param {String|Object} `file` If the file is an object, it must have a `path` property.
* @param {Object} `options` See [available options](#options).
* @return {String|Object} Returns a file of the same type that was given, with an increment added to the file name.
* @api public
*/
const increment = (...args) => {
return typeof args[0] === 'string' ? increment.path(...args) : increment.file(...args);
};
/**
* Add a trailing increment to the given `filepath`.
*
* ```js
* console.log(increment.path('foo/bar.txt', { platform: 'darwin' }));
* //=> foo/bar copy.txt
* console.log(increment.path('foo/bar.txt', { platform: 'linux' }));
* //=> foo/bar (copy).txt
* console.log(increment.path('foo/bar.txt', { platform: 'win32' }));
* //=> foo/bar (2).txt
* ```
* @name .path
* @param {String} `filepath`
* @param {Object} `options` See [available options](#options).
* @return {String}
* @api public
*/
increment.path = (filepath, options = {}) => {
return path.format(increment.file(path.parse(filepath), options));
};
/**
* Add a trailing increment to the `file.base` of the given file object.
*
* ```js
* console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'darwin' }));
* //=> { path: 'foo/bar copy.txt', base: 'bar copy.txt' }
* console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'linux' }));
* //=> { path: 'foo/bar (copy).txt', base: 'bar (copy).txt' }
* console.log(increment.file({ path: 'foo/bar.txt' }, { platform: 'win32' }));
* //=> { path: 'foo/bar (2).txt', base: 'bar (2).txt' }
* ```
* @name .file
* @param {String|Object} `file` If passed as a string, the path will be parsed to create an object using `path.parse()`.
* @param {Object} `options` See [available options](#options).
* @return {Object} Returns an object.
* @api public
*/
increment.file = (file, options = {}) => {
if (typeof file === 'string') {
let temp = file;
file = path.parse(file);
file.path = temp;
}
file = { ...file };
if (file.path && Object.keys(file).length === 1) {
let temp = file.path;
file = path.parse(file.path);
file.path = temp;
}
if (file.dirname && !file.dir) file.dir = file.dirname;
if (file.basename && !file.base) file.base = file.basename;
if (file.extname && !file.ext) file.ext = file.extname;
if (file.stem && !file.name) file.name = file.stem;
let { start = 1, platform = process.platform } = options;
let fn = options.increment || format[platform] || format.default;
if (start === 1 && (platform === 'win32' || platform === 'windows')) {
if (!options.increment) {
start++;
}
}
if (options.strip === true) {
file.name = strip.increment(file.name, options);
file.dir = strip.increment(file.dir, options);
file.base = file.name + file.ext;
}
if (options.fs === true) {
let name = file.name;
let dest = path.format(file);
while (fs.existsSync(dest)) {
file.base = fn(name, start++) + file.ext;
dest = path.format(file);
}
} else {
file.base = fn(file.name, start) + file.ext;
}
file.path = path.join(file.dir, file.base);
return file;
};
/**
* Returns an ordinal-suffix for the given number. This is used
* when creating increments for files on Linux.
*
* ```js
* const { ordinal } = require('add-filename-increment');
* console.log(ordinal(1)); //=> 'st'
* console.log(ordinal(2)); //=> 'nd'
* console.log(ordinal(3)); //=> 'rd'
* console.log(ordinal(110)); //=> 'th'
* ```
* @name .ordinal
* @param {Number} `num`
* @return {String}
* @api public
*/
increment.ordinal = ordinal;
/**
* Returns an ordinal for the given number.
*
* ```js
* const { toOrdinal } = require('add-filename-increment');
* console.log(toOrdinal(1)); //=> '1st'
* console.log(toOrdinal(2)); //=> '2nd'
* console.log(toOrdinal(3)); //=> '3rd'
* console.log(toOrdinal(110)); //=> '110th'
* ```
* @name .toOrdinal
* @param {Number} `num`
* @return {String}
* @api public
*/
increment.toOrdinal = toOrdinal;
module.exports = increment;
add-filename-increment-1.0.0/package.json 0000664 0000000 0000000 00000002415 13533654047 0020302 0 ustar 00root root 0000000 0000000 {
"name": "add-filename-increment",
"description": "When copying or moving files, it's common for operating systems to automatically add an increment or 'copy' to duplicate file names. This does that for Node.js applications, with automatic platform detection and support for Linux, MacOs, and Windows conventions.",
"version": "1.0.0",
"homepage": "https://github.com/jonschlinkert/add-filename-increment",
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
"repository": "jonschlinkert/add-filename-increment",
"bugs": {
"url": "https://github.com/jonschlinkert/add-filename-increment/issues"
},
"license": "MIT",
"files": [
"index.js"
],
"main": "index.js",
"engines": {
"node": ">=8"
},
"scripts": {
"test": "mocha"
},
"dependencies": {
"strip-filename-increment": "^2.0.1"
},
"devDependencies": {
"gulp-format-md": "^2.0.0",
"mocha": "^6.2.0"
},
"keywords": [
"filename",
"increment"
],
"verb": {
"toc": false,
"layout": "default",
"tasks": [
"readme"
],
"plugins": [
"gulp-format-md"
],
"related": {
"list": [
"micromatch",
"write",
"strip-filename-increment"
]
},
"lint": {
"reflinks": true
}
}
} add-filename-increment-1.0.0/test/ 0000775 0000000 0000000 00000000000 13533654047 0016771 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/darwin.js 0000664 0000000 0000000 00000007474 13533654047 0020627 0 ustar 00root root 0000000 0000000 'use strict';
require('mocha');
const path = require('path');
const assert = require('assert').strict;
const increment = require('..');
const fixtures = (...args) => {
return path.join(__dirname, 'fixtures', ...args).replace(/\\/g, '/');
};
const inc = (fp, opts) => {
return increment(fixtures(fp), { ...opts, fs: true, platform: 'darwin' });
};
describe('darwin', () => {
it('should not increment the filename when it does not exist', () => {
assert.equal(inc('baz.txt'), fixtures('baz.txt'));
});
it('should increment the filename when it exists already', () => {
assert.equal(inc('bar.txt'), fixtures('bar copy.txt'));
assert.equal(inc('sub/foo.txt'), fixtures('sub/foo copy.txt'));
assert.equal(inc('sub/nested/foo.txt'), fixtures('sub/nested/foo copy 2.txt'));
});
it('should strip existing increments and raw numbers before updating increment', () => {
const opts = { strip: true, removeRawNumbers: true };
assert.equal(inc('foo.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('qux 2.txt', opts), fixtures('qux copy.txt'));
assert.equal(inc('abc (2) - Copy.txt', opts), fixtures('abc copy.txt'));
assert.equal(inc('abc (2) - Copy Copy.txt', opts), fixtures('abc copy.txt'));
assert.equal(inc('sub/nested/foo copy.txt', opts), fixtures('sub/nested/foo copy 2.txt'));
assert.equal(inc('sub/nested/foo copy 2.txt', opts), fixtures('sub/nested/foo copy 2.txt'));
});
it('should strip existing increments before updating increment', () => {
const opts = { strip: true };
assert.equal(inc('foo.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo 2 copy.txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('qux 2.txt', opts), fixtures('qux 2 copy.txt'));
assert.equal(inc('abc (2) - Copy.txt', opts), fixtures('abc copy.txt'));
assert.equal(inc('abc (2) - Copy Copy.txt', opts), fixtures('abc copy.txt'));
assert.equal(inc('sub/nested/foo copy.txt', opts), fixtures('sub/nested/foo copy 2.txt'));
assert.equal(inc('sub/nested/foo copy 2.txt', opts), fixtures('sub/nested/foo copy 2.txt'));
});
it('should start at the given number', () => {
// fixtures exist up to "6", so "7" is the lowest number we should see.
assert.equal(inc('foo.txt', { start: 1 }), fixtures('foo copy 7.txt'));
assert.equal(inc('foo.txt', { start: 2 }), fixtures('foo copy 7.txt'));
assert.equal(inc('foo.txt', { start: 3 }), fixtures('foo copy 7.txt'));
assert.equal(inc('foo.txt', { start: 4 }), fixtures('foo copy 7.txt'));
assert.equal(inc('foo.txt', { start: 5 }), fixtures('foo copy 7.txt'));
assert.equal(inc('foo.txt', { start: 6 }), fixtures('foo copy 7.txt'));
assert.equal(inc('foo.txt', { start: 7 }), fixtures('foo copy 7.txt'));
assert.equal(inc('foo.txt', { start: 8 }), fixtures('foo copy 8.txt'));
assert.equal(inc('foo.txt', { start: 101 }), fixtures('foo copy 101.txt'));
});
it('should not strip increments when disabled', () => {
let opts = { strip: false };
assert.equal(inc('foo.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo 2 copy.txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy copy.txt'));
});
it('should use a custom function to increment the file name', () => {
let opts = {
increment(stem, n) {
return stem.replace(/(\s+copy\s*|\s\d+)$/, '') + ' copy ' + (n + 1);
}
};
assert.equal(inc('foo.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy 7.txt'));
});
});
add-filename-increment-1.0.0/test/expected/ 0000775 0000000 0000000 00000000000 13533654047 0020572 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo 2.txt 0000664 0000000 0000000 00000000000 13533654047 0022226 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo copy 2.txt 0000664 0000000 0000000 00000000000 13533654047 0023161 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo copy 3.txt 0000664 0000000 0000000 00000000000 13533654047 0023162 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo copy 4.txt 0000664 0000000 0000000 00000000000 13533654047 0023163 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo copy 5.txt 0000664 0000000 0000000 00000000000 13533654047 0023164 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo copy 6.txt 0000664 0000000 0000000 00000000000 13533654047 0023165 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo copy.txt 0000664 0000000 0000000 00000000000 13533654047 0023037 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/expected/foo.txt 0000664 0000000 0000000 00000000012 13533654047 0022107 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/ 0000775 0000000 0000000 00000000000 13533654047 0020642 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/abc (2) - Copy - Copy.txt 0000664 0000000 0000000 00000000000 13533654047 0024401 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/abc (2) - Copy.txt 0000664 0000000 0000000 00000000000 13533654047 0023371 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/abc.txt 0000664 0000000 0000000 00000000012 13533654047 0022121 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/bar.txt 0000664 0000000 0000000 00000000000 13533654047 0022135 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo (2).txt 0000664 0000000 0000000 00000000000 13533654047 0022417 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo 2 2.txt 0000664 0000000 0000000 00000000000 13533654047 0022420 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo 2.txt 0000664 0000000 0000000 00000000000 13533654047 0022276 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo 22.txt 0000664 0000000 0000000 00000000000 13533654047 0022360 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo 3 copy.txt 0000664 0000000 0000000 00000000000 13533654047 0023232 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo copy 2.txt 0000664 0000000 0000000 00000000000 13533654047 0023231 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo copy 3.txt 0000664 0000000 0000000 00000000000 13533654047 0023232 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo copy 4.txt 0000664 0000000 0000000 00000000000 13533654047 0023233 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo copy 5.txt 0000664 0000000 0000000 00000000000 13533654047 0023234 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo copy 6.txt 0000664 0000000 0000000 00000000000 13533654047 0023235 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo copy.txt 0000664 0000000 0000000 00000000000 13533654047 0023107 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/foo.txt 0000664 0000000 0000000 00000000012 13533654047 0022157 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/one (copy).txt 0000664 0000000 0000000 00000000000 13533654047 0023226 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/one.txt 0000664 0000000 0000000 00000000000 13533654047 0022152 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/qux (2).txt 0000664 0000000 0000000 00000000000 13533654047 0022451 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/qux 2.txt 0000664 0000000 0000000 00000000000 13533654047 0022330 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/qux.txt 0000664 0000000 0000000 00000000000 13533654047 0022206 0 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/sub/ 0000775 0000000 0000000 00000000000 13533654047 0021433 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/sub/bar.txt 0000664 0000000 0000000 00000000012 13533654047 0022731 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/sub/foo.txt 0000664 0000000 0000000 00000000012 13533654047 0022750 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/sub/nested/ 0000775 0000000 0000000 00000000000 13533654047 0022715 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/fixtures/sub/nested/bar.txt 0000664 0000000 0000000 00000000012 13533654047 0024213 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/sub/nested/foo copy.txt 0000664 0000000 0000000 00000000012 13533654047 0025165 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/sub/nested/foo.txt 0000664 0000000 0000000 00000000012 13533654047 0024232 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/sub/nested/qux (2).txt 0000664 0000000 0000000 00000000012 13533654047 0024527 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/sub/nested/qux 2.txt 0000664 0000000 0000000 00000000012 13533654047 0024406 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/fixtures/sub/nested/qux.txt 0000664 0000000 0000000 00000000012 13533654047 0024264 0 ustar 00root root 0000000 0000000 content... add-filename-increment-1.0.0/test/linux.js 0000664 0000000 0000000 00000012153 13533654047 0020470 0 ustar 00root root 0000000 0000000 'use strict';
require('mocha');
const path = require('path');
const assert = require('assert').strict;
const increment = require('..');
const fixtures = (...args) => {
return path.join(__dirname, 'fixtures', ...args).replace(/\\/g, '/');
};
const inc = (fp, opts) => {
return increment(fixtures(fp), { ...opts, fs: true, platform: 'linux' });
};
describe('linux', () => {
it('should not increment the filename when it does not exist', () => {
assert.equal(inc('baz.txt'), fixtures('baz.txt'));
});
it('should increment the filename when it exists already', () => {
assert.equal(inc('bar.txt'), fixtures('bar (copy).txt'));
assert.equal(inc('sub/foo.txt'), fixtures('sub/foo (copy).txt'));
assert.equal(inc('sub/nested/foo.txt'), fixtures('sub/nested/foo (copy).txt'));
});
it('should strip existing increments and raw numbers before updating increment', () => {
let opts = { strip: true, removeRawNumbers: true };
assert.equal(inc('foo.txt', opts), fixtures('foo (copy).txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo (copy).txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo (copy).txt'));
assert.equal(inc('one (copy).txt', opts), fixtures('one (another copy).txt'));
assert.equal(inc('qux 2.txt', opts), fixtures('qux (copy).txt'));
assert.equal(inc('abc (2) - Copy.txt', opts), fixtures('abc (copy).txt'));
assert.equal(inc('abc (2) - Copy Copy.txt', opts), fixtures('abc (copy).txt'));
assert.equal(inc('sub/nested/foo copy.txt', opts), fixtures('sub/nested/foo (copy).txt'));
assert.equal(inc('sub/nested/foo copy 2.txt', opts), fixtures('sub/nested/foo (copy).txt'));
});
it('should strip existing increments before updating increment', () => {
let opts = { strip: true };
assert.equal(inc('foo.txt', opts), fixtures('foo (copy).txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo 2 (copy).txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo (copy).txt'));
assert.equal(inc('one (copy).txt', opts), fixtures('one (another copy).txt'));
assert.equal(inc('qux 2.txt', opts), fixtures('qux 2 (copy).txt'));
assert.equal(inc('abc (2) - Copy.txt', opts), fixtures('abc (copy).txt'));
assert.equal(inc('abc (2) - Copy Copy.txt', opts), fixtures('abc (copy).txt'));
assert.equal(inc('sub/nested/foo copy.txt', opts), fixtures('sub/nested/foo (copy).txt'));
assert.equal(inc('sub/nested/foo copy 2.txt', opts), fixtures('sub/nested/foo (copy).txt'));
});
it('should start at the given number, or the next number that does not exist', () => {
assert.equal(inc('baz.txt', { start: 0 }), fixtures('baz.txt'), 'baz does not exist');
assert.equal(inc('bar.txt', { start: 0 }), fixtures('bar (copy).txt'), 'bar is in fixtures');
assert.equal(inc('foo.txt', { start: 2 }), fixtures('foo (another copy).txt'), 'foo is in fixtures');
assert.equal(inc('foo.txt', { start: 3 }), fixtures('foo (3rd copy).txt'));
assert.equal(inc('foo.txt', { start: 4 }), fixtures('foo (4th copy).txt'));
assert.equal(inc('foo.txt', { start: 5 }), fixtures('foo (5th copy).txt'));
assert.equal(inc('foo.txt', { start: 6 }), fixtures('foo (6th copy).txt'));
assert.equal(inc('foo.txt', { start: 7 }), fixtures('foo (7th copy).txt'));
assert.equal(inc('foo.txt', { start: 8 }), fixtures('foo (8th copy).txt'));
assert.equal(inc('foo.txt', { start: 9 }), fixtures('foo (9th copy).txt'));
assert.equal(inc('foo.txt', { start: 10 }), fixtures('foo (10th copy).txt'));
assert.equal(inc('foo.txt', { start: 11 }), fixtures('foo (11th copy).txt'));
assert.equal(inc('foo.txt', { start: 12 }), fixtures('foo (12th copy).txt'));
assert.equal(inc('foo.txt', { start: 13 }), fixtures('foo (13th copy).txt'));
assert.equal(inc('foo.txt', { start: 14 }), fixtures('foo (14th copy).txt'));
assert.equal(inc('foo.txt', { start: 112 }), fixtures('foo (112th copy).txt'));
assert.equal(inc('foo.txt', { start: 1112 }), fixtures('foo (1112th copy).txt'));
assert.equal(inc('foo.txt', { start: 22 }), fixtures('foo (22nd copy).txt'));
assert.equal(inc('foo.txt', { start: 122 }), fixtures('foo (122nd copy).txt'));
assert.equal(inc('foo.txt', { start: 1122 }), fixtures('foo (1122nd copy).txt'));
assert.equal(inc('foo.txt', { start: 102 }), fixtures('foo (102nd copy).txt'));
assert.equal(inc('foo.txt', { start: 103 }), fixtures('foo (103rd copy).txt'));
});
it('should not strip increments when disabled', () => {
let opts = { stripIncrement: false };
assert.equal(inc('foo.txt', opts), fixtures('foo (copy).txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo 2 (copy).txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy (copy).txt'));
});
it('should use a custom function to increment the file name', () => {
let opts = {
increment(stem, n) {
return stem.replace(/\s\d+$/, '') + ' [copy ' + (n + 1) + ']';
}
};
assert.equal(inc('foo.txt', opts), fixtures('foo [copy 2].txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo [copy 2].txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy [copy 2].txt'));
});
});
add-filename-increment-1.0.0/test/ordinals.js 0000664 0000000 0000000 00000006064 13533654047 0021150 0 ustar 00root root 0000000 0000000 'use strict';
require('mocha');
const assert = require('assert').strict;
const { ordinal, toOrdinal } = require('..');
describe('ordinals', () => {
it('should return the ordinal suffix only', () => {
assert.equal(ordinal(0), 'th');
assert.equal(ordinal(1), 'st');
assert.equal(ordinal(2), 'nd');
assert.equal(ordinal(3), 'rd');
});
it('should append zero with "th"', () => {
assert.equal(toOrdinal(0), '0th');
assert.equal(toOrdinal(-0), '0th');
});
it('should append "st" to numbers ending with 1, accept for 11', () => {
assert.equal(toOrdinal(1), '1st');
assert.equal(toOrdinal(11), '11th');
assert.equal(toOrdinal(21), '21st');
assert.equal(toOrdinal(31), '31st');
assert.equal(toOrdinal(41), '41st');
assert.equal(toOrdinal(51), '51st');
assert.equal(toOrdinal(61), '61st');
assert.equal(toOrdinal(71), '71st');
assert.equal(toOrdinal(81), '81st');
assert.equal(toOrdinal(91), '91st');
assert.equal(toOrdinal(111), '111th');
assert.equal(toOrdinal(121), '121st');
assert.equal(toOrdinal(211), '211th');
assert.equal(toOrdinal(311), '311th');
assert.equal(toOrdinal(321), '321st');
assert.equal(toOrdinal(1111), '1111th');
assert.equal(toOrdinal(10011), '10011th');
assert.equal(toOrdinal(10111), '10111th');
});
it('should append "nd" to numbers ending in 2, accept for 12', () => {
assert.equal(toOrdinal(2), '2nd');
assert.equal(toOrdinal(12), '12th');
assert.equal(toOrdinal(22), '22nd');
assert.equal(toOrdinal(32), '32nd');
assert.equal(toOrdinal(42), '42nd');
assert.equal(toOrdinal(52), '52nd');
assert.equal(toOrdinal(62), '62nd');
assert.equal(toOrdinal(72), '72nd');
assert.equal(toOrdinal(82), '82nd');
assert.equal(toOrdinal(92), '92nd');
assert.equal(toOrdinal(112), '112th');
assert.equal(toOrdinal(212), '212th');
assert.equal(toOrdinal(1012), '1012th');
assert.equal(toOrdinal(10012), '10012th');
});
it('should append "rd" to numbers ending with 3, accept for 13', () => {
assert.equal(toOrdinal('03'), '3rd');
assert.equal(toOrdinal(3), '3rd');
assert.equal(toOrdinal(13), '13th');
assert.equal(toOrdinal(23), '23rd');
assert.equal(toOrdinal(33), '33rd');
assert.equal(toOrdinal(43), '43rd');
assert.equal(toOrdinal(53), '53rd');
assert.equal(toOrdinal(63), '63rd');
assert.equal(toOrdinal(73), '73rd');
assert.equal(toOrdinal(83), '83rd');
assert.equal(toOrdinal(93), '93rd');
assert.equal(toOrdinal(103), '103rd');
assert.equal(toOrdinal(113), '113th');
assert.equal(toOrdinal(123), '123rd');
assert.equal(toOrdinal(213), '213th');
assert.equal(toOrdinal(1013), '1013th');
assert.equal(toOrdinal(10013), '10013th');
});
it('should work with negative numbers', () => {
assert.equal(toOrdinal(-0), '0th');
assert.equal(toOrdinal(-1), '-1st');
assert.equal(toOrdinal(-2), '-2nd');
assert.equal(toOrdinal(-3), '-3rd');
});
it('should throw a TypeError when NaN', () => {
assert.throws(() => toOrdinal(NaN), TypeError);
});
});
add-filename-increment-1.0.0/test/support/ 0000775 0000000 0000000 00000000000 13533654047 0020505 5 ustar 00root root 0000000 0000000 add-filename-increment-1.0.0/test/support/index.js 0000664 0000000 0000000 00000001074 13533654047 0022154 0 ustar 00root root 0000000 0000000 'use strict';
const fs = require('fs');
const path = require('path');
const increment = require('../..');
const generate = (dir, filenames, options = {}) => {
let { start = 0, number = 1 } = options;
let files = [];
for (let filename of [].concat(filenames)) {
let basepath = path.join(dir, filename);
for (let i = start; i < number; i++) {
let file = increment.path(basepath, { ...options, start: i });
files.push(file);
}
}
return files;
};
console.log(generate(__dirname, 'foo.txt', { start: 1, number: 20, platform: 'win32' }))
add-filename-increment-1.0.0/test/windows.js 0000664 0000000 0000000 00000007323 13533654047 0021026 0 ustar 00root root 0000000 0000000 'use strict';
require('mocha');
const path = require('path');
const assert = require('assert').strict;
const increment = require('..');
const fixtures = (...args) => {
return path.join(__dirname, 'fixtures', ...args).replace(/\\/g, '/');
};
const inc = (fp, opts) => {
return increment(fixtures(fp), { ...opts, fs: true, platform: 'windows' });
};
describe('darwin', () => {
it('should not increment the filename when it does not exist', () => {
assert.equal(inc('baz.txt'), fixtures('baz.txt'));
});
it('should increment the filename when it exists already', () => {
assert.equal(inc('bar.txt'), fixtures('bar (2).txt'));
assert.equal(inc('sub/foo.txt'), fixtures('sub/foo (2).txt'));
assert.equal(inc('sub/nested/foo.txt'), fixtures('sub/nested/foo (2).txt'));
});
it('should strip existing raw numbers and increments before updating increment', () => {
let opts = { strip: true, removeRawNumbers: true };
assert.equal(inc('foo.txt', opts), fixtures('foo (3).txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo (3).txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo (3).txt'));
assert.equal(inc('qux 2.txt', opts), fixtures('qux (3).txt'));
assert.equal(inc('abc (2) - Copy.txt', opts), fixtures('abc (2).txt'));
assert.equal(inc('abc (2) - Copy Copy.txt', opts), fixtures('abc (2).txt'));
assert.equal(inc('sub/nested/foo copy.txt', opts), fixtures('sub/nested/foo (2).txt'));
assert.equal(inc('sub/nested/foo copy 2.txt', opts), fixtures('sub/nested/foo (2).txt'));
});
it('should strip existing increments before updating increment', () => {
let opts = { strip: true };
assert.equal(inc('foo.txt', opts), fixtures('foo (3).txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo 2 (2).txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo (3).txt'));
assert.equal(inc('qux 2.txt', opts), fixtures('qux 2 (2).txt'));
assert.equal(inc('abc (2) - Copy.txt', opts), fixtures('abc (2).txt'));
assert.equal(inc('abc (2) - Copy Copy.txt', opts), fixtures('abc (2).txt'));
assert.equal(inc('sub/nested/foo copy.txt', opts), fixtures('sub/nested/foo (2).txt'));
assert.equal(inc('sub/nested/foo copy 2.txt', opts), fixtures('sub/nested/foo (2).txt'));
});
it('should start at the given number, or the next number that does not exist', () => {
assert.equal(inc('foo.txt', { start: 1 }), fixtures('foo (3).txt'));
assert.equal(inc('foo.txt', { start: 2 }), fixtures('foo (3).txt'));
assert.equal(inc('foo.txt', { start: 3 }), fixtures('foo (3).txt'));
assert.equal(inc('foo.txt', { start: 4 }), fixtures('foo (4).txt'));
assert.equal(inc('foo.txt', { start: 5 }), fixtures('foo (5).txt'));
assert.equal(inc('foo.txt', { start: 6 }), fixtures('foo (6).txt'));
assert.equal(inc('foo.txt', { start: 7 }), fixtures('foo (7).txt'));
assert.equal(inc('foo.txt', { start: 101 }), fixtures('foo (101).txt'));
assert.equal(inc('foo.txt', { start: 102 }), fixtures('foo (102).txt'));
});
it('should not strip increments when disabled', () => {
let opts = { stripIncrement: false };
assert.equal(inc('foo.txt', opts), fixtures('foo (3).txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo 2 (2).txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy (2).txt'));
});
it('should use a custom function to increment the file name', () => {
let opts = {
increment(stem, n) {
return stem.replace(/\s\d+$/, '') + ' copy ' + (n + 1);
}
};
assert.equal(inc('foo.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo 2.txt', opts), fixtures('foo copy 7.txt'));
assert.equal(inc('foo copy.txt', opts), fixtures('foo copy copy 2.txt'));
});
});