pax_global_header00006660000000000000000000000064135336540470014524gustar00rootroot0000000000000052 comment=9f48d0e87242f05ae9db716c239c4b52866a2e3f add-filename-increment-1.0.0/000077500000000000000000000000001353365404700160125ustar00rootroot00000000000000add-filename-increment-1.0.0/.editorconfig000066400000000000000000000003271353365404700204710ustar00rootroot00000000000000# 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.json000066400000000000000000000073251353365404700206150ustar00rootroot00000000000000{ "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/.gitattributes000066400000000000000000000000461353365404700207050ustar00rootroot00000000000000# Enforce Unix newlines * text eol=lf add-filename-increment-1.0.0/.github/000077500000000000000000000000001353365404700173525ustar00rootroot00000000000000add-filename-increment-1.0.0/.github/contributing.md000066400000000000000000000157761353365404700224230ustar00rootroot00000000000000# 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/.gitignore000066400000000000000000000004461353365404700200060ustar00rootroot00000000000000# 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.jsonadd-filename-increment-1.0.0/.npmrc000066400000000000000000000000231353365404700171250ustar00rootroot00000000000000package-lock=false add-filename-increment-1.0.0/.travis.yml000066400000000000000000000001641353365404700201240ustar00rootroot00000000000000sudo: false os: - linux - osx - windows language: node_js node_js: - node - '11' - '10' - '9' - '8' add-filename-increment-1.0.0/.verb.md000066400000000000000000000110251353365404700173470ustar00rootroot00000000000000## 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/LICENSE000066400000000000000000000021031353365404700170130ustar00rootroot00000000000000The 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.md000066400000000000000000000264471353365404700173060ustar00rootroot00000000000000# add-filename-increment [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/add-filename-increment.svg?style=flat)](https://www.npmjs.com/package/add-filename-increment) [![NPM monthly downloads](https://img.shields.io/npm/dm/add-filename-increment.svg?style=flat)](https://npmjs.org/package/add-filename-increment) [![NPM total downloads](https://img.shields.io/npm/dt/add-filename-increment.svg?style=flat)](https://npmjs.org/package/add-filename-increment) [![Build Status](https://travis-ci.org/jonschlinkert/add-filename-increment.svg?branch=master)](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.js000066400000000000000000000024751353365404700201760ustar00rootroot00000000000000const 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.js000066400000000000000000000124741353365404700174670ustar00rootroot00000000000000'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.json000066400000000000000000000024151353365404700203020ustar00rootroot00000000000000{ "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/000077500000000000000000000000001353365404700167715ustar00rootroot00000000000000add-filename-increment-1.0.0/test/darwin.js000066400000000000000000000074741353365404700206270ustar00rootroot00000000000000'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/000077500000000000000000000000001353365404700205725ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo 2.txt000066400000000000000000000000001353365404700222260ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo copy 2.txt000066400000000000000000000000001353365404700231610ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo copy 3.txt000066400000000000000000000000001353365404700231620ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo copy 4.txt000066400000000000000000000000001353365404700231630ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo copy 5.txt000066400000000000000000000000001353365404700231640ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo copy 6.txt000066400000000000000000000000001353365404700231650ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo copy.txt000066400000000000000000000000001353365404700230370ustar00rootroot00000000000000add-filename-increment-1.0.0/test/expected/foo.txt000066400000000000000000000000121353365404700221070ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/000077500000000000000000000000001353365404700206425ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/abc (2) - Copy - Copy.txt000066400000000000000000000000001353365404700244010ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/abc (2) - Copy.txt000066400000000000000000000000001353365404700233710ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/abc.txt000066400000000000000000000000121353365404700221210ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/bar.txt000066400000000000000000000000001353365404700221350ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo (2).txt000066400000000000000000000000001353365404700224170ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo 2 2.txt000066400000000000000000000000001353365404700224200ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo 2.txt000066400000000000000000000000001353365404700222760ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo 22.txt000066400000000000000000000000001353365404700223600ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo 3 copy.txt000066400000000000000000000000001353365404700232320ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo copy 2.txt000066400000000000000000000000001353365404700232310ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo copy 3.txt000066400000000000000000000000001353365404700232320ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo copy 4.txt000066400000000000000000000000001353365404700232330ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo copy 5.txt000066400000000000000000000000001353365404700232340ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo copy 6.txt000066400000000000000000000000001353365404700232350ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo copy.txt000066400000000000000000000000001353365404700231070ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/foo.txt000066400000000000000000000000121353365404700221570ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/one (copy).txt000066400000000000000000000000001353365404700232260ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/one.txt000066400000000000000000000000001353365404700221520ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/qux (2).txt000066400000000000000000000000001353365404700224510ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/qux 2.txt000066400000000000000000000000001353365404700223300ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/qux.txt000066400000000000000000000000001353365404700222060ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/sub/000077500000000000000000000000001353365404700214335ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/sub/bar.txt000066400000000000000000000000121353365404700227310ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/sub/foo.txt000066400000000000000000000000121353365404700227500ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/sub/nested/000077500000000000000000000000001353365404700227155ustar00rootroot00000000000000add-filename-increment-1.0.0/test/fixtures/sub/nested/bar.txt000066400000000000000000000000121353365404700242130ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/sub/nested/foo copy.txt000066400000000000000000000000121353365404700251650ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/sub/nested/foo.txt000066400000000000000000000000121353365404700242320ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/sub/nested/qux (2).txt000066400000000000000000000000121353365404700245270ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/sub/nested/qux 2.txt000066400000000000000000000000121353365404700244060ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/fixtures/sub/nested/qux.txt000066400000000000000000000000121353365404700242640ustar00rootroot00000000000000content...add-filename-increment-1.0.0/test/linux.js000066400000000000000000000121531353365404700204700ustar00rootroot00000000000000'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.js000066400000000000000000000060641353365404700211500ustar00rootroot00000000000000'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/000077500000000000000000000000001353365404700205055ustar00rootroot00000000000000add-filename-increment-1.0.0/test/support/index.js000066400000000000000000000010741353365404700221540ustar00rootroot00000000000000'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.js000066400000000000000000000073231353365404700210260ustar00rootroot00000000000000'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')); }); });