Skip to content

Commit c3965d3

Browse files
authored
Support Rule Promotions and resource creation/updates via raw JSON inputs. (#525)
1 parent c8b1d75 commit c3965d3

File tree

8 files changed

+133
-52
lines changed

8 files changed

+133
-52
lines changed

cmd/create.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
gojson "encoding/json"
66
"fmt"
7+
"strings"
8+
79
"github.com/elasticpath/epcc-cli/external/aliases"
810
"github.com/elasticpath/epcc-cli/external/completion"
911
"github.com/elasticpath/epcc-cli/external/httpclient"
@@ -12,7 +14,6 @@ import (
1214
"github.com/elasticpath/epcc-cli/external/rest"
1315
log "github.com/sirupsen/logrus"
1416
"github.com/spf13/cobra"
15-
"strings"
1617
)
1718

1819
func NewCreateCommand(parentCmd *cobra.Command) func() {
@@ -49,6 +50,7 @@ func NewCreateCommand(parentCmd *cobra.Command) func() {
4950
var logOnSuccess = ""
5051
var logOnFailure = ""
5152
var disableConstants = false
53+
var data = ""
5254

5355
resetFunc := func() {
5456
autoFillOnCreate = false
@@ -67,6 +69,7 @@ func NewCreateCommand(parentCmd *cobra.Command) func() {
6769
logOnSuccess = ""
6870
logOnFailure = ""
6971
disableConstants = false
72+
data = ""
7073
}
7174

7275
for _, resource := range resources.GetPluralResources() {
@@ -106,7 +109,7 @@ func NewCreateCommand(parentCmd *cobra.Command) func() {
106109
}
107110
}
108111

109-
body, err := rest.CreateInternal(context.Background(), overrides, append([]string{resourceName}, args...), autoFillOnCreate, setAlias, skipAliases, disableConstants)
112+
body, err := rest.CreateInternal(context.Background(), overrides, append([]string{resourceName}, args...), autoFillOnCreate, setAlias, skipAliases, disableConstants, data)
110113

111114
if err != nil {
112115
return err
@@ -149,7 +152,6 @@ func NewCreateCommand(parentCmd *cobra.Command) func() {
149152

150153
return json.PrintJson(body)
151154
}
152-
153155
}
154156

155157
res := repeater(c, repeat, repeatDelay, cmd, args, ignoreErrors)
@@ -252,6 +254,7 @@ func NewCreateCommand(parentCmd *cobra.Command) func() {
252254
createCmd.PersistentFlags().BoolVarP(&disableConstants, "no-auto-constants", "", false, "Disable setting of known constant values in the request body")
253255
createCmd.PersistentFlags().StringVarP(&logOnSuccess, "log-on-success", "", "", "Output the following message as an info if the result is successful")
254256
createCmd.PersistentFlags().StringVarP(&logOnFailure, "log-on-failure", "", "", "Output the following message as an error if the result fails")
257+
createCmd.PersistentFlags().StringVarP(&data, "data", "d", "", "Raw JSON data to use as the request body. If provided, positional arguments will be ignored.")
255258

256259
_ = createCmd.RegisterFlagCompletionFunc("output-jq", jqCompletionFunc)
257260

cmd/login.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import (
44
"context"
55
gojson "encoding/json"
66
"fmt"
7+
"net/url"
8+
"time"
9+
710
"github.com/elasticpath/epcc-cli/config"
811
"github.com/elasticpath/epcc-cli/external/aliases"
912
"github.com/elasticpath/epcc-cli/external/authentication"
@@ -17,8 +20,6 @@ import (
1720
"github.com/elasticpath/epcc-cli/external/rest"
1821
log "github.com/sirupsen/logrus"
1922
"github.com/spf13/cobra"
20-
"net/url"
21-
"time"
2223
)
2324

2425
const (
@@ -301,7 +302,7 @@ var loginCustomer = &cobra.Command{
301302
newArgs = append(newArgs, "customer-token")
302303
newArgs = append(newArgs, args...)
303304

304-
body, err := rest.CreateInternal(ctx, overrides, newArgs, false, "", false, false)
305+
body, err := rest.CreateInternal(ctx, overrides, newArgs, false, "", false, false, "")
305306

306307
if err != nil {
307308
log.Warnf("Login not completed successfully")
@@ -511,7 +512,7 @@ var loginAccountManagement = &cobra.Command{
511512
}
512513

513514
// Do the login and get back a list of accounts
514-
body, err := rest.CreateInternal(ctx, overrides, loginArgs, false, "", false, false)
515+
body, err := rest.CreateInternal(ctx, overrides, append([]string{"account-management-authentication-token"}, args...), false, "", false, false, "")
515516

516517
if err != nil {
517518
log.Warnf("Login not completed successfully")

cmd/reset-store.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import (
44
"context"
55
gojson "encoding/json"
66
"fmt"
7+
"io"
8+
"net/url"
9+
"regexp"
10+
"sort"
11+
"strings"
12+
713
"github.com/elasticpath/epcc-cli/external/aliases"
814
"github.com/elasticpath/epcc-cli/external/authentication"
915
"github.com/elasticpath/epcc-cli/external/httpclient"
@@ -12,11 +18,6 @@ import (
1218
"github.com/elasticpath/epcc-cli/external/rest"
1319
log "github.com/sirupsen/logrus"
1420
"github.com/spf13/cobra"
15-
"io"
16-
"net/url"
17-
"regexp"
18-
"sort"
19-
"strings"
2021
)
2122

2223
var DeleteApplicationKeys = true
@@ -201,7 +202,7 @@ func resetResourcesUndeletableResources(ctx context.Context, overrides *httpclie
201202
errors := make([]string, 0)
202203

203204
for _, resetCmd := range resetCmds {
204-
body, err := rest.UpdateInternal(ctx, overrides, false, false, resetCmd)
205+
body, err := rest.UpdateInternal(ctx, overrides, false, false, resetCmd, "")
205206

206207
if err != nil {
207208
errors = append(errors, fmt.Errorf("error resetting %s: %v", resetCmd[0], err).Error())

cmd/update.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
gojson "encoding/json"
66
"fmt"
7+
78
"github.com/elasticpath/epcc-cli/external/aliases"
89
"github.com/elasticpath/epcc-cli/external/completion"
910
"github.com/elasticpath/epcc-cli/external/httpclient"
@@ -33,6 +34,7 @@ func NewUpdateCommand(parentCmd *cobra.Command) func() {
3334
var logOnSuccess = ""
3435
var logOnFailure = ""
3536
var disableConstants = false
37+
var data = ""
3638

3739
resetFunc := func() {
3840
overrides.QueryParameters = nil
@@ -49,6 +51,7 @@ func NewUpdateCommand(parentCmd *cobra.Command) func() {
4951
logOnSuccess = ""
5052
logOnFailure = ""
5153
disableConstants = false
54+
data = ""
5255
}
5356

5457
var updateCmd = &cobra.Command{
@@ -98,7 +101,7 @@ func NewUpdateCommand(parentCmd *cobra.Command) func() {
98101
}
99102
}
100103

101-
body, err := rest.UpdateInternal(context.Background(), overrides, skipAliases, disableConstants, append([]string{resourceName}, args...))
104+
body, err := rest.UpdateInternal(context.Background(), overrides, skipAliases, disableConstants, append([]string{resourceName}, args...), data)
102105

103106
if err != nil {
104107
return err
@@ -226,6 +229,7 @@ func NewUpdateCommand(parentCmd *cobra.Command) func() {
226229
updateCmd.PersistentFlags().BoolVarP(&disableConstants, "no-auto-constants", "", false, "Disable setting of known constant values in the request body (e.g., `type`)")
227230
updateCmd.PersistentFlags().StringVarP(&logOnSuccess, "log-on-success", "", "", "Output the following message as an info if the result is successful")
228231
updateCmd.PersistentFlags().StringVarP(&logOnFailure, "log-on-failure", "", "", "Output the following message as an error if the result fails")
232+
updateCmd.PersistentFlags().StringVarP(&data, "data", "d", "", "Raw JSON data to use as the request body. If provided, positional arguments will be ignored.")
229233

230234
parentCmd.AddCommand(updateCmd)
231235

external/oidc/callback.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import (
55
"encoding/base64"
66
gojson "encoding/json"
77
"fmt"
8+
"net/http"
9+
810
"github.com/elasticpath/epcc-cli/external/authentication"
911
"github.com/elasticpath/epcc-cli/external/httpclient"
1012
"github.com/elasticpath/epcc-cli/external/rest"
11-
"net/http"
1213
)
1314

1415
type CallbackPageInfo struct {
@@ -66,12 +67,12 @@ func GetCallbackData(ctx context.Context, port uint16, r *http.Request) (*Callba
6667
}
6768

6869
if login_type.Value == "AM" {
69-
result, err := rest.CreateInternal(context.Background(), &httpclient.HttpParameterOverrides{}, []string{"account-management-authentication-token",
70+
result, err := rest.CreateInternal(ctx, &httpclient.HttpParameterOverrides{}, append([]string{"account-management-authentication-token"},
7071
"authentication_mechanism", "oidc",
7172
"oauth_authorization_code", data["code"],
7273
"oauth_redirect_uri", fmt.Sprintf("http://localhost:%d/callback", port),
7374
"oauth_code_verifier", verifier.Value,
74-
}, false, "", true, false)
75+
), false, "", true, false, "")
7576

7677
if err != nil {
7778
return nil, fmt.Errorf("could not get account tokens: %w", err)
@@ -96,12 +97,12 @@ func GetCallbackData(ctx context.Context, port uint16, r *http.Request) (*Callba
9697

9798
return &cpi, nil
9899
} else if login_type.Value == "Customers" {
99-
result, err := rest.CreateInternal(context.Background(), &httpclient.HttpParameterOverrides{}, []string{"customer-token",
100+
result, err := rest.CreateInternal(ctx, &httpclient.HttpParameterOverrides{}, append([]string{"customer-token"},
100101
"authentication_mechanism", "oidc",
101102
"oauth_authorization_code", data["code"],
102103
"oauth_redirect_uri", fmt.Sprintf("http://localhost:%d/callback", port),
103104
"oauth_code_verifier", verifier.Value,
104-
}, false, "", true, false)
105+
), false, "", true, false, "")
105106

106107
if err != nil {
107108
return nil, fmt.Errorf("could not get customer tokens: %w", err)

external/resources/yaml/resources.yaml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2907,5 +2907,66 @@ mli-inventory-list-stocks:
29072907
type: CONST:stock
29082908
data[n].id:
29092909
type: RESOURCE_ID:pcm-products
2910+
rule-promotions:
2911+
singular-name: "rule-promotion"
2912+
json-api-type: "rule_promotion"
2913+
json-api-format: "compliant"
2914+
docs: "https://elasticpath.dev/docs/promotions-builder/overview"
2915+
get-collection:
2916+
docs: "https://elasticpath.dev/docs/api/promotions-builder/get-rule-promotions"
2917+
url: "/v2/rule-promotions"
2918+
get-entity:
2919+
docs: "https://elasticpath.dev/docs/api/promotions-builder/get-rule-promotion-by-id"
2920+
url: "/v2/rule-promotions/{rule_promotions}"
2921+
create-entity:
2922+
docs: "https://elasticpath.dev/docs/api/promotions-builder/create-rule-promotion"
2923+
url: "/v2/rule-promotions"
2924+
update-entity:
2925+
docs: "https://elasticpath.dev/docs/api/promotions-builder/update-rule-promotion"
2926+
url: "/v2/rule-promotions/{rule_promotions}"
2927+
delete-entity:
2928+
docs: "https://elasticpath.dev/docs/api/promotions-builder/delete-rule-promotion"
2929+
url: "/v2/rule-promotions/{rule_promotions}"
2930+
attributes:
2931+
name:
2932+
type: STRING
2933+
description:
2934+
type: STRING
2935+
enabled:
2936+
type: BOOL
2937+
automatic:
2938+
type: BOOL
2939+
priority:
2940+
type: INT
2941+
stackable:
2942+
type: BOOL
2943+
start:
2944+
type: STRING
2945+
end:
2946+
type: STRING
2947+
rule_set.rules.strategy:
2948+
type: STRING
2949+
rule_set.rules.operator:
2950+
type: STRING
2951+
rule_set.rules.args[n]:
2952+
type: STRING
2953+
rule_set.rules.children[n].strategy:
2954+
type: STRING
2955+
rule_set.rules.children[n].operator:
2956+
type: STRING
2957+
rule_set.rules.children[n].args[n]:
2958+
type: STRING
2959+
rule_set.actions[n].strategy:
2960+
type: STRING
2961+
rule_set.actions[n].args[n]:
2962+
type: STRING
2963+
rule_set.actions[n].condition.strategy:
2964+
type: STRING
2965+
rule_set.actions[n].condition.operator:
2966+
type: STRING
2967+
rule_set.actions[n].condition.args[n]:
2968+
type: STRING
2969+
rule_set.actions[n].limitations.max_quantity:
2970+
type: INT
29102971

29112972

external/rest/create.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ package rest
33
import (
44
"context"
55
"fmt"
6+
"io"
7+
"net/http"
8+
"net/url"
9+
"strings"
10+
611
"github.com/elasticpath/epcc-cli/external/aliases"
712
"github.com/elasticpath/epcc-cli/external/autofill"
813
"github.com/elasticpath/epcc-cli/external/encoding"
@@ -11,13 +16,9 @@ import (
1116
"github.com/elasticpath/epcc-cli/external/resources"
1217
"github.com/elasticpath/epcc-cli/external/shutdown"
1318
log "github.com/sirupsen/logrus"
14-
"io"
15-
"net/http"
16-
"net/url"
17-
"strings"
1819
)
1920

20-
func CreateInternal(ctx context.Context, overrides *httpclient.HttpParameterOverrides, args []string, autoFillOnCreate bool, aliasName string, skipAliases bool, disableConstants bool) (string, error) {
21+
func CreateInternal(ctx context.Context, overrides *httpclient.HttpParameterOverrides, args []string, autoFillOnCreate bool, aliasName string, skipAliases bool, disableConstants bool, data string) (string, error) {
2122
shutdown.OutstandingOpCounter.Add(1)
2223
defer shutdown.OutstandingOpCounter.Done()
2324

@@ -56,7 +57,6 @@ func CreateInternal(ctx context.Context, overrides *httpclient.HttpParameterOver
5657
var resBody []byte
5758

5859
if resource.CreateEntityInfo.ContentType == "multipart/form-data" {
59-
6060
byteBuf, contentType, err := encoding.ToMultiPartEncoding(args[(idCount+1):], resource.NoWrapping, resource.JsonApiFormat == "complaint", resource.Attributes)
6161
if err != nil {
6262
return "", err
@@ -78,28 +78,32 @@ func CreateInternal(ctx context.Context, overrides *httpclient.HttpParameterOver
7878
params.Add(keyAndValue[0], keyAndValue[1])
7979
}
8080

81-
if !resource.NoWrapping && !disableConstants {
82-
args = append(args, "type", resource.JsonApiType)
83-
}
81+
var body string
82+
var err error
8483

85-
// Create the body from remaining args
86-
87-
jsonArgs := args[(idCount + 1):]
88-
if autoFillOnCreate {
89-
autofilledData := autofill.GetJsonArrayForResource(&resource)
90-
91-
jsonArgs = append(autofilledData, jsonArgs...)
92-
}
84+
if data != "" {
85+
// Use the provided data as the request body
86+
body = data
87+
} else {
88+
if !resource.NoWrapping && !disableConstants {
89+
args = append(args, "type", resource.JsonApiType)
90+
}
9391

94-
body, err := json.ToJson(jsonArgs, resource.NoWrapping, resource.JsonApiFormat == "compliant", resource.Attributes, true, !disableConstants)
92+
// Create the body from remaining args
93+
jsonArgs := args[(idCount + 1):]
94+
if autoFillOnCreate {
95+
autofilledData := autofill.GetJsonArrayForResource(&resource)
96+
jsonArgs = append(autofilledData, jsonArgs...)
97+
}
9598

96-
if err != nil {
97-
return "", err
99+
body, err = json.ToJson(jsonArgs, resource.NoWrapping, resource.JsonApiFormat == "compliant", resource.Attributes, true, !disableConstants)
100+
if err != nil {
101+
return "", err
102+
}
98103
}
99104

100105
// Submit request
101106
resp, err = httpclient.DoRequest(ctx, "POST", resourceURL, params.Encode(), strings.NewReader(body))
102-
103107
}
104108

105109
if err != nil {
@@ -138,5 +142,4 @@ func CreateInternal(ctx context.Context, overrides *httpclient.HttpParameterOver
138142
} else {
139143
return "", nil
140144
}
141-
142145
}

0 commit comments

Comments
 (0)