@reveldigital/gadgetizer 1.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/README.md +126 -0
- package/cli.js +255 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# 🚀 Revel Digital Gadgetizer
|
|
2
|
+
|
|
3
|
+
A command-line tool for integrating the Revel Digital client SDK into existing Angular, Vue, React, or vanilla JavaScript projects. This tool automates the setup process and generates the necessary configuration files for deploying your application as a Revel Digital gadget.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
Install globally via npm:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @reveldigital/gadgetizer
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or use directly with npx:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx @reveldigital/gadgetizer
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 🎯 Usage
|
|
20
|
+
|
|
21
|
+
Navigate to your existing project directory and run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gadgetizer
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The tool will guide you through the setup process with interactive prompts.
|
|
28
|
+
|
|
29
|
+
### Command Options
|
|
30
|
+
|
|
31
|
+
- `--help`, `-h` - Show help message
|
|
32
|
+
- `--build-only` - Run only the XML build step (skips SDK installation)
|
|
33
|
+
|
|
34
|
+
### Examples
|
|
35
|
+
|
|
36
|
+
Basic usage:
|
|
37
|
+
```bash
|
|
38
|
+
cd my-react-app
|
|
39
|
+
gadgetizer
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Build XML only (useful for CI/CD):
|
|
43
|
+
```bash
|
|
44
|
+
gadgetizer --build-only
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Show help:
|
|
48
|
+
```bash
|
|
49
|
+
gadgetizer --help
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## ⚡ What It Does
|
|
53
|
+
|
|
54
|
+
The Gadgetizer tool performs the following actions based on your project type:
|
|
55
|
+
|
|
56
|
+
### For Angular Projects
|
|
57
|
+
- Installs `@reveldigital/player-client@latest`
|
|
58
|
+
- Runs the Angular schematic: `ng add @reveldigital/player-client@latest`
|
|
59
|
+
|
|
60
|
+
### For React, Vue, and Vanilla JavaScript Projects
|
|
61
|
+
- Copies `gadget.yaml` configuration file to your project root (if not already present)
|
|
62
|
+
- Prompts for deployment URL configuration
|
|
63
|
+
- Installs the following dependencies:
|
|
64
|
+
- `@reveldigital/client-sdk`
|
|
65
|
+
- `@reveldigital/gadget-types`
|
|
66
|
+
- Adds a `build:gadget` script to your `package.json`
|
|
67
|
+
- Generates XML gadget configuration file in your build directory
|
|
68
|
+
|
|
69
|
+
## 📁 Project Structure
|
|
70
|
+
|
|
71
|
+
After running the tool, your project will have:
|
|
72
|
+
|
|
73
|
+
- 📄 `gadget.yaml` - Gadget configuration file
|
|
74
|
+
- 📦 Updated `package.json` with Revel Digital dependencies
|
|
75
|
+
- 🛠️ `build:gadget` npm script for regenerating the gadget XML
|
|
76
|
+
- 🗂️ Generated XML file in your build/dist directory
|
|
77
|
+
|
|
78
|
+
## ⚙️ Configuration
|
|
79
|
+
|
|
80
|
+
The `gadget.yaml` file contains metadata about your gadget:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
title: My Gadget
|
|
84
|
+
title_url: https://mysupporturl.org
|
|
85
|
+
description: Describe the purpose of your gadget here
|
|
86
|
+
author: My Organization
|
|
87
|
+
background: transparent
|
|
88
|
+
|
|
89
|
+
requirements:
|
|
90
|
+
- reveldigital
|
|
91
|
+
- offline
|
|
92
|
+
- webfont
|
|
93
|
+
|
|
94
|
+
prefs:
|
|
95
|
+
- name: myStringPref
|
|
96
|
+
display_name: Sample string preference
|
|
97
|
+
datatype: string
|
|
98
|
+
default_value: test string
|
|
99
|
+
required: true
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Edit this file to customize your gadget's properties and user preferences.
|
|
103
|
+
|
|
104
|
+
## 🛠️ Supported Frameworks
|
|
105
|
+
|
|
106
|
+
- **Angular** - Uses the official Revel Digital Angular schematic
|
|
107
|
+
- **React** - Instruments with client SDK and generates gadget configuration
|
|
108
|
+
- **Vue** - Instruments with client SDK and generates gadget configuration
|
|
109
|
+
- **Vanilla JavaScript** - Instruments with client SDK and generates gadget configuration
|
|
110
|
+
|
|
111
|
+
## 📚 Revel Digital Client SDK
|
|
112
|
+
|
|
113
|
+
For more information about the Revel Digital client SDK, including API documentation and examples, visit:
|
|
114
|
+
https://www.npmjs.com/package/@reveldigital/client-sdk
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## 📜 License
|
|
118
|
+
|
|
119
|
+
ISC
|
|
120
|
+
|
|
121
|
+
## 🤝 Support
|
|
122
|
+
|
|
123
|
+
For issues and questions:
|
|
124
|
+
- File an issue on this repository
|
|
125
|
+
- Visit the Revel Digital documentation at https://developer.reveldigital.com
|
|
126
|
+
- Check the client SDK documentation at https://www.npmjs.com/package/@reveldigital/client-sdk
|
package/cli.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { confirm, intro, outro, select, text } from '@clack/prompts';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import pc from 'picocolors';
|
|
8
|
+
import { getDeploymentUrl } from './utils/changeBasePath.js';
|
|
9
|
+
import { convertYmlToXml } from './utils/yml2xml.js';
|
|
10
|
+
import { dirname } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
|
|
13
|
+
//const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
//const __filename = fileURLToPath(process.cwd());
|
|
15
|
+
//const __dirname = path.dirname(__filename);
|
|
16
|
+
const __dirname = dirname(process.argv[1]);
|
|
17
|
+
|
|
18
|
+
// Parse command line arguments
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
const showHelp = args.includes('help') || args.includes('--help') || args.includes('-h');
|
|
21
|
+
const buildOnly = args.includes('build-only') || args.includes('--build-only');
|
|
22
|
+
const projectPath = process.cwd();
|
|
23
|
+
|
|
24
|
+
intro(pc.cyan('🚀 Revel Digital SDK Integrator'));
|
|
25
|
+
|
|
26
|
+
if (showHelp) {
|
|
27
|
+
outro(pc.cyan(`
|
|
28
|
+
Usage: gadgetizer [options]
|
|
29
|
+
|
|
30
|
+
Options:
|
|
31
|
+
--help, -h Show this help message
|
|
32
|
+
--build-only Run only the Gadget XML build step
|
|
33
|
+
|
|
34
|
+
Description:
|
|
35
|
+
Integrates the Revel Digital SDK into your project and generates gadget XML.
|
|
36
|
+
Supports React, Vue, Angular, and vanilla JavaScript projects.
|
|
37
|
+
`));
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (buildOnly) {
|
|
42
|
+
build({ projectPath: process.cwd(), __dirname });
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const framework = await select({
|
|
47
|
+
message: 'Select your project framework:',
|
|
48
|
+
options: [
|
|
49
|
+
{ value: 'react', label: 'React' },
|
|
50
|
+
{ value: 'vue', label: 'Vue' },
|
|
51
|
+
{ value: 'angular', label: 'Angular' },
|
|
52
|
+
{ value: 'js', label: 'Vanilla JavaScript' }
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
let entryFile = '';
|
|
57
|
+
switch (framework) {
|
|
58
|
+
case 'react':
|
|
59
|
+
entryFile = fs.existsSync(path.join(projectPath, 'src', 'App.js')) ? path.join('src', 'App.js') : '';
|
|
60
|
+
break;
|
|
61
|
+
case 'vue':
|
|
62
|
+
entryFile = fs.existsSync(path.join(projectPath, 'src', 'App.vue')) ? path.join('src', 'App.vue') : '';
|
|
63
|
+
break;
|
|
64
|
+
case 'angular':
|
|
65
|
+
entryFile = fs.existsSync(path.join(projectPath, 'src', 'main.ts')) ? path.join('src', 'main.ts') : '';
|
|
66
|
+
break;
|
|
67
|
+
case 'js':
|
|
68
|
+
entryFile = fs.existsSync(path.join(projectPath, 'src', 'main.js')) ? path.join('src', 'main.js') : '';
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (!entryFile) {
|
|
72
|
+
outro(pc.yellow(`⚠️ Could not automatically detect the main entry file for ${framework}. Please manually instrument your app with the Revel Digital SDK.`));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const pkgPath = path.join(projectPath, 'package.json');
|
|
76
|
+
if (!fs.existsSync(pkgPath)) {
|
|
77
|
+
outro(pc.red('❌ No package.json found in this directory. Please run this tool from your project root.'));
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (framework === 'angular') { // Angular uses schematic for integration
|
|
82
|
+
outro(pc.cyan('📦 Installing @reveldigital/player-client and running ng add schematic...'));
|
|
83
|
+
try {
|
|
84
|
+
execSync('npm install @reveldigital/player-client@latest', { stdio: 'inherit' });
|
|
85
|
+
execSync('ng add @reveldigital/player-client@latest', { stdio: 'inherit' });
|
|
86
|
+
outro(pc.green('✅ Angular project successfully instrumented with Revel Digital Player Client.'));
|
|
87
|
+
process.exit(0);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
outro(pc.red('❌ Error instrumenting Angular project. Please check your Angular CLI and npm setup.'));
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
// All other frameworks utilize SDK package installation
|
|
96
|
+
// Copy gadget.yaml to project root
|
|
97
|
+
const sourceYaml = path.join(__dirname, 'assets', 'gadget.yaml');
|
|
98
|
+
const destYaml = path.join(projectPath, 'gadget.yaml');
|
|
99
|
+
if (!fs.existsSync(destYaml)) {
|
|
100
|
+
try {
|
|
101
|
+
fs.copyFileSync(sourceYaml, destYaml);
|
|
102
|
+
outro(pc.green('📄 gadget.yaml copied to project root.'));
|
|
103
|
+
} catch (err) {
|
|
104
|
+
outro(pc.red('❌ Failed to copy gadget.yaml to project root. Please copy it manually.'));
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
outro(pc.yellow('⚠️ gadget.yaml already exists in project root. Skipping copy.'));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
// Prompt for deployment URL
|
|
112
|
+
let defaultDeploymentUrl = '';
|
|
113
|
+
try {
|
|
114
|
+
defaultDeploymentUrl = await getDeploymentUrl(pkgPath);
|
|
115
|
+
outro(pc.cyan(`🌎 Configuring gadget deployment URL based on Git: ${defaultDeploymentUrl}`));
|
|
116
|
+
} catch (e) {
|
|
117
|
+
defaultDeploymentUrl = '';
|
|
118
|
+
outro(pc.yellow(`⚠️ Warning: Could not get deployment URL automatically.`));
|
|
119
|
+
}
|
|
120
|
+
const deploymentUrl = await text({
|
|
121
|
+
message: 'Enter the deployment URL:',
|
|
122
|
+
initialValue: defaultDeploymentUrl
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Prompt for SDK version
|
|
126
|
+
const sdkVersion = await select({
|
|
127
|
+
message: 'Select Revel Digital SDK version to install:',
|
|
128
|
+
options: [
|
|
129
|
+
{ value: 'latest', label: 'Latest' },
|
|
130
|
+
{ value: 'custom', label: 'Custom version' }
|
|
131
|
+
]
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
let customVersion = '';
|
|
135
|
+
if (sdkVersion === 'custom') {
|
|
136
|
+
customVersion = await text({
|
|
137
|
+
message: 'Enter the custom SDK version:'
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
142
|
+
|
|
143
|
+
const shouldInstall = await confirm({
|
|
144
|
+
message: `Install Revel Digital SDK (${sdkVersion === 'custom' ? customVersion : sdkVersion})?`
|
|
145
|
+
});
|
|
146
|
+
if (shouldInstall) {
|
|
147
|
+
// Add SDK to package.json dependencies
|
|
148
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
149
|
+
const gadgetTypesPkgName = '@reveldigital/gadget-types';
|
|
150
|
+
pkg.dependencies[gadgetTypesPkgName] = 'latest';
|
|
151
|
+
const sdkPkgName = '@reveldigital/client-sdk';
|
|
152
|
+
const versionToInstall = sdkVersion === 'custom' ? customVersion : sdkVersion;
|
|
153
|
+
pkg.dependencies[sdkPkgName] = versionToInstall === 'latest' ? 'latest' : versionToInstall;
|
|
154
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
155
|
+
|
|
156
|
+
outro(pc.cyan(`🎉 Revel Digital SDK (${versionToInstall}) added to dependencies.`));
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
execSync('npm install', { stdio: 'inherit' });
|
|
160
|
+
outro(pc.green('📦 npm install completed successfully.'));
|
|
161
|
+
} catch (err) {
|
|
162
|
+
outro(pc.red('❌ npm install failed. Please run it manually.'));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// For Vue or Vite projects, set the base path in their respective configs
|
|
167
|
+
const viteConfigJsPath = path.join(projectPath, 'vite.config.js');
|
|
168
|
+
const viteConfigTsPath = path.join(projectPath, 'vite.config.ts');
|
|
169
|
+
const vueConfigPath = path.join(projectPath, 'vue.config.js');
|
|
170
|
+
|
|
171
|
+
let viteConfigPath = '';
|
|
172
|
+
if (fs.existsSync(viteConfigJsPath)) {
|
|
173
|
+
viteConfigPath = viteConfigJsPath;
|
|
174
|
+
} else if (fs.existsSync(viteConfigTsPath)) {
|
|
175
|
+
viteConfigPath = viteConfigTsPath;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (viteConfigPath) {
|
|
179
|
+
try {
|
|
180
|
+
let content = fs.readFileSync(viteConfigPath, 'utf8');
|
|
181
|
+
if (/\bbase\s*:/.test(content)) {
|
|
182
|
+
content = content.replace(/(\bbase\s*:\s*['"])[^'"]*(['"])/, `$1${deploymentUrl}$2`);
|
|
183
|
+
outro(pc.yellow(`🔧 Updated "base" in ${path.basename(viteConfigPath)}.`));
|
|
184
|
+
} else if (content.includes('defineConfig({')) {
|
|
185
|
+
content = content.replace(/(defineConfig\({)/, `$1\n base: '${deploymentUrl}',`);
|
|
186
|
+
outro(pc.green(`🔧 Added "base" to ${path.basename(viteConfigPath)}.`));
|
|
187
|
+
}
|
|
188
|
+
fs.writeFileSync(viteConfigPath, content);
|
|
189
|
+
} catch (err) {
|
|
190
|
+
outro(pc.red(`❌ Failed to update ${path.basename(viteConfigPath)}. Please set the "base" property manually.`));
|
|
191
|
+
}
|
|
192
|
+
} else if (fs.existsSync(vueConfigPath)) {
|
|
193
|
+
try {
|
|
194
|
+
let content = fs.readFileSync(vueConfigPath, 'utf8');
|
|
195
|
+
if (/\bpublicPath\s*:/.test(content)) {
|
|
196
|
+
content = content.replace(/(\bpublicPath\s*:\s*['"])[^'"]*(['"])/, `$1${deploymentUrl}$2`);
|
|
197
|
+
outro(pc.yellow('🔧 Updated "publicPath" in vue.config.js.'));
|
|
198
|
+
} else if (content.includes('module.exports = {')) {
|
|
199
|
+
content = content.replace(/(module.exports = {)/, `$1\n publicPath: '${deploymentUrl}',`);
|
|
200
|
+
outro(pc.green('🔧 Added "publicPath" to vue.config.js.'));
|
|
201
|
+
}
|
|
202
|
+
fs.writeFileSync(vueConfigPath, content);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
outro(pc.red('❌ Failed to update vue.config.js. Please set the "publicPath" property manually.'));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// For plain JS projects, check if Parcel is used and configure publicUrl
|
|
209
|
+
const isParcel = (pkg.dependencies && pkg.dependencies.parcel) || (pkg.devDependencies && pkg.devDependencies.parcel);
|
|
210
|
+
if (isParcel) {
|
|
211
|
+
pkg.targets = pkg.targets || {};
|
|
212
|
+
pkg.targets.default = pkg.targets.default || {};
|
|
213
|
+
pkg.targets.default.publicUrl = deploymentUrl;
|
|
214
|
+
outro(pc.green('🔧 Set "targets.default.publicUrl" in package.json for Parcel.'));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
pkg.scripts = pkg.scripts || {};
|
|
218
|
+
pkg.scripts['build:gadget'] = 'npm run build && gadgetizer --build-only';
|
|
219
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
220
|
+
outro(pc.green('🔧 Added "build:gadget" script to package.json.'));
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
build({ projectPath, __dirname });
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
function build({ projectPath, __dirname }) {
|
|
227
|
+
const pkgPath = path.join(projectPath, 'package.json');
|
|
228
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
229
|
+
const destYaml = path.join(projectPath, 'gadget.yaml');
|
|
230
|
+
const htmlCandidates = [
|
|
231
|
+
path.join(projectPath, 'dist', 'index.html'),
|
|
232
|
+
path.join(projectPath, 'public', 'index.html'),
|
|
233
|
+
];
|
|
234
|
+
let foundHtml = '';
|
|
235
|
+
for (const candidate of htmlCandidates) {
|
|
236
|
+
if (fs.existsSync(candidate)) {
|
|
237
|
+
foundHtml = candidate;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (!foundHtml) {
|
|
242
|
+
outro(pc.red('❌ index.html not found in public/, src/, or project root. Please add it and re-run the tool.'));
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
const distDir = path.join(path.dirname(foundHtml));
|
|
246
|
+
//const yml2xmlPath = path.join(__dirname, 'utils', 'yml2xml.js');
|
|
247
|
+
try {
|
|
248
|
+
const outputXmlName = `${pkg.name}.xml`;
|
|
249
|
+
convertYmlToXml(destYaml, foundHtml, path.join(distDir, outputXmlName), pkg.version);
|
|
250
|
+
//execSync(`node "${yml2xmlPath}" "${destYaml}" "${foundHtml}" "${path.join(distDir, outputXmlName)}" "${pkg.version}"`, { encoding: 'utf8' });
|
|
251
|
+
outro(pc.green(`✅ Gadget XML file "${outputXmlName}" generated in dist folder.`));
|
|
252
|
+
} catch (err) {
|
|
253
|
+
outro(pc.red('❌ Failed to generate XML file. Please check yml2xml.js and your input files.'));
|
|
254
|
+
}
|
|
255
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reveldigital/gadgetizer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Add Revel Digital SDK bindings to your project and configure for deployment",
|
|
5
|
+
"main": "cli.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"gadgetizer": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"/dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "parcel build cli.js --target node && shx cp -r assets dist/",
|
|
15
|
+
"start": "node ./dist/main.js",
|
|
16
|
+
"link": "npm link",
|
|
17
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
18
|
+
},
|
|
19
|
+
"targets": {
|
|
20
|
+
"node": {
|
|
21
|
+
"context": "node",
|
|
22
|
+
"includeNodeModules": true,
|
|
23
|
+
"outputFormat": "esmodule",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"author": "Revel Digital Worldwide Operations",
|
|
30
|
+
"license": "ISC",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@types/node": "^24.3.1",
|
|
33
|
+
"@clack/prompts": "^0.11.0",
|
|
34
|
+
"git-remote-origin-url": "4.0.0",
|
|
35
|
+
"js-yaml": "4.1.0",
|
|
36
|
+
"node-html-parser": "7.0.1",
|
|
37
|
+
"picocolors": "^1.0.0",
|
|
38
|
+
"xmlbuilder2": "3.1.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"typescript": "^5.9.2",
|
|
42
|
+
"parcel": "^2.15.4"
|
|
43
|
+
},
|
|
44
|
+
"release": {
|
|
45
|
+
"branches": [
|
|
46
|
+
"main"
|
|
47
|
+
],
|
|
48
|
+
"plugins": [
|
|
49
|
+
"@semantic-release/commit-analyzer",
|
|
50
|
+
"@semantic-release/release-notes-generator",
|
|
51
|
+
"@semantic-release/npm",
|
|
52
|
+
"@semantic-release/github"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|