openxiangda 1.0.239 → 1.0.240

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/cli.js CHANGED
@@ -7292,6 +7292,11 @@ async function runAppReleaseCommand(
7292
7292
  environmentControl: appReleaseEnvironmentControl(flags),
7293
7293
  }
7294
7294
  );
7295
+ const finalizedDataViews = await finalizeDeferredDataViewResources(
7296
+ config,
7297
+ target,
7298
+ readCommaSeparatedFlag(flags, 'finalize-data-views')
7299
+ );
7295
7300
  const bindingVerification =
7296
7301
  await verifyFinalizedBackendBindingContracts(
7297
7302
  config,
@@ -7336,6 +7341,9 @@ async function runAppReleaseCommand(
7336
7341
  prepared,
7337
7342
  verified,
7338
7343
  activated,
7344
+ ...(finalizedDataViews
7345
+ ? { finalizedDataViews }
7346
+ : {}),
7339
7347
  ...(bindingVerification ? { bindingVerification } : {}),
7340
7348
  ...(healthWait ? { healthWait } : {}),
7341
7349
  ...(stateReconcileWarning ? { stateReconcileWarning } : {}),
@@ -14380,9 +14388,16 @@ async function resource(args) {
14380
14388
  manifest.scopeGrantSources || []
14381
14389
  )
14382
14390
  : [];
14391
+ const dataViewFormCodes = stagedChangeId
14392
+ ? resolveDataViewSourceFormCodes(
14393
+ manifest.dataViews || [],
14394
+ target.bound
14395
+ )
14396
+ : [];
14383
14397
  const stagedContractFormCodes = unique([
14384
14398
  ...workflowFormCodes,
14385
14399
  ...scopeGrantSourceFormCodes,
14400
+ ...dataViewFormCodes,
14386
14401
  ]).sort();
14387
14402
  if (
14388
14403
  stagedContractFormCodes.length > 0 &&
@@ -23789,6 +23804,10 @@ async function findExistingScopeResource(config, target, segment, code) {
23789
23804
  }
23790
23805
 
23791
23806
  async function publishDataViewResources(config, target, dataViews, result, options = {}) {
23807
+ const stagedFormBindingOverlays =
23808
+ options.stagedFormBindingOverlays instanceof Map
23809
+ ? options.stagedFormBindingOverlays
23810
+ : new Map();
23792
23811
  for (const dataViewItem of dataViews) {
23793
23812
  if (shouldSkipNoopResource(options, 'dataView', dataViewItem.code)) {
23794
23813
  recordNoopResource(result, 'dataView', dataViewItem.code, options);
@@ -23796,6 +23815,18 @@ async function publishDataViewResources(config, target, dataViews, result, optio
23796
23815
  }
23797
23816
  const existing = await findExistingDataView(config, target, dataViewItem.code);
23798
23817
  const body = normalizeDataViewManifest(target.bound, dataViewItem);
23818
+ const stagedFormReleases = options.finalizeDeferredDataViews
23819
+ ? []
23820
+ : stagedDataViewFormReleaseDependencies(
23821
+ body,
23822
+ stagedFormBindingOverlays
23823
+ );
23824
+ if (stagedFormReleases.length > 0) {
23825
+ body.stagedFormReleases = stagedFormReleases;
23826
+ }
23827
+ if (options.finalizeDeferredDataViews) {
23828
+ body.finalizeDeferred = true;
23829
+ }
23799
23830
  const data = existing
23800
23831
  ? await requestWithAuth(
23801
23832
  config,
@@ -23819,10 +23850,26 @@ async function publishDataViewResources(config, target, dataViews, result, optio
23819
23850
  result.published.push({
23820
23851
  kind: 'dataView',
23821
23852
  code: dataViewItem.code,
23822
- action: existing ? 'update' : 'create',
23853
+ action: options.finalizeDeferredDataViews
23854
+ ? data?.status === 'active'
23855
+ ? 'finalize'
23856
+ : 'noop'
23857
+ : existing
23858
+ ? 'update'
23859
+ : 'create',
23823
23860
  id: data?.id,
23861
+ status: data?.status || null,
23862
+ ...(stagedFormReleases.length > 0
23863
+ ? {
23864
+ activation: 'deferred-until-form-activation',
23865
+ stagedFormReleaseCount: stagedFormReleases.length,
23866
+ }
23867
+ : {}),
23824
23868
  });
23825
- if (Array.isArray(body.permissionGroups)) {
23869
+ if (
23870
+ !options.finalizeDeferredDataViews &&
23871
+ Array.isArray(body.permissionGroups)
23872
+ ) {
23826
23873
  await publishDataViewPermissionGroups(config, target, dataViewItem.code, body.permissionGroups);
23827
23874
  result.published.push({
23828
23875
  kind: 'dataViewPermissionGroup',
@@ -23833,6 +23880,128 @@ async function publishDataViewResources(config, target, dataViews, result, optio
23833
23880
  }
23834
23881
  }
23835
23882
 
23883
+ function stagedDataViewFormReleaseDependencies(
23884
+ body,
23885
+ stagedFormBindingOverlays = new Map()
23886
+ ) {
23887
+ const overlaysByFormUuid = new Map(
23888
+ Array.from(stagedFormBindingOverlays.values())
23889
+ .map(overlay => [String(overlay?.formUuid || '').trim(), overlay])
23890
+ .filter(([formUuid]) => Boolean(formUuid))
23891
+ );
23892
+ const sources = [
23893
+ body?.definition?.base,
23894
+ ...(body?.definition?.joins || []),
23895
+ ].filter(Boolean);
23896
+ const dependencies = new Map();
23897
+ for (const source of sources) {
23898
+ const formUuid = String(source?.formUuid || '').trim();
23899
+ const staged = overlaysByFormUuid.get(formUuid);
23900
+ if (!staged) continue;
23901
+ dependencies.set(formUuid, {
23902
+ formUuid,
23903
+ releaseId: staged.releaseId,
23904
+ contentHash: staged.contentHash,
23905
+ baseRevision: staged.baseRevision,
23906
+ parentReleaseId: staged.parentReleaseId,
23907
+ });
23908
+ }
23909
+ return Array.from(dependencies.values()).sort((left, right) =>
23910
+ left.formUuid.localeCompare(right.formUuid)
23911
+ );
23912
+ }
23913
+
23914
+ function resolveDataViewSourceFormCodes(dataViews, bound) {
23915
+ const codeByFormUuid = new Map(
23916
+ Object.entries(bound.resources?.forms || {})
23917
+ .map(([formCode, resource]) => [
23918
+ String(resource?.formUuid || '').trim(),
23919
+ formCode,
23920
+ ])
23921
+ .filter(([formUuid]) => Boolean(formUuid))
23922
+ );
23923
+ const formCodes = [];
23924
+ for (const dataView of dataViews || []) {
23925
+ const definition =
23926
+ dataView?.definition !== undefined
23927
+ ? dataView.definition
23928
+ : dataView;
23929
+ const sources = [
23930
+ definition?.base,
23931
+ ...(definition?.joins || []),
23932
+ ].filter(Boolean);
23933
+ for (const source of sources) {
23934
+ const formCode = String(
23935
+ source?.formCode ||
23936
+ source?.form ||
23937
+ (source?.kind === 'form' ? source?.code : '') ||
23938
+ codeByFormUuid.get(String(source?.formUuid || '').trim()) ||
23939
+ ''
23940
+ ).trim();
23941
+ if (formCode) formCodes.push(formCode);
23942
+ }
23943
+ }
23944
+ return unique(formCodes).sort();
23945
+ }
23946
+
23947
+ async function finalizeDeferredDataViewResources(
23948
+ config,
23949
+ target,
23950
+ codes
23951
+ ) {
23952
+ if (!Array.isArray(codes) || codes.length === 0) return null;
23953
+ const selectors = codes.map(code => ({
23954
+ key: 'dataViews',
23955
+ code,
23956
+ raw: code,
23957
+ }));
23958
+ const manifest = loadWorkspaceResources({
23959
+ typeFilters: new Set(['dataViews']),
23960
+ codeFilters: selectors,
23961
+ });
23962
+ if ((manifest.unmatchedResourceCodeFilters || []).length > 0) {
23963
+ fail(
23964
+ `DATA_VIEW_FINALIZE_SOURCE_MISSING: App finalize 找不到数据视图源码: ${manifest.unmatchedResourceCodeFilters.join(', ')}`
23965
+ );
23966
+ }
23967
+ const result = {
23968
+ appType: target.appType,
23969
+ profile: target.profileName,
23970
+ published: [],
23971
+ warnings: [],
23972
+ };
23973
+ await publishDataViewResources(
23974
+ config,
23975
+ target,
23976
+ manifest.dataViews || [],
23977
+ result,
23978
+ {
23979
+ skipNoop: false,
23980
+ finalizeDeferredDataViews: true,
23981
+ }
23982
+ );
23983
+ const notActive = result.published.filter(
23984
+ item => item.kind === 'dataView' && item.status !== 'active'
23985
+ );
23986
+ if (notActive.length > 0) {
23987
+ fail(
23988
+ `DATA_VIEW_FINALIZE_INCOMPLETE: ${notActive
23989
+ .map(item => `${item.code}:${item.status || 'unknown'}`)
23990
+ .join(', ')}`
23991
+ );
23992
+ }
23993
+ return {
23994
+ requested: codes,
23995
+ finalized: result.published
23996
+ .filter(item => item.kind === 'dataView')
23997
+ .map(item => ({
23998
+ code: item.code,
23999
+ id: item.id || null,
24000
+ status: item.status,
24001
+ })),
24002
+ };
24003
+ }
24004
+
23836
24005
  async function publishStorageConfigResources(config, target, storageConfigs, result, options = {}) {
23837
24006
  for (const storageItem of storageConfigs) {
23838
24007
  const code = storageItem.code || storageItem.resourceCode;
@@ -29431,6 +29600,16 @@ function readStringFlag(flags, key) {
29431
29600
  return String(value).trim();
29432
29601
  }
29433
29602
 
29603
+ function readCommaSeparatedFlag(flags, key) {
29604
+ const value = readStringFlag(flags, key);
29605
+ return unique(
29606
+ value
29607
+ .split(',')
29608
+ .map(item => item.trim())
29609
+ .filter(Boolean)
29610
+ ).sort();
29611
+ }
29612
+
29434
29613
  function normalizeWorkspacePublishOptions(flags) {
29435
29614
  const targetForm = readStringFlag(flags, 'form');
29436
29615
  const targetPage = readStringFlag(flags, 'page');
@@ -29812,5 +29991,7 @@ module.exports = {
29812
29991
  buildScopeGrantSourceSyncDecision,
29813
29992
  main,
29814
29993
  resolveReleaseCommandScopedFiles,
29994
+ resolveDataViewSourceFormCodes,
29815
29995
  satisfiedFormCodesFromContext,
29996
+ stagedDataViewFormReleaseDependencies,
29816
29997
  };
@@ -327,6 +327,9 @@ function buildWorkspaceReleaseSteps(
327
327
  const stagesFormRelease =
328
328
  runtimeMode === 'react-spa' &&
329
329
  (targets.forms.length > 0 || formPermissionGroups.length > 0);
330
+ const deferredDataViewCodes = stagesFormRelease
331
+ ? uniqueSorted(targets.resourceSelectors?.dataViews || [])
332
+ : [];
330
333
  const directConfigurationSteps =
331
334
  buildDirectConfigurationReleaseSteps(
332
335
  targets,
@@ -437,6 +440,12 @@ function buildWorkspaceReleaseSteps(
437
440
  `.openxiangda/releases/${changeId || 'change'}/staged-resources.json`,
438
441
  ]
439
442
  : []),
443
+ ...(deferredDataViewCodes.length > 0
444
+ ? [
445
+ '--finalize-data-views',
446
+ deferredDataViewCodes.join(','),
447
+ ]
448
+ : []),
440
449
  '--wait',
441
450
  ],
442
451
  profileArg,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda",
3
- "version": "1.0.239",
3
+ "version": "1.0.240",
4
4
  "description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
5
5
  "private": false,
6
6
  "bin": {