Skip to content

@W-17701711@ Generate isomorphic SDK from OAS#194

Merged
vcua-mobify merged 31 commits intofeature/oasfrom
oas-support
Jun 3, 2025
Merged

@W-17701711@ Generate isomorphic SDK from OAS#194
vcua-mobify merged 31 commits intofeature/oasfrom
oas-support

Conversation

@vcua-mobify
Copy link
Contributor

@vcua-mobify vcua-mobify commented May 23, 2025

THIS PR CONTAINS BREAKING CHANGES

This PR updates commerce-sdk-isomorphic so that it generates from OAS spec files rather than RAML files.

This requires the changes from SalesforceCommerceCloud/raml-toolkit#228 to work

Testing the changes:

  1. Check out both this PR and the raml-toolkit pr
    Build raml-toolkit: npm install && npm run build

  2. In commerce-sdk-isomorphic's package.json, ensure the dependency to raml-toolkit is pointed to your local raml-toolkit.
    Run yarn ci to install dependencies and include the local raml-toolkit

  3. Set some env vars for the anypoint exchange credentials
    export ANYPOINT_USERNAME="<insert_username_here>"
    export ANYPOINT_PASSWORD="<insert_password_here>"

  4. Download the OAS files from anypoint exchange and run diff check. You currently need to run this twice; the 1st run will compare the current contents of the apis dir (which contain raml files) with the newly downloaded oas files. The 2nd run onwards will compare only oas files (the files you downloaded from the 1st run with the files you downloaded from the 2nd run)
    yarn updateApis

  5. yarn renderTemplates will call raml-toolkit to run openapi-generator. The files it generates will be outputted under src/lib

  6. Currently the generated files have a naming conflict for ShopperContext. Current workaround is to manually rename the ShopperContext class to ShopperContexts and update the corresponding entry in src/lib/index.ts

  7. Bundle the generated files with yarn build:lib

  8. Run tests with yarn test

TODO - will be done in a follow up PR:
* Identify why the bundled package is 1 mb (double the previous size of 565 kb). Once resolved, bump down the threshold for bundle size in package.json

  • UPDATE: Only the .ts files have doubled in size. The minified .js files are roughly the same size so we might be ok with this.
  • Fix issues in the generated code
  • Major version bump

Out of Scope
The test app / yarn start as it seems to have been broken for a while

@vcua-mobify vcua-mobify changed the base branch from main to feature/oas May 27, 2025 16:36
'shopper-baskets',
'shopper-context',
'shopper-customers',
'shopper-discovery-search',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is shopper-discovery-search no longer needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, according to Kay, both shopper-discovery-search and slas-shopper-login-uap artifact are out of scope for the OAS work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we are not using these in PWA?

}

export function main(): void {
console.log('Starting OAS generation script');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you separate this (until line #120 )into its own function - loadApiDirectories

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything from line 116 to 141 is inside the callback function passed into fs.readdir
Outside of that, there isn't much; just a ternary for determining the API directory and 2 lines for copying the static directory. I can separate out the static file bits.

fs.ensureDirSync(PRODUCTION_API_PATH);

API_LIST.forEach(name => {
// TODO: come up with a way to set isOAS other than using the name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we really want to maintain code for OAS and RAML then create a new file for OAS - updateOpenApis.ts. But I feel if we are getting rid RAML completely then default to OAS.

Question- Does the generated SDK from OAS has same interface has the RAML?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to have the same interface from a glance but I have not done a deep dive yet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isOAS seems unnecessary as we only support OAS in the SDK. Can we default to true while calling the raml-toolkit?

scripts/utils.ts Outdated
name: string,
rootPath: string
rootPath: string,
isOAS = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here. Do we really need this if OAS is the only spec

const privateClient = !!credentials.clientSecret;

const tokenBody: TokenRequest = {
const tokenBody = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We removed the type because we are not able to generate the type for the request body?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the removal of TokenRequest is one of the things called out by @joeluong-sfcc in his spike: https://github.com/joeluong-sfcc/oas-spike/pull/11

@vcua-mobify vcua-mobify requested a review from unandyala May 28, 2025 22:09
@vcua-mobify vcua-mobify requested a review from joeluong-sfcc May 29, 2025 17:16
package.json Outdated
"@typescript-eslint/parser": "^4.33.0",
"autoprefixer": "9.8.8",
"bundlesize2": "^0.0.31",
"cross-env": "^5.2.1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we use cross-env in our other projects, but just double checking that this is 3PP approved correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the exact same version of cross-env used by the PWA Kit. But I'll remove this since I added this as a just in case someone were to run this in windows, which is admittedly unlikely.

package.json Outdated
{
"path": "commerce-sdk-isomorphic-with-deps.tgz",
"maxSize": "565 kB"
"maxSize": "2048 kB"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was expecting this to jump but not by that much, but to be honest, I think this should be fine. The bundle size that we really care about is the one that gets sent to the browser, which is the minified version generated by rollup in ./lib.

We still have to update the rollup config to split up files to support tree-shaking, and so we won't exactly know how the minified bundle size will be affected until then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual size of the tgz is 1.1 mb, and is caused by the .ts files doubling in size. The minified files have grown by less than 1 kb.

I'll lower the max size to something like 1.2 mb for now

package.json Outdated
"lint:style": "stylelint ./src/",
"prepare": "snyk protect",
"renderTemplates": "ts-node --compiler-options '{\"module\": \"commonjs\", \"target\": \"ES6\" }' ./scripts/generate.ts",
"renderTemplates": "cross-env PACKAGE_VERSION=$(node -p \"require('./package.json').version\") ts-node --compiler-options '{\"module\": \"commonjs\", \"target\": \"ES6\" }' ./scripts/generate-oas.ts",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use case for using cross-env?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was just a just in case someone were to run this in windows since we're setting an env var before running the generator. But as that is unlikely, I'll remove it for now.

@vcua-mobify vcua-mobify requested a review from joeluong-sfcc May 29, 2025 21:13
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the generate from raml script. Removed since the isomorphic sdk will only be generated from oas.

@@ -175,18 +36,21 @@ export async function updateApis(
*/
export async function downloadLatestApis(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only method in utils.ts that is used by the oas version of updateApis. Every other function here has been removed as they were only used by the raml generator.

'shopper-baskets',
'shopper-context',
'shopper-customers',
'shopper-discovery-search',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we are not using these in PWA?


import nock from 'nock';
import {ShopperSearch} from '../lib/shopperSearch';
import {ShopperSearch} from '../lib/shopper-search';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we planning to change the case in a different PR?

Copy link
Contributor Author

@vcua-mobify vcua-mobify May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the imports here are ok since they only affect the non-bundled APIs.

In the bundled code, the imports should still be the same. Ie.
import {ShopperSearch} from 'commerce-sdk-isomorphic'

fs.ensureDirSync(PRODUCTION_API_PATH);

API_LIST.forEach(name => {
// TODO: come up with a way to set isOAS other than using the name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isOAS seems unnecessary as we only support OAS in the SDK. Can we default to true while calling the raml-toolkit?

@vcua-mobify
Copy link
Contributor Author

@unandyala the entries in the config file correspond to the names of the files in anypoint exchange.
The actual APIs themselves are mostly the same. I say mostly because discovery in particular is out of scope.

From what I can see, we don't use discovery in commerce-sdk-react

package.json Outdated
"@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@commerce-apps/raml-toolkit": "0.5.12",
"@commerce-apps/raml-toolkit": "file:../raml-toolkit",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we wait until the RAML toolkit is released and then update this before merging? If not, let's note somewhere that we have to update this so we don't forget

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this to the newly released raml-toolkit version

'shopper-search',
'shopper-seo',
'shopper-stores',
'shopper-baskets-oas',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a comment in the other PR for just replacing the APIs, but do we want to add shopper baskets v1 as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at anypoint exchange, there is only one version of shopper-baskets-oas.

We should bring up getting an OAS version of baskets v1 with the api team.

ShopperLogin,
} from '../lib/shopper-login';
import ClientConfig, {ClientConfigInit} from '../static/clientConfig';
import {ShopperBaskets} from '../lib/shopper-baskets';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NIT] but if we have time let's update the generator to use camelCase instead of kebab-case so it's ../lib/shopperBaskets just for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This suggestion has been applied

* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
export const USER_AGENT_HEADER = "user-agent";
export const USER_AGENT_VALUE = "commerce-sdk-isomorphic@3.3.0";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is generated correct? Do we need this file since we already generate one with the SDK in src/lib/version.ts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good eye. This is a current quirk where the generated version of version.ts outputs to /src/static then is copied over into src/lib later on.

The reason I had this is because the templates currently set imports to go to the static directory rather than the lib directory.

I'll update the templates to point to /src/lib rather than src/static then we won't need this file anymore

},
body: {
grant_type: 'client_credentials',
grant_type: 'client_credentials' as const,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this added because there were new typescript errors?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, yes. There were errors around the 'client_credentials' string not being allowed with the enum values of grant_type without this.

organizationId: string;
name: string;
tags: string[];
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this type already exist in RAML toolkit? If so, we should export it there and import it here instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type does not exist in raml toolkit but I could move it there if we want since I'm duplicating this type in the node sdk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type is now in the raml toolkit and this PR has been updated to refer there

@vcua-mobify vcua-mobify changed the title @W-17701711@ WIP - DO NOT MERGE - Generate isomorphic SDK from OAS @W-17701711@ Generate isomorphic SDK from OAS Jun 2, 2025
@vcua-mobify vcua-mobify marked this pull request as ready for review June 2, 2025 19:48
@vcua-mobify vcua-mobify requested a review from a team as a code owner June 2, 2025 19:48
Copy link
Contributor

@unandyala unandyala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left small comment/question

@@ -0,0 +1,7 @@
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this file here? Will it not use from raml-toolkit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I just tried generating the sdk again using the raml-toolkit command after deleting it and it didn't return.
This was probably an artifact from when I ran openapi-generator directly in the sdk. I'll delete it.

@vcua-mobify vcua-mobify merged commit e54456c into feature/oas Jun 3, 2025
4 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants