Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a v1-like stateless API in v2 #1130

Merged
merged 11 commits into from
Dec 20, 2023
Merged
3 changes: 3 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,21 @@ flags:
paths:
- src/
- index.js
- stateless.js
- testing.js
integration-Ubuntu:
carryforward: true
paths:
- src/
- index.js
- stateless.js
- testing.js
integration-Windows:
carryforward: true
paths:
- src/
- index.js
- stateless.js
- testing.js
unit:
carryforward: true
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ checksums.txt
crash-*
index.cjs
index.d.cts
stateless.cjs
stateless.d.cts
testing.cjs
testing.d.cts

Expand Down
4 changes: 4 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
!LICENSE
!README.md
!SECURITY.md
!stateless.cjs
!stateless.d.cts
!stateless.d.ts
!stateless.js
!testing.cjs
!testing.d.cts
!testing.d.ts
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Versioning].

## [Unreleased]

- Add `shescape/stateless` module with v1-like API. ([#1130])
- Re-export `Shescape` as `Stubscape` from `shescape/testing`. ([#1308])

## [2.0.2] - 2023-11-19
Expand Down Expand Up @@ -321,6 +322,7 @@ Versioning].
[#1082]: https://github.com/ericcornelissen/shescape/pull/1082
[#1083]: https://github.com/ericcornelissen/shescape/pull/1083
[#1094]: https://github.com/ericcornelissen/shescape/pull/1094
[#1130]: https://github.com/ericcornelissen/shescape/pull/1130
[#1137]: https://github.com/ericcornelissen/shescape/pull/1137
[#1142]: https://github.com/ericcornelissen/shescape/pull/1142
[#1149]: https://github.com/ericcornelissen/shescape/pull/1149
Expand Down
2 changes: 1 addition & 1 deletion config/c8/breakage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"all": true,
"include": ["src/", "index.js", "testing.js"],
"include": ["src/", "index.js", "stateless.js", "testing.js"],
"exclude": [],
"check-coverage": false,
"reports-dir": "_reports/coverage/breakage",
Expand Down
2 changes: 1 addition & 1 deletion config/c8/compat.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"all": true,
"include": ["src/", "index.js", "testing.js"],
"include": ["src/", "index.js", "stateless.js", "testing.js"],
"exclude": [],
"check-coverage": false,
"reports-dir": "_reports/coverage/compat",
Expand Down
2 changes: 1 addition & 1 deletion config/c8/integration-unix.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"all": true,
"include": ["src/", "index.js", "testing.js"],
"include": ["src/", "index.js", "stateless.js", "testing.js"],
"exclude": ["src/win/", "src/win.js"],
"check-coverage": false,
"reports-dir": "_reports/coverage/integration",
Expand Down
2 changes: 1 addition & 1 deletion config/c8/integration-win.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"all": true,
"include": ["src/", "index.js", "testing.js"],
"include": ["src/", "index.js", "stateless.js", "testing.js"],
"exclude": ["src/unix/", "src/unix.js"],
"check-coverage": false,
"reports-dir": "_reports/coverage/integration",
Expand Down
2 changes: 2 additions & 0 deletions config/eslint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -755,5 +755,7 @@ ignorePatterns:
- script/maybe-run.js
- index.cjs
- index.d.cts
- stateless.cjs
- stateless.d.cts
- testing.cjs
- testing.d.cts
8 changes: 8 additions & 0 deletions config/rollup.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ export default [
},
external,
},
{
input: "stateless.js",
output: {
file: "stateless.cjs",
format: "cjs",
},
external,
},
{
input: "testing.js",
output: {
Expand Down
2 changes: 1 addition & 1 deletion config/stryker/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
export default {
coverageAnalysis: "perTest",
inPlace: false,
mutate: ["index.js", "testing.js"],
mutate: ["index.js", "stateless.js", "testing.js"],
testRunner: "tap",
tap: {
testFiles: ["test/integration/**/*.test.js"],
Expand Down
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*
* @since 2.0.0
*/
interface ShescapeOptions {
export interface ShescapeOptions {
/**
* Whether or not to protect against flag and option (such as `--verbose`)
* injection
Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@
"default": "./index.cjs"
}
},
"./stateless": {
"import": {
"types": "./stateless.d.ts",
"default": "./stateless.js"
},
"require": {
"types": "./stateless.d.cts",
"default": "./stateless.cjs"
}
},
"./testing": {
"import": {
"types": "./testing.d.ts",
Expand Down
9 changes: 8 additions & 1 deletion script/clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ import path from "node:path";

import { common } from "./_.js";

const files = ["index.cjs", "index.d.cts", "testing.cjs", "testing.d.cts"];
const files = [
"index.cjs",
"index.d.cts",
"stateless.cjs",
"stateless.d.cts",
"testing.cjs",
"testing.d.cts",
];
const folders = [".corpus/", ".nyc_output/", ".temp/", "_reports/"];

for (const file of files) {
Expand Down
2 changes: 1 addition & 1 deletion script/create-d-cts.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import path from "node:path";

import { common } from "./_.js";

const files = ["index.d.ts", "testing.d.ts"];
const files = ["index.d.ts", "stateless.d.ts", "testing.d.ts"];

for (const file of files) {
const copy = file.replace(".d.ts", ".d.cts");
Expand Down
108 changes: 108 additions & 0 deletions stateless.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* @overview Contains TypeScript type definitions for Shescape's stateless
* alternative.
* @license MPL-2.0
*/

import type { ShescapeOptions } from "shescape";

/**
* Take a single value, the argument, and escape any dangerous characters.
*
* Non-string inputs will be converted to strings using a `toString()` method.
*
* @example
* import { spawn } from "node:child_process";
* spawn(
* "echo",
* ["Hello", shescape.escape(userInput, { shell: false })],
* null // `options.shell` MUST be falsy
* );
* @param {string} arg The argument to escape.
* @param {object} [options] The escape options.
* @param {boolean} [options.flagProtection=true] Is flag protection enabled.
* @param {boolean | string} [options.shell=true] The shell to escape for.
* @returns {string} The escaped argument.
* @throws {TypeError} The argument is not stringable.
* @throws {Error} The shell is not supported or could not be found.
* @since 2.1.0
*/
export function escape(arg: string, options?: ShescapeOptions): string;

/**
* Take an array of values, the arguments, and escape any dangerous characters
* in every argument.
*
* Non-array inputs will be converted to one-value arrays and non-string values
* will be converted to strings using a `toString()` method.
*
* @example
* import { spawn } from "node:child_process";
* spawn(
* "echo",
* shescape.escapeAll(["Hello", userInput], { shell: false }),
* null // `options.shell` MUST be falsy
* );
* @param {string[]} args The arguments to escape.
* @param {object} [options] The escape options.
* @param {boolean} [options.flagProtection=true] Is flag protection enabled.
* @param {boolean | string} [options.shell=true] The shell to escape for.
* @returns {string[]} The escaped arguments.
* @throws {TypeError} One of the arguments is not stringable.
* @throws {Error} The shell is not supported or could not be found.
* @since 2.1.0
*/
export function escapeAll(args: string[], options?: ShescapeOptions): string[];

/**
* Take a single value, the argument, put shell-specific quotes around it and
* escape any dangerous characters.
*
* Non-string inputs will be converted to strings using a `toString()` method.
*
* @example
* import { spawn } from "node:child_process";
* const spawnOptions = { shell: true }; // `options.shell` SHOULD be truthy
* spawn(
* "echo",
* ["Hello", shescape.quote(userInput, { shell: spawnOptions.shell })],
* spawnOptions
* );
* @param {string} arg The argument to quote and escape.
* @param {object} [options] The escape options.
* @param {boolean} [options.flagProtection=true] Is flag protection enabled.
* @param {boolean | string} [options.shell=true] The shell to escape for.
* @returns {string} The quoted and escaped argument.
* @throws {TypeError} The argument is not stringable.
* @throws {Error} The shell is not supported or could not be found.
* @throws {Error} Quoting is not supported with `shell: false`.
* @since 2.1.0
*/
export function quote(arg: string, options?: ShescapeOptions): string;

/**
* Take an array of values, the arguments, put shell-specific quotes around
* every argument and escape any dangerous characters in every argument.
*
* Non-array inputs will be converted to one-value arrays and non-string
* values will be converted to strings using a `toString()` method.
*
* @example
* import { spawn } from "node:child_process";
* const spawnOptions = { shell: true }; // `options.shell` SHOULD be truthy
* spawn(
* "echo",
* shescape.quoteAll(["Hello", userInput], { shell: spawnOptions.shell }),
* spawnOptions
* );
* @param {string[]} args The arguments to quote and escape.
* @param {object} [options] The escape options.
* @param {boolean} [options.flagProtection=true] Is flag protection enabled.
* @param {boolean | string} [options.shell=true] The shell to escape for.
* @returns {string[]} The quoted and escaped arguments.
* @throws {TypeError} One of the arguments is not stringable.
* @throws {Error} The shell is not supported or could not be found.
* @throws {Error} Quoting is not supported with `shell: false`.
* @since 2.1.0
*/
export function quoteAll(args: string[], options?: ShescapeOptions): string[];
Loading