@styleframe/cli 2.3.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @styleframe/cli
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#117](https://github.com/styleframe-dev/styleframe/pull/117) [`ffe6764`](https://github.com/styleframe-dev/styleframe/commit/ffe6764a2e6c84d5b3cfdf431bf11f17a3f3f118) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Introduce global Styleframe single-instance architecture. Extension files (`*.styleframe.ts`) now share the same instance created in `styleframe.config.ts` instead of creating independent instances. This is a breaking change that affects how styles are imported and composed across files.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`ffe6764`](https://github.com/styleframe-dev/styleframe/commit/ffe6764a2e6c84d5b3cfdf431bf11f17a3f3f118)]:
12
+ - @styleframe/loader@3.0.0
13
+ - @styleframe/figma@1.0.1
14
+
15
+ ## 2.4.0
16
+
17
+ ### Minor Changes
18
+
19
+ - [#83](https://github.com/styleframe-dev/styleframe/pull/83) [`6deddfd`](https://github.com/styleframe-dev/styleframe/commit/6deddfd7a97df13a7fcb865dbf088995f79bd4f3) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add Figma plugin for syncing Styleframe variables with Figma variables and CLI commands for Figma import/export
20
+
21
+ ## 2.3.3
22
+
23
+ ### Patch Changes
24
+
25
+ - [#102](https://github.com/styleframe-dev/styleframe/pull/102) [`90c3ae8`](https://github.com/styleframe-dev/styleframe/commit/90c3ae8dd19a688f88d1b362af6bef732de988d6) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add `@styleframe/license` dependency and move runtime to production dependencies in init command
26
+
3
27
  ## 2.3.2
4
28
 
5
29
  ### Patch Changes
@@ -0,0 +1,49 @@
1
+ import path from "node:path";
2
+ import { l as loadConfiguration, b as build$1 } from "./index-DtEAy_us.js";
3
+ import { defineCommand } from "citty";
4
+ import consola from "consola";
5
+ const build = defineCommand({
6
+ meta: {
7
+ name: "build",
8
+ description: "Build Styleframe project from source files"
9
+ },
10
+ args: {
11
+ entry: {
12
+ type: "positional",
13
+ description: "Entry point file(s) for the build",
14
+ default: "styleframe.config.ts",
15
+ valueHint: "path"
16
+ },
17
+ outputDir: {
18
+ type: "string",
19
+ description: "Output directory for built files",
20
+ default: "styleframe",
21
+ alias: ["o", "out"],
22
+ valueHint: "path"
23
+ },
24
+ clean: {
25
+ type: "boolean",
26
+ description: "Clean output directory before build",
27
+ default: false
28
+ }
29
+ },
30
+ async run({ args }) {
31
+ consola.info(
32
+ `Loading configuration from "${path.relative(process.cwd(), path.resolve(args.entry))}"...`
33
+ );
34
+ const instance = await loadConfiguration({ entry: args.entry });
35
+ consola.info("Building styleframe...");
36
+ try {
37
+ await build$1(instance, {
38
+ outputDir: args.outputDir,
39
+ clean: args.clean
40
+ });
41
+ consola.success("Styleframe built successfully!");
42
+ } catch (error) {
43
+ consola.error("Failed to build Styleframe:", error);
44
+ }
45
+ }
46
+ });
47
+ export {
48
+ build as default
49
+ };
@@ -0,0 +1,139 @@
1
+ import path from "node:path";
2
+ import { writeFile } from "node:fs/promises";
3
+ import { l as loadConfiguration } from "./index-DtEAy_us.js";
4
+ import { defineCommand } from "citty";
5
+ import consola from "consola";
6
+ import { d as detectFigmaType, s as styleframeValueToFigma, a as styleframeToFigmaName, t as toDTCG } from "./index-C3Gqfamh.js";
7
+ const _export = defineCommand({
8
+ meta: {
9
+ name: "export",
10
+ description: "Export Styleframe variables to DTCG format JSON"
11
+ },
12
+ args: {
13
+ config: {
14
+ type: "string",
15
+ description: "Path to the Styleframe config file",
16
+ default: "styleframe.config.ts",
17
+ alias: ["c"],
18
+ valueHint: "path"
19
+ },
20
+ output: {
21
+ type: "string",
22
+ description: "Output JSON file path",
23
+ default: "tokens.json",
24
+ alias: ["o"],
25
+ valueHint: "path"
26
+ },
27
+ collection: {
28
+ type: "string",
29
+ description: "Name for the Figma collection",
30
+ default: "Design Tokens",
31
+ alias: ["n", "name"]
32
+ },
33
+ baseFontSize: {
34
+ type: "string",
35
+ description: "Base font size for rem conversion (in pixels)",
36
+ default: "16"
37
+ }
38
+ },
39
+ async run({ args }) {
40
+ const configPath = path.resolve(args.config);
41
+ const outputPath = path.resolve(args.output);
42
+ const baseFontSize = Number.parseInt(args.baseFontSize, 10) || 16;
43
+ consola.info(
44
+ `Loading configuration from "${path.relative(process.cwd(), configPath)}"...`
45
+ );
46
+ const instance = await loadConfiguration({ entry: configPath });
47
+ const root = instance.root;
48
+ consola.info("Extracting variables...");
49
+ const modes = ["Default", ...root.themes.map((t) => capitalize(t.name))];
50
+ const variableMap = /* @__PURE__ */ new Map();
51
+ for (const variable of root.variables) {
52
+ if (!variableMap.has(variable.name)) {
53
+ variableMap.set(variable.name, /* @__PURE__ */ new Map());
54
+ }
55
+ const modeValues = variableMap.get(variable.name);
56
+ modeValues.set("Default", resolveValue(variable.value));
57
+ }
58
+ for (const theme of root.themes) {
59
+ const modeName = capitalize(theme.name);
60
+ for (const variable of theme.variables) {
61
+ if (!variableMap.has(variable.name)) {
62
+ variableMap.set(variable.name, /* @__PURE__ */ new Map());
63
+ }
64
+ const modeValues = variableMap.get(variable.name);
65
+ modeValues.set(modeName, resolveValue(variable.value));
66
+ }
67
+ }
68
+ const variables = [];
69
+ for (const [name, modeValues] of variableMap) {
70
+ const defaultValue = modeValues.get("Default");
71
+ if (defaultValue === void 0) continue;
72
+ const type = detectFigmaType(defaultValue);
73
+ const figmaValues = {};
74
+ for (const [modeName, value] of modeValues) {
75
+ const figmaValue = styleframeValueToFigma(value, type, baseFontSize);
76
+ if (figmaValue !== null) {
77
+ figmaValues[modeName] = figmaValue;
78
+ }
79
+ }
80
+ const rawDefaultValue = getRawValue(
81
+ root.variables.find((v) => v.name === name)?.value
82
+ );
83
+ const isReference = isReferenceValue(rawDefaultValue);
84
+ const aliasTo = isReference ? getReferenceName(rawDefaultValue) : void 0;
85
+ variables.push({
86
+ name: styleframeToFigmaName(name),
87
+ styleframeName: name,
88
+ type,
89
+ values: figmaValues,
90
+ aliasTo
91
+ });
92
+ }
93
+ const intermediateData = {
94
+ collection: args.collection,
95
+ modes,
96
+ variables
97
+ };
98
+ const themeNames = root.themes.map((t) => capitalize(t.name));
99
+ const dtcgData = toDTCG(intermediateData, { themeNames });
100
+ consola.info(
101
+ `Writing ${variables.length} variables to "${path.relative(process.cwd(), outputPath)}"...`
102
+ );
103
+ await writeFile(outputPath, JSON.stringify(dtcgData, null, 2));
104
+ consola.success(
105
+ `Exported ${variables.length} variables in DTCG format to "${path.relative(process.cwd(), outputPath)}"`
106
+ );
107
+ }
108
+ });
109
+ function capitalize(str) {
110
+ return str.charAt(0).toUpperCase() + str.slice(1);
111
+ }
112
+ function resolveValue(value) {
113
+ if (value === null || value === void 0) return value;
114
+ if (typeof value !== "object") return value;
115
+ if ("type" in value) {
116
+ if (value.type === "reference") {
117
+ return value.fallback ?? "";
118
+ }
119
+ if (value.type === "css") {
120
+ return value.value.map((v) => resolveValue(v)).join("");
121
+ }
122
+ }
123
+ if (Array.isArray(value)) {
124
+ return value.map((v) => resolveValue(v)).join("");
125
+ }
126
+ return String(value);
127
+ }
128
+ function getRawValue(value) {
129
+ return value ?? "";
130
+ }
131
+ function isReferenceValue(value) {
132
+ return typeof value === "object" && value !== null && "type" in value && value.type === "reference";
133
+ }
134
+ function getReferenceName(value) {
135
+ return value.name;
136
+ }
137
+ export {
138
+ _export as default
139
+ };
@@ -0,0 +1,90 @@
1
+ import path from "node:path";
2
+ import { readFile, writeFile } from "node:fs/promises";
3
+ import { defineCommand } from "citty";
4
+ import consola from "consola";
5
+ import { f as fromDTCG, g as generateStyleframeCode } from "./index-C3Gqfamh.js";
6
+ const _import = defineCommand({
7
+ meta: {
8
+ name: "import",
9
+ description: "Generate Styleframe code from DTCG format JSON"
10
+ },
11
+ args: {
12
+ input: {
13
+ type: "string",
14
+ description: "Input DTCG JSON file path",
15
+ required: true,
16
+ alias: ["i"],
17
+ valueHint: "path"
18
+ },
19
+ output: {
20
+ type: "string",
21
+ description: "Output Styleframe TypeScript file path",
22
+ default: "tokens.styleframe.ts",
23
+ alias: ["o"],
24
+ valueHint: "path"
25
+ },
26
+ composables: {
27
+ type: "boolean",
28
+ description: "Use @styleframe/theme composables (useColor, useSpacing, etc.)",
29
+ default: true
30
+ },
31
+ rem: {
32
+ type: "boolean",
33
+ description: "Use rem units for dimensions instead of px",
34
+ default: false
35
+ },
36
+ baseFontSize: {
37
+ type: "string",
38
+ description: "Base font size for rem conversion (in pixels)",
39
+ default: "16"
40
+ },
41
+ instanceName: {
42
+ type: "string",
43
+ description: "Name for the Styleframe instance variable",
44
+ default: "s"
45
+ }
46
+ },
47
+ async run({ args }) {
48
+ const inputPath = path.resolve(args.input);
49
+ const outputPath = path.resolve(args.output);
50
+ const baseFontSize = Number.parseInt(args.baseFontSize, 10) || 16;
51
+ consola.info(
52
+ `Reading JSON from "${path.relative(process.cwd(), inputPath)}"...`
53
+ );
54
+ let data;
55
+ try {
56
+ const content = await readFile(inputPath, "utf-8");
57
+ const rawData = JSON.parse(content);
58
+ data = fromDTCG(rawData);
59
+ } catch (error) {
60
+ consola.error(
61
+ `Failed to read or parse input file: ${error instanceof Error ? error.message : error}`
62
+ );
63
+ process.exit(1);
64
+ }
65
+ consola.info(
66
+ `Generating Styleframe code for ${data.variables.length} variables...`
67
+ );
68
+ const result = generateStyleframeCode(data, {
69
+ useComposables: args.composables,
70
+ useRem: args.rem,
71
+ baseFontSize,
72
+ instanceName: args.instanceName
73
+ });
74
+ consola.info(`Writing to "${path.relative(process.cwd(), outputPath)}"...`);
75
+ await writeFile(outputPath, result.code);
76
+ consola.success(`Generated Styleframe code with:`);
77
+ consola.info(` - ${result.variables.length} variables`);
78
+ consola.info(` - ${result.themes.length} theme(s)`);
79
+ if (args.composables && result.imports.length > 1) {
80
+ consola.info(
81
+ ` - Using composables: ${result.imports.slice(1).join(", ")}`
82
+ );
83
+ }
84
+ consola.info(`
85
+ Output: ${path.relative(process.cwd(), outputPath)}`);
86
+ }
87
+ });
88
+ export {
89
+ _import as default
90
+ };