From 0fcf229f78e334a5c6bec55725fe92a8de97590c Mon Sep 17 00:00:00 2001 From: jack <75576058+jackholden@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:06:16 +0000 Subject: [PATCH] feat(format): new built-in format for es6 module object (#1380) * feat(format): new built-in format for es6 module object * feat(format): additional es6 module object test and snapshot * style(format): improve readability with additional indentation Co-authored-by: Joren Broekema * chore: add changeset and rename to javascript/esm --------- Co-authored-by: Joren Broekema --- .changeset/dull-bags-collect.md | 5 ++ .../formats/__snapshots__/all.test.snap.js | 51 +++++++++++++++ .../__snapshots__/es6Module.test.snap.js | 18 ++++++ .../es6ModuleMinify.test.snap.js | 16 +++++ __tests__/formats/es6Module.test.js | 50 +++++++++++++++ __tests__/formats/es6ModuleMinify.test.js | 53 ++++++++++++++++ .../reference/Hooks/Formats/predefined.md | 63 +++++++++++++++++++ lib/common/formats.js | 33 ++++++++++ 8 files changed, 289 insertions(+) create mode 100644 .changeset/dull-bags-collect.md create mode 100644 __tests__/formats/__snapshots__/es6Module.test.snap.js create mode 100644 __tests__/formats/__snapshots__/es6ModuleMinify.test.snap.js create mode 100644 __tests__/formats/es6Module.test.js create mode 100644 __tests__/formats/es6ModuleMinify.test.js diff --git a/.changeset/dull-bags-collect.md b/.changeset/dull-bags-collect.md new file mode 100644 index 000000000..79209ba59 --- /dev/null +++ b/.changeset/dull-bags-collect.md @@ -0,0 +1,5 @@ +--- +'style-dictionary': minor +--- + +Add a new built-in format javascript/esm that outputs an ES module JS default export. diff --git a/__tests__/formats/__snapshots__/all.test.snap.js b/__tests__/formats/__snapshots__/all.test.snap.js index 2eed5c385..61dacabd3 100644 --- a/__tests__/formats/__snapshots__/all.test.snap.js +++ b/__tests__/formats/__snapshots__/all.test.snap.js @@ -1513,3 +1513,54 @@ class { }`; /* end snapshot formats all should match flutter/class.dart snapshot with fileHeaderTimestamp set */ +snapshots["formats all should match javascript/esm snapshot"] = +`/** + * Do not edit directly, this file was auto-generated. + */ + +export default { + "color": { + "red": { + "value": "#FF0000", + "type": "color", + "original": { + "value": "#FF0000" + }, + "name": "color_red", + "comment": "comment", + "path": [ + "color", + "red" + ] + } + } +}; +`; +/* end snapshot formats all should match javascript/esm snapshot */ + +snapshots["formats all should match javascript/esm snapshot with fileHeaderTimestamp set"] = +`/** + * Do not edit directly, this file was auto-generated. + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +export default { + "color": { + "red": { + "value": "#FF0000", + "type": "color", + "original": { + "value": "#FF0000" + }, + "name": "color_red", + "comment": "comment", + "path": [ + "color", + "red" + ] + } + } +}; +`; +/* end snapshot formats all should match javascript/esm snapshot with fileHeaderTimestamp set */ + diff --git a/__tests__/formats/__snapshots__/es6Module.test.snap.js b/__tests__/formats/__snapshots__/es6Module.test.snap.js new file mode 100644 index 000000000..f74df61d3 --- /dev/null +++ b/__tests__/formats/__snapshots__/es6Module.test.snap.js @@ -0,0 +1,18 @@ +/* @web/test-runner snapshot v1 */ +export const snapshots = {}; + +snapshots["formats javascript/esm should be a valid JS file and match snapshot"] = +`/** + * Do not edit directly, this file was auto-generated. + */ + +export default { + "color": { + "red": { + "value": "#FF0000" + } + } +}; +`; +/* end snapshot formats javascript/esm should be a valid JS file and match snapshot */ + diff --git a/__tests__/formats/__snapshots__/es6ModuleMinify.test.snap.js b/__tests__/formats/__snapshots__/es6ModuleMinify.test.snap.js new file mode 100644 index 000000000..af0bd1d0c --- /dev/null +++ b/__tests__/formats/__snapshots__/es6ModuleMinify.test.snap.js @@ -0,0 +1,16 @@ +/* @web/test-runner snapshot v1 */ +export const snapshots = {}; + +snapshots["formats javascript/esm should be a valid JS file and match snapshot"] = +`/** + * Do not edit directly, this file was auto-generated. + */ + +export default { + "color": { + "red": "#FF0000" + } +}; +`; +/* end snapshot formats javascript/esm should be a valid JS file and match snapshot */ + diff --git a/__tests__/formats/es6Module.test.js b/__tests__/formats/es6Module.test.js new file mode 100644 index 000000000..05cfae406 --- /dev/null +++ b/__tests__/formats/es6Module.test.js @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import { expect } from 'chai'; +import formats from '../../lib/common/formats.js'; +import createFormatArgs from '../../lib/utils/createFormatArgs.js'; +import flattenTokens from '../../lib/utils/flattenTokens.js'; + +const file = { + destination: '__output/', + format: 'javascript/esm', + filter: { + type: 'color', + }, +}; + +const tokens = { + color: { + red: { value: '#FF0000' }, + }, +}; + +const format = formats['javascript/esm']; + +describe('formats', () => { + describe('javascript/esm', () => { + it('should be a valid JS file and match snapshot', async () => { + await expect( + await format( + createFormatArgs({ + dictionary: { tokens, allTokens: flattenTokens(tokens) }, + file, + platform: {}, + }), + {}, + file, + ), + ).to.matchSnapshot(); + }); + }); +}); diff --git a/__tests__/formats/es6ModuleMinify.test.js b/__tests__/formats/es6ModuleMinify.test.js new file mode 100644 index 000000000..d9ffe0497 --- /dev/null +++ b/__tests__/formats/es6ModuleMinify.test.js @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import { expect } from 'chai'; +import formats from '../../lib/common/formats.js'; +import createFormatArgs from '../../lib/utils/createFormatArgs.js'; +import flattenTokens from '../../lib/utils/flattenTokens.js'; + +const file = { + destination: '__output/', + format: 'javascript/esm', + options: { + minify: true, + }, + filter: { + type: 'color', + }, +}; + +const tokens = { + color: { + red: { value: '#FF0000' }, + }, +}; + +const format = formats['javascript/esm']; + +describe('formats', () => { + describe('javascript/esm', () => { + it('should be a valid JS file and match snapshot', async () => { + await expect( + await format( + createFormatArgs({ + dictionary: { tokens, allTokens: flattenTokens(tokens) }, + file, + platform: {}, + }), + {}, + file, + ), + ).to.matchSnapshot(); + }); + }); +}); diff --git a/docs/src/content/docs/reference/Hooks/Formats/predefined.md b/docs/src/content/docs/reference/Hooks/Formats/predefined.md index 865386852..9b9d5bf33 100644 --- a/docs/src/content/docs/reference/Hooks/Formats/predefined.md +++ b/docs/src/content/docs/reference/Hooks/Formats/predefined.md @@ -285,6 +285,69 @@ export const ColorBackgroundBase = '#ffffff'; export const ColorBackgroundAlt = '#fcfcfcfc'; ``` +### javascript/esm + +Creates an ES6 module object of the style dictionary. + +```json title="config.json" +{ + "platforms": { + "js": { + "transformGroup": "js", + "files": [ + { + "format": "javascript/esm", + "destination": "colors.js", + "options": { + "minify": true + } + } + ] + } + } +} +``` + +| Param | Type | Description | +| ---------------- | --------- | --------------------------------------------------------- | +| `options` | `Object` | | +| `options.minify` | `boolean` | Whether or not to minify the output. Defaults to `false`. | + +Example: + +```js title="vars.js" +export default { + colors: { + black: { + $value: '#000000', + filePath: 'src/tokens/color.json', + isSource: true, + $type: 'color', + original: { + $value: '#000000', + $type: 'color', + }, + name: 'ColorsBlack', + attributes: { + category: 'colors', + type: 'black', + }, + path: ['colors', 'black'], + }, + }, +}; +``` + +Example with `minify` flag: + +```js title="vars.js" +export default { + colors: { + black: '#000000', + }, +}; +``` + --- ### typescript/es6-declarations diff --git a/lib/common/formats.js b/lib/common/formats.js index 5559ee5c2..173d06139 100644 --- a/lib/common/formats.js +++ b/lib/common/formats.js @@ -534,6 +534,39 @@ const formats = { ); }, + /** + * Creates a ES6 module with the whole style dictionary + * + * @memberof Formats + * @kind member + * @example + * ```js + * export default { + * "color": { + * "base": { + * "red": "#ff0000" + * } + * } + * } + * ``` + */ + 'javascript/esm': async function ({ dictionary, file, options }) { + const { formatting, minify = false } = options; + const header = await fileHeader({ + file, + formatting: getFormattingCloneWithoutPrefix(formatting), + options, + }); + + const dictionaryString = JSON.stringify( + minify ? minifyDictionary(dictionary.tokens, options.usesDtcg) : dictionary.tokens, + null, + 2, + ); + + return `${header}export default ${dictionaryString};\n`; + }, + // TypeScript declarations /** * Creates TypeScript declarations for ES6 modules