@webmate-studio/cli 0.3.7 → 0.3.9

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/bin/wm.mjs CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { Command } from 'commander';
4
4
  import { buildCommand } from '../src/commands/build.js';
5
- import { pushCommand } from '../src/commands/push.js';
6
5
  import { devCommand } from '../src/commands/dev.js';
7
6
  import { initCommand } from '../src/commands/init.js';
8
7
  import { loginCommand } from '../src/commands/login.js';
@@ -58,28 +57,15 @@ program
58
57
  .option('-o, --open', 'Open browser automatically')
59
58
  .action(devCommand);
60
59
 
61
- // wm build - Build components
60
+ // wm build - Build components (for local testing only - deployment via GitHub)
62
61
  program
63
62
  .command('build')
64
- .description('Build components for production')
63
+ .description('Build components for production (local testing only)')
65
64
  .option('-o, --output <dir>', 'Output directory', './dist')
66
65
  .option('-m, --minify', 'Minify output')
67
66
  .option('--watch', 'Watch for changes')
68
67
  .action(buildCommand);
69
68
 
70
- // wm push - Upload to CMS
71
- program
72
- .command('push')
73
- .description('Upload components to CMS (auto-builds by default)')
74
- .option('-t, --target <url>', 'CMS target URL')
75
- .option('--token <token>', 'Authentication token')
76
- .option('-f, --force', 'Overwrite existing version (development only)')
77
- .option('--patch', 'Increment patch version (x.y.Z)')
78
- .option('--minor', 'Increment minor version (x.Y.0)')
79
- .option('--major', 'Increment major version (X.0.0)')
80
- .option('--no-build', 'Skip auto-build, use existing dist/ (for CI/CD)')
81
- .action(pushCommand);
82
-
83
69
  // wm logout - Logout from CMS
84
70
  program
85
71
  .command('logout')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webmate-studio/cli",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio CLI - Build and manage your Webmate components",
6
6
  "keywords": [
@@ -34,7 +34,7 @@
34
34
  "@webmate-studio/builder": "^0.2.1",
35
35
  "@webmate-studio/core": "^0.2.0",
36
36
  "@webmate-studio/parser": "^0.2.1",
37
- "@webmate-studio/preview": "^0.2.3",
37
+ "@webmate-studio/preview": "^0.2.7",
38
38
  "alpinejs": "^3.15.0",
39
39
  "commander": "^11.0.0",
40
40
  "esbuild": "^0.19.0",
@@ -1,275 +0,0 @@
1
- import { uploadComponents, logger } from '@webmate-studio/core';
2
- import { loadAuth, getTenantCmsUrl, getApiToken, isLoggedIn } from '../utils/auth.js';
3
- import { loadConfig, updateConfigVersion } from '../utils/config.js';
4
- import { incrementPatch, incrementMinor, incrementMajor } from '../utils/semver.js';
5
- import { build as buildComponents } from '@webmate-studio/builder';
6
- import { existsSync, readFileSync, statSync, readdirSync } from 'fs';
7
- import { join } from 'path';
8
- import { select } from '@inquirer/prompts';
9
- import ora from 'ora';
10
- import pc from 'picocolors';
11
-
12
- /**
13
- * Load design tokens from CMS
14
- */
15
- async function loadDesignTokens() {
16
- try {
17
- const auth = loadAuth();
18
- if (!auth || !auth.apiToken) {
19
- return null;
20
- }
21
-
22
- const cmsUrl = getTenantCmsUrl();
23
- if (!cmsUrl) {
24
- return null;
25
- }
26
-
27
- // Disable SSL verification for localhost
28
- const isLocalhost = cmsUrl.includes('localhost') || cmsUrl.includes('127.0.0.1');
29
- if (isLocalhost) {
30
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
31
- }
32
-
33
- const response = await fetch(`${cmsUrl}/api/design-tokens`, {
34
- headers: {
35
- 'x-api-token': auth.apiToken
36
- }
37
- });
38
-
39
- if (!response.ok) {
40
- return null;
41
- }
42
-
43
- const data = await response.json();
44
-
45
- // Restore SSL verification
46
- if (isLocalhost) {
47
- delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
48
- }
49
-
50
- return data.tokens || null;
51
- } catch (error) {
52
- return null;
53
- }
54
- }
55
-
56
- /**
57
- * Check if build is stale (source files newer than build)
58
- */
59
- function isBuildStale(config) {
60
- const distDir = config.output.dir;
61
- const componentsDir = config.components.path;
62
-
63
- const manifestPath = join(distDir, 'manifest.json');
64
- if (!existsSync(manifestPath)) {
65
- return true; // No build exists
66
- }
67
-
68
- try {
69
- const manifestStat = statSync(manifestPath);
70
- const manifestTime = manifestStat.mtimeMs;
71
-
72
- // Check if any component file is newer than manifest
73
- const componentFiles = readdirSync(componentsDir, { recursive: true, withFileTypes: true });
74
- for (const file of componentFiles) {
75
- if (file.isFile() && (file.name.endsWith('.html') || file.name.endsWith('.js'))) {
76
- const filePath = join(file.path, file.name);
77
- const fileStat = statSync(filePath);
78
- if (fileStat.mtimeMs > manifestTime) {
79
- return true; // Source file is newer
80
- }
81
- }
82
- }
83
-
84
- return false; // Build is up to date
85
- } catch (error) {
86
- return true; // On error, assume stale
87
- }
88
- }
89
-
90
- /**
91
- * Push command - upload built components to CMS
92
- * Auto-builds unless --no-build is specified
93
- */
94
- export async function pushCommand(options) {
95
- const config = await loadConfig();
96
- const distDir = config.output.dir;
97
- const manifestPath = join(distDir, 'manifest.json');
98
-
99
- // Auto-build unless --no-build is specified
100
- // Commander sets build: false when --no-build is used
101
- if (options.build === false) {
102
- // --no-build flag: Check if build exists
103
- if (!existsSync(manifestPath)) {
104
- logger.error('No build found and --no-build specified.');
105
- logger.info('Run `wm build` first or remove --no-build flag.');
106
- process.exit(1);
107
- }
108
- logger.info('Using existing build (--no-build).');
109
- } else {
110
- // Auto-build mode (default)
111
- const buildExists = existsSync(manifestPath);
112
- const buildStale = buildExists ? isBuildStale(config) : true;
113
-
114
- if (!buildExists) {
115
- logger.info('No build found. Building components...');
116
- } else if (buildStale) {
117
- logger.info('Source files changed. Rebuilding components...');
118
- } else {
119
- logger.info('Using existing build (up to date).');
120
- }
121
-
122
- if (!buildExists || buildStale) {
123
- const buildSpinner = ora('Building components...').start();
124
- try {
125
- await buildComponents({
126
- outputDir: config.output.dir,
127
- minify: config.output.minify || false,
128
- designTokens: await loadDesignTokens()
129
- });
130
- buildSpinner.succeed('Build complete!');
131
- } catch (error) {
132
- buildSpinner.fail('Build failed');
133
- logger.error(error.message);
134
- process.exit(1);
135
- }
136
- }
137
- }
138
-
139
- const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
140
-
141
- // Get target and token - prefer auth over config
142
- let target;
143
- let token;
144
-
145
- // Use auth credentials if logged in (priority!)
146
- if (isLoggedIn()) {
147
- const auth = loadAuth();
148
- target = options.target || getTenantCmsUrl();
149
- token = options.token || getApiToken();
150
-
151
- console.log('');
152
- logger.info(`Using logged in project: ${pc.cyan(auth.tenant.name)}`);
153
- logger.info(`Target: ${pc.cyan(target)}`);
154
- } else {
155
- // Not logged in - require explicit options
156
- target = options.target;
157
- token = options.token || process.env.CMS_TOKEN;
158
-
159
- if (!target) {
160
- logger.error('Not logged in and no target URL specified.');
161
- logger.info('Either run `wm login` first or use --target option');
162
- process.exit(1);
163
- }
164
-
165
- if (!token) {
166
- logger.error('Not authenticated.');
167
- logger.info('Run `wm login` first or set CMS_TOKEN env variable');
168
- process.exit(1);
169
- }
170
- }
171
-
172
- // Determine new version
173
- const currentVersion = config.version || '0.1.0';
174
- let newVersion;
175
- let shouldUpdateConfig = false;
176
-
177
- if (options.force) {
178
- // Force mode: Keep current version, overwrite
179
- newVersion = currentVersion;
180
- logger.info(`Version: ${pc.cyan(currentVersion)} ${pc.dim('(force overwrite)')}`);
181
- } else if (options.patch) {
182
- // Explicit patch increment
183
- newVersion = incrementPatch(currentVersion);
184
- shouldUpdateConfig = true;
185
- logger.info(`Version: ${pc.cyan(currentVersion)} → ${pc.cyan(newVersion)} ${pc.dim('(patch)')}`);
186
- } else if (options.minor) {
187
- // Explicit minor increment
188
- newVersion = incrementMinor(currentVersion);
189
- shouldUpdateConfig = true;
190
- logger.info(`Version: ${pc.cyan(currentVersion)} → ${pc.cyan(newVersion)} ${pc.dim('(minor)')}`);
191
- } else if (options.major) {
192
- // Explicit major increment
193
- newVersion = incrementMajor(currentVersion);
194
- shouldUpdateConfig = true;
195
- logger.info(`Version: ${pc.cyan(currentVersion)} → ${pc.cyan(newVersion)} ${pc.dim('(major)')}`);
196
- } else {
197
- // Interactive prompt
198
- console.log('');
199
- const choice = await select({
200
- message: `Current version: ${pc.cyan(currentVersion)}. How do you want to publish?`,
201
- choices: [
202
- {
203
- name: `Patch (${pc.cyan(incrementPatch(currentVersion))}) - Bug fixes, small changes`,
204
- value: 'patch',
205
- description: 'Backwards compatible bug fixes'
206
- },
207
- {
208
- name: `Minor (${pc.cyan(incrementMinor(currentVersion))}) - New features, backwards compatible`,
209
- value: 'minor',
210
- description: 'New functionality, backwards compatible'
211
- },
212
- {
213
- name: `Major (${pc.cyan(incrementMajor(currentVersion))}) - Breaking changes`,
214
- value: 'major',
215
- description: 'Breaking changes, incompatible with previous versions'
216
- },
217
- {
218
- name: `Force (${pc.cyan(currentVersion)}) - Overwrite current version ${pc.dim('(development only)')}`,
219
- value: 'force',
220
- description: 'Overwrite existing version without incrementing'
221
- }
222
- ]
223
- });
224
-
225
- if (choice === 'patch') {
226
- newVersion = incrementPatch(currentVersion);
227
- shouldUpdateConfig = true;
228
- } else if (choice === 'minor') {
229
- newVersion = incrementMinor(currentVersion);
230
- shouldUpdateConfig = true;
231
- } else if (choice === 'major') {
232
- newVersion = incrementMajor(currentVersion);
233
- shouldUpdateConfig = true;
234
- } else if (choice === 'force') {
235
- newVersion = currentVersion;
236
- shouldUpdateConfig = false;
237
- options.force = true; // Enable force mode
238
- }
239
-
240
- console.log('');
241
- logger.info(`Publishing version: ${pc.cyan(newVersion)}`);
242
- }
243
-
244
- // Update manifest with new version
245
- manifest.version = newVersion;
246
-
247
- const spinner = ora(`Uploading to ${target}...`).start();
248
-
249
- try {
250
- await uploadComponents(distDir, target, token, {
251
- force: options.force || false,
252
- version: newVersion
253
- });
254
-
255
- spinner.succeed('Upload complete!');
256
-
257
- // Update config file with new version (only if not force mode)
258
- if (shouldUpdateConfig) {
259
- try {
260
- updateConfigVersion(newVersion);
261
- logger.success(`Updated wm.config.js with version ${pc.cyan(newVersion)}`);
262
- } catch (err) {
263
- logger.warn(`Could not update config file: ${err.message}`);
264
- }
265
- }
266
-
267
- logger.success(`\n✅ Uploaded ${manifest.components.length} components to ${target}`);
268
- logger.info(`Version: ${pc.cyan(newVersion)}`);
269
- logger.info('Components are now available in your CMS.');
270
- } catch (error) {
271
- spinner.fail('Upload failed');
272
- logger.error(error.message);
273
- process.exit(1);
274
- }
275
- }