@abtnode/core 1.16.52-beta-20251005-235515-42ad5caf → 1.16.52-beta-20251008-091027-c46c73e3

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/lib/api/team.js CHANGED
@@ -2792,14 +2792,21 @@ class TeamAPI extends EventEmitter {
2792
2792
  try {
2793
2793
  const state = await this.getOrgState(teamDid);
2794
2794
  const { passports, orgs, ...rest } = await state.list(payload, context);
2795
- // 获取每个组织的 passports
2796
- const orgPassports = await Promise.all(orgs.map((o) => this.getRoles({ teamDid, orgId: o.id })));
2797
-
2798
- orgs.forEach((o, index) => {
2799
- const roles = orgPassports[index]; // 获取每个组织的角色
2800
- // 过滤 passports
2801
- o.passports = passports.filter((p) => roles.some((r) => r.name === p.name));
2802
- });
2795
+ const { includePassports = true } = payload.options || {};
2796
+ if (includePassports) {
2797
+ // 获取每个组织的 passports
2798
+ const orgPassports = await Promise.all(orgs.map((o) => this.getRoles({ teamDid, orgId: o.id })));
2799
+
2800
+ orgs.forEach((o, index) => {
2801
+ const roles = orgPassports[index]; // 获取每个组织的角色
2802
+ // 过滤 passports
2803
+ o.passports = passports.filter((p) => roles.some((r) => r.name === p.name));
2804
+ });
2805
+ } else {
2806
+ orgs.forEach((o) => {
2807
+ o.passports = [];
2808
+ });
2809
+ }
2803
2810
 
2804
2811
  return {
2805
2812
  ...rest,
@@ -2848,7 +2855,12 @@ class TeamAPI extends EventEmitter {
2848
2855
  }
2849
2856
 
2850
2857
  const state = await this.getOrgState(teamDid);
2851
- const blocklet = await getBlocklet({ did: teamDid, states: this.states, dataDirs: this.dataDirs });
2858
+ const blocklet = await getBlocklet({
2859
+ did: teamDid,
2860
+ states: this.states,
2861
+ dataDirs: this.dataDirs,
2862
+ useCache: true,
2863
+ });
2852
2864
  const orgCount = await state.getOrgCountByUser(context.user.did);
2853
2865
 
2854
2866
  const { veriftMaxOrgPerUser } = createOrgValidators(blocklet);
@@ -2859,13 +2871,15 @@ class TeamAPI extends EventEmitter {
2859
2871
 
2860
2872
  // 创建 org 的 owner passport, 并赋值给 owner
2861
2873
  const roleName = md5(`${result.id}-owner`); // 避免 name 重复
2862
- await this.createRole({ teamDid, name: roleName, title: result.name, description: 'Owner', orgId: result.id });
2863
- await this.issuePassportToUser({
2864
- teamDid,
2865
- userDid: result.ownerDid,
2866
- role: roleName,
2867
- notification: {},
2868
- });
2874
+ await Promise.all([
2875
+ this.createRole({ teamDid, name: roleName, title: result.name, description: 'Owner', orgId: result.id }),
2876
+ this.issuePassportToUser({
2877
+ teamDid,
2878
+ userDid: result.ownerDid,
2879
+ role: roleName,
2880
+ notification: {},
2881
+ }),
2882
+ ]);
2869
2883
 
2870
2884
  return result;
2871
2885
  } catch (err) {
@@ -2959,6 +2959,7 @@ class DiskBlockletManager extends BaseBlockletManager {
2959
2959
  };
2960
2960
  }
2961
2961
 
2962
+ let shouldRotateSession = false;
2962
2963
  if (!isNil(org)) {
2963
2964
  const ORG_SCHEMA = Joi.object({
2964
2965
  enabled: Joi.boolean().required(),
@@ -2969,6 +2970,11 @@ class DiskBlockletManager extends BaseBlockletManager {
2969
2970
  if (error) {
2970
2971
  throw new CustomError(400, error.message);
2971
2972
  }
2973
+ const currentState = await this.getBlocklet(did, { useCache: true });
2974
+ const orgEnabled = get(currentState, 'settings.org.enabled', false);
2975
+ if (orgEnabled !== org.enabled) {
2976
+ shouldRotateSession = true;
2977
+ }
2972
2978
  params.org = org;
2973
2979
  }
2974
2980
 
@@ -2989,6 +2995,10 @@ class DiskBlockletManager extends BaseBlockletManager {
2989
2995
  this.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
2990
2996
  this.emit(BlockletEvents.updated, { ...newState, context });
2991
2997
 
2998
+ if (shouldRotateSession) {
2999
+ this.teamAPI.rotateSessionKey({ teamDid: did });
3000
+ }
3001
+
2992
3002
  return newState;
2993
3003
  }
2994
3004
 
@@ -3519,26 +3529,30 @@ class DiskBlockletManager extends BaseBlockletManager {
3519
3529
  isGreen,
3520
3530
  });
3521
3531
 
3522
- const res = await this.getBlocklet(did);
3532
+ if (needUpdateBlueStatus) {
3533
+ await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, {
3534
+ componentDids,
3535
+ isGreen: !isGreen,
3536
+ });
3537
+ }
3538
+
3539
+ const nextBlocklet = await this.getBlocklet(did);
3523
3540
 
3541
+ await this.configSynchronizer.throttledSyncAppConfig(nextBlocklet);
3542
+ const componentsInfo = getComponentsInternalInfo(nextBlocklet);
3524
3543
  this.emit(BlockletInternalEvents.componentStarted, {
3525
3544
  appDid: blocklet.appDid,
3526
- components: (componentDids || []).map((x) => ({ did: x })),
3545
+ components: componentsInfo,
3527
3546
  });
3528
- this.configSynchronizer.throttledSyncAppConfig(res);
3529
3547
 
3530
- this.emit(BlockletEvents.statusChange, res);
3531
- this.emit(BlockletEvents.started, { ...res, componentDids });
3548
+ this.emit(BlockletEvents.statusChange, nextBlocklet);
3549
+ this.emit(BlockletEvents.started, { ...nextBlocklet, componentDids });
3532
3550
 
3533
3551
  launcher.notifyBlockletStarted(blocklet);
3534
3552
 
3535
3553
  logger.info('blocklet healthy', { did, name, time: Date.now() - startedAt });
3536
3554
 
3537
3555
  if (needUpdateBlueStatus) {
3538
- await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, {
3539
- componentDids,
3540
- isGreen: !isGreen,
3541
- });
3542
3556
  try {
3543
3557
  await this.deleteProcess({ did, componentDids, isGreen: !isGreen }, context);
3544
3558
  } catch {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-await-in-loop */
2
2
  const logger = require('@abtnode/logger')('@abtnode/core:blocklet-manager:blue-green');
3
- const { BlockletStatus, BlockletGroup, BlockletEvents } = require('@blocklet/constant');
3
+ const { BlockletStatus, BlockletGroup, BlockletEvents, BlockletInternalEvents } = require('@blocklet/constant');
4
4
  const {
5
5
  hasRunnableComponent,
6
6
  getDisplayName,
@@ -9,6 +9,7 @@ const {
9
9
  getComponentMissingConfigs,
10
10
  } = require('@blocklet/meta/lib/util');
11
11
  const { getBlockletEngine, hasStartEngine } = require('@blocklet/meta/lib/engine');
12
+ const { getComponentsInternalInfo } = require('@blocklet/meta/lib/blocklet');
12
13
  const {
13
14
  forEachBlocklet,
14
15
  validateBlocklet,
@@ -168,123 +169,131 @@ const blueGreenStartBlocklet = async (
168
169
  const blueGreenComponentIds = await blueGreenGetComponentIds(blocklet1, entryComponentIds);
169
170
 
170
171
  // eslint-disable-next-line no-unreachable-loop
171
- await Promise.all(
172
- blueGreenComponentIds.map(async (item) => {
173
- if (!item.componentDids.length) {
174
- return;
175
- }
176
- const nextBlocklet = await ensureAppPortsNotOccupied({
177
- blocklet: blocklet1,
172
+ for (const item of blueGreenComponentIds) {
173
+ if (!item.componentDids.length) {
174
+ continue;
175
+ }
176
+ const nextBlocklet = await ensureAppPortsNotOccupied({
177
+ blocklet: blocklet1,
178
+ componentDids: item.componentDids,
179
+ states,
180
+ manager,
181
+ isGreen: item.changeToGreen,
182
+ });
183
+
184
+ try {
185
+ const doc1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, {
178
186
  componentDids: item.componentDids,
179
- states,
180
- manager,
187
+ operator,
181
188
  isGreen: item.changeToGreen,
182
189
  });
183
- try {
184
- const doc1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, {
185
- componentDids: item.componentDids,
186
- operator,
187
- isGreen: item.changeToGreen,
188
- });
189
- nextBlocklet.greenStatus = BlockletStatus.starting;
190
- manager.emit(BlockletEvents.statusChange, doc1);
190
+ nextBlocklet.greenStatus = BlockletStatus.starting;
191
+ manager.emit(BlockletEvents.statusChange, doc1);
191
192
 
192
- const nodeInfo = await states.node.read();
193
- const nodeEnvironments = await states.node.getEnvironments();
193
+ const nodeInfo = await states.node.read();
194
+ const nodeEnvironments = await states.node.getEnvironments();
194
195
 
195
- // 钩子函数设置
196
- const getHookFn =
197
- (hookName) =>
198
- async (b, { env }) => {
199
- const hookArgs = getHookArgs(b);
200
- const needRunDocker = await checkNeedRunDocker(b.meta, env, nodeInfo, isExternalBlocklet(nextBlocklet));
201
- if (!b.meta.scripts?.[hookName]) {
202
- return null;
203
- }
204
- if (needRunDocker) {
205
- return dockerExec({
206
- blocklet: nextBlocklet,
207
- meta: b.meta,
208
- script: b.meta.scripts?.[hookName],
209
- hookName,
210
- nodeInfo,
211
- env,
212
- ...hookArgs,
213
- });
214
- }
215
- return hooks[hookName](b, {
216
- appDir: b.env.appDir,
217
- hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
196
+ // 钩子函数设置
197
+ const getHookFn =
198
+ (hookName) =>
199
+ async (b, { env }) => {
200
+ const hookArgs = getHookArgs(b);
201
+ const needRunDocker = await checkNeedRunDocker(b.meta, env, nodeInfo, isExternalBlocklet(nextBlocklet));
202
+ if (!b.meta.scripts?.[hookName]) {
203
+ return null;
204
+ }
205
+ if (needRunDocker) {
206
+ return dockerExec({
207
+ blocklet: nextBlocklet,
208
+ meta: b.meta,
209
+ script: b.meta.scripts?.[hookName],
210
+ hookName,
211
+ nodeInfo,
218
212
  env,
219
- did, // root blocklet did,
220
- teamManager: manager.teamManager,
221
213
  ...hookArgs,
222
214
  });
223
- };
224
-
225
- await startBlockletProcess(nextBlocklet, {
226
- ...context,
227
- preFlight: getHookFn('preFlight'),
228
- preStart: getHookFn('preStart'),
229
- postStart: getHookFn('postStart'),
230
- nodeEnvironments,
231
- nodeInfo,
232
- e2eMode,
233
- componentDids: item.componentDids,
234
- configSynchronizer: manager.configSynchronizer,
235
- isGreen: item.changeToGreen,
236
- });
215
+ }
216
+ return hooks[hookName](b, {
217
+ appDir: b.env.appDir,
218
+ hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
219
+ env,
220
+ did, // root blocklet did,
221
+ teamManager: manager.teamManager,
222
+ ...hookArgs,
223
+ });
224
+ };
237
225
 
238
- // 健康检查绿色环境
239
- const { startTimeout, minConsecutiveTime } = getHealthyCheckTimeout(nextBlocklet, {
240
- checkHealthImmediately,
241
- componentDids: item.componentDids,
242
- });
226
+ await startBlockletProcess(nextBlocklet, {
227
+ ...context,
228
+ preFlight: getHookFn('preFlight'),
229
+ preStart: getHookFn('preStart'),
230
+ postStart: getHookFn('postStart'),
231
+ nodeEnvironments,
232
+ nodeInfo,
233
+ e2eMode,
234
+ componentDids: item.componentDids,
235
+ configSynchronizer: manager.configSynchronizer,
236
+ isGreen: item.changeToGreen,
237
+ });
243
238
 
244
- await manager._onCheckIfStarted(
245
- {
246
- did,
247
- context,
248
- minConsecutiveTime,
249
- timeout: startTimeout,
250
- componentDids: item.componentDids,
251
- },
252
- { throwOnError: true, isGreen: item.changeToGreen, needUpdateBlueStatus: true }
253
- );
239
+ // 健康检查绿色环境
240
+ const { startTimeout, minConsecutiveTime } = getHealthyCheckTimeout(nextBlocklet, {
241
+ checkHealthImmediately,
242
+ componentDids: item.componentDids,
243
+ });
254
244
 
255
- logger.info('Green environment started successfully', {
245
+ await manager._onCheckIfStarted(
246
+ {
256
247
  did,
248
+ context,
249
+ minConsecutiveTime,
250
+ timeout: startTimeout,
257
251
  componentDids: item.componentDids,
258
- });
259
- } catch (err) {
260
- const error = Array.isArray(err) ? err[0] : err;
261
- logger.error('Failed to start green environment', { error, did, title: blocklet1.meta.title });
252
+ },
253
+ { throwOnError: true, isGreen: item.changeToGreen, needUpdateBlueStatus: true }
254
+ );
262
255
 
263
- try {
264
- await manager.deleteProcess({ did, componentDids: item.componentDids, isGreen: item.changeToGreen });
265
- manager.emit(BlockletEvents.statusChange, blocklet1);
266
- } catch (cleanupError) {
267
- logger.error('Failed to cleanup green environment', { cleanupError });
268
- }
256
+ logger.info('Green environment started successfully', {
257
+ did,
258
+ componentDids: item.componentDids,
259
+ });
260
+ } catch (err) {
261
+ const error = Array.isArray(err) ? err[0] : err;
262
+ logger.error('Failed to start green environment', { error, did, title: blocklet1.meta.title });
269
263
 
270
- const description = `Green environment start failed for ${getDisplayName(blocklet1)}: ${error.message}`;
271
- if (!ignoreErrorNotification) {
272
- manager._createNotification(did, {
273
- title: 'Blue-Green Deployment: Green Start Failed',
274
- description,
275
- entityType: 'blocklet',
276
- entityId: did,
277
- severity: 'error',
278
- });
279
- }
264
+ try {
265
+ await manager.deleteProcess({ did, componentDids: item.componentDids, isGreen: item.changeToGreen });
266
+ manager.emit(BlockletEvents.statusChange, blocklet1);
267
+ } catch (cleanupError) {
268
+ logger.error('Failed to cleanup green environment', { cleanupError });
269
+ }
280
270
 
281
- if (throwOnError) {
282
- throw new Error(description);
283
- }
284
- throw error;
271
+ const description = `Green environment start failed for ${getDisplayName(blocklet1)}: ${error.message}`;
272
+ if (!ignoreErrorNotification) {
273
+ manager._createNotification(did, {
274
+ title: 'Blue-Green Deployment: Green Start Failed',
275
+ description,
276
+ entityType: 'blocklet',
277
+ entityId: did,
278
+ severity: 'error',
279
+ });
285
280
  }
286
- })
287
- );
281
+
282
+ if (throwOnError) {
283
+ throw new Error(description);
284
+ }
285
+ throw error;
286
+ }
287
+ }
288
+
289
+ const nextBlocklet = await manager.getBlocklet(did);
290
+ const componentsInfo = getComponentsInternalInfo(nextBlocklet);
291
+ manager.emit(BlockletInternalEvents.componentStarted, {
292
+ appDid: nextBlocklet.appDid,
293
+ components: componentsInfo,
294
+ });
295
+
296
+ manager.emit(BlockletEvents.statusChange, nextBlocklet);
288
297
  };
289
298
 
290
299
  module.exports = {