neutrinos-cli 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/.configs/auth.json +5 -0
- package/.configs/preferences.json +5 -0
- package/.env +6 -0
- package/README.md +173 -0
- package/bin/cli.js +239 -0
- package/cli-auth/auth.js +54 -0
- package/cli-auth/publish.js +7 -0
- package/cli-auth/server.js +44 -0
- package/cli-auth/services/auth-utils.js +68 -0
- package/commands/alpha-publish.js +219 -0
- package/commands/attribute.js +155 -0
- package/commands/build.js +83 -0
- package/commands/deprecate.js +88 -0
- package/commands/dev.js +21 -0
- package/commands/generate.js +19 -0
- package/commands/new-workspace.js +142 -0
- package/commands/publish.js +334 -0
- package/commands/select-packages.mjs +36 -0
- package/commands/serve.js +27 -0
- package/package.json +34 -0
- package/setup.js +55 -0
- package/templates/assets/default-icon.png +0 -0
- package/templates/component/.component.ts.hbs +126 -0
- package/templates/component/.spec.ts.hbs +15 -0
- package/templates/component/.styles.ts.hbs +2 -0
- package/templates/module/.module.js.hbs +11 -0
- package/templates/plugins-server/index.js +18 -0
- package/templates/project/.vscode/extensions.json +6 -0
- package/templates/project/ATTRIBUTE.md +127 -0
- package/templates/project/Dockerfile +15 -0
- package/templates/project/helmchart/.helmignore +23 -0
- package/templates/project/helmchart/Chart.yaml +24 -0
- package/templates/project/helmchart/templates/NOTES.txt +22 -0
- package/templates/project/helmchart/templates/_helpers.tpl +62 -0
- package/templates/project/helmchart/templates/deployment.yaml +69 -0
- package/templates/project/helmchart/templates/ingress.yaml +62 -0
- package/templates/project/helmchart/templates/service.yaml +14 -0
- package/templates/project/helmchart/values.yaml +74 -0
- package/templates/project/index.html +24 -0
- package/templates/project/index.ts +86 -0
- package/templates/project/public-api.ts +0 -0
- package/templates/project/tsconfig.json +27 -0
- package/utils/attribute-utils.js +149 -0
- package/utils/check-valid-ws.js +21 -0
- package/utils/copy-utils.js +68 -0
- package/utils/create-client.js +23 -0
- package/utils/file-utils.js +43 -0
- package/utils/generate-component.js +101 -0
- package/utils/generate-module.js +51 -0
- package/utils/get-package-info.js +53 -0
- package/utils/get-packages.js +15 -0
- package/utils/inquirer-utils.js +49 -0
- package/utils/logger.js +35 -0
- package/utils/marketplace-api-utils.js +34 -0
- package/utils/path-utils.js +40 -0
- package/utils/prettify.js +36 -0
- package/utils/user-seesion-utils.js +43 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { bold } from 'colorette';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
// prettier-ignore
|
|
4
|
+
import { cpSync,mkdirSync,readFileSync,rmSync,writeFileSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { exit } from 'node:process';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { done, failed, inprogress } from '../utils/logger.js';
|
|
9
|
+
// prettier-ignore
|
|
10
|
+
import { pluginJsonPath,pluginServerTemplatesPath } from '../utils/path-utils.js';
|
|
11
|
+
import { prettify } from '../utils/prettify.js';
|
|
12
|
+
|
|
13
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
14
|
+
|
|
15
|
+
export const createWorkspace = async (dir, name) => {
|
|
16
|
+
process.on('SIGINT', () => {
|
|
17
|
+
cleanUp(dir);
|
|
18
|
+
exit(0);
|
|
19
|
+
});
|
|
20
|
+
process.on('SIGTERM', () => {
|
|
21
|
+
cleanUp(dir);
|
|
22
|
+
exit(0);
|
|
23
|
+
});
|
|
24
|
+
try {
|
|
25
|
+
createWorkspaceDirectory(dir);
|
|
26
|
+
} catch (err) {
|
|
27
|
+
handleWorkspaceDirectoryCreationError(err, dir);
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
initializeNpmProject(dir);
|
|
31
|
+
copyProjectTemplate(dir);
|
|
32
|
+
await createPluginJson(dir, name);
|
|
33
|
+
await initializePackages(dir);
|
|
34
|
+
await createReadme(dir, name);
|
|
35
|
+
initializeGit(dir);
|
|
36
|
+
initializeStaticServer(dir);
|
|
37
|
+
done(`Plugin Workspace created successfully: ${bold(dir)}`);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
handleWorkspaceCreationError(err, dir);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const createWorkspaceDirectory = (dir) => {
|
|
44
|
+
mkdirSync(dir);
|
|
45
|
+
done(`Created workspace directory: ${bold(dir)}`);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const initializeNpmProject = (dir) => {
|
|
49
|
+
execSync(`npm init -y`, {
|
|
50
|
+
cwd: dir,
|
|
51
|
+
});
|
|
52
|
+
done(`Initialized npm project in workspace`);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const copyProjectTemplate = (dir) => {
|
|
56
|
+
cpSync(join(__dirname, '../templates/project'), dir, {
|
|
57
|
+
recursive: true,
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const createPluginJson = async (dir, name) => {
|
|
62
|
+
writeFileSync(
|
|
63
|
+
pluginJsonPath(dir),
|
|
64
|
+
await prettify(
|
|
65
|
+
{
|
|
66
|
+
name,
|
|
67
|
+
components: { selectorPrefix: 'comp' },
|
|
68
|
+
modules: { idPrefix: 'mod' },
|
|
69
|
+
},
|
|
70
|
+
'json',
|
|
71
|
+
),
|
|
72
|
+
);
|
|
73
|
+
done(`Created plugin.json in workspace`);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const createReadme = async (dir, name) => {
|
|
77
|
+
writeFileSync(
|
|
78
|
+
join(dir, 'README.md'),
|
|
79
|
+
await prettify(`# ${name}\n\nThis is a new workspace for creating plugins for studio`, 'markdown'),
|
|
80
|
+
);
|
|
81
|
+
done(`Created README.md in workspace`);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const initializeGit = (dir) => {
|
|
85
|
+
writeFileSync(join(dir, '.gitignore'), ['node_modules', 'dist', 'build', 'coverage'].join('\n'));
|
|
86
|
+
execSync(`git init`, {
|
|
87
|
+
cwd: dir,
|
|
88
|
+
});
|
|
89
|
+
done(`Initialized git in workspace`);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const cleanUp = (dir) => {
|
|
93
|
+
inprogress('Cleaning up...');
|
|
94
|
+
rmSync(dir, { recursive: true });
|
|
95
|
+
done('Cleaned up workspace');
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const initializePackages = async (dir) => {
|
|
99
|
+
inprogress(`Adding default npm scripts to workspace...`);
|
|
100
|
+
const pkgJson = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf-8'));
|
|
101
|
+
const scripts = {
|
|
102
|
+
build: 'alpha build',
|
|
103
|
+
start: 'alpha start',
|
|
104
|
+
serve: 'alpha serve',
|
|
105
|
+
};
|
|
106
|
+
pkgJson.devDependencies = {
|
|
107
|
+
lit: '^3.1.4',
|
|
108
|
+
typescript: '^5.2.2',
|
|
109
|
+
};
|
|
110
|
+
pkgJson.dependencies = {
|
|
111
|
+
express: '^4.19.2',
|
|
112
|
+
'@jatahworx/alpha-annotations-lib': '^1.0.9',
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
pkgJson.workspaces = ['packages/*'];
|
|
116
|
+
pkgJson.type = 'module';
|
|
117
|
+
Object.assign(pkgJson.scripts, {}, scripts);
|
|
118
|
+
writeFileSync(join(dir, 'package.json'), await prettify(pkgJson, 'json'));
|
|
119
|
+
execSync(`npm install`, {
|
|
120
|
+
cwd: dir,
|
|
121
|
+
});
|
|
122
|
+
done(`Installed default packages in workspace: ${bold(dir)}`);
|
|
123
|
+
done(`Added default npm scripts to workspace: ${bold(dir)}`);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const initializeStaticServer = (dir) => {
|
|
127
|
+
cpSync(pluginServerTemplatesPath(), join(dir, 'plugins-server'), {
|
|
128
|
+
recursive: true,
|
|
129
|
+
});
|
|
130
|
+
done(`Initialized static server in workspace`);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const handleWorkspaceDirectoryCreationError = (err, dir) => {
|
|
134
|
+
failed(`Failed to create workspace directory: ${bold(dir)}`, err);
|
|
135
|
+
exit(1);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const handleWorkspaceCreationError = (err, dir) => {
|
|
139
|
+
failed(`Failed to create workspace: ${bold(dir)}`, err);
|
|
140
|
+
cleanUp(dir);
|
|
141
|
+
return;
|
|
142
|
+
};
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
import AdmZip from 'adm-zip';
|
|
3
|
+
import FormData from 'form-data';
|
|
4
|
+
import { remove } from 'fs-extra';
|
|
5
|
+
import { execSync } from 'node:child_process';
|
|
6
|
+
import { createReadStream, existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { copyIconToAsset, copyImagesToAsset, getPackageIcon, getPackageImages } from '../utils/copy-utils.js';
|
|
9
|
+
import { getPackageMetadata } from '../utils/get-package-info.js';
|
|
10
|
+
import { inquiry, multipleInquiry } from '../utils/inquirer-utils.js';
|
|
11
|
+
import { done, failed, inprogress } from '../utils/logger.js';
|
|
12
|
+
import { publishToMarketplace } from '../utils/marketplace-api-utils.js';
|
|
13
|
+
import { getLoggedInUserSession } from '../utils/user-seesion-utils.js';
|
|
14
|
+
|
|
15
|
+
const DISPLAY_NAME_QUERY = {
|
|
16
|
+
type: 'input',
|
|
17
|
+
name: 'name',
|
|
18
|
+
message: 'Enter the Display Name of the package :',
|
|
19
|
+
};
|
|
20
|
+
const ICON_FILE_PATH_QUERY = {
|
|
21
|
+
type: 'input',
|
|
22
|
+
name: 'value',
|
|
23
|
+
message: 'Enter the path to the icon of the package :',
|
|
24
|
+
};
|
|
25
|
+
const IMAGES_FILE_PATH_QUERY = {
|
|
26
|
+
type: 'input',
|
|
27
|
+
name: 'value',
|
|
28
|
+
message: 'Enter the path to images of the package :',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @param {string} name
|
|
34
|
+
* @param {string} wsPath
|
|
35
|
+
* @param {any} options
|
|
36
|
+
*/
|
|
37
|
+
export const publish = async (name, wsPath, options) => {
|
|
38
|
+
const session = await getLoggedInUserSession();
|
|
39
|
+
const { packageName, componentDirPath } = await getPackageMetadata(wsPath, name);
|
|
40
|
+
await handlePackagePublish(packageName, componentDirPath, wsPath, options, session);
|
|
41
|
+
done('Published Successfully');
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @param {string} packageName
|
|
47
|
+
* @param {string} componentDirPath
|
|
48
|
+
* @param {string} wsPath
|
|
49
|
+
* @param {any} options
|
|
50
|
+
* @param {any} session
|
|
51
|
+
*/
|
|
52
|
+
const handlePackagePublish = async (packageName, componentDirPath, wsPath, options, session) => {
|
|
53
|
+
const pkgJsonPath = join(componentDirPath, 'package.json');
|
|
54
|
+
let pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
55
|
+
if (!pkgJson.alpha) {
|
|
56
|
+
throw new Error('It is not an alpha package');
|
|
57
|
+
}
|
|
58
|
+
if (pkgJson.alpha.deprecated) {
|
|
59
|
+
throw new Error('This is a deprecated package');
|
|
60
|
+
}
|
|
61
|
+
if (pkgJson.alpha.packageId) {
|
|
62
|
+
await publishPackageVersion(packageName, wsPath, pkgJson, options, componentDirPath, pkgJsonPath, session);
|
|
63
|
+
} else {
|
|
64
|
+
await publishNewPackage(packageName, wsPath, pkgJson, options, componentDirPath, pkgJsonPath, session);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @param {string} name
|
|
71
|
+
* @param {string} wsPath
|
|
72
|
+
* @param {any} pkgJson
|
|
73
|
+
* @param {any} options
|
|
74
|
+
* @param {string} componentDirPath
|
|
75
|
+
* @param {string} pkgJsonPath
|
|
76
|
+
* @param {any} session
|
|
77
|
+
*/
|
|
78
|
+
const publishPackageVersion = async (name, wsPath, pkgJson, options, componentDirPath, pkgJsonPath, session) => {
|
|
79
|
+
await incrementPackageVersion(wsPath, pkgJson.name, options);
|
|
80
|
+
pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
81
|
+
|
|
82
|
+
const iconForPkg = options.icon || (await getIconPath(componentDirPath));
|
|
83
|
+
const imagesForPkg = options.images?.length
|
|
84
|
+
? JSON.stringify(options.images)
|
|
85
|
+
: JSON.stringify(await getImagesPath(componentDirPath));
|
|
86
|
+
|
|
87
|
+
const publishArgs = createVersionPublishArgs(name, pkgJson, iconForPkg, imagesForPkg);
|
|
88
|
+
inprogress('Publishing...');
|
|
89
|
+
const { version } = await uploadPackageFiles(
|
|
90
|
+
wsPath,
|
|
91
|
+
componentDirPath,
|
|
92
|
+
publishArgs,
|
|
93
|
+
pkgJson.alpha.packageId,
|
|
94
|
+
session,
|
|
95
|
+
);
|
|
96
|
+
if (version.version_id) {
|
|
97
|
+
updatePackageJson(pkgJsonPath, pkgJson, pkgJson.alpha.packageId, version.version_id);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* @param {string} name
|
|
104
|
+
* @param {string} wsPath
|
|
105
|
+
* @param {any} pkgJson
|
|
106
|
+
* @param {any} options
|
|
107
|
+
* @param {string} componentDirPath
|
|
108
|
+
* @param {string} pkgJsonPath
|
|
109
|
+
* @param {any} session
|
|
110
|
+
*/
|
|
111
|
+
const publishNewPackage = async (name, wsPath, pkgJson, options, componentDirPath, pkgJsonPath, session) => {
|
|
112
|
+
const displayName = options.displayName || (await inquiry(DISPLAY_NAME_QUERY)).name || name;
|
|
113
|
+
const iconForPkg = options.icon || (await getIconPath(componentDirPath));
|
|
114
|
+
const imagesForPkg = options.images?.length ? options.images : await getImagesPath(componentDirPath);
|
|
115
|
+
|
|
116
|
+
const publishArgs = createNewPackagePublishArgs(name, pkgJson, displayName, iconForPkg, imagesForPkg);
|
|
117
|
+
inprogress('Publishing...');
|
|
118
|
+
const response = await uploadPackageFiles(wsPath, componentDirPath, publishArgs, '', session);
|
|
119
|
+
if (response.package) {
|
|
120
|
+
updatePackageJson(
|
|
121
|
+
pkgJsonPath,
|
|
122
|
+
pkgJson,
|
|
123
|
+
response.package.package_id,
|
|
124
|
+
response.package.latest_version.version_id,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
* @param {string} componentDirPath
|
|
132
|
+
* @returns
|
|
133
|
+
*/
|
|
134
|
+
const getIconPath = async (componentDirPath) => {
|
|
135
|
+
const icon = getPackageIcon(componentDirPath);
|
|
136
|
+
return icon || (await inquiry(ICON_FILE_PATH_QUERY)).value;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @param {string} componentDirPath
|
|
142
|
+
* @returns
|
|
143
|
+
*/
|
|
144
|
+
const getImagesPath = async (componentDirPath) => {
|
|
145
|
+
const images = getPackageImages(componentDirPath);
|
|
146
|
+
if (images.length) {
|
|
147
|
+
return images;
|
|
148
|
+
}
|
|
149
|
+
const imagesAns = await multipleInquiry(IMAGES_FILE_PATH_QUERY);
|
|
150
|
+
return imagesAns.map((img) => img.value);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
*
|
|
155
|
+
* @param {string} name
|
|
156
|
+
* @param {any} pkgJson
|
|
157
|
+
* @param {string} iconForPkg
|
|
158
|
+
* @param {string} imagesForPkg
|
|
159
|
+
* @returns
|
|
160
|
+
*/
|
|
161
|
+
const createVersionPublishArgs = (name, pkgJson, iconForPkg, imagesForPkg) => ({
|
|
162
|
+
name,
|
|
163
|
+
version_number: pkgJson.version,
|
|
164
|
+
metadata: JSON.stringify({
|
|
165
|
+
platform: 'alpha',
|
|
166
|
+
type: pkgJson.alpha.component ? 'component' : 'module',
|
|
167
|
+
}),
|
|
168
|
+
icon_file_path: iconForPkg,
|
|
169
|
+
image_file_path: imagesForPkg,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
*
|
|
174
|
+
* @param {string} name
|
|
175
|
+
* @param {any} pkgJson
|
|
176
|
+
* @param {string} displayName
|
|
177
|
+
* @param {string} iconForPkg
|
|
178
|
+
* @param {string[]} imagesForPkg
|
|
179
|
+
* @returns
|
|
180
|
+
*/
|
|
181
|
+
const createNewPackagePublishArgs = (name, pkgJson, displayName, iconForPkg, imagesForPkg) => ({
|
|
182
|
+
package_metadata: JSON.stringify({
|
|
183
|
+
platform: 'alpha',
|
|
184
|
+
type: pkgJson.alpha.component ? 'component' : 'module',
|
|
185
|
+
}),
|
|
186
|
+
display_name: displayName,
|
|
187
|
+
name,
|
|
188
|
+
version_number: pkgJson.version,
|
|
189
|
+
package_type: 'zip',
|
|
190
|
+
version_metadata: JSON.stringify({
|
|
191
|
+
platform: 'alpha',
|
|
192
|
+
type: pkgJson.alpha.component ? 'component' : 'module',
|
|
193
|
+
}),
|
|
194
|
+
description: pkgJson.description || 'Package published by CLI',
|
|
195
|
+
icon_file_path: iconForPkg,
|
|
196
|
+
image_file_path: JSON.stringify(imagesForPkg),
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
*
|
|
201
|
+
* @param {string} wsPath
|
|
202
|
+
* @param {string} pkgName
|
|
203
|
+
* @param {any} options
|
|
204
|
+
*/
|
|
205
|
+
const incrementPackageVersion = async (wsPath, pkgName, options) => {
|
|
206
|
+
if (!pkgName) throw new Error('Package name is required');
|
|
207
|
+
const versionType =
|
|
208
|
+
options.versionType ||
|
|
209
|
+
(
|
|
210
|
+
await inquiry({
|
|
211
|
+
type: 'list',
|
|
212
|
+
name: 'type',
|
|
213
|
+
choices: ['patch', 'minor', 'major'],
|
|
214
|
+
message: 'Choose the Version type :',
|
|
215
|
+
})
|
|
216
|
+
).type;
|
|
217
|
+
execSync(`npm version ${versionType} -w ${pkgName}`, {
|
|
218
|
+
cwd: wsPath,
|
|
219
|
+
stdio: 'inherit',
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
*
|
|
225
|
+
* @param {string} wsPath
|
|
226
|
+
* @param {string} componentDirPath
|
|
227
|
+
* @param {any} publishArgs
|
|
228
|
+
* @param {string} path
|
|
229
|
+
* @param {any} session
|
|
230
|
+
* @returns
|
|
231
|
+
*/
|
|
232
|
+
const uploadPackageFiles = async (wsPath, componentDirPath, publishArgs, path = '', session) => {
|
|
233
|
+
const form = createFormData(publishArgs, componentDirPath);
|
|
234
|
+
|
|
235
|
+
const zipFile = await createZipFile(wsPath, componentDirPath, publishArgs.name);
|
|
236
|
+
form.append('zip_file', zipFile);
|
|
237
|
+
|
|
238
|
+
return publishToMarketplace(form, path, session, false);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
*
|
|
243
|
+
* @param {any} publishArgs
|
|
244
|
+
* @param {string} componentDirPath
|
|
245
|
+
* @returns
|
|
246
|
+
*/
|
|
247
|
+
const createFormData = (publishArgs, componentDirPath) => {
|
|
248
|
+
const form = new FormData();
|
|
249
|
+
for (let key in publishArgs) {
|
|
250
|
+
form.append(key, publishArgs[key]);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
appendIconToForm(form, publishArgs.icon_file_path, componentDirPath);
|
|
254
|
+
appendImagesToForm(form, JSON.parse(publishArgs.image_file_path), componentDirPath);
|
|
255
|
+
|
|
256
|
+
return form;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
*
|
|
261
|
+
* @param {FormData} form
|
|
262
|
+
* @param {string} iconPath
|
|
263
|
+
* @param {string} componentDirPath
|
|
264
|
+
*/
|
|
265
|
+
const appendIconToForm = (form, iconPath, componentDirPath) => {
|
|
266
|
+
if (existsSync(iconPath)) {
|
|
267
|
+
copyIconToAsset(iconPath, componentDirPath);
|
|
268
|
+
form.append('icon', createReadStream(iconPath));
|
|
269
|
+
} else {
|
|
270
|
+
failed("Invalid icon path or icon doesn't exist");
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
*
|
|
276
|
+
* @param {FormData} form
|
|
277
|
+
* @param {string[]} imagesPaths
|
|
278
|
+
* @param {string} componentDirPath
|
|
279
|
+
*/
|
|
280
|
+
const appendImagesToForm = (form, imagesPaths, componentDirPath) => {
|
|
281
|
+
//@ts-ignore
|
|
282
|
+
imagesPaths.forEach((imgPath) => {
|
|
283
|
+
if (existsSync(imgPath)) {
|
|
284
|
+
copyImagesToAsset(imgPath, componentDirPath);
|
|
285
|
+
form.append('images', createReadStream(imgPath));
|
|
286
|
+
} else {
|
|
287
|
+
failed("Invalid images path or image doesn't exist");
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
*
|
|
294
|
+
* @param {string} wsPath
|
|
295
|
+
* @param {string} componentDirPath
|
|
296
|
+
* @param {string} packageName
|
|
297
|
+
* @returns
|
|
298
|
+
*/
|
|
299
|
+
const createZipFile = async (wsPath, componentDirPath, packageName) => {
|
|
300
|
+
const componentDistPath = join(componentDirPath, 'dist');
|
|
301
|
+
execSync(`npm run build plugins ${packageName}`, {
|
|
302
|
+
cwd: wsPath,
|
|
303
|
+
stdio: 'inherit',
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
//@ts-ignore
|
|
307
|
+
const zip = new AdmZip();
|
|
308
|
+
zip.addLocalFolder(componentDistPath);
|
|
309
|
+
const zipBuffer = zip.toBuffer();
|
|
310
|
+
|
|
311
|
+
const zipFilePath = join(componentDistPath, `${packageName.toLowerCase()}.zip`);
|
|
312
|
+
writeFileSync(zipFilePath, zipBuffer);
|
|
313
|
+
|
|
314
|
+
const readStream = createReadStream(zipFilePath);
|
|
315
|
+
readStream.on('close', () =>
|
|
316
|
+
remove(zipFilePath, (err) => {
|
|
317
|
+
if (err) console.error('Error deleting file:', err);
|
|
318
|
+
}),
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
return readStream;
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
*
|
|
326
|
+
* @param {string} pkgJsonPath
|
|
327
|
+
* @param {any} pkgJson
|
|
328
|
+
* @param {string} packageId
|
|
329
|
+
* @param {string} versionId
|
|
330
|
+
*/
|
|
331
|
+
const updatePackageJson = (pkgJsonPath, pkgJson, packageId, versionId) => {
|
|
332
|
+
Object.assign(pkgJson.alpha, { packageId, versionId });
|
|
333
|
+
writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
334
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
import checkbox from '@inquirer/checkbox';
|
|
3
|
+
import { existsSync, globSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { basename, join, sep } from 'node:path';
|
|
5
|
+
|
|
6
|
+
export const selectPackages = async (dirname, all = false, pluginName) => {
|
|
7
|
+
/**@type {string[]} */
|
|
8
|
+
const packagesDir = JSON.parse(readFileSync(join(dirname, 'package.json'), 'utf-8')).workspaces;
|
|
9
|
+
const packageNames = globSync(packagesDir, { cwd: join(dirname) });
|
|
10
|
+
const packages = packageNames
|
|
11
|
+
.map((name) => join(dirname, name))
|
|
12
|
+
.filter((p) => {
|
|
13
|
+
return existsSync(join(p, 'package.json'));
|
|
14
|
+
});
|
|
15
|
+
if (pluginName) {
|
|
16
|
+
const pluginPath = packages.filter((p) => basename(p) === pluginName);
|
|
17
|
+
return pluginPath;
|
|
18
|
+
}
|
|
19
|
+
if (all) {
|
|
20
|
+
return packages;
|
|
21
|
+
}
|
|
22
|
+
const selectedPackages = await checkbox({
|
|
23
|
+
message: 'Select the packages',
|
|
24
|
+
instructions: ' [NOTE: Press <space> to toggle selection, <return> to submit]',
|
|
25
|
+
choices: packages.map((p) => {
|
|
26
|
+
return {
|
|
27
|
+
name: p.split(sep).pop(),
|
|
28
|
+
value: p,
|
|
29
|
+
// checked: true,
|
|
30
|
+
};
|
|
31
|
+
}),
|
|
32
|
+
required: true,
|
|
33
|
+
pageSize: 10,
|
|
34
|
+
});
|
|
35
|
+
return selectedPackages;
|
|
36
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { platform } from 'node:process';
|
|
4
|
+
import { failed } from '../utils/logger.js';
|
|
5
|
+
import { pluginServerRoot } from '../utils/path-utils.js';
|
|
6
|
+
|
|
7
|
+
export const startPluginsServer = async (wsPath) => {
|
|
8
|
+
const serverRoot = pluginServerRoot(wsPath);
|
|
9
|
+
if (!existsSync(serverRoot)) {
|
|
10
|
+
failed('The plugins server is not found in the workspace');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const index = 'index.js';
|
|
14
|
+
const cmd = platform === 'win32' ? `node.exe` : `node`;
|
|
15
|
+
const args = ['--watch', `"${index}"`];
|
|
16
|
+
const execuatable = `${cmd} ${args.join(' ')}`;
|
|
17
|
+
execSync(execuatable, {
|
|
18
|
+
cwd: serverRoot,
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
env: {
|
|
21
|
+
...process.env,
|
|
22
|
+
PORT: '666',
|
|
23
|
+
BASE_PATH: '/plugins-service',
|
|
24
|
+
PLUGIN_DIR_ROOT: 'plugins',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "neutrinos-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "./bin/cli.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"neutrinos": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
".configs",
|
|
11
|
+
"bin",
|
|
12
|
+
"cli-auth",
|
|
13
|
+
"commands",
|
|
14
|
+
"templates",
|
|
15
|
+
"utils",
|
|
16
|
+
"setup.js",
|
|
17
|
+
".env",
|
|
18
|
+
"package.json"
|
|
19
|
+
],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
25
|
+
"postinstall": "node ./setup.js"
|
|
26
|
+
},
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"keywords": [],
|
|
30
|
+
"description": "",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"fastify": "^5.4.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/setup.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Ensure that the config folder exists
|
|
5
|
+
* @param {string} configDir
|
|
6
|
+
*/
|
|
7
|
+
export const ensureConfigFolder = async (configDir) => {
|
|
8
|
+
try {
|
|
9
|
+
await mkdir(configDir, { recursive: true });
|
|
10
|
+
} catch (error) {
|
|
11
|
+
if (error.code !== 'EEXIST') {
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const ensureDefaultPreferences = async (configDir, preferences) => {
|
|
18
|
+
const preferencesPath = `${configDir}/preferences.json`;
|
|
19
|
+
try {
|
|
20
|
+
await mkdir(configDir, { recursive: true });
|
|
21
|
+
await writeFile(preferencesPath, JSON.stringify(preferences, null, 4));
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error.code !== 'EEXIST') {
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const ensureAuthConfig = async (configDir, authConfig) => {
|
|
30
|
+
const authConfigPath = `${configDir}/auth.json`;
|
|
31
|
+
try {
|
|
32
|
+
await mkdir(configDir, { recursive: true });
|
|
33
|
+
await writeFile(authConfigPath, JSON.stringify(authConfig, null, 4));
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error.code !== 'EEXIST') {
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const CONFIG_DIR = './.configs';
|
|
42
|
+
|
|
43
|
+
ensureConfigFolder(CONFIG_DIR);
|
|
44
|
+
|
|
45
|
+
ensureAuthConfig(CONFIG_DIR, {
|
|
46
|
+
clientId: 'your-client-id',
|
|
47
|
+
clientSecret: 'your-client-secret',
|
|
48
|
+
redirectUri: 'http://localhost:3000/callback',
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
ensureDefaultPreferences(CONFIG_DIR, {
|
|
52
|
+
theme: 'light',
|
|
53
|
+
language: 'en',
|
|
54
|
+
showNotifications: true,
|
|
55
|
+
});
|
|
Binary file
|