openxiangda 1.0.228 → 1.0.229

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.
@@ -17,8 +17,21 @@ const SIDE_EFFECT_POLICY_FIELDS = new Set([
17
17
  'environmentBanner',
18
18
  'externalDingTalkDepartmentRootId',
19
19
  ]);
20
- const CANDIDATE_STATE_HASH_POLICY =
20
+ const CANDIDATE_STATE_HASH_POLICY_V1 =
21
21
  'openxiangda-state-without-runtime-promotion-v1';
22
+ const CANDIDATE_STATE_HASH_POLICY =
23
+ 'openxiangda-state-stable-managed-bindings-v2';
24
+ const CANDIDATE_STATE_HASH_POLICIES = new Set([
25
+ CANDIDATE_STATE_HASH_POLICY_V1,
26
+ CANDIDATE_STATE_HASH_POLICY,
27
+ ]);
28
+ const CANDIDATE_RESOURCE_OBSERVATION_FIELDS = new Set([
29
+ 'createdAt',
30
+ 'updatedAt',
31
+ 'syncedAt',
32
+ 'schemaSyncedAt',
33
+ 'bundlePublishedAt',
34
+ ]);
22
35
 
23
36
  function canonicalJson(value) {
24
37
  if (Array.isArray(value)) {
@@ -611,7 +624,7 @@ function hashCandidateWorkspaceFile(cwd, relativePath, options = {}) {
611
624
  ? options.hashPolicy
612
625
  : candidateFileHashPolicy(normalized);
613
626
  if (!hashPolicy) return hashWorkspaceFile(cwd, normalized);
614
- if (hashPolicy !== CANDIDATE_STATE_HASH_POLICY) {
627
+ if (!CANDIDATE_STATE_HASH_POLICIES.has(hashPolicy)) {
615
628
  const error = new Error(
616
629
  `不支持的 candidate 文件哈希策略: ${hashPolicy}`
617
630
  );
@@ -636,7 +649,10 @@ function hashCandidateWorkspaceFile(cwd, relativePath, options = {}) {
636
649
  invalid.code = 'CANDIDATE_STATE_INPUT_INVALID';
637
650
  throw invalid;
638
651
  }
639
- const normalizedState = normalizeCandidateProjectStateForHash(state);
652
+ const normalizedState = normalizeCandidateProjectStateForHash(
653
+ state,
654
+ hashPolicy
655
+ );
640
656
  const buffer = Buffer.from(canonicalJson(normalizedState), 'utf8');
641
657
  return {
642
658
  path: normalized,
@@ -647,7 +663,7 @@ function hashCandidateWorkspaceFile(cwd, relativePath, options = {}) {
647
663
  };
648
664
  }
649
665
 
650
- function normalizeCandidateProjectStateForHash(input) {
666
+ function normalizeCandidateProjectStateForHash(input, hashPolicy) {
651
667
  const state = cloneJsonValue(input);
652
668
  if (!state || typeof state !== 'object' || Array.isArray(state)) {
653
669
  const error = new Error(
@@ -674,6 +690,18 @@ function normalizeCandidateProjectStateForHash(input) {
674
690
  // that caused the release, while all durable binding fields remain hashed.
675
691
  delete binding.promotion;
676
692
  delete binding.updatedAt;
693
+ if (
694
+ collectionName === 'targets' &&
695
+ hashPolicy === CANDIDATE_STATE_HASH_POLICY
696
+ ) {
697
+ // Managed release stages persist discovered/created resource IDs and
698
+ // the activated runtime head as their durable local execution result.
699
+ // The sealed environmentBindings manifest independently protects every
700
+ // resource identity that existed before sealing, while intentionally
701
+ // allowing additive bindings created by the candidate itself.
702
+ delete binding.resources;
703
+ delete binding.runtime;
704
+ }
677
705
  }
678
706
  }
679
707
  return state;
@@ -686,7 +714,7 @@ function normalizeCandidateResourceBindings(value) {
686
714
  if (!value || typeof value !== 'object') return value;
687
715
  return Object.fromEntries(
688
716
  Object.entries(value)
689
- .filter(([key]) => !['createdAt', 'updatedAt', 'syncedAt'].includes(key))
717
+ .filter(([key]) => !CANDIDATE_RESOURCE_OBSERVATION_FIELDS.has(key))
690
718
  .sort(([left], [right]) => left.localeCompare(right))
691
719
  .map(([key, item]) => [
692
720
  key,
@@ -901,7 +929,7 @@ function inspectCandidateBundleFiles(candidate, cwd = process.cwd()) {
901
929
  }
902
930
  seen.add(file);
903
931
  const hashPolicy = expected.hashPolicy || null;
904
- if (hashPolicy && hashPolicy !== CANDIDATE_STATE_HASH_POLICY) {
932
+ if (hashPolicy && !CANDIDATE_STATE_HASH_POLICIES.has(hashPolicy)) {
905
933
  mismatches.push({
906
934
  path: file,
907
935
  reason: 'unsupported-hash-policy',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda",
3
- "version": "1.0.228",
3
+ "version": "1.0.229",
4
4
  "description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
5
5
  "private": false,
6
6
  "bin": {