@rollup/pluginutils
Advanced tools
Comparing version
@@ -288,3 +288,13 @@ 'use strict'; | ||
} | ||
// isWellFormed exists from Node.js 20 | ||
const hasStringIsWellFormed = 'isWellFormed' in String.prototype; | ||
function isWellFormedString(input) { | ||
// @ts-expect-error String::isWellFormed exists from ES2024. tsconfig lib is set to ES6 | ||
if (hasStringIsWellFormed) | ||
return input.isWellFormed(); | ||
// https://github.com/tc39/proposal-is-usv-string/blob/main/README.md#algorithm | ||
return !/\p{Surrogate}/u.test(input); | ||
} | ||
const dataToEsm = function dataToEsm(data, options = {}) { | ||
var _a, _b; | ||
const t = options.compact ? '' : 'indent' in options ? options.indent : '\t'; | ||
@@ -304,4 +314,13 @@ const _ = options.compact ? '' : ' '; | ||
} | ||
let maxUnderbarPrefixLength = 0; | ||
for (const key of Object.keys(data)) { | ||
const underbarPrefixLength = (_b = (_a = key.match(/^(_+)/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0; | ||
if (underbarPrefixLength > maxUnderbarPrefixLength) { | ||
maxUnderbarPrefixLength = underbarPrefixLength; | ||
} | ||
} | ||
const arbitraryNamePrefix = `${'_'.repeat(maxUnderbarPrefixLength + 1)}arbitrary`; | ||
let namedExportCode = ''; | ||
const defaultExportRows = []; | ||
const arbitraryNameExportRows = []; | ||
for (const [key, value] of Object.entries(data)) { | ||
@@ -317,5 +336,14 @@ if (key === makeLegalIdentifier(key)) { | ||
defaultExportRows.push(`${stringify(key)}:${_}${serialize(value, options.compact ? null : t, '')}`); | ||
if (options.includeArbitraryNames && isWellFormedString(key)) { | ||
const variableName = `${arbitraryNamePrefix}${arbitraryNameExportRows.length}`; | ||
namedExportCode += `${declarationType} ${variableName}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`; | ||
arbitraryNameExportRows.push(`${variableName} as ${JSON.stringify(key)}`); | ||
} | ||
} | ||
} | ||
return `${namedExportCode}export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`; | ||
const arbitraryExportCode = arbitraryNameExportRows.length > 0 | ||
? `export${_}{${n}${t}${arbitraryNameExportRows.join(`,${n}${t}`)}${n}};${n}` | ||
: ''; | ||
const defaultExportCode = `export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`; | ||
return `${namedExportCode}${arbitraryExportCode}${defaultExportCode}`; | ||
}; | ||
@@ -322,0 +350,0 @@ |
@@ -284,3 +284,13 @@ import { extname, win32, posix, isAbsolute, resolve } from 'path'; | ||
} | ||
// isWellFormed exists from Node.js 20 | ||
const hasStringIsWellFormed = 'isWellFormed' in String.prototype; | ||
function isWellFormedString(input) { | ||
// @ts-expect-error String::isWellFormed exists from ES2024. tsconfig lib is set to ES6 | ||
if (hasStringIsWellFormed) | ||
return input.isWellFormed(); | ||
// https://github.com/tc39/proposal-is-usv-string/blob/main/README.md#algorithm | ||
return !/\p{Surrogate}/u.test(input); | ||
} | ||
const dataToEsm = function dataToEsm(data, options = {}) { | ||
var _a, _b; | ||
const t = options.compact ? '' : 'indent' in options ? options.indent : '\t'; | ||
@@ -300,4 +310,13 @@ const _ = options.compact ? '' : ' '; | ||
} | ||
let maxUnderbarPrefixLength = 0; | ||
for (const key of Object.keys(data)) { | ||
const underbarPrefixLength = (_b = (_a = key.match(/^(_+)/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0; | ||
if (underbarPrefixLength > maxUnderbarPrefixLength) { | ||
maxUnderbarPrefixLength = underbarPrefixLength; | ||
} | ||
} | ||
const arbitraryNamePrefix = `${'_'.repeat(maxUnderbarPrefixLength + 1)}arbitrary`; | ||
let namedExportCode = ''; | ||
const defaultExportRows = []; | ||
const arbitraryNameExportRows = []; | ||
for (const [key, value] of Object.entries(data)) { | ||
@@ -313,5 +332,14 @@ if (key === makeLegalIdentifier(key)) { | ||
defaultExportRows.push(`${stringify(key)}:${_}${serialize(value, options.compact ? null : t, '')}`); | ||
if (options.includeArbitraryNames && isWellFormedString(key)) { | ||
const variableName = `${arbitraryNamePrefix}${arbitraryNameExportRows.length}`; | ||
namedExportCode += `${declarationType} ${variableName}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`; | ||
arbitraryNameExportRows.push(`${variableName} as ${JSON.stringify(key)}`); | ||
} | ||
} | ||
} | ||
return `${namedExportCode}export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`; | ||
const arbitraryExportCode = arbitraryNameExportRows.length > 0 | ||
? `export${_}{${n}${t}${arbitraryNameExportRows.join(`,${n}${t}`)}${n}};${n}` | ||
: ''; | ||
const defaultExportCode = `export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`; | ||
return `${namedExportCode}${arbitraryExportCode}${defaultExportCode}`; | ||
}; | ||
@@ -318,0 +346,0 @@ |
{ | ||
"name": "@rollup/pluginutils", | ||
"version": "5.0.5", | ||
"version": "5.1.0", | ||
"publishConfig": { | ||
@@ -29,16 +29,2 @@ "access": "public" | ||
}, | ||
"scripts": { | ||
"build": "rollup -c", | ||
"ci:coverage": "nyc pnpm test && nyc report --reporter=text-lcov > coverage.lcov", | ||
"ci:lint": "pnpm build && pnpm lint", | ||
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}", | ||
"ci:test": "pnpm test -- --verbose", | ||
"prebuild": "del-cli dist", | ||
"prepare": "if [ ! -d 'dist' ]; then pnpm build; fi", | ||
"prerelease": "pnpm build", | ||
"pretest": "pnpm build --sourcemap", | ||
"release": "pnpm --workspace-root plugin:release --pkg $npm_package_name", | ||
"test": "ava", | ||
"test:ts": "tsc --noEmit" | ||
}, | ||
"files": [ | ||
@@ -100,3 +86,16 @@ "dist", | ||
] | ||
}, | ||
"scripts": { | ||
"build": "rollup -c", | ||
"ci:coverage": "nyc pnpm test && nyc report --reporter=text-lcov > coverage.lcov", | ||
"ci:lint": "pnpm build && pnpm lint", | ||
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}", | ||
"ci:test": "pnpm test -- --verbose", | ||
"prebuild": "del-cli dist", | ||
"prerelease": "pnpm build", | ||
"pretest": "pnpm build --sourcemap", | ||
"release": "pnpm --workspace-root package:release $(pwd)", | ||
"test": "ava", | ||
"test:ts": "tsc --noEmit" | ||
} | ||
} | ||
} |
@@ -103,3 +103,3 @@ [npm]: https://img.shields.io/npm/v/@rollup/pluginutils | ||
Parameters: `(include?: <picomatch>, exclude?: <picomatch>, options?: Object)`<br> | ||
Returns: `String` | ||
Returns: `(id: string | unknown) => boolean` | ||
@@ -147,3 +147,3 @@ #### `include` and `exclude` | ||
Parameters: `(data: Object)`<br> | ||
Parameters: `(data: Object, options: DataToEsmOptions)`<br> | ||
Returns: `String` | ||
@@ -157,2 +157,8 @@ | ||
#### `options` | ||
Type: `DataToEsmOptions` | ||
_Note: Please see the TypeScript definition for complete documentation of these options_ | ||
#### Usage | ||
@@ -173,3 +179,4 @@ | ||
objectShorthand: true, | ||
namedExports: true | ||
namedExports: true, | ||
includeArbitraryNames: false | ||
} | ||
@@ -176,0 +183,0 @@ ); |
@@ -13,2 +13,8 @@ import type { BaseNode } from 'estree'; | ||
compact?: boolean; | ||
/** | ||
* @desc When this option is set, dataToEsm will generate a named export for keys that | ||
* are not a valid identifier, by leveraging the "Arbitrary Module Namespace Identifier | ||
* Names" feature. See: https://github.com/tc39/ecma262/pull/2154 | ||
*/ | ||
includeArbitraryNames?: boolean; | ||
indent?: string; | ||
@@ -15,0 +21,0 @@ namedExports?: boolean; |
57092
51.27%8
33.33%1150
57.53%263
2.73%