@steedos/service-package-registry 2.6.1-beta.7 → 2.6.2-beta.2

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.
Files changed (27) hide show
  1. package/main/default/client/project_nodes.client.js +2 -2
  2. package/main/default/manager/loader.js +136 -40
  3. package/main/default/manager/packages.js +29 -6
  4. package/main/default/manager/registry.js +26 -2
  5. package/main/default/objectTranslations/steedos_packages.en/steedos_packages.en.objectTranslation.yml +4 -0
  6. package/main/default/objects/steedos_packages/fields/dependencies.field.yml +4 -0
  7. package/main/default/objects/steedos_packages/fields/description.field.yml +1 -1
  8. package/main/default/objects/steedos_packages/fields/homepage.field.yml +4 -0
  9. package/main/default/objects/steedos_packages/fields/icon.field.yml +3 -0
  10. package/main/default/objects/steedos_packages/fields/instance_id.field.yml +1 -0
  11. package/main/default/objects/steedos_packages/fields/metadata.$.type.field.yml +1 -1
  12. package/main/default/objects/steedos_packages/fields/metadata.field.yml +2 -1
  13. package/main/default/objects/steedos_packages/fields/node_id.field.yml +1 -0
  14. package/main/default/objects/steedos_packages/fields/readme.field.yml +4 -0
  15. package/main/default/objects/steedos_packages/fields/service_name.field.yml +1 -0
  16. package/main/default/objects/steedos_packages/fields/static.field.yml +4 -0
  17. package/main/default/objects/steedos_packages/listviews/all.listview.yml +6 -5
  18. package/main/default/objects/steedos_packages/listviews/custom.listview.yml +8 -0
  19. package/main/default/objects/steedos_packages/listviews/system.listview.yml +8 -0
  20. package/main/default/pages/steedos_package_detail.page.amis.json +144 -0
  21. package/main/default/pages/steedos_package_detail.page.yml +12 -0
  22. package/main/default/pages/steedos_packages_list.page.amis.json +146 -0
  23. package/main/default/pages/steedos_packages_list.page.yml +12 -0
  24. package/package.json +7 -7
  25. package/project.package.service.js +179 -220
  26. package/main/default/routes/nodes.router.js +0 -226
  27. package/main/default/routes/registry.router.js +0 -21
@@ -1,10 +1,10 @@
1
1
  Steedos.PackageRegistry = {
2
2
  getNodes: function(){
3
- const projectNodes = Steedos.authRequest('/service/api/~packages-project-server/getProjectNodes', {async: false});
3
+ const projectNodes = Steedos.authRequest('/service/api/@steedos/service-project/getProjectNodes', {async: false});
4
4
  return projectNodes;
5
5
  },
6
6
  getNodesSelect: function(){
7
- const projectNodes = Steedos.authRequest('/service/api/~packages-project-server/getProjectNodes', {async: false});
7
+ const projectNodes = Steedos.authRequest('/service/api/@steedos/service-project/getProjectNodes', {async: false});
8
8
  let selectOptions = '';
9
9
  _.each(projectNodes, function(nodeID){
10
10
  selectOptions = selectOptions + `<option value ="${nodeID}">${nodeID}</option>`
@@ -9,11 +9,41 @@ const userDir = path.join(process.cwd(), '.steedos');
9
9
  const packagesFilePath = path.join(userDir, 'steedos-packages.yml');
10
10
  const metadataApi = require('@steedos/metadata-api');
11
11
  const util = require('./util');
12
+ const metaDataCore = require('@steedos/metadata-core');
13
+ const npmRCFilePath = path.join(userDir, '.npmrc')
14
+
15
+ // 读取.steedos下的.npmrc文件内容
16
+ const getNpmrc = ()=>{
17
+ let npmrc = "";
18
+ if(fs.existsSync(npmRCFilePath)){
19
+ npmrc = fs.readFileSync(npmRCFilePath, 'utf8')
20
+ }
21
+ return npmrc;
22
+ }
23
+
24
+ // 写入.steedos下的.npmrc文件内容
25
+ const setNpmrc = (data)=>{
26
+ fs.writeFileSync(npmRCFilePath, data);
27
+ }
28
+
29
+ const getPackageYmlData = (packagePath)=>{
30
+ let packageYmlData = {};
31
+ if(fs.existsSync(path.join(packagePath, 'package.service.yml'))){
32
+ packageYmlData = metaDataCore.loadFile(path.join(packagePath, 'package.service.yml')) || {};
33
+ }
34
+ if(fs.existsSync(path.join(packagePath, 'README.md'))){
35
+ packageYmlData.readme = metaDataCore.loadFile(path.join(packagePath, 'README.md'));
36
+ }else if(fs.existsSync(path.join(packagePath, 'readme.md'))){
37
+ packageYmlData.readme = metaDataCore.loadFile(path.join(packagePath, 'readme.md'));
38
+ }
39
+ return packageYmlData;
40
+ }
41
+
12
42
  const loadPackagesConfig = ()=>{
13
43
  return yaml.load(fs.readFileSync(packagesFilePath, 'utf8')) || {};
14
44
  }
15
45
 
16
- const appendToPackagesConfig = (packageName, options)=>{
46
+ const appendToPackagesConfig = (packageName, options, actionName)=>{
17
47
  let packages = loadPackagesConfig();
18
48
  let changeNamePackage = null;
19
49
  if(options.local && !packages[packageName]){
@@ -24,37 +54,72 @@ const appendToPackagesConfig = (packageName, options)=>{
24
54
  }
25
55
  })
26
56
  }
27
- if(changeNamePackage){
28
- //如果是修改package name, 在steedos-package.yml位置保持不变
29
- const newPackages = {};
30
- _.each(packages, (info, key)=>{
31
- if(key === changeNamePackage.module){
32
- delete changeNamePackage.module
33
- newPackages[packageName] = Object.assign(changeNamePackage, options)
34
- }else{
35
- newPackages[key] = info
36
- }
37
- })
38
- packages = newPackages
39
- }else{
57
+ if(options.static){
40
58
  if(!packages[packageName]){
41
59
  packages[packageName] = Object.assign({
42
- enable: true
60
+ enable: false,
61
+ local: true
43
62
  }, options)
63
+ if(options.enable){
64
+ const packagePath = options.path || path.dirname(require.resolve(`${packageName}/package.json`))
65
+ loadPackage(packageName, packagePath);
66
+ }
44
67
  }else{
68
+ // 对于已经存在的软件包, 不支持使用传入的enable控制软件包状态.
69
+ if(actionName === 'addPackage'){
70
+ delete options.enable
71
+ }
45
72
  packages[packageName] = Object.assign(packages[packageName], options)
46
73
  }
74
+ }else{
75
+ if(changeNamePackage){
76
+ //如果是修改package name, 在steedos-package.yml位置保持不变
77
+ const newPackages = {};
78
+ _.each(packages, (info, key)=>{
79
+ if(key === changeNamePackage.module){
80
+ delete changeNamePackage.module
81
+ newPackages[packageName] = Object.assign(changeNamePackage, options)
82
+ }else{
83
+ newPackages[key] = info
84
+ }
85
+ })
86
+ packages = newPackages
87
+ }else{
88
+ if(!packages[packageName]){
89
+ packages[packageName] = Object.assign({
90
+ enable: true
91
+ }, options)
92
+ }else{
93
+ packages[packageName] = Object.assign(packages[packageName], options)
94
+ }
95
+ }
47
96
  }
97
+
48
98
  let data = yaml.dump(packages);
49
99
  fs.writeFileSync(packagesFilePath, data);
50
100
  }
51
101
 
52
102
  const loadPackages = async ()=>{
103
+ let schema = objectql.getSteedosSchema();
104
+ let broker = schema.broker;
53
105
  const packages = loadPackagesConfig();
54
106
  for (const packageName in packages) {
55
107
  const package = packages[packageName]
56
108
  if(package.enable){
57
- if(package.local !== true){
109
+ if(package.static === true){
110
+ try {
111
+ const packagePath = package.path || path.dirname(require.resolve(`${packageName}/package.json`))
112
+ if(packagePath){
113
+ const packageInfo = await loadPackage(packageName, packagePath);
114
+ if(packageInfo){
115
+ appendToPackagesConfig(packageInfo.name, {version: packageInfo.version, description: packageInfo.description, local: true});
116
+ }
117
+ }
118
+ } catch (error) {
119
+ broker.logger.error(`start package ${packageName} error: ${error.message}`)
120
+ }
121
+
122
+ }else if(package.local !== true){
58
123
  try {
59
124
  const packagePath = path.dirname(require.resolve(`${packageName}/package.json`, {
60
125
  paths: [path.join(userDir, 'node_modules')]
@@ -69,18 +134,22 @@ const loadPackages = async ()=>{
69
134
  const packageInfo = await loadPackage(packageName);
70
135
  appendToPackagesConfig(packageInfo.name, {version: packageInfo.version, description: packageInfo.description, local: false});
71
136
  } catch (error) {
72
- console.error(error)
137
+ broker.logger.error(`start package ${packageName} error: ${error.message}`)
73
138
  }
74
139
  }
75
- }else if(package.local === true){
140
+ }else if(package.local === true && package.static != true){
76
141
  let packagePath = package.path;
77
142
  if(!path.isAbsolute(packagePath)){
78
143
  packagePath = path.resolve(process.cwd(), packagePath)
79
144
  }
80
145
  if(packagePath){
81
- const packageInfo = await loadPackage(packageName, packagePath);
82
- if(packageInfo){
83
- appendToPackagesConfig(packageInfo.name, {version: packageInfo.version, description: packageInfo.description, local: true});
146
+ try {
147
+ const packageInfo = await loadPackage(packageName, packagePath);
148
+ if(packageInfo){
149
+ appendToPackagesConfig(packageInfo.name, {version: packageInfo.version, description: packageInfo.description, local: true});
150
+ }
151
+ } catch (error) {
152
+ broker.logger.error(`start package ${packageName} error: ${error.message}`)
84
153
  }
85
154
  }
86
155
  }
@@ -130,7 +199,11 @@ const isPackage = (name)=>{
130
199
  }
131
200
  }
132
201
 
133
- const loadDependency = async (dependencyName, dependencyVersion)=>{
202
+ const loadDependency = async (mainPackageInfo = {}, dependencyName, dependencyVersion)=>{
203
+ // console.log(`loadDependency`, mainPackageInfo, dependencyName, dependencyVersion)
204
+ if(mainPackageInfo.static == true){
205
+ return ;
206
+ }
134
207
  let schema = objectql.getSteedosSchema();
135
208
  let broker = schema.broker;
136
209
  let packageInfo = null;
@@ -154,9 +227,11 @@ const loadDependency = async (dependencyName, dependencyVersion)=>{
154
227
  await enablePackage(dependencyName)
155
228
  }else{
156
229
  try {
157
- await installPackage(broker, {module: dependencyName, version: dependencyVersion, enable: true})
230
+ if(mainPackageInfo && mainPackageInfo.static != true){
231
+ await installPackage(broker, {module: dependencyName, version: dependencyVersion, enable: true})
232
+ }
158
233
  } catch (error) {
159
-
234
+ // console.log(error)
160
235
  }
161
236
  }
162
237
  // 如果steedos package yml 中没有该依赖,则直接安装
@@ -165,7 +240,7 @@ const loadDependency = async (dependencyName, dependencyVersion)=>{
165
240
  }
166
241
 
167
242
  const loadPackage = async (packageName, packagePath)=>{
168
- try {
243
+ // try {
169
244
  if(!packagePath){
170
245
  packagePath = path.dirname(require.resolve(`${packageName}/package.json`, {
171
246
  paths: [path.join(userDir, 'node_modules')]
@@ -179,19 +254,28 @@ const loadPackage = async (packageName, packagePath)=>{
179
254
  return ;
180
255
  }
181
256
  const packageInfo = require(path.join(packagePath, 'package.json'));
182
- await destroyExistThePackageService(packageInfo);
183
- await steedos.loadPackage(packagePath);
257
+ const packageYml = getPackageYmlData(packagePath);
184
258
 
185
- if(packageInfo.dependencies){
186
- for (const dependencyName in packageInfo.dependencies) {
187
- const dependencyVersion = packageInfo.dependencies[dependencyName];
188
- await loadDependency(dependencyName, dependencyVersion);
259
+ if(packageYml && packageYml.license && _.isArray(packageYml.license) && packageYml.license.length > 0){
260
+ const has = await broker.call('@steedos/service-license.checkProducts', {keys: packageYml.license});
261
+ if(!has){
262
+ throw new Error(`Software package 「${packageName}」 requires 「${packageYml.license.join(',')}」 license.`)
189
263
  }
190
- }
264
+ }
265
+
266
+ await destroyExistThePackageService(packageInfo);
267
+ await steedos.loadPackage(packagePath);
268
+ // const packageConfig = getPackageConfig(packageName);
269
+ // if(packageInfo.dependencies){
270
+ // for (const dependencyName in packageInfo.dependencies) {
271
+ // const dependencyVersion = packageInfo.dependencies[dependencyName];
272
+ // await loadDependency(packageConfig, dependencyName, dependencyVersion);
273
+ // }
274
+ // }
191
275
  return Object.assign({packagePath: packagePath}, packageInfo);
192
- } catch (error) {
193
- console.error(error)
194
- }
276
+ // } catch (error) {
277
+ // console.error(packageName, packagePath, error)
278
+ // }
195
279
  }
196
280
 
197
281
  const disablePackage = async (packageName)=>{
@@ -236,6 +320,7 @@ const removePackageConfig = (packageName)=>{
236
320
  const getPackageConfig = (packageName)=>{
237
321
  const packages = loadPackagesConfig();
238
322
  return _.find(packages, (info, name)=>{
323
+ info.name = name;
239
324
  return packageName == name
240
325
  });
241
326
  }
@@ -243,16 +328,20 @@ const getPackageConfig = (packageName)=>{
243
328
  const enablePackage = async (packageName)=>{
244
329
  let packagePath = null;
245
330
  let package = getPackageConfig(packageName);
246
- if(package && package.local){
331
+ if(package && package.local && package.static !=true){
247
332
  if(path.isAbsolute(package.path)){
248
333
  packagePath = package.path
249
334
  }else{
250
335
  packagePath = path.resolve(process.cwd(), package.path)
251
336
  }
252
337
  }else{
253
- packagePath = path.dirname(require.resolve(`${packageName}/package.json`, {
254
- paths: [path.join(userDir, 'node_modules')]
255
- }))
338
+ if(package && package.static){
339
+ packagePath = path.dirname(require.resolve(`${packageName}/package.json`))
340
+ }else{
341
+ packagePath = path.dirname(require.resolve(`${packageName}/package.json`, {
342
+ paths: [path.join(userDir, 'node_modules')]
343
+ }))
344
+ }
256
345
  }
257
346
  await loadPackage(packageName, packagePath)
258
347
 
@@ -271,6 +360,7 @@ const enablePackage = async (packageName)=>{
271
360
  }
272
361
  appendToPackagesConfig(packageName, package);
273
362
  let packageInfo = Object.assign({}, package, {name: packageName});
363
+ // console.log(`enable packageInfo`, packageInfo)
274
364
  return packageInfo;
275
365
  }
276
366
  const installPackage = async (broker, options)=>{
@@ -291,8 +381,10 @@ const installPackage = async (broker, options)=>{
291
381
  }
292
382
  appendToPackagesConfig(module, packageConfig);
293
383
  const metadata = await getPackageMetadata(util.getPackageRelativePath(process.cwd(), packagePath));
384
+ const packageYmlData = getPackageYmlData(packagePath);
294
385
  await broker.call(`@steedos/service-packages.install`, {
295
386
  serviceInfo: Object.assign({}, packageConfig, {
387
+ packageYmlData: packageYmlData,
296
388
  name: module,
297
389
  enable: enable,
298
390
  nodeID: broker.nodeID,
@@ -345,5 +437,9 @@ module.exports = {
345
437
  removePackage,
346
438
  getPackageInfo,
347
439
  getPackageMetadata,
348
- installPackage
440
+ installPackage,
441
+ getPackageYmlData,
442
+ getNpmrc,
443
+ setNpmrc,
444
+ getPackageConfig
349
445
  }
@@ -32,6 +32,8 @@ const getAllPackages = async ()=>{
32
32
  package.status = '';
33
33
  package.new_version = package.version
34
34
  package.local = package.local
35
+ package.static = package.static
36
+ package.homepage = package.homepage
35
37
  delete package.version
36
38
  if(installPackages[package.name]){
37
39
  package.status = installPackages[package.name].enable ? 'enable' : 'disable'
@@ -45,14 +47,17 @@ const getAllPackages = async ()=>{
45
47
  _package.version = package.version
46
48
  }else{
47
49
  packages.push({
50
+ label: package.label || packageName,
51
+ homepage: package.homepage,
52
+ description: package.description,
53
+ ...(package.packageYmlData || {}),
48
54
  _id : packageName.replace("/", '_'),
49
55
  name: packageName,
50
56
  status : package.enable ? 'starting' : 'disable',
51
57
  version : package.version,
52
58
  local: package.local,
53
- label: package.label || packageName,
54
- description: package.description,
55
- metadata: package.metadata
59
+ metadata: package.metadata,
60
+ static: package.static
56
61
  })
57
62
  }
58
63
  })
@@ -65,8 +70,13 @@ const getAllPackages = async ()=>{
65
70
  _package.node_id = packageInfo.nodeID
66
71
  _package.instance_id = packageInfo.instanceID
67
72
  _package.version = packageInfo.version
73
+ _package.homepage = packageInfo.homepage
68
74
  }else{
69
75
  packages.push({
76
+ label: packageInfo.label || packageName,
77
+ description: packageInfo.description,
78
+ homepage: packageInfo.homepage,
79
+ ...(packageInfo.packageYmlData || {}),
70
80
  _id : packageName.replace("/", '_'),
71
81
  name: packageName,
72
82
  service_name: packageInfo.name,
@@ -74,8 +84,6 @@ const getAllPackages = async ()=>{
74
84
  instance_id: packageInfo.instanceID,
75
85
  status : 'enable',
76
86
  version : packageInfo.version,
77
- label: packageInfo.label || packageName,
78
- description: packageInfo.description,
79
87
  local: false
80
88
  })
81
89
  }
@@ -178,9 +186,24 @@ const scanPackageMetadatas = async (packagePath) => {
178
186
  return packageMetadatas;
179
187
  }
180
188
 
189
+ const checkDependencies = async (packagePath, dependencies)=>{
190
+ if(!dependencies){
191
+ const packageServiceConfig = require(path.join(packagePath, 'package.service.js'));
192
+ dependencies = (packageServiceConfig && packageServiceConfig.dependencies) || [];
193
+ }
194
+ for(const item of dependencies){
195
+ const hasService = await objectql.getSteedosSchema().broker.registry.hasService(item);
196
+ if(!hasService){
197
+ throw new Error(`依赖项${item}未启动, 请先启动依赖项`)
198
+ }
199
+ }
200
+ return true;
201
+ }
202
+
181
203
  module.exports = {
182
204
  maintainSystemFiles,
183
205
  getAllPackages,
184
206
  getPackageVersions,
185
- scanPackageMetadatas
207
+ scanPackageMetadatas,
208
+ checkDependencies
186
209
  }
@@ -14,6 +14,8 @@ let installDenyList = [];
14
14
  let installAllAllowed = true;
15
15
  let installVersionRestricted = false;
16
16
  var activePromise = Promise.resolve();
17
+ const _ = require('lodash');
18
+ const npa = require("npm-package-arg");
17
19
 
18
20
  log.init({});
19
21
 
@@ -268,6 +270,27 @@ async function installModule(module, version, url, registry_url) {
268
270
  return activePromise;
269
271
  }
270
272
 
273
+ async function yarnAddPackage(yarnPackage){
274
+ var installDir = settings.userDir || ".";
275
+ var yarnArgs = ['add', '-E', ...yarnPackage.split(' '), '--json'];
276
+ const data = await exec.run(yarnCommand, yarnArgs, {cwd: installDir}, true);
277
+ const formatData = JSON.parse(_.last(_.compact(data.stdout.split('\n'))))
278
+ // 解析 yarn add 返回的结果
279
+ const steedosPackages = [];
280
+ _.each(formatData.data.trees, (module)=>{
281
+ const parsed = npa(module.name);
282
+ const packagePath = path.dirname(require.resolve(`${parsed.name}/package.json`, {
283
+ paths: [path.join(installDir, 'node_modules')]
284
+ }))
285
+ steedosPackages.push({
286
+ name: parsed.name,
287
+ version: parsed.rawSpec,
288
+ path: packagePath
289
+ })
290
+ })
291
+ return steedosPackages;
292
+ }
293
+
271
294
 
272
295
  async function uninstallModule(module){
273
296
  if (Buffer.isBuffer(module)) {
@@ -320,11 +343,12 @@ async function uninstallModule(module){
320
343
  // }
321
344
 
322
345
  const isPackageUrl = (url)=>{
323
- return pkgurlRe.test(url)
346
+ return pkgurlRe.test(url) || localtgzRe.test(url)
324
347
  }
325
348
 
326
349
  module.exports = {
327
350
  installModule,
328
351
  uninstallModule,
329
- isPackageUrl
352
+ isPackageUrl,
353
+ yarnAddPackage
330
354
  }
@@ -104,6 +104,10 @@ fields:
104
104
  listviews:
105
105
  all:
106
106
  label: All Packages
107
+ custom:
108
+ label: Custom Packages
109
+ system:
110
+ label: System Packages
107
111
  actions:
108
112
  disable:
109
113
  label: Disable
@@ -0,0 +1,4 @@
1
+ name: dependencies
2
+ type: select
3
+ multiple: true
4
+ label: 依赖项
@@ -10,6 +10,6 @@ readonly: false
10
10
  required: false
11
11
  rows: 2
12
12
  searchable: false
13
- sort_no: 130
13
+ sort_no: 450
14
14
  sortable: false
15
15
  type: textarea
@@ -0,0 +1,4 @@
1
+ name: homepage
2
+ type: url
3
+ label: homepage
4
+ sort_no: 130
@@ -0,0 +1,3 @@
1
+ name: icon
2
+ type: text
3
+ visible_on: "{{false}}"
@@ -12,3 +12,4 @@ searchable: true
12
12
  sort_no: 110
13
13
  sortable: true
14
14
  type: text
15
+ visible_on: "{{false}}"
@@ -33,7 +33,7 @@ options:
33
33
  value: ApprovalProcess
34
34
  - label: 角色
35
35
  value: Role
36
- - label: 岗位
36
+ - label: 审批岗位
37
37
  value: FlowRole
38
38
  - label: 查询
39
39
  value: Query
@@ -1,4 +1,5 @@
1
1
  name: metadata
2
2
  label: 软件包组件
3
3
  type: grid
4
- is_wide: true
4
+ is_wide: true
5
+ sort_no: 500
@@ -12,3 +12,4 @@ searchable: true
12
12
  sort_no: 110
13
13
  sortable: true
14
14
  type: text
15
+ visible_on: "{{false}}"
@@ -0,0 +1,4 @@
1
+ name: readme
2
+ type: markdown
3
+ is_wide: true
4
+ visible_on: "{{false}}"
@@ -12,3 +12,4 @@ searchable: true
12
12
  sort_no: 100
13
13
  sortable: true
14
14
  type: text
15
+ visible_on: "{{false}}"
@@ -0,0 +1,4 @@
1
+ name: static
2
+ type: boolean
3
+ label: 静态(不支持卸载、升级)
4
+ visible_on: "{{false}}"
@@ -2,15 +2,16 @@ name: all
2
2
  columns:
3
3
  - field: label
4
4
  wrap: false
5
- - field: version
6
- wrap: false
7
5
  - field: description
8
- width: '150'
6
+ wrap: false
7
+ - field: version
9
8
  wrap: false
10
9
  - field: status
10
+ - field: static
11
+ - field: icon
11
12
  filter_scope: space
12
- label: 已安装
13
+ label: 所有软件包
13
14
  scrolling_mode: standard
14
15
  shared: true
15
16
  show_count: false
16
- type: grid
17
+ type: grid
@@ -0,0 +1,8 @@
1
+ name: custom
2
+ filter_scope: space
3
+ label: 自定义软件包
4
+ scrolling_mode: standard
5
+ shared: true
6
+ show_count: false
7
+ type: grid
8
+ filters: [["static","!=", true]]
@@ -0,0 +1,8 @@
1
+ name: system
2
+ filter_scope: space
3
+ label: 系统软件包
4
+ scrolling_mode: standard
5
+ shared: true
6
+ show_count: false
7
+ type: grid
8
+ filters: [["static","=", true]]