@advantacode/brander 0.1.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/dist/setup.js ADDED
@@ -0,0 +1,153 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { generateTokens } from "./generate-tokens.js";
4
+ const defaultSetupOutputDir = path.join("src", "brander");
5
+ const defaultStyleCandidates = [
6
+ path.join("src", "style.css"),
7
+ path.join("src", "main.css"),
8
+ path.join("src", "index.css"),
9
+ path.join("src", "app.css"),
10
+ path.join("resources", "css", "app.css")
11
+ ];
12
+ export async function setupProject(options) {
13
+ const resolvedOutputDir = options.outputDir ?? defaultSetupOutputDir;
14
+ const scriptName = options.scriptName ?? "brand:generate";
15
+ const notes = [];
16
+ if (!options.skipConfig) {
17
+ const configResult = ensureBrandConfig();
18
+ notes.push(configResult.message);
19
+ }
20
+ if (!options.skipScript) {
21
+ const scriptResult = ensurePackageScript(scriptName, buildGenerateCommand({
22
+ ...options,
23
+ outputDir: resolvedOutputDir
24
+ }));
25
+ notes.push(scriptResult.message);
26
+ }
27
+ if (!options.skipImports) {
28
+ const styleResult = ensureStyleImports(options.stylePath, resolvedOutputDir);
29
+ notes.push(styleResult.message);
30
+ }
31
+ if (!options.skipGenerate) {
32
+ await generateTokens({
33
+ outputDir: resolvedOutputDir,
34
+ formats: options.formats,
35
+ theme: options.theme,
36
+ prefix: options.prefix
37
+ });
38
+ notes.push(`Generated tokens in ${resolvedOutputDir}.`);
39
+ }
40
+ console.log(`✔ AdvantaCode Brander ${options.command} complete.`);
41
+ for (const note of notes) {
42
+ console.log(` - ${note}`);
43
+ }
44
+ }
45
+ function ensureBrandConfig() {
46
+ const configPath = path.resolve(process.cwd(), "brand.config.ts");
47
+ if (fs.existsSync(configPath)) {
48
+ return { message: "Kept existing brand.config.ts." };
49
+ }
50
+ fs.writeFileSync(configPath, getDefaultBrandConfigTemplate());
51
+ return { message: "Created brand.config.ts." };
52
+ }
53
+ function ensurePackageScript(scriptName, command) {
54
+ const packageJsonPath = path.resolve(process.cwd(), "package.json");
55
+ if (!fs.existsSync(packageJsonPath)) {
56
+ return { message: "Skipped package.json script update because package.json was not found." };
57
+ }
58
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
59
+ const scripts = packageJson.scripts ?? {};
60
+ if (scripts[scriptName] === command) {
61
+ return { message: `Kept existing "${scriptName}" script.` };
62
+ }
63
+ if (scriptName in scripts && scripts[scriptName] !== command) {
64
+ return { message: `Skipped "${scriptName}" because package.json already defines it.` };
65
+ }
66
+ packageJson.scripts = {
67
+ ...scripts,
68
+ [scriptName]: command
69
+ };
70
+ fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
71
+ return { message: `Added "${scriptName}" script to package.json.` };
72
+ }
73
+ function ensureStyleImports(stylePath, outputDir) {
74
+ const resolvedStylePath = resolveStylePath(stylePath);
75
+ if (!resolvedStylePath) {
76
+ return {
77
+ message: "Skipped stylesheet imports because no stylesheet was found. Use --style <path> to target a file explicitly."
78
+ };
79
+ }
80
+ const styleFileContents = fs.readFileSync(resolvedStylePath, "utf8");
81
+ const importLines = [
82
+ buildImportLine(resolvedStylePath, path.join(outputDir, "tokens.css")),
83
+ buildImportLine(resolvedStylePath, path.join(outputDir, "themes", "light.css")),
84
+ buildImportLine(resolvedStylePath, path.join(outputDir, "themes", "dark.css"))
85
+ ];
86
+ const missingImports = importLines.filter((importLine) => !styleFileContents.includes(importLine));
87
+ if (missingImports.length === 0) {
88
+ return { message: `Kept existing token imports in ${path.relative(process.cwd(), resolvedStylePath)}.` };
89
+ }
90
+ const nextContents = `${missingImports.join("\n")}\n${styleFileContents}`;
91
+ fs.writeFileSync(resolvedStylePath, nextContents);
92
+ return { message: `Added token imports to ${path.relative(process.cwd(), resolvedStylePath)}.` };
93
+ }
94
+ function resolveStylePath(stylePath) {
95
+ if (stylePath) {
96
+ const candidatePath = path.resolve(process.cwd(), stylePath);
97
+ if (!fs.existsSync(candidatePath)) {
98
+ throw new Error(`Unable to find stylesheet "${stylePath}".`);
99
+ }
100
+ return candidatePath;
101
+ }
102
+ const existingCandidates = defaultStyleCandidates
103
+ .map((candidate) => path.resolve(process.cwd(), candidate))
104
+ .filter((candidatePath) => fs.existsSync(candidatePath));
105
+ if (existingCandidates.length === 1) {
106
+ return existingCandidates[0];
107
+ }
108
+ if (existingCandidates.length > 1) {
109
+ throw new Error(`Multiple stylesheet candidates were found: ${existingCandidates
110
+ .map((candidatePath) => path.relative(process.cwd(), candidatePath))
111
+ .join(", ")}. Use --style <path> to choose one.`);
112
+ }
113
+ return undefined;
114
+ }
115
+ function buildImportLine(stylePath, targetPath) {
116
+ const relativeImportPath = path.relative(path.dirname(stylePath), path.resolve(process.cwd(), targetPath)).replace(/\\/g, "/");
117
+ const normalizedImportPath = relativeImportPath.startsWith(".") ? relativeImportPath : `./${relativeImportPath}`;
118
+ return `@import '${normalizedImportPath}';`;
119
+ }
120
+ function buildGenerateCommand(options) {
121
+ const commandParts = ["advantacode-brander"];
122
+ const outputDir = options.outputDir ?? defaultSetupOutputDir;
123
+ commandParts.push("--out", outputDir);
124
+ if (options.formats && options.formats.length > 0) {
125
+ commandParts.push("--format", options.formats.join(","));
126
+ }
127
+ if (options.theme && options.theme !== "both") {
128
+ commandParts.push("--theme", options.theme);
129
+ }
130
+ if (options.prefix) {
131
+ commandParts.push("--prefix", options.prefix);
132
+ }
133
+ return commandParts.join(" ");
134
+ }
135
+ function getDefaultBrandConfigTemplate() {
136
+ return `export default {
137
+ name: process.env.COMPANY_NAME || "My Company",
138
+ css: {
139
+ prefix: process.env.CSS_PREFIX ?? ""
140
+ },
141
+ colors: {
142
+ primary: process.env.PRIMARY_COLOR || "amber-500",
143
+ secondary: process.env.SECONDARY_COLOR || "zinc-700",
144
+ neutral: process.env.NEUTRAL_COLOR || process.env.SECONDARY_COLOR || "zinc-700",
145
+ accent: process.env.ACCENT_COLOR || "amber-400",
146
+ info: process.env.INFO_COLOR || "sky-500",
147
+ success: process.env.SUCCESS_COLOR || "green-500",
148
+ warning: process.env.WARNING_COLOR || "yellow-500",
149
+ danger: process.env.DANGER_COLOR || "red-500"
150
+ }
151
+ };
152
+ `;
153
+ }
@@ -0,0 +1,288 @@
1
+ export const tailwindColors = {
2
+ slate: {
3
+ 50: "#f8fafc",
4
+ 100: "#f1f5f9",
5
+ 200: "#e2e8f0",
6
+ 300: "#cbd5e1",
7
+ 400: "#94a3b8",
8
+ 500: "#64748b",
9
+ 600: "#475569",
10
+ 700: "#334155",
11
+ 800: "#1e293b",
12
+ 900: "#0f172a",
13
+ 950: "#020617"
14
+ },
15
+ gray: {
16
+ 50: "#f9fafb",
17
+ 100: "#f3f4f6",
18
+ 200: "#e5e7eb",
19
+ 300: "#d1d5db",
20
+ 400: "#9ca3af",
21
+ 500: "#6b7280",
22
+ 600: "#4b5563",
23
+ 700: "#374151",
24
+ 800: "#1f2937",
25
+ 900: "#111827",
26
+ 950: "#030712"
27
+ },
28
+ zinc: {
29
+ 50: "#fafafa",
30
+ 100: "#f4f4f5",
31
+ 200: "#e4e4e7",
32
+ 300: "#d4d4d8",
33
+ 400: "#a1a1aa",
34
+ 500: "#71717a",
35
+ 600: "#52525b",
36
+ 700: "#3f3f46",
37
+ 800: "#27272a",
38
+ 900: "#18181b",
39
+ 950: "#09090b"
40
+ },
41
+ neutral: {
42
+ 50: "#fafafa",
43
+ 100: "#f5f5f5",
44
+ 200: "#e5e5e5",
45
+ 300: "#d4d4d4",
46
+ 400: "#a3a3a3",
47
+ 500: "#737373",
48
+ 600: "#525252",
49
+ 700: "#404040",
50
+ 800: "#262626",
51
+ 900: "#171717",
52
+ 950: "#0a0a0a"
53
+ },
54
+ stone: {
55
+ 50: "#fafaf9",
56
+ 100: "#f5f5f4",
57
+ 200: "#e7e5e4",
58
+ 300: "#d6d3d1",
59
+ 400: "#a8a29e",
60
+ 500: "#78716c",
61
+ 600: "#57534e",
62
+ 700: "#44403c",
63
+ 800: "#292524",
64
+ 900: "#1c1917",
65
+ 950: "#0c0a09"
66
+ },
67
+ red: {
68
+ 50: "#fef2f2",
69
+ 100: "#fee2e2",
70
+ 200: "#fecaca",
71
+ 300: "#fca5a5",
72
+ 400: "#f87171",
73
+ 500: "#ef4444",
74
+ 600: "#dc2626",
75
+ 700: "#b91c1c",
76
+ 800: "#991b1b",
77
+ 900: "#7f1d1d",
78
+ 950: "#450a0a"
79
+ },
80
+ orange: {
81
+ 50: "#fff7ed",
82
+ 100: "#ffedd5",
83
+ 200: "#fed7aa",
84
+ 300: "#fdba74",
85
+ 400: "#fb923c",
86
+ 500: "#f97316",
87
+ 600: "#ea580c",
88
+ 700: "#c2410c",
89
+ 800: "#9a3412",
90
+ 900: "#7c2d12",
91
+ 950: "#431407"
92
+ },
93
+ amber: {
94
+ 50: "#fffbeb",
95
+ 100: "#fef3c7",
96
+ 200: "#fde68a",
97
+ 300: "#fcd34d",
98
+ 400: "#fbbf24",
99
+ 500: "#f59e0b",
100
+ 600: "#d97706",
101
+ 700: "#b45309",
102
+ 800: "#92400e",
103
+ 900: "#78350f",
104
+ 950: "#451a03"
105
+ },
106
+ yellow: {
107
+ 50: "#fefce8",
108
+ 100: "#fef9c3",
109
+ 200: "#fef08a",
110
+ 300: "#fde047",
111
+ 400: "#facc15",
112
+ 500: "#eab308",
113
+ 600: "#ca8a04",
114
+ 700: "#a16207",
115
+ 800: "#854d0e",
116
+ 900: "#713f12",
117
+ 950: "#422006"
118
+ },
119
+ lime: {
120
+ 50: "#f7fee7",
121
+ 100: "#ecfccb",
122
+ 200: "#d9f99d",
123
+ 300: "#bef264",
124
+ 400: "#a3e635",
125
+ 500: "#84cc16",
126
+ 600: "#65a30d",
127
+ 700: "#4d7c0f",
128
+ 800: "#3f6212",
129
+ 900: "#365314",
130
+ 950: "#1a2e05"
131
+ },
132
+ green: {
133
+ 50: "#f0fdf4",
134
+ 100: "#dcfce7",
135
+ 200: "#bbf7d0",
136
+ 300: "#86efac",
137
+ 400: "#4ade80",
138
+ 500: "#22c55e",
139
+ 600: "#16a34a",
140
+ 700: "#15803d",
141
+ 800: "#166534",
142
+ 900: "#14532d",
143
+ 950: "#052e16"
144
+ },
145
+ emerald: {
146
+ 50: "#ecfdf5",
147
+ 100: "#d1fae5",
148
+ 200: "#a7f3d0",
149
+ 300: "#6ee7b7",
150
+ 400: "#34d399",
151
+ 500: "#10b981",
152
+ 600: "#059669",
153
+ 700: "#047857",
154
+ 800: "#065f46",
155
+ 900: "#064e3b",
156
+ 950: "#022c22"
157
+ },
158
+ teal: {
159
+ 50: "#f0fdfa",
160
+ 100: "#ccfbf1",
161
+ 200: "#99f6e4",
162
+ 300: "#5eead4",
163
+ 400: "#2dd4bf",
164
+ 500: "#14b8a6",
165
+ 600: "#0d9488",
166
+ 700: "#0f766e",
167
+ 800: "#115e59",
168
+ 900: "#134e4a",
169
+ 950: "#042f2e"
170
+ },
171
+ cyan: {
172
+ 50: "#ecfeff",
173
+ 100: "#cffafe",
174
+ 200: "#a5f3fc",
175
+ 300: "#67e8f9",
176
+ 400: "#22d3ee",
177
+ 500: "#06b6d4",
178
+ 600: "#0891b2",
179
+ 700: "#0e7490",
180
+ 800: "#155e75",
181
+ 900: "#164e63",
182
+ 950: "#083344"
183
+ },
184
+ sky: {
185
+ 50: "#f0f9ff",
186
+ 100: "#e0f2fe",
187
+ 200: "#bae6fd",
188
+ 300: "#7dd3fc",
189
+ 400: "#38bdf8",
190
+ 500: "#0ea5e9",
191
+ 600: "#0284c7",
192
+ 700: "#0369a1",
193
+ 800: "#075985",
194
+ 900: "#0c4a6e",
195
+ 950: "#082f49"
196
+ },
197
+ blue: {
198
+ 50: "#eff6ff",
199
+ 100: "#dbeafe",
200
+ 200: "#bfdbfe",
201
+ 300: "#93c5fd",
202
+ 400: "#60a5fa",
203
+ 500: "#3b82f6",
204
+ 600: "#2563eb",
205
+ 700: "#1d4ed8",
206
+ 800: "#1e40af",
207
+ 900: "#1e3a8a",
208
+ 950: "#172554"
209
+ },
210
+ indigo: {
211
+ 50: "#eef2ff",
212
+ 100: "#e0e7ff",
213
+ 200: "#c7d2fe",
214
+ 300: "#a5b4fc",
215
+ 400: "#818cf8",
216
+ 500: "#6366f1",
217
+ 600: "#4f46e5",
218
+ 700: "#4338ca",
219
+ 800: "#3730a3",
220
+ 900: "#312e81",
221
+ 950: "#1e1b4b"
222
+ },
223
+ violet: {
224
+ 50: "#f5f3ff",
225
+ 100: "#ede9fe",
226
+ 200: "#ddd6fe",
227
+ 300: "#c4b5fd",
228
+ 400: "#a78bfa",
229
+ 500: "#8b5cf6",
230
+ 600: "#7c3aed",
231
+ 700: "#6d28d9",
232
+ 800: "#5b21b6",
233
+ 900: "#4c1d95",
234
+ 950: "#2e1065"
235
+ },
236
+ purple: {
237
+ 50: "#faf5ff",
238
+ 100: "#f3e8ff",
239
+ 200: "#e9d5ff",
240
+ 300: "#d8b4fe",
241
+ 400: "#c084fc",
242
+ 500: "#a855f7",
243
+ 600: "#9333ea",
244
+ 700: "#7e22ce",
245
+ 800: "#6b21a8",
246
+ 900: "#581c87",
247
+ 950: "#3b0764"
248
+ },
249
+ fuchsia: {
250
+ 50: "#fdf4ff",
251
+ 100: "#fae8ff",
252
+ 200: "#f5d0fe",
253
+ 300: "#f0abfc",
254
+ 400: "#e879f9",
255
+ 500: "#d946ef",
256
+ 600: "#c026d3",
257
+ 700: "#a21caf",
258
+ 800: "#86198f",
259
+ 900: "#701a75",
260
+ 950: "#4a044e"
261
+ },
262
+ pink: {
263
+ 50: "#fdf2f8",
264
+ 100: "#fce7f3",
265
+ 200: "#fbcfe8",
266
+ 300: "#f9a8d4",
267
+ 400: "#f472b6",
268
+ 500: "#ec4899",
269
+ 600: "#db2777",
270
+ 700: "#be185d",
271
+ 800: "#9d174d",
272
+ 900: "#831843",
273
+ 950: "#500724"
274
+ },
275
+ rose: {
276
+ 50: "#fff1f2",
277
+ 100: "#ffe4e6",
278
+ 200: "#fecdd3",
279
+ 300: "#fda4af",
280
+ 400: "#fb7185",
281
+ 500: "#f43f5e",
282
+ 600: "#e11d48",
283
+ 700: "#be123c",
284
+ 800: "#9f1239",
285
+ 900: "#881337",
286
+ 950: "#4c0519"
287
+ }
288
+ };
@@ -0,0 +1,41 @@
1
+ # Contributing
2
+
3
+ Thank you for your interest in AdvantaCode Brander.
4
+
5
+ ## Governance Model
6
+
7
+ AdvantaCode Brander follows a **closed governance model**.
8
+
9
+ The project is maintained by AdvantaCode, and core development decisions are managed by the maintainer.
10
+
11
+ External pull requests may not be accepted in order to maintain consistent architecture and long-term project direction.
12
+
13
+ ## Issues and Feature Requests
14
+
15
+ Bug reports and feature suggestions are welcome.
16
+
17
+ Please use the GitHub issue templates when opening a bug report or feature request.
18
+
19
+ Bug reports should include:
20
+
21
+ - the problem
22
+ - reproduction steps
23
+ - expected behavior
24
+
25
+ Feature requests should explain:
26
+
27
+ - the problem you want to solve
28
+ - the proposed solution
29
+ - any alternatives considered
30
+
31
+ ## Development Documentation
32
+
33
+ For internal architecture and technical details, see:
34
+
35
+ [TECH_OVERVIEW.md](TECH_OVERVIEW.md)
36
+
37
+ ## Branding and Trademarks
38
+
39
+ Use of the AdvantaCode name, logos, package names, domains, and other brand identifiers is governed by the trademark policy.
40
+
41
+ See [TRADEMARKS.md](TRADEMARKS.md).