Skip to content

Commit

Permalink
feat: rewrite as ESM and improve the TypeScript declaration file
Browse files Browse the repository at this point in the history
And a new `keepLeadingDash` option has been added to the kebabCase function.
When set to `false` it will remove any leading dash from the kebab-cased string,
in case the original string starts with a leading uppercase letter.
Fixes #7, Closes #12.

BREAKING CHANGE: kebab-case is rewritten in ESM and is not published as CommonJS anymore. If you still need CJS you should stick to the v1 version.
  • Loading branch information
joakimbeng committed Jun 28, 2024
1 parent 66b27a7 commit f572ed3
Show file tree
Hide file tree
Showing 11 changed files with 877 additions and 1,009 deletions.
23 changes: 17 additions & 6 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,25 @@ jobs:

strategy:
matrix:
node-version: [14.x, 15.x]
node-version: [20.x, 22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 2

- uses: pnpm/action-setup@v4.0.0

- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
cache: 'pnpm'

- name: Install dependencies
run: pnpm install

- name: Checks
run: pnpm test
38 changes: 28 additions & 10 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,41 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4.0.0

- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 14
- run: npm ci
- run: npm test
node-version: 20
cache: 'pnpm'

- name: Install dependencies
run: pnpm install

- name: Run tests
run: pnpm test

publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4.0.0

- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 14
node-version: 20
cache: 'pnpm'
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish

- name: Install dependencies
run: pnpm install

- name: Publish package
run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,24 @@ npm install --save kebab-case
### Module usage

```javascript
var kebabCase = require("kebab-case");
import kebabCase from "kebab-case";

kebabCase("WebkitTransform");
// "-webkit-transform"
kebabCase.reverse("-webkit-transform");
// "WebkitTransform"
kebabCase("WebkitTransform", false);
// "webkit-transform"
```

## API

### `kebabCase(str)`

| Name | Type | Description |
| ---- | -------- | --------------------- |
| str | `String` | The string to convert |
| Name | Type | Description |
| --------------- | --------- | ----------------------------------------------------------- |
| str | `String` | The string to convert |
| keepLeadingDash | `Boolean` | Whether to keep the leading dash or not. Default is `true`. |

Returns: `String`, the kebab cased string.

Expand Down
7 changes: 7 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import globals from "globals";
import pluginJs from "@eslint/js";

export default [
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
pluginJs.configs.recommended,
];
33 changes: 25 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
type Fn = (str: string) => string;

interface KebabCase extends Fn {
reverse: Fn
}

const kebabCase: KebabCase;

export default kebabCase;
/**
* Transforms a string into kebab-case.
*
* @example
* kebabCase("helloWorld"); // "hello-world"
* kebabCase("HelloWorld"); // "-hello-world"
* kebabCase("HelloWorld", false); // "hello-world"
*
* @param {string} str The string to transform
* @param {boolean} keepLeadingDash Whether to keep the leading dash in case the string starts with an uppercase letter (default: true)
* @returns The kebab-cased string
*/
declare function kebabCase(str: string, keepLeadingDash?: boolean): string | undefined;
declare namespace kebabCase {
/**
* Transforms a kebab-cased string back to the original string.
*
* @example
* kebabCase.reverse("hello-world"); // "helloWorld"
*
* @param {string} str
* @returns The original string, with the kebab-case transformation reversed
*/
function reverse(str: string): string;
}
50 changes: 37 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
'use strict';
var KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g;
var REVERSE_REGEX = /-[a-z\u00E0-\u00F6\u00F8-\u00FE]/g;

module.exports = exports = function kebabCase(str) {
return str.replace(KEBAB_REGEX, function (match) {
return '-' + match.toLowerCase();
});
};
const KEBAB_REGEX = /\p{Lu}/gu;
const REVERSE_REGEX = /-\p{Ll}/gu;

/**
* Transforms a string into kebab-case.
*
* @example
* kebabCase("helloWorld"); // "hello-world"
* kebabCase("HelloWorld"); // "-hello-world"
* kebabCase("HelloWorld", false); // "hello-world"
*
* @param {string} str The string to transform
* @param {boolean} keepLeadingDash Whether to keep the leading dash in case the string starts with an uppercase letter (default: true)
* @returns The kebab-cased string
*/
const kebabCase = (str, keepLeadingDash = true) => {
const result = str.replace(KEBAB_REGEX, (match) => `-${match.toLowerCase()}`);

if (keepLeadingDash) {
return result;
}

exports.reverse = function (str) {
return str.replace(REVERSE_REGEX, function (match) {
return match.slice(1).toUpperCase();
});
if (result.startsWith("-")) {
return result.slice(1);
}
};

/**
* Transforms a kebab-cased string back to the original string.
*
* @example
* kebabCase.reverse("hello-world"); // "helloWorld"
*
* @param {string} str
* @returns The original string, with the kebab-case transformation reversed
*/
kebabCase.reverse = (str) => str.replace(REVERSE_REGEX, (match) => match.slice(1).toUpperCase());

export default kebabCase;
Loading

0 comments on commit f572ed3

Please sign in to comment.