openyida 2026.5.9-beta.0 → 2026.5.9-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.
@@ -483,12 +483,15 @@ async function fetchLegacyQrCodeUrl(baseUrl, cookieHeader) {
483
483
  };
484
484
  }
485
485
 
486
- async function fetchDingtalkOAuthQrCodeUrl(loginPageUrl, cookieHeader) {
486
+ async function fetchDingtalkOAuthQrCodeUrl(loginPageUrl, cookieHeader, options = {}) {
487
487
  const parsedLoginUrl = new URL(loginPageUrl);
488
488
  const origin = parsedLoginUrl.origin;
489
489
  const apiUrl = `${origin}/oauth2/generate_qrcode`;
490
+ const targetCorpId = getTargetCorpId(options);
490
491
 
491
- const response = await fetchPost(apiUrl, buildOAuthPostData(loginPageUrl), {
492
+ const response = await fetchPost(apiUrl, buildOAuthPostData(loginPageUrl, {
493
+ ...(targetCorpId ? { corpId: targetCorpId } : {}),
494
+ }), {
492
495
  cookieHeader,
493
496
  referer: loginPageUrl,
494
497
  origin,
@@ -522,6 +525,7 @@ async function fetchDingtalkOAuthQrCodeUrl(loginPageUrl, cookieHeader) {
522
525
  loginPageUrl,
523
526
  origin,
524
527
  code,
528
+ corpId: targetCorpId,
525
529
  },
526
530
  };
527
531
  }
@@ -534,9 +538,9 @@ async function fetchDingtalkOAuthQrCodeUrl(loginPageUrl, cookieHeader) {
534
538
  * @param {string} loginPageUrl
535
539
  * @returns {Promise<{ qrUrl: string, state: string, cookieHeader: string, context: object }>}
536
540
  */
537
- async function fetchQrCodeUrl(baseUrl, cookieHeader, loginPageUrl) {
541
+ async function fetchQrCodeUrl(baseUrl, cookieHeader, loginPageUrl, options = {}) {
538
542
  if (isDingtalkOAuthChallengeUrl(loginPageUrl)) {
539
- return fetchDingtalkOAuthQrCodeUrl(loginPageUrl, cookieHeader);
543
+ return fetchDingtalkOAuthQrCodeUrl(loginPageUrl, cookieHeader, options);
540
544
  }
541
545
 
542
546
  return fetchLegacyQrCodeUrl(baseUrl, cookieHeader);
@@ -546,7 +550,7 @@ async function postDingtalkOAuthLoginWithQr(context, cookieHeader, extraParams =
546
550
  const pollUrl = `${context.origin}/oauth2/login_with_qr`;
547
551
  const response = await fetchPost(pollUrl, buildOAuthPostData(context.loginPageUrl, {
548
552
  code: context.code,
549
- exclusiveCorpId: '',
553
+ ...(context.corpId ? { corpId: context.corpId } : {}),
550
554
  stayLogin: false,
551
555
  ...extraParams,
552
556
  }), {
@@ -585,7 +589,7 @@ async function pollDingtalkQrCodeStatus(state, cookieHeader, onWaiting, context,
585
589
 
586
590
  const { parsed, cookieHeader: updatedCookieHeader } = await postLoginWithQr(context, cookieHeader, {
587
591
  code: state,
588
- exclusiveCorpId: targetCorpId || '',
592
+ ...(targetCorpId ? { corpId: targetCorpId } : {}),
589
593
  stayLogin: false,
590
594
  });
591
595
  cookieHeader = updatedCookieHeader;
@@ -724,7 +728,7 @@ async function exchangeDingtalkOAuthResult(baseUrl, loginResult, cookieHeader, c
724
728
  selectedCorp = await resolveCorpSelection(corpList, options);
725
729
 
726
730
  const retryResult = await postLoginWithQr(context, cookieHeader, {
727
- exclusiveCorpId: selectedCorp.corpId,
731
+ corpId: selectedCorp.corpId,
728
732
  });
729
733
  cookieHeader = retryResult.cookieHeader;
730
734
  const parsed = retryResult.parsed;
@@ -753,6 +757,15 @@ async function exchangeDingtalkOAuthResult(baseUrl, loginResult, cookieHeader, c
753
757
  };
754
758
  }
755
759
 
760
+ async function resolveDingtalkOAuthCorpForFreshQr(loginResult, options = {}) {
761
+ if (!shouldChooseDingtalkOAuthOrganization(loginResult)) {return null;}
762
+ if (getTargetCorpId(options)) {return null;}
763
+
764
+ const corpList = normalizeDingtalkOAuthOrgList(loginResult.orgList);
765
+ if (corpList.length === 0) {return null;}
766
+ return resolveCorpSelection(corpList, options);
767
+ }
768
+
756
769
  /**
757
770
  * Step 5:获取用户可访问的组织列表。
758
771
  * @param {string} baseUrl
@@ -1053,7 +1066,9 @@ async function startCodexQrLogin(options = {}) {
1053
1066
  const session = await fetchInitialSession(baseUrl, options);
1054
1067
  let { cookieHeader } = session;
1055
1068
  const { loginPageUrl } = session;
1056
- const { qrUrl, state, cookieHeader: updatedCookieHeader, context } = await fetchQrCodeUrl(baseUrl, cookieHeader, loginPageUrl);
1069
+ const { qrUrl, state, cookieHeader: updatedCookieHeader, context } = await fetchQrCodeUrl(baseUrl, cookieHeader, loginPageUrl, {
1070
+ corpId: targetCorpId,
1071
+ });
1057
1072
  cookieHeader = updatedCookieHeader;
1058
1073
 
1059
1074
  let imageWritten = false;
@@ -1199,6 +1214,7 @@ async function selectCodexQrCorp(sessionFile, options = {}) {
1199
1214
  async function qrLogin(options = {}) {
1200
1215
  // 优先使用传入的 baseUrl,否则从环境配置解析(支持私有化)
1201
1216
  let baseUrl = (options.baseUrl || resolveEndpoint(null)).replace(/\/+$/, '');
1217
+ const targetCorpId = getTargetCorpId(options);
1202
1218
 
1203
1219
  const { banner: qBanner, step: qStep, info: qInfo, success: qSuccess, warn: qWarn, label: qLabel, sep: qSep } = require('../core/chalk');
1204
1220
 
@@ -1214,7 +1230,9 @@ async function qrLogin(options = {}) {
1214
1230
  qStep(2, t('qr_login.step_get_qr'));
1215
1231
  let qrUrl, state, context;
1216
1232
  try {
1217
- ({ qrUrl, state, cookieHeader, context } = await fetchQrCodeUrl(baseUrl, cookieHeader, loginPageUrl));
1233
+ ({ qrUrl, state, cookieHeader, context } = await fetchQrCodeUrl(baseUrl, cookieHeader, loginPageUrl, {
1234
+ corpId: targetCorpId,
1235
+ }));
1218
1236
  } catch (err) {
1219
1237
  throw new Error(t('qr_login.get_qr_error', err.message));
1220
1238
  }
@@ -1242,7 +1260,10 @@ async function qrLogin(options = {}) {
1242
1260
  scannedMessageShown = true;
1243
1261
  }
1244
1262
  },
1245
- context
1263
+ context,
1264
+ {
1265
+ corpId: targetCorpId,
1266
+ }
1246
1267
  ));
1247
1268
  } catch (err) {
1248
1269
  throw new Error(t('qr_login.poll_error', err.message));
@@ -1255,8 +1276,18 @@ async function qrLogin(options = {}) {
1255
1276
  let selectedCorp = null;
1256
1277
  try {
1257
1278
  if (context && context.type === 'dingtalk_oauth') {
1279
+ selectedCorp = await resolveDingtalkOAuthCorpForFreshQr(loginResult, options);
1280
+ if (selectedCorp && !options.retryWithSelectedCorp) {
1281
+ qSuccess(t('qr_login.corp_selected', selectedCorp.corpName));
1282
+ return qrLogin({
1283
+ ...options,
1284
+ corpId: selectedCorp.corpId,
1285
+ retryWithSelectedCorp: true,
1286
+ });
1287
+ }
1288
+
1258
1289
  const exchangeResult = await exchangeDingtalkOAuthResult(baseUrl, loginResult, cookieHeader, context, {
1259
- corpId: options.corpId,
1290
+ corpId: targetCorpId,
1260
1291
  });
1261
1292
  ({ cookieHeader, baseUrl, selectedCorp } = exchangeResult);
1262
1293
  if (selectedCorp) {
@@ -1282,7 +1313,7 @@ async function qrLogin(options = {}) {
1282
1313
  // Step 7: 选择组织(如果有多个)
1283
1314
  if (!selectedCorp && corpList.length > 0) {
1284
1315
  try {
1285
- selectedCorp = await resolveCorpSelection(corpList, { corpId: options.corpId });
1316
+ selectedCorp = await resolveCorpSelection(corpList, { corpId: targetCorpId });
1286
1317
  qSuccess(t('qr_login.corp_selected', selectedCorp.corpName));
1287
1318
 
1288
1319
  // 切换到目标组织
@@ -1339,7 +1370,9 @@ module.exports = {
1339
1370
  selectCorpById,
1340
1371
  resolveCorpSelection,
1341
1372
  exchangeDingtalkOAuthResult,
1373
+ resolveDingtalkOAuthCorpForFreshQr,
1342
1374
  pollDingtalkQrCodeStatus,
1375
+ buildOAuthPostData,
1343
1376
  buildCodexCorpInteraction,
1344
1377
  buildCodexPollCommand,
1345
1378
  getTargetCorpId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.5.9-beta.0",
3
+ "version": "2026.5.9-beta.2",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",