From bd49db6589d886654bcc93e704fe55d49d0d4b54 Mon Sep 17 00:00:00 2001 From: Steve Ramage <49958178+steve-r-west@users.noreply.github.com> Date: Fri, 17 Jan 2025 16:42:41 -0800 Subject: [PATCH] Resolves #458 - Add support for Commerce Extensions (#494) --- external/resources/yaml/resources.yaml | 265 +++++++++++++++++- .../runbooks/commerce-extensions.epcc.yml | 55 ++++ external/runbooks/run-all-runbooks.sh | 7 + 3 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 external/runbooks/commerce-extensions.epcc.yml diff --git a/external/resources/yaml/resources.yaml b/external/resources/yaml/resources.yaml index a53ad0a..d061eb6 100644 --- a/external/resources/yaml/resources.yaml +++ b/external/resources/yaml/resources.yaml @@ -18,7 +18,7 @@ account-authentication-settings: auto_create_account_for_account_members: type: BOOL account_member_self_management: - type: BOOL + type: ENUM:disabled,update_only account-management-authentication-tokens: singular-name: "account-management-authentication-token" json-api-type: "account_management_authentication_token" @@ -30,7 +30,7 @@ account-management-authentication-tokens: content-type: application/json attributes: authentication_mechanism: - type: STRING + type: ENUM:oidc,password,passwordless,self_signup oauth_authorization_code: type: STRING oauth_redirect_uri: @@ -43,6 +43,12 @@ account-management-authentication-tokens: type: STRING password: type: STRING + name: + type: STRING + autofill: FUNC:Name + email: + type: STRING + autofill: FUNC:Email suppress-reset-warning: true account-members: singular-name: "account-member" @@ -1601,7 +1607,7 @@ pcm-nodes: singular-name: "pcm-node" json-api-type: "node" json-api-format: "compliant" - docs: "https://documentation.elasticpath.com/commerce-cloud/docs/api/pcm/hierarchies/nodes/get-a-hierarchy-node.html" + docs: "https://elasticpath.dev/docs/api/pxm/products/hierarchies?utm_source=elasticpath-dev&utm_medium=dev-site&utm_campaign=fy25q1-dev#characteristics-of-hierarchies-and-nodes" get-entity: docs: "https://elasticpath.dev/docs/api/pxm/products/get-hierarchy-node" url: "/pcm/hierarchies/{pcm_hierarchies}/nodes/{pcm_nodes}" @@ -1810,8 +1816,10 @@ pcm-pricebooks: attributes: name: type: STRING + autofill: FUNC:Company description: type: STRING + autofill: FUNC:Phrase pcm-product-prices: singular-name: "pcm-product-price" json-api-type: "product-price" @@ -1849,6 +1857,41 @@ pcm-product-prices: type: INT currencies.CAD.includes_tax: type: BOOL +pcm-pricebook-modifiers: + singular-name: "pcm-pricebook-modifier" + json-api-format: "compliant" + json-api-type: "price-modifier" + docs: "https://elasticpath.dev/docs/pxm/pricebooks/pxm-pricebooks-modifiers/get-a-price-modifier" + get-collection: + docs: "https://elasticpath.dev/docs/pxm/pricebooks/pxm-pricebooks-modifiers/get-all-price-modifiers" + url: "/pcm/pricebooks/{pcm_pricebooks}/modifiers/" + get-entity: + docs: "https://elasticpath.dev/docs/pxm/pricebooks/pxm-pricebooks-modifiers/get-a-price-modifier" + url: "/pcm/pricebooks/{pcm_pricebooks}/modifiers/{pcm_pricebook_modifiers}" + create-entity: + docs: "https://elasticpath.dev/docs/pxm/pricebooks/pxm-pricebooks-modifiers/create-a-price-modifier" + url: "/pcm/pricebooks/{pcm_pricebooks}/modifiers" + update-entity: + docs: "https://elasticpath.dev/docs/pxm/pricebooks/pxm-pricebooks-modifiers/update-a-price-modifier" + url: "/pcm/pricebooks/{pcm_pricebooks}/modifiers/{pcm_pricebook_modifiers}" + delete-entity: + docs: "https://elasticpath.dev/docs/pxm/pricebooks/pxm-pricebooks-modifiers/delete-a-price-modifier" + url: "/pcm/pricebooks/{pcm_pricebooks}/modifiers/{pcm_pricebook_modifiers}" + attributes: + name: + type: STRING + autofill: FUNC:BuzzWord + modifier_type: + type: ENUM:price_increment,price_decrement,price_equals + autofill: VALUE:price_equals + currencies.USD.amount: + type: INT + currencies.USD.includes_tax: + type: BOOL + ^currencies\.USD\.tiers\..+\.minimum_quantity$: + type: INT + ^currencies\.USD\.tiers\..+\.amount$: + type: INT pcm-variations: singular-name: "pcm-variation" json-api-type: "product-variation" @@ -1957,7 +2000,7 @@ personal-data-related-data-entries: resource_id: type: RESOURCE_ID:* personal-data-erasure-requests: - singular-name: "personal-data-erasure-request" + singular-name: "personal-data-erasure-request" json-api-type: "erasure_request" json-api-format: "legacy" docs: "https://documentation.elasticpath.com/commerce-cloud/docs/api/customers-and-accounts/personal-data/personal-data-erasure-requests/index.html" @@ -2539,3 +2582,217 @@ subscription-offerings: type: STRING autofill: FUNC:Name singular-name: subscription-offering +custom-apis: + singular-name: custom-api + json-api-type: custom_api + json-api-format: "legacy" + docs: "https://elasticpath.dev/docs/api/commerce-extensions/custom-ap-is" + delete-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/delete-a-custom-api" + url: "/v2/settings/extensions/custom-apis/{custom_apis}" + create-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/create-a-custom-api" + url: "/v2/settings/extensions/custom-apis/" + update-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/update-a-custom-api" + url: "/v2/settings/extensions/custom-apis/{custom_apis}" + get-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-a-custom-api" + url: "/v2/settings/extensions/custom-apis/{custom_apis}" + get-collection: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-all-custom-apis" + url: "/v2/settings/extensions/custom-apis" + attributes: + name: + type: STRING + autofill: FUNC:Company + slug: + type: STRING + api_type: + type: STRING + description: + type: STRING + autofill: FUNC:Phrase + relationships.parent_apis[n].type: + type: ENUM:api_location,custom_api + relationships.parent_apis[n].id: + type: RESOURCE_ID:custom-apis +custom-fields: + singular-name: custom-field + json-api-type: custom_field + json-api-format: "legacy" + docs: "https://elasticpath.dev/docs/api/commerce-extensions/custom-fields" + delete-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/delete-a-custom-field" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/fields/{custom_fields}" + create-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/create-a-custom-field" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/fields" + update-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/update-a-custom-field" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/fields/{custom_fields}" + get-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-a-custom-field" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/fields/{custom_fields}" + get-collection: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-all-custom-fields" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/fields/" + attributes: + name: + type: STRING + autofill: FUNC:Company + slug: + type: STRING + field_type: + type: ENUM:string,integer,boolean,float + description: + type: STRING + autofill: FUNC:Phrase + use_as_url_slug: + type: BOOL + autofill: VALUE:false + presentation.sort_order: + type: INT + validation.string.min_length: + type: INT + validation.string.max_length: + type: INT + validation.string.regex: + type: STRING + validation.string.allow_null_values: + type: BOOL + validation.string.unique: + type: ENUM:yes,no + validation.string.unique_case_insensitivity: + type: BOOL + validation.string.immutable: + type: BOOL + validation.integer.min_value: + type: INT + validation.integer.max_value: + type: INT + validation.integer.allow_null_values: + type: BOOL + validation.integer.immutable: + type: BOOL + validation.boolean.allow_null_values: + type: BOOL + validation.boolean.immutable: + type: BOOL +custom-api-settings-entries: + singular-name: custom-api-settings-entry + json-api-type: custom_entry + json-api-format: "legacy" + no-wrapping: true + docs: "https://elasticpath.dev/docs/api/commerce-extensions/custom-api-entries" + delete-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/delete-a-custom-entry" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/entries/{custom_api_settings_entries}" + create-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/create-a-custom-entry" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/entries" + update-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/update-a-custom-entry" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/entries/{custom_api_settings_entries}" + get-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-a-custom-entry" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/entries/{custom_api_settings_entries}" + get-collection: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-all-custom-entries" + url: "/v2/settings/extensions/custom-apis/{custom_apis}/entries/" + attributes: + data.type: + type: STRING + ^data\.(.+)$: + type: STRING +custom-api-extensions-entries: + singular-name: custom-api-extension-entry + json-api-type: custom_entry + json-api-format: "legacy" + no-wrapping: true + docs: "https://elasticpath.dev/docs/api/commerce-extensions/custom-api-entries" + delete-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/delete-a-custom-entry-settings" + url: "/v2/extensions/{custom_apis}/{custom_api_extensions_entries}" + parent_resource_value_overrides: + custom_apis: slug + create-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/create-a-custom-entry-settings" + url: "/v2/extensions/{custom_apis}" + # BUG: Why doesn't this work + parent_resource_value_overrides: + custom_apis: slug + update-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/put-a-custom-entry-settings" + url: "/v2/extensions/{custom_apis}/{custom_api_extensions_entries}" + parent_resource_value_overrides: + custom_apis: slug + get-entity: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-a-custom-entry-settings" + url: "/v2/extensions/{custom_apis}/{custom_api_extensions_entries}" + parent_resource_value_overrides: + custom_apis: slug + get-collection: + docs: "https://elasticpath.dev/docs/api/commerce-extensions/get-custom-entries-settings" + url: "/v2/extensions/{custom_apis}/" + parent_resource_value_overrides: + custom_apis: slug + attributes: + data.type: + type: STRING + ^data\.(.+)$: + type: STRING +built-in-roles: + singular-name: built-in-role + json-api-type: built_in_role + json-api-format: legacy + docs: "https://elasticpath.dev/docs/api/permissions/built-in-roles" + get-collection: + docs: "https://elasticpath.dev/docs/api/permissions/list-built-in-roles" + url: "/v2/permissions/built-in-roles" + get-entity: + docs: "https://elasticpath.dev/docs/api/permissions/get-a-built-in-role" + url: "/v2/permissions/built-in-roles/{built_in_roles}" +custom-api-role-policies: + singular-name: custom-api-role-policy + json-api-type: custom_api_role_policy + json-api-format: "legacy" + docs: "https://elasticpath.dev/docs/api/permissions/custom-api-role-policies" + delete-entity: + docs: "https://elasticpath.dev/docs/api/permissions/delete-a-custom-api-role-policy" + url: "/v2/permissions/custom-api-role-policies/{custom_api_role_policies}" + create-entity: + docs: "https://elasticpath.dev/docs/api/permissions/create-a-custom-api-role-policy" + url: "/v2/permissions/custom-api-role-policies/" + update-entity: + docs: "https://elasticpath.dev/docs/api/permissions/update-a-custom-api-role-policy" + url: "/v2/permissions/custom-api-role-policies/{custom_api_role_policies}" + get-entity: + docs: "https://elasticpath.dev/docs/api/permissions/get-a-custom-api-role-policy" + url: "/v2/permissions/custom-api-role-policies/{custom_api_role_policies}" + get-collection: + docs: "https://elasticpath.dev/docs/api/permissions/list-custom-api-role-policies" + url: "/v2/permissions/custom-api-role-policies" + attributes: + create: + type: BOOL + list: + type: BOOL + read: + type: BOOL + update: + type: BOOL + delete: + type: BOOL + relationships.custom_api.data.type: + type: ENUM:custom_api + relationships.custom_api.data.id: + type: RESOURCE_ID:custom-apis + relationships.role.data.type: + type: ENUM:built_in_role + relationships.role.data.id: + type: RESOURCE_ID:built-in-role + + + + diff --git a/external/runbooks/commerce-extensions.epcc.yml b/external/runbooks/commerce-extensions.epcc.yml new file mode 100644 index 0000000..2f635a7 --- /dev/null +++ b/external/runbooks/commerce-extensions.epcc.yml @@ -0,0 +1,55 @@ +name: "commerce-extensions" +description: + long: "Examples for using Commerce Extensions" + short: "Examples for using Commerce Extensions" +actions: + create-product-review-custom-api: + description: + short: "Create a sample API that can be used for product reviews" + commands: + # Populate aliases + - epcc get built-in-roles -s + - epcc create -s custom-api name "Product Reviews" slug "product-reviews" description "Stores reviews for products" api_type "product_review_ext" + - | + epcc create -s custom-field name=Product_Reviews field_type string name "Title" slug "title" validation.string.min_length 1 validation.string.max_length 100 description "Title" validation.string.allow_null_values false + epcc create -s custom-field name=Product_Reviews field_type string name "Review" slug "review" validation.string.min_length 1 validation.string.max_length 4000 description "Review" validation.string.allow_null_values false + epcc create -s custom-field name=Product_Reviews field_type string name "Product ID" slug "product_id" validation.string.regex "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" description "Product" validation.string.allow_null_values false + epcc create -s custom-field name=Product_Reviews field_type integer name "Rating" slug "rating" validation.integer.min_value 0 validation.integer.max_value 100 description "Rating" validation.integer.allow_null_values false + - | + epcc create custom-api-role-policy -s relationships.custom_api.data.id name=Product_Reviews relationships.role.data.id name=Registered_Shopper list true read true create true update false delete false relationships.custom_api.data.type custom_api relationships.role.data.type built_in_role + epcc create custom-api-role-policy -s relationships.custom_api.data.id name=Product_Reviews relationships.role.data.id name=Guest_Shopper list true read true create false update false delete false relationships.custom_api.data.type custom_api relationships.role.data.type built_in_role + epcc create custom-api-role-policy -s relationships.custom_api.data.id name=Product_Reviews relationships.role.data.id name=eCommerce_Admin list true read true create false update false delete true relationships.custom_api.data.type custom_api relationships.role.data.type built_in_role + epcc create custom-api-role-policy -s relationships.custom_api.data.id name=Product_Reviews relationships.role.data.id name=Promotions_Manager list true read true create false update false delete false relationships.custom_api.data.type custom_api relationships.role.data.type built_in_role + epcc create custom-api-role-policy -s relationships.custom_api.data.id name=Product_Reviews relationships.role.data.id name=Support list true read true create false update true delete true relationships.custom_api.data.type custom_api relationships.role.data.type built_in_role + # Aliases don't work with / for the moment sadly + # epcc create custom-api-role-policy -s relationships.custom_api.data.id name=Product_Reviews relationships.role.data.id "name=IT/Developer" list true read true create false update false delete false relationships.custom_api.data.type custom_api relationships.role.data.type built_in_role + # epcc create custom-api-role-policy -s relationships.custom_api.data.id name=Product_Reviews relationships.role.data.id "name=Marketing/Sales" list true read true create false update false delete true relationships.custom_api.data.type custom_api relationships.role.data.type built_in_role + create-review-for-random-product: + description: + short: "Create a review for a randomly generated product id" + variables: + title: + type: STRING + default: "Great product!" + description: + short: "The title of the review" + review: + type: STRING + default: "I love this product!" + description: + short: "The review" + + rating: + type: INT + default: 80 + description: + short: "The rating" + commands: + - epcc create custom-api-extension-entry product-reviews data.type product_review_ext data.title "{{ .title }}" data.review "{{ .review }}" data.rating {{ .rating }} data.product_id {{ uuidv4 }} + + + delete-product-review-custom-api: + description: + short: "Delete the sample API that can be used for product reviews" + commands: + - epcc delete custom-api name=Product_Reviews --if-alias-exists name=Product_Reviews diff --git a/external/runbooks/run-all-runbooks.sh b/external/runbooks/run-all-runbooks.sh index 120966d..8852fed 100755 --- a/external/runbooks/run-all-runbooks.sh +++ b/external/runbooks/run-all-runbooks.sh @@ -13,6 +13,13 @@ set -x #Let's test that epcc command works after an embarrassing bug that caused it to panic :( epcc +echo "Starting Commerce Extensions Runbook" +epcc reset-store .+ + +epcc runbooks run commerce-extensions create-product-review-custom-api +epcc runbooks run commerce-extensions create-review-for-random-product +epcc runbooks run commerce-extensions delete-product-review-custom-api + echo "Starting Subscriptions Tests" epcc reset-store .+ epcc runbooks run subscriptions create-subscription-plans