From 9f5f95a7e06de41c16a7bece723d712e844fae27 Mon Sep 17 00:00:00 2001 From: Sarangan Rajamanickam Date: Sat, 26 Feb 2022 19:06:10 -0800 Subject: [PATCH 1/2] Add Core Compatability Package Dependency --- package-lock.json | 9 + package.json | 1 + src/autorestSession.ts | 1 + src/generators/clientFileGenerator.ts | 31 +- src/generators/modelsGenerator.ts | 26 +- src/generators/static/packageFileGenerator.ts | 64 +- src/utils/autorestOptions.ts | 22 +- .../generated/corecompattest/README.md | 31 + .../corecompattest/api-extractor.json | 18 + .../generated/corecompattest/package.json | 88 +++ .../generated/corecompattest/rollup.config.js | 114 +++ .../generated/corecompattest/src/index.ts | 2 + .../corecompattest/src/models/index.ts | 283 ++++++++ .../corecompattest/src/models/mappers.ts | 295 ++++++++ .../corecompattest/src/models/parameters.ts | 312 +++++++++ .../generated/corecompattest/src/petStore.ts | 660 ++++++++++++++++++ .../generated/corecompattest/tsconfig.json | 19 + test/utils/run.ts | 9 +- test/utils/test-swagger-gen.ts | 19 +- 19 files changed, 1957 insertions(+), 47 deletions(-) create mode 100644 test/integration/generated/corecompattest/README.md create mode 100644 test/integration/generated/corecompattest/api-extractor.json create mode 100644 test/integration/generated/corecompattest/package.json create mode 100644 test/integration/generated/corecompattest/rollup.config.js create mode 100644 test/integration/generated/corecompattest/src/index.ts create mode 100644 test/integration/generated/corecompattest/src/models/index.ts create mode 100644 test/integration/generated/corecompattest/src/models/mappers.ts create mode 100644 test/integration/generated/corecompattest/src/models/parameters.ts create mode 100644 test/integration/generated/corecompattest/src/petStore.ts create mode 100644 test/integration/generated/corecompattest/tsconfig.json diff --git a/package-lock.json b/package-lock.json index 6d79911212..28613a3c5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -508,6 +508,15 @@ } } }, + "@azure/core-http-compat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.1.0.tgz", + "integrity": "sha512-uehsmf50QJOfZb4qMFJJcxOmpXk0/uPYLgMw+3Cubzd7EPJMsNP9M6ESBewo5mCZiSenA1RU6YQf2FY10nsZ5A==", + "requires": { + "@azure/core-client": "^1.3.0", + "@azure/core-rest-pipeline": "^1.3.0" + } + }, "@azure/core-lro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.1.0.tgz", diff --git a/package.json b/package.json index 472ede4cb0..e7c9b6a14e 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@azure-tools/codegen": "^2.5.294", "@azure/core-client": "^1.3.0", "@azure/core-http": "^1.2.4", + "@azure/core-http-compat": "^1.1.0", "@azure/core-lro": "^2.1.0", "@azure/core-paging": "^1.2.0", "@azure/core-rest-pipeline": "^1.3.0", diff --git a/src/autorestSession.ts b/src/autorestSession.ts index fedc9cc38e..04b2ed0132 100644 --- a/src/autorestSession.ts +++ b/src/autorestSession.ts @@ -35,6 +35,7 @@ export interface AutorestOptions { batch?: [string, any][]; multiClient?: boolean; generateSample?: boolean; + coreHttpCompatMode?: boolean; } let host: AutorestExtensionHost; diff --git a/src/generators/clientFileGenerator.ts b/src/generators/clientFileGenerator.ts index e5eaa4d9e5..094a198c0a 100644 --- a/src/generators/clientFileGenerator.ts +++ b/src/generators/clientFileGenerator.ts @@ -38,7 +38,8 @@ export function generateClient(clientDetails: ClientDetails, project: Project) { hideClients, srcPath, addCredentials, - packageDetails + packageDetails, + coreHttpCompatMode } = getAutorestOptions(); const hasMappers = !!clientDetails.mappers.length; @@ -110,6 +111,10 @@ export function generateClient(clientDetails: ClientDetails, project: Project) { moduleSpecifier: "@azure/core-auth" }); } + clientFile.addImportDeclaration({ + namespaceImport: "coreHttpCompat", + moduleSpecifier: "@azure/core-http-compat" + }); } addPagingEsNextRef(flattenedInlineOperations, clientFile); @@ -172,7 +177,11 @@ export function generateClient(clientDetails: ClientDetails, project: Project) { const clientClass = clientFile.addClass({ name: clientDetails.className, - extends: !useCoreV2 ? "coreHttp.ServiceClient" : "coreClient.ServiceClient", + extends: !useCoreV2 + ? "coreHttp.ServiceClient" + : coreHttpCompatMode + ? "coreHttpCompat.ExtendedServiceClient" + : "coreClient.ServiceClient", isExported: true }); @@ -330,7 +339,7 @@ function writeConstructor( shouldAddBlankLine && writer.blankLine(); } }; - + const writeStatements = (lines: string[], shouldAddBlankLine = false) => ( writer: CodeBlockWriter ) => { @@ -477,7 +486,12 @@ function getTrack2DefaultContent(addScopes: string, hasCredentials: boolean) { `; } -function getTrack1DefaultContent(addScopes: string, defaults: string, packageDetails: PackageDetails, clientDetails: ClientDetails) { +function getTrack1DefaultContent( + addScopes: string, + defaults: string, + packageDetails: PackageDetails, + clientDetails: ClientDetails +) { return `// Initializing default values for options if (!options) { options = {}; @@ -531,7 +545,12 @@ function writeDefaultOptions( return !useCoreV2 ? getTrack2DefaultContent(addScopes, hasCredentials) - : getTrack1DefaultContent(addScopes, defaults, packageDetails, clientDetails); + : getTrack1DefaultContent( + addScopes, + defaults, + packageDetails, + clientDetails + ); } function getEndpointStatement({ endpoint }: EndpointDetails) { @@ -571,4 +590,4 @@ function writePackageInfo( `const packageName = "${packageDetails.name || ""}";`, `const packageVersion = "${packageDetails.version || ""}";` ]); -} \ No newline at end of file +} diff --git a/src/generators/modelsGenerator.ts b/src/generators/modelsGenerator.ts index e3ad400f96..f81d6d6e2b 100644 --- a/src/generators/modelsGenerator.ts +++ b/src/generators/modelsGenerator.ts @@ -69,6 +69,10 @@ export function generateModels(clientDetails: ClientDetails, project: Project) { namespaceImport: "coreRestPipeline", moduleSpecifier: "@azure/core-rest-pipeline" }); + modelsIndexFile.addImportDeclaration({ + namespaceImport: "coreHttpCompat", + moduleSpecifier: "@azure/core-http-compat" + }); } writeUniontypes(clientDetails, modelsIndexFile); @@ -78,18 +82,20 @@ export function generateModels(clientDetails: ClientDetails, project: Project) { writeClientModels(clientDetails, modelsIndexFile); modelsIndexFile.fixUnusedIdentifiers(); const allTypes = modelsIndexFile.getTypeAliases(); - clientDetails.allTypes = allTypes.filter(item => { - return item.isExported() - }).map(item => { - return item.getName() - }); + clientDetails.allTypes = allTypes + .filter(item => { + return item.isExported(); + }) + .map(item => { + return item.getName(); + }); } const writeClientModels = ( clientDetails: ClientDetails, modelsIndexFile: SourceFile ) => { - const { useCoreV2 } = getAutorestOptions(); + const { useCoreV2, coreHttpCompatMode } = getAutorestOptions(); let clientOptionalParams = clientDetails.parameters.filter( p => (!p.required || p.defaultValue) && @@ -103,6 +109,8 @@ const writeClientModels = ( { baseClass: !useCoreV2 ? "coreHttp.ServiceClientOptions" + : coreHttpCompatMode + ? "coreHttpCompat.ExtendedServiceClientOptions" : "coreClient.ServiceClientOptions" } ); @@ -777,8 +785,10 @@ function getPropertyTypeName( ignoreNullableOnOptional: boolean ) { if (property.isConstant) { - if (property.type === SchemaType.Number - || property.type === SchemaType.Boolean) { + if ( + property.type === SchemaType.Number || + property.type === SchemaType.Boolean + ) { return `${property.defaultValue}`; } return `"${getStringForValue( diff --git a/src/generators/static/packageFileGenerator.ts b/src/generators/static/packageFileGenerator.ts index 68d98e2491..e001342d35 100644 --- a/src/generators/static/packageFileGenerator.ts +++ b/src/generators/static/packageFileGenerator.ts @@ -53,7 +53,7 @@ function restLevelPackage(packageDetails: PackageDetails) { const { model } = getSession(); const hasPaging = hasPagingOperations(model); const hasLRO = hasPollingOperations(model); - const packageInfo: Record = { + const packageInfo: Record = { name: `${packageDetails.name}`, "sdk-type": `${azureArm ? "mgmt" : "client"}`, version: `${packageDetails.version}`, @@ -144,20 +144,29 @@ function restLevelPackage(packageDetails: PackageDetails) { packageInfo.devDependencies["nyc"] = "^14.0.0"; packageInfo.devDependencies["source-map-support"] = "^0.5.9"; - packageInfo.scripts["test"] = "npm run clean && npm run build:test && npm run unit-test"; - packageInfo.scripts["test:node"] = "npm run clean && npm run build:test && npm run unit-test:node"; - packageInfo.scripts["test:browser"] = "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1"; + packageInfo.scripts["test"] = + "npm run clean && npm run build:test && npm run unit-test"; + packageInfo.scripts["test:node"] = + "npm run clean && npm run build:test && npm run unit-test:node"; + packageInfo.scripts["test:browser"] = + "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1"; packageInfo.scripts["build:test"] = "tsc -p . && rollup -c 2>&1"; - packageInfo.scripts["unit-test"] = "npm run unit-test:node && npm run unit-test:browser"; - packageInfo.scripts["unit-test:node"] = "mocha -r esm --require ts-node/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 1200000 --full-trace \"test/{,!(browser)/**/}*.spec.ts\""; + packageInfo.scripts["unit-test"] = + "npm run unit-test:node && npm run unit-test:browser"; + packageInfo.scripts["unit-test:node"] = + 'mocha -r esm --require ts-node/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 1200000 --full-trace "test/{,!(browser)/**/}*.spec.ts"'; packageInfo.scripts["unit-test:browser"] = "karma start --single-run"; - packageInfo.scripts["integration-test"] = "npm run integration-test:node && npm run integration-test:browser"; - packageInfo.scripts["integration-test:browser"] = "karma start --single-run"; - packageInfo.scripts["integration-test:node"] = "nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 5000000 --full-trace \"dist-esm/test/{,!(browser)/**/}*.spec.js\""; + packageInfo.scripts["integration-test"] = + "npm run integration-test:node && npm run integration-test:browser"; + packageInfo.scripts["integration-test:browser"] = + "karma start --single-run"; + packageInfo.scripts["integration-test:node"] = + 'nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 5000000 --full-trace "dist-esm/test/{,!(browser)/**/}*.spec.js"'; packageInfo["browser"] = { - "./dist-esm/test/public/utils/env.js": "./dist-esm/test/public/utils/env.browser.js" - } + "./dist-esm/test/public/utils/env.js": + "./dist-esm/test/public/utils/env.browser.js" + }; } return packageInfo; @@ -180,7 +189,8 @@ function regularAutorestPackage( addCredentials, azureOutputDirectory, generateTest, - generateSample + generateSample, + coreHttpCompatMode } = getAutorestOptions(); const { model } = getSession(); const hasLro = hasPollingOperations(model); @@ -211,6 +221,8 @@ function regularAutorestPackage( ...(!useCoreV2 && { "@azure/core-http": "^2.0.0" }), ...(useCoreV2 && { "@azure/core-client": "^1.0.0" }), ...(useCoreV2 && addCredentials && { "@azure/core-auth": "^1.3.0" }), + ...(useCoreV2 && + coreHttpCompatMode && { "@azure/core-http-compat": "^1.0.0" }), ...(useCoreV2 && { "@azure/core-rest-pipeline": "^1.1.0" }), @@ -295,11 +307,13 @@ function regularAutorestPackage( docs: "echo skipped" }, sideEffects: false, - "//metadata":{ - constantPaths: [{ - path: `src/${normalizeName(clientDetails.name, NameType.File)}.ts`, - prefix: "packageDetails", - }], + "//metadata": { + constantPaths: [ + { + path: `src/${normalizeName(clientDetails.name, NameType.File)}.ts`, + prefix: "packageDetails" + } + ] }, autoPublish: true }; @@ -319,14 +333,16 @@ function regularAutorestPackage( packageInfo.scripts["integration-test:node"] = "mocha -r esm --require ts-node/register --timeout 1200000 --full-trace test/*.ts --reporter ../../../common/tools/mocha-multi-reporter.js"; } - if (generateSample && clientDetails.samples && clientDetails.samples.length > 0) { + if ( + generateSample && + clientDetails.samples && + clientDetails.samples.length > 0 + ) { packageInfo["//sampleConfiguration"] = { - "productName": description, - "productSlugs": [ - "azure" - ], - "disableDocsMs": true, - "apiRefLink": `https://docs.microsoft.com/javascript/api/${clientPackageName}${apiRefUrlQueryParameter}` + productName: description, + productSlugs: ["azure"], + disableDocsMs: true, + apiRefLink: `https://docs.microsoft.com/javascript/api/${clientPackageName}${apiRefUrlQueryParameter}` }; } return packageInfo; diff --git a/src/utils/autorestOptions.ts b/src/utils/autorestOptions.ts index e65e3df81c..919f15d894 100644 --- a/src/utils/autorestOptions.ts +++ b/src/utils/autorestOptions.ts @@ -36,6 +36,7 @@ export async function extractAutorestOptions(): Promise { const batch = await getBatch(host); const multiClient = await getMultiClient(host); const generateSample = await getGenerateSample(host); + const coreHttpCompatMode = await getCoreHttpCompatMode(host); return { azureArm, @@ -63,7 +64,8 @@ export async function extractAutorestOptions(): Promise { generateTest, batch, multiClient, - generateSample + generateSample, + coreHttpCompatMode }; } @@ -91,7 +93,9 @@ async function getGenerateTest(host: AutorestExtensionHost): Promise { return generateTest === null ? false : Boolean(generateTest); } -async function getGenerateSample(host: AutorestExtensionHost): Promise { +async function getGenerateSample( + host: AutorestExtensionHost +): Promise { const generateSample = await host.getValue("generate-sample"); return generateSample === null ? false : Boolean(generateSample); } @@ -289,12 +293,20 @@ async function getAzureOutputDirectoryPath( : undefined; } -async function getBatch(host: AutorestExtensionHost): Promise<[string, any][] | undefined> { - const batch = await host.getValue<[string, any][]>('batch'); +async function getBatch( + host: AutorestExtensionHost +): Promise<[string, any][] | undefined> { + const batch = await host.getValue<[string, any][]>("batch"); return batch; } async function getMultiClient(host: AutorestExtensionHost): Promise { - const multiClient = await host.getValue("multi-client") || undefined; + const multiClient = (await host.getValue("multi-client")) || undefined; return !!multiClient; } + +async function getCoreHttpCompatMode( + host: AutorestExtensionHost +): Promise { + return (await host.getValue("core-http-compat-mode")) || false; +} diff --git a/test/integration/generated/corecompattest/README.md b/test/integration/generated/corecompattest/README.md new file mode 100644 index 0000000000..24c1c9d0fc --- /dev/null +++ b/test/integration/generated/corecompattest/README.md @@ -0,0 +1,31 @@ +# Service client library for JavaScript + +This package contains an isomorphic SDK (runs both in Node.js and in browsers) for Service client. + +This is a sample server Petstore server. You can find out more about Swagger at http://swagger.io or on irc.freenode.net, #swagger. For this sample, you can use the api key "special-key" to test the authorization filters + +[Package (NPM)](https://www.npmjs.com/package/@msinternal/petstore) | +[Samples](https://github.com/Azure-Samples/azure-samples-js-management) + +## Getting started + +### Currently supported environments + +- [LTS versions of Node.js](https://nodejs.org/about/releases/) +- Latest versions of Safari, Chrome, Edge and Firefox. + +See our [support policy](https://github.com/Azure/azure-sdk-for-js/blob/main/SUPPORT.md) for more details. + + + + + +### JavaScript Bundle +To use this client library in the browser, first you need to use a bundler. For details on how to do this, please refer to our [bundling documentation](https://aka.ms/AzureSDKBundling). + +## Key concepts + +### PetStore + +`PetStore` is the primary interface for developers using the Service client library. Explore the methods on this client object to understand the different features of the Service service that you can access. + diff --git a/test/integration/generated/corecompattest/api-extractor.json b/test/integration/generated/corecompattest/api-extractor.json new file mode 100644 index 0000000000..a3982997c2 --- /dev/null +++ b/test/integration/generated/corecompattest/api-extractor.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "./dist-esm/index.d.ts", + "docModel": { "enabled": true }, + "apiReport": { "enabled": true, "reportFolder": "./review" }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "", + "publicTrimmedFilePath": "./types/petstore.d.ts" + }, + "messages": { + "tsdocMessageReporting": { "default": { "logLevel": "none" } }, + "extractorMessageReporting": { + "ae-missing-release-tag": { "logLevel": "none" }, + "ae-unresolved-link": { "logLevel": "none" } + } + } +} diff --git a/test/integration/generated/corecompattest/package.json b/test/integration/generated/corecompattest/package.json new file mode 100644 index 0000000000..8b1e9822a7 --- /dev/null +++ b/test/integration/generated/corecompattest/package.json @@ -0,0 +1,88 @@ +{ + "name": "@msinternal/petstore", + "sdk-type": "mgmt", + "author": "Microsoft Corporation", + "description": "A generated SDK for PetStore.", + "version": "1.0.0-preview1", + "engines": { "node": ">=12.0.0" }, + "dependencies": { + "@azure/core-client": "^1.0.0", + "@azure/core-http-compat": "^1.0.0", + "@azure/core-rest-pipeline": "^1.1.0", + "tslib": "^2.2.0" + }, + "keywords": ["node", "azure", "typescript", "browser", "isomorphic"], + "license": "MIT", + "main": "./dist/index.js", + "module": "./dist-esm/index.js", + "types": "./types/petstore.d.ts", + "devDependencies": { + "@microsoft/api-extractor": "^7.18.11", + "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-multi-entry": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.1.3", + "mkdirp": "^1.0.4", + "rollup": "^2.66.1", + "rollup-plugin-sourcemaps": "^0.6.3", + "typescript": "~4.2.0", + "uglify-js": "^3.4.9", + "rimraf": "^3.0.0" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/undefined", + "repository": { + "type": "git", + "url": "https://github.com/Azure/azure-sdk-for-js.git" + }, + "bugs": { "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, + "files": [ + "dist/**/*.js", + "dist/**/*.js.map", + "dist/**/*.d.ts", + "dist/**/*.d.ts.map", + "dist-esm/**/*.js", + "dist-esm/**/*.js.map", + "dist-esm/**/*.d.ts", + "dist-esm/**/*.d.ts.map", + "src/**/*.ts", + "README.md", + "LICENSE", + "rollup.config.js", + "tsconfig.json", + "review/*", + "CHANGELOG.md", + "types/*" + ], + "scripts": { + "build": "npm run clean && tsc && rollup -c 2>&1 && npm run minify && mkdirp ./review && npm run extract-api", + "minify": "uglifyjs -c -m --comments --source-map \"content='./dist/index.js.map'\" -o ./dist/index.min.js ./dist/index.js", + "prepack": "npm run build", + "pack": "npm pack 2>&1", + "extract-api": "api-extractor run --local", + "lint": "echo skipped", + "audit": "echo skipped", + "clean": "rimraf dist dist-browser dist-esm test-dist temp types *.tgz *.log", + "build:node": "echo skipped", + "build:browser": "echo skipped", + "build:test": "echo skipped", + "build:samples": "echo skipped.", + "check-format": "echo skipped", + "execute:samples": "echo skipped", + "format": "echo skipped", + "test": "echo skipped", + "test:node": "echo skipped", + "test:browser": "echo skipped", + "unit-test": "echo skipped", + "unit-test:node": "echo skipped", + "unit-test:browser": "echo skipped", + "integration-test": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test:browser": "echo skipped", + "docs": "echo skipped" + }, + "sideEffects": false, + "//metadata": { + "constantPaths": [{ "path": "src/petStore.ts", "prefix": "packageDetails" }] + }, + "autoPublish": true +} diff --git a/test/integration/generated/corecompattest/rollup.config.js b/test/integration/generated/corecompattest/rollup.config.js new file mode 100644 index 0000000000..7c67b82139 --- /dev/null +++ b/test/integration/generated/corecompattest/rollup.config.js @@ -0,0 +1,114 @@ +import nodeResolve from "@rollup/plugin-node-resolve"; +import cjs from "@rollup/plugin-commonjs"; +import sourcemaps from "rollup-plugin-sourcemaps"; +import multiEntry from "@rollup/plugin-multi-entry"; +import json from "@rollup/plugin-json"; + +import nodeBuiltins from "builtin-modules"; + +// #region Warning Handler + +/** + * A function that can determine whether a rollup warning should be ignored. If + * the function returns `true`, then the warning will not be displayed. + */ + +function ignoreNiseSinonEval(warning) { + return ( + warning.code === "EVAL" && + warning.id && + (warning.id.includes("node_modules/nise") || + warning.id.includes("node_modules/sinon")) === true + ); +} + +function ignoreChaiCircularDependency(warning) { + return ( + warning.code === "CIRCULAR_DEPENDENCY" && + warning.importer && warning.importer.includes("node_modules/chai") === true + ); +} + +const warningInhibitors = [ignoreChaiCircularDependency, ignoreNiseSinonEval]; + +/** + * Construct a warning handler for the shared rollup configuration + * that ignores certain warnings that are not relevant to testing. + */ +function makeOnWarnForTesting() { + return (warning, warn) => { + // If every inhibitor returns false (i.e. no inhibitors), then show the warning + if (warningInhibitors.every((inhib) => !inhib(warning))) { + warn(warning); + } + }; +} + +// #endregion + +function makeBrowserTestConfig() { + const config = { + input: { + include: ["dist-esm/test/**/*.spec.js"], + exclude: ["dist-esm/test/**/node/**"] + }, + output: { + file: `dist-test/index.browser.js`, + format: "umd", + sourcemap: true + }, + preserveSymlinks: false, + plugins: [ + multiEntry({ exports: false }), + nodeResolve({ + mainFields: ["module", "browser"] + }), + cjs(), + json(), + sourcemaps() + //viz({ filename: "dist-test/browser-stats.html", sourcemap: true }) + ], + onwarn: makeOnWarnForTesting(), + // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, + // rollup started respecting the "sideEffects" field in package.json. Since + // our package.json sets "sideEffects=false", this also applies to test + // code, which causes all tests to be removed by tree-shaking. + treeshake: false + }; + + return config; +} + +const defaultConfigurationOptions = { + disableBrowserBundle: false +}; + +export function makeConfig(pkg, options) { + options = { + ...defaultConfigurationOptions, + ...(options || {}) + }; + + const baseConfig = { + // Use the package's module field if it has one + input: pkg["module"] || "dist-esm/src/index.js", + external: [ + ...nodeBuiltins, + ...Object.keys(pkg.dependencies), + ...Object.keys(pkg.devDependencies) + ], + output: { file: "dist/index.js", format: "cjs", sourcemap: true }, + preserveSymlinks: false, + plugins: [sourcemaps(), nodeResolve()] + }; + + const config = [baseConfig]; + + if (!options.disableBrowserBundle) { + config.push(makeBrowserTestConfig()); + } + + return config; +} + +export default makeConfig(require("./package.json")); diff --git a/test/integration/generated/corecompattest/src/index.ts b/test/integration/generated/corecompattest/src/index.ts new file mode 100644 index 0000000000..e7627063d3 --- /dev/null +++ b/test/integration/generated/corecompattest/src/index.ts @@ -0,0 +1,2 @@ +export * from "./models"; +export { PetStore } from "./petStore"; diff --git a/test/integration/generated/corecompattest/src/models/index.ts b/test/integration/generated/corecompattest/src/models/index.ts new file mode 100644 index 0000000000..41de5d61e4 --- /dev/null +++ b/test/integration/generated/corecompattest/src/models/index.ts @@ -0,0 +1,283 @@ +import * as coreClient from "@azure/core-client"; +import * as coreRestPipeline from "@azure/core-rest-pipeline"; +import * as coreHttpCompat from "@azure/core-http-compat"; + +/** A group of properties representing a pet. */ +export interface Pet { + /** A more detailed description of the id of the pet. */ + id?: number; + category?: Category; + name: string; + photoUrls: string[]; + tags?: Tag[]; + /** pet status in the store */ + status?: PetStatus; +} + +export interface Category { + id?: number; + name?: string; +} + +export interface Tag { + id?: number; + name?: string; +} + +export interface Order { + /** NOTE: This property will not be serialized. It can only be populated by the server. */ + readonly id?: number; + petId?: number; + quantity?: number; + shipDate?: Date; + /** Order Status */ + status?: OrderStatus; + complete?: boolean; +} + +export interface User { + id?: number; + username?: string; + firstName?: string; + lastName?: string; + email?: string; + password?: string; + phone?: string; + /** User Status */ + userStatus?: number; +} + +export interface PathsN18Gb4PetPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema { + /** Updated name of the pet */ + name?: string; + /** Updated status of the pet */ + status?: string; +} + +export interface PathsQ1AtbnPetPetidUploadimagePostRequestbodyContentMultipartFormDataSchema { + /** Additional data to pass to server */ + additionalMetadata?: string; + /** file to upload */ + file?: coreRestPipeline.RequestBodyType; +} + +/** Known values of {@link PetStatus} that the service accepts. */ +export enum KnownPetStatus { + Available = "available", + Pending = "pending", + Sold = "sold" +} + +/** + * Defines values for PetStatus. \ + * {@link KnownPetStatus} can be used interchangeably with PetStatus, + * this enum contains the known values that the service supports. + * ### Known values supported by the service + * **available** \ + * **pending** \ + * **sold** + */ +export type PetStatus = string; + +/** Known values of {@link OrderStatus} that the service accepts. */ +export enum KnownOrderStatus { + Placed = "placed", + Approved = "approved", + Delivered = "delivered" +} + +/** + * Defines values for OrderStatus. \ + * {@link KnownOrderStatus} can be used interchangeably with OrderStatus, + * this enum contains the known values that the service supports. + * ### Known values supported by the service + * **placed** \ + * **approved** \ + * **delivered** + */ +export type OrderStatus = string; + +/** Optional parameters. */ +export interface AddPetUsingByteArray$binaryOptionalParams + extends coreClient.OperationOptions { + /** Pet object in the form of byte array */ + body?: coreRestPipeline.RequestBodyType; +} + +/** Optional parameters. */ +export interface AddPetUsingByteArray$xmlOptionalParams + extends coreClient.OperationOptions { + /** Pet object in the form of byte array */ + body?: coreRestPipeline.RequestBodyType; +} + +/** Optional parameters. */ +export interface AddPetOptionalParams extends coreClient.OperationOptions { + /** Pet object that needs to be added to the store */ + body?: Pet; +} + +/** Optional parameters. */ +export interface UpdatePetOptionalParams extends coreClient.OperationOptions { + /** Pet object that needs to be added to the store */ + body?: Pet; +} + +/** Optional parameters. */ +export interface FindPetsByStatusOptionalParams + extends coreClient.OperationOptions { + /** Status values that need to be considered for filter */ + status?: string[]; +} + +/** Contains response data for the findPetsByStatus operation. */ +export type FindPetsByStatusResponse = Pet[]; + +/** Optional parameters. */ +export interface FindPetsByTagsOptionalParams + extends coreClient.OperationOptions { + /** Tags to filter by */ + tags?: string[]; +} + +/** Contains response data for the findPetsByTags operation. */ +export type FindPetsByTagsResponse = Pet[]; + +/** Optional parameters. */ +export interface FindPetsWithByteArrayOptionalParams + extends coreClient.OperationOptions {} + +/** Contains response data for the findPetsWithByteArray operation. */ +export type FindPetsWithByteArrayResponse = { + /** + * BROWSER ONLY + * + * The response body as a browser Blob. + * Always `undefined` in node.js. + */ + blobBody?: Promise; + /** + * NODEJS ONLY + * + * The response body as a node.js Readable stream. + * Always `undefined` in the browser. + */ + readableStreamBody?: NodeJS.ReadableStream; +}; + +/** Optional parameters. */ +export interface GetPetByIdOptionalParams extends coreClient.OperationOptions {} + +/** Contains response data for the getPetById operation. */ +export type GetPetByIdResponse = Pet; + +/** Optional parameters. */ +export interface UpdatePetWithFormOptionalParams + extends coreClient.OperationOptions { + /** Updated name of the pet */ + name?: string; + /** Updated status of the pet */ + status?: string; +} + +/** Optional parameters. */ +export interface DeletePetOptionalParams extends coreClient.OperationOptions { + apiKey?: string; +} + +/** Optional parameters. */ +export interface UploadFileOptionalParams extends coreClient.OperationOptions { + /** Additional data to pass to server */ + additionalMetadata?: string; + /** file to upload */ + file?: coreRestPipeline.RequestBodyType; +} + +/** Optional parameters. */ +export interface GetInventoryOptionalParams + extends coreClient.OperationOptions {} + +/** Contains response data for the getInventory operation. */ +export type GetInventoryResponse = { [propertyName: string]: number }; + +/** Optional parameters. */ +export interface PlaceOrderOptionalParams extends coreClient.OperationOptions { + /** order placed for purchasing the pet */ + body?: Order; +} + +/** Contains response data for the placeOrder operation. */ +export type PlaceOrderResponse = Order; + +/** Optional parameters. */ +export interface GetOrderByIdOptionalParams + extends coreClient.OperationOptions {} + +/** Contains response data for the getOrderById operation. */ +export type GetOrderByIdResponse = Order; + +/** Optional parameters. */ +export interface DeleteOrderOptionalParams + extends coreClient.OperationOptions {} + +/** Optional parameters. */ +export interface CreateUserOptionalParams extends coreClient.OperationOptions { + /** Created user object */ + body?: User; +} + +/** Optional parameters. */ +export interface CreateUsersWithArrayInputOptionalParams + extends coreClient.OperationOptions { + /** List of user object */ + body?: User[]; +} + +/** Optional parameters. */ +export interface CreateUsersWithListInputOptionalParams + extends coreClient.OperationOptions { + /** List of user object */ + body?: User[]; +} + +/** Optional parameters. */ +export interface LoginUserOptionalParams extends coreClient.OperationOptions { + /** The user name for login */ + username?: string; + /** The password for login in clear text */ + password?: string; +} + +/** Contains response data for the loginUser operation. */ +export type LoginUserResponse = { + /** The parsed response body. */ + body: string; +}; + +/** Optional parameters. */ +export interface LogoutUserOptionalParams extends coreClient.OperationOptions {} + +/** Optional parameters. */ +export interface GetUserByNameOptionalParams + extends coreClient.OperationOptions {} + +/** Contains response data for the getUserByName operation. */ +export type GetUserByNameResponse = User; + +/** Optional parameters. */ +export interface UpdateUserOptionalParams extends coreClient.OperationOptions { + /** Updated user object */ + body?: User; +} + +/** Optional parameters. */ +export interface DeleteUserOptionalParams extends coreClient.OperationOptions {} + +/** Optional parameters. */ +export interface PetStoreOptionalParams + extends coreHttpCompat.ExtendedServiceClientOptions { + /** server parameter */ + $host?: string; + /** Overrides client endpoint. */ + endpoint?: string; +} diff --git a/test/integration/generated/corecompattest/src/models/mappers.ts b/test/integration/generated/corecompattest/src/models/mappers.ts new file mode 100644 index 0000000000..2f9427a7bf --- /dev/null +++ b/test/integration/generated/corecompattest/src/models/mappers.ts @@ -0,0 +1,295 @@ +import * as coreClient from "@azure/core-client"; + +export const Pet: coreClient.CompositeMapper = { + serializedName: "Pet", + xmlName: "Pet", + type: { + name: "Composite", + className: "Pet", + modelProperties: { + id: { + serializedName: "id", + xmlName: "id", + type: { + name: "Number" + } + }, + category: { + serializedName: "category", + xmlName: "Category", + type: { + name: "Composite", + className: "Category" + } + }, + name: { + serializedName: "name", + required: true, + xmlName: "name", + type: { + name: "String" + } + }, + photoUrls: { + serializedName: "photoUrls", + required: true, + xmlName: "photoUrl", + xmlIsWrapped: true, + xmlElementName: "PetPhotoUrlsItem", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + tags: { + serializedName: "tags", + xmlName: "tag", + xmlIsWrapped: true, + xmlElementName: "Tag", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Tag" + } + } + } + }, + status: { + serializedName: "status", + xmlName: "status", + type: { + name: "String" + } + } + } + } +}; + +export const Category: coreClient.CompositeMapper = { + serializedName: "Category", + xmlName: "Category", + type: { + name: "Composite", + className: "Category", + modelProperties: { + id: { + serializedName: "id", + xmlName: "id", + type: { + name: "Number" + } + }, + name: { + serializedName: "name", + xmlName: "name", + type: { + name: "String" + } + } + } + } +}; + +export const Tag: coreClient.CompositeMapper = { + serializedName: "Tag", + xmlName: "Tag", + type: { + name: "Composite", + className: "Tag", + modelProperties: { + id: { + serializedName: "id", + xmlName: "id", + type: { + name: "Number" + } + }, + name: { + serializedName: "name", + xmlName: "name", + type: { + name: "String" + } + } + } + } +}; + +export const Order: coreClient.CompositeMapper = { + serializedName: "Order", + xmlName: "Order", + type: { + name: "Composite", + className: "Order", + modelProperties: { + id: { + serializedName: "id", + readOnly: true, + xmlName: "id", + type: { + name: "Number" + } + }, + petId: { + serializedName: "petId", + xmlName: "petId", + type: { + name: "Number" + } + }, + quantity: { + serializedName: "quantity", + xmlName: "quantity", + type: { + name: "Number" + } + }, + shipDate: { + serializedName: "shipDate", + xmlName: "shipDate", + type: { + name: "DateTime" + } + }, + status: { + serializedName: "status", + xmlName: "status", + type: { + name: "String" + } + }, + complete: { + serializedName: "complete", + xmlName: "complete", + type: { + name: "Boolean" + } + } + } + } +}; + +export const User: coreClient.CompositeMapper = { + serializedName: "User", + xmlName: "User", + type: { + name: "Composite", + className: "User", + modelProperties: { + id: { + serializedName: "id", + xmlName: "id", + type: { + name: "Number" + } + }, + username: { + serializedName: "username", + xmlName: "username", + type: { + name: "String" + } + }, + firstName: { + serializedName: "firstName", + xmlName: "firstName", + type: { + name: "String" + } + }, + lastName: { + serializedName: "lastName", + xmlName: "lastName", + type: { + name: "String" + } + }, + email: { + serializedName: "email", + xmlName: "email", + type: { + name: "String" + } + }, + password: { + serializedName: "password", + xmlName: "password", + type: { + name: "String" + } + }, + phone: { + serializedName: "phone", + xmlName: "phone", + type: { + name: "String" + } + }, + userStatus: { + serializedName: "userStatus", + xmlName: "userStatus", + type: { + name: "Number" + } + } + } + } +}; + +export const PathsN18Gb4PetPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema: coreClient.CompositeMapper = { + serializedName: + "PathsN18Gb4PetPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema", + type: { + name: "Composite", + className: + "PathsN18Gb4PetPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema", + modelProperties: { + name: { + serializedName: "name", + xmlName: "name", + type: { + name: "String" + } + }, + status: { + serializedName: "status", + xmlName: "status", + type: { + name: "String" + } + } + } + } +}; + +export const PathsQ1AtbnPetPetidUploadimagePostRequestbodyContentMultipartFormDataSchema: coreClient.CompositeMapper = { + serializedName: + "PathsQ1AtbnPetPetidUploadimagePostRequestbodyContentMultipartFormDataSchema", + type: { + name: "Composite", + className: + "PathsQ1AtbnPetPetidUploadimagePostRequestbodyContentMultipartFormDataSchema", + modelProperties: { + additionalMetadata: { + serializedName: "additionalMetadata", + xmlName: "additionalMetadata", + type: { + name: "String" + } + }, + file: { + serializedName: "file", + xmlName: "file", + type: { + name: "Stream" + } + } + } + } +}; diff --git a/test/integration/generated/corecompattest/src/models/parameters.ts b/test/integration/generated/corecompattest/src/models/parameters.ts new file mode 100644 index 0000000000..a43f538df9 --- /dev/null +++ b/test/integration/generated/corecompattest/src/models/parameters.ts @@ -0,0 +1,312 @@ +import { + OperationParameter, + OperationURLParameter, + OperationQueryParameter +} from "@azure/core-client"; +import { + Pet as PetMapper, + Order as OrderMapper, + User as UserMapper +} from "../models/mappers"; + +export const contentType: OperationParameter = { + parameterPath: "contentType", + mapper: { + defaultValue: "application/json", + isConstant: true, + serializedName: "Content-Type", + type: { + name: "String" + } + } +}; + +export const body: OperationParameter = { + parameterPath: ["options", "body"], + mapper: { + serializedName: "body", + xmlName: "body", + type: { + name: "Stream" + } + } +}; + +export const contentType1: OperationParameter = { + parameterPath: "contentType", + mapper: { + defaultValue: "application/xml", + isConstant: true, + serializedName: "Content-Type", + type: { + name: "String" + } + } +}; + +export const body1: OperationParameter = { + parameterPath: ["options", "body"], + mapper: { + serializedName: "body", + xmlName: "body", + type: { + name: "Stream" + } + } +}; + +export const $host: OperationURLParameter = { + parameterPath: "$host", + mapper: { + serializedName: "$host", + required: true, + xmlName: "$host", + type: { + name: "String" + } + }, + skipEncoding: true +}; + +export const contentType2: OperationParameter = { + parameterPath: ["options", "contentType"], + mapper: { + defaultValue: "application/json", + isConstant: true, + serializedName: "Content-Type", + type: { + name: "String" + } + } +}; + +export const body2: OperationParameter = { + parameterPath: ["options", "body"], + mapper: PetMapper +}; + +export const accept: OperationParameter = { + parameterPath: "accept", + mapper: { + defaultValue: "application/json, application/xml", + isConstant: true, + serializedName: "Accept", + type: { + name: "String" + } + } +}; + +export const status: OperationQueryParameter = { + parameterPath: ["options", "status"], + mapper: { + defaultValue: "available", + serializedName: "status", + xmlName: "status", + xmlElementName: "Get0ItemsItem", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + collectionFormat: "CSV" +}; + +export const tags: OperationQueryParameter = { + parameterPath: ["options", "tags"], + mapper: { + serializedName: "tags", + xmlName: "tags", + xmlElementName: "String", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + collectionFormat: "CSV" +}; + +export const petId: OperationURLParameter = { + parameterPath: "petId", + mapper: { + serializedName: "petId", + required: true, + xmlName: "petId", + type: { + name: "Number" + } + } +}; + +export const contentType3: OperationParameter = { + parameterPath: ["options", "contentType"], + mapper: { + defaultValue: "application/x-www-form-urlencoded", + isConstant: true, + serializedName: "Content-Type", + type: { + name: "String" + } + } +}; + +export const name: OperationParameter = { + parameterPath: ["options", "name"], + mapper: { + serializedName: "name", + xmlName: "name", + type: { + name: "String" + } + } +}; + +export const status1: OperationParameter = { + parameterPath: ["options", "status"], + mapper: { + serializedName: "status", + xmlName: "status", + type: { + name: "String" + } + } +}; + +export const petId1: OperationURLParameter = { + parameterPath: "petId", + mapper: { + serializedName: "petId", + required: true, + xmlName: "petId", + type: { + name: "String" + } + } +}; + +export const apiKey: OperationParameter = { + parameterPath: ["options", "apiKey"], + mapper: { + serializedName: "api_key", + xmlName: "api_key", + type: { + name: "String" + } + } +}; + +export const contentType4: OperationParameter = { + parameterPath: ["options", "contentType"], + mapper: { + defaultValue: "multipart/form-data", + isConstant: true, + serializedName: "Content-Type", + type: { + name: "String" + } + } +}; + +export const additionalMetadata: OperationParameter = { + parameterPath: ["options", "additionalMetadata"], + mapper: { + serializedName: "additionalMetadata", + xmlName: "additionalMetadata", + type: { + name: "String" + } + } +}; + +export const file: OperationParameter = { + parameterPath: ["options", "file"], + mapper: { + serializedName: "file", + xmlName: "file", + type: { + name: "Stream" + } + } +}; + +export const body3: OperationParameter = { + parameterPath: ["options", "body"], + mapper: OrderMapper +}; + +export const orderId: OperationURLParameter = { + parameterPath: "orderId", + mapper: { + serializedName: "orderId", + required: true, + xmlName: "orderId", + type: { + name: "String" + } + } +}; + +export const body4: OperationParameter = { + parameterPath: ["options", "body"], + mapper: UserMapper +}; + +export const body5: OperationParameter = { + parameterPath: ["options", "body"], + mapper: { + serializedName: "body", + xmlName: "body", + xmlElementName: "User", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "User" + } + } + } + } +}; + +export const username: OperationQueryParameter = { + parameterPath: ["options", "username"], + mapper: { + serializedName: "username", + xmlName: "username", + type: { + name: "String" + } + } +}; + +export const password: OperationQueryParameter = { + parameterPath: ["options", "password"], + mapper: { + serializedName: "password", + xmlName: "password", + type: { + name: "String" + } + } +}; + +export const username1: OperationURLParameter = { + parameterPath: "username", + mapper: { + serializedName: "username", + required: true, + xmlName: "username", + type: { + name: "String" + } + } +}; diff --git a/test/integration/generated/corecompattest/src/petStore.ts b/test/integration/generated/corecompattest/src/petStore.ts new file mode 100644 index 0000000000..4fb158057e --- /dev/null +++ b/test/integration/generated/corecompattest/src/petStore.ts @@ -0,0 +1,660 @@ +import * as coreClient from "@azure/core-client"; +import * as coreHttpCompat from "@azure/core-http-compat"; +import * as Parameters from "./models/parameters"; +import * as Mappers from "./models/mappers"; +import { + PetStoreOptionalParams, + AddPetUsingByteArray$binaryOptionalParams, + AddPetUsingByteArray$xmlOptionalParams, + AddPetOptionalParams, + UpdatePetOptionalParams, + FindPetsByStatusOptionalParams, + FindPetsByStatusResponse, + FindPetsByTagsOptionalParams, + FindPetsByTagsResponse, + FindPetsWithByteArrayOptionalParams, + FindPetsWithByteArrayResponse, + GetPetByIdOptionalParams, + GetPetByIdResponse, + UpdatePetWithFormOptionalParams, + DeletePetOptionalParams, + UploadFileOptionalParams, + GetInventoryOptionalParams, + GetInventoryResponse, + PlaceOrderOptionalParams, + PlaceOrderResponse, + GetOrderByIdOptionalParams, + GetOrderByIdResponse, + DeleteOrderOptionalParams, + CreateUserOptionalParams, + CreateUsersWithArrayInputOptionalParams, + CreateUsersWithListInputOptionalParams, + LoginUserOptionalParams, + LoginUserResponse, + LogoutUserOptionalParams, + GetUserByNameOptionalParams, + GetUserByNameResponse, + UpdateUserOptionalParams, + DeleteUserOptionalParams +} from "./models"; + +export class PetStore extends coreHttpCompat.ExtendedServiceClient { + $host: string; + + /** + * Initializes a new instance of the PetStore class. + * @param options The parameter options + */ + constructor(options?: PetStoreOptionalParams) { + // Initializing default values for options + if (!options) { + options = {}; + } + const defaults: PetStoreOptionalParams = { + requestContentType: "application/json; charset=utf-8" + }; + + const packageDetails = `azsdk-js-petstore/1.0.0-preview1`; + const userAgentPrefix = + options.userAgentOptions && options.userAgentOptions.userAgentPrefix + ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}` + : `${packageDetails}`; + + const optionsWithDefaults = { + ...defaults, + ...options, + userAgentOptions: { + userAgentPrefix + }, + baseUri: options.endpoint || "http://petstore.swagger.io/v2" + }; + super(optionsWithDefaults); + + // Assigning values to Constant parameters + this.$host = options.$host || "http://petstore.swagger.io/v2"; + } + + /** + * Fake endpoint to test byte array in body parameter for adding a new pet to the store + * @param contentType Upload file type + * @param options The options parameters. + */ + addPetUsingByteArray( + contentType: "application/json", + options?: AddPetUsingByteArray$binaryOptionalParams + ): Promise; + /** + * Fake endpoint to test byte array in body parameter for adding a new pet to the store + * @param contentType Body Parameter content-type + * @param options The options parameters. + */ + addPetUsingByteArray( + contentType: "application/xml", + options?: AddPetUsingByteArray$xmlOptionalParams + ): Promise; + /** + * Fake endpoint to test byte array in body parameter for adding a new pet to the store + * @param args Includes all the parameters for this operation. + */ + addPetUsingByteArray( + ...args: + | ["application/json", AddPetUsingByteArray$binaryOptionalParams?] + | ["application/xml", AddPetUsingByteArray$xmlOptionalParams?] + ): Promise { + let operationSpec: coreClient.OperationSpec; + let operationArguments: coreClient.OperationArguments; + let options; + if (args[0] === "application/json") { + operationSpec = addPetUsingByteArray$binaryOperationSpec; + operationArguments = { contentType: args[0], options: args[1] }; + options = args[1]; + } else if (args[0] === "application/xml") { + operationSpec = addPetUsingByteArray$xmlOperationSpec; + operationArguments = { contentType: args[0], options: args[1] }; + options = args[1]; + } else { + throw new TypeError( + `"contentType" must be a valid value but instead was "${args[0]}".` + ); + } + operationArguments.options = options || {}; + return this.sendOperationRequest(operationArguments, operationSpec); + } + + /** + * Adds a new pet to the store. You may receive an HTTP invalid input if your pet is invalid. + * @param options The options parameters. + */ + addPet(options?: AddPetOptionalParams): Promise { + return this.sendOperationRequest({ options }, addPetOperationSpec); + } + + /** + * Update an existing pet + * @param options The options parameters. + */ + updatePet(options?: UpdatePetOptionalParams): Promise { + return this.sendOperationRequest({ options }, updatePetOperationSpec); + } + + /** + * Multiple status values can be provided with comma seperated strings + * @param options The options parameters. + */ + findPetsByStatus( + options?: FindPetsByStatusOptionalParams + ): Promise { + return this.sendOperationRequest( + { options }, + findPetsByStatusOperationSpec + ); + } + + /** + * Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. + * @param options The options parameters. + */ + findPetsByTags( + options?: FindPetsByTagsOptionalParams + ): Promise { + return this.sendOperationRequest({ options }, findPetsByTagsOperationSpec); + } + + /** + * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + * @param petId ID of pet that needs to be fetched + * @param options The options parameters. + */ + findPetsWithByteArray( + petId: number, + options?: FindPetsWithByteArrayOptionalParams + ): Promise { + return this.sendOperationRequest( + { petId, options }, + findPetsWithByteArrayOperationSpec + ); + } + + /** + * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + * @param petId ID of pet that needs to be fetched + * @param options The options parameters. + */ + getPetById( + petId: number, + options?: GetPetByIdOptionalParams + ): Promise { + return this.sendOperationRequest( + { petId, options }, + getPetByIdOperationSpec + ); + } + + /** + * Updates a pet in the store with form data + * @param petId ID of pet that needs to be updated + * @param options The options parameters. + */ + updatePetWithForm( + petId: string, + options?: UpdatePetWithFormOptionalParams + ): Promise { + return this.sendOperationRequest( + { petId, options }, + updatePetWithFormOperationSpec + ); + } + + /** + * Deletes a pet + * @param petId Pet id to delete + * @param options The options parameters. + */ + deletePet(petId: number, options?: DeletePetOptionalParams): Promise { + return this.sendOperationRequest( + { petId, options }, + deletePetOperationSpec + ); + } + + /** + * uploads an image + * @param petId ID of pet to update + * @param options The options parameters. + */ + uploadFile(petId: number, options?: UploadFileOptionalParams): Promise { + return this.sendOperationRequest( + { petId, options }, + uploadFileOperationSpec + ); + } + + /** + * Returns a map of status codes to quantities + * @param options The options parameters. + */ + getInventory( + options?: GetInventoryOptionalParams + ): Promise { + return this.sendOperationRequest({ options }, getInventoryOperationSpec); + } + + /** + * Place an order for a pet + * @param options The options parameters. + */ + placeOrder(options?: PlaceOrderOptionalParams): Promise { + return this.sendOperationRequest({ options }, placeOrderOperationSpec); + } + + /** + * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + * @param orderId ID of pet that needs to be fetched + * @param options The options parameters. + */ + getOrderById( + orderId: string, + options?: GetOrderByIdOptionalParams + ): Promise { + return this.sendOperationRequest( + { orderId, options }, + getOrderByIdOperationSpec + ); + } + + /** + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will + * generate API errors + * @param orderId ID of the order that needs to be deleted + * @param options The options parameters. + */ + deleteOrder( + orderId: string, + options?: DeleteOrderOptionalParams + ): Promise { + return this.sendOperationRequest( + { orderId, options }, + deleteOrderOperationSpec + ); + } + + /** + * This can only be done by the logged in user. + * @param options The options parameters. + */ + createUser(options?: CreateUserOptionalParams): Promise { + return this.sendOperationRequest({ options }, createUserOperationSpec); + } + + /** + * Creates list of users with given input array + * @param options The options parameters. + */ + createUsersWithArrayInput( + options?: CreateUsersWithArrayInputOptionalParams + ): Promise { + return this.sendOperationRequest( + { options }, + createUsersWithArrayInputOperationSpec + ); + } + + /** + * Creates list of users with given input array + * @param options The options parameters. + */ + createUsersWithListInput( + options?: CreateUsersWithListInputOptionalParams + ): Promise { + return this.sendOperationRequest( + { options }, + createUsersWithListInputOperationSpec + ); + } + + /** + * Logs user into the system + * @param options The options parameters. + */ + loginUser(options?: LoginUserOptionalParams): Promise { + return this.sendOperationRequest({ options }, loginUserOperationSpec); + } + + /** + * Logs out current logged in user session + * @param options The options parameters. + */ + logoutUser(options?: LogoutUserOptionalParams): Promise { + return this.sendOperationRequest({ options }, logoutUserOperationSpec); + } + + /** + * Get user by user name + * @param username The name that needs to be fetched. Use user1 for testing. + * @param options The options parameters. + */ + getUserByName( + username: string, + options?: GetUserByNameOptionalParams + ): Promise { + return this.sendOperationRequest( + { username, options }, + getUserByNameOperationSpec + ); + } + + /** + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param options The options parameters. + */ + updateUser( + username: string, + options?: UpdateUserOptionalParams + ): Promise { + return this.sendOperationRequest( + { username, options }, + updateUserOperationSpec + ); + } + + /** + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + * @param options The options parameters. + */ + deleteUser( + username: string, + options?: DeleteUserOptionalParams + ): Promise { + return this.sendOperationRequest( + { username, options }, + deleteUserOperationSpec + ); + } +} +// Operation Specifications +const xmlSerializer = coreClient.createSerializer(Mappers, /* isXml */ true); + +const serializer = coreClient.createSerializer(Mappers, /* isXml */ false); + +const addPetUsingByteArray$binaryOperationSpec: coreClient.OperationSpec = { + path: "/pet", + httpMethod: "POST", + responses: { 405: {} }, + requestBody: Parameters.body, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType], + isXML: true, + contentType: "application/xml; charset=utf-8", + mediaType: "binary", + serializer: xmlSerializer +}; +const addPetUsingByteArray$xmlOperationSpec: coreClient.OperationSpec = { + path: "/pet", + httpMethod: "POST", + responses: { 405: {} }, + requestBody: Parameters.body1, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType1], + isXML: true, + contentType: "application/xml; charset=utf-8", + mediaType: "xml", + serializer: xmlSerializer +}; +const addPetOperationSpec: coreClient.OperationSpec = { + path: "/pet", + httpMethod: "POST", + responses: { 405: {} }, + requestBody: Parameters.body2, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType2], + mediaType: "json", + serializer +}; +const updatePetOperationSpec: coreClient.OperationSpec = { + path: "/pet", + httpMethod: "PUT", + responses: { 400: {}, 404: {}, 405: {} }, + requestBody: Parameters.body2, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType2], + mediaType: "json", + serializer +}; +const findPetsByStatusOperationSpec: coreClient.OperationSpec = { + path: "/pet/findByStatus", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: { + type: { + name: "Sequence", + element: { type: { name: "Composite", className: "Pet" } } + }, + serializedName: "ArrayOfPet", + xmlElementName: "Pet" + } + }, + 400: {} + }, + queryParameters: [Parameters.status], + urlParameters: [Parameters.$host], + headerParameters: [Parameters.accept], + isXML: true, + serializer: xmlSerializer +}; +const findPetsByTagsOperationSpec: coreClient.OperationSpec = { + path: "/pet/findByTags", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: { + type: { + name: "Sequence", + element: { type: { name: "Composite", className: "Pet" } } + }, + serializedName: "ArrayOfPet", + xmlElementName: "Pet" + } + }, + 400: {} + }, + queryParameters: [Parameters.tags], + urlParameters: [Parameters.$host], + headerParameters: [Parameters.accept], + isXML: true, + serializer: xmlSerializer +}; +const findPetsWithByteArrayOperationSpec: coreClient.OperationSpec = { + path: "/pet/{petId}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: { type: { name: "Stream" }, serializedName: "parsedResponse" } + }, + 400: {}, + 404: {} + }, + urlParameters: [Parameters.$host, Parameters.petId], + headerParameters: [Parameters.accept], + serializer +}; +const getPetByIdOperationSpec: coreClient.OperationSpec = { + path: "/pet/{petId}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.Pet + }, + 400: {}, + 404: {} + }, + urlParameters: [Parameters.$host, Parameters.petId], + headerParameters: [Parameters.accept], + isXML: true, + serializer: xmlSerializer +}; +const updatePetWithFormOperationSpec: coreClient.OperationSpec = { + path: "/pet/{petId}", + httpMethod: "POST", + responses: { 405: {} }, + formDataParameters: [Parameters.name, Parameters.status1], + urlParameters: [Parameters.$host, Parameters.petId1], + headerParameters: [Parameters.contentType3], + serializer +}; +const deletePetOperationSpec: coreClient.OperationSpec = { + path: "/pet/{petId}", + httpMethod: "DELETE", + responses: { 400: {} }, + urlParameters: [Parameters.$host, Parameters.petId], + headerParameters: [Parameters.apiKey], + serializer +}; +const uploadFileOperationSpec: coreClient.OperationSpec = { + path: "/pet/{petId}/uploadImage", + httpMethod: "POST", + responses: { default: {} }, + formDataParameters: [Parameters.additionalMetadata, Parameters.file], + urlParameters: [Parameters.$host, Parameters.petId], + headerParameters: [Parameters.contentType4], + serializer +}; +const getInventoryOperationSpec: coreClient.OperationSpec = { + path: "/store/inventory", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: { + type: { name: "Dictionary", value: { type: { name: "Number" } } }, + serializedName: "DictionaryOfInteger" + } + } + }, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.accept], + isXML: true, + serializer: xmlSerializer +}; +const placeOrderOperationSpec: coreClient.OperationSpec = { + path: "/store/order", + httpMethod: "POST", + responses: { + 200: { + bodyMapper: Mappers.Order + }, + 400: {} + }, + requestBody: Parameters.body3, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType2, Parameters.accept], + mediaType: "json", + serializer +}; +const getOrderByIdOperationSpec: coreClient.OperationSpec = { + path: "/store/order/{orderId}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.Order + }, + 400: {}, + 404: {} + }, + urlParameters: [Parameters.$host, Parameters.orderId], + headerParameters: [Parameters.accept], + isXML: true, + serializer: xmlSerializer +}; +const deleteOrderOperationSpec: coreClient.OperationSpec = { + path: "/store/order/{orderId}", + httpMethod: "DELETE", + responses: { 400: {}, 404: {} }, + urlParameters: [Parameters.$host, Parameters.orderId], + serializer +}; +const createUserOperationSpec: coreClient.OperationSpec = { + path: "/user", + httpMethod: "POST", + responses: { default: {} }, + requestBody: Parameters.body4, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType2], + mediaType: "json", + serializer +}; +const createUsersWithArrayInputOperationSpec: coreClient.OperationSpec = { + path: "/user/createWithArray", + httpMethod: "POST", + responses: { default: {} }, + requestBody: Parameters.body5, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType2], + mediaType: "json", + serializer +}; +const createUsersWithListInputOperationSpec: coreClient.OperationSpec = { + path: "/user/createWithList", + httpMethod: "POST", + responses: { default: {} }, + requestBody: Parameters.body5, + urlParameters: [Parameters.$host], + headerParameters: [Parameters.contentType2], + mediaType: "json", + serializer +}; +const loginUserOperationSpec: coreClient.OperationSpec = { + path: "/user/login", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: { type: { name: "String" }, serializedName: "String" } + }, + 400: {} + }, + queryParameters: [Parameters.username, Parameters.password], + urlParameters: [Parameters.$host], + headerParameters: [Parameters.accept], + isXML: true, + serializer: xmlSerializer +}; +const logoutUserOperationSpec: coreClient.OperationSpec = { + path: "/user/logout", + httpMethod: "GET", + responses: { default: {} }, + urlParameters: [Parameters.$host], + serializer +}; +const getUserByNameOperationSpec: coreClient.OperationSpec = { + path: "/user/{username}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.User + }, + 400: {}, + 404: {} + }, + urlParameters: [Parameters.$host, Parameters.username1], + headerParameters: [Parameters.accept], + isXML: true, + serializer: xmlSerializer +}; +const updateUserOperationSpec: coreClient.OperationSpec = { + path: "/user/{username}", + httpMethod: "PUT", + responses: { 400: {}, 404: {} }, + requestBody: Parameters.body4, + urlParameters: [Parameters.$host, Parameters.username1], + headerParameters: [Parameters.contentType2], + mediaType: "json", + serializer +}; +const deleteUserOperationSpec: coreClient.OperationSpec = { + path: "/user/{username}", + httpMethod: "DELETE", + responses: { 400: {}, 404: {} }, + urlParameters: [Parameters.$host, Parameters.username1], + serializer +}; diff --git a/test/integration/generated/corecompattest/tsconfig.json b/test/integration/generated/corecompattest/tsconfig.json new file mode 100644 index 0000000000..603440b3a3 --- /dev/null +++ b/test/integration/generated/corecompattest/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "es6", + "moduleResolution": "node", + "strict": true, + "target": "es6", + "sourceMap": true, + "declarationMap": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "lib": ["es6", "dom"], + "declaration": true, + "outDir": "./dist-esm", + "importHelpers": true + }, + "include": ["./src/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/test/utils/run.ts b/test/utils/run.ts index 04cb04c474..40235bf3f2 100644 --- a/test/utils/run.ts +++ b/test/utils/run.ts @@ -28,7 +28,8 @@ export async function runAutorest( rlcShortcut, headAsBoolean, isTestPackage, - generateTest + generateTest, + coreHttpCompatMode } = options; let autorestCommand = `autorest${ /^win/.test(process.platform) ? ".cmd" : "" @@ -93,9 +94,15 @@ export async function runAutorest( if (licenseHeader !== undefined) { commandArguments.push(`--license-header=${licenseHeader}`); } + + if (coreHttpCompatMode) { + commandArguments.push(`--core-http-compat-mode=${coreHttpCompatMode}`); + } + if (addCredentials !== undefined) { commandArguments.push(`--add-credentials=${!!addCredentials}`); } + if (packageDetails.version !== "") { commandArguments.push(`--package-version=${packageDetails.version}`); } diff --git a/test/utils/test-swagger-gen.ts b/test/utils/test-swagger-gen.ts index da114f2e31..8101026d4d 100644 --- a/test/utils/test-swagger-gen.ts +++ b/test/utils/test-swagger-gen.ts @@ -22,6 +22,7 @@ interface SwaggerConfig { isTestPackage?: boolean; generateTest?: boolean; generateSample?: boolean; + coreHttpCompatMode?: boolean; } const package_version = "1.0.0-preview1"; @@ -840,6 +841,16 @@ const testSwaggers: { [name: string]: SwaggerConfig } = { addCredentials: false, isTestPackage: true }, + corecompattest: { + swaggerOrConfig: "test/integration/swaggers/petstore.json", + clientName: "PetStore", + packageName: "petstore", + useCoreV2: true, + allowInsecureConnection: true, + addCredentials: false, + isTestPackage: true, + coreHttpCompatMode: true + }, // TEST REST LEVEL CLIENTS lroRest: { swaggerOrConfig: "lro.json", @@ -965,7 +976,7 @@ const testSwaggers: { [name: string]: SwaggerConfig } = { allowInsecureConnection: true, addCredentials: false, isTestPackage: true - }, + } }; const generateSwaggers = async ( @@ -997,7 +1008,8 @@ const generateSwaggers = async ( headAsBoolean, isTestPackage, generateTest, - rlcShortcut + rlcShortcut, + coreHttpCompatMode } = testSwaggers[name]; let swaggerPath = swaggerOrConfig; @@ -1037,7 +1049,8 @@ const generateSwaggers = async ( rlcShortcut, headAsBoolean, isTestPackage, - generateTest + generateTest, + coreHttpCompatMode }, isDebugging ); From faf120efb43d5b3dde8ff012b0d65567386498ca Mon Sep 17 00:00:00 2001 From: Sarangan Rajamanickam Date: Mon, 28 Feb 2022 16:17:18 -0800 Subject: [PATCH 2/2] Added test and updated changelog --- CHANGELOG.md | 3 ++- test/integration/corecampat.spec.ts | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/integration/corecampat.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e43309b7cc..5559aa39ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -## 6.0.0-beta.16 (UNRELEASED) +## 6.0.0-beta.16 (2022-03-01) - [Feature] Bumped @autorest/extension-base version to 3.4.1 and fix breaking changes. [#1253](https://github.com/Azure/autorest.typescript/pull/1253) +- [Feature] Introduced new flag `core-http-compat-mode` and supported generation of SDKs with the new compatability package. ## 6.0.0-beta.15 (2021-11-10) diff --git a/test/integration/corecampat.spec.ts b/test/integration/corecampat.spec.ts new file mode 100644 index 0000000000..8d8bfc4a4f --- /dev/null +++ b/test/integration/corecampat.spec.ts @@ -0,0 +1,18 @@ +import { PetStore as PetStoreClient } from "./generated/corecompattest/src"; +import { assert } from "chai"; + +describe("Integration tests for Core Comapability", () => { + let client: PetStoreClient; + + it("should create a client successfully", async () => { + client = new PetStoreClient({ + keepAliveOptions: { + enable: true + }, + redirectOptions: { + handleRedirects: true + } + }); + assert.notEqual(client, null); + }); +});