@abtnode/core 1.16.22 → 1.16.23-beta-f85576a6
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.
|
@@ -3,13 +3,20 @@ const throttle = require('lodash/throttle');
|
|
|
3
3
|
const fs = require('fs-extra');
|
|
4
4
|
const logger = require('@abtnode/logger')('@abtnode/core:config-synchronizer');
|
|
5
5
|
const { encrypt } = require('@blocklet/sdk/lib/security');
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
APP_CONFIG_FILE_PATH,
|
|
8
|
+
APP_CONFIG_DIR,
|
|
9
|
+
COMPONENT_ENV_FILE_NAME,
|
|
10
|
+
APP_CONFIG_PUBLIC_DIR,
|
|
11
|
+
} = require('@blocklet/constant');
|
|
7
12
|
|
|
8
13
|
const { findComponentByIdV2, getSharedConfigObj, getBlockletAppIdList } = require('@blocklet/meta/lib/util');
|
|
9
14
|
const { getBlockletLanguages, getBlockletPreferences } = require('@blocklet/env/lib/util');
|
|
10
15
|
const { getComponentsInternalInfo } = require('@blocklet/meta/lib/blocklet');
|
|
11
16
|
const { getComponentApiKey } = require('@abtnode/util/lib/blocklet');
|
|
12
17
|
|
|
18
|
+
const { getBlockletConfigObj } = require('../../util/blocklet');
|
|
19
|
+
|
|
13
20
|
const getValueFromEnvironments = (environments, key) => {
|
|
14
21
|
const env = (environments || []).find((x) => x.key === key);
|
|
15
22
|
return env ? env.value : undefined;
|
|
@@ -63,6 +70,9 @@ class ConfigSynchronizer {
|
|
|
63
70
|
try {
|
|
64
71
|
const app = await this.manager.getBlocklet(rootDid);
|
|
65
72
|
const component = findComponentByIdV2(app, did);
|
|
73
|
+
|
|
74
|
+
const hasResources = !!component.meta.resource?.bundles?.length;
|
|
75
|
+
|
|
66
76
|
const env = {
|
|
67
77
|
...component.configObj,
|
|
68
78
|
...getSharedConfigObj(app, component),
|
|
@@ -76,12 +86,21 @@ class ConfigSynchronizer {
|
|
|
76
86
|
|
|
77
87
|
const dataDir = getValueFromEnvironments(app.environments, 'BLOCKLET_DATA_DIR');
|
|
78
88
|
|
|
79
|
-
const envString = JSON.stringify(env);
|
|
80
|
-
|
|
81
89
|
await fs.outputFile(
|
|
82
90
|
path.join(dataDir, APP_CONFIG_DIR, component.meta.did, COMPONENT_ENV_FILE_NAME),
|
|
83
|
-
encrypt(
|
|
91
|
+
encrypt(JSON.stringify(env), componentApiKey, component.meta.did)
|
|
84
92
|
);
|
|
93
|
+
|
|
94
|
+
if (hasResources) {
|
|
95
|
+
const publicEnv = {
|
|
96
|
+
...getBlockletConfigObj(component, { excludeSecure: true }),
|
|
97
|
+
...getSharedConfigObj(app, component),
|
|
98
|
+
};
|
|
99
|
+
await fs.outputFile(
|
|
100
|
+
path.join(dataDir, APP_CONFIG_PUBLIC_DIR, component.meta.did, COMPONENT_ENV_FILE_NAME),
|
|
101
|
+
JSON.stringify(publicEnv)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
85
104
|
} catch (error) {
|
|
86
105
|
logger.error('sync component config failed', { error });
|
|
87
106
|
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WARNING this feature is not ready for production
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs-extra');
|
|
7
|
+
const createArchive = require('archiver');
|
|
8
|
+
const { slugify } = require('transliteration');
|
|
9
|
+
const { BLOCKLET_META_FILE, PROJECT } = require('@blocklet/constant');
|
|
10
|
+
const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
11
|
+
const { createRelease: createBlockletRelease } = require('@abtnode/util/lib/create-blocklet-release');
|
|
12
|
+
const urlPathFriendly = require('@blocklet/meta/lib/url-path-friendly').default;
|
|
13
|
+
|
|
14
|
+
const logger = require('@abtnode/logger')('create-resource-blocklet-pack');
|
|
15
|
+
|
|
16
|
+
const { createReleaseSchema } = require('../../validators/project');
|
|
17
|
+
|
|
18
|
+
const { getLogoFile, exportBlockletResources, getResourceList, checkResourceExists } = require('./util');
|
|
19
|
+
|
|
20
|
+
const createRandomStr = () => Math.random().toString(36).substring(2, 8);
|
|
21
|
+
|
|
22
|
+
const createPackRelease = async ({
|
|
23
|
+
did,
|
|
24
|
+
projectId,
|
|
25
|
+
releaseId,
|
|
26
|
+
blockletTitle,
|
|
27
|
+
blockletDescription,
|
|
28
|
+
blockletVersion,
|
|
29
|
+
blockletIntroduction,
|
|
30
|
+
blockletLogo,
|
|
31
|
+
blockletScreenshots,
|
|
32
|
+
note,
|
|
33
|
+
manager,
|
|
34
|
+
status,
|
|
35
|
+
}) => {
|
|
36
|
+
if (!projectId) {
|
|
37
|
+
throw new Error('projectId is required');
|
|
38
|
+
}
|
|
39
|
+
if (!PROJECT.RELEASE_STATUS[status]) {
|
|
40
|
+
throw new Error(`status is invalid: ${status}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const params = {
|
|
44
|
+
blockletVersion,
|
|
45
|
+
blockletTitle,
|
|
46
|
+
blockletDescription,
|
|
47
|
+
blockletLogo,
|
|
48
|
+
blockletIntroduction,
|
|
49
|
+
blockletScreenshots,
|
|
50
|
+
note,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const releaseSchema = createReleaseSchema(status);
|
|
54
|
+
await releaseSchema.validateAsync(params);
|
|
55
|
+
|
|
56
|
+
const blocklet = await manager.getBlocklet(did);
|
|
57
|
+
const { projectState, releaseState } = await manager._getProjectState(did);
|
|
58
|
+
|
|
59
|
+
const project0 = await projectState.findOne({ id: projectId });
|
|
60
|
+
if (!project0) {
|
|
61
|
+
throw new Error('project not found');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (project0.type !== PROJECT.TYPES.pack) {
|
|
65
|
+
throw new Error('project type is not pack');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const action = releaseId ? 'update' : 'create';
|
|
69
|
+
|
|
70
|
+
if (action === 'update') {
|
|
71
|
+
const release = await releaseState.findOne({ projectId, id: releaseId });
|
|
72
|
+
if (!release) {
|
|
73
|
+
throw new Error('release not found');
|
|
74
|
+
}
|
|
75
|
+
if (release.status !== 'draft') {
|
|
76
|
+
throw new Error('Can not update a published release');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const existVersion = await releaseState.findOne({ projectId, blockletVersion });
|
|
81
|
+
if (existVersion && (action === 'create' || existVersion.id !== releaseId)) {
|
|
82
|
+
throw new Error(`blockletVersion ${blockletVersion} already exists`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const { blockletDid } = project0;
|
|
86
|
+
|
|
87
|
+
params.blockletDid = blockletDid;
|
|
88
|
+
|
|
89
|
+
const projectDir = path.join(blocklet.env.dataDir, PROJECT.DIR, `${projectId}`);
|
|
90
|
+
|
|
91
|
+
// test
|
|
92
|
+
// const components = blocklet.children.map((x) => ({
|
|
93
|
+
// did: x.meta.did,
|
|
94
|
+
// configs: x.configs.filter((y) => !y.secure),
|
|
95
|
+
// }));
|
|
96
|
+
// console.log(components.map((x) => x.configs));
|
|
97
|
+
// throw new Error('test');
|
|
98
|
+
|
|
99
|
+
if (status !== PROJECT.RELEASE_STATUS.draft) {
|
|
100
|
+
await checkResourceExists(projectDir, action, releaseId);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const release = await releaseState.upsertRelease({
|
|
104
|
+
...params,
|
|
105
|
+
projectId,
|
|
106
|
+
releaseId,
|
|
107
|
+
status,
|
|
108
|
+
});
|
|
109
|
+
const project = await projectState.updateProject(projectId, params);
|
|
110
|
+
|
|
111
|
+
const _releaseId = release.id;
|
|
112
|
+
|
|
113
|
+
const tmpDir = path.join(manager.dataDirs.tmp, PROJECT.DIR, `${blockletDid}-${createRandomStr()}`);
|
|
114
|
+
const releaseDir = path.join(projectDir, PROJECT.RELEASE_DIR, `${_releaseId}`);
|
|
115
|
+
const resourceDir = path.join(releaseDir, PROJECT.RESOURCE_DIR);
|
|
116
|
+
const tmpResourceDir = path.join(projectDir, PROJECT.RESOURCE_DIR);
|
|
117
|
+
|
|
118
|
+
await fs.ensureDir(releaseDir);
|
|
119
|
+
|
|
120
|
+
// move tmp resource to release
|
|
121
|
+
if (action === 'create') {
|
|
122
|
+
await fs.ensureDir(tmpResourceDir);
|
|
123
|
+
await fs.remove(releaseDir);
|
|
124
|
+
await fs.ensureDir(releaseDir);
|
|
125
|
+
await fs.move(tmpResourceDir, resourceDir);
|
|
126
|
+
await fs.ensureDir(tmpResourceDir);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (status === PROJECT.RELEASE_STATUS.draft) {
|
|
130
|
+
return release;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// create a release
|
|
134
|
+
if (fs.existsSync(tmpDir)) {
|
|
135
|
+
await fs.remove(tmpDir);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const tmpExportDir = path.join(tmpDir, 'export');
|
|
139
|
+
const tmpBundleDir = path.join(tmpExportDir, 'bundle');
|
|
140
|
+
const tmpReleaseDir = path.join(tmpExportDir, 'release');
|
|
141
|
+
|
|
142
|
+
const moniker = (urlPathFriendly(slugify(release.blockletTitle)) || 'blocklet').toLowerCase();
|
|
143
|
+
const releaseFileName = `${moniker}-${release.blockletVersion}.zip`;
|
|
144
|
+
const releaseFile = path.join(releaseDir, releaseFileName);
|
|
145
|
+
if (fs.existsSync(releaseFile)) {
|
|
146
|
+
logger.error('release file already exists, remove it', releaseFile);
|
|
147
|
+
await fs.remove(releaseFile);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
await fs.ensureDir(tmpBundleDir);
|
|
152
|
+
|
|
153
|
+
// create logo
|
|
154
|
+
const { logoFile, logoFileName } = getLogoFile(blocklet, project);
|
|
155
|
+
await fs.copy(logoFile, path.join(tmpBundleDir, logoFileName));
|
|
156
|
+
|
|
157
|
+
// create screenshots
|
|
158
|
+
const screenshotsDistDir = path.join(tmpBundleDir, 'screenshots');
|
|
159
|
+
await fs.ensureDir(screenshotsDistDir);
|
|
160
|
+
if (project.blockletScreenshots?.length) {
|
|
161
|
+
await Promise.all(
|
|
162
|
+
project.blockletScreenshots.map(async (screenshot) => {
|
|
163
|
+
const screenshotFile = path.join(projectDir, PROJECT.ASSET_DIR, screenshot);
|
|
164
|
+
await fs.copy(screenshotFile, path.join(screenshotsDistDir, screenshot));
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// create readme
|
|
170
|
+
if (blockletIntroduction) {
|
|
171
|
+
await fs.outputFile(path.join(tmpBundleDir, 'README.md'), blockletIntroduction);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// changelog
|
|
175
|
+
const changelogDistFile = path.join(tmpBundleDir, 'CHANGELOG.md');
|
|
176
|
+
const releases = await releaseState.getReleases({ projectId, status: PROJECT.RELEASE_STATUS.published });
|
|
177
|
+
const changelog = releases.map((_release) => {
|
|
178
|
+
const { blockletVersion: version, note: content } = _release;
|
|
179
|
+
return `## ${version}\n\n${content}`;
|
|
180
|
+
});
|
|
181
|
+
await fs.outputFile(changelogDistFile, changelog.join('\n\n'));
|
|
182
|
+
|
|
183
|
+
// create resource
|
|
184
|
+
await exportBlockletResources({
|
|
185
|
+
app: blocklet,
|
|
186
|
+
projectId,
|
|
187
|
+
releaseId: _releaseId,
|
|
188
|
+
exportDir: tmpBundleDir,
|
|
189
|
+
blockletDid,
|
|
190
|
+
isPack: true,
|
|
191
|
+
});
|
|
192
|
+
const resourceList = await getResourceList(tmpBundleDir, { isPublic: false });
|
|
193
|
+
|
|
194
|
+
const components = blocklet.children
|
|
195
|
+
.filter((x) => x.bundleSource?.url || x.bundleSource?.store)
|
|
196
|
+
.map((x) => ({
|
|
197
|
+
name: x.meta.name,
|
|
198
|
+
mountPoint: x.mountPoint,
|
|
199
|
+
source: x.bundleSource,
|
|
200
|
+
}));
|
|
201
|
+
|
|
202
|
+
// create blocklet.yml
|
|
203
|
+
const meta = {
|
|
204
|
+
did: blockletDid,
|
|
205
|
+
name: blockletDid,
|
|
206
|
+
title: blockletTitle,
|
|
207
|
+
description: blockletDescription,
|
|
208
|
+
version: blockletVersion,
|
|
209
|
+
group: 'pack',
|
|
210
|
+
logo: logoFileName,
|
|
211
|
+
resource: {
|
|
212
|
+
bundles: resourceList.length ? resourceList : undefined,
|
|
213
|
+
},
|
|
214
|
+
components,
|
|
215
|
+
files: project.blockletScreenshots?.length ? ['screenshots'] : [],
|
|
216
|
+
screenshots: project.blockletScreenshots || [],
|
|
217
|
+
};
|
|
218
|
+
await updateMetaFile(path.join(tmpBundleDir, BLOCKLET_META_FILE), meta);
|
|
219
|
+
|
|
220
|
+
// create release
|
|
221
|
+
await createBlockletRelease(tmpExportDir, { printError: logger.error, printInfo: logger.info });
|
|
222
|
+
|
|
223
|
+
// archive
|
|
224
|
+
const archive = createArchive('zip', { zlib: { level: 9 } });
|
|
225
|
+
const writeStream = fs.createWriteStream(releaseFile);
|
|
226
|
+
|
|
227
|
+
await new Promise((resolve, reject) => {
|
|
228
|
+
archive
|
|
229
|
+
.directory(tmpReleaseDir, false)
|
|
230
|
+
.on('error', (err) => reject(err))
|
|
231
|
+
.pipe(writeStream);
|
|
232
|
+
|
|
233
|
+
writeStream.on('close', () => resolve(releaseFile));
|
|
234
|
+
archive.finalize();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const res2 = await releaseState.upsertRelease({
|
|
238
|
+
projectId,
|
|
239
|
+
releaseId: _releaseId,
|
|
240
|
+
files: [releaseFileName],
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
await fs.remove(tmpDir);
|
|
244
|
+
|
|
245
|
+
logger.info('create release success', res2);
|
|
246
|
+
|
|
247
|
+
return res2;
|
|
248
|
+
} catch (error) {
|
|
249
|
+
await fs.remove(tmpDir);
|
|
250
|
+
await fs.remove(releaseFile);
|
|
251
|
+
if (action === 'create') {
|
|
252
|
+
await fs.remove(releaseDir);
|
|
253
|
+
await releaseState.remove({ projectId, id: _releaseId });
|
|
254
|
+
} else {
|
|
255
|
+
await releaseState.update({ id: _releaseId }, { $set: { status: PROJECT.RELEASE_STATUS.draft } });
|
|
256
|
+
}
|
|
257
|
+
logger.error(`export ${project.type} error`, error);
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
module.exports = createPackRelease;
|
|
@@ -2,19 +2,20 @@ const path = require('path');
|
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
3
|
const createArchive = require('archiver');
|
|
4
4
|
const { slugify } = require('transliteration');
|
|
5
|
-
const {
|
|
6
|
-
const { BLOCKLET_META_FILE, PROJECT, BLOCKLET_RESOURCE_DIR } = require('@blocklet/constant');
|
|
5
|
+
const { BLOCKLET_META_FILE, PROJECT } = require('@blocklet/constant');
|
|
7
6
|
const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
8
7
|
const { createRelease: createBlockletRelease } = require('@abtnode/util/lib/create-blocklet-release');
|
|
9
8
|
const { titleSchema } = require('@blocklet/meta/lib/schema');
|
|
10
9
|
const { validateNewDid } = require('@blocklet/meta/lib/name');
|
|
11
10
|
const urlPathFriendly = require('@blocklet/meta/lib/url-path-friendly').default;
|
|
12
|
-
const fg = require('fast-glob');
|
|
13
11
|
|
|
14
12
|
const logger = require('@abtnode/logger')('create-resource-blocklet');
|
|
15
13
|
|
|
16
14
|
const { createReleaseSchema } = require('../../validators/project');
|
|
17
15
|
|
|
16
|
+
const { getLogoFile, exportBlockletResources, getResourceList, checkResourceExists } = require('./util');
|
|
17
|
+
const createPackRelease = require('./create-pack-release');
|
|
18
|
+
|
|
18
19
|
const createRandomStr = () => Math.random().toString(36).substring(2, 8);
|
|
19
20
|
|
|
20
21
|
const COMPONENT_CONFIG_MAP_DIR = '.component_config';
|
|
@@ -103,46 +104,6 @@ const deleteRelease = async ({ did, projectId, releaseId, manager }) => {
|
|
|
103
104
|
await fs.remove(releaseDir);
|
|
104
105
|
};
|
|
105
106
|
|
|
106
|
-
const checkResourceExists = async (projectDir, action, releaseId) => {
|
|
107
|
-
const releaseDir =
|
|
108
|
-
action === 'create'
|
|
109
|
-
? path.join(projectDir, PROJECT.RESOURCE_DIR)
|
|
110
|
-
: path.join(projectDir, PROJECT.RELEASE_DIR, `${releaseId}`, PROJECT.RESOURCE_DIR);
|
|
111
|
-
|
|
112
|
-
const configDir = path.join(releaseDir, COMPONENT_CONFIG_MAP_DIR);
|
|
113
|
-
const errMsg = 'resource should not be empty';
|
|
114
|
-
if (!fs.existsSync(configDir)) {
|
|
115
|
-
throw new Error(errMsg);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const files = await fs.readdir(configDir);
|
|
119
|
-
if (!files.length) {
|
|
120
|
-
throw new Error(errMsg);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const getResourceList = async (resourceDir) => {
|
|
125
|
-
const list = await fg(['*/*'], { cwd: resourceDir, onlyDirectories: true });
|
|
126
|
-
|
|
127
|
-
return list
|
|
128
|
-
.filter((x) => x !== COMPONENT_CONFIG_MAP_DIR)
|
|
129
|
-
.map((x) => {
|
|
130
|
-
const [did, type] = x.split('/');
|
|
131
|
-
if (!type) {
|
|
132
|
-
throw new Error(`invalid resource: ${x}. type is required`);
|
|
133
|
-
}
|
|
134
|
-
if (!isValidDid(did)) {
|
|
135
|
-
throw new Error(`invalid resource: ${x}. did is invalid`);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
did,
|
|
140
|
-
type,
|
|
141
|
-
public: true,
|
|
142
|
-
};
|
|
143
|
-
});
|
|
144
|
-
};
|
|
145
|
-
|
|
146
107
|
const createRelease = async ({
|
|
147
108
|
did,
|
|
148
109
|
projectId,
|
|
@@ -185,6 +146,23 @@ const createRelease = async ({
|
|
|
185
146
|
throw new Error('project not found');
|
|
186
147
|
}
|
|
187
148
|
|
|
149
|
+
if (project0.type === PROJECT.TYPES.pack) {
|
|
150
|
+
return createPackRelease({
|
|
151
|
+
did,
|
|
152
|
+
projectId,
|
|
153
|
+
releaseId,
|
|
154
|
+
blockletTitle,
|
|
155
|
+
blockletDescription,
|
|
156
|
+
blockletVersion,
|
|
157
|
+
blockletIntroduction,
|
|
158
|
+
blockletLogo,
|
|
159
|
+
blockletScreenshots,
|
|
160
|
+
note,
|
|
161
|
+
manager,
|
|
162
|
+
status,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
188
166
|
const action = releaseId ? 'update' : 'create';
|
|
189
167
|
|
|
190
168
|
if (action === 'update') {
|
|
@@ -263,11 +241,7 @@ const createRelease = async ({
|
|
|
263
241
|
await fs.ensureDir(tmpBundleDir);
|
|
264
242
|
|
|
265
243
|
// create logo
|
|
266
|
-
const logoFile = project
|
|
267
|
-
? path.join(projectDir, PROJECT.ASSET_DIR, project.blockletLogo)
|
|
268
|
-
: path.join(__dirname, 'logo.png');
|
|
269
|
-
const logoExt = path.extname(logoFile);
|
|
270
|
-
const logoFileName = `logo${logoExt}`;
|
|
244
|
+
const { logoFile, logoFileName } = getLogoFile(blocklet, project);
|
|
271
245
|
await fs.copy(logoFile, path.join(tmpBundleDir, logoFileName));
|
|
272
246
|
|
|
273
247
|
// create screenshots
|
|
@@ -297,10 +271,13 @@ const createRelease = async ({
|
|
|
297
271
|
await fs.outputFile(changelogDistFile, changelog.join('\n\n'));
|
|
298
272
|
|
|
299
273
|
// create resource
|
|
300
|
-
await
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
274
|
+
await exportBlockletResources({
|
|
275
|
+
app: blocklet,
|
|
276
|
+
projectId,
|
|
277
|
+
releaseId: _releaseId,
|
|
278
|
+
exportDir: tmpBundleDir,
|
|
279
|
+
blockletDid,
|
|
280
|
+
});
|
|
304
281
|
|
|
305
282
|
// create blocklet.yml
|
|
306
283
|
const resourceList = await getResourceList(resourceDir);
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const fg = require('fast-glob');
|
|
4
|
+
const { isValid: isValidDid } = require('@arcblock/did');
|
|
5
|
+
const { PROJECT, BLOCKLET_RESOURCE_DIR } = require('@blocklet/constant');
|
|
6
|
+
|
|
7
|
+
const COMPONENT_CONFIG_MAP_DIR = '.component_config';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {import('@abtnode/client').BlockletState} blocklet
|
|
11
|
+
* @param {{
|
|
12
|
+
* id: string;
|
|
13
|
+
* blockletLogo?: string;
|
|
14
|
+
* }} project
|
|
15
|
+
*/
|
|
16
|
+
const getLogoFile = (blocklet, project) => {
|
|
17
|
+
const { id } = project;
|
|
18
|
+
const projectDir = path.join(blocklet.env.dataDir, PROJECT.DIR, id);
|
|
19
|
+
|
|
20
|
+
const logoFile = project.blockletLogo
|
|
21
|
+
? path.join(projectDir, PROJECT.ASSET_DIR, project.blockletLogo)
|
|
22
|
+
: path.join(__dirname, 'logo.png');
|
|
23
|
+
const logoExt = path.extname(logoFile);
|
|
24
|
+
const logoFileName = `logo${logoExt}`;
|
|
25
|
+
return { logoFile, logoFileName };
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const exportBlockletResources = async ({ app, projectId, releaseId, exportDir, blockletDid, isPack }) => {
|
|
29
|
+
// create resource
|
|
30
|
+
const projectDir = path.join(app.env.dataDir, PROJECT.DIR, `${projectId}`);
|
|
31
|
+
const releaseDir = path.join(projectDir, PROJECT.RELEASE_DIR, `${releaseId}`);
|
|
32
|
+
const sourceDir = path.join(releaseDir, PROJECT.RESOURCE_DIR);
|
|
33
|
+
|
|
34
|
+
const resourceDir = path.join(exportDir, BLOCKLET_RESOURCE_DIR);
|
|
35
|
+
await fs.ensureDir(resourceDir);
|
|
36
|
+
await fs.copy(sourceDir, resourceDir);
|
|
37
|
+
await fs.remove(path.join(resourceDir, COMPONENT_CONFIG_MAP_DIR));
|
|
38
|
+
|
|
39
|
+
if (isPack) {
|
|
40
|
+
// create pack resource
|
|
41
|
+
const packResourceDir = path.join(resourceDir, blockletDid, 'config');
|
|
42
|
+
await fs.ensureDir(packResourceDir);
|
|
43
|
+
const site = {
|
|
44
|
+
rules: (app.site?.rules || [])
|
|
45
|
+
.filter((x) => !x.isProtected)
|
|
46
|
+
.map((rule) => ({
|
|
47
|
+
from: rule.from,
|
|
48
|
+
to: rule.to,
|
|
49
|
+
}))
|
|
50
|
+
.filter(Boolean),
|
|
51
|
+
};
|
|
52
|
+
const navigations = app.settings.navigations || [];
|
|
53
|
+
const componentsConfigs = app.children.map((x) => ({
|
|
54
|
+
did: x.meta.did,
|
|
55
|
+
configs: x.configs.filter((y) => !y.secure),
|
|
56
|
+
}));
|
|
57
|
+
await fs.outputJSON(path.join(packResourceDir, 'config.json'), {
|
|
58
|
+
site,
|
|
59
|
+
navigations,
|
|
60
|
+
components: componentsConfigs,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
async function checkIfDirectory(file) {
|
|
66
|
+
try {
|
|
67
|
+
const stats = await fs.promises.stat(file);
|
|
68
|
+
return stats.isDirectory();
|
|
69
|
+
} catch {
|
|
70
|
+
// maybe file not exists
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const getResourceList = async (resourceDir, { isPublic = true } = {}) => {
|
|
76
|
+
const hasResourceDir = await checkIfDirectory(path.join(resourceDir, BLOCKLET_RESOURCE_DIR));
|
|
77
|
+
const dir = hasResourceDir ? path.join(resourceDir, BLOCKLET_RESOURCE_DIR) : resourceDir;
|
|
78
|
+
|
|
79
|
+
const list = await fg(['*/*'], { cwd: dir, onlyDirectories: true });
|
|
80
|
+
|
|
81
|
+
return list
|
|
82
|
+
.filter((x) => x !== COMPONENT_CONFIG_MAP_DIR)
|
|
83
|
+
.map((x) => {
|
|
84
|
+
const [did, type] = x.split('/');
|
|
85
|
+
if (!type) {
|
|
86
|
+
throw new Error(`invalid resource: ${x}. type is required`);
|
|
87
|
+
}
|
|
88
|
+
if (!isValidDid(did)) {
|
|
89
|
+
throw new Error(`invalid resource: ${x}. did is invalid`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const res = {
|
|
93
|
+
did,
|
|
94
|
+
type,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
if (isPublic) {
|
|
98
|
+
res.public = true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return res;
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const checkResourceExists = async (projectDir, action, releaseId) => {
|
|
106
|
+
const releaseDir =
|
|
107
|
+
action === 'create'
|
|
108
|
+
? path.join(projectDir, PROJECT.RESOURCE_DIR)
|
|
109
|
+
: path.join(projectDir, PROJECT.RELEASE_DIR, `${releaseId}`, PROJECT.RESOURCE_DIR);
|
|
110
|
+
|
|
111
|
+
const configDir = path.join(releaseDir, COMPONENT_CONFIG_MAP_DIR);
|
|
112
|
+
const errMsg = 'resource should not be empty';
|
|
113
|
+
if (!fs.existsSync(configDir)) {
|
|
114
|
+
throw new Error(errMsg);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const files = await fs.readdir(configDir);
|
|
118
|
+
if (!files.length) {
|
|
119
|
+
throw new Error(errMsg);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
module.exports = {
|
|
124
|
+
getLogoFile,
|
|
125
|
+
exportBlockletResources,
|
|
126
|
+
getResourceList,
|
|
127
|
+
checkResourceExists,
|
|
128
|
+
};
|
package/lib/util/blocklet.js
CHANGED
|
@@ -231,6 +231,22 @@ const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
|
231
231
|
return { cwd, script, args, environmentObj, interpreter, interpreterArgs };
|
|
232
232
|
};
|
|
233
233
|
|
|
234
|
+
const getBlockletConfigObj = (blocklet, { excludeSecure } = {}) => {
|
|
235
|
+
const obj = (blocklet?.configs || [])
|
|
236
|
+
.filter((x) => {
|
|
237
|
+
if (excludeSecure) {
|
|
238
|
+
return !x.secure;
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
})
|
|
242
|
+
.reduce((acc, x) => {
|
|
243
|
+
acc[x.key] = templateReplace(x.value, blocklet);
|
|
244
|
+
return acc;
|
|
245
|
+
}, {});
|
|
246
|
+
|
|
247
|
+
return obj;
|
|
248
|
+
};
|
|
249
|
+
|
|
234
250
|
/**
|
|
235
251
|
* set 'configs', configObj', 'environmentObj' to blocklet TODO
|
|
236
252
|
* @param {*} blocklet
|
|
@@ -238,10 +254,7 @@ const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
|
238
254
|
*/
|
|
239
255
|
const fillBlockletConfigs = (blocklet, configs) => {
|
|
240
256
|
blocklet.configs = configs || [];
|
|
241
|
-
blocklet.configObj = blocklet
|
|
242
|
-
acc[x.key] = templateReplace(x.value, blocklet);
|
|
243
|
-
return acc;
|
|
244
|
-
}, {});
|
|
257
|
+
blocklet.configObj = getBlockletConfigObj(blocklet);
|
|
245
258
|
blocklet.environments = blocklet.environments || [];
|
|
246
259
|
blocklet.environmentObj = blocklet.environments.reduce((acc, x) => {
|
|
247
260
|
acc[x.key] = templateReplace(x.value, blocklet);
|
|
@@ -2028,4 +2041,5 @@ module.exports = {
|
|
|
2028
2041
|
removeAppConfigsFromComponent,
|
|
2029
2042
|
getConfigsFromInput,
|
|
2030
2043
|
getPackConfig,
|
|
2044
|
+
getBlockletConfigObj,
|
|
2031
2045
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.
|
|
6
|
+
"version": "1.16.23-beta-f85576a6",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.
|
|
23
|
-
"@abtnode/auth": "1.16.
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.
|
|
25
|
-
"@abtnode/constant": "1.16.
|
|
26
|
-
"@abtnode/cron": "1.16.
|
|
27
|
-
"@abtnode/logger": "1.16.
|
|
28
|
-
"@abtnode/models": "1.16.
|
|
29
|
-
"@abtnode/queue": "1.16.
|
|
30
|
-
"@abtnode/rbac": "1.16.
|
|
31
|
-
"@abtnode/router-provider": "1.16.
|
|
32
|
-
"@abtnode/static-server": "1.16.
|
|
33
|
-
"@abtnode/timemachine": "1.16.
|
|
34
|
-
"@abtnode/util": "1.16.
|
|
22
|
+
"@abtnode/analytics": "1.16.23-beta-f85576a6",
|
|
23
|
+
"@abtnode/auth": "1.16.23-beta-f85576a6",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.23-beta-f85576a6",
|
|
25
|
+
"@abtnode/constant": "1.16.23-beta-f85576a6",
|
|
26
|
+
"@abtnode/cron": "1.16.23-beta-f85576a6",
|
|
27
|
+
"@abtnode/logger": "1.16.23-beta-f85576a6",
|
|
28
|
+
"@abtnode/models": "1.16.23-beta-f85576a6",
|
|
29
|
+
"@abtnode/queue": "1.16.23-beta-f85576a6",
|
|
30
|
+
"@abtnode/rbac": "1.16.23-beta-f85576a6",
|
|
31
|
+
"@abtnode/router-provider": "1.16.23-beta-f85576a6",
|
|
32
|
+
"@abtnode/static-server": "1.16.23-beta-f85576a6",
|
|
33
|
+
"@abtnode/timemachine": "1.16.23-beta-f85576a6",
|
|
34
|
+
"@abtnode/util": "1.16.23-beta-f85576a6",
|
|
35
35
|
"@arcblock/did": "1.18.108",
|
|
36
36
|
"@arcblock/did-auth": "1.18.108",
|
|
37
37
|
"@arcblock/did-ext": "^1.18.108",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
43
43
|
"@arcblock/validator": "^1.18.108",
|
|
44
44
|
"@arcblock/vc": "1.18.108",
|
|
45
|
-
"@blocklet/constant": "1.16.
|
|
46
|
-
"@blocklet/env": "1.16.
|
|
47
|
-
"@blocklet/meta": "1.16.
|
|
48
|
-
"@blocklet/resolver": "1.16.
|
|
49
|
-
"@blocklet/sdk": "1.16.
|
|
45
|
+
"@blocklet/constant": "1.16.23-beta-f85576a6",
|
|
46
|
+
"@blocklet/env": "1.16.23-beta-f85576a6",
|
|
47
|
+
"@blocklet/meta": "1.16.23-beta-f85576a6",
|
|
48
|
+
"@blocklet/resolver": "1.16.23-beta-f85576a6",
|
|
49
|
+
"@blocklet/sdk": "1.16.23-beta-f85576a6",
|
|
50
50
|
"@did-space/client": "^0.3.50",
|
|
51
51
|
"@fidm/x509": "^1.2.1",
|
|
52
52
|
"@ocap/mcrypto": "1.18.108",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"jest": "^27.5.1",
|
|
103
103
|
"unzipper": "^0.10.11"
|
|
104
104
|
},
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "bac83a74944b4cef3ccb386277023caf0e1d5cd4"
|
|
106
106
|
}
|