Fix compiler errors in tests and samples (#31649)
After moving to ESM/tshy, we no longer build tests/samples. This PR enables running "typecheck" as an optional rush bulk command, and fixes some of the errors found. The known errors reported on files from vite/vitest/chai are ignored. The update-snippets dev-tool command throws error of reading undefined in some cases, adding a null check fixes it. Snippets are updated as well after snippets.spec.ts files are fixed.
This commit is contained in:
Родитель
36f4f4d4ad
Коммит
cf8d25ff5e
|
@ -151,6 +151,20 @@
|
|||
"enableParallelism": true,
|
||||
"ignoreMissingScript": true
|
||||
},
|
||||
{
|
||||
"commandKind": "bulk",
|
||||
"name": "typecheck",
|
||||
"summary": "type check files that are not part of the build",
|
||||
"enableParallelism": true,
|
||||
"ignoreMissingScript": true
|
||||
},
|
||||
{
|
||||
"commandKind": "bulk",
|
||||
"name": "update-snippets",
|
||||
"summary": "Replace snippets placeholders with code extracted from TypeScript files",
|
||||
"enableParallelism": true,
|
||||
"ignoreMissingScript": true
|
||||
},
|
||||
{
|
||||
"commandKind": "bulk",
|
||||
"name": "lint:fix",
|
||||
|
|
|
@ -28,6 +28,10 @@ export default leafCommand(commandInfo, async (options) => {
|
|||
|
||||
const project = new Project({
|
||||
tsConfigFilePath: path.join(projPath, "tsconfig.json"),
|
||||
compilerOptions: {
|
||||
noUnusedLocals: false,
|
||||
noUnusedParameters: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (options.paths) {
|
||||
|
@ -39,7 +43,17 @@ export default leafCommand(commandInfo, async (options) => {
|
|||
}
|
||||
}
|
||||
|
||||
const diagnostics = project.getPreEmitDiagnostics();
|
||||
const diagnostics = project.getPreEmitDiagnostics().filter((d) =>
|
||||
{
|
||||
const filepath = d.getSourceFile()?.getFilePath();
|
||||
return !(
|
||||
filepath?.includes("node_modules") &&
|
||||
(filepath?.includes("@vitest") ||
|
||||
filepath?.includes("vite-node") ||
|
||||
filepath?.includes("chai"))
|
||||
);
|
||||
},
|
||||
);
|
||||
const hasError = diagnostics.some((d) => d.getCategory() === DiagnosticCategory.Error);
|
||||
if (hasError) {
|
||||
log.error(
|
||||
|
|
|
@ -385,7 +385,10 @@ async function parseSnippetDefinitions(
|
|||
// Get all the decls that are in source files and where the decl comes from an import clause.
|
||||
return sym?.declarations
|
||||
?.filter(
|
||||
(decl) => decl.getSourceFile() === sourceFile && ts.isImportClause(decl.parent.parent),
|
||||
(decl) =>
|
||||
decl.getSourceFile() === sourceFile &&
|
||||
decl.parent?.parent &&
|
||||
ts.isImportClause(decl.parent.parent),
|
||||
)
|
||||
.map(
|
||||
// It is a grammar error for moduleSpecifier to be anything other than a string literal. In future versions of
|
||||
|
|
|
@ -44,6 +44,7 @@ declare global {
|
|||
[k: string]: string[];
|
||||
};
|
||||
};
|
||||
tshy?: Record<string, object>;
|
||||
type?: string;
|
||||
module?: string;
|
||||
bin?: Record<string, string>;
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
"devDependencies": {
|
||||
"@azure-tools/test-credential": "^1.0.0",
|
||||
"@azure-tools/test-recorder": "^4.0.0",
|
||||
"@azure-tools/test-utils": "~1.0.0",
|
||||
"@azure-tools/vite-plugin-browser-test-map": "~1.0.0",
|
||||
"@azure/core-util": "^1.0.0",
|
||||
"@azure/dev-tool": "^1.0.0",
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
// AzureCliCredential,
|
||||
InteractiveBrowserCredential,
|
||||
} from "@azure/identity";
|
||||
import { isNode } from "@azure-tools/test-utils";
|
||||
import { isNodeLike } from "@azure/core-util";
|
||||
import { NoOpCredential } from "@azure-tools/test-credential";
|
||||
import { AzureNamedKeyCredential } from "@azure/core-auth";
|
||||
|
||||
|
@ -69,7 +69,7 @@ export async function createRecorder(ctx: VitestTestContext): Promise<Recorder>
|
|||
export function createBatchClient(recorder?: Recorder, options: ClientOptions = {}): BatchClient {
|
||||
const credential = isPlaybackMode()
|
||||
? new NoOpCredential()
|
||||
: isNode
|
||||
: isNodeLike
|
||||
? new AzureNamedKeyCredential(env.AZURE_BATCH_ACCOUNT!, env.AZURE_BATCH_ACCESS_KEY!)
|
||||
: // : new AzureCliCredential();
|
||||
new InteractiveBrowserCredential({
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* try {
|
||||
* doAsyncWork({ abortSignal: controller.signal });
|
||||
* } catch (e) {
|
||||
* if (e.name === "AbortError") {
|
||||
* if (e instanceof Error && e.name === "AbortError") {
|
||||
* // handle abort error here.
|
||||
* }
|
||||
* }
|
||||
|
|
|
@ -48,7 +48,7 @@ describe("snippets", () => {
|
|||
try {
|
||||
doAsyncWork({ abortSignal: controller.signal });
|
||||
} catch (e) {
|
||||
if (e.name === "AbortError") {
|
||||
if (e instanceof Error && e.name === "AbortError") {
|
||||
// handle abort error here.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,9 +202,9 @@ export interface Client {
|
|||
* strong types. When used by the codegen this type gets overridden with the generated
|
||||
* types. For example:
|
||||
* ```typescript snippet:path_example
|
||||
* import { Client, Routes } from "@azure-rest/core-client";
|
||||
* import { Client } from "@azure-rest/core-client";
|
||||
*
|
||||
* export type MyClient = Client & {
|
||||
* type MyClient = Client & {
|
||||
* path: Routes;
|
||||
* };
|
||||
* ```
|
||||
|
|
|
@ -2,11 +2,20 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
import { describe, it } from "vitest";
|
||||
import type { Client, Routes } from "@azure-rest/core-client";
|
||||
import type { Client } from "@azure-rest/core-client";
|
||||
|
||||
interface GetOperationResult {}
|
||||
interface DetectFromUrl {}
|
||||
interface Routes {
|
||||
/** Resource for '/operations/\{operationId\}' has methods for the following verbs: get */
|
||||
(path: "/operations/{operationId}", operationId: string): GetOperationResult;
|
||||
/** Resource for '/detect' has methods for the following verbs: post */
|
||||
(path: "/detect"): DetectFromUrl;
|
||||
}
|
||||
|
||||
describe("snippets", () => {
|
||||
it("path_example", () => {
|
||||
export type MyClient = Client & {
|
||||
type MyClient = Client & {
|
||||
path: Routes;
|
||||
};
|
||||
});
|
||||
|
|
|
@ -7,7 +7,6 @@ import { describe, it } from "vitest";
|
|||
|
||||
describe("snippets", () => {
|
||||
it("authorize_request_on_claim_challenge", () => {
|
||||
// @ts-ignore
|
||||
const policy = bearerTokenAuthenticationPolicy({
|
||||
challengeCallbacks: {
|
||||
authorizeRequestOnChallenge: authorizeRequestOnClaimChallenge,
|
||||
|
|
|
@ -43,7 +43,7 @@ A poller is an object that can poll the long running operation on the server for
|
|||
A type for the operation state. It contains a `status` field with the following possible values: `notStarted`, `running`, `succeeded`, `failed`, and `canceled`. It can be accessed as follows:
|
||||
|
||||
```typescript snippet:operation_state
|
||||
switch (poller.getOperationState().status) {
|
||||
switch (poller.operationState.status) {
|
||||
case "succeeded": // return poller.getResult();
|
||||
case "failed": // throw poller.getOperationState().error;
|
||||
case "canceled": // throw new Error("Operation was canceled");
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { PollerLike } from "@azure/core-lro";
|
||||
import { describe, it } from "vitest";
|
||||
|
||||
const poller = {} as unknown as PollerLike<any, any>;
|
||||
describe("snippets", () => {
|
||||
it("operation_state", async () => {
|
||||
switch (poller.getOperationState().status) {
|
||||
switch (poller.operationState.status) {
|
||||
case "succeeded": // return poller.getResult();
|
||||
case "failed": // throw poller.getOperationState().error;
|
||||
case "canceled": // throw new Error("Operation was canceled");
|
||||
|
|
|
@ -24,10 +24,12 @@ You can find an explanation of how this repository's code works by going to our
|
|||
Example of building with the types:
|
||||
|
||||
```typescript snippet:paging_example
|
||||
import { PagedAsyncIterableIterator, PageSettings } from "@azure/core-paging";
|
||||
|
||||
function listSecrets(
|
||||
options: ListSecretsOptions = {},
|
||||
): PagedAsyncIterableIterator<SecretAttributes> {
|
||||
const iter = this.listSecretsAll(options);
|
||||
const iter = listSecretsAll(options);
|
||||
return {
|
||||
async next() {
|
||||
return iter.next();
|
||||
|
@ -35,7 +37,7 @@ function listSecrets(
|
|||
[Symbol.asyncIterator]() {
|
||||
return this;
|
||||
},
|
||||
byPage: (settings: PageSettings = {}) => this.listSecretsPage(settings, options),
|
||||
byPage: (settings: PageSettings = {}) => listSecretsPage(settings, options),
|
||||
};
|
||||
}
|
||||
for await (const page of listSecrets().byPage({ maxPageSize: 2 })) {
|
||||
|
|
|
@ -2,13 +2,26 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
import { describe, it } from "vitest";
|
||||
import { PagedAsyncIterableIterator, PageSettings } from "@azure/core-paging";
|
||||
|
||||
interface ListSecretsOptions {}
|
||||
interface SecretAttributes {}
|
||||
function listSecretsAll(options: ListSecretsOptions): AsyncIterableIterator<SecretAttributes> {
|
||||
throw "stub";
|
||||
}
|
||||
function listSecretsPage(
|
||||
pageSettings: PageSettings,
|
||||
options: ListSecretsOptions,
|
||||
): AsyncIterableIterator<SecretAttributes[]> {
|
||||
throw "stub";
|
||||
}
|
||||
|
||||
describe("snippets", () => {
|
||||
it("paging_example", () => {
|
||||
it("paging_example", async () => {
|
||||
function listSecrets(
|
||||
options: ListSecretsOptions = {},
|
||||
): PagedAsyncIterableIterator<SecretAttributes> {
|
||||
const iter = this.listSecretsAll(options);
|
||||
const iter = listSecretsAll(options);
|
||||
return {
|
||||
async next() {
|
||||
return iter.next();
|
||||
|
@ -16,7 +29,7 @@ describe("snippets", () => {
|
|||
[Symbol.asyncIterator]() {
|
||||
return this;
|
||||
},
|
||||
byPage: (settings: PageSettings = {}) => this.listSecretsPage(settings, options),
|
||||
byPage: (settings: PageSettings = {}) => listSecretsPage(settings, options),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,9 @@ A `PipelineResponse` describes the HTTP response (body, headers, and status code
|
|||
A `SendRequest` method is a method that given a `PipelineRequest` can asynchronously return a `PipelineResponse`.
|
||||
|
||||
```ts snippet:send_request
|
||||
export type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
import { PipelineRequest, PipelineResponse } from "@azure/core-rest-pipeline";
|
||||
|
||||
type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
```
|
||||
|
||||
### HttpClient
|
||||
|
@ -40,7 +42,9 @@ export type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse
|
|||
An `HttpClient` is any object that satisfies the following interface to implement a `SendRequest` method:
|
||||
|
||||
```ts snippet:http_request
|
||||
export interface HttpClient {
|
||||
import { SendRequest } from "@azure/core-rest-pipeline";
|
||||
|
||||
interface HttpClient {
|
||||
/**
|
||||
* The method that makes the request and returns a response.
|
||||
*/
|
||||
|
@ -55,7 +59,9 @@ export interface HttpClient {
|
|||
A `PipelinePolicy` is a simple object that implements the following interface:
|
||||
|
||||
```ts snippet:pipeline_policy
|
||||
export interface PipelinePolicy {
|
||||
import { PipelineRequest, SendRequest, PipelineResponse } from "@azure/core-rest-pipeline";
|
||||
|
||||
interface PipelinePolicy {
|
||||
/**
|
||||
* The policy name. Must be a unique string in the pipeline.
|
||||
*/
|
||||
|
@ -76,13 +82,15 @@ One can view the role of policies as that of `middleware`, a concept that is fam
|
|||
The `sendRequest` implementation can both transform the outgoing request as well as the incoming response:
|
||||
|
||||
```ts snippet:custom_policy
|
||||
import { PipelineRequest, SendRequest, PipelineResponse } from "@azure/core-rest-pipeline";
|
||||
|
||||
const customPolicy = {
|
||||
name: "My wonderful policy",
|
||||
async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {
|
||||
// Change the outgoing request by adding a new header
|
||||
request.headers.set("X-Cool-Header", 42);
|
||||
const result = await next(request);
|
||||
if (response.status === 403) {
|
||||
if (result.status === 403) {
|
||||
// Do something special if this policy sees Forbidden
|
||||
}
|
||||
return result;
|
||||
|
@ -101,8 +109,17 @@ You can think of policies being applied like a stack (first-in/last-out.) The fi
|
|||
A `Pipeline` satisfies the following interface:
|
||||
|
||||
```ts snippet:pipeline
|
||||
export interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPolicyOptions): void;
|
||||
import {
|
||||
PipelinePolicy,
|
||||
AddPipelineOptions,
|
||||
PipelinePhase,
|
||||
HttpClient,
|
||||
PipelineRequest,
|
||||
PipelineResponse,
|
||||
} from "@azure/core-rest-pipeline";
|
||||
|
||||
interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPipelineOptions): void;
|
||||
removePolicy(options: { name?: string; phase?: PipelinePhase }): PipelinePolicy[];
|
||||
sendRequest(httpClient: HttpClient, request: PipelineRequest): Promise<PipelineResponse>;
|
||||
getOrderedPolicies(): PipelinePolicy[];
|
||||
|
@ -124,7 +141,9 @@ Phases occur in the above order, with serialization policies being applied first
|
|||
When adding a policy to the pipeline you can specify not only what phase a policy is in, but also if it has any dependencies:
|
||||
|
||||
```ts snippet:add_policy_options
|
||||
export interface AddPolicyOptions {
|
||||
import { PipelinePhase } from "@azure/core-rest-pipeline";
|
||||
|
||||
interface AddPipelineOptions {
|
||||
beforePolicies?: string[];
|
||||
afterPolicies?: string[];
|
||||
afterPhase?: PipelinePhase;
|
||||
|
|
|
@ -19,7 +19,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle an empty process.versions", async () => {
|
||||
vi.mocked(process).versions = undefined;
|
||||
(vi.mocked(process) as any).versions = undefined;
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
@ -31,7 +31,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle a Node.js process.versions with Bun", async () => {
|
||||
vi.mocked(process).versions = { bun: "1.0.0" };
|
||||
(vi.mocked(process) as any).versions = { bun: "1.0.0" };
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
@ -44,7 +44,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle a Node.js process.versions with Deno", async () => {
|
||||
vi.mocked(process).versions = { deno: "2.0.0" };
|
||||
(vi.mocked(process) as any).versions = { deno: "2.0.0" };
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
@ -57,7 +57,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle a Node.js process.versions", async () => {
|
||||
vi.mocked(process).versions = { node: "20.0.0" };
|
||||
(vi.mocked(process) as any).versions = { node: "20.0.0" };
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
|
|
@ -2,14 +2,23 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
import { describe, it } from "vitest";
|
||||
import {
|
||||
AddPipelineOptions,
|
||||
HttpClient,
|
||||
PipelinePhase,
|
||||
PipelinePolicy,
|
||||
PipelineRequest,
|
||||
PipelineResponse,
|
||||
SendRequest,
|
||||
} from "@azure/core-rest-pipeline";
|
||||
|
||||
describe("snippets", () => {
|
||||
it("send_request", () => {
|
||||
export type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
});
|
||||
|
||||
it("http_request", () => {
|
||||
export interface HttpClient {
|
||||
interface HttpClient {
|
||||
/**
|
||||
* The method that makes the request and returns a response.
|
||||
*/
|
||||
|
@ -18,7 +27,7 @@ describe("snippets", () => {
|
|||
});
|
||||
|
||||
it("pipeline_policy", () => {
|
||||
export interface PipelinePolicy {
|
||||
interface PipelinePolicy {
|
||||
/**
|
||||
* The policy name. Must be a unique string in the pipeline.
|
||||
*/
|
||||
|
@ -40,7 +49,7 @@ describe("snippets", () => {
|
|||
// Change the outgoing request by adding a new header
|
||||
request.headers.set("X-Cool-Header", 42);
|
||||
const result = await next(request);
|
||||
if (response.status === 403) {
|
||||
if (result.status === 403) {
|
||||
// Do something special if this policy sees Forbidden
|
||||
}
|
||||
return result;
|
||||
|
@ -49,8 +58,8 @@ describe("snippets", () => {
|
|||
});
|
||||
|
||||
it("pipeline", () => {
|
||||
export interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPolicyOptions): void;
|
||||
interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPipelineOptions): void;
|
||||
removePolicy(options: { name?: string; phase?: PipelinePhase }): PipelinePolicy[];
|
||||
sendRequest(httpClient: HttpClient, request: PipelineRequest): Promise<PipelineResponse>;
|
||||
getOrderedPolicies(): PipelinePolicy[];
|
||||
|
@ -59,7 +68,7 @@ describe("snippets", () => {
|
|||
});
|
||||
|
||||
it("add_policy_options", () => {
|
||||
export interface AddPolicyOptions {
|
||||
interface AddPipelineOptions {
|
||||
beforePolicies?: string[];
|
||||
afterPolicies?: string[];
|
||||
afterPhase?: PipelinePhase;
|
||||
|
|
|
@ -80,7 +80,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@azure-rest/core-client": "^2.2.0",
|
||||
"@azure-tools/test-utils": "^1.0.1",
|
||||
"@azure-tools/test-utils-vitest": "^1.0.0",
|
||||
"@azure-tools/vite-plugin-browser-test-map": "^1.0.0",
|
||||
"@azure/dev-tool": "^1.0.0",
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
import { createSseStream } from "../../../src/index.js";
|
||||
import { Client, getClient } from "@azure-rest/core-client";
|
||||
import { assert, beforeAll, beforeEach, afterEach, describe, it } from "vitest";
|
||||
import { port } from "../../server/config.mts";
|
||||
import { port } from "../../server/config.mjs";
|
||||
import { IncomingMessage } from "http";
|
||||
import { matrix } from "@azure-tools/test-utils";
|
||||
import { matrix } from "@azure-tools/test-utils-vitest";
|
||||
|
||||
const contentType = "text/event-stream";
|
||||
function getEndpoint(): string {
|
||||
|
|
|
@ -5,7 +5,7 @@ import { describe, it } from "vitest";
|
|||
import { createTracingClient } from "@azure/core-tracing";
|
||||
|
||||
describe("snippets", () => {
|
||||
it("with_span_example", () => {
|
||||
it("with_span_example", async () => {
|
||||
const tracingClient = createTracingClient({
|
||||
namespace: "test.namespace",
|
||||
packageName: "test-package",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
import { setLogLevel, AzureLogger } from "@azure/logger";
|
||||
import { describe, it, assert } from "vitest";
|
||||
import { describe, it } from "vitest";
|
||||
|
||||
describe("snippets", () => {
|
||||
it("basic_usage", () => {
|
||||
|
|
|
@ -32,9 +32,9 @@ A `PipelineResponse` describes the HTTP response (body, headers, and status code
|
|||
A `SendRequest` method is a method that given a `PipelineRequest` can asynchronously return a `PipelineResponse`.
|
||||
|
||||
```ts snippet:send_request
|
||||
import { PipelineResponse } from "@typespec/ts-http-runtime";
|
||||
import { PipelineRequest, PipelineResponse } from "@typespec/ts-http-runtime";
|
||||
|
||||
export type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
```
|
||||
|
||||
### HttpClient
|
||||
|
@ -42,7 +42,9 @@ export type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse
|
|||
An `HttpClient` is any object that satisfies the following interface to implement a `SendRequest` method:
|
||||
|
||||
```ts snippet:http_request
|
||||
export interface HttpClient {
|
||||
import { SendRequest } from "@typespec/ts-http-runtime";
|
||||
|
||||
interface HttpClient {
|
||||
/**
|
||||
* The method that makes the request and returns a response.
|
||||
*/
|
||||
|
@ -57,9 +59,9 @@ export interface HttpClient {
|
|||
A `PipelinePolicy` is a simple object that implements the following interface:
|
||||
|
||||
```ts snippet:pipeline_policy
|
||||
import { PipelineResponse } from "@typespec/ts-http-runtime";
|
||||
import { PipelineRequest, SendRequest, PipelineResponse } from "@typespec/ts-http-runtime";
|
||||
|
||||
export interface PipelinePolicy {
|
||||
interface PipelinePolicy {
|
||||
/**
|
||||
* The policy name. Must be a unique string in the pipeline.
|
||||
*/
|
||||
|
@ -80,7 +82,7 @@ One can view the role of policies as that of `middleware`, a concept that is fam
|
|||
The `sendRequest` implementation can both transform the outgoing request as well as the incoming response:
|
||||
|
||||
```ts snippet:custom_policy
|
||||
import { PipelineResponse } from "@typespec/ts-http-runtime";
|
||||
import { PipelineRequest, SendRequest, PipelineResponse } from "@typespec/ts-http-runtime";
|
||||
|
||||
const customPolicy = {
|
||||
name: "My wonderful policy",
|
||||
|
@ -88,7 +90,7 @@ const customPolicy = {
|
|||
// Change the outgoing request by adding a new header
|
||||
request.headers.set("X-Cool-Header", 42);
|
||||
const result = await next(request);
|
||||
if (response.status === 403) {
|
||||
if (result.status === 403) {
|
||||
// Do something special if this policy sees Forbidden
|
||||
}
|
||||
return result;
|
||||
|
@ -107,10 +109,17 @@ You can think of policies being applied like a stack (first-in/last-out.) The fi
|
|||
A `Pipeline` satisfies the following interface:
|
||||
|
||||
```ts snippet:pipeline
|
||||
import { PipelineResponse } from "@typespec/ts-http-runtime";
|
||||
import {
|
||||
PipelinePolicy,
|
||||
AddPipelineOptions,
|
||||
PipelinePhase,
|
||||
HttpClient,
|
||||
PipelineRequest,
|
||||
PipelineResponse,
|
||||
} from "@typespec/ts-http-runtime";
|
||||
|
||||
export interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPolicyOptions): void;
|
||||
interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPipelineOptions): void;
|
||||
removePolicy(options: { name?: string; phase?: PipelinePhase }): PipelinePolicy[];
|
||||
sendRequest(httpClient: HttpClient, request: PipelineRequest): Promise<PipelineResponse>;
|
||||
getOrderedPolicies(): PipelinePolicy[];
|
||||
|
@ -132,7 +141,9 @@ Phases occur in the above order, with serialization policies being applied first
|
|||
When adding a policy to the pipeline you can specify not only what phase a policy is in, but also if it has any dependencies:
|
||||
|
||||
```ts snippet:add_policy_options
|
||||
export interface AddPolicyOptions {
|
||||
import { PipelinePhase } from "@typespec/ts-http-runtime";
|
||||
|
||||
interface AddPipelineOptions {
|
||||
beforePolicies?: string[];
|
||||
afterPolicies?: string[];
|
||||
afterPhase?: PipelinePhase;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/src/abort-controller/AbortError.ts b/src/abort-controller/AbortError.ts
|
||||
index 053733c..31dd275 100644
|
||||
index 60662ec..1c6cf1a 100644
|
||||
--- a/src/abort-controller/AbortError.ts
|
||||
+++ b/src/abort-controller/AbortError.ts
|
||||
@@ -8,7 +8,7 @@
|
||||
|
@ -464,7 +464,7 @@ index 30dac33..66ea99c 100644
|
|||
if (!cachedHttpClient) {
|
||||
cachedHttpClient = createDefaultHttpClient();
|
||||
diff --git a/src/client/common.ts b/src/client/common.ts
|
||||
index 4e49dde..f43f7c1 100644
|
||||
index 026f516..edda1c6 100644
|
||||
--- a/src/client/common.ts
|
||||
+++ b/src/client/common.ts
|
||||
@@ -3,19 +3,18 @@
|
||||
|
@ -517,10 +517,10 @@ index 4e49dde..f43f7c1 100644
|
|||
* strong types. When used by the codegen this type gets overridden with the generated
|
||||
* types. For example:
|
||||
* ```typescript snippet:path_example
|
||||
- * import { Client, Routes } from "@azure-rest/core-client";
|
||||
+ * import { Client, Routes } from "@typespec/ts-http-runtime";
|
||||
- * import { Client } from "@azure-rest/core-client";
|
||||
+ * import { Client } from "@typespec/ts-http-runtime";
|
||||
*
|
||||
* export type MyClient = Client & {
|
||||
* type MyClient = Client & {
|
||||
* path: Routes;
|
||||
@@ -326,11 +318,9 @@ export type ClientOptions = PipelineOptions & {
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* try {
|
||||
* doAsyncWork({ abortSignal: controller.signal });
|
||||
* } catch (e) {
|
||||
* if (e.name === "AbortError") {
|
||||
* if (e instanceof Error && e.name === "AbortError") {
|
||||
* // handle abort error here.
|
||||
* }
|
||||
* }
|
||||
|
|
|
@ -194,9 +194,9 @@ export interface Client {
|
|||
* strong types. When used by the codegen this type gets overridden with the generated
|
||||
* types. For example:
|
||||
* ```typescript snippet:path_example
|
||||
* import { Client, Routes } from "@typespec/ts-http-runtime";
|
||||
* import { Client } from "@typespec/ts-http-runtime";
|
||||
*
|
||||
* export type MyClient = Client & {
|
||||
* type MyClient = Client & {
|
||||
* path: Routes;
|
||||
* };
|
||||
* ```
|
||||
|
|
|
@ -19,7 +19,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle an empty process.versions", async () => {
|
||||
vi.mocked(process).versions = undefined;
|
||||
(vi.mocked(process) as any).versions = undefined;
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
@ -31,7 +31,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle a Node.js process.versions with Bun", async () => {
|
||||
vi.mocked(process).versions = { bun: "1.0.0" };
|
||||
(vi.mocked(process) as any).versions = { bun: "1.0.0" };
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
@ -44,7 +44,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle a Node.js process.versions with Deno", async () => {
|
||||
vi.mocked(process).versions = { deno: "2.0.0" };
|
||||
(vi.mocked(process) as any).versions = { deno: "2.0.0" };
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
@ -57,7 +57,7 @@ describe("userAgentPlatform", () => {
|
|||
});
|
||||
|
||||
it("should handle a Node.js process.versions", async () => {
|
||||
vi.mocked(process).versions = { node: "20.0.0" };
|
||||
(vi.mocked(process) as any).versions = { node: "20.0.0" };
|
||||
const map = new Map<string, string>();
|
||||
|
||||
await setPlatformSpecificData(map);
|
||||
|
|
|
@ -1,17 +1,37 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
/* eslint "@typescript-eslint/no-shadow": "off" */
|
||||
|
||||
import { describe, it, assert } from "vitest";
|
||||
import type { Client, PipelineResponse, Routes } from "@typespec/ts-http-runtime";
|
||||
import type {
|
||||
HttpClient,
|
||||
PipelinePhase,
|
||||
PipelinePolicy,
|
||||
PipelineRequest,
|
||||
PipelineResponse,
|
||||
SendRequest,
|
||||
AddPipelineOptions,
|
||||
Client,
|
||||
} from "@typespec/ts-http-runtime";
|
||||
import { AbortError, createTracingClient } from "@typespec/ts-http-runtime";
|
||||
|
||||
interface GetOperationResult {}
|
||||
interface DetectFromUrl {}
|
||||
interface Routes {
|
||||
/** Resource for '/operations/\{operationId\}' has methods for the following verbs: get */
|
||||
(path: "/operations/{operationId}", operationId: string): GetOperationResult;
|
||||
/** Resource for '/detect' has methods for the following verbs: post */
|
||||
(path: "/detect"): DetectFromUrl;
|
||||
}
|
||||
|
||||
describe("snippets", () => {
|
||||
it("send_request", () => {
|
||||
export type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
|
||||
});
|
||||
|
||||
it("http_request", () => {
|
||||
export interface HttpClient {
|
||||
interface HttpClient {
|
||||
/**
|
||||
* The method that makes the request and returns a response.
|
||||
*/
|
||||
|
@ -20,7 +40,7 @@ describe("snippets", () => {
|
|||
});
|
||||
|
||||
it("pipeline_policy", () => {
|
||||
export interface PipelinePolicy {
|
||||
interface PipelinePolicy {
|
||||
/**
|
||||
* The policy name. Must be a unique string in the pipeline.
|
||||
*/
|
||||
|
@ -42,7 +62,7 @@ describe("snippets", () => {
|
|||
// Change the outgoing request by adding a new header
|
||||
request.headers.set("X-Cool-Header", 42);
|
||||
const result = await next(request);
|
||||
if (response.status === 403) {
|
||||
if (result.status === 403) {
|
||||
// Do something special if this policy sees Forbidden
|
||||
}
|
||||
return result;
|
||||
|
@ -51,8 +71,8 @@ describe("snippets", () => {
|
|||
});
|
||||
|
||||
it("pipeline", () => {
|
||||
export interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPolicyOptions): void;
|
||||
interface Pipeline {
|
||||
addPolicy(policy: PipelinePolicy, options?: AddPipelineOptions): void;
|
||||
removePolicy(options: { name?: string; phase?: PipelinePhase }): PipelinePolicy[];
|
||||
sendRequest(httpClient: HttpClient, request: PipelineRequest): Promise<PipelineResponse>;
|
||||
getOrderedPolicies(): PipelinePolicy[];
|
||||
|
@ -61,7 +81,7 @@ describe("snippets", () => {
|
|||
});
|
||||
|
||||
it("add_policy_options", () => {
|
||||
export interface AddPolicyOptions {
|
||||
interface AddPipelineOptions {
|
||||
beforePolicies?: string[];
|
||||
afterPolicies?: string[];
|
||||
afterPhase?: PipelinePhase;
|
||||
|
@ -83,19 +103,19 @@ describe("snippets", () => {
|
|||
try {
|
||||
doAsyncWork({ abortSignal: controller.signal });
|
||||
} catch (e) {
|
||||
if (e.name === "AbortError") {
|
||||
if (e instanceof Error && e.name === "AbortError") {
|
||||
// handle abort error here.
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("path_example", () => {
|
||||
export type MyClient = Client & {
|
||||
type MyClient = Client & {
|
||||
path: Routes;
|
||||
};
|
||||
});
|
||||
|
||||
it("with_span_example", () => {
|
||||
it("with_span_example", async () => {
|
||||
const tracingClient = createTracingClient({
|
||||
namespace: "test.namespace",
|
||||
packageName: "test-package",
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
KnownKeyVaultRoleScope,
|
||||
} from "@azure/keyvault-admin";
|
||||
import { DefaultAzureCredential } from "@azure/identity";
|
||||
import * as uuid from "uuid";
|
||||
import { randomUUID } from "@azure/core-util";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
|
@ -34,7 +34,7 @@ export async function main(): Promise<void> {
|
|||
}
|
||||
|
||||
const globalScope = KnownKeyVaultRoleScope.Global;
|
||||
const roleDefinitionName = uuid.v4();
|
||||
const roleDefinitionName = randomUUID();
|
||||
const permissions: KeyVaultPermission[] = [
|
||||
{
|
||||
dataActions: [
|
||||
|
@ -53,7 +53,7 @@ export async function main(): Promise<void> {
|
|||
|
||||
// This sample uses a custom role but you may assign one of the many built-in roles.
|
||||
// Please refer to https://docs.microsoft.com/azure/key-vault/managed-hsm/built-in-roles for more information.
|
||||
const roleAssignmentName = uuid.v4();
|
||||
const roleAssignmentName = randomUUID();
|
||||
const clientObjectId = process.env["CLIENT_OBJECT_ID"];
|
||||
if (!clientObjectId) {
|
||||
throw new Error("Missing environment variable CLIENT_OBJECT_ID.");
|
||||
|
|
|
@ -10,7 +10,7 @@ import { authenticate, envSetupForPlayback } from "../utils/testAuthentication.j
|
|||
import type TestClient from "../utils/testClient.js";
|
||||
import { stringToUint8Array, uint8ArrayToString } from "./../utils/crypto.js";
|
||||
import { RsaCryptographyProvider } from "../../../src/cryptography/rsaCryptographyProvider.js";
|
||||
import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { describe, it, assert, expect, beforeEach, afterEach } from "vitest";
|
||||
|
||||
import { toSupportTracing } from "@azure-tools/test-utils-vitest";
|
||||
|
||||
|
@ -139,7 +139,7 @@ describe("CryptographyClient (all decrypts happen remotely)", () => {
|
|||
assert.equal(text, decryptedText);
|
||||
});
|
||||
|
||||
it("wrap and unwrap with rsa1_5", async function () {
|
||||
it("wrap and unwrap with rsa1_5", async function (ctx) {
|
||||
if (!isLiveMode()) {
|
||||
console.log(
|
||||
"Wrapping and unwrapping don't cause a repeatable pattern, so these tests can only run in playback mode",
|
||||
|
@ -308,7 +308,7 @@ describe("CryptographyClient (all decrypts happen remotely)", () => {
|
|||
assert.equal(text, unwrappedText);
|
||||
});
|
||||
|
||||
it("sign and verify with RS256 through an RSA-HSM key", async function (ctx): Promise<void> {
|
||||
it("sign and verify with RS256 through an RSA-HSM key", async function (): Promise<void> {
|
||||
const signatureValue = Buffer.from("My Message");
|
||||
const hash = createHash("sha256");
|
||||
hash.update(signatureValue);
|
||||
|
@ -325,7 +325,7 @@ describe("CryptographyClient (all decrypts happen remotely)", () => {
|
|||
assert.ok(verifyResult.result);
|
||||
});
|
||||
|
||||
it("sign and verify with RS384 through an RSA-HSM key", async function (ctx): Promise<void> {
|
||||
it("sign and verify with RS384 through an RSA-HSM key", async function (): Promise<void> {
|
||||
const signatureValue = Buffer.from("My Message");
|
||||
const hash = createHash("sha384");
|
||||
hash.update(signatureValue);
|
||||
|
@ -356,7 +356,7 @@ describe("CryptographyClient (all decrypts happen remotely)", () => {
|
|||
["P-384", "ES384", "SHA384"],
|
||||
["P-521", "ES512", "SHA512"],
|
||||
] as const) {
|
||||
it(`sign / signData and verify / verifyData using ${signatureAlgorithm}`, async function (ctx) {
|
||||
it(`sign / signData and verify / verifyData using ${signatureAlgorithm}`, async function () {
|
||||
keyVaultKey = await client.createEcKey(keyName, { curve: keyCurve });
|
||||
// Implicitly test the getCryptographyClient method here
|
||||
cryptoClient = client.getCryptographyClient(
|
||||
|
|
|
@ -41,6 +41,7 @@ import type {
|
|||
RequestData,
|
||||
TelemetryExceptionData,
|
||||
MessageData,
|
||||
MonitorDomain,
|
||||
} from "../../src/generated/index.js";
|
||||
import { KnownContextTagKeys } from "../../src/generated/index.js";
|
||||
import type { TelemetryItem as Envelope } from "../../src/generated/index.js";
|
||||
|
|
Загрузка…
Ссылка в новой задаче