@@ -5,15 +5,14 @@ import (
55 "bytes"
66 "encoding/base64"
77 "encoding/json"
8- "errors"
98 "fmt"
109 "log"
1110 "os"
1211 "os/exec"
1312 "path/filepath"
14- "regexp"
1513 "runtime"
1614 "strconv"
15+ "strings"
1716 "testing"
1817
1918 "github.com/pelletier/go-toml/v2"
@@ -28,12 +27,18 @@ type ObjectChange struct {
2827 Sender string `json:"sender,omitempty"`
2928 Owner Owner `json:"owner,omitempty"`
3029 ObjectType string `json:"objectType,omitempty"`
30+ ObjectTypeSnake string `json:"object_type,omitempty"`
3131 ObjectID string `json:"objectId,omitempty"`
32+ ObjectIDSnake string `json:"object_id,omitempty"`
3233 Version string `json:"version,omitempty"`
3334 PreviousVersion string `json:"previousVersion,omitempty"`
3435 Digest string `json:"digest,omitempty"`
3536 PackageID string `json:"packageId,omitempty"` // Only in type == "published"
36- Modules []string `json:"modules,omitempty"` // Only in type == "published"
37+ OutputState string `json:"outputState,omitempty"`
38+ OutputStateAlt string `json:"output_state,omitempty"`
39+ IDOperation string `json:"idOperation,omitempty"`
40+ IDOperationAlt string `json:"id_operation,omitempty"`
41+ Modules []string `json:"modules,omitempty"` // Only in type == "published"
3742}
3843
3944type Owner struct {
@@ -47,7 +52,40 @@ type SharedOwner struct {
4752}
4853
4954type TxnMetaWithObjectChanges struct {
50- ObjectChanges []ObjectChange `json:"objectChanges"`
55+ ObjectChanges []ObjectChange `json:"objectChanges"`
56+ ObjectChangesSnake []ObjectChange `json:"object_changes"`
57+ ChangedObjects []ObjectChange `json:"changed_objects"`
58+ ChangedObjectsCamel []ObjectChange `json:"changedObjects"`
59+ }
60+
61+ func normalizeObjectChanges (changes []ObjectChange ) []ObjectChange {
62+ for i := range changes {
63+ if changes [i ].ObjectID == "" {
64+ changes [i ].ObjectID = changes [i ].ObjectIDSnake
65+ }
66+ if changes [i ].ObjectType == "" {
67+ changes [i ].ObjectType = changes [i ].ObjectTypeSnake
68+ }
69+ if changes [i ].OutputState == "" {
70+ changes [i ].OutputState = changes [i ].OutputStateAlt
71+ }
72+ if changes [i ].IDOperation == "" {
73+ changes [i ].IDOperation = changes [i ].IDOperationAlt
74+ }
75+
76+ // Newer Sui JSON uses object-level metadata rather than "type":"published/created".
77+ if changes [i ].Type == "" {
78+ if changes [i ].ObjectType == "package" || changes [i ].OutputState == "OUTPUT_OBJECT_STATE_PACKAGE_WRITE" {
79+ changes [i ].Type = "published"
80+ if changes [i ].PackageID == "" {
81+ changes [i ].PackageID = changes [i ].ObjectID
82+ }
83+ } else if strings .EqualFold (changes [i ].IDOperation , "CREATED" ) {
84+ changes [i ].Type = "created"
85+ }
86+ }
87+ }
88+ return changes
5189}
5290
5391func BuildSetup (t * testing.T , packagePath string ) string {
@@ -69,14 +107,13 @@ func BuildSetup(t *testing.T, packagePath string) string {
69107 return contractPath
70108}
71109
72- func findDigestIndex ( input string ) (int , error ) {
73- digestRegex := regexp . MustCompile ( `"digest":\s*"[A-Za-z0-9]+"` )
74- loc := digestRegex . FindStringIndex ( input )
75- if loc == nil {
76- return - 1 , errors . New ( "digest not found" )
110+ func extractJSONOutput ( output string ) (string , error ) {
111+ start := strings . Index ( output , "{" )
112+ end := strings . LastIndex ( output , "}" )
113+ if start == - 1 || end == - 1 || end < start {
114+ return "" , fmt . Errorf ( "json output not found" )
77115 }
78-
79- return loc [0 ], nil
116+ return output [start : end + 1 ], nil
80117}
81118
82119func BuildContract (t * testing.T , contractPath string ) {
@@ -172,26 +209,39 @@ func PublishContract(t *testing.T, packageName string, contractPath string, acco
172209 publishOutput , err := publishCmd .CombinedOutput ()
173210 require .NoError (t , err , "Failed to publish contract: %s" , string (publishOutput ))
174211
175- // This is a hack to skip the warnings from the CLI output by searching for "digest" with regex
176- // and then extracting the JSON from there.
177- idx , err := findDigestIndex (string (publishOutput ))
212+ cleanedOutput , err := extractJSONOutput (string (publishOutput ))
178213 require .NoError (t , err )
179- cleanedOutput := "{" + string (publishOutput )[idx :]
180214
181215 // Unmarshal the JSON into a map.
182216 var parsedPublishTxn TxnMetaWithObjectChanges
183- if err := json .Unmarshal ([]byte (cleanedOutput ), & parsedPublishTxn ); err != nil {
184- log .Fatalf ("failed to unmarshal JSON: %v" , err )
217+ err = json .Unmarshal ([]byte (cleanedOutput ), & parsedPublishTxn )
218+ require .NoError (t , err , "Failed to parse publish output: %s" , cleanedOutput )
219+
220+ if len (parsedPublishTxn .ObjectChanges ) == 0 && len (parsedPublishTxn .ObjectChangesSnake ) > 0 {
221+ parsedPublishTxn .ObjectChanges = parsedPublishTxn .ObjectChangesSnake
222+ }
223+ if len (parsedPublishTxn .ObjectChanges ) == 0 && len (parsedPublishTxn .ChangedObjects ) > 0 {
224+ parsedPublishTxn .ObjectChanges = parsedPublishTxn .ChangedObjects
185225 }
226+ if len (parsedPublishTxn .ObjectChanges ) == 0 && len (parsedPublishTxn .ChangedObjectsCamel ) > 0 {
227+ parsedPublishTxn .ObjectChanges = parsedPublishTxn .ChangedObjectsCamel
228+ }
229+ parsedPublishTxn .ObjectChanges = normalizeObjectChanges (parsedPublishTxn .ObjectChanges )
186230
187231 changes := parsedPublishTxn .ObjectChanges
188232
189233 var packageId string
190234 for _ , change := range changes {
191- if change .Type == "published" {
235+ if change .Type == "published" && change . PackageID != "" {
192236 packageId = change .PackageID
193237 break
194238 }
239+
240+ // Newer Sui output can represent package publish as objectType=package.
241+ if (change .ObjectType == "package" || change .OutputState == "OUTPUT_OBJECT_STATE_PACKAGE_WRITE" ) && change .ObjectID != "" {
242+ packageId = change .ObjectID
243+ break
244+ }
195245 }
196246 require .NotEmpty (t , packageId , "Package ID not found" )
197247
0 commit comments