@cobalt-ui/core
Advanced tools
Comparing version 1.9.0 to 1.10.0
# @cobalt-ui/core | ||
## 1.10.0 | ||
### Minor Changes | ||
- [#231](https://github.com/drwpow/cobalt-ui/pull/231) [`6bd99785eb50af83c96a0d70bd78fe6c6ab88a19`](https://github.com/drwpow/cobalt-ui/commit/6bd99785eb50af83c96a0d70bd78fe6c6ab88a19) Thanks [@drwpow](https://github.com/drwpow)! - Support YAML parsing in core | ||
### Patch Changes | ||
- [#231](https://github.com/drwpow/cobalt-ui/pull/231) [`6bd99785eb50af83c96a0d70bd78fe6c6ab88a19`](https://github.com/drwpow/cobalt-ui/commit/6bd99785eb50af83c96a0d70bd78fe6c6ab88a19) Thanks [@drwpow](https://github.com/drwpow)! - ⚠️ Tiny breaking change: Remove index.min.js from package (not used by anything, and probably shouldn’t be used; just using default package entryfile will yield better results in all setups) | ||
- [#231](https://github.com/drwpow/cobalt-ui/pull/231) [`6bd99785eb50af83c96a0d70bd78fe6c6ab88a19`](https://github.com/drwpow/cobalt-ui/commit/6bd99785eb50af83c96a0d70bd78fe6c6ab88a19) Thanks [@drwpow](https://github.com/drwpow)! - Improve JSON parsing errors with json-parse | ||
## 1.9.0 | ||
@@ -4,0 +16,0 @@ |
@@ -7,2 +7,3 @@ /// <reference types="node" /> | ||
export { parse, type LintRule, type ParseOptions, type ParseResult } from './parse/index.js'; | ||
export * from './util.js'; | ||
export interface BuildResult { | ||
@@ -9,0 +10,0 @@ /** File to output inside config.outDir (ex: ./tokens.sass) */ |
@@ -27,2 +27,3 @@ /** | ||
export { parse } from './parse/index.js'; | ||
export * from './util.js'; | ||
export default { | ||
@@ -29,0 +30,0 @@ parse, |
import type { ParsedToken } from '../token.js'; | ||
import type { ParseColorOptions } from './tokens/color.js'; | ||
import { type ParseColorOptions } from './tokens/color.js'; | ||
import { type FigmaParseOptions } from './figma.js'; | ||
@@ -27,4 +27,4 @@ export interface ParseResult { | ||
} | ||
export declare function parse(rawTokens: unknown, options: ParseOptions): ParseResult; | ||
export declare function parse(rawTokens: unknown, options?: ParseOptions): ParseResult; | ||
/** given a string, find all {aliases} */ | ||
export declare function findAliases(input: string): string[]; |
import { cloneDeep, FG_YELLOW, getAliasID, invalidTokenIDError, isAlias, RESET } from '@cobalt-ui/utils'; | ||
import { isEmpty, isObj, splitType } from '../util.js'; | ||
import parseJSON from 'parse-json'; | ||
import yaml from 'yaml'; | ||
import { isEmpty, isJSON, isObj, splitType } from '../util.js'; | ||
import { normalizeBorderValue } from './tokens/border.js'; | ||
import { normalizeColorValue } from './tokens/color.js'; | ||
import { normalizeCubicBezierValue } from './tokens/cubic-bezier.js'; | ||
import { normalizeDimensionValue } from './tokens/dimension.js'; | ||
import { normalizeDurationValue } from './tokens/duration.js'; | ||
import { normalizeFontFamilyValue } from './tokens/fontFamily.js'; | ||
import { normalizeDurationValue } from './tokens/duration.js'; | ||
import { normalizeDimensionValue } from './tokens/dimension.js'; | ||
import { normalizeCubicBezierValue } from './tokens/cubic-bezier.js'; | ||
import { normalizeFontWeightValue } from './tokens/fontWeight.js'; | ||
import { normalizeGradientValue } from './tokens/gradient.js'; | ||
import { normalizeLinkValue } from './tokens/link.js'; | ||
import { normalizeNumberValue } from './tokens/number.js'; | ||
import { normalizeShadowValue } from './tokens/shadow.js'; | ||
import { normalizeStrokeStyleValue } from './tokens/stroke-style.js'; | ||
import { normalizeBorderValue } from './tokens/border.js'; | ||
import { normalizeTransitionValue } from './tokens/transition.js'; | ||
import { normalizeShadowValue } from './tokens/shadow.js'; | ||
import { normalizeGradientValue } from './tokens/gradient.js'; | ||
import { normalizeTypographyValue } from './tokens/typography.js'; | ||
import { normalizeFontWeightValue } from './tokens/fontWeight.js'; | ||
import { normalizeNumberValue } from './tokens/number.js'; | ||
import { convertTokensStudioFormat, isTokensStudioFormat } from './tokens-studio.js'; | ||
@@ -24,11 +26,32 @@ import { convertFigmaVariablesFormat, isFigmaVariablesFormat } from './figma.js'; | ||
const result = { result: { metadata: {}, tokens: [] } }; | ||
if (!rawTokens || typeof rawTokens !== 'object' || Array.isArray(rawTokens)) { | ||
errors.push(`Invalid schema type. Expected object, received "${Array.isArray(rawTokens) ? 'Array' : typeof rawTokens}"`); | ||
let tokensObj = rawTokens; | ||
if (typeof tokensObj === 'string') { | ||
if (isJSON(tokensObj)) { | ||
try { | ||
tokensObj = parseJSON(tokensObj); | ||
} | ||
catch (err) { | ||
result.errors = [String(err)]; | ||
return result; | ||
} | ||
} | ||
else { | ||
try { | ||
tokensObj = yaml.parse(tokensObj); | ||
} | ||
catch (err) { | ||
result.errors = [String(err)]; | ||
return result; | ||
} | ||
} | ||
} | ||
if (!tokensObj || typeof tokensObj !== 'object' || Array.isArray(tokensObj)) { | ||
errors.push(`Invalid schema. Expected JSON or YAML, received "${Array.isArray(tokensObj) ? 'Array' : typeof tokensObj}"`); | ||
result.errors = errors; | ||
return result; | ||
} | ||
let schema = rawTokens; | ||
let schema = tokensObj; | ||
// 0. handle Figma Variables format | ||
if (isFigmaVariablesFormat(rawTokens)) { | ||
const figmaTokensResult = convertFigmaVariablesFormat(rawTokens, options?.figma); | ||
if (isFigmaVariablesFormat(tokensObj)) { | ||
const figmaTokensResult = convertFigmaVariablesFormat(tokensObj, options?.figma); | ||
errors.push(...(figmaTokensResult.errors ?? [])); | ||
@@ -39,4 +62,4 @@ warnings.push(...(figmaTokensResult.warnings ?? [])); | ||
// 0. handle Tokens Studio for Figma format | ||
else if (isTokensStudioFormat(rawTokens)) { | ||
const tokensStudioResult = convertTokensStudioFormat(rawTokens); | ||
else if (isTokensStudioFormat(tokensObj)) { | ||
const tokensStudioResult = convertTokensStudioFormat(tokensObj); | ||
errors.push(...(tokensStudioResult.errors ?? [])); | ||
@@ -239,4 +262,4 @@ warnings.push(...(tokensStudioResult.warnings ?? [])); | ||
case 'color': { | ||
tokens[id].$value = normalizeColorValue(values[id], options.color); | ||
normalizeModes(id, (v) => normalizeColorValue(v, options.color)); | ||
tokens[id].$value = normalizeColorValue(values[id], options?.color); | ||
normalizeModes(id, (v) => normalizeColorValue(v, options?.color)); | ||
break; | ||
@@ -298,4 +321,4 @@ } | ||
case 'border': { | ||
tokens[id].$value = normalizeBorderValue(values[id], { color: options.color }); | ||
normalizeModes(id, (v) => normalizeBorderValue(v, { color: options.color })); | ||
tokens[id].$value = normalizeBorderValue(values[id], { color: options?.color }); | ||
normalizeModes(id, (v) => normalizeBorderValue(v, { color: options?.color })); | ||
break; | ||
@@ -311,4 +334,4 @@ } | ||
case 'shadow': { | ||
tokens[id].$value = normalizeShadowValue(values[id], { color: options.color }); | ||
normalizeModes(id, (v) => normalizeShadowValue(v, { color: options.color })); | ||
tokens[id].$value = normalizeShadowValue(values[id], { color: options?.color }); | ||
normalizeModes(id, (v) => normalizeShadowValue(v, { color: options?.color })); | ||
break; | ||
@@ -318,4 +341,4 @@ } | ||
case 'gradient': { | ||
tokens[id].$value = normalizeGradientValue(values[id], { color: options.color }); | ||
normalizeModes(id, (v) => normalizeGradientValue(v, { color: options.color })); | ||
tokens[id].$value = normalizeGradientValue(values[id], { color: options?.color }); | ||
normalizeModes(id, (v) => normalizeGradientValue(v, { color: options?.color })); | ||
break; | ||
@@ -322,0 +345,0 @@ } |
export declare function isObj(value: unknown): boolean; | ||
/** return true for undefined/null, and empty strings, arrays, and objects (numbers aren’t empty) */ | ||
export declare function isEmpty(value: unknown): boolean; | ||
/** determine using very advanced, sophisticated techniques whether a string is JSON or YAML */ | ||
export declare function isJSON(value: unknown): boolean; | ||
/** perform a specific operation given an unknown type */ | ||
@@ -5,0 +7,0 @@ export declare function splitType(input: unknown, ops: { |
@@ -20,2 +20,9 @@ export function isObj(value) { | ||
} | ||
/** determine using very advanced, sophisticated techniques whether a string is JSON or YAML */ | ||
export function isJSON(value) { | ||
if (typeof value !== 'string') { | ||
return false; | ||
} | ||
return value.trim()[0] === '{'; | ||
} | ||
/** perform a specific operation given an unknown type */ | ||
@@ -22,0 +29,0 @@ export function splitType(input, ops) { |
{ | ||
"name": "@cobalt-ui/core", | ||
"description": "Parser/validator for the Design Tokens Community Group (DTCG) standard.", | ||
"version": "1.9.0", | ||
"version": "1.10.0", | ||
"author": { | ||
@@ -35,17 +35,18 @@ "name": "Drew Powers", | ||
"@types/culori": "^2.1.0", | ||
"culori": "^4.0.1" | ||
"culori": "^4.0.1", | ||
"parse-json": "^8.1.0", | ||
"yaml": "^2.4.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.11.27", | ||
"esbuild": "^0.19.12", | ||
"vitest": "^1.3.1" | ||
"vitest": "^1.4.0" | ||
}, | ||
"scripts": { | ||
"build": "pnpm run build:clean && pnpm run build:ts && pnpm run build:bundle && pnpm run build:license", | ||
"build": "pnpm run build:clean && pnpm run build:ts && pnpm run build:license", | ||
"build:clean": "del dist", | ||
"build:ts": "tsc", | ||
"build:bundle": "esbuild --format=esm --bundle --minify dist/index.js --outfile=dist/index.min.js --sourcemap && cp dist/index.d.ts dist/index.min.d.ts", | ||
"build:license": "node ../../scripts/inject-license.js @cobalt-ui/core dist/index.js,dist/index.min.js", | ||
"build:ts": "tsc -p tsconfig.build.json", | ||
"build:license": "node ../../scripts/inject-license.js @cobalt-ui/core dist/index.js", | ||
"dev": "pnpm run --parallel \"/^dev:.*/\"", | ||
"dev:ts": "tsc --watch", | ||
"lint": "eslint \"{src,test}/**/*\"", | ||
"dev:ts": "tsc -p tsconfig.build.json --watch", | ||
"test": "pnpm run \"/^test:.*/\"", | ||
@@ -52,0 +53,0 @@ "test:js": "vitest run", |
@@ -48,2 +48,3 @@ import type { Group, ParsedToken } from './token.js'; | ||
export { parse, type LintRule, type ParseOptions, type ParseResult } from './parse/index.js'; | ||
export * from './util.js'; | ||
@@ -50,0 +51,0 @@ export interface BuildResult { |
import { cloneDeep, FG_YELLOW, getAliasID, invalidTokenIDError, isAlias, RESET } from '@cobalt-ui/utils'; | ||
import parseJSON from 'parse-json'; | ||
import yaml from 'yaml'; | ||
import type { Group, ParsedToken, TokenType, TokenOrGroup } from '../token.js'; | ||
import { isEmpty, isObj, splitType } from '../util.js'; | ||
import type { ParseColorOptions } from './tokens/color.js'; | ||
import { normalizeColorValue } from './tokens/color.js'; | ||
import { isEmpty, isJSON, isObj, splitType } from '../util.js'; | ||
import { normalizeBorderValue } from './tokens/border.js'; | ||
import { normalizeColorValue, type ParseColorOptions } from './tokens/color.js'; | ||
import { normalizeCubicBezierValue } from './tokens/cubic-bezier.js'; | ||
import { normalizeDimensionValue } from './tokens/dimension.js'; | ||
import { normalizeDurationValue } from './tokens/duration.js'; | ||
import { normalizeFontFamilyValue } from './tokens/fontFamily.js'; | ||
import { normalizeDurationValue } from './tokens/duration.js'; | ||
import { normalizeDimensionValue } from './tokens/dimension.js'; | ||
import { normalizeCubicBezierValue } from './tokens/cubic-bezier.js'; | ||
import { normalizeFontWeightValue } from './tokens/fontWeight.js'; | ||
import { normalizeGradientValue } from './tokens/gradient.js'; | ||
import { normalizeLinkValue } from './tokens/link.js'; | ||
import { normalizeNumberValue } from './tokens/number.js'; | ||
import { normalizeShadowValue } from './tokens/shadow.js'; | ||
import { normalizeStrokeStyleValue } from './tokens/stroke-style.js'; | ||
import { normalizeBorderValue } from './tokens/border.js'; | ||
import { normalizeTransitionValue } from './tokens/transition.js'; | ||
import { normalizeShadowValue } from './tokens/shadow.js'; | ||
import { normalizeGradientValue } from './tokens/gradient.js'; | ||
import { normalizeTypographyValue } from './tokens/typography.js'; | ||
import { normalizeFontWeightValue } from './tokens/fontWeight.js'; | ||
import { normalizeNumberValue } from './tokens/number.js'; | ||
import { convertTokensStudioFormat, isTokensStudioFormat } from './tokens-studio.js'; | ||
import type { FigmaVariableManifest } from './figma.js'; | ||
import { convertFigmaVariablesFormat, isFigmaVariablesFormat, type FigmaParseOptions } from './figma.js'; | ||
import { convertFigmaVariablesFormat, isFigmaVariablesFormat, type FigmaParseOptions, type FigmaVariableManifest } from './figma.js'; | ||
@@ -59,8 +59,29 @@ export interface ParseResult { | ||
export function parse(rawTokens: unknown, options: ParseOptions): ParseResult { | ||
export function parse(rawTokens: unknown, options?: ParseOptions): ParseResult { | ||
const errors: string[] = []; | ||
const warnings: string[] = []; | ||
const result: ParseResult = { result: { metadata: {}, tokens: [] } }; | ||
if (!rawTokens || typeof rawTokens !== 'object' || Array.isArray(rawTokens)) { | ||
errors.push(`Invalid schema type. Expected object, received "${Array.isArray(rawTokens) ? 'Array' : typeof rawTokens}"`); | ||
let tokensObj = rawTokens; | ||
if (typeof tokensObj === 'string') { | ||
if (isJSON(tokensObj)) { | ||
try { | ||
tokensObj = parseJSON(tokensObj); | ||
} catch (err) { | ||
result.errors = [String(err)]; | ||
return result; | ||
} | ||
} else { | ||
try { | ||
tokensObj = yaml.parse(tokensObj); | ||
} catch (err) { | ||
result.errors = [String(err)]; | ||
return result; | ||
} | ||
} | ||
} | ||
if (!tokensObj || typeof tokensObj !== 'object' || Array.isArray(tokensObj)) { | ||
errors.push(`Invalid schema. Expected JSON or YAML, received "${Array.isArray(tokensObj) ? 'Array' : typeof tokensObj}"`); | ||
result.errors = errors; | ||
@@ -70,7 +91,7 @@ return result; | ||
let schema = rawTokens as Group; | ||
let schema = tokensObj as Group; | ||
// 0. handle Figma Variables format | ||
if (isFigmaVariablesFormat(rawTokens)) { | ||
const figmaTokensResult = convertFigmaVariablesFormat(rawTokens as FigmaVariableManifest, options?.figma); | ||
if (isFigmaVariablesFormat(tokensObj)) { | ||
const figmaTokensResult = convertFigmaVariablesFormat(tokensObj as FigmaVariableManifest, options?.figma); | ||
errors.push(...(figmaTokensResult.errors ?? [])); | ||
@@ -82,4 +103,4 @@ warnings.push(...(figmaTokensResult.warnings ?? [])); | ||
// 0. handle Tokens Studio for Figma format | ||
else if (isTokensStudioFormat(rawTokens)) { | ||
const tokensStudioResult = convertTokensStudioFormat(rawTokens as Group); | ||
else if (isTokensStudioFormat(tokensObj)) { | ||
const tokensStudioResult = convertTokensStudioFormat(tokensObj as Group); | ||
errors.push(...(tokensStudioResult.errors ?? [])); | ||
@@ -290,4 +311,4 @@ warnings.push(...(tokensStudioResult.warnings ?? [])); | ||
case 'color': { | ||
tokens[id]!.$value = normalizeColorValue(values[id], options.color); | ||
normalizeModes(id, (v) => normalizeColorValue(v, options.color)); | ||
tokens[id]!.$value = normalizeColorValue(values[id], options?.color); | ||
normalizeModes(id, (v) => normalizeColorValue(v, options?.color)); | ||
break; | ||
@@ -349,4 +370,4 @@ } | ||
case 'border': { | ||
tokens[id]!.$value = normalizeBorderValue(values[id], { color: options.color }); | ||
normalizeModes(id, (v) => normalizeBorderValue(v, { color: options.color })); | ||
tokens[id]!.$value = normalizeBorderValue(values[id], { color: options?.color }); | ||
normalizeModes(id, (v) => normalizeBorderValue(v, { color: options?.color })); | ||
break; | ||
@@ -362,4 +383,4 @@ } | ||
case 'shadow': { | ||
tokens[id]!.$value = normalizeShadowValue(values[id], { color: options.color }); | ||
normalizeModes(id, (v) => normalizeShadowValue(v, { color: options.color })); | ||
tokens[id]!.$value = normalizeShadowValue(values[id], { color: options?.color }); | ||
normalizeModes(id, (v) => normalizeShadowValue(v, { color: options?.color })); | ||
break; | ||
@@ -369,4 +390,4 @@ } | ||
case 'gradient': { | ||
tokens[id]!.$value = normalizeGradientValue(values[id], { color: options.color }); | ||
normalizeModes(id, (v) => normalizeGradientValue(v, { color: options.color })); | ||
tokens[id]!.$value = normalizeGradientValue(values[id], { color: options?.color }); | ||
normalizeModes(id, (v) => normalizeGradientValue(v, { color: options?.color })); | ||
break; | ||
@@ -373,0 +394,0 @@ } |
@@ -22,2 +22,10 @@ export function isObj(value: unknown): boolean { | ||
/** determine using very advanced, sophisticated techniques whether a string is JSON or YAML */ | ||
export function isJSON(value: unknown) { | ||
if (typeof value !== 'string') { | ||
return false; | ||
} | ||
return value.trim()[0] === '{'; | ||
} | ||
/** perform a specific operation given an unknown type */ | ||
@@ -24,0 +32,0 @@ export function splitType( |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2
255468
5
87
5035
+ Addedparse-json@^8.1.0
+ Addedyaml@^2.4.1
+ Added@babel/code-frame@7.26.2(transitive)
+ Added@babel/helper-validator-identifier@7.25.9(transitive)
+ Addedindex-to-position@0.1.2(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedparse-json@8.1.0(transitive)
+ Addedpicocolors@1.1.1(transitive)
+ Addedtype-fest@4.33.0(transitive)
+ Addedyaml@2.7.0(transitive)