@blocklet/cli 1.16.33 → 1.16.34-beta-20241120-080738-bbbe036c
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 +32 -25
- package/bin/blocklet.js +292 -1
- package/config.example.yml +33 -0
- package/lib/arcblock.js +53 -0
- package/lib/commands/blocklet/add.js +124 -0
- package/lib/commands/blocklet/assets/git-ignore +28 -0
- package/lib/commands/blocklet/assets/index.html +9 -0
- package/lib/commands/blocklet/assets/index.js +14 -0
- package/lib/commands/blocklet/assets/logo.png +0 -0
- package/lib/commands/blocklet/bundle/bundle.js +184 -0
- package/lib/commands/blocklet/bundle/bundlers/blocklet.js +138 -0
- package/lib/commands/blocklet/bundle/bundlers/changelog.js +100 -0
- package/lib/commands/blocklet/bundle/bundlers/logo.js +56 -0
- package/lib/commands/blocklet/bundle/bundlers/markdown.js +241 -0
- package/lib/commands/blocklet/bundle/bundlers/preference.js +50 -0
- package/lib/commands/blocklet/bundle/bundlers/readme.js +43 -0
- package/lib/commands/blocklet/bundle/bundlers/screenshots.js +94 -0
- package/lib/commands/blocklet/bundle/bundlers/simple.js +70 -0
- package/lib/commands/blocklet/bundle/compact/bundle-compact-file.js +48 -0
- package/lib/commands/blocklet/bundle/compact/bundle-merge-extra.js +66 -0
- package/lib/commands/blocklet/bundle/compact/default-external.js +5 -0
- package/lib/commands/blocklet/bundle/compact/index.js +88 -0
- package/lib/commands/blocklet/bundle/index.js +139 -0
- package/lib/commands/blocklet/bundle/pack.js +8 -0
- package/lib/commands/blocklet/bundle/parse-external-dependencies.js +97 -0
- package/lib/commands/blocklet/bundle/simple/index.js +62 -0
- package/lib/commands/blocklet/bundle/zip/archive.js +35 -0
- package/lib/commands/blocklet/bundle/zip/dependencies.js +333 -0
- package/lib/commands/blocklet/bundle/zip/index.js +165 -0
- package/lib/commands/blocklet/bundle/zip/main.js +124 -0
- package/lib/commands/blocklet/bundle/zip/node.js +59 -0
- package/lib/commands/blocklet/bundle/zip/resolve.js +93 -0
- package/lib/commands/blocklet/cleanup.js +52 -0
- package/lib/commands/blocklet/config.js +108 -0
- package/lib/commands/blocklet/connect.js +87 -0
- package/lib/commands/blocklet/create.js +38 -0
- package/lib/commands/blocklet/deploy.js +435 -0
- package/lib/commands/blocklet/dev.js +1000 -0
- package/lib/commands/blocklet/document.js +39 -0
- package/lib/commands/blocklet/exec.js +106 -0
- package/lib/commands/blocklet/init.js +300 -0
- package/lib/commands/blocklet/meta.js +22 -0
- package/lib/commands/blocklet/remove.js +35 -0
- package/lib/commands/blocklet/test.js +201 -0
- package/lib/commands/blocklet/upload.js +105 -0
- package/lib/commands/blocklet/version.js +81 -0
- package/lib/commands/server/cleanup.js +32 -0
- package/lib/commands/server/command.js +131 -0
- package/lib/commands/server/info.js +92 -0
- package/lib/commands/server/init.js +433 -0
- package/lib/commands/server/logs.js +99 -0
- package/lib/commands/server/rescue.js +71 -0
- package/lib/commands/server/start.js +821 -0
- package/lib/commands/server/status.js +107 -0
- package/lib/commands/server/stop.js +163 -0
- package/lib/commands/server/upgrade.js +123 -0
- package/lib/constant.js +21 -2
- package/lib/debug.js +20 -0
- package/lib/manager/config.js +122 -0
- package/lib/manager/deploy.js +75 -0
- package/lib/manager/index.js +23 -0
- package/lib/manager/process.js +47 -0
- package/lib/node.js +214 -0
- package/lib/port.js +19 -0
- package/lib/postinstall.js +3 -0
- package/lib/process/daemon.js +196 -0
- package/lib/process/service.js +86 -0
- package/lib/ui.js +137 -0
- package/lib/util/blocklet/config.js +78 -0
- package/lib/util/blocklet/env.js +172 -0
- package/lib/util/blocklet/meta.js +36 -0
- package/lib/util/blocklet/payment.js +88 -0
- package/lib/util/blocklet/sign.js +21 -0
- package/lib/util/blocklet/tar.js +119 -0
- package/lib/util/convert-to-nosources-sourcemap.js +37 -0
- package/lib/util/docker-status-log.js +17 -0
- package/lib/util/exit-when-server-stopped.js +44 -0
- package/lib/util/get-cli-binary-name.js +8 -0
- package/lib/util/get-download-bundle-step.js +36 -0
- package/lib/util/get-service-instance-number.js +12 -0
- package/lib/util/index.js +626 -0
- package/lib/util/print-error.js +11 -0
- package/lib/util/print.js +9 -0
- package/lib/util/what-uri.js +40 -0
- package/package.json +123 -27
- package/lib/run.d.ts +0 -2
- package/lib/run.js +0 -73
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
const os = require('os');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const packList = require('npm-packlist');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const uniq = require('lodash/uniq');
|
|
6
|
+
const pick = require('lodash/pick');
|
|
7
|
+
const merge = require('lodash/merge');
|
|
8
|
+
const cloneDeep = require('lodash/cloneDeep');
|
|
9
|
+
const fs = require('fs-extra');
|
|
10
|
+
const fg = require('fast-glob');
|
|
11
|
+
const isGlob = require('is-glob');
|
|
12
|
+
const { list: metaFiles, select: getMetaFile, update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
13
|
+
const {
|
|
14
|
+
BLOCKLET_BUNDLE_FOLDER,
|
|
15
|
+
BLOCKLET_ENTRY_FILE,
|
|
16
|
+
BLOCKLET_BUNDLE_FILE,
|
|
17
|
+
BLOCKLET_OPEN_API_FILE,
|
|
18
|
+
BLOCKLET_OPEN_API_FILE_JSON,
|
|
19
|
+
BLOCKLET_OPEN_COMPONENT_FILE,
|
|
20
|
+
BLOCKLET_OPEN_COMPONENT_FILE_JSON,
|
|
21
|
+
BLOCKLET_RESOURCE_DIR,
|
|
22
|
+
} = require('@blocklet/constant');
|
|
23
|
+
const formatBackSlash = require('@abtnode/util/lib/format-back-slash');
|
|
24
|
+
const { getGitHash, printInfo } = require('../../../util');
|
|
25
|
+
const SimpleBundler = require('./bundlers/simple');
|
|
26
|
+
const { parseExternalDependencies } = require('./parse-external-dependencies');
|
|
27
|
+
|
|
28
|
+
const createBlockletEntry = (blockletDir, entryFile) => {
|
|
29
|
+
const packageFile = path.join(blockletDir, 'package.json');
|
|
30
|
+
const hasPackageFile = fs.existsSync(packageFile);
|
|
31
|
+
const tempEntryFile = formatBackSlash(`./${path.normalize(entryFile)}`);
|
|
32
|
+
if (hasPackageFile) {
|
|
33
|
+
const packageJson = JSON.parse(fs.readFileSync(packageFile).toString());
|
|
34
|
+
if (packageJson.type === 'module') {
|
|
35
|
+
return `import '${tempEntryFile}';${os.EOL}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return `require('${tempEntryFile}');${os.EOL}`;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const PACKAGE_JSON_KEYS = [
|
|
43
|
+
'name',
|
|
44
|
+
'version',
|
|
45
|
+
'type',
|
|
46
|
+
'description',
|
|
47
|
+
'keywords',
|
|
48
|
+
'author',
|
|
49
|
+
'repository',
|
|
50
|
+
'bugs',
|
|
51
|
+
'publishConfig',
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const createBlockletBundle = async ({
|
|
55
|
+
blockletDir,
|
|
56
|
+
meta,
|
|
57
|
+
updates = {},
|
|
58
|
+
inMonoRepo = false,
|
|
59
|
+
withChangeLog = true,
|
|
60
|
+
externals = [],
|
|
61
|
+
externalManager = 'npm',
|
|
62
|
+
}) => {
|
|
63
|
+
// 新增 meta.files 支持 glob 后,需要将 glob 匹配的文件也进行复制放入 bundle 中
|
|
64
|
+
const metaFileList = meta.files || [];
|
|
65
|
+
const distDir = path.join(blockletDir, BLOCKLET_BUNDLE_FOLDER);
|
|
66
|
+
|
|
67
|
+
let files = [
|
|
68
|
+
`!${path.dirname(BLOCKLET_BUNDLE_FOLDER)}`,
|
|
69
|
+
...metaFiles,
|
|
70
|
+
BLOCKLET_BUNDLE_FILE,
|
|
71
|
+
BLOCKLET_ENTRY_FILE,
|
|
72
|
+
BLOCKLET_OPEN_API_FILE,
|
|
73
|
+
BLOCKLET_OPEN_API_FILE_JSON,
|
|
74
|
+
BLOCKLET_OPEN_COMPONENT_FILE,
|
|
75
|
+
BLOCKLET_OPEN_COMPONENT_FILE_JSON,
|
|
76
|
+
BLOCKLET_RESOURCE_DIR,
|
|
77
|
+
'LICENSE',
|
|
78
|
+
meta.group === 'static' ? meta.main : '',
|
|
79
|
+
...metaFileList,
|
|
80
|
+
].filter(Boolean);
|
|
81
|
+
|
|
82
|
+
// #5823, always include the entire main folder for dapps
|
|
83
|
+
if (meta.group === 'dapp') {
|
|
84
|
+
const mainPath = path.join(blockletDir, meta.main);
|
|
85
|
+
const hasMainFile = fs.statSync(mainPath).isFile();
|
|
86
|
+
if (hasMainFile) {
|
|
87
|
+
if (path.dirname(mainPath) !== blockletDir) {
|
|
88
|
+
files.unshift(path.dirname(meta.main));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
files = uniq(files);
|
|
94
|
+
|
|
95
|
+
if (!fs.existsSync(distDir)) {
|
|
96
|
+
fs.mkdirSync(distDir);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// https://docs.npmjs.com/cli/v9/configuring-npm/package-json#files
|
|
100
|
+
const selected = await packList({ package: { files } }, { path: blockletDir });
|
|
101
|
+
selected.forEach((fileName) => {
|
|
102
|
+
const source = path.join(blockletDir, fileName);
|
|
103
|
+
const target = path.join(distDir, fileName);
|
|
104
|
+
if (fs.existsSync(source) && !fs.existsSync(target)) {
|
|
105
|
+
fs.copySync(source, target);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
await new SimpleBundler({ blockletDir, inMonoRepo, withChangeLog, meta }).bundle();
|
|
110
|
+
|
|
111
|
+
// Update blocklet meta file in the bundle
|
|
112
|
+
try {
|
|
113
|
+
updates.gitHash = getGitHash(blockletDir);
|
|
114
|
+
} catch (err) {
|
|
115
|
+
// Do nothing
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const metaToUpdate = getMetaFile(path.join(distDir));
|
|
119
|
+
const rawMeta = cloneDeep(meta);
|
|
120
|
+
updateMetaFile(metaToUpdate, Object.assign(rawMeta, updates));
|
|
121
|
+
|
|
122
|
+
// Rewrite the package.json file if exist
|
|
123
|
+
const packageFile = path.join(blockletDir, 'package.json');
|
|
124
|
+
const hasPackageFile = fs.existsSync(packageFile);
|
|
125
|
+
if (hasPackageFile) {
|
|
126
|
+
const json = JSON.parse(fs.readFileSync(packageFile).toString());
|
|
127
|
+
const result = parseExternalDependencies({
|
|
128
|
+
externals,
|
|
129
|
+
externalManager,
|
|
130
|
+
distDir,
|
|
131
|
+
persist: false,
|
|
132
|
+
});
|
|
133
|
+
fs.writeFileSync(
|
|
134
|
+
path.join(distDir, 'package.json'),
|
|
135
|
+
JSON.stringify(merge(pick(json, PACKAGE_JSON_KEYS), result), null, 2)
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 获取所有 extraFiles,理论上所有 .js 都需要查出来,才能进一步去找到依赖
|
|
142
|
+
* @param {Object} meta blocklet meta
|
|
143
|
+
* @returns Array
|
|
144
|
+
*/
|
|
145
|
+
const getExtraFiles = (blockletDir, meta) => {
|
|
146
|
+
const { files = [], scripts = {} } = meta;
|
|
147
|
+
const fileList = [];
|
|
148
|
+
for (const file of files) {
|
|
149
|
+
if (isGlob(file)) {
|
|
150
|
+
const entries = fg.sync(file, { cwd: blockletDir, absolute: false });
|
|
151
|
+
fileList.push(...entries);
|
|
152
|
+
} else {
|
|
153
|
+
const filePath = path.join(blockletDir, file);
|
|
154
|
+
const fileStat = fs.lstatSync(filePath);
|
|
155
|
+
if (fileStat.isFile() && path.extname(filePath) === '.js') {
|
|
156
|
+
fileList.push(file);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
Object.entries(scripts).forEach(([key, script]) => {
|
|
162
|
+
if (key.startsWith('pre') || key.startsWith('post')) {
|
|
163
|
+
[script]
|
|
164
|
+
.concat(script.split(' ').filter(Boolean))
|
|
165
|
+
.filter((x) => path.extname(x) === '.js')
|
|
166
|
+
.forEach((x) => {
|
|
167
|
+
const filePath = path.join(blockletDir, x);
|
|
168
|
+
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
|
|
169
|
+
printInfo(`Extra script file detected for bundling ${chalk.cyan(x)}`);
|
|
170
|
+
fileList.push(x);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// add migration scripts
|
|
177
|
+
const migrationScripts = fg.sync('migration/*.js', { cwd: blockletDir, absolute: false });
|
|
178
|
+
fileList.push(...migrationScripts);
|
|
179
|
+
migrationScripts.forEach((x) => printInfo(`Extra migration file detected for bundling ${chalk.cyan(x)}`));
|
|
180
|
+
|
|
181
|
+
return uniq([...fileList]).filter((x) => x !== BLOCKLET_ENTRY_FILE);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
module.exports = { createBlockletBundle, createBlockletEntry, getExtraFiles };
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fg = require('fast-glob');
|
|
3
|
+
const isEmpty = require('lodash/isEmpty');
|
|
4
|
+
const { printError, printWarning, print } = require('../../../../util');
|
|
5
|
+
const MarkdownBundler = require('./markdown');
|
|
6
|
+
|
|
7
|
+
class BlockletMdBundler extends MarkdownBundler {
|
|
8
|
+
static BLOCKLET_MD_REGEX = /blocklet\.[\S]*md$/i;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates an instance of BlockletMdBundler.
|
|
12
|
+
* @param {{
|
|
13
|
+
* blockletDir: string,
|
|
14
|
+
* blockletMdFileName: string, // 约定: blocklet.md的文件名是小写的
|
|
15
|
+
* backupMdFileNames?: string[];
|
|
16
|
+
* required?: boolean = false;
|
|
17
|
+
* duplicateMdFileName?: string;
|
|
18
|
+
* }} { blockletDir, backupMdFileNames, backupMdFileName, required, duplicateMdFileName }
|
|
19
|
+
* @memberof BlockletMdBundler
|
|
20
|
+
*/
|
|
21
|
+
constructor({ blockletDir, blockletMdFileName, backupMdFileNames, required = false, duplicateMdFileName }) {
|
|
22
|
+
super({ blockletDir });
|
|
23
|
+
this.blockletMdFileName = blockletMdFileName;
|
|
24
|
+
this.backupMdFileNames = backupMdFileNames;
|
|
25
|
+
this.required = required;
|
|
26
|
+
this.duplicateMdFileName = duplicateMdFileName;
|
|
27
|
+
this.fastGlobOptions = {
|
|
28
|
+
cwd: this.blockletDir,
|
|
29
|
+
deep: 1,
|
|
30
|
+
caseSensitiveMatch: false,
|
|
31
|
+
onlyFiles: true,
|
|
32
|
+
absolute: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
*
|
|
39
|
+
* @return {string[]} blocklet.md absolute paths
|
|
40
|
+
* @memberof BlockletMdBundler
|
|
41
|
+
*/
|
|
42
|
+
async _find() {
|
|
43
|
+
const found = fg.sync(this.blockletMdFileName, this.fastGlobOptions);
|
|
44
|
+
|
|
45
|
+
if (found.length === 0 && !isEmpty(this.backupMdFileNames)) {
|
|
46
|
+
const foundByBackupMdFileName = await this._findByBackupFileNames();
|
|
47
|
+
if (foundByBackupMdFileName.length === 1) {
|
|
48
|
+
return foundByBackupMdFileName;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (found.length === 0 && this.required) {
|
|
53
|
+
printError(`File ${chalk.red(this.blockletMdFileName)} must exist in ${chalk.cyan(this.blockletDir)}`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (found.length > 1) {
|
|
58
|
+
printError(
|
|
59
|
+
`Only one ${chalk.red(this.blockletMdFileName)}(not case sensitive) can exist in ${chalk.cyan(
|
|
60
|
+
this.blockletDir
|
|
61
|
+
)}`
|
|
62
|
+
);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (this.duplicateMdFileName) {
|
|
67
|
+
await this.warnDuplicateMdFileName();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return found;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
_findByBackupFileNames() {
|
|
74
|
+
for (const backupMdFileName of this.backupMdFileNames) {
|
|
75
|
+
// 我们先来找找备份文件
|
|
76
|
+
const foundByBackupMdFileName = fg.sync(backupMdFileName, this.fastGlobOptions);
|
|
77
|
+
|
|
78
|
+
if (foundByBackupMdFileName.length === 1) {
|
|
79
|
+
// 找到了1个备份的文件
|
|
80
|
+
return foundByBackupMdFileName;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (foundByBackupMdFileName.length > 1) {
|
|
84
|
+
// 备份文件太多了,我不知道选哪个好
|
|
85
|
+
printError(
|
|
86
|
+
`Only one ${chalk.red(backupMdFileName)}(not case sensitive) can exist in ${chalk.cyan(this.blockletDir)}`
|
|
87
|
+
);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (this.required) {
|
|
93
|
+
// 连备份文件也没找到,但是文件还是必要的,不能没有啊,故中断当前任务
|
|
94
|
+
printError(
|
|
95
|
+
`Either ${chalk.red(this.blockletMdFileName)} or ${this.backupMdFileNames
|
|
96
|
+
.map((backupMdFileName) => chalk.red(backupMdFileName))
|
|
97
|
+
.join(',')} should exist in ${chalk.cyan(this.blockletDir)}`
|
|
98
|
+
);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
warnDuplicateMdFileName() {
|
|
106
|
+
const foundByDuplicateMdFileName = fg.sync(this.duplicateMdFileName, this.fastGlobOptions);
|
|
107
|
+
|
|
108
|
+
if (foundByDuplicateMdFileName.length) {
|
|
109
|
+
// 我是故意这么换行的,不然warning信息和其他信息会显示在同一行,不太美观
|
|
110
|
+
print();
|
|
111
|
+
printWarning(
|
|
112
|
+
`File ${chalk.cyan(this.blockletMdFileName)} is currently in use, file ${chalk.yellow(
|
|
113
|
+
this.duplicateMdFileName
|
|
114
|
+
)} is ignored`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
bundle() {
|
|
120
|
+
return super.bundle();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
*
|
|
126
|
+
* @param {string} dest
|
|
127
|
+
* @param {string | NodeJS.ArrayBufferView} data
|
|
128
|
+
* @memberof BlockletMdBundler
|
|
129
|
+
*/
|
|
130
|
+
async writeFile(dest, data) {
|
|
131
|
+
await super.writeFile(
|
|
132
|
+
dest.replace(BlockletMdBundler.BLOCKLET_MD_REGEX, this.blockletMdFileName.toLowerCase()),
|
|
133
|
+
data
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = BlockletMdBundler;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fromMarkdown = require('mdast-util-from-markdown');
|
|
3
|
+
const detectWorkspace = require('@abtnode/util/lib/detect-workspace');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const { BLOCKLET_BUNDLE_FOLDER } = require('@blocklet/constant');
|
|
6
|
+
const fg = require('fast-glob');
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
const { printError } = require('../../../../util');
|
|
9
|
+
|
|
10
|
+
class ChangelogBundler {
|
|
11
|
+
constructor({ blockletDir, inMonoRepo }) {
|
|
12
|
+
this.blockletDir = blockletDir;
|
|
13
|
+
this.inMonoRepo = inMonoRepo;
|
|
14
|
+
this.bundlerDir = path.join(this.blockletDir, BLOCKLET_BUNDLE_FOLDER);
|
|
15
|
+
this.changelogFileName = 'CHANGELOG.md';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
* @return {string | null} changelog.md absolute path
|
|
22
|
+
* @memberof ChangelogBundler
|
|
23
|
+
*/
|
|
24
|
+
_find() {
|
|
25
|
+
const found = fg.sync(this.changelogFileName, {
|
|
26
|
+
cwd: this.blockletDir,
|
|
27
|
+
deep: 1,
|
|
28
|
+
caseSensitiveMatch: false,
|
|
29
|
+
onlyFiles: true,
|
|
30
|
+
absolute: true,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (found.length === 1) {
|
|
34
|
+
return found[0];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (found.length > 1) {
|
|
38
|
+
printError(
|
|
39
|
+
`Only one ${chalk.red(this.changelogFileName)}(not case sensitive) can exist in ${chalk.cyan(this.blockletDir)}`
|
|
40
|
+
);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (this.inMonoRepo) {
|
|
45
|
+
const workspace = detectWorkspace(this.blockletDir);
|
|
46
|
+
if (workspace) {
|
|
47
|
+
const foundByMonoRepo = fg.sync(this.changelogFileName, {
|
|
48
|
+
cwd: workspace.dir,
|
|
49
|
+
deep: 1,
|
|
50
|
+
caseSensitiveMatch: false,
|
|
51
|
+
onlyFiles: true,
|
|
52
|
+
absolute: true,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (foundByMonoRepo.length === 1) {
|
|
56
|
+
return foundByMonoRepo[0];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (foundByMonoRepo.length > 1) {
|
|
60
|
+
printError(
|
|
61
|
+
`Only one ${chalk.red(this.changelogFileName)}(not case sensitive) can exist in ${chalk.cyan(
|
|
62
|
+
workspace.dir
|
|
63
|
+
)}`
|
|
64
|
+
);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async _bundle(changelogAbsolutePath) {
|
|
74
|
+
if (changelogAbsolutePath && fs.existsSync(changelogAbsolutePath)) {
|
|
75
|
+
await fs.copy(changelogAbsolutePath, path.join(this.bundlerDir, this.changelogFileName));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
_validate(changelogAbsolutePath) {
|
|
80
|
+
if (changelogAbsolutePath && fs.existsSync(changelogAbsolutePath)) {
|
|
81
|
+
const ast = fromMarkdown(fs.readFileSync(changelogAbsolutePath));
|
|
82
|
+
const children = ast?.children || [];
|
|
83
|
+
children.forEach((element) => {
|
|
84
|
+
if (element.type === 'heading' && element.depth !== 2) {
|
|
85
|
+
const line = element.position?.start.line || 0;
|
|
86
|
+
printError(`Only H2 headings should be used in ${chalk.cyan(changelogAbsolutePath)} at line ${line}`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async bundle() {
|
|
94
|
+
const changelogAbsolutePath = await this._find();
|
|
95
|
+
this._validate(changelogAbsolutePath);
|
|
96
|
+
await this._bundle(changelogAbsolutePath);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = ChangelogBundler;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { BLOCKLET_BUNDLE_FOLDER } = require('@blocklet/constant');
|
|
5
|
+
const { validateLogo } = require('@blocklet/images');
|
|
6
|
+
const { print, printError, printInfo, printWarning } = require('../../../../util');
|
|
7
|
+
|
|
8
|
+
class LogoBundler {
|
|
9
|
+
static minSide = 256;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates an instance of LogBundler.
|
|
13
|
+
* @param {{
|
|
14
|
+
* blockletDir: string,
|
|
15
|
+
* minSide: number = LogoBundler.minSide,
|
|
16
|
+
* logoFileName: string,
|
|
17
|
+
* maxFileSize: string = "100KB",
|
|
18
|
+
* }} { widthPx, heightPx, logoFileName }
|
|
19
|
+
* @see https://looka.com/blog/logo-size-guidelines/
|
|
20
|
+
* @memberof LogBundler
|
|
21
|
+
*/
|
|
22
|
+
constructor({ blockletDir = '', minSide = LogoBundler.minSide, logoFileName = '', maxFileSize = 1024 }) {
|
|
23
|
+
this.blockletDir = blockletDir;
|
|
24
|
+
this.logoFileName = logoFileName;
|
|
25
|
+
this.minSide = minSide;
|
|
26
|
+
this.maxFileSize = maxFileSize;
|
|
27
|
+
|
|
28
|
+
this.sourceLogoPath = path.join(blockletDir, logoFileName);
|
|
29
|
+
this.targetLogoPath = path.join(blockletDir, BLOCKLET_BUNDLE_FOLDER, logoFileName);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_verify() {
|
|
33
|
+
const errorMessages = validateLogo(this.logoFileName, {
|
|
34
|
+
extractedFilepath: this.blockletDir,
|
|
35
|
+
width: this.minSide,
|
|
36
|
+
maxSize: this.maxFileSize,
|
|
37
|
+
});
|
|
38
|
+
if (errorMessages.length) {
|
|
39
|
+
print('');
|
|
40
|
+
printWarning('Blocklet bundle failed! Please check the following errors about logo:');
|
|
41
|
+
errorMessages.forEach((errorMessage) => printError(errorMessage));
|
|
42
|
+
printInfo(
|
|
43
|
+
`You can run the command "${chalk.cyan('blocklet dev studio')}" to help you generate more standard images.`
|
|
44
|
+
);
|
|
45
|
+
print('');
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async bundle() {
|
|
51
|
+
this._verify();
|
|
52
|
+
await fs.copy(this.sourceLogoPath, this.targetLogoPath);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = LogoBundler;
|