@blocklet/component-studio-cli 0.6.14 → 0.6.16
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/commands/add.js +77 -1
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.js +68 -0
- package/dist/commands/bump-version.d.ts +2 -0
- package/dist/commands/bump-version.js +100 -0
- package/dist/commands/component-studio.js +4 -0
- package/dist/commands/dev.js +12 -85
- package/dist/utils/helper.d.ts +15 -0
- package/dist/utils/helper.js +114 -9
- package/package.json +5 -2
- package/templates/add/tools/teamwork-tools/.github/workflows/ci.yml +35 -0
- package/templates/add/tools/teamwork-tools/.github/workflows/code-reviewer.yml +40 -0
- package/templates/add/tools/teamwork-tools/.github/workflows/pr-title.yml +21 -0
- package/templates/add/tools/teamwork-tools/.github/workflows/upload-to-blocklet-store.yml +71 -0
- package/templates/add/tools/teamwork-tools/.github/workflows/version-check.yml +20 -0
- package/templates/add/tools/teamwork-tools/@template.json +4 -0
- package/templates/init/0-basic/.gitignore_example +4 -1
- package/templates/init/0-basic/package.json +4 -1
- package/templates/init/1-professional/.gitignore_example +4 -1
- package/templates/init/1-professional/biome.json +1 -1
- package/templates/init/1-professional/package.json +7 -5
- package/templates/init/2-blank/.gitignore_example +4 -1
- package/templates/init/2-blank/package.json +4 -1
- package/templates/workspace/.gitignore_example +4 -1
- package/templates/workspace/biome.json +1 -1
- package/templates/workspace/package.json +3 -3
- package/templates/init/1-professional/scripts/bump-version.mjs +0 -35
- package/templates/init/1-professional/version +0 -1
package/dist/commands/add.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import AdmZip from 'adm-zip';
|
|
1
2
|
import chalk from 'chalk';
|
|
2
3
|
import { Command } from 'commander';
|
|
3
4
|
import inquirer from 'inquirer';
|
|
4
5
|
import { camelCase, upperFirst } from 'lodash-es';
|
|
5
6
|
import { nanoid } from 'nanoid';
|
|
6
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, rmSync } from 'node:fs';
|
|
7
8
|
import { join, relative } from 'node:path';
|
|
8
9
|
import ora from 'ora';
|
|
10
|
+
import os from 'os';
|
|
11
|
+
import * as tar from 'tar';
|
|
12
|
+
import { BLOCKLET_INFO_DIR } from '../utils/helper.js';
|
|
9
13
|
import { copyTemplateFilesExcept, loadTemplates, selectTemplate, validateTemplate, getTemplatePath, getProjectPath, replaceInDirectory, findClosestMetadataDir, checkTargetDirectoryExists, } from '../utils/helper.js';
|
|
10
14
|
// 模板目录常量
|
|
11
15
|
const TOOLS_DIR = 'tools';
|
|
@@ -60,6 +64,78 @@ export function createAddCommand() {
|
|
|
60
64
|
if (!canContinue) {
|
|
61
65
|
process.exit(0);
|
|
62
66
|
}
|
|
67
|
+
// Notice: 如果是 teamwork-tools 模板,则需要获取 Resource Blocklet 路径
|
|
68
|
+
if (selectedTemplate.name === 'Teamwork Tools') {
|
|
69
|
+
const { resourceBlockletPath } = await inquirer.prompt([
|
|
70
|
+
{
|
|
71
|
+
type: 'input',
|
|
72
|
+
name: 'resourceBlockletPath',
|
|
73
|
+
message: 'Please provide the latest Resource Blocklet path (e.g. /Users/your-username/xxxxx-0.0.1.{zip,tgz}): \n ',
|
|
74
|
+
validate: (input) => {
|
|
75
|
+
if (!existsSync(input))
|
|
76
|
+
return 'Resource Blocklet path does not exist.';
|
|
77
|
+
// 支持 .zip 和 .tgz 文件
|
|
78
|
+
if (!input.endsWith('.zip') && !input.endsWith('.tgz')) {
|
|
79
|
+
return 'Resource Blocklet path must be a .zip or .tgz file.';
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
// 如果存在,解压到 tmp 目录
|
|
86
|
+
const tmpDir = join(os.tmpdir(), Math.random().toString(36).substring(2, 15));
|
|
87
|
+
if (existsSync(tmpDir)) {
|
|
88
|
+
rmSync(tmpDir, { recursive: true });
|
|
89
|
+
}
|
|
90
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
91
|
+
let extractDir;
|
|
92
|
+
if (resourceBlockletPath.endsWith('.zip')) {
|
|
93
|
+
// Extract zip file
|
|
94
|
+
const zip = new AdmZip(resourceBlockletPath);
|
|
95
|
+
zip.extractAllTo(tmpDir, true);
|
|
96
|
+
// Read blocklet.json to get tarball name
|
|
97
|
+
const blockletJsonPath = join(tmpDir, 'blocklet.json');
|
|
98
|
+
if (!existsSync(blockletJsonPath)) {
|
|
99
|
+
console.log(chalk.red('blocklet.json not found in the extracted zip file.'));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
const blockletJson = JSON.parse(readFileSync(blockletJsonPath, 'utf-8'));
|
|
103
|
+
const tarballName = blockletJson.dist?.tarball;
|
|
104
|
+
if (!tarballName) {
|
|
105
|
+
console.log(chalk.red('No tarball found in blocklet.json'));
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
// Extract .tgz file
|
|
109
|
+
const tarballPath = join(tmpDir, tarballName);
|
|
110
|
+
if (!existsSync(tarballPath)) {
|
|
111
|
+
console.log(chalk.red(`Tarball file not found: ${tarballName}`));
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
extractDir = join(tmpDir, 'extracted');
|
|
115
|
+
mkdirSync(extractDir, { recursive: true });
|
|
116
|
+
await tar.x({ file: tarballPath, cwd: extractDir });
|
|
117
|
+
}
|
|
118
|
+
else if (resourceBlockletPath.endsWith('.tgz')) {
|
|
119
|
+
// Extract .tgz file directly
|
|
120
|
+
extractDir = tmpDir;
|
|
121
|
+
await tar.x({ file: resourceBlockletPath, cwd: extractDir });
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
console.log(chalk.red('Unsupported file format.'));
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
// Validate extracted structure - check for package directory
|
|
128
|
+
const packageDir = join(extractDir, 'package');
|
|
129
|
+
if (!existsSync(packageDir)) {
|
|
130
|
+
console.log(chalk.red('Invalid Resource Blocklet: missing "package" directory.'));
|
|
131
|
+
console.log(chalk.red('This does not appear to be a standard Resource Blocklet package.'));
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
// console.log(chalk.green(`Resource Blocklet extracted to: ${chalk.cyan(packageDir)}`));
|
|
135
|
+
// copy package to project
|
|
136
|
+
await copyTemplateFilesExcept(packageDir, join(projectPath, BLOCKLET_INFO_DIR));
|
|
137
|
+
spinner.succeed(chalk.green(`Resource Blocklet extracted successfully!`));
|
|
138
|
+
}
|
|
63
139
|
// 对于工具类模板,直接复制到项目根目录
|
|
64
140
|
spinner.start(`Adding tool "${selectedTemplate.name}" to project...`);
|
|
65
141
|
try {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { readFile } from 'fs/promises';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { parse } from 'yaml';
|
|
6
|
+
import { BLOCKLET_INFO_DIR, getProjectPath, setupWorkspaceEnvironment } from '../utils/helper.js';
|
|
7
|
+
export function createBuildCommand() {
|
|
8
|
+
return new Command('build')
|
|
9
|
+
.description('Build project')
|
|
10
|
+
.option('-c, --components <components>', 'Build components, please use comma to separate')
|
|
11
|
+
.option('-b, --bundle-resource-blocklet', 'Bundle resource blocklet, default is false')
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const projectPath = getProjectPath();
|
|
14
|
+
const { workspacePath } = await setupWorkspaceEnvironment(projectPath);
|
|
15
|
+
const bundleDir = join(projectPath, BLOCKLET_INFO_DIR);
|
|
16
|
+
const extraEnvs = {};
|
|
17
|
+
if (options.components) {
|
|
18
|
+
extraEnvs.BLOCK_FILTER = options.components;
|
|
19
|
+
}
|
|
20
|
+
if (options.bundleResourceBlocklet) {
|
|
21
|
+
// 读取 projectPath 的 yaml 文件,提取里面的 resources 信息
|
|
22
|
+
const projectYaml = await readFile(join(bundleDir, 'blocklet.yml'), 'utf-8');
|
|
23
|
+
const projectYamlData = parse(projectYaml);
|
|
24
|
+
const { bundles } = projectYamlData.resource;
|
|
25
|
+
const bundleInfo = bundles[0];
|
|
26
|
+
if (bundleInfo) {
|
|
27
|
+
// 复制 resource-blocklet 到指定目录
|
|
28
|
+
extraEnvs.EXPORT_DIR = join(bundleDir, 'resources', bundleInfo.did, bundleInfo.type);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const buildProcess = spawn('pnpm', ['run', 'build-lib'], {
|
|
32
|
+
stdio: 'inherit',
|
|
33
|
+
cwd: workspacePath,
|
|
34
|
+
shell: true,
|
|
35
|
+
env: {
|
|
36
|
+
...process.env,
|
|
37
|
+
FORCE_COLOR: '1',
|
|
38
|
+
NODE_OPTIONS: '--max_old_space_size=16384',
|
|
39
|
+
NODE_ENV: 'production',
|
|
40
|
+
...extraEnvs,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
await new Promise((resolve, reject) => {
|
|
44
|
+
buildProcess.on('close', (code) => {
|
|
45
|
+
if (code === 0) {
|
|
46
|
+
if (options.bundleResourceBlocklet) {
|
|
47
|
+
spawn('npx', ['-y', '@blocklet/cli', 'bundle', '--create-release'], {
|
|
48
|
+
stdio: 'inherit',
|
|
49
|
+
cwd: bundleDir,
|
|
50
|
+
shell: true,
|
|
51
|
+
env: {
|
|
52
|
+
...process.env,
|
|
53
|
+
FORCE_COLOR: '1',
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
resolve(null);
|
|
58
|
+
}
|
|
59
|
+
else
|
|
60
|
+
reject(new Error(`Build process exited with code ${code}`));
|
|
61
|
+
});
|
|
62
|
+
buildProcess.on('error', (error) => {
|
|
63
|
+
console.error('Build process error:', error);
|
|
64
|
+
reject(error);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { readFile, writeFile, ensureFile } from 'fs-extra';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { getProjectPath, BLOCKLET_INFO_DIR } from '../utils/helper.js';
|
|
9
|
+
export function createBumpVersionCommand() {
|
|
10
|
+
return new Command('bump-version')
|
|
11
|
+
.description('Bump version for project')
|
|
12
|
+
.option('-c, --changelog <changelog>', 'Custom changelog content')
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
const projectPath = getProjectPath();
|
|
15
|
+
const spinner = ora('Bumping version...');
|
|
16
|
+
try {
|
|
17
|
+
// Step 1: Bump version using bumpp
|
|
18
|
+
execSync(`npx -y bumpp --no-tag --no-commit --no-push package.json`, {
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
cwd: projectPath,
|
|
21
|
+
});
|
|
22
|
+
// Step 2: Read new version and write to version file
|
|
23
|
+
const packageJsonPath = join(projectPath, 'package.json');
|
|
24
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8'));
|
|
25
|
+
const newVersion = packageJson.version;
|
|
26
|
+
await writeFile(join(projectPath, 'version'), newVersion);
|
|
27
|
+
spinner.succeed(chalk.green(`Version bumped to ${newVersion}`));
|
|
28
|
+
// Step 3: get blockletInfo path
|
|
29
|
+
const blockletInfoPath = join(projectPath, BLOCKLET_INFO_DIR);
|
|
30
|
+
// Step 4: Prepare changelog
|
|
31
|
+
let newChangelog = '';
|
|
32
|
+
const now = new Date();
|
|
33
|
+
const currentDate = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
|
|
34
|
+
const title = `## ${newVersion} (${currentDate})`;
|
|
35
|
+
if (options.changelog) {
|
|
36
|
+
newChangelog = options.changelog;
|
|
37
|
+
console.log(chalk.blue(`Using custom changelog: ${newChangelog}`));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Ask user for custom changelog input
|
|
41
|
+
const { userChangelog } = await inquirer.prompt([
|
|
42
|
+
{
|
|
43
|
+
type: 'input',
|
|
44
|
+
name: 'userChangelog',
|
|
45
|
+
message: 'Enter changelog content (leave empty to use git log):',
|
|
46
|
+
default: '',
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
49
|
+
if (userChangelog?.trim()) {
|
|
50
|
+
newChangelog = userChangelog.trim();
|
|
51
|
+
console.log(chalk.blue(`Using user input changelog: ${newChangelog}`));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Fallback to git log
|
|
55
|
+
try {
|
|
56
|
+
const gitLogResult = execSync('git log --pretty=format:"- %s" "main"...HEAD', {
|
|
57
|
+
encoding: 'utf-8',
|
|
58
|
+
cwd: projectPath,
|
|
59
|
+
});
|
|
60
|
+
newChangelog = gitLogResult.trim();
|
|
61
|
+
console.log(chalk.blue('Using git log for changelog'));
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error(chalk.red('Could not get git log, using default changelog.'));
|
|
65
|
+
newChangelog = '- Manual changelog entry needed';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Step 5: Update blockletInfoPath version
|
|
70
|
+
try {
|
|
71
|
+
// Update blocklet version
|
|
72
|
+
execSync(`npx -y @blocklet/cli version ${newVersion}`, {
|
|
73
|
+
stdio: 'inherit',
|
|
74
|
+
cwd: blockletInfoPath,
|
|
75
|
+
});
|
|
76
|
+
// Update changelog
|
|
77
|
+
const changelogPath = join(blockletInfoPath, 'CHANGELOG.md');
|
|
78
|
+
await ensureFile(changelogPath);
|
|
79
|
+
let oldChangelog = '';
|
|
80
|
+
try {
|
|
81
|
+
oldChangelog = await readFile(changelogPath, 'utf-8');
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// File doesn't exist, that's OK
|
|
85
|
+
}
|
|
86
|
+
const changelog = [title, newChangelog, oldChangelog].filter((item) => !!item).join('\n\n');
|
|
87
|
+
await writeFile(changelogPath, changelog);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error(chalk.red(`Failed to update blocklet at ${blockletInfoPath}:`, error));
|
|
91
|
+
}
|
|
92
|
+
console.log(chalk.green('✅ Bump version successfully!'));
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.log(chalk.red('Bump version failed'));
|
|
96
|
+
console.error(error);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
@@ -4,6 +4,8 @@ import inquirer from 'inquirer';
|
|
|
4
4
|
import pkg from '../../package.json' with { type: 'json' };
|
|
5
5
|
import { isCommandAvailable, installGlobalPackage } from '../utils/helper.js';
|
|
6
6
|
import { createAddCommand } from './add.js';
|
|
7
|
+
import { createBuildCommand } from './build.js';
|
|
8
|
+
import { createBumpVersionCommand } from './bump-version.js';
|
|
7
9
|
import { createDevCommand } from './dev.js';
|
|
8
10
|
import { createInitCommand } from './init.js';
|
|
9
11
|
import { createMigrateCommand } from './migrate.js';
|
|
@@ -58,6 +60,8 @@ export function createComponentStudioCommand() {
|
|
|
58
60
|
.addCommand(createUpdateCommand()) // 更新依赖
|
|
59
61
|
.addCommand(createAddCommand()) // 添加组件
|
|
60
62
|
.addCommand(createMigrateCommand()) // 迁移组件
|
|
63
|
+
.addCommand(createBuildCommand()) // 构建组件
|
|
64
|
+
.addCommand(createBumpVersionCommand()) // 版本升级
|
|
61
65
|
.showHelpAfterError(true)
|
|
62
66
|
.showSuggestionAfterError(true)
|
|
63
67
|
.action(() => {
|
package/dist/commands/dev.js
CHANGED
|
@@ -1,92 +1,16 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { spawn } from 'child_process';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
-
import fs from 'fs-extra';
|
|
5
|
-
import { existsSync } from 'node:fs';
|
|
6
|
-
import { join, dirname } from 'node:path';
|
|
7
4
|
import ora from 'ora';
|
|
8
|
-
import {
|
|
5
|
+
import { getProjectPath, setupWorkspaceEnvironment } from '../utils/helper.js';
|
|
9
6
|
async function createDevServer(projectPath, options) {
|
|
10
|
-
//
|
|
11
|
-
const workspacePath =
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
// 2. 准备基础环境
|
|
18
|
-
if (!existsSync(workspacePath)) {
|
|
19
|
-
const workspaceTemplatePath = getWorkspaceTemplatePath();
|
|
20
|
-
const workspaceParentDir = dirname(workspacePath);
|
|
21
|
-
// Selectively clean workspace parent directory, preserving @ prefixed directories
|
|
22
|
-
if (existsSync(workspaceParentDir)) {
|
|
23
|
-
const items = await fs.readdir(workspaceParentDir);
|
|
24
|
-
await Promise.all(items
|
|
25
|
-
.filter((item) => !item.startsWith('@'))
|
|
26
|
-
.map((item) => fs.remove(join(workspaceParentDir, item))));
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
// 创建 workspace parent 目录
|
|
30
|
-
await fs.ensureDir(workspaceParentDir);
|
|
31
|
-
}
|
|
32
|
-
// 复制 workspace 模板
|
|
33
|
-
await fs.copy(workspaceTemplatePath, workspacePath);
|
|
34
|
-
// 修改 workspace 目录中,_example 后缀的文件名,删除 _example 后缀
|
|
35
|
-
await replaceInDirectoryFileNameWithExample(workspacePath);
|
|
36
|
-
workspaceSpinner.succeed(chalk.green(`Workspace created successfully! ${workspacePathText}`));
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
workspaceSpinner.succeed(chalk.green(`Using existing workspace! ${workspacePathText}`));
|
|
40
|
-
}
|
|
41
|
-
// 3. 确保目录中有projects目录
|
|
42
|
-
const projectsDir = join(workspacePath, 'projects');
|
|
43
|
-
const projectLinkDir = join(projectsDir, 'user-project');
|
|
44
|
-
const projectLinkSpinner = ora({ text: 'Setting up project to workspace...', color: 'blue' }).start();
|
|
45
|
-
// 检查是否已经正确链接
|
|
46
|
-
let needsNewLink = true;
|
|
47
|
-
if (existsSync(projectsDir)) {
|
|
48
|
-
try {
|
|
49
|
-
const stats = await fs.lstat(projectLinkDir);
|
|
50
|
-
if (stats.isSymbolicLink()) {
|
|
51
|
-
const currentTarget = await fs.readlink(projectLinkDir);
|
|
52
|
-
if (currentTarget === projectPath) {
|
|
53
|
-
needsNewLink = false;
|
|
54
|
-
projectLinkSpinner.succeed(chalk.green('Project already linked to workspace!'));
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
await fs.remove(projectsDir);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
await fs.remove(projectsDir);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
await fs.remove(projectsDir);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (needsNewLink) {
|
|
69
|
-
await fs.ensureDir(projectsDir);
|
|
70
|
-
await fs.ensureSymlink(projectPath, projectLinkDir);
|
|
71
|
-
projectLinkSpinner.succeed(chalk.green('Project linked to workspace successfully!'));
|
|
72
|
-
}
|
|
73
|
-
let shouldInstallWorkspaceDeps = await checkShouldInstallDependencies(workspacePath);
|
|
74
|
-
let shouldInstallProjectDeps = await checkShouldInstallDependencies(projectPath);
|
|
75
|
-
// 5. 安装依赖
|
|
76
|
-
if (shouldInstallWorkspaceDeps || shouldInstallProjectDeps) {
|
|
77
|
-
const installDeps = {};
|
|
78
|
-
if (shouldInstallProjectDeps) {
|
|
79
|
-
installDeps.Project = projectPath;
|
|
80
|
-
}
|
|
81
|
-
if (shouldInstallWorkspaceDeps) {
|
|
82
|
-
installDeps.Workspace = workspacePath;
|
|
83
|
-
}
|
|
84
|
-
const result = await installDependencies(installDeps);
|
|
85
|
-
if (!result) {
|
|
86
|
-
process.exit(1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const devServerSpinner = ora({ text: 'Creating development server...', color: 'blue' }).start();
|
|
7
|
+
// Setup workspace environment
|
|
8
|
+
const { workspacePath, shouldInstallWorkspaceDeps, shouldInstallProjectDeps } = await setupWorkspaceEnvironment(projectPath, options);
|
|
9
|
+
// Start development server
|
|
10
|
+
const devServerSpinner = ora({
|
|
11
|
+
text: 'Creating development server...',
|
|
12
|
+
color: 'blue',
|
|
13
|
+
}).start();
|
|
90
14
|
const devProcess = spawn('pnpm', ['run', 'dev'], {
|
|
91
15
|
cwd: workspacePath,
|
|
92
16
|
stdio: 'inherit',
|
|
@@ -110,7 +34,10 @@ async function createDevServer(projectPath, options) {
|
|
|
110
34
|
shouldInstallProjectDeps,
|
|
111
35
|
close: async () => {
|
|
112
36
|
if (devProcess) {
|
|
113
|
-
const closeSpinner = ora({
|
|
37
|
+
const closeSpinner = ora({
|
|
38
|
+
text: 'Shutting down development server...',
|
|
39
|
+
color: 'yellow',
|
|
40
|
+
}).start();
|
|
114
41
|
devProcess.kill('SIGTERM');
|
|
115
42
|
closeSpinner.succeed(chalk.green('Development server stopped'));
|
|
116
43
|
}
|
package/dist/utils/helper.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const BLOCKLET_INFO_DIR = ".blocklet-info";
|
|
1
2
|
export declare function getWorkspaceTemplatePath(): string;
|
|
2
3
|
export declare function getWorkspacePath(version?: string): string;
|
|
3
4
|
export declare function getProjectPath(): string;
|
|
@@ -101,3 +102,17 @@ export declare function isCommandAvailable(command: string): boolean;
|
|
|
101
102
|
*/
|
|
102
103
|
export declare function installGlobalPackage(packageName: string): Promise<boolean>;
|
|
103
104
|
export declare function checkShouldInstallDependencies(dirPath: string): Promise<boolean>;
|
|
105
|
+
/**
|
|
106
|
+
* Setup workspace environment for development
|
|
107
|
+
* @param projectPath - Current project path
|
|
108
|
+
* @param options - Setup options
|
|
109
|
+
* @returns Setup result with dependency installation status
|
|
110
|
+
*/
|
|
111
|
+
export declare function setupWorkspaceEnvironment(projectPath: string, options?: {
|
|
112
|
+
version?: string;
|
|
113
|
+
}): Promise<{
|
|
114
|
+
workspacePath: string;
|
|
115
|
+
projectPath: string;
|
|
116
|
+
shouldInstallWorkspaceDeps: boolean;
|
|
117
|
+
shouldInstallProjectDeps: boolean;
|
|
118
|
+
}>;
|
package/dist/utils/helper.js
CHANGED
|
@@ -10,8 +10,9 @@ import { join, resolve, dirname, basename, relative } from 'node:path';
|
|
|
10
10
|
import ora from 'ora';
|
|
11
11
|
import os from 'os';
|
|
12
12
|
import path from 'path';
|
|
13
|
-
const DEFAULT_WORKSPACE_VERSION = '0.2.
|
|
13
|
+
const DEFAULT_WORKSPACE_VERSION = '0.2.1';
|
|
14
14
|
const METADATA_FILE_NAME = '@metadata.json';
|
|
15
|
+
export const BLOCKLET_INFO_DIR = '.blocklet-info';
|
|
15
16
|
// 获取CLI内置的workspace模板路径
|
|
16
17
|
export function getWorkspaceTemplatePath() {
|
|
17
18
|
return join(import.meta.dirname, '../../templates/workspace');
|
|
@@ -122,34 +123,39 @@ export async function installDependencies(dirs, operation = 'install') {
|
|
|
122
123
|
// ignore error
|
|
123
124
|
}
|
|
124
125
|
let errorOutput = '';
|
|
125
|
-
|
|
126
|
+
let fullOutput = '';
|
|
127
|
+
const command = "npx -y taze -f -r -w -n '/arcblock|ocap|abtnode|blocklet|did-connect|did-comment|nedb/' minor && pnpm install -f --no-frozen-lockfile && pnpm dedupe";
|
|
128
|
+
const depProcess = exec(command, {
|
|
126
129
|
cwd: dirPath,
|
|
127
130
|
env: {
|
|
128
131
|
...process.env,
|
|
129
132
|
NODE_ENV: 'development',
|
|
130
133
|
},
|
|
131
134
|
});
|
|
132
|
-
//
|
|
133
|
-
depProcess.stderr?.on('data', (data) => {
|
|
134
|
-
errorOutput += data.toString();
|
|
135
|
-
});
|
|
136
|
-
// 收集标准输出(可能包含错误信息)
|
|
135
|
+
// 收集所有输出
|
|
137
136
|
depProcess.stdout?.on('data', (data) => {
|
|
138
137
|
const output = data.toString();
|
|
138
|
+
fullOutput += output;
|
|
139
139
|
if (output.toLowerCase().includes('error')) {
|
|
140
140
|
errorOutput += output;
|
|
141
141
|
}
|
|
142
142
|
});
|
|
143
|
+
// 收集错误输出
|
|
144
|
+
depProcess.stderr?.on('data', (data) => {
|
|
145
|
+
const output = data.toString();
|
|
146
|
+
errorOutput += output;
|
|
147
|
+
fullOutput += output;
|
|
148
|
+
});
|
|
143
149
|
depProcess.on('close', (code) => {
|
|
144
150
|
if (code === 0) {
|
|
145
151
|
resolve();
|
|
146
152
|
}
|
|
147
153
|
else {
|
|
148
|
-
reject(new Error(`${dirType} dependencies install failed with code ${code}. ${errorOutput ? `\nError details:\n${errorOutput?.trimStart()}` : ''}}`));
|
|
154
|
+
reject(new Error(`${dirType} dependencies install failed with code ${code}. ${errorOutput ? `\nError details:\n${errorOutput?.trimStart()}` : ''}\n\nFull output:\n${fullOutput}`));
|
|
149
155
|
}
|
|
150
156
|
});
|
|
151
157
|
depProcess.on('error', (error) => {
|
|
152
|
-
reject(new Error(`${dirType} process error: ${error.message}\n${errorOutput}`));
|
|
158
|
+
reject(new Error(`${dirType} process error: ${error.message}\n${errorOutput}\n\nFull output:\n${fullOutput}`));
|
|
153
159
|
});
|
|
154
160
|
});
|
|
155
161
|
})
|
|
@@ -540,3 +546,102 @@ export async function installGlobalPackage(packageName) {
|
|
|
540
546
|
export async function checkShouldInstallDependencies(dirPath) {
|
|
541
547
|
return !(await fs.exists(join(dirPath, 'node_modules'))) || !(await fs.exists(join(dirPath, 'pnpm-lock.yaml')));
|
|
542
548
|
}
|
|
549
|
+
/**
|
|
550
|
+
* Setup workspace environment for development
|
|
551
|
+
* @param projectPath - Current project path
|
|
552
|
+
* @param options - Setup options
|
|
553
|
+
* @returns Setup result with dependency installation status
|
|
554
|
+
*/
|
|
555
|
+
export async function setupWorkspaceEnvironment(projectPath, options = {}) {
|
|
556
|
+
// 1. Create workspace
|
|
557
|
+
const workspacePath = getWorkspacePath(options.version);
|
|
558
|
+
const workspaceSpinner = ora({
|
|
559
|
+
text: 'Creating workspace...',
|
|
560
|
+
color: 'blue',
|
|
561
|
+
}).start();
|
|
562
|
+
const workspacePathText = chalk.blue(`The workspace directory: ${workspacePath}`);
|
|
563
|
+
if (options.version) {
|
|
564
|
+
console.log(chalk.cyan(`Using version: ${options.version}`));
|
|
565
|
+
}
|
|
566
|
+
// 2. Prepare base environment
|
|
567
|
+
if (!existsSync(workspacePath)) {
|
|
568
|
+
const workspaceTemplatePath = getWorkspaceTemplatePath();
|
|
569
|
+
const workspaceParentDir = dirname(workspacePath);
|
|
570
|
+
// Selectively clean workspace parent directory, preserving @ prefixed directories
|
|
571
|
+
if (existsSync(workspaceParentDir)) {
|
|
572
|
+
const items = await fs.readdir(workspaceParentDir);
|
|
573
|
+
await Promise.all(items
|
|
574
|
+
.filter((item) => !item.startsWith('@'))
|
|
575
|
+
.map((item) => fs.remove(join(workspaceParentDir, item))));
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
// Create workspace parent directory
|
|
579
|
+
await fs.ensureDir(workspaceParentDir);
|
|
580
|
+
}
|
|
581
|
+
// Copy workspace template
|
|
582
|
+
await fs.copy(workspaceTemplatePath, workspacePath);
|
|
583
|
+
// Replace _example suffix in workspace directory file names
|
|
584
|
+
await replaceInDirectoryFileNameWithExample(workspacePath);
|
|
585
|
+
workspaceSpinner.succeed(chalk.green(`Workspace created successfully! ${workspacePathText}`));
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
workspaceSpinner.succeed(chalk.green(`Using existing workspace! ${workspacePathText}`));
|
|
589
|
+
}
|
|
590
|
+
// 3. Ensure projects directory exists
|
|
591
|
+
const projectsDir = join(workspacePath, 'projects');
|
|
592
|
+
const projectLinkDir = join(projectsDir, 'user-project');
|
|
593
|
+
const projectLinkSpinner = ora({
|
|
594
|
+
text: 'Setting up project to workspace...',
|
|
595
|
+
color: 'blue',
|
|
596
|
+
}).start();
|
|
597
|
+
// Check if already correctly linked
|
|
598
|
+
let needsNewLink = true;
|
|
599
|
+
if (existsSync(projectsDir)) {
|
|
600
|
+
try {
|
|
601
|
+
const stats = await fs.lstat(projectLinkDir);
|
|
602
|
+
if (stats.isSymbolicLink()) {
|
|
603
|
+
const currentTarget = await fs.readlink(projectLinkDir);
|
|
604
|
+
if (currentTarget === projectPath) {
|
|
605
|
+
needsNewLink = false;
|
|
606
|
+
projectLinkSpinner.succeed(chalk.green('Project already linked to workspace!'));
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
await fs.remove(projectsDir);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
await fs.remove(projectsDir);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
catch (error) {
|
|
617
|
+
await fs.remove(projectsDir);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if (needsNewLink) {
|
|
621
|
+
await fs.ensureDir(projectsDir);
|
|
622
|
+
await fs.ensureSymlink(projectPath, projectLinkDir);
|
|
623
|
+
projectLinkSpinner.succeed(chalk.green('Project linked to workspace successfully!'));
|
|
624
|
+
}
|
|
625
|
+
const shouldInstallWorkspaceDeps = await checkShouldInstallDependencies(workspacePath);
|
|
626
|
+
const shouldInstallProjectDeps = await checkShouldInstallDependencies(projectPath);
|
|
627
|
+
// Install dependencies
|
|
628
|
+
if (shouldInstallWorkspaceDeps || shouldInstallProjectDeps) {
|
|
629
|
+
const installDeps = {};
|
|
630
|
+
if (shouldInstallProjectDeps) {
|
|
631
|
+
installDeps.Project = projectPath;
|
|
632
|
+
}
|
|
633
|
+
if (shouldInstallWorkspaceDeps) {
|
|
634
|
+
installDeps.Workspace = workspacePath;
|
|
635
|
+
}
|
|
636
|
+
const result = await installDependencies(installDeps);
|
|
637
|
+
if (!result) {
|
|
638
|
+
process.exit(1);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return {
|
|
642
|
+
workspacePath,
|
|
643
|
+
projectPath,
|
|
644
|
+
shouldInstallWorkspaceDeps,
|
|
645
|
+
shouldInstallProjectDeps,
|
|
646
|
+
};
|
|
647
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/component-studio-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.16",
|
|
4
4
|
"description": "CLI for Component Studio",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"adm-zip": "^0.5.16",
|
|
33
34
|
"chalk": "^5.4.1",
|
|
34
35
|
"commander": "^13.1.0",
|
|
35
36
|
"fs-extra": "^11.2.0",
|
|
@@ -41,9 +42,11 @@
|
|
|
41
42
|
"node-fetch": "^2.7.0",
|
|
42
43
|
"ora": "^8.2.0",
|
|
43
44
|
"pretty-error": "^4.0.0",
|
|
44
|
-
"tar": "^7.4.3"
|
|
45
|
+
"tar": "^7.4.3",
|
|
46
|
+
"yaml": "^2.5.0"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
49
|
+
"@types/adm-zip": "^0.5.7",
|
|
47
50
|
"@types/glob": "^8.1.0",
|
|
48
51
|
"@types/node": "^22.14.1",
|
|
49
52
|
"npm-run-all": "^4.1.5",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
NODE_OPTIONS: '--max_old_space_size=6144'
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
Deploy:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
if: "contains(toJSON(github.event.commits.*.message), '[ci]')"
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout repo
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- uses: pnpm/action-setup@v3
|
|
22
|
+
with:
|
|
23
|
+
version: 9
|
|
24
|
+
|
|
25
|
+
- name: Setup node
|
|
26
|
+
uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: 20
|
|
29
|
+
cache: pnpm
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: pnpm install
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: pnpm lint
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Code Review
|
|
2
|
+
|
|
3
|
+
permissions:
|
|
4
|
+
contents: read
|
|
5
|
+
pull-requests: write
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
pull_request:
|
|
9
|
+
branches:
|
|
10
|
+
- main
|
|
11
|
+
pull_request_review_comment:
|
|
12
|
+
types: [created]
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ${{ github.repository }}-${{ github.event.number || github.head_ref ||
|
|
16
|
+
github.sha }}-${{ github.workflow }}-${{ github.event_name ==
|
|
17
|
+
'pull_request_review_comment' && 'pr_comment' || 'pr' }}
|
|
18
|
+
cancel-in-progress: ${{ github.event_name != 'pull_request_review_comment' }}
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
review:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: blocklet/aigne-code-reviewer@v0.1.14
|
|
25
|
+
env:
|
|
26
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
27
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
28
|
+
DEBUG: "@aigne/*"
|
|
29
|
+
with:
|
|
30
|
+
debug: true
|
|
31
|
+
language: "zh-CN"
|
|
32
|
+
review_simple_changes: false
|
|
33
|
+
review_comment_lgtm: false
|
|
34
|
+
disable_review: true
|
|
35
|
+
path_filters: |
|
|
36
|
+
!core/types/**
|
|
37
|
+
!core/schema/lib/**
|
|
38
|
+
!**/types.js
|
|
39
|
+
!**/*.d.ts
|
|
40
|
+
!**/*.lock
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: 'Lint PR Title'
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types:
|
|
6
|
+
- opened
|
|
7
|
+
- reopened
|
|
8
|
+
- edited
|
|
9
|
+
- synchronize
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
- dev
|
|
13
|
+
- master
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
lint-title:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: ArcBlock/action-lint-pull-request-title@master
|
|
20
|
+
env:
|
|
21
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: Upload To Blocklet Store
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
NODE_OPTIONS: "--max_old_space_size=8192"
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
- dev
|
|
11
|
+
- release
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
Deploy:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
if: "! contains(toJSON(github.event.commits.head_commit.message), '[skip ci]')"
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Set environment variables based on branch
|
|
21
|
+
run: |
|
|
22
|
+
echo "Current branch: ${{ github.ref_name }}"
|
|
23
|
+
if [ "${{ github.ref_name }}" == "main" ]; then
|
|
24
|
+
echo "STORE_ENDPOINT=${{ secrets.STORE_ENDPOINT_TEST }}" >> $GITHUB_ENV
|
|
25
|
+
echo "STORE_ACCESS_TOKEN=${{ secrets.STORE_ACCESS_TOKEN_TEST }}" >> $GITHUB_ENV
|
|
26
|
+
elif [ "${{ github.ref_name }}" == "dev" ]; then
|
|
27
|
+
echo "STORE_ENDPOINT=${{ secrets.STORE_ENDPOINT_DEV }}" >> $GITHUB_ENV
|
|
28
|
+
echo "STORE_ACCESS_TOKEN=${{ secrets.STORE_ACCESS_TOKEN_DEV }}" >> $GITHUB_ENV
|
|
29
|
+
elif [ "${{ github.ref_name }}" == "release" ]; then
|
|
30
|
+
echo "STORE_ENDPOINT=${{ secrets.STORE_ENDPOINT_PROD }}" >> $GITHUB_ENV
|
|
31
|
+
echo "STORE_ACCESS_TOKEN=${{ secrets.STORE_ACCESS_TOKEN_PROD }}" >> $GITHUB_ENV
|
|
32
|
+
else
|
|
33
|
+
echo "❌ Error: Branch '${{ github.ref_name }}' is not supported for upload to blocklet store"
|
|
34
|
+
echo "✅ Supported branches: main, dev, release"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
- name: Checkout repo
|
|
39
|
+
uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- uses: pnpm/action-setup@v3
|
|
42
|
+
with:
|
|
43
|
+
version: 9
|
|
44
|
+
|
|
45
|
+
- name: Setup node
|
|
46
|
+
uses: actions/setup-node@v4
|
|
47
|
+
with:
|
|
48
|
+
node-version: 22
|
|
49
|
+
cache: pnpm
|
|
50
|
+
|
|
51
|
+
- name: Using Component Studio to build project
|
|
52
|
+
run: npx -y @blocklet/cli@beta component build --bundle-resource-blocklet
|
|
53
|
+
|
|
54
|
+
- name: Blocklet workflow
|
|
55
|
+
if: "! contains(toJSON(github.event.commits.head_commit.message), '[skip blocklet]')"
|
|
56
|
+
uses: blocklet/action-workflow@v1
|
|
57
|
+
env:
|
|
58
|
+
COMPONENT_STORE_URL: ${{ env.STORE_ENDPOINT }}
|
|
59
|
+
with:
|
|
60
|
+
deps-server-version: beta
|
|
61
|
+
skip-deps: true
|
|
62
|
+
skip-release: true
|
|
63
|
+
skip-deploy: true
|
|
64
|
+
skip-bundle: true
|
|
65
|
+
skip-upload: false
|
|
66
|
+
bundle-command: pnpm -v # it means skip bundle
|
|
67
|
+
working-directory: .blocklet-info
|
|
68
|
+
store-endpoint: ${{ env.STORE_ENDPOINT }}
|
|
69
|
+
store-access-token: ${{ env.STORE_ACCESS_TOKEN }}
|
|
70
|
+
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
|
71
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: 'Version Check'
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types:
|
|
6
|
+
- opened
|
|
7
|
+
- reopened
|
|
8
|
+
- edited
|
|
9
|
+
- synchronize
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
- master
|
|
13
|
+
jobs:
|
|
14
|
+
main:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- name: action-version-check
|
|
18
|
+
uses: arcblock/action-version-check@master
|
|
19
|
+
env:
|
|
20
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "blocklet component dev",
|
|
9
9
|
"dev": "blocklet component dev",
|
|
10
|
-
"update:deps": "blocklet component update"
|
|
10
|
+
"update:deps": "blocklet component update",
|
|
11
|
+
"update": "blocklet component update",
|
|
12
|
+
"bundle": "blocklet component build --bundle-resource-blocklet",
|
|
13
|
+
"bump-version": "blocklet component bump-version"
|
|
11
14
|
},
|
|
12
15
|
"lint-staged": {
|
|
13
16
|
"*.{js,jsx,ts,tsx}": [
|
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"dev": "blocklet component dev",
|
|
14
14
|
"start": "blocklet component dev",
|
|
15
|
-
"lint": "biome check
|
|
15
|
+
"lint": "biome check ./src && tsc --noEmit",
|
|
16
16
|
"lint:skip": "echo 'skip lint'",
|
|
17
|
-
"lint:fix": "biome check --apply
|
|
18
|
-
"format": "biome format --write
|
|
17
|
+
"lint:fix": "biome check --apply ./src",
|
|
18
|
+
"format": "biome format --write ./src",
|
|
19
19
|
"prepare": "npx -y simple-git-hooks",
|
|
20
|
-
"
|
|
21
|
-
"update
|
|
20
|
+
"update:deps": "blocklet component update",
|
|
21
|
+
"update": "blocklet component update",
|
|
22
|
+
"bundle": "blocklet component build --bundle-resource-blocklet",
|
|
23
|
+
"bump-version": "blocklet component bump-version"
|
|
22
24
|
},
|
|
23
25
|
"lint-staged": {
|
|
24
26
|
"*.{mjs,js,jsx,ts,tsx,css,less,scss,json,graphql}": [
|
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "blocklet component dev",
|
|
9
9
|
"dev": "blocklet component dev",
|
|
10
|
-
"update:deps": "blocklet component update"
|
|
10
|
+
"update:deps": "blocklet component update",
|
|
11
|
+
"update": "blocklet component update",
|
|
12
|
+
"bundle": "blocklet component build --bundle-resource-blocklet",
|
|
13
|
+
"bump-version": "blocklet component bump-version"
|
|
11
14
|
},
|
|
12
15
|
"lint-staged": {
|
|
13
16
|
"*.{js,jsx,ts,tsx}": [
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"dev": "COMPONENT_STORE_URL=https://test.store.blocklet.dev blocklet dev",
|
|
18
|
-
"lint": "biome check
|
|
18
|
+
"lint": "biome check ./src && tsc --noEmit",
|
|
19
19
|
"lint:skip": "echo 'skip lint'",
|
|
20
|
-
"lint:fix": "biome check --apply
|
|
21
|
-
"format": "biome format --write
|
|
20
|
+
"lint:fix": "biome check --apply ./src",
|
|
21
|
+
"format": "biome format --write ./src",
|
|
22
22
|
"start": "vite-node -c vite-server.config.ts -w api/dev.ts",
|
|
23
23
|
"clean": "node scripts/build-clean.mjs",
|
|
24
24
|
"bundle": "echo 'skip bundle'",
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
import { execSync } from 'child_process';
|
|
3
|
-
import { $, chalk, fs } from 'zx';
|
|
4
|
-
|
|
5
|
-
async function main() {
|
|
6
|
-
execSync('bumpp --no-tag --no-commit --no-push package.json', { stdio: 'inherit' });
|
|
7
|
-
|
|
8
|
-
const { version } = await fs.readJSON('package.json');
|
|
9
|
-
await fs.writeFileSync('version', version);
|
|
10
|
-
|
|
11
|
-
let newChangelog = '';
|
|
12
|
-
try {
|
|
13
|
-
const gitRes = await $`git log --pretty=format:"- %s" "main"...HEAD`;
|
|
14
|
-
newChangelog = gitRes.stdout.trim();
|
|
15
|
-
} catch {
|
|
16
|
-
console.error(chalk.redBright('Could not get git log, please write changelog manually.'));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const now = new Date();
|
|
20
|
-
const currentDate = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
|
|
21
|
-
const title = `## ${version} (${currentDate})`;
|
|
22
|
-
|
|
23
|
-
await fs.ensureFile('CHANGELOG.md');
|
|
24
|
-
const oldChangelog = await fs.readFile('CHANGELOG.md', 'utf8');
|
|
25
|
-
const changelog = [title, newChangelog, oldChangelog].filter((item) => !!item).join('\n\n');
|
|
26
|
-
await fs.writeFile('CHANGELOG.md', changelog);
|
|
27
|
-
|
|
28
|
-
console.log(`\nNow you can make adjustments to ${chalk.cyan('CHANGELOG.md')} . Then press enter to continue.`);
|
|
29
|
-
|
|
30
|
-
process.stdin.setRawMode(true);
|
|
31
|
-
process.stdin.resume();
|
|
32
|
-
process.stdin.on('data', process.exit.bind(process, 0));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
main();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.1.0
|