Skip to content

Commit

Permalink
Merge pull request #460 from microsoft/feature/multi-valued-headers
Browse files Browse the repository at this point in the history
feature/multi valued headers
  • Loading branch information
baywet authored Dec 13, 2022
2 parents 682cfc1 + 6897e16 commit 526fe93
Show file tree
Hide file tree
Showing 351 changed files with 4,980 additions and 2,456 deletions.
2 changes: 1 addition & 1 deletion packages/abstractions/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-abstractions",
"version": "1.0.0-preview.8",
"version": "1.0.0-preview.9",
"description": "Core abstractions for kiota generated libraries in TypeScript and JavaScript",
"main": "dist/cjs/src/index.js",
"files": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ export class ApiKeyAuthenticationProvider implements AuthenticationProvider {
this.apiKey;
break;
case ApiKeyLocation.Header:
request.headers[this.parameterName] = this.apiKey;
if (request.headers[this.parameterName]) {
request.headers[this.parameterName].push(this.apiKey);
} else {
request.headers[this.parameterName] = [this.apiKey];
}
break;
}
return Promise.resolve();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class BaseBearerTokenAuthenticationProvider
if (token) {
request.headers[
BaseBearerTokenAuthenticationProvider.authorizationHeaderKey
] = `Bearer ${token}`;
] = [`Bearer ${token}`];
}
}
};
Expand Down
11 changes: 6 additions & 5 deletions packages/abstractions/src/requestInformation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ export class RequestInformation {
string | number | boolean | undefined
> = {}; //TODO: case insensitive
/** The Request Headers. */
public headers: Record<string, string> = {}; //TODO: case insensitive
public headers: Record<string, string[]> = {};
private _requestOptions: Record<string, RequestOption> = {}; //TODO: case insensitive
/** Gets the request options for the request. */
public getRequestOptions() {
return this._requestOptions;
}
/** Adds the headers for the request. */
public addRequestHeaders(source: Record<string, string> | undefined) {
public addRequestHeaders(source: Record<string, string[]> | undefined) {
if (!source) return;
for (const key in source) {
this.headers[key] = source[key];
Expand Down Expand Up @@ -141,7 +141,7 @@ export class RequestInformation {
contentType?: string | undefined
) => {
if (contentType) {
this.headers[RequestInformation.contentTypeHeader] = contentType;
this.headers[RequestInformation.contentTypeHeader] = [contentType];
}
this.content = writer.getSerializedContent();
};
Expand Down Expand Up @@ -225,8 +225,9 @@ export class RequestInformation {
* @param value the binary stream
*/
public setStreamContent = (value: ArrayBuffer): void => {
this.headers[RequestInformation.contentTypeHeader] =
RequestInformation.binaryContentType;
this.headers[RequestInformation.contentTypeHeader] = [
RequestInformation.binaryContentType,
];
this.content = value;
};
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ describe("ApiKeyAuthenticationProvider", () => {
request.urlTemplate = "https://localhost{?param1}";
await provider.authenticateRequest(request);
assert.equal(request.URL, "https://localhost");
assert.equal(request.headers["param"], "key");
assert.equal(request.headers["param"][0], "key");
});
});
48 changes: 35 additions & 13 deletions packages/abstractions/test/common/requestInformation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import { URL } from "url";

const assert = chai.assert;

import { Parsable, RequestAdapter, RequestInformation, SerializationWriter, SerializationWriterFactory } from "../../src";
import {
Parsable,
RequestAdapter,
RequestInformation,
SerializationWriter,
SerializationWriterFactory,
} from "../../src";

class GetQueryParameters {
select?: string[];
Expand All @@ -20,12 +26,18 @@ class GetQueryParameters {
search?: string;
getQueryParameter(originalName: string): string {
switch (originalName.toLowerCase()) {
case 'select': return '%24select';
case 'count': return '%24count';
case 'filter': return '%24filter';
case 'orderby': return '%24orderby';
case 'search': return '%24search';
default: return originalName;
case "select":
return "%24select";
case "count":
return "%24count";
case "filter":
return "%24filter";
case "orderby":
return "%24orderby";
case "search":
return "%24search";
default:
return originalName;
}
}
}
Expand Down Expand Up @@ -58,10 +70,12 @@ describe("RequestInformation", () => {
const requestInformation = new RequestInformation();
requestInformation.pathParameters["baseurl"] = baseUrl;
requestInformation.urlTemplate = "http://localhost/me{?%24select}";
const headers: Record<string, string> = { ConsistencyLevel: "eventual" };
const headers: Record<string, string[]> = {
ConsistencyLevel: ["eventual"],
};
requestInformation.addRequestHeaders(headers);
assert.isNotEmpty(requestInformation.headers);
assert.equal("eventual", requestInformation.headers["ConsistencyLevel"]);
assert.equal(requestInformation.headers["ConsistencyLevel"][0], "eventual");
});

it("Sets a parsable content", () => {
Expand Down Expand Up @@ -94,7 +108,9 @@ describe("RequestInformation", () => {
"application/json",
{} as unknown as Parsable
);
const headers: Record<string, string> = { ConsistencyLevel: "eventual" };
const headers: Record<string, string[]> = {
ConsistencyLevel: ["eventual"],
};
requestInformation.addRequestHeaders(headers);
assert.isNotEmpty(requestInformation.headers);
assert.equal(methodCalledCount, 1);
Expand Down Expand Up @@ -130,7 +146,9 @@ describe("RequestInformation", () => {
"application/json",
[{} as unknown as Parsable]
);
const headers: Record<string, string> = { ConsistencyLevel: "eventual" };
const headers: Record<string, string[]> = {
ConsistencyLevel: ["eventual"],
};
requestInformation.addRequestHeaders(headers);
assert.isNotEmpty(requestInformation.headers);
assert.equal(methodCalledCount, 1);
Expand Down Expand Up @@ -164,7 +182,9 @@ describe("RequestInformation", () => {
"application/json",
"some content"
);
const headers: Record<string, string> = { ConsistencyLevel: "eventual" };
const headers: Record<string, string[]> = {
ConsistencyLevel: ["eventual"],
};
requestInformation.addRequestHeaders(headers);
assert.isNotEmpty(requestInformation.headers);
assert.equal(writtenValue, "some content");
Expand Down Expand Up @@ -198,7 +218,9 @@ describe("RequestInformation", () => {
"application/json",
["some content"]
);
const headers: Record<string, string> = { ConsistencyLevel: "eventual" };
const headers: Record<string, string[]> = {
ConsistencyLevel: ["eventual"],
};
requestInformation.addRequestHeaders(headers);
assert.isNotEmpty(requestInformation.headers);
assert.equal(writtenValue, '["some content"]');
Expand Down
4 changes: 2 additions & 2 deletions packages/authentication/azure/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-authentication-azure",
"version": "1.0.0-preview.6",
"version": "1.0.0-preview.7",
"description": "Authentication provider for Kiota using Azure Identity",
"main": "dist/cjs/src/index.js",
"module": "dist/es/src/index.js",
Expand Down Expand Up @@ -34,7 +34,7 @@
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@azure/core-auth": "^1.3.2",
"@microsoft/kiota-abstractions": "^1.0.0-preview.8",
"@microsoft/kiota-abstractions": "^1.0.0-preview.9",
"@opentelemetry/api": "^1.2.0",
"tslib": "^2.3.1"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe("Test authentication using @azure/identity", () => {
new AzureIdentityAuthenticationProvider(clientCredential, scopes);
await tokenCredentialAuthenticationProvider.authenticateRequest(request);
assert.equal(
request.headers["Authorization"],
request.headers["Authorization"][0],
"Bearer " + accessToken.token
);
});
Expand Down Expand Up @@ -110,7 +110,7 @@ describe("Test authentication using @azure/identity", () => {
new BaseBearerTokenAuthenticationProvider(accessTokenProvider);
await tokenCredentialAuthenticationProvider.authenticateRequest(request);
assert.equal(
request.headers["Authorization"],
request.headers["Authorization"][0],
"Bearer " + accessToken.token
);
});
Expand Down Expand Up @@ -140,7 +140,7 @@ describe("Test authentication using @azure/identity", () => {
const request: RequestInformation = new RequestInformation();
request.urlTemplate = "test";
request.URL = "https://graph.microsoft.com/v1.0";
request.headers.Authorization = "Bearer dummy_valid_token";
request.headers.Authorization = ["Bearer dummy_valid_token"];
const tokenCredentialAuthenticationProvider =
new AzureIdentityAuthenticationProvider(clientCredential, scopes);
await tokenCredentialAuthenticationProvider.authenticateRequest(request, {
Expand Down
4 changes: 2 additions & 2 deletions packages/authentication/spfx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-authentication-spfx",
"version": "1.0.0-preview.2",
"version": "1.0.0-preview.3",
"description": "Authentication provider for using Kiota in SPFx solutions",
"main": "dist/cjs/src/index.js",
"module": "dist/es/src/index.js",
Expand Down Expand Up @@ -43,7 +43,7 @@
},
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.8",
"@microsoft/kiota-abstractions": "^1.0.0-preview.9",
"@microsoft/sp-http": "^1.15.2",
"@opentelemetry/api": "^1.2.0",
"tslib": "^2.3.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe("Test authentication using SharePoint Framework", () => {
await azureAdSpfxAuthProvider.authenticateRequest(request);

assert.equal(
request.headers["Authorization"],
request.headers["Authorization"][0],
"Bearer " + expectedToken
);
});
Expand Down
4 changes: 2 additions & 2 deletions packages/http/fetch/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-http-fetchlibrary",
"version": "1.0.0-preview.9",
"version": "1.0.0-preview.10",
"description": "Kiota request adapter implementation with fetch",
"keywords": [
"Kiota",
Expand Down Expand Up @@ -43,7 +43,7 @@
"test:cjs": "mocha 'dist/cjs/test/common/**/*.js' && mocha 'dist/cjs/test/node/**/*.js'"
},
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.8",
"@microsoft/kiota-abstractions": "^1.0.0-preview.9",
"@opentelemetry/api": "^1.2.0",
"node-fetch": "^2.6.5",
"tslib": "^2.3.1"
Expand Down
14 changes: 12 additions & 2 deletions packages/http/fetch/src/fetchRequestAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,15 +427,16 @@ export class FetchRequestAdapter implements RequestAdapter {
}
const requestContentLength = requestInfo.headers["Content-Length"];
if (requestContentLength) {
spanForAttributes.setAttribute("http.request_content_length", parseInt(requestContentLength));
spanForAttributes.setAttribute("http.request_content_length", parseInt(requestContentLength[0]));
}
const requestContentType = requestInfo.headers["Content-Type"];
if (requestContentType) {
spanForAttributes.setAttribute("http.request_content_type", requestContentType);
}
const headers: [string, string][] | undefined = requestInfo.headers ? Object.entries(requestInfo.headers).map(([key, value]) => [key.toLocaleLowerCase(), this.foldHeaderValue(value)]) : undefined;
const request = {
method,
headers: requestInfo.headers,
headers,
body: requestInfo.content,
} as RequestInit;
return request;
Expand All @@ -444,4 +445,13 @@ export class FetchRequestAdapter implements RequestAdapter {
}
});
};
private foldHeaderValue = (value: string[]): string => {
if (value.length < 1) {
return "";
} else if (value.length === 1) {
return value[0];
} else {
return value.reduce((acc, val) => acc + val, ",");
}
};
}
4 changes: 2 additions & 2 deletions packages/serialization/json/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-serialization-json",
"version": "1.0.0-preview.9",
"version": "1.0.0-preview.10",
"description": "Implementation of Kiota Serialization interfaces for JSON",
"main": "dist/cjs/src/index.js",
"browser": {
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.8",
"@microsoft/kiota-abstractions": "^1.0.0-preview.9",
"tslib": "^2.3.1"
}
}
4 changes: 2 additions & 2 deletions packages/serialization/text/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-serialization-text",
"version": "1.0.0-preview.8",
"version": "1.0.0-preview.9",
"description": "Implementation of Kiota Serialization interfaces for text",
"files": [
"src",
Expand Down Expand Up @@ -43,7 +43,7 @@
},
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.8",
"@microsoft/kiota-abstractions": "^1.0.0-preview.9",
"tslib": "^2.3.1"
}
}
20 changes: 11 additions & 9 deletions packages/test/generatedCode/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import {enableBackingStoreForSerializationWriterFactory, getPathParameters, Pars
import {JsonParseNodeFactory, JsonSerializationWriterFactory} from '@microsoft/kiota-serialization-json';
import {TextParseNodeFactory, TextSerializationWriterFactory} from '@microsoft/kiota-serialization-text';

/** The main entry point of the SDK, exposes the configuration and the fluent API. */
/**
* The main entry point of the SDK, exposes the configuration and the fluent API.
*/
export class ApiClient {
/** Path parameters for the request */
private readonly pathParameters: Record<string, unknown>;
/** The request adapter to use to execute the requests. */
private readonly requestAdapter: RequestAdapter;
/** Url template to use to build the URL for the current request builder */
private readonly urlTemplate: string;
/** The users property */
/** Path parameters for the request */
private pathParameters: Record<string, unknown>;
/** The request adapter to use to execute the requests. */
private requestAdapter: RequestAdapter;
/** Url template to use to build the URL for the current request builder */
private urlTemplate: string;
/** The users property */
public get users(): UsersRequestBuilder {
return new UsersRequestBuilder(this.pathParameters, this.requestAdapter);
}
Expand All @@ -36,7 +38,7 @@ export class ApiClient {
/**
* Gets an item from the ApiSdk.users.item collection
* @param id Unique identifier of the item
* @returns a userItemRequestBuilder
* @returns a UserItemRequestBuilder
*/
public usersById(id: string) : UserItemRequestBuilder {
if(!id) throw new Error("id cannot be undefined");
Expand Down
29 changes: 29 additions & 0 deletions packages/test/generatedCode/kiota-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"descriptionHash": "F596AEE180E3F5E630E95E91134E5F51300268288352AD41F209515486123F460BB400675277991DDB81462B72C196FEB70CB2E148E9209DA2AA9ADBFA8F9233",
"descriptionLocation": "https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-powershell/dev/openApiDocs/v1.0/Mail.yml",
"lockFileVersion": "1.0.0",
"kiotaVersion": "0.8.3.0",
"clientClassName": "ApiClient",
"clientNamespaceName": "ApiSdk",
"language": "TypeScript",
"usesBackingStore": false,
"includeAdditionalData": true,
"serializers": [
"Microsoft.Kiota.Serialization.Json.JsonSerializationWriterFactory",
"Microsoft.Kiota.Serialization.Text.TextSerializationWriterFactory"
],
"deserializers": [
"Microsoft.Kiota.Serialization.Json.JsonParseNodeFactory",
"Microsoft.Kiota.Serialization.Text.TextParseNodeFactory"
],
"structuredMimeTypes": [
"application/json",
"application/xml",
"text/plain",
"text/xml",
"text/yaml"
],
"includePatterns": [],
"excludePatterns": [],
"disabledValidationRules": []
}
Loading

0 comments on commit 526fe93

Please sign in to comment.