@clubz/cli 0.1.1 → 0.1.2

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.
@@ -9,6 +9,8 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
9
9
  const chalk_1 = __importDefault(require("chalk"));
10
10
  const child_process_1 = require("child_process");
11
11
  const archiver_1 = __importDefault(require("archiver"));
12
+ const axios_1 = __importDefault(require("axios"));
13
+ const form_data_1 = __importDefault(require("form-data"));
12
14
  async function deployCommand() {
13
15
  console.log(chalk_1.default.blue('šŸš€ Deploying Widget to Clubz...'));
14
16
  const cwd = process.cwd();
@@ -39,36 +41,38 @@ async function deployCommand() {
39
41
  }
40
42
  await zipDirectory(distDir, zipPath);
41
43
  console.log(chalk_1.default.green(` Bundle created: ${getSize(zipPath)}`));
42
- // 4. Upload (Mock for now, replacing previous simple push)
44
+ // 4. Upload to Clubz Registry
43
45
  console.log(chalk_1.default.yellow('\nā˜ļø Uploading to Clubz Registry...'));
44
46
  try {
47
+ // Load .env if present
48
+ const userEnvPath = path_1.default.join(cwd, '.env');
49
+ if (fs_extra_1.default.existsSync(userEnvPath)) {
50
+ require('dotenv').config({ path: userEnvPath });
51
+ }
45
52
  const apiKey = process.env.CLUBZ_API_KEY;
53
+ const apiUrl = process.env.CLUBZ_API_URL || 'http://localhost:3000'; // Default to Community Builder for now
46
54
  if (!apiKey) {
47
- console.warn(chalk_1.default.yellow('āš ļø No CLUBZ_API_KEY found in env. simulating upload...'));
55
+ console.error(chalk_1.default.red('āŒ Authentication required.'));
56
+ console.error(chalk_1.default.yellow(' Please add CLUBZ_API_KEY to your .env file.'));
57
+ process.exit(1);
48
58
  }
49
59
  const isSubmission = process.argv.includes('--submit');
50
60
  const status = isSubmission ? 'pending' : 'draft';
51
- // Real implementation would look like this:
52
- /*
53
- const form = new FormData();
54
- form.append('file', fs.createReadStream(zipPath));
61
+ const form = new form_data_1.default();
62
+ form.append('file', fs_extra_1.default.createReadStream(zipPath));
55
63
  form.append('manifest', JSON.stringify({ ...config, status }));
56
-
57
- await axios.post('http://localhost:3000/api/registry/deploy', form, {
64
+ const response = await axios_1.default.post(`${apiUrl}/api/registry/deploy`, form, {
58
65
  headers: {
59
66
  ...form.getHeaders(),
60
67
  'Authorization': `Bearer ${apiKey}`
61
- }
68
+ },
69
+ maxContentLength: Infinity,
70
+ maxBodyLength: Infinity
62
71
  });
63
- */
64
- // Simulating network delay
65
- await new Promise(r => setTimeout(r, 1500));
66
72
  console.log(chalk_1.default.green('\nāœ… Deployment Successful!'));
67
- console.log(chalk_1.default.cyan(` Widget ID: ${config.type}-${Date.now().toString().slice(-4)}`));
68
- console.log(chalk_1.default.cyan(` Version: ${config.version}`));
69
- if (config.tags && config.tags.length > 0) {
70
- console.log(chalk_1.default.cyan(` Tags: ${config.tags.join(', ')}`));
71
- }
73
+ console.log(chalk_1.default.cyan(` Widget ID: ${response.data.widgetId}`));
74
+ console.log(chalk_1.default.cyan(` Version: ${response.data.version}`));
75
+ console.log(chalk_1.default.dim(` Download URL: ${response.data.url}`));
72
76
  if (isSubmission) {
73
77
  console.log(chalk_1.default.magenta(' šŸš€ Submitted for validation (Status: Pending)'));
74
78
  console.log(chalk_1.default.dim(' An admin will review your widget shortly.'));
@@ -81,7 +85,14 @@ async function deployCommand() {
81
85
  await fs_extra_1.default.remove(zipPath);
82
86
  }
83
87
  catch (error) {
84
- console.error(chalk_1.default.red('āŒ Upload failed'), error.message);
88
+ console.error(chalk_1.default.red('āŒ Upload failed'));
89
+ if (error.response) {
90
+ console.error(chalk_1.default.red(` Server Error: ${error.response.status} ${error.response.statusText}`));
91
+ console.error(chalk_1.default.red(` ${JSON.stringify(error.response.data)}`));
92
+ }
93
+ else {
94
+ console.error(chalk_1.default.red(` ${error.message}`));
95
+ }
85
96
  process.exit(1);
86
97
  }
87
98
  }
@@ -9,11 +9,19 @@ const express_1 = __importDefault(require("express"));
9
9
  const cross_spawn_1 = __importDefault(require("cross-spawn"));
10
10
  const chalk_1 = __importDefault(require("chalk"));
11
11
  const fs_1 = __importDefault(require("fs"));
12
- // In CommonJS (which we compile to), __dirname is available globally
13
- // const __filename = fileURLToPath(import.meta.url); // Not needed
14
- // const __dirname = path.dirname(__filename); // Not needed
12
+ const dotenv_1 = __importDefault(require("dotenv"));
13
+ const axios_1 = __importDefault(require("axios"));
15
14
  async function devCommand() {
16
15
  console.log(chalk_1.default.blue('šŸš€ Starting Clubz Development Environment...'));
16
+ // 0. Load Environment Variables from the User's Project
17
+ const userEnvPath = path_1.default.join(process.cwd(), '.env');
18
+ if (fs_1.default.existsSync(userEnvPath)) {
19
+ dotenv_1.default.config({ path: userEnvPath });
20
+ console.log(chalk_1.default.green('āœ… Loaded .env file'));
21
+ }
22
+ else {
23
+ console.log(chalk_1.default.yellow('āš ļø No .env file found. API Key integration will be disabled.'));
24
+ }
17
25
  // 1. Start User's Widget Server (Vite)
18
26
  const widgetPort = 3001;
19
27
  console.log(chalk_1.default.dim(` Starting widget server on port ${widgetPort}...`));
@@ -26,24 +34,45 @@ async function devCommand() {
26
34
  });
27
35
  // 2. Start Simulator Server
28
36
  const app = (0, express_1.default)();
29
- const simulatorPort = 3000;
37
+ const simulatorPort = 3002; // Changed from 3000 to avoid conflict with API
38
+ const realApiUrl = process.env.CLUBZ_API_URL || 'http://localhost:3000';
39
+ // API Route for Simulator to get Configuration
40
+ app.get('/simulator/api/config', async (req, res) => {
41
+ const apiKey = process.env.CLUBZ_API_KEY;
42
+ let user = null;
43
+ if (apiKey) {
44
+ try {
45
+ // Determine if apiKey is a JWT or a special key.
46
+ // For now, assuming it's a Bearer Token (Personal Access Token)
47
+ const response = await axios_1.default.get(`${realApiUrl}/api/auth/me`, {
48
+ headers: { Authorization: `Bearer ${apiKey}` }
49
+ });
50
+ user = response.data;
51
+ // Add role/permissions if needed
52
+ }
53
+ catch (error) {
54
+ console.error(chalk_1.default.red('āŒ Failed to validate API Key:'), error.message);
55
+ // Don't fail the request, just return guest mode with error
56
+ }
57
+ }
58
+ res.json({
59
+ user: user || { id: 'guest', name: 'Guest Developer', role: 'guest' },
60
+ mode: apiKey ? 'authenticated' : 'guest',
61
+ apiUrl: realApiUrl
62
+ });
63
+ });
30
64
  // Resolve path to built simulator client assets
31
- // In dist structure: dist/src/commands/dev.js -> dist/simulator/client
32
- // adjustable based on actual build output structure
33
65
  let simulatorDist = path_1.default.join(__dirname, '../../simulator/client');
34
- // Fallback for dev execution (ts-node)
35
66
  if (!fs_1.default.existsSync(simulatorDist) || !fs_1.default.existsSync(path_1.default.join(simulatorDist, 'index.html'))) {
36
- // If not built, maybe we can warn or try source (but source needs building)
37
- // Check relative to src: src/commands/dev.ts -> src/simulator/client (source)
38
- // For now, let's assume we need to build it.
39
- // We can point to a mocked path or ensure build happens.
40
67
  console.warn(chalk_1.default.yellow('āš ļø Simulator build not found. Ensure CLI is built.'));
41
- // Try pointing to package root dist if structure is flattened
42
68
  simulatorDist = path_1.default.join(__dirname, '../../../dist/simulator/client');
43
69
  }
44
70
  app.use(express_1.default.static(simulatorDist));
45
- // Fallback to index.html for SPA routing
46
71
  app.get('*', (req, res) => {
72
+ // handle api routes not found
73
+ if (req.path.startsWith('/simulator/api')) {
74
+ return res.status(404).json({ error: 'Not Found' });
75
+ }
47
76
  res.sendFile(path_1.default.join(simulatorDist, 'index.html'));
48
77
  });
49
78
  app.listen(simulatorPort, () => {
@@ -51,7 +80,6 @@ async function devCommand() {
51
80
  console.log(chalk_1.default.cyan(` Widget running at http://localhost:${widgetPort}`));
52
81
  console.log(chalk_1.default.dim(' Press Ctrl+C to stop.'));
53
82
  });
54
- // Handle cleanup
55
83
  process.on('SIGINT', () => {
56
84
  widgetProcess.kill();
57
85
  process.exit();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "My Amazing Widget",
3
3
  "description": "A widget built for Clubz",
4
- "version": "1.0.0",
4
+ "version": "0.0.1",
5
5
  "type": "widget",
6
6
  "config": {
7
7
  "props": [
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "my-clubz-widget",
3
3
  "private": true,
4
- "version": "0.0.0",
4
+ "version": "0.0.1",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "build": "tsc && vite build",
9
+ "deploy": "clubz deploy --submit",
9
10
  "preview": "vite preview"
10
11
  },
11
12
  "dependencies": {
@@ -0,0 +1,33 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": [
6
+ "ES2020",
7
+ "DOM",
8
+ "DOM.Iterable"
9
+ ],
10
+ "module": "ESNext",
11
+ "skipLibCheck": true,
12
+ /* Bundler mode */
13
+ "moduleResolution": "bundler",
14
+ "allowImportingTsExtensions": true,
15
+ "resolveJsonModule": true,
16
+ "isolatedModules": true,
17
+ "noEmit": true,
18
+ "jsx": "react-jsx",
19
+ /* Linting */
20
+ "strict": true,
21
+ "noUnusedLocals": true,
22
+ "noUnusedParameters": true,
23
+ "noFallthroughCasesInSwitch": true
24
+ },
25
+ "include": [
26
+ "src"
27
+ ],
28
+ "references": [
29
+ {
30
+ "path": "./tsconfig.node.json"
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true
8
+ },
9
+ "include": [
10
+ "vite.config.ts"
11
+ ]
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clubz/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "bin": {
5
5
  "clubz": "bin/clubz.js"
6
6
  },
@@ -22,6 +22,7 @@
22
22
  "chalk": "^4.1.2",
23
23
  "commander": "^11.0.0",
24
24
  "cross-spawn": "^7.0.6",
25
+ "dotenv": "^17.2.4",
25
26
  "express": "^5.2.1",
26
27
  "form-data": "^4.0.5",
27
28
  "fs-extra": "^11.3.3",
@@ -42,41 +42,45 @@ export async function deployCommand() {
42
42
  await zipDirectory(distDir, zipPath);
43
43
  console.log(chalk.green(` Bundle created: ${getSize(zipPath)}`));
44
44
 
45
- // 4. Upload (Mock for now, replacing previous simple push)
45
+ // 4. Upload to Clubz Registry
46
46
  console.log(chalk.yellow('\nā˜ļø Uploading to Clubz Registry...'));
47
47
 
48
48
  try {
49
+ // Load .env if present
50
+ const userEnvPath = path.join(cwd, '.env');
51
+ if (fs.existsSync(userEnvPath)) {
52
+ require('dotenv').config({ path: userEnvPath });
53
+ }
54
+
49
55
  const apiKey = process.env.CLUBZ_API_KEY;
56
+ const apiUrl = process.env.CLUBZ_API_URL || 'http://localhost:3000'; // Default to Community Builder for now
57
+
50
58
  if (!apiKey) {
51
- console.warn(chalk.yellow('āš ļø No CLUBZ_API_KEY found in env. simulating upload...'));
59
+ console.error(chalk.red('āŒ Authentication required.'));
60
+ console.error(chalk.yellow(' Please add CLUBZ_API_KEY to your .env file.'));
61
+ process.exit(1);
52
62
  }
53
63
 
54
64
  const isSubmission = process.argv.includes('--submit');
55
65
  const status = isSubmission ? 'pending' : 'draft';
56
66
 
57
- // Real implementation would look like this:
58
- /*
59
67
  const form = new FormData();
60
68
  form.append('file', fs.createReadStream(zipPath));
61
69
  form.append('manifest', JSON.stringify({ ...config, status }));
62
-
63
- await axios.post('http://localhost:3000/api/registry/deploy', form, {
64
- headers: {
70
+
71
+ const response = await axios.post(`${apiUrl}/api/registry/deploy`, form, {
72
+ headers: {
65
73
  ...form.getHeaders(),
66
74
  'Authorization': `Bearer ${apiKey}`
67
- }
75
+ },
76
+ maxContentLength: Infinity,
77
+ maxBodyLength: Infinity
68
78
  });
69
- */
70
-
71
- // Simulating network delay
72
- await new Promise(r => setTimeout(r, 1500));
73
79
 
74
80
  console.log(chalk.green('\nāœ… Deployment Successful!'));
75
- console.log(chalk.cyan(` Widget ID: ${config.type}-${Date.now().toString().slice(-4)}`));
76
- console.log(chalk.cyan(` Version: ${config.version}`));
77
- if (config.tags && config.tags.length > 0) {
78
- console.log(chalk.cyan(` Tags: ${config.tags.join(', ')}`));
79
- }
81
+ console.log(chalk.cyan(` Widget ID: ${response.data.widgetId}`));
82
+ console.log(chalk.cyan(` Version: ${response.data.version}`));
83
+ console.log(chalk.dim(` Download URL: ${response.data.url}`));
80
84
 
81
85
  if (isSubmission) {
82
86
  console.log(chalk.magenta(' šŸš€ Submitted for validation (Status: Pending)'));
@@ -91,7 +95,13 @@ export async function deployCommand() {
91
95
  await fs.remove(zipPath);
92
96
 
93
97
  } catch (error: any) {
94
- console.error(chalk.red('āŒ Upload failed'), error.message);
98
+ console.error(chalk.red('āŒ Upload failed'));
99
+ if (error.response) {
100
+ console.error(chalk.red(` Server Error: ${error.response.status} ${error.response.statusText}`));
101
+ console.error(chalk.red(` ${JSON.stringify(error.response.data)}`));
102
+ } else {
103
+ console.error(chalk.red(` ${error.message}`));
104
+ }
95
105
  process.exit(1);
96
106
  }
97
107
  }
@@ -3,14 +3,21 @@ import express from 'express';
3
3
  import spawn from 'cross-spawn';
4
4
  import chalk from 'chalk';
5
5
  import fs from 'fs';
6
-
7
- // In CommonJS (which we compile to), __dirname is available globally
8
- // const __filename = fileURLToPath(import.meta.url); // Not needed
9
- // const __dirname = path.dirname(__filename); // Not needed
6
+ import dotenv from 'dotenv';
7
+ import axios from 'axios';
10
8
 
11
9
  export async function devCommand() {
12
10
  console.log(chalk.blue('šŸš€ Starting Clubz Development Environment...'));
13
11
 
12
+ // 0. Load Environment Variables from the User's Project
13
+ const userEnvPath = path.join(process.cwd(), '.env');
14
+ if (fs.existsSync(userEnvPath)) {
15
+ dotenv.config({ path: userEnvPath });
16
+ console.log(chalk.green('āœ… Loaded .env file'));
17
+ } else {
18
+ console.log(chalk.yellow('āš ļø No .env file found. API Key integration will be disabled.'));
19
+ }
20
+
14
21
  // 1. Start User's Widget Server (Vite)
15
22
  const widgetPort = 3001;
16
23
  console.log(chalk.dim(` Starting widget server on port ${widgetPort}...`));
@@ -26,28 +33,51 @@ export async function devCommand() {
26
33
 
27
34
  // 2. Start Simulator Server
28
35
  const app = express();
29
- const simulatorPort = 3000;
36
+ const simulatorPort = 3002; // Changed from 3000 to avoid conflict with API
37
+ const realApiUrl = process.env.CLUBZ_API_URL || 'http://localhost:3000';
38
+
39
+ // API Route for Simulator to get Configuration
40
+ app.get('/simulator/api/config', async (req, res) => {
41
+ const apiKey = process.env.CLUBZ_API_KEY;
42
+ let user = null;
43
+
44
+ if (apiKey) {
45
+ try {
46
+ // Determine if apiKey is a JWT or a special key.
47
+ // For now, assuming it's a Bearer Token (Personal Access Token)
48
+ const response = await axios.get(`${realApiUrl}/api/auth/me`, {
49
+ headers: { Authorization: `Bearer ${apiKey}` }
50
+ });
51
+ user = response.data;
52
+ // Add role/permissions if needed
53
+ } catch (error: any) {
54
+ console.error(chalk.red('āŒ Failed to validate API Key:'), error.message);
55
+ // Don't fail the request, just return guest mode with error
56
+ }
57
+ }
58
+
59
+ res.json({
60
+ user: user || { id: 'guest', name: 'Guest Developer', role: 'guest' },
61
+ mode: apiKey ? 'authenticated' : 'guest',
62
+ apiUrl: realApiUrl
63
+ });
64
+ });
30
65
 
31
66
  // Resolve path to built simulator client assets
32
- // In dist structure: dist/src/commands/dev.js -> dist/simulator/client
33
- // adjustable based on actual build output structure
34
67
  let simulatorDist = path.join(__dirname, '../../simulator/client');
35
68
 
36
- // Fallback for dev execution (ts-node)
37
69
  if (!fs.existsSync(simulatorDist) || !fs.existsSync(path.join(simulatorDist, 'index.html'))) {
38
- // If not built, maybe we can warn or try source (but source needs building)
39
- // Check relative to src: src/commands/dev.ts -> src/simulator/client (source)
40
- // For now, let's assume we need to build it.
41
- // We can point to a mocked path or ensure build happens.
42
70
  console.warn(chalk.yellow('āš ļø Simulator build not found. Ensure CLI is built.'));
43
- // Try pointing to package root dist if structure is flattened
44
71
  simulatorDist = path.join(__dirname, '../../../dist/simulator/client');
45
72
  }
46
73
 
47
74
  app.use(express.static(simulatorDist));
48
75
 
49
- // Fallback to index.html for SPA routing
50
76
  app.get('*', (req, res) => {
77
+ // handle api routes not found
78
+ if (req.path.startsWith('/simulator/api')) {
79
+ return res.status(404).json({ error: 'Not Found' });
80
+ }
51
81
  res.sendFile(path.join(simulatorDist, 'index.html'));
52
82
  });
53
83
 
@@ -57,7 +87,6 @@ export async function devCommand() {
57
87
  console.log(chalk.dim(' Press Ctrl+C to stop.'));
58
88
  });
59
89
 
60
- // Handle cleanup
61
90
  process.on('SIGINT', () => {
62
91
  widgetProcess.kill();
63
92
  process.exit();
@@ -9,12 +9,29 @@ export default function SimulatorApp() {
9
9
  // State
10
10
  const [widgetUrl, setWidgetUrl] = useState('http://localhost:3001'); // Default widget port
11
11
  const [logs, setLogs] = useState<{ time: string, type: 'req' | 'res', msg: string }[]>([]);
12
+ const [userContext, setUserContext] = useState<any>({ id: 'sim-user-1', name: 'Simulator User (Guest)', role: 'guest' });
13
+ const [authStatus, setAuthStatus] = useState<'loading' | 'authenticated' | 'guest'>('loading');
12
14
 
13
15
  // Iframe ref to send responses back
14
16
  const iframeRef = useRef<HTMLIFrameElement>(null);
15
17
 
16
- // Initial load
18
+ // Initial load & Config Fetch
17
19
  useEffect(() => {
20
+ // Fetch Simulator Config
21
+ fetch('/simulator/api/config')
22
+ .then(res => res.json())
23
+ .then(data => {
24
+ if (data.user) {
25
+ setUserContext(data.user);
26
+ }
27
+ setAuthStatus(data.mode);
28
+ log('sys', `Loaded configuration: ${data.mode}`);
29
+ })
30
+ .catch(err => {
31
+ console.error('Failed to load simulator config', err);
32
+ setAuthStatus('guest');
33
+ });
34
+
18
35
  const handleMessage = (event: MessageEvent) => {
19
36
  const data = event.data as BridgeRequest;
20
37
 
@@ -31,7 +48,15 @@ export default function SimulatorApp() {
31
48
  return () => window.removeEventListener('message', handleMessage);
32
49
  }, []);
33
50
 
34
- const log = (type: 'req' | 'res', msg: string) => {
51
+ // Update handler to use current state (via ref or dependency)
52
+ // Actually we need to be careful with stale closures in event listeners.
53
+ // The easiest way is to use a ref for userContext or pass it to the handler if it was stable.
54
+ // But since the listener is added once, it will see stale userContext.
55
+ // Let's use a ref for userContext.
56
+ const userContextRef = useRef(userContext);
57
+ useEffect(() => { userContextRef.current = userContext; }, [userContext]);
58
+
59
+ const log = (type: 'req' | 'res' | 'sys', msg: string) => {
35
60
  setLogs(prev => [{
36
61
  time: new Date().toLocaleTimeString().split(' ')[0],
37
62
  type,
@@ -45,7 +70,8 @@ export default function SimulatorApp() {
45
70
 
46
71
  switch (req.action) {
47
72
  case 'GET_USER':
48
- responseData = { id: 'sim-user-1', name: 'Simulator User', role: 'admin' };
73
+ // Use the ref to get the latest user context
74
+ responseData = userContextRef.current;
49
75
  break;
50
76
  case 'VIBRATE':
51
77
  // Visual feedback
@@ -90,7 +116,14 @@ export default function SimulatorApp() {
90
116
  />
91
117
  </div>
92
118
  </div>
93
- <p className="mt-4 text-slate-400 text-sm">iPhone 14 Pro Simulator</p>
119
+ <div className="mt-4 text-center">
120
+ <p className="text-slate-400 text-sm">iPhone 14 Pro Simulator</p>
121
+ <div className="mt-2 text-xs">
122
+ Status: <span className={authStatus === 'authenticated' ? 'text-green-600 font-bold' : 'text-orange-500'}>
123
+ {authStatus === 'authenticated' ? 'Logged In' : 'Guest Mode'}
124
+ </span>
125
+ </div>
126
+ </div>
94
127
  </div>
95
128
 
96
129
  {/* Right: Debug Console */}
@@ -114,8 +147,11 @@ export default function SimulatorApp() {
114
147
  {logs.map((l, i) => (
115
148
  <div key={i} className="flex gap-2">
116
149
  <span className="text-slate-500">[{l.time}]</span>
117
- <span className={l.type === 'req' ? 'text-blue-400' : 'text-green-400'}>
118
- {l.type === 'req' ? '→' : '←'}
150
+ <span className={
151
+ l.type === 'req' ? 'text-blue-400' :
152
+ l.type === 'res' ? 'text-green-400' : 'text-yellow-400'
153
+ }>
154
+ {l.type === 'req' ? '→' : l.type === 'res' ? '←' : '•'}
119
155
  </span>
120
156
  <span className="text-slate-300 break-all">{l.msg}</span>
121
157
  </div>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "My Amazing Widget",
3
3
  "description": "A widget built for Clubz",
4
- "version": "1.0.0",
4
+ "version": "0.0.1",
5
5
  "type": "widget",
6
6
  "config": {
7
7
  "props": [
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "my-clubz-widget",
3
3
  "private": true,
4
- "version": "0.0.0",
4
+ "version": "0.0.1",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "build": "tsc && vite build",
9
+ "deploy": "clubz deploy --submit",
9
10
  "preview": "vite preview"
10
11
  },
11
12
  "dependencies": {
@@ -0,0 +1,33 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": [
6
+ "ES2020",
7
+ "DOM",
8
+ "DOM.Iterable"
9
+ ],
10
+ "module": "ESNext",
11
+ "skipLibCheck": true,
12
+ /* Bundler mode */
13
+ "moduleResolution": "bundler",
14
+ "allowImportingTsExtensions": true,
15
+ "resolveJsonModule": true,
16
+ "isolatedModules": true,
17
+ "noEmit": true,
18
+ "jsx": "react-jsx",
19
+ /* Linting */
20
+ "strict": true,
21
+ "noUnusedLocals": true,
22
+ "noUnusedParameters": true,
23
+ "noFallthroughCasesInSwitch": true
24
+ },
25
+ "include": [
26
+ "src"
27
+ ],
28
+ "references": [
29
+ {
30
+ "path": "./tsconfig.node.json"
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true
8
+ },
9
+ "include": [
10
+ "vite.config.ts"
11
+ ]
12
+ }