@nocobase/utils 1.9.32 → 1.9.34
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/package.json +3 -2
- package/plugin-symlink.js +129 -67
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/utils",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.34",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "./lib/index.d.ts",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
"dayjs": "^1.11.9",
|
|
12
12
|
"deepmerge": "^4.2.2",
|
|
13
13
|
"flat-to-nested": "^1.1.1",
|
|
14
|
+
"fs-extra": "^11.1.1",
|
|
14
15
|
"graphlib": "^2.1.8",
|
|
15
16
|
"handlebars": "^4.7.8",
|
|
16
17
|
"multer": "^1.4.5-lts.2",
|
|
17
18
|
"object-path": "^0.11.8"
|
|
18
19
|
},
|
|
19
|
-
"gitHead": "
|
|
20
|
+
"gitHead": "8779a68face5b8f159aef726f73695f319ab7659"
|
|
20
21
|
}
|
package/plugin-symlink.js
CHANGED
|
@@ -1,114 +1,176 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const
|
|
1
|
+
const { resolve } = require('path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Recursively get plugin names from a directory
|
|
6
|
+
* @param {string} target - Target directory to scan
|
|
7
|
+
* @returns {Promise<string[]>} Array of plugin names
|
|
8
|
+
*/
|
|
4
9
|
async function getStoragePluginNames(target) {
|
|
5
10
|
const plugins = [];
|
|
6
|
-
const items = await readdir(target);
|
|
11
|
+
const items = await fs.readdir(target);
|
|
12
|
+
|
|
7
13
|
for (const item of items) {
|
|
14
|
+
const itemPath = resolve(target, item);
|
|
15
|
+
|
|
8
16
|
if (item.startsWith('@')) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
if (!s.isDirectory()) {
|
|
17
|
+
const statResult = await fs.stat(itemPath);
|
|
18
|
+
if (!statResult.isDirectory()) {
|
|
12
19
|
continue;
|
|
13
20
|
}
|
|
14
|
-
const children = await getStoragePluginNames(
|
|
15
|
-
plugins.push(
|
|
16
|
-
|
|
17
|
-
return `${item}/${child}`;
|
|
18
|
-
}),
|
|
19
|
-
);
|
|
20
|
-
} else if (await fsExists(resolve(target, item, 'package.json'))) {
|
|
21
|
+
const children = await getStoragePluginNames(itemPath);
|
|
22
|
+
plugins.push(...children.map((child) => `${item}/${child}`));
|
|
23
|
+
} else if (await fs.pathExists(resolve(itemPath, 'package.json'))) {
|
|
21
24
|
plugins.push(item);
|
|
22
25
|
}
|
|
23
26
|
}
|
|
27
|
+
|
|
24
28
|
return plugins;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Ensure the organization directory exists for scoped packages
|
|
33
|
+
* @param {string} nodeModulesPath - Path to node_modules
|
|
34
|
+
* @param {string} pluginName - Plugin name (may be scoped)
|
|
35
|
+
* @returns {Promise<void>}
|
|
36
|
+
*/
|
|
37
|
+
async function ensureOrgDirectory(nodeModulesPath, pluginName) {
|
|
38
|
+
if (pluginName.startsWith('@')) {
|
|
39
|
+
const [orgName] = pluginName.split('/');
|
|
40
|
+
const orgPath = resolve(nodeModulesPath, orgName);
|
|
41
|
+
await fs.ensureDir(orgPath);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check if a symlink already points to the correct target
|
|
47
|
+
* @param {string} linkPath - Path to the symlink
|
|
48
|
+
* @param {string} targetPath - Expected target path
|
|
49
|
+
* @returns {Promise<boolean>} True if symlink exists and points to target
|
|
50
|
+
*/
|
|
51
|
+
async function isSymlinkValid(linkPath, targetPath) {
|
|
28
52
|
try {
|
|
29
|
-
await
|
|
30
|
-
|
|
53
|
+
if (await fs.pathExists(linkPath)) {
|
|
54
|
+
const realPath = await fs.realpath(linkPath);
|
|
55
|
+
return realPath === targetPath;
|
|
56
|
+
}
|
|
31
57
|
} catch (error) {
|
|
58
|
+
// If realpath fails, the symlink is invalid
|
|
32
59
|
return false;
|
|
33
60
|
}
|
|
61
|
+
return false;
|
|
34
62
|
}
|
|
35
63
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Remove an existing symlink or file at the given path
|
|
66
|
+
* @param {string} linkPath - Path to remove
|
|
67
|
+
* @param {string} pluginName - Plugin name for error messages
|
|
68
|
+
* @param {string} pluginType - Type of plugin ('storage' or 'dev') for error messages
|
|
69
|
+
* @returns {Promise<void>}
|
|
70
|
+
*/
|
|
71
|
+
async function removeExistingLink(linkPath, pluginName, pluginType) {
|
|
42
72
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
73
|
+
await fs.remove(linkPath);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// Ignore ENOENT errors (file doesn't exist)
|
|
76
|
+
if (error.code !== 'ENOENT') {
|
|
77
|
+
console.error(`Failed to remove existing symlink for ${pluginType} plugin: ${pluginName}`, error.message);
|
|
48
78
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Create a symlink for a plugin
|
|
84
|
+
* @param {string} pluginName - Name of the plugin
|
|
85
|
+
* @param {string} sourcePath - Source directory path
|
|
86
|
+
* @param {string} nodeModulesPath - Target node_modules path
|
|
87
|
+
* @param {string} pluginType - Type of plugin ('storage' or 'dev')
|
|
88
|
+
* @returns {Promise<void>}
|
|
89
|
+
*/
|
|
90
|
+
async function createPluginSymLink(pluginName, sourcePath, nodeModulesPath, pluginType) {
|
|
91
|
+
if (!nodeModulesPath) {
|
|
92
|
+
console.error(`NODE_MODULES_PATH is not set, cannot create symlink for ${pluginType} plugin: ${pluginName}`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const targetPath = resolve(sourcePath, pluginName);
|
|
98
|
+
|
|
99
|
+
// Check if source exists
|
|
100
|
+
if (!(await fs.pathExists(targetPath))) {
|
|
101
|
+
console.warn(`Source path does not exist for ${pluginType} plugin: ${pluginName} at ${targetPath}`);
|
|
102
|
+
return;
|
|
55
103
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
104
|
+
|
|
105
|
+
// Ensure organization directory exists for scoped packages
|
|
106
|
+
await ensureOrgDirectory(nodeModulesPath, pluginName);
|
|
107
|
+
|
|
108
|
+
const linkPath = resolve(nodeModulesPath, pluginName);
|
|
109
|
+
|
|
110
|
+
// Check if symlink already points to the correct target
|
|
111
|
+
if (await isSymlinkValid(linkPath, targetPath)) {
|
|
112
|
+
return; // Symlink is already correct, no need to recreate
|
|
60
113
|
}
|
|
61
|
-
|
|
62
|
-
//
|
|
114
|
+
|
|
115
|
+
// Remove existing link if it exists
|
|
116
|
+
await removeExistingLink(linkPath, pluginName, pluginType);
|
|
117
|
+
|
|
118
|
+
// Create new symlink
|
|
119
|
+
await fs.symlink(targetPath, linkPath, 'dir');
|
|
63
120
|
} catch (error) {
|
|
64
|
-
console.error(`Failed to create symlink for
|
|
121
|
+
console.error(`Failed to create symlink for ${pluginType} plugin: ${pluginName}`, error.message);
|
|
65
122
|
}
|
|
66
123
|
}
|
|
67
124
|
|
|
68
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Create a symlink for a storage plugin
|
|
127
|
+
* @param {string} pluginName - Name of the plugin
|
|
128
|
+
* @returns {Promise<void>}
|
|
129
|
+
*/
|
|
130
|
+
async function createStoragePluginSymLink(pluginName) {
|
|
131
|
+
const storagePluginsPath = resolve(process.cwd(), 'storage/plugins');
|
|
132
|
+
const nodeModulesPath = process.env.NODE_MODULES_PATH;
|
|
133
|
+
await createPluginSymLink(pluginName, storagePluginsPath, nodeModulesPath, 'storage');
|
|
134
|
+
}
|
|
69
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Create symlinks for all storage plugins
|
|
138
|
+
* @returns {Promise<void>}
|
|
139
|
+
*/
|
|
70
140
|
async function createStoragePluginsSymlink() {
|
|
71
141
|
const storagePluginsPath = resolve(process.cwd(), 'storage/plugins');
|
|
72
|
-
if (!(await
|
|
142
|
+
if (!(await fs.pathExists(storagePluginsPath))) {
|
|
73
143
|
return;
|
|
74
144
|
}
|
|
75
145
|
const pluginNames = await getStoragePluginNames(storagePluginsPath);
|
|
76
146
|
await Promise.all(pluginNames.map((pluginName) => createStoragePluginSymLink(pluginName)));
|
|
77
147
|
}
|
|
78
148
|
|
|
79
|
-
|
|
80
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Create a symlink for a dev plugin
|
|
151
|
+
* @param {string} pluginName - Name of the plugin
|
|
152
|
+
* @returns {Promise<void>}
|
|
153
|
+
*/
|
|
81
154
|
async function createDevPluginSymLink(pluginName) {
|
|
82
155
|
const packagePluginsPath = resolve(process.cwd(), 'packages/plugins');
|
|
83
|
-
const nodeModulesPath = process.env.NODE_MODULES_PATH;
|
|
84
|
-
|
|
85
|
-
if (pluginName.startsWith('@')) {
|
|
86
|
-
const [orgName] = pluginName.split('/');
|
|
87
|
-
if (!(await fsExists(resolve(nodeModulesPath, orgName)))) {
|
|
88
|
-
await mkdir(resolve(nodeModulesPath, orgName), { recursive: true });
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const link = resolve(nodeModulesPath, pluginName);
|
|
92
|
-
try {
|
|
93
|
-
await unlink(link);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
console.error(`Failed to remove existing symlink for dev plugin: ${pluginName}`);
|
|
96
|
-
}
|
|
97
|
-
await symlink(resolve(packagePluginsPath, pluginName), link, 'dir');
|
|
98
|
-
} catch (error) {
|
|
99
|
-
console.error(`Failed to create symlink for dev plugin: ${pluginName}`);
|
|
100
|
-
}
|
|
156
|
+
const nodeModulesPath = process.env.NODE_MODULES_PATH;
|
|
157
|
+
await createPluginSymLink(pluginName, packagePluginsPath, nodeModulesPath, 'dev');
|
|
101
158
|
}
|
|
102
159
|
|
|
103
|
-
|
|
104
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Create symlinks for all dev plugins
|
|
162
|
+
* @returns {Promise<void>}
|
|
163
|
+
*/
|
|
105
164
|
async function createDevPluginsSymlink() {
|
|
106
|
-
const
|
|
107
|
-
if (!(await
|
|
165
|
+
const packagePluginsPath = resolve(process.cwd(), 'packages/plugins');
|
|
166
|
+
if (!(await fs.pathExists(packagePluginsPath))) {
|
|
108
167
|
return;
|
|
109
168
|
}
|
|
110
|
-
const pluginNames = await getStoragePluginNames(
|
|
169
|
+
const pluginNames = await getStoragePluginNames(packagePluginsPath);
|
|
111
170
|
await Promise.all(pluginNames.map((pluginName) => createDevPluginSymLink(pluginName)));
|
|
112
171
|
}
|
|
113
172
|
|
|
173
|
+
exports.createStoragePluginSymLink = createStoragePluginSymLink;
|
|
174
|
+
exports.createStoragePluginsSymlink = createStoragePluginsSymlink;
|
|
175
|
+
exports.createDevPluginSymLink = createDevPluginSymLink;
|
|
114
176
|
exports.createDevPluginsSymlink = createDevPluginsSymlink;
|