Skip to content

Commit

Permalink
Feat(exporters): Variables exporter export new token structure #DS-1435
Browse files Browse the repository at this point in the history
  • Loading branch information
curdaj committed Sep 3, 2024
1 parent cdc61cf commit 59f8021
Show file tree
Hide file tree
Showing 31 changed files with 784 additions and 105 deletions.
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ makefile

# GitHub
CODEOWNERS

# variable-scss exporter example mock test files
exporters/variables-scss/src/**/*.scss

# variable-scss exporter generated cjs
exporters/variables-scss/generated/**/*.cjs
8 changes: 8 additions & 0 deletions exporters/variables-scss/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
extends: ['../../.eslintrc', '@lmc-eu/eslint-config-typescript', '@lmc-eu/eslint-config-jest'],

parserOptions: {
ecmaVersion: 'latest',
project: './tsconfig.eslint.json',
},
};
24 changes: 0 additions & 24 deletions exporters/variables-scss/.eslintrc.js

This file was deleted.

2 changes: 1 addition & 1 deletion exporters/variables-scss/exporter.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"version": "1.0.0",
"usesBrands": true,
"usesThemes": true,
"executable": "/generated/exporter.js",
"executable": "/generated/exporter.cjs",
"engine": "latest",
"tags": ["spirit", "scss", "variables", "exporter"]
}
17 changes: 17 additions & 0 deletions exporters/variables-scss/generated/exporter.cjs

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions exporters/variables-scss/generated/exporter.js

This file was deleted.

7 changes: 4 additions & 3 deletions exporters/variables-scss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
"description": "Spirit SCSS Exporter for Supernova",
"author": "Spirit Team",
"license": "MIT",
"main": "gennerated/exporter.js",
"main": "generated/exporter.cjs",
"type": "module",
"scripts": {
"dev": "vite watch",
"dev": "vite build --watch",
"build": "vite build",
"lint": "eslint ./",
"lint:fix": "yarn lint --fix",
Expand All @@ -32,4 +33,4 @@
"prettier-config-spirit": "workspace:^",
"typescript": "5.5.2"
}
}
}
28 changes: 0 additions & 28 deletions exporters/variables-scss/src/content/token.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* This file was generated by Supernova, don't change manually */
$grid-spacing-desktop: 32px !default;

$grid-columns: 12 !default;

$grid-spacings: (
spacing-desktop: $grid-spacing-desktop,
) !default;

$grids: (
columns: $grid-columns,
) !default;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$my-var: (
color: #000,
background: #fff,
border: 1px solid #000,
) !default;
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {
DimensionToken,
DimensionTokenValue,
StringToken,
StringTokenValue,
Token,
TokenGroup,
TokenType,
Unit,
} from '@supernovaio/sdk-exporters';
import { TokenGroupRemoteModel } from '@supernovaio/sdk-exporters/build/sdk-typescript/src/model/groups/SDKTokenGroup';

const testDimension: DimensionTokenValue = {
measure: 32,
unit: Unit.pixels,
referencedTokenId: null,
};

const testString: StringTokenValue = {
text: '12',
referencedTokenId: null,
};

export const exampleMockedTokens = new Map<string, Token>();
exampleMockedTokens.set('dimensionRef', {
id: 'dimensionRef',
name: 'desktop',
tokenType: TokenType.dimension,
parentGroupId: '1',
origin: {
name: 'Grid/spacing/desktop',
},
value: testDimension,
} as DimensionToken);
exampleMockedTokens.set('stringRef', {
id: 'stringRef',
name: 'Columns',
tokenType: TokenType.string,
parentGroupId: '2',
origin: {
name: 'Grid/Columns',
},
value: testString,
} as StringToken);

const groupFunctions = {
addChild(): void {},
addChildren(): void {},
setParentGroupId(): void {},
setPath(): void {},
setSortOrder(): void {},
toMutatedObject(): TokenGroup {
return new TokenGroup({
id: this.id,
parentId: this.parentGroupId,
brandId: this.brandId,
tokenType: this.tokenType,
designSystemVersionId: this.designSystemVersionId,
isRoot: this.isRoot,
meta: {
name: this.name,
description: this.description,
},
childrenIds: this.childrenIds,
});
},
toWriteObject(): TokenGroupRemoteModel {
return {
id: this.id,
brandId: this.brandId,
designSystemVersionId: this.designSystemVersionId,
isRoot: this.isRoot,
tokenType: this.tokenType,
childrenIds: this.childrenIds,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
meta: {
name: this.name,
description: this.description,
},
};
},
};

export const exampleMockedGroups: TokenGroup[] = [
{
...groupFunctions,
id: '1',
idInVersion: 'idInVersionValue',
brandId: 'brandIdValue',
designSystemVersionId: 'designSystemVersionIdValue',
name: 'spacing',
description: '',
isRoot: false,
tokenType: TokenType.dimension,
childrenIds: ['dimensionRef'],
path: ['Grid'],
tokenIds: ['dimensionRef'],
subgroupIds: [],
parentGroupId: 'parent1',
sortOrder: -1,
createdAt: null,
updatedAt: null,
},
{
...groupFunctions,
id: '2',
idInVersion: 'idInVersionValue',
brandId: 'brandIdValue',
designSystemVersionId: 'designSystemVersionIdValue',
name: 'Grid',
description: '',
isRoot: false,
tokenType: TokenType.string,
childrenIds: ['stringRef'],
path: [],
tokenIds: ['stringRef'],
subgroupIds: [],
parentGroupId: 'parent2',
sortOrder: -1,
createdAt: null,
updatedAt: null,
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$my-var: (
color: #000,
background: #fff,
border: 1px solid #000,
) !default;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import fs from 'fs';
import path from 'path';
import { formatCSS } from '../cssFormatter';

const mockedUnformattedCSS = fs.readFileSync(path.join(__dirname, '../__fixtures__/unformattedExample.scss'), 'utf-8');

const mockedFormattedCSS = fs.readFileSync(path.join(__dirname, '../__fixtures__/formattedExample.scss'), 'utf-8');

describe('formatCSS', () => {
it('should correctly format CSS string', () => {
expect(formatCSS(mockedUnformattedCSS)).toBe(mockedFormattedCSS);
});
});
33 changes: 33 additions & 0 deletions exporters/variables-scss/src/formatters/cssFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const IDENTATION = ' ';

export const removeExtraBlankLines = (css: string): string => {
return css.replace(/\n{3,}/g, '\n\n');
};

export const formatLinesAtEndOfTheFile = (css: string): string => {
return css.replace(/\n{2,}$/, '\n');
};

export const formatCSS = (css: string): string => {
let indentationLevel = 0;
let formattedCSS = '';

const lines = css.split('\n');

for (const line of lines) {
if (line.includes('(')) {
indentationLevel += 1;
formattedCSS += `${line}\n`;
} else if (line.includes(')')) {
indentationLevel -= 1;
formattedCSS += `${IDENTATION.repeat(indentationLevel)}${line}\n`;
} else {
formattedCSS += `${IDENTATION.repeat(indentationLevel)}${line}\n`;
}
}

formattedCSS = removeExtraBlankLines(formattedCSS);
formattedCSS = formatLinesAtEndOfTheFile(formattedCSS);

return formattedCSS;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import fs from 'fs';
import path from 'path';
import { Token, TokenGroup, TokenType } from '@supernovaio/sdk-exporters';
import { generateFileContent, addDisclaimer, filterTokensByTypeAndGroup } from '../contentGenerator';
import { exampleMockedGroups, exampleMockedTokens } from '../../formatters/__fixtures__/mockedExampleTokens';

const mockedExpectedResult = fs.readFileSync(
path.join(__dirname, '../../formatters/__fixtures__/exampleFileContent.scss'),
'utf-8',
);
const mappedTokens: Map<string, Token> = new Map([]);
const tokenGroups: Array<TokenGroup> = exampleMockedGroups;

describe('contentGenerator', () => {
describe('generateFileContent', () => {
it('should generate file content', () => {
const tokens = Array.from(exampleMockedTokens.values());
const tokenTypes = [TokenType.dimension, TokenType.string];
const groupNames = ['Grid', 'String'];
const withCssObject = true;
const hasParentPrefix = true;

const fileContent = generateFileContent(
tokens,
mappedTokens,
tokenGroups,
tokenTypes,
groupNames,
withCssObject,
hasParentPrefix,
);

expect(fileContent).toStrictEqual({ content: mockedExpectedResult });
});
});

describe('addDisclaimer', () => {
it('should add disclaimer to the top of the content', () => {
const content = '/* This is a test content */';
const expectedContent = `/* This file was generated by Supernova, don't change manually */\n${content}`;

expect(addDisclaimer(content)).toBe(expectedContent);
});
});

describe('filterTokensByTypeAndGroup', () => {
const dataProviderItems = [
{
type: TokenType.dimension,
group: 'Grid',
tokenIdentifier: 'dimensionRef',
description: 'dimension token type and Grid group',
},
{
type: TokenType.string,
group: 'Grid',
tokenIdentifier: 'stringRef',
description: 'string token type and Grid group',
},
];

it.each(dataProviderItems)('should filter $description', ({ type, group, tokenIdentifier }) => {
const tokens = Array.from(exampleMockedTokens.values());
const expectedTokens = [exampleMockedTokens.get(tokenIdentifier) as Token];

expect(filterTokensByTypeAndGroup(tokens, type, group)).toStrictEqual(expectedTokens);
});
});
});
Loading

0 comments on commit 59f8021

Please sign in to comment.