diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 5718fd4a9037..dd4d4d3912c4 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -4479,6 +4479,40 @@ packages: vitest: 1.6.0(@types/node@18.19.60)(@vitest/browser@1.6.0) dev: false + /@vitest/browser@2.1.4(@types/node@18.19.60)(playwright@1.48.2)(typescript@5.5.4)(vitest@2.1.4): + resolution: {integrity: sha512-89SrvShW6kWzmEYtBj5k1gBq88emoC2qrngw5hE1vNpRFteQ5/1URbKIVww391rIALTpzhhCt5yJt5tjLPZxYw==} + peerDependencies: + playwright: '*' + safaridriver: '*' + vitest: 2.1.4 + webdriverio: '*' + peerDependenciesMeta: + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@testing-library/dom': 10.4.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/mocker': 2.1.4(msw@2.5.2) + '@vitest/utils': 2.1.4 + magic-string: 0.30.12 + msw: 2.5.2(@types/node@18.19.60)(typescript@5.5.4) + playwright: 1.48.2 + sirv: 3.0.0 + tinyrainbow: 1.2.0 + vitest: 2.1.4(@types/node@18.19.60)(@vitest/browser@2.1.4) + ws: 8.18.0 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - typescript + - utf-8-validate + - vite + dev: false + /@vitest/browser@2.1.4(@types/node@18.19.60)(playwright@1.48.2)(typescript@5.6.3)(vitest@2.1.4): resolution: {integrity: sha512-89SrvShW6kWzmEYtBj5k1gBq88emoC2qrngw5hE1vNpRFteQ5/1URbKIVww391rIALTpzhhCt5yJt5tjLPZxYw==} peerDependencies: @@ -8488,6 +8522,39 @@ packages: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: false + /msw@2.5.2(@types/node@18.19.60)(typescript@5.5.4): + resolution: {integrity: sha512-eBsFgU30NYtrfC62XzS1rdAzFK+Br0zKU4ORqD9Qliq86362DWZyPiD6FLfMgy0Ktik83DPTXmqPMz2bqwmJdA==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@bundled-es-modules/cookie': 2.0.0 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.0.1(@types/node@18.19.60) + '@mswjs/interceptors': 0.36.6 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + chalk: 4.1.2 + graphql: 16.9.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + strict-event-emitter: 0.5.1 + type-fest: 4.26.1 + typescript: 5.5.4 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + dev: false + /msw@2.5.2(@types/node@18.19.60)(typescript@5.6.3): resolution: {integrity: sha512-eBsFgU30NYtrfC62XzS1rdAzFK+Br0zKU4ORqD9Qliq86362DWZyPiD6FLfMgy0Ktik83DPTXmqPMz2bqwmJdA==} engines: {node: '>=18'} @@ -20889,26 +20956,30 @@ packages: dev: false file:projects/health-deidentification.tgz: - resolution: {integrity: sha512-6LdN/I3/IT+r5A4w8Ac5rRXYnfUzCGhSyEhSq0zB1vEsyX0oOz5viCnGYYqmiyOOfGvgqaMBOk4KwrCCeMcTOA==, tarball: file:projects/health-deidentification.tgz} + resolution: {integrity: sha512-w5eKRoH+bP36aQEual+1VQC/1Y6lgkzEaVxUHTac619etV7C3UMQqhMxMyO9tPSGb+nwEAhV0spizPX0ULkWJw==, tarball: file:projects/health-deidentification.tgz} name: '@rush-temp/health-deidentification' version: 0.0.0 dependencies: + '@microsoft/api-extractor': 7.47.11(@types/node@18.19.60) '@types/node': 18.19.60 - '@vitest/browser': 2.1.4(@types/node@18.19.60)(playwright@1.48.2)(typescript@5.6.3)(vitest@2.1.4) + '@vitest/browser': 2.1.4(@types/node@18.19.60)(playwright@1.48.2)(typescript@5.5.4)(vitest@2.1.4) '@vitest/coverage-istanbul': 2.1.4(vitest@2.1.4) dotenv: 16.4.5 - eslint: 9.13.0 + eslint: 8.57.1 loupe: 3.1.2 + mkdirp: 3.0.1 playwright: 1.48.2 + prettier: 3.3.3 + rimraf: 5.0.10 + tshy: 1.18.0 tslib: 2.8.0 - typescript: 5.6.3 + typescript: 5.5.4 vitest: 2.1.4(@types/node@18.19.60)(@vitest/browser@2.1.4) transitivePeerDependencies: - '@edge-runtime/vm' - '@vitest/ui' - bufferutil - happy-dom - - jiti - jsdom - less - lightningcss @@ -22057,7 +22128,7 @@ packages: dev: false file:projects/monitor-query.tgz: - resolution: {integrity: sha512-HkkRUizRaOlpop0fq+/U++wYFe5iDv35zb3pwyLvCaYPja0tga3qIa8yKCYBUhipRbNhIXnnnjeWuSElJ2KTKg==, tarball: file:projects/monitor-query.tgz} + resolution: {integrity: sha512-q8yL4hV7Lzv4J8wDJcNBuIaeZfVGGpNfDhqQ+EuTzX4zXlJbks7OBa24nIgQAkW+Og1E5nsP2X+UnHrabKJq2g==, tarball: file:projects/monitor-query.tgz} name: '@rush-temp/monitor-query' version: 0.0.0 dependencies: @@ -22105,7 +22176,6 @@ packages: - less - lightningcss - msw - - rollup - safaridriver - sass - sass-embedded diff --git a/sdk/healthdataaiservices/azure-health-deidentification/CHANGELOG.md b/sdk/healthdataaiservices/azure-health-deidentification/CHANGELOG.md index f5986a61661e..7f9b928ff802 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/CHANGELOG.md +++ b/sdk/healthdataaiservices/azure-health-deidentification/CHANGELOG.md @@ -1,9 +1,7 @@ -# Release History - -## 1.0.0-beta.1 (2024-08-15) - -- Azure Deidentification client library for JS. This package contains Microsoft Azure Deidentification client library. - +## 1.0.0-beta.1 (2024-11-01) + ### Features Added -- Azure Deidentification client library for JS. This package contains Microsoft Azure Deidentification client library. + - Added Interface DeidServicesClientOptions + - Added Type Alias DeidServicesClient + diff --git a/sdk/healthdataaiservices/azure-health-deidentification/README.md b/sdk/healthdataaiservices/azure-health-deidentification/README.md index ce0923b0f8ae..11f98866bcb4 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/README.md +++ b/sdk/healthdataaiservices/azure-health-deidentification/README.md @@ -1,12 +1,13 @@ -# Azure Deidentification REST client library for JavaScript +# Azure DeidServices REST client library for JavaScript -`@azure-rest/health-deidentification` is a managed service that enables users to tag, redact, or surrogate health data. +Health Deidentification Service + +**Please rely heavily on our [REST client docs](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/rest-clients.md) to use this library** - - Key links: - [Package (NPM)](https://www.npmjs.com/package/@azure-rest/health-deidentification) +- [API reference documentation](https://docs.microsoft.com/javascript/api/@azure-rest/health-deidentification?view=azure-node-preview) ## Getting started @@ -20,69 +21,26 @@ Key links: ### Install the `@azure-rest/health-deidentification` package -Install the Azure Deidentification REST client REST client library for JavaScript with `npm`: +Install the Azure DeidServices REST client REST client library for JavaScript with `npm`: ```bash npm install @azure-rest/health-deidentification ``` -### Create and authenticate a `DeidentificationClient` +### Create and authenticate a `DeidServicesClient` To use an [Azure Active Directory (AAD) token credential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token), provide an instance of the desired credential type obtained from the [@azure/identity](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) library. -To authenticate with AAD, you must first `npm` install [`@azure/identity`](https://www.npmjs.com/package/@azure/identity) +To authenticate with AAD, you must first `npm` install [`@azure/identity`](https://www.npmjs.com/package/@azure/identity) After setup, you can choose which type of [credential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) from `@azure/identity` to use. As an example, [DefaultAzureCredential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#defaultazurecredential) can be used to authenticate the client. Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: -`AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_SECRET` - -Pull `ServiceUrl` from your created Deidentification Service. - -![Service Url Location](documentation/images/ServiceUrl_Location.png) - -Basic code snippet to create your Deidentification Client and Deidentify a string. - -```javascript -import createClient, { - DeidentificationContent, - isUnexpected, -} from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -const credential = new DefaultAzureCredential(); -const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; -const client = createClient(serviceEndpoint, credential); - -const content: DeidentificationContent = { - inputText: "Hello John!" -}; - -const response = await client.path("/deid").post({ body: content }); - -if (isUnexpected(response)) { - throw response.body.error; -} - -console.log(response.body.outputText); // Hello, Tom! -``` - -## Key concept - -Operation Modes: - -- Tag: Will return a structure of offset and length with the PHI category of the related text spans. -- Redact: Will return output text with placeholder stubbed text. ex. `[name]` -- Surrogate: Will return output text with synthetic replacements. - - `My name is John Smith` - - `My name is Tom Jones` +AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET ## Troubleshooting diff --git a/sdk/healthdataaiservices/azure-health-deidentification/api-extractor.json b/sdk/healthdataaiservices/azure-health-deidentification/api-extractor.json index 5c52d7bd991b..3ad083c82add 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/api-extractor.json +++ b/sdk/healthdataaiservices/azure-health-deidentification/api-extractor.json @@ -1,18 +1,31 @@ { "$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" }, + "docModel": { + "enabled": true + }, + "apiReport": { + "enabled": true, + "reportFolder": "./review" + }, "dtsRollup": { "enabled": true, "untrimmedFilePath": "", "publicTrimmedFilePath": "./types/health-deidentification.d.ts" }, "messages": { - "tsdocMessageReporting": { "default": { "logLevel": "none" } }, + "tsdocMessageReporting": { + "default": { + "logLevel": "none" + } + }, "extractorMessageReporting": { - "ae-missing-release-tag": { "logLevel": "none" }, - "ae-unresolved-link": { "logLevel": "none" } + "ae-missing-release-tag": { + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "none" + } } } -} +} \ No newline at end of file diff --git a/sdk/healthdataaiservices/azure-health-deidentification/assets.json b/sdk/healthdataaiservices/azure-health-deidentification/assets.json deleted file mode 100644 index 31fc3d9e152c..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/assets.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "AssetsRepo": "Azure/azure-sdk-assets", - "AssetsRepoPrefixPath": "js", - "TagPrefix": "js/healthdataaiservices/azure-health-deidentification", - "Tag": "js/healthdataaiservices/azure-health-deidentification_69c12d020a" -} diff --git a/sdk/healthdataaiservices/azure-health-deidentification/config/rush-project.json b/sdk/healthdataaiservices/azure-health-deidentification/config/rush-project.json deleted file mode 100644 index c53fef6ca15b..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/config/rush-project.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../../../common/config/rush-project.json", -} diff --git a/sdk/healthdataaiservices/azure-health-deidentification/documentation/images/ServiceUrl_Location.png b/sdk/healthdataaiservices/azure-health-deidentification/documentation/images/ServiceUrl_Location.png deleted file mode 100644 index 923747280e93..000000000000 Binary files a/sdk/healthdataaiservices/azure-health-deidentification/documentation/images/ServiceUrl_Location.png and /dev/null differ diff --git a/sdk/healthdataaiservices/azure-health-deidentification/eslint.config.mjs b/sdk/healthdataaiservices/azure-health-deidentification/eslint.config.mjs index a6244dc85716..113bdc3eaf5f 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/eslint.config.mjs +++ b/sdk/healthdataaiservices/azure-health-deidentification/eslint.config.mjs @@ -8,12 +8,10 @@ export default [ "@azure/azure-sdk/ts-apiextractor-json-types": "warn", "@azure/azure-sdk/ts-package-json-types": "warn", "@azure/azure-sdk/ts-package-json-engine-is-present": "warn", - "tsdoc/syntax": "warn", "@azure/azure-sdk/ts-package-json-module": "off", "@azure/azure-sdk/ts-package-json-files-required": "off", "@azure/azure-sdk/ts-package-json-main-is-cjs": "off", - "@azure/azure-sdk/ts-package-json-name": "warn", - "@azure/azure-sdk/ts-package-json-homepage": "warn", - }, - }, + "tsdoc/syntax": "warn" + } + } ]; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/package.json b/sdk/healthdataaiservices/azure-health-deidentification/package.json index 9e7f861696ef..e9a956a0ad32 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/package.json +++ b/sdk/healthdataaiservices/azure-health-deidentification/package.json @@ -1,7 +1,6 @@ { "name": "@azure-rest/health-deidentification", "version": "1.0.0-beta.1", - "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/healthdataaiservices/azure-health-deidentification", "description": "Health Deidentification Service", "engines": { "node": ">=18.0.0" @@ -38,7 +37,8 @@ "dist", "README.md", "LICENSE", - "review/*" + "review/*", + "CHANGELOG.md" ], "sdk-type": "client", "repository": "github:Azure/azure-sdk-for-js", @@ -49,95 +49,91 @@ "//metadata": { "constantPaths": [ { - "path": "src/deidentificationClient.ts", - "prefix": "package-version" + "path": "src/deidServicesClient.ts", + "prefix": "userAgentInfo" } - ], - "sampleConfiguration": { - "skipFolder": false, - "disableDocsMs": true, - "productName": "Health Deidentification Service", - "productSlugs": [], - "apiRefLink": "https://docs.microsoft.com/javascript/api/", - "requiredResources": { - "De-identification Service": "https://docs.microsoft.com/javascript/api/" - } - } + ] }, "dependencies": { - "@azure-rest/core-client": "^2.2.0", - "@azure/abort-controller": "^2.0.0", + "@azure-rest/core-client": "^2.1.0", "@azure/core-auth": "^1.6.0", - "@azure/core-lro": "^3.0.0", - "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.5.0", - "@azure/identity": "^4.4.0", "@azure/logger": "^1.0.0", - "dotenv": "^16.0.0", - "tslib": "^2.6.2" + "tslib": "^2.6.2", + "@azure/core-lro": "^3.0.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-paging": "^1.5.0" }, "devDependencies": { - "@azure-tools/test-credential": "^2.1.0", - "@azure-tools/test-recorder": "^4.1.0", - "@azure/core-util": "^1.9.0", - "@azure/dev-tool": "^1.0.0", - "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "dotenv": "^16.0.0", + "@microsoft/api-extractor": "^7.40.3", "@types/node": "^18.0.0", + "eslint": "^8.55.0", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "mkdirp": "^3.0.1", + "typescript": "~5.5.3", + "tshy": "^1.11.1", + "@azure/identity": "^4.2.1", "@vitest/browser": "^2.0.5", "@vitest/coverage-istanbul": "^2.0.5", - "eslint": "^9.9.0", - "loupe": "~3.1.1", "playwright": "^1.41.2", - "typescript": "~5.6.2", - "vitest": "^2.0.5" + "vitest": "^2.0.5", + "@azure-tools/test-credential": "^2.0.0", + "@azure-tools/test-recorder": "^4.0.0", + "@azure/dev-tool": "^1.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0" }, "scripts": { - "build": "npm run clean && dev-tool run build-package && dev-tool run extract-api", - "build:node": "dev-tool run build-package", - "build:samples": "echo Obsolete.", - "build:test": "echo skipped. actual commands inlined in browser test scripts", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"", - "clean": "dev-tool run vendored rimraf --glob dist dist-browser dist-esm test-dist temp types *.tgz *.log", - "execute:samples": "dev-tool samples run samples-dev", - "extract-api": "dev-tool run build-package && dev-tool run extract-api", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"", - "generate:client": "autorest --typescript ./swagger/README.md", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "integration-test:browser": "dev-tool run build-package && dev-tool run build-test && dev-tool run test:vitest --browser", - "integration-test:node": "dev-tool run build-package && dev-tool run build-test && dev-tool run test:vitest", + "clean": "rimraf --glob dist dist-browser dist-esm test-dist temp types *.tgz *.log", + "extract-api": "rimraf review && mkdirp ./review && dev-tool run extract-api", + "pack": "npm pack 2>&1", "lint": "eslint package.json api-extractor.json src test", "lint:fix": "eslint package.json api-extractor.json src test --fix --fix-type [problem,suggestion]", - "pack": "npm pack 2>&1", - "test": "npm run clean && dev-tool run build-package && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser", - "test:node": "npm run clean && dev-tool run build-package && npm run unit-test:node", "unit-test": "npm run unit-test:node && npm run unit-test:browser", - "unit-test:browser": "npm run integration-test:browser", - "unit-test:node": "npm run integration-test:node", - "update-snippets": "echo skipped" + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --browser", + "unit-test:node": "dev-tool run test:vitest", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build:samples": "echo skipped", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.{ts,cts,mts}\" \"test/**/*.{ts,cts,mts}\" \"*.{js,cjs,mjs,json}\" ", + "execute:samples": "echo skipped", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.{ts,cts,mts}\" \"test/**/*.{ts,cts,mts}\" \"*.{js,cjs,mjs,json}\" ", + "generate:client": "echo skipped", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "minify": "uglifyjs -c -m --comments --source-map \"content='./dist/index.js.map'\" -o ./dist/index.min.js ./dist/index.js", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && mkdirp ./review && dev-tool run extract-api", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test" }, "exports": { "./package.json": "./package.json", ".": { "browser": { + "source": "./src/index.ts", "types": "./dist/browser/index.d.ts", "default": "./dist/browser/index.js" }, "react-native": { + "source": "./src/index.ts", "types": "./dist/react-native/index.d.ts", "default": "./dist/react-native/index.js" }, "import": { + "source": "./src/index.ts", "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" }, "require": { + "source": "./src/index.ts", "types": "./dist/commonjs/index.d.ts", "default": "./dist/commonjs/index.js" } } }, "main": "./dist/commonjs/index.js", - "types": "./dist/commonjs/index.d.ts", - "module": "./dist/esm/index.js" -} + "types": "./dist/commonjs/index.d.ts" +} \ No newline at end of file diff --git a/sdk/healthdataaiservices/azure-health-deidentification/review/health-deidentification.api.md b/sdk/healthdataaiservices/azure-health-deidentification/review/health-deidentification.api.md index 2a20f945c003..5ed56148be0c 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/review/health-deidentification.api.md +++ b/sdk/healthdataaiservices/azure-health-deidentification/review/health-deidentification.api.md @@ -4,23 +4,23 @@ ```ts -import type { AbortSignalLike } from '@azure/abort-controller'; -import type { CancelOnProgress } from '@azure/core-lro'; -import type { Client } from '@azure-rest/core-client'; -import type { ClientOptions } from '@azure-rest/core-client'; -import type { CreateHttpPollerOptions } from '@azure/core-lro'; -import type { ErrorModel } from '@azure-rest/core-client'; -import type { ErrorResponse } from '@azure-rest/core-client'; -import type { HttpResponse } from '@azure-rest/core-client'; -import type { OperationState } from '@azure/core-lro'; -import type { Paged } from '@azure/core-paging'; -import type { PagedAsyncIterableIterator } from '@azure/core-paging'; -import type { PathUncheckedResponse } from '@azure-rest/core-client'; -import type { RawHttpHeaders } from '@azure/core-rest-pipeline'; -import type { RawHttpHeadersInput } from '@azure/core-rest-pipeline'; -import type { RequestParameters } from '@azure-rest/core-client'; -import type { StreamableMethod } from '@azure-rest/core-client'; -import type { TokenCredential } from '@azure/core-auth'; +import { AbortSignalLike } from '@azure/abort-controller'; +import { CancelOnProgress } from '@azure/core-lro'; +import { Client } from '@azure-rest/core-client'; +import { ClientOptions } from '@azure-rest/core-client'; +import { CreateHttpPollerOptions } from '@azure/core-lro'; +import { ErrorModel } from '@azure-rest/core-client'; +import { ErrorResponse } from '@azure-rest/core-client'; +import { HttpResponse } from '@azure-rest/core-client'; +import { OperationState } from '@azure/core-lro'; +import { Paged } from '@azure/core-paging'; +import { PagedAsyncIterableIterator } from '@azure/core-paging'; +import { PathUncheckedResponse } from '@azure-rest/core-client'; +import { RawHttpHeaders } from '@azure/core-rest-pipeline'; +import { RawHttpHeadersInput } from '@azure/core-rest-pipeline'; +import { RequestParameters } from '@azure-rest/core-client'; +import { StreamableMethod } from '@azure-rest/core-client'; +import { TokenCredential } from '@azure/core-auth'; // @public (undocumented) export interface CancelJob { @@ -72,7 +72,7 @@ export interface CancelJobHeaders { export type CancelJobParameters = CancelJobHeaderParam & RequestParameters; // @public -function createClient(endpointParam: string, credentials: TokenCredential, { apiVersion, ...options }?: DeidentificationClientOptions): DeidentificationClient; +function createClient(endpointParam: string, credentials: TokenCredential, { apiVersion, ...options }?: DeidServicesClientOptions): DeidServicesClient; export default createClient; // @public (undocumented) @@ -149,16 +149,6 @@ export interface CreateJobLogicalResponse extends HttpResponse { // @public (undocumented) export type CreateJobParameters = CreateJobHeaderParam & CreateJobBodyParam & RequestParameters; -// @public (undocumented) -export type DeidentificationClient = Client & { - path: Routes; -}; - -// @public -export interface DeidentificationClientOptions extends ClientOptions { - apiVersion?: string; -} - // @public export interface DeidentificationContent { dataType?: DocumentDataType; @@ -234,6 +224,16 @@ export interface DeidentifyDefaultResponse extends HttpResponse { // @public (undocumented) export type DeidentifyParameters = DeidentifyBodyParam & RequestParameters; +// @public (undocumented) +export type DeidServicesClient = Client & { + path: Routes; +}; + +// @public +export interface DeidServicesClientOptions extends ClientOptions { + apiVersion?: string; +} + // @public (undocumented) export interface DeleteJob204Headers { "x-ms-client-request-id"?: string; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/sample.env b/sdk/healthdataaiservices/azure-health-deidentification/sample.env deleted file mode 100644 index 2ff41595523b..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/sample.env +++ /dev/null @@ -1,5 +0,0 @@ -# Your De-identification Service URL can be found in the overview section of the Azure Portal. -DEID_SERVICE_ENDPOINT= -# Storage account and container name -STORAGE_ACCOUNT_NAME= -STORAGE_CONTAINER_NAME= diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/createJob.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/createJob.ts deleted file mode 100644 index 44b6b71301ad..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/createJob.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to create a job which will deidentify all files within a blob storage container filtering via a prefix. - */ - -import createClient, { - DeidentificationJob, - isUnexpected, -} from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const storageLocation = `https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net/${process.env["STORAGE_CONTAINER_NAME"]}`; - const location = storageLocation || "defaultSasUri"; - const OUTPUT_FOLDER = "_output"; - const inputPrefix = "example_patient_1"; - const client = createClient(serviceEndpoint, credential); - const jobName = "exampleJob"; - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { location, prefix: inputPrefix }, - targetLocation: { location, prefix: OUTPUT_FOLDER }, - }; - const response = await client.path("/jobs/{name}", jobName).put({ body: job }); - - if (isUnexpected(response)) { - throw response.body.error; - } - - console.log(response.body); -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/helloWorld.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/helloWorld.ts deleted file mode 100644 index c96423ff88e9..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/helloWorld.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to create a `DeidentificationClient` and then deidentify a `string` - */ - -import createClient, { - DeidentificationContent, - isUnexpected, -} from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const client = createClient(serviceEndpoint, credential); - - const content: DeidentificationContent = { - inputText: "Hello John!", - }; - - const response = await client.path("/deid").post({ body: content }); - - if (isUnexpected(response)) { - throw response.body.error; - } - - console.log(response.body.outputText); // Hello, Tom! -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/listCompletedFiles.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/listCompletedFiles.ts deleted file mode 100644 index 01e35025cffe..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/listCompletedFiles.ts +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to list files that were completed by a job. - */ - -import createClient, { - DeidentificationJob, - isUnexpected, - paginate, -} from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const storageLocation = `https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net/${process.env["STORAGE_CONTAINER_NAME"]}`; - const location = storageLocation || "defaultSasUri"; - const OUTPUT_FOLDER = "_output"; - const inputPrefix = "example_patient_1"; - const client = createClient(serviceEndpoint, credential); - const jobName = "exampleJob"; - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { location, prefix: inputPrefix }, - targetLocation: { location, prefix: OUTPUT_FOLDER }, - }; - - await client.path("/jobs/{name}", jobName).put({ body: job }); - - const response = await client.path("/jobs/{name}/documents", jobName).get(); - - if (isUnexpected(response)) { - throw response.body.error; - } - - const items = []; - const iter = paginate(client, response); - - for await (const item of iter) { - items.push(item); - } - - console.log(items); // items will contain all the completed files -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/listJobs.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/listJobs.ts deleted file mode 100644 index 99301ef9eac5..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples-dev/listJobs.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to list jobs and iterate over them in a for loop. - */ - -import createClient, { isUnexpected, paginate } from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const client = createClient(serviceEndpoint, credential); - - const response = await client.path("/jobs").get(); - - if (isUnexpected(response)) { - throw response.body.error; - } - - const items = []; - const iter = paginate(client, response); - for await (const item of iter) { - items.push(item); - } - - console.log(items); // items will contain all the jobs -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/README.md b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/README.md deleted file mode 100644 index 1bc7ba770827..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Health Deidentification Service client library samples for JavaScript (Beta) - -These sample programs show how to use the JavaScript client libraries for Health Deidentification Service in some common scenarios. - -| **File Name** | **Description** | -| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| [createJob.js][createjob] | This sample demonstrates how to create a job which will deidentify all files within a blob storage container filtering via a prefix. | -| [helloWorld.js][helloworld] | This sample demonstrates how to create a `DeidentificationClient` and then deidentify a `string` | -| [listCompletedFiles.js][listcompletedfiles] | This sample demonstrates how to list files that were completed by a job. | -| [listJobs.js][listjobs] | This sample demonstrates how to list jobs and iterate over them in a for loop. | - -## Prerequisites - -The sample programs are compatible with [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule). - -You need [an Azure subscription][freesub] and the following Azure resources to run these sample programs: - -- [De-identification Service][createinstance_de-identificationservice] - -Samples retrieve credentials to access the service endpoint from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function. - -Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README][package]. - -## Setup - -To run the samples using the published version of the package: - -1. Install the dependencies using `npm`: - -```bash -npm install -``` - -2. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically. - -3. Run whichever samples you like (note that some samples may require additional setup, see the table above): - -```bash -node createJob.js -``` - -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): - -```bash -npx cross-env DEID_SERVICE_ENDPOINT="" STORAGE_ACCOUNT_NAME="" STORAGE_CONTAINER_NAME="" node createJob.js -``` - -## Next Steps - -Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients. - -[createjob]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/createJob.js -[helloworld]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/helloWorld.js -[listcompletedfiles]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listCompletedFiles.js -[listjobs]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listJobs.js -[apiref]: https://docs.microsoft.com/javascript/api/ -[freesub]: https://azure.microsoft.com/free/ -[createinstance_de-identificationservice]: https://docs.microsoft.com/javascript/api/ -[package]: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/healthdataaiservices/azure-health-deidentification/README.md diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/createJob.js b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/createJob.js deleted file mode 100644 index cfc1a10ae227..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/createJob.js +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to create a job which will deidentify all files within a blob storage container filtering via a prefix. - */ - -const createClient = require("@azure-rest/health-deidentification").default, - { isUnexpected } = require("@azure-rest/health-deidentification"); -const { DefaultAzureCredential } = require("@azure/identity"); -require("dotenv").config(); - -async function main() { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const storageLocation = `https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net/${process.env["STORAGE_CONTAINER_NAME"]}`; - const location = storageLocation || "defaultSasUri"; - const OUTPUT_FOLDER = "_output"; - const inputPrefix = "example_patient_1"; - const client = createClient(serviceEndpoint, credential); - const jobName = "exampleJob"; - - const job = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { location, prefix: inputPrefix }, - targetLocation: { location, prefix: OUTPUT_FOLDER }, - }; - const response = await client.path("/jobs/{name}", jobName).put({ body: job }); - - if (isUnexpected(response)) { - throw response.body.error; - } - - console.log(response.body); -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); - -module.exports = { main }; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/helloWorld.js b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/helloWorld.js deleted file mode 100644 index cd01a19b6e1c..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/helloWorld.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to create a `DeidentificationClient` and then deidentify a `string` - */ - -const createClient = require("@azure-rest/health-deidentification").default, - { isUnexpected } = require("@azure-rest/health-deidentification"); -const { DefaultAzureCredential } = require("@azure/identity"); -require("dotenv").config(); - -async function main() { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const client = createClient(serviceEndpoint, credential); - - const content = { - inputText: "Hello John!", - }; - - const response = await client.path("/deid").post({ body: content }); - - if (isUnexpected(response)) { - throw response.body.error; - } - - console.log(response.body.outputText); // Hello, Tom! -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); - -module.exports = { main }; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listCompletedFiles.js b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listCompletedFiles.js deleted file mode 100644 index d44825fc5533..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listCompletedFiles.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to list files that were completed by a job. - */ - -const createClient = require("@azure-rest/health-deidentification").default, - { isUnexpected, paginate } = require("@azure-rest/health-deidentification"); -const { DefaultAzureCredential } = require("@azure/identity"); -require("dotenv").config(); - -async function main() { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const storageLocation = `https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net/${process.env["STORAGE_CONTAINER_NAME"]}`; - const location = storageLocation || "defaultSasUri"; - const OUTPUT_FOLDER = "_output"; - const inputPrefix = "example_patient_1"; - const client = createClient(serviceEndpoint, credential); - const jobName = "exampleJob"; - - const job = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { location, prefix: inputPrefix }, - targetLocation: { location, prefix: OUTPUT_FOLDER }, - }; - - await client.path("/jobs/{name}", jobName).put({ body: job }); - - const response = await client.path("/jobs/{name}/documents", jobName).get(); - - if (isUnexpected(response)) { - throw response.body.error; - } - - const items = []; - const iter = paginate(client, response); - - for await (const item of iter) { - items.push(item); - } - - console.log(items); // items will contain all the completed files -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); - -module.exports = { main }; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listJobs.js b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listJobs.js deleted file mode 100644 index aa5d0903082f..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/listJobs.js +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to list jobs and iterate over them in a for loop. - */ - -const createClient = require("@azure-rest/health-deidentification").default, - { isUnexpected, paginate } = require("@azure-rest/health-deidentification"); -const { DefaultAzureCredential } = require("@azure/identity"); -require("dotenv").config(); - -async function main() { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const client = createClient(serviceEndpoint, credential); - - const response = await client.path("/jobs").get(); - - if (isUnexpected(response)) { - throw response.body.error; - } - - const items = []; - const iter = paginate(client, response); - for await (const item of iter) { - items.push(item); - } - - console.log(items); // items will contain all the jobs -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); - -module.exports = { main }; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/package.json b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/package.json deleted file mode 100644 index 2e6d1369680e..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "@azure-samples/health-deidentification-js-beta", - "private": true, - "version": "1.0.0", - "description": "Health Deidentification Service client library samples for JavaScript (Beta)", - "engines": { - "node": ">=18.0.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Azure/azure-sdk-for-js.git", - "directory": "sdk/healthdataaiservices/azure-health-deidentification" - }, - "keywords": [ - "node", - "azure", - "cloud", - "typescript", - "browser", - "isomorphic" - ], - "author": "Microsoft Corporation", - "license": "MIT", - "bugs": { - "url": "https://github.com/Azure/azure-sdk-for-js/issues" - }, - "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/healthdataaiservices/azure-health-deidentification", - "dependencies": { - "@azure-rest/health-deidentification": "next", - "dotenv": "latest", - "@azure/identity": "~4.3.0-beta.1" - } -} diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/sample.env b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/sample.env deleted file mode 100644 index 2ff41595523b..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/javascript/sample.env +++ /dev/null @@ -1,5 +0,0 @@ -# Your De-identification Service URL can be found in the overview section of the Azure Portal. -DEID_SERVICE_ENDPOINT= -# Storage account and container name -STORAGE_ACCOUNT_NAME= -STORAGE_CONTAINER_NAME= diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/README.md b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/README.md deleted file mode 100644 index 4d6c06341c2d..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# Health Deidentification Service client library samples for TypeScript (Beta) - -These sample programs show how to use the TypeScript client libraries for Health Deidentification Service in some common scenarios. - -| **File Name** | **Description** | -| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| [createJob.ts][createjob] | This sample demonstrates how to create a job which will deidentify all files within a blob storage container filtering via a prefix. | -| [helloWorld.ts][helloworld] | This sample demonstrates how to create a `DeidentificationClient` and then deidentify a `string` | -| [listCompletedFiles.ts][listcompletedfiles] | This sample demonstrates how to list files that were completed by a job. | -| [listJobs.ts][listjobs] | This sample demonstrates how to list jobs and iterate over them in a for loop. | - -## Prerequisites - -The sample programs are compatible with [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule). - -Before running the samples in Node, they must be compiled to JavaScript using the TypeScript compiler. For more information on TypeScript, see the [TypeScript documentation][typescript]. Install the TypeScript compiler using: - -```bash -npm install -g typescript -``` - -You need [an Azure subscription][freesub] and the following Azure resources to run these sample programs: - -- [De-identification Service][createinstance_de-identificationservice] - -Samples retrieve credentials to access the service endpoint from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function. - -Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README][package]. - -## Setup - -To run the samples using the published version of the package: - -1. Install the dependencies using `npm`: - -```bash -npm install -``` - -2. Compile the samples: - -```bash -npm run build -``` - -3. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically. - -4. Run whichever samples you like (note that some samples may require additional setup, see the table above): - -```bash -node dist/createJob.js -``` - -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): - -```bash -npx cross-env DEID_SERVICE_ENDPOINT="" STORAGE_ACCOUNT_NAME="" STORAGE_CONTAINER_NAME="" node dist/createJob.js -``` - -## Next Steps - -Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients. - -[createjob]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/createJob.ts -[helloworld]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/helloWorld.ts -[listcompletedfiles]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listCompletedFiles.ts -[listjobs]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listJobs.ts -[apiref]: https://docs.microsoft.com/javascript/api/ -[freesub]: https://azure.microsoft.com/free/ -[createinstance_de-identificationservice]: https://docs.microsoft.com/javascript/api/ -[package]: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/healthdataaiservices/azure-health-deidentification/README.md -[typescript]: https://www.typescriptlang.org/docs/home.html diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/package.json b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/package.json deleted file mode 100644 index cf24dbdfb56c..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "@azure-samples/health-deidentification-ts-beta", - "private": true, - "version": "1.0.0", - "description": "Health Deidentification Service client library samples for TypeScript (Beta)", - "engines": { - "node": ">=18.0.0" - }, - "scripts": { - "build": "tsc", - "prebuild": "rimraf dist/" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Azure/azure-sdk-for-js.git", - "directory": "sdk/healthdataaiservices/azure-health-deidentification" - }, - "keywords": [ - "node", - "azure", - "cloud", - "typescript", - "browser", - "isomorphic" - ], - "author": "Microsoft Corporation", - "license": "MIT", - "bugs": { - "url": "https://github.com/Azure/azure-sdk-for-js/issues" - }, - "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/healthdataaiservices/azure-health-deidentification", - "dependencies": { - "@azure-rest/health-deidentification": "next", - "dotenv": "latest", - "@azure/identity": "~4.3.0-beta.1" - }, - "devDependencies": { - "@types/node": "^18.0.0", - "typescript": "~5.6.2", - "rimraf": "latest" - } -} diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/sample.env b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/sample.env deleted file mode 100644 index 2ff41595523b..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/sample.env +++ /dev/null @@ -1,5 +0,0 @@ -# Your De-identification Service URL can be found in the overview section of the Azure Portal. -DEID_SERVICE_ENDPOINT= -# Storage account and container name -STORAGE_ACCOUNT_NAME= -STORAGE_CONTAINER_NAME= diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/createJob.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/createJob.ts deleted file mode 100644 index 44b6b71301ad..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/createJob.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to create a job which will deidentify all files within a blob storage container filtering via a prefix. - */ - -import createClient, { - DeidentificationJob, - isUnexpected, -} from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const storageLocation = `https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net/${process.env["STORAGE_CONTAINER_NAME"]}`; - const location = storageLocation || "defaultSasUri"; - const OUTPUT_FOLDER = "_output"; - const inputPrefix = "example_patient_1"; - const client = createClient(serviceEndpoint, credential); - const jobName = "exampleJob"; - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { location, prefix: inputPrefix }, - targetLocation: { location, prefix: OUTPUT_FOLDER }, - }; - const response = await client.path("/jobs/{name}", jobName).put({ body: job }); - - if (isUnexpected(response)) { - throw response.body.error; - } - - console.log(response.body); -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/helloWorld.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/helloWorld.ts deleted file mode 100644 index c96423ff88e9..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/helloWorld.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to create a `DeidentificationClient` and then deidentify a `string` - */ - -import createClient, { - DeidentificationContent, - isUnexpected, -} from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const client = createClient(serviceEndpoint, credential); - - const content: DeidentificationContent = { - inputText: "Hello John!", - }; - - const response = await client.path("/deid").post({ body: content }); - - if (isUnexpected(response)) { - throw response.body.error; - } - - console.log(response.body.outputText); // Hello, Tom! -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listCompletedFiles.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listCompletedFiles.ts deleted file mode 100644 index 01e35025cffe..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listCompletedFiles.ts +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to list files that were completed by a job. - */ - -import createClient, { - DeidentificationJob, - isUnexpected, - paginate, -} from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const storageLocation = `https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net/${process.env["STORAGE_CONTAINER_NAME"]}`; - const location = storageLocation || "defaultSasUri"; - const OUTPUT_FOLDER = "_output"; - const inputPrefix = "example_patient_1"; - const client = createClient(serviceEndpoint, credential); - const jobName = "exampleJob"; - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { location, prefix: inputPrefix }, - targetLocation: { location, prefix: OUTPUT_FOLDER }, - }; - - await client.path("/jobs/{name}", jobName).put({ body: job }); - - const response = await client.path("/jobs/{name}/documents", jobName).get(); - - if (isUnexpected(response)) { - throw response.body.error; - } - - const items = []; - const iter = paginate(client, response); - - for await (const item of iter) { - items.push(item); - } - - console.log(items); // items will contain all the completed files -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listJobs.ts b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listJobs.ts deleted file mode 100644 index 99301ef9eac5..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/src/listJobs.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * @summary This sample demonstrates how to list jobs and iterate over them in a for loop. - */ - -import createClient, { isUnexpected, paginate } from "@azure-rest/health-deidentification"; -import { DefaultAzureCredential } from "@azure/identity"; -import * as dotenv from "dotenv"; -dotenv.config(); - -export async function main(): Promise { - const credential = new DefaultAzureCredential(); - const serviceEndpoint = - process.env["DEID_SERVICE_ENDPOINT"] || "https://example.api.cac001.deid.azure.com"; - const client = createClient(serviceEndpoint, credential); - - const response = await client.path("/jobs").get(); - - if (isUnexpected(response)) { - throw response.body.error; - } - - const items = []; - const iter = paginate(client, response); - for await (const item of iter) { - items.push(item); - } - - console.log(items); // items will contain all the jobs -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/tsconfig.json b/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/tsconfig.json deleted file mode 100644 index 984eed535aa8..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/samples/v1-beta/typescript/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "alwaysStrict": true, - "outDir": "dist", - "rootDir": "src" - }, - "include": [ - "src/**/*.ts" - ] -} diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/clientDefinitions.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/clientDefinitions.ts index c153bb2c1725..04491d467dbb 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/clientDefinitions.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/clientDefinitions.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { +import { GetJobParameters, CreateJobParameters, DeleteJobParameters, @@ -10,7 +10,7 @@ import type { CancelJobParameters, DeidentifyParameters, } from "./parameters.js"; -import type { +import { GetJob200Response, GetJobDefaultResponse, CreateJob200Response, @@ -27,15 +27,19 @@ import type { Deidentify200Response, DeidentifyDefaultResponse, } from "./responses.js"; -import type { Client, StreamableMethod } from "@azure-rest/core-client"; +import { Client, StreamableMethod } from "@azure-rest/core-client"; export interface GetJob { /** Resource read operation template. */ - get(options?: GetJobParameters): StreamableMethod; + get( + options?: GetJobParameters, + ): StreamableMethod; /** Long-running resource create or replace operation template. */ put( options: CreateJobParameters, - ): StreamableMethod; + ): StreamableMethod< + CreateJob200Response | CreateJob201Response | CreateJobDefaultResponse + >; /** Removes the record of the job from the service. Does not delete any documents. */ delete( options?: DeleteJobParameters, @@ -53,7 +57,9 @@ export interface ListJobDocuments { /** Resource list operation template. */ get( options?: ListJobDocumentsParameters, - ): StreamableMethod; + ): StreamableMethod< + ListJobDocuments200Response | ListJobDocumentsDefaultResponse + >; } export interface CancelJob { @@ -89,6 +95,6 @@ export interface Routes { (path: "/deid"): Deidentify; } -export type DeidentificationClient = Client & { +export type DeidServicesClient = Client & { path: Routes; }; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/deidentificationClient.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/deidServicesClient.ts similarity index 68% rename from sdk/healthdataaiservices/azure-health-deidentification/src/deidentificationClient.ts rename to sdk/healthdataaiservices/azure-health-deidentification/src/deidServicesClient.ts index b07991a8ff93..07abf10b1c09 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/deidentificationClient.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/deidServicesClient.ts @@ -1,20 +1,19 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { ClientOptions } from "@azure-rest/core-client"; -import { getClient } from "@azure-rest/core-client"; +import { getClient, ClientOptions } from "@azure-rest/core-client"; import { logger } from "./logger.js"; -import type { TokenCredential } from "@azure/core-auth"; -import type { DeidentificationClient } from "./clientDefinitions.js"; +import { TokenCredential } from "@azure/core-auth"; +import { DeidServicesClient } from "./clientDefinitions.js"; /** The optional parameters for the client */ -export interface DeidentificationClientOptions extends ClientOptions { +export interface DeidServicesClientOptions extends ClientOptions { /** The api version option of the client */ apiVersion?: string; } /** - * Initialize a new instance of `DeidentificationClient` + * Initialize a new instance of `DeidServicesClient` * @param endpointParam - Url of your De-identification Service. * @param credentials - uniquely identify client credential * @param options - the parameter for all optional parameters @@ -22,9 +21,13 @@ export interface DeidentificationClientOptions extends ClientOptions { export default function createClient( endpointParam: string, credentials: TokenCredential, - { apiVersion = "2024-07-12-preview", ...options }: DeidentificationClientOptions = {}, -): DeidentificationClient { - const endpointUrl = options.endpoint ?? options.baseUrl ?? `https://${endpointParam}`; + { + apiVersion = "2024-07-12-preview", + ...options + }: DeidServicesClientOptions = {}, +): DeidServicesClient { + const endpointUrl = + options.endpoint ?? options.baseUrl ?? `https://${endpointParam}`; const userAgentInfo = `azsdk-js-health-deidentification-rest/1.0.0-beta.1`; const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix @@ -39,10 +42,16 @@ export default function createClient( logger: options.loggingOptions?.logger ?? logger.info, }, credentials: { - scopes: options.credentials?.scopes ?? ["https://deid.azure.com/.default"], + scopes: options.credentials?.scopes ?? [ + "https://deid.azure.com/.default", + ], }, }; - const client = getClient(endpointUrl, credentials, options) as DeidentificationClient; + const client = getClient( + endpointUrl, + credentials, + options, + ) as DeidServicesClient; client.pipeline.removePolicy({ name: "ApiVersionPolicy" }); client.pipeline.addPolicy({ @@ -60,5 +69,6 @@ export default function createClient( return next(req); }, }); + return client; } diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/index.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/index.ts index de1723896f8a..38b4433baa6f 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/index.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/index.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import DeidentificationClient from "./deidentificationClient.js"; +import DeidServicesClient from "./deidServicesClient.js"; -export * from "./deidentificationClient.js"; +export * from "./deidServicesClient.js"; export * from "./parameters.js"; export * from "./responses.js"; export * from "./clientDefinitions.js"; @@ -13,4 +13,4 @@ export * from "./outputModels.js"; export * from "./paginateHelper.js"; export * from "./pollingHelper.js"; -export default DeidentificationClient; +export default DeidServicesClient; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/isUnexpected.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/isUnexpected.ts index b99766aa2f8b..e67e9d160051 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/isUnexpected.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/isUnexpected.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { +import { GetJob200Response, GetJobDefaultResponse, CreateJob200Response, @@ -113,17 +113,24 @@ function getParametrizedPathSuccess(method: string, path: string): string[] { // track if we have found a match to return the values found. let found = true; - for (let i = candidateParts.length - 1, j = pathParts.length - 1; i >= 1 && j >= 1; i--, j--) { - if (candidateParts[i]?.startsWith("{") && candidateParts[i]?.indexOf("}") !== -1) { + for ( + let i = candidateParts.length - 1, j = pathParts.length - 1; + i >= 1 && j >= 1; + i--, j-- + ) { + if ( + candidateParts[i]?.startsWith("{") && + candidateParts[i]?.indexOf("}") !== -1 + ) { const start = candidateParts[i]!.indexOf("}") + 1, end = candidateParts[i]?.length; // If the current part of the candidate is a "template" part // Try to use the suffix of pattern to match the path // {guid} ==> $ // {guid}:export ==> :export$ - const isMatched = new RegExp(`${candidateParts[i]?.slice(start, end)}`).test( - pathParts[j] || "", - ); + const isMatched = new RegExp( + `${candidateParts[i]?.slice(start, end)}`, + ).test(pathParts[j] || ""); if (!isMatched) { found = false; diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/outputModels.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/outputModels.ts index a336f45fe532..85cf9bd62e5b 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/outputModels.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/outputModels.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { Paged } from "@azure/core-paging"; -import type { ErrorModel } from "@azure-rest/core-client"; +import { Paged } from "@azure/core-paging"; +import { ErrorModel } from "@azure-rest/core-client"; /** A job containing a batch of documents to de-identify. */ export interface DeidentificationJobOutput { diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/paginateHelper.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/paginateHelper.ts index 5d541b4e406d..94d5220235d9 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/paginateHelper.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/paginateHelper.ts @@ -1,10 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { PagedAsyncIterableIterator, PagedResult } from "@azure/core-paging"; -import { getPagedAsyncIterator } from "@azure/core-paging"; -import type { Client, PathUncheckedResponse } from "@azure-rest/core-client"; -import { createRestError } from "@azure-rest/core-client"; +import { + getPagedAsyncIterator, + PagedAsyncIterableIterator, + PagedResult, +} from "@azure/core-paging"; +import { + Client, + createRestError, + PathUncheckedResponse, +} from "@azure-rest/core-client"; /** * Helper type to extract the type of an array @@ -69,7 +75,9 @@ export function paginate( typeof customGetPage === "function" ? customGetPage : async (pageLink: string) => { - const result = firstRun ? initialResponse : await client.pathUnchecked(pageLink).get(); + const result = firstRun + ? initialResponse + : await client.pathUnchecked(pageLink).get(); firstRun = false; checkPagingRequest(result); const nextLink = getNextLink(result.body, nextLinkName); @@ -95,7 +103,9 @@ function getNextLink(body: unknown, nextLinkName?: string): string | undefined { const nextLink = (body as Record)[nextLinkName]; if (typeof nextLink !== "string" && typeof nextLink !== "undefined") { - throw new Error(`Body Property ${nextLinkName} should be a string or undefined`); + throw new Error( + `Body Property ${nextLinkName} should be a string or undefined`, + ); } return nextLink; @@ -123,7 +133,18 @@ function getElements(body: unknown, itemName: string): T[] { * Checks if a request failed */ function checkPagingRequest(response: PathUncheckedResponse): void { - const Http2xxStatusCodes = ["200", "201", "202", "203", "204", "205", "206", "207", "208", "226"]; + const Http2xxStatusCodes = [ + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "226", + ]; if (!Http2xxStatusCodes.includes(response.status)) { throw createRestError( `Pagination failed with unexpected statusCode ${response.status}`, diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/parameters.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/parameters.ts index 22d840140ea7..15d0ddfdfef1 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/parameters.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/parameters.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { RawHttpHeadersInput } from "@azure/core-rest-pipeline"; -import type { RequestParameters } from "@azure-rest/core-client"; -import type { DeidentificationJob, DeidentificationContent } from "./models.js"; +import { RawHttpHeadersInput } from "@azure/core-rest-pipeline"; +import { RequestParameters } from "@azure-rest/core-client"; +import { DeidentificationJob, DeidentificationContent } from "./models.js"; export interface GetJobHeaders { /** An opaque, globally-unique, client-generated string identifier for the request. */ @@ -30,7 +30,9 @@ export interface CreateJobHeaderParam { headers?: RawHttpHeadersInput & CreateJobHeaders; } -export type CreateJobParameters = CreateJobHeaderParam & CreateJobBodyParam & RequestParameters; +export type CreateJobParameters = CreateJobHeaderParam & + CreateJobBodyParam & + RequestParameters; export interface ListJobsHeaders { /** An opaque, globally-unique, client-generated string identifier for the request. */ @@ -52,7 +54,9 @@ export interface ListJobsHeaderParam { headers?: RawHttpHeadersInput & ListJobsHeaders; } -export type ListJobsParameters = ListJobsQueryParam & ListJobsHeaderParam & RequestParameters; +export type ListJobsParameters = ListJobsQueryParam & + ListJobsHeaderParam & + RequestParameters; export interface ListJobDocumentsHeaders { /** An opaque, globally-unique, client-generated string identifier for the request. */ diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/pollingHelper.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/pollingHelper.ts index 5abda1a6550f..986993876973 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/pollingHelper.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/pollingHelper.ts @@ -1,17 +1,17 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { Client, HttpResponse } from "@azure-rest/core-client"; -import type { AbortSignalLike } from "@azure/abort-controller"; -import type { +import { Client, HttpResponse } from "@azure-rest/core-client"; +import { AbortSignalLike } from "@azure/abort-controller"; +import { CancelOnProgress, CreateHttpPollerOptions, RunningOperation, OperationResponse, OperationState, + createHttpPoller, } from "@azure/core-lro"; -import { createHttpPoller } from "@azure/core-lro"; -import type { +import { CreateJob200Response, CreateJob201Response, CreateJobDefaultResponse, @@ -21,7 +21,10 @@ import type { /** * A simple poller that can be used to poll a long running operation. */ -export interface SimplePollerLike, TResult> { +export interface SimplePollerLike< + TState extends OperationState, + TResult, +> { /** * Returns true if the poller has finished polling. */ @@ -45,7 +48,9 @@ export interface SimplePollerLike, TResul /** * Returns a promise that will resolve once the underlying operation is completed. */ - pollUntilDone(pollOptions?: { abortSignal?: AbortSignalLike }): Promise; + pollUntilDone(pollOptions?: { + abortSignal?: AbortSignalLike; + }): Promise; /** * Invokes the provided callback after each polling is completed, * sending the current state of the poller's operation. @@ -95,7 +100,10 @@ export async function getLongRunningPoller< TResult extends CreateJobLogicalResponse | CreateJobDefaultResponse, >( client: Client, - initialResponse: CreateJob200Response | CreateJob201Response | CreateJobDefaultResponse, + initialResponse: + | CreateJob200Response + | CreateJob201Response + | CreateJobDefaultResponse, options?: CreateHttpPollerOptions>, ): Promise, TResult>>; export async function getLongRunningPoller( @@ -111,7 +119,10 @@ export async function getLongRunningPoller( // response we were provided. return getLroResponse(initialResponse); }, - sendPollRequest: async (path: string, pollOptions?: { abortSignal?: AbortSignalLike }) => { + sendPollRequest: async ( + path: string, + pollOptions?: { abortSignal?: AbortSignalLike }, + ) => { // This is the callback that is going to be called to poll the service // to get the latest status. We use the client provided and the polling path // which is an opaque URL provided by caller, the service sends this in one of the following headers: operation-location, azure-asyncoperation or location @@ -137,7 +148,8 @@ export async function getLongRunningPoller( inputAbortSignal?.removeEventListener("abort", abortListener); } const lroResponse = getLroResponse(response as TResult); - lroResponse.rawResponse.headers["x-ms-original-url"] = initialResponse.request.url; + lroResponse.rawResponse.headers["x-ms-original-url"] = + initialResponse.request.url; return lroResponse; }, }; @@ -193,7 +205,9 @@ function getLroResponse( response: TResult, ): OperationResponse { if (Number.isNaN(response.status)) { - throw new TypeError(`Status code of the response is not a number. Value: ${response.status}`); + throw new TypeError( + `Status code of the response is not a number. Value: ${response.status}`, + ); } return { diff --git a/sdk/healthdataaiservices/azure-health-deidentification/src/responses.ts b/sdk/healthdataaiservices/azure-health-deidentification/src/responses.ts index 0db6d44e9749..95c6452476a7 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/src/responses.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/src/responses.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { RawHttpHeaders } from "@azure/core-rest-pipeline"; -import type { HttpResponse, ErrorResponse } from "@azure-rest/core-client"; -import type { +import { RawHttpHeaders } from "@azure/core-rest-pipeline"; +import { HttpResponse, ErrorResponse } from "@azure-rest/core-client"; +import { DeidentificationJobOutput, PagedDeidentificationJobOutput, PagedDocumentDetailsOutput, diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test-resources-post.ps1 b/sdk/healthdataaiservices/azure-health-deidentification/test-resources-post.ps1 deleted file mode 100644 index 3400bf3ec4ae..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/test-resources-post.ps1 +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -# This script is used to set up SIP Configuration domains for Azure Communication Services SIP Routing SDK GA tests - -# It is invoked by the https://github.com/Azure/azure-sdk-for-net/blob/main/eng/New-TestResources.ps1 -# script after the ARM template, defined in https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/storage/test-resources.json, -# is finished being deployed. The ARM template is responsible for creating the Storage accounts needed for live tests. - -param ( - [hashtable] $DeploymentOutputs, - [string] $TenantId, - [string] $TestApplicationId, - [string] $TestApplicationSecret -) - -# Retrieve the connection string from environment variables -$resourceGroup = $DeploymentOutputs['HEALTHDATAAISERVICES_RESOURCE_GROUP'] -$endpoint = $DeploymentOutputs['HEALTHDATAAISERVICES_DEID_SERVICE_ENDPOINT'] -$storageAccountName = $DeploymentOutputs['HEALTHDATAAISERVICES_STORAGE_ACCOUNT_NAME'] -$containerName = $DeploymentOutputs['HEALTHDATAAISERVICES_STORAGE_CONTAINER_NAME'] -$testMode = "live" - -# Set the local folder path to upload -$localFolderPath = "test\public\data\example_patient_1" - -# Check if the connection string is present -if ([string]::IsNullOrWhiteSpace($storageAccountName)) { - Write-Host "Error: Azure Storage Name string not found in environment variables." - exit 1 -} - -# Load the Azure Storage module -Import-Module Az.Storage - -# Connect to the storage account -$storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -UseConnectedAccount - -# FIXME Remove once vpn team fixes the network acl issue -$networkRuleSet = New-Object -TypeName Microsoft.Azure.Commands.Management.Storage.Models.PSNetworkRuleSet -$networkRuleSet.DefaultAction = "Allow" -Set-AzStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccountName -NetworkRuleSet $networkRuleSet - -# Sleep for 15 seconds to allow the network rule to take effect -Write-Host "[Fix] Temporary sleep to allow network rule to take effect." -Start-Sleep -Seconds 30 - -Get-AzStorageContainer -Name $containerName -Context $storageContext - -# Upload the folder and its contents to the container -# Gets last folder name + filename. example_patient_1\doctor_dictation.txt -Get-ChildItem -Path $localFolderPath -Recurse | ForEach-Object { - $relativePath = $_.FullName - $relativePath = $relativePath.Replace("\\", "\") - $folderName = ($relativePath -split "\\")[-2] # Get only the folder name. - $blobName = ($relativePath -split "\\")[-1] # Get only the file name. - $destinationBlob = $blobName -replace ":", "" - - $destinationBlob = "$folderName\$destinationBlob" - Write-Host "Uploading file '$destinationBlob'" - Set-AzStorageBlobContent -File $_.FullName -Container $containerName -Blob $destinationBlob -Context $storageContext -Force -} - -Write-Host "Folder '$localFolderPath' uploaded to container '$containerName' successfully." - -$endpoint = $endpoint -replace '^https://', '' -# Create the content for the .env file -$content = @" -DEID_SERVICE_ENDPOINT=$endpoint -TEST_MODE=$testMode -STORAGE_ACCOUNT_NAME=$storageAccountName -STORAGE_CONTAINER_NAME=$containerName -"@ - -# Specify the path for the .env file -$envFilePath = ".\.env" - -# Write the content to the .env file, overwrite if it exists -$content | Out-File -FilePath $envFilePath -Force diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test-resources.bicep b/sdk/healthdataaiservices/azure-health-deidentification/test-resources.bicep deleted file mode 100644 index 63e8f4e54d58..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/test-resources.bicep +++ /dev/null @@ -1,205 +0,0 @@ -// "id": "/subscriptions/d12535ed-5958-4ce6-8350-b17b3af1d6b1/resourceGroups/oro-billing-exhaust-test/providers/Microsoft.HealthDataAIServices/DeidServices/deid-billing-test", -// "name": "deid-billing-test", -// "type": "microsoft.healthdataaiservices/deidservices", -// "location": "East US 2 EUAP", -// "tags": {}, - -@minLength(10) -param testApplicationOid string - -@minLength(6) -@maxLength(50) -@description('The base resource name.') -param baseName string - -param location string = resourceGroup().location - -@description('The location of the resource. By default, this is the same as the resource group.') -param deidLocation string = 'eastus2euap' -param deidLocationShort string = 'eup' - -param deploymentTime string = utcNow('u') - -var realtimeDataUserRoleId = 'bb6577c4-ea0a-40b2-8962-ea18cb8ecd4e' -var batchDataOwnerRoleId = '8a90fa6b-6997-4a07-8a95-30633a7c97b9' -var storageBlobDataContributor = 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' - -var blobStorageName = take(toLower(replace('blob-${baseName}', '-', '')), 24) -var blobContainerName = 'container-${baseName}' -var deidServiceName = 'deid${baseName}${deidLocationShort}' - -resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { - name: blobStorageName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - properties: { - minimumTlsVersion: 'TLS1_2' - networkAcls: { - bypass: 'AzureServices' - defaultAction: 'Deny' - ipRules: [ - { - action: 'Allow' - value: '4.0.0.0/8' - } - { - action: 'Allow' - value: '13.0.0.0/8' - } - { - action: 'Allow' - value: '20.0.0.0/8' - } - { - action: 'Allow' - value: '40.0.0.0/8' - } - { - action: 'Allow' - value: '51.0.0.0/8' - } - { - action: 'Allow' - value: '52.0.0.0/8' - } - { - action: 'Allow' - value: '65.0.0.0/8' - } - { - action: 'Allow' - value: '70.0.0.0/8' - } - { - action: 'Allow' - value: '74.234.0.0/16' - } - { - action: 'Allow' - value: '74.235.60.120/30' - } - { - action: 'Allow' - value: '94.245.0.0/16' - } - { - action: 'Allow' - value: '98.71.0.0/16' - } - { - action: 'Allow' - value: '102.133.0.0/16' - } - { - action: 'Allow' - value: '104.41.214.32/29' - } - { - action: 'Allow' - value: '104.44.0.0/16' - } - { - action: 'Allow' - value: '104.45.71.156/30' - } - { - action: 'Allow' - value: '104.208.0.0/12' - } - { - action: 'Allow' - value: '108.142.0.0/16' - } - { - action: 'Allow' - value: '131.107.0.0/16' - } - { - action: 'Allow' - value: '157.58.0.0/16' - } - { - action: 'Allow' - value: '167.220.0.0/16' - } - { - action: 'Allow' - value: '172.128.0.0/13' - } - { - action: 'Allow' - value: '191.234.97.0/26' - } - { - action: 'Allow' - value: '194.69.0.0/16' - } - { - action: 'Allow' - value: '207.46.0.0/16' - } - ] - } - } -} - -resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2022-05-01' = { - parent: storageAccount - name: 'default' -} - -resource container 'Microsoft.Storage/storageAccounts/blobServices/containers@2022-05-01' = { - parent: blobService - name: blobContainerName -} - -resource storageRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { - name: guid(resourceGroup().id, storageAccount.id, testApplicationOid, storageBlobDataContributor) - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageBlobDataContributor) - principalId: testApplicationOid - } - scope: storageAccount -} - -resource testDeidService 'microsoft.healthdataaiservices/deidservices@2024-02-28-preview' = { - name: deidServiceName - location: deidLocation - identity: { - type: 'SystemAssigned' - } -} - -resource storageMIRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { - name: guid(resourceGroup().id, storageAccount.id, testDeidService.id, storageBlobDataContributor) - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageBlobDataContributor) - principalId: testDeidService.identity.principalId - } - scope: storageAccount -} - -resource realtimeRole 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = { - name: guid(resourceGroup().id, testDeidService.id, testApplicationOid, realtimeDataUserRoleId) - scope: testDeidService - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', realtimeDataUserRoleId) - principalId: testApplicationOid - } -} - -resource batchRole 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = { - name: guid(resourceGroup().id, testDeidService.id, testApplicationOid, batchDataOwnerRoleId) - scope: testDeidService - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', batchDataOwnerRoleId) - principalId: testApplicationOid - } -} - -output HEALTHDATAAISERVICES_DEID_SERVICE_ENDPOINT string = testDeidService.properties.serviceUrl -output HEALTHDATAAISERVICES_STORAGE_ACCOUNT_NAME string = storageAccount.name -output HEALTHDATAAISERVICES_STORAGE_CONTAINER_NAME string = container.name diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test/public/data/example_patient_1/doctor_dictation.txt b/sdk/healthdataaiservices/azure-health-deidentification/test/public/data/example_patient_1/doctor_dictation.txt deleted file mode 100644 index dfb10187f123..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/test/public/data/example_patient_1/doctor_dictation.txt +++ /dev/null @@ -1 +0,0 @@ -Mr. Doe is a 97-year-old gentleman who presented to the clinic today complaining of persistent lower back pain. He reports the pain as dull and achy, primarily localized to the lumbar region. Onset was approximately three weeks ago, following a period of heavy lifting during a recent move. The pain is exacerbated by prolonged sitting and relieved with rest. No associated symptoms of radiculopathy, such as numbness or weakness, were reported. diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test/public/data/example_patient_1/visit_summary.txt b/sdk/healthdataaiservices/azure-health-deidentification/test/public/data/example_patient_1/visit_summary.txt deleted file mode 100644 index 427472ff8d1d..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/test/public/data/example_patient_1/visit_summary.txt +++ /dev/null @@ -1,8 +0,0 @@ -Patient Name: John Doe -Date of Visit: May 8, 2024 -Physician: Dr. Emily Carter - -Summary: - -Chief Complaint: -John Doe presented today with complaints of persistent lower back pain that has been bothering him for the past three weeks. He reports the pain as dull and achy, localized primarily to the lumbar region, exacerbated by prolonged sitting and relieved with rest. diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test/public/jobOperationsTest.spec.ts b/sdk/healthdataaiservices/azure-health-deidentification/test/public/jobOperationsTest.spec.ts deleted file mode 100644 index fe2fc07180f2..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/test/public/jobOperationsTest.spec.ts +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { - createRecordedDeidentificationClient, - createRecorder, - getStorageAccountLocation, - getTestEnvironment, -} from "./utils/recordedClient.js"; -import { assert, beforeEach, afterEach, it, describe } from "vitest"; -import type { DeidentificationClient } from "../../src/clientDefinitions.js"; -import { createTestCredential } from "@azure-tools/test-credential"; -import type { DeidentificationJob } from "../../src/models.js"; -import type { DeidentificationJobOutput, DocumentDetailsOutput } from "../../src/outputModels.js"; -import type { Recorder } from "@azure-tools/test-recorder"; -import { isPlaybackMode, isRecordMode } from "@azure-tools/test-recorder"; -import type { ErrorResponse } from "@azure-rest/core-client"; -import { getLongRunningPoller } from "../../src/pollingHelper.js"; -import { paginate } from "../../src/paginateHelper.js"; -import { isUnexpected } from "../../src/isUnexpected.js"; - -const testPollingOptions = { - intervalInMs: isPlaybackMode() ? 0 : undefined, -}; - -const TEST_TIMEOUT_MS: number = 200000; - -const fakeServiceEndpoint = "example.com"; -const replaceableVariables: Record = { - DEID_SERVICE_ENDPOINT: fakeServiceEndpoint, - STORAGE_ACCOUNT_LOCATION: - "https://fake_storage_account_sas_uri.blob.core.windows.net/container-sdk-dev-fakeid", -}; - -const generateJobName = (testName?: string): string => { - let jobName = "js-sdk-job-" + Date.now(); - if (isPlaybackMode() || isRecordMode()) { - jobName = `js-sdk-job-recorded-${testName}`; - } - return jobName; -}; - -const OUTPUT_FOLDER = "_output"; - -describe("Batch", () => { - let recorder: Recorder; - let client: DeidentificationClient; - const environment = getTestEnvironment(); - - beforeEach(async function (context) { - recorder = await createRecorder(context); - await recorder.start({ - envSetupForPlayback: replaceableVariables, - sanitizerOptions: { - bodyKeySanitizers: [ - { - value: replaceableVariables.STORAGE_ACCOUNT_LOCATION, - jsonPath: "$..location", - regex: "^(?!.*FAKE_STORAGE_ACCOUNT).*", - }, - ], - }, - removeCentralSanitizers: ["AZSDK4001", "AZSDK2030", "AZSDK3430", "AZSDK3493"], - }); - const credential = createTestCredential(); - if (process.env.DEID_SERVICE_ENDPOINT) { - client = await createRecordedDeidentificationClient(recorder, credential); - } else { - throw new Error("DEID_SERVICE_ENDPOINT is not set"); - } - }); - - afterEach(async function () { - await recorder.stop(); - }); - - // Note: When your re-run recording you need to update jobName to avoid conflict with existing job "environment" is either node or browser depending on the test mode - it( - "CreateJob returns expected", - async function () { - const jobName = generateJobName(`001-${environment}`); - const inputPrefix = "example_patient_1"; - const storageAccountLocation = isPlaybackMode() - ? replaceableVariables.STORAGE_ACCOUNT_LOCATION - : getStorageAccountLocation(); - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { - location: storageAccountLocation, - prefix: inputPrefix, - extensions: ["*"], - }, - targetLocation: { location: storageAccountLocation, prefix: OUTPUT_FOLDER }, - }; - - const jobOutput = await client.path("/jobs/{name}", jobName).put({ body: job }); - - if (isUnexpected(jobOutput)) { - throw new Error("Unexpected job result"); - } - - assert.isNotNull(jobOutput); - assert.equal(jobName, jobOutput.body.name, "Job name should match"); - assert.isNotNull(jobOutput.body.createdAt, "Job should have createdAt"); - assert.isNotNull(jobOutput.body.lastUpdatedAt, "Job should have lastUpdatedAt"); - assert.isUndefined(jobOutput.body.startedAt, "Job should not have startedAt"); - assert.equal("NotStarted", jobOutput.body.status, "Job status should be NotStarted"); - assert.isUndefined(jobOutput.body.error, "Job should not have error"); - assert.isUndefined(jobOutput.body.redactionFormat, "Job should not have redactionFormat"); - assert.isUndefined(jobOutput.body.summary, "Job should not have summary"); - assert.equal( - inputPrefix, - jobOutput.body.sourceLocation.prefix, - "Job sourceLocation prefix should match", - ); - assert.isTrue( - storageAccountLocation.includes("blob.core.windows.net"), - "Storage account location should contain 'blob.core.windows.net'", - ); - assert.equal( - OUTPUT_FOLDER, - jobOutput.body.targetLocation.prefix, - "Job targetLocation prefix should match", - ); - assert.isTrue( - storageAccountLocation.includes("blob.core.windows.net"), - "Storage account location should contain 'blob.core.windows.net'", - ); - }, - TEST_TIMEOUT_MS, - ); - - it( - "CreateThenList returns expected", - async function () { - const jobName = generateJobName(`002-${environment}`); - const inputPrefix = "example_patient_1"; - const storageAccountLocation = isPlaybackMode() - ? replaceableVariables.STORAGE_ACCOUNT_LOCATION - : getStorageAccountLocation(); - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { - location: storageAccountLocation, - prefix: inputPrefix, - extensions: ["*"], - }, - targetLocation: { location: storageAccountLocation, prefix: OUTPUT_FOLDER }, - }; - - const initialResponse = await client.path("/jobs/{name}", jobName).put({ body: job }); - const poller = await getLongRunningPoller(client, initialResponse, testPollingOptions); - await poller.poll(); - assert.equal(poller.getOperationState().status, "running"); - - // Test list jobs with pagination - const jobs = await client.path("/jobs").get(); - const items = []; - const iter = paginate(client, jobs); - for await (const item of iter) { - items.push(item); - } - const foundJob = (items as DeidentificationJobOutput[]).find((j) => j.name === jobName); - - assert.isTrue(foundJob !== undefined, "Job should be found"); - assert.isNotNull(foundJob!.createdAt, "Job should have createdAt"); - assert.isNotNull(foundJob!.lastUpdatedAt, "Job should have lastUpdatedAt"); - assert.isNotNull(foundJob!.startedAt, "Job should have startedAt"); - assert.equal("NotStarted", foundJob!.status, "Job status should be NotStarted"); - assert.isUndefined(foundJob!.error, "Job should not have error"); - assert.isUndefined(foundJob!.redactionFormat, "Job should not have redactionFormat"); - assert.isUndefined(foundJob!.summary, "Job should not have summary"); - assert.equal( - inputPrefix, - foundJob!.sourceLocation.prefix, - "Job sourceLocation prefix should match", - ); - assert.isTrue( - storageAccountLocation.includes("blob.core.windows.net"), - "Storage account location should contain 'blob.core.windows.net'", - ); - assert.equal( - OUTPUT_FOLDER, - foundJob!.targetLocation.prefix, - "Job targetLocation prefix should match", - ); - assert.isTrue( - storageAccountLocation.includes("blob.core.windows.net"), - "Storage account location should contain 'blob.core.windows.net", - ); - }, - TEST_TIMEOUT_MS, - ); - - it( - "JobE2E wait until success", - async function () { - const jobName = generateJobName(`003-${environment}`); - const inputPrefix = "example_patient_1"; - const storageAccountLocation = isPlaybackMode() - ? replaceableVariables.STORAGE_ACCOUNT_LOCATION - : getStorageAccountLocation(); - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { - location: storageAccountLocation, - prefix: inputPrefix, - extensions: ["*"], - }, - targetLocation: { location: storageAccountLocation, prefix: OUTPUT_FOLDER }, - }; - - const initialResponse = await client.path("/jobs/{name}", jobName).put({ body: job }); - - const poller = await getLongRunningPoller(client, initialResponse, testPollingOptions); - const finalJobOutput = await poller.pollUntilDone(); - assert.equal(poller.getOperationState().status, "succeeded"); - - if (isUnexpected(finalJobOutput)) { - throw new Error("Unexpected error occurred"); - } - - assert.equal(finalJobOutput.body.status, "Succeeded", "Job status should be Succeeded"); - assert.notEqual(finalJobOutput.body.startedAt, null, "Job should have startedAt"); - assert.notEqual(finalJobOutput.body.summary, null, "Job should have summary"); - assert.equal(finalJobOutput.body.summary!.total, 2, "Job should have processed 2 documents"); - assert.equal( - finalJobOutput.body.summary!.successful, - 2, - "Job should have succeeded 2 documents", - ); - - const reports = await client.path("/jobs/{name}/documents", jobName).get(); - - if (isUnexpected(reports)) { - throw new Error("Unexpected error occurred"); - } - - const items = []; - const iter = paginate(client, reports); - - for await (const item of iter) { - items.push(item); - } - - assert.isTrue( - (items as unknown[] as DocumentDetailsOutput[]).length === 2, - "Should have 2 documents", - ); - assert.isTrue( - (items as unknown[] as DocumentDetailsOutput[]).every((obj) => obj.status === "Succeeded"), - "All documents should have succeeded", - ); - assert.isTrue( - (items as unknown[] as DocumentDetailsOutput[]).every((obj) => - obj.output!.path.startsWith(OUTPUT_FOLDER), - ), - "Output path should start with the output folder", - ); - assert.isTrue( - (items as unknown[] as DocumentDetailsOutput[]).every((obj) => obj.id.length === 36), - "Document id should be a GUID", - ); - }, - TEST_TIMEOUT_MS, - ); - - it( - "JobE2E cancel job then delete it deletes job", - async function () { - const jobName = generateJobName(`004-${environment}`); - const inputPrefix = "example_patient_1"; - const storageAccountLocation = isPlaybackMode() - ? replaceableVariables.STORAGE_ACCOUNT_LOCATION - : getStorageAccountLocation(); - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { - location: storageAccountLocation, - prefix: inputPrefix, - extensions: ["*"], - }, - targetLocation: { location: storageAccountLocation, prefix: OUTPUT_FOLDER }, - }; - - const initialResponse = await client.path("/jobs/{name}", jobName).put({ body: job }); - const poller = await getLongRunningPoller(client, initialResponse, testPollingOptions); - await poller.poll(); - assert.equal(poller.getOperationState().status, "running", "Job should be running"); - - const cancelledJob = await client.path("/jobs/{name}:cancel", jobName).post(); - assert.equal(cancelledJob.status, "200", "Job should be canceled"); - - const cancelledJobOutput = cancelledJob.body as DeidentificationJobOutput; - assert.equal("Canceled", cancelledJobOutput.status, "Job status should be Canceled"); - - const deleteRequest = await client.path("/jobs/{name}", jobName).delete(); - assert.equal(deleteRequest.status, "204", "Job should be deleted"); - - const deletedJob = await client.path("/jobs/{name}", jobName).get(); - assert.equal(deletedJob.status, "404", "Job should not be found"); - }, - TEST_TIMEOUT_MS, - ); - - it( - "JobE2E cannot access storage create job returns 404", - async function () { - const jobName = generateJobName(`005-${environment}`); - const inputPrefix = "example_patient_1"; - const storageAccountLocation = "FAKE_STORAGE_ACCOUNT"; - - const job: DeidentificationJob = { - dataType: "Plaintext", - operation: "Surrogate", - sourceLocation: { - location: storageAccountLocation, - prefix: inputPrefix, - extensions: ["*"], - }, - targetLocation: { location: storageAccountLocation, prefix: OUTPUT_FOLDER }, - }; - - const initialResponse = await client.path("/jobs/{name}", jobName).put({ body: job }); - - const poller = await getLongRunningPoller(client, initialResponse, testPollingOptions); - - await poller.poll(); - assert.equal(poller.getOperationState().status, "failed", "Job should fail"); - - const createdJob = await client.path("/jobs/{name}", jobName).get(); - assert.equal(createdJob.status, "404", "Job should not be found"); - const createdJobOutput = createdJob.body as ErrorResponse; - assert.isNotNull(createdJobOutput.error, "Job should have error"); - assert.equal("JobNotFound", createdJobOutput.error.code, "Error code should be JobNotFound"); - assert.isTrue( - createdJobOutput.error!.message.length > 10, - "Error message should be descriptive", - ); - }, - TEST_TIMEOUT_MS, - ); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test/public/realtimeOperationsTest.spec.ts b/sdk/healthdataaiservices/azure-health-deidentification/test/public/realtimeOperationsTest.spec.ts deleted file mode 100644 index 793a2bc36b90..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/test/public/realtimeOperationsTest.spec.ts +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { createRecordedDeidentificationClient, createRecorder } from "./utils/recordedClient.js"; -import { assert, beforeEach, afterEach, it, describe } from "vitest"; -import type { DeidentificationClient } from "../../src/clientDefinitions.js"; -import { createTestCredential } from "@azure-tools/test-credential"; - -import type { DeidentificationContent } from "../../src/models.js"; -import type { DeidentificationResultOutput } from "../../src/outputModels.js"; -import type { Recorder } from "@azure-tools/test-recorder"; - -const fakeServiceEndpoint = "example.com"; -const replaceableVariables: Record = { - DEID_SERVICE_ENDPOINT: fakeServiceEndpoint, -}; - -describe("Realtime", () => { - let recorder: Recorder; - let client: DeidentificationClient; - - beforeEach(async function (context) { - recorder = await createRecorder(context); - await recorder.start({ - envSetupForPlayback: replaceableVariables, - removeCentralSanitizers: ["AZSDK4001", "AZSDK2030", "AZSDK3430", "AZSDK3493"], - }); - const credential = createTestCredential(); - if (process.env.DEID_SERVICE_ENDPOINT) { - client = await createRecordedDeidentificationClient(recorder, credential); - } else { - throw new Error("DEID_SERVICE_ENDPOINT is not set"); - } - }); - - afterEach(async function () { - await recorder.stop(); - }); - - it("surrogate returns expected", async function () { - const content: DeidentificationContent = { - dataType: "Plaintext", - inputText: "Hello, my name is John Smith.", - operation: "Surrogate", - }; - const response = await client.path("/deid").post({ body: content }); - assert.equal(response.status, "200"); - const output = response.body as DeidentificationResultOutput; - assert.isUndefined( - output.taggerResult, - "On Surrogate Operation, expect TaggerResult to be null.", - ); - assert.isNotNull( - output.outputText, - "On Surrogate Operation, expect OutputText to be not null.", - ); - assert.isTrue( - (output.outputText as string).length > 21, - "Expected output text to be longer than the tag and a single character for each name token.", - ); - assert.notEqual( - content.inputText, - output.outputText, - "Expected output text to be different from input text.", - ); - }, 10000); - - it("tag returns expected", async function () { - const content: DeidentificationContent = { - dataType: "Plaintext", - inputText: "Hello, my name is John Smith.", - operation: "Tag", - }; - const response = await client.path("/deid").post({ body: content }); - assert.equal(response.status, "200"); - const output = response.body as DeidentificationResultOutput; - assert.isNotNull(output.taggerResult, "On Tag Operation, expect TaggerResult to be not null."); - assert.isObject(output.taggerResult, "On Tag Operation, expect TaggerResult to be not null."); - assert.isUndefined(output.outputText, "On Tag Operation, expect OutputText to be null."); - assert.isTrue(output.taggerResult!.etag === undefined, "Expected Etag to be null."); - assert.isTrue(output.taggerResult!.path === undefined, "Expected Path to be null."); - - assert.isTrue( - output.taggerResult!.entities.length > 0, - "Expected taggerResult to have at least one tag.", - ); - assert.isTrue( - output.taggerResult!.entities[0].category === "Doctor" || - output.taggerResult!.entities[0].category === "Patient", - "Expected first tag to be a patient/doctor.", - ); - assert.isTrue( - output.taggerResult!.entities[0].text === "John Smith", - "Expected first tag to be 'John Smith'.", - ); - assert.isTrue( - output.taggerResult!.entities[0].offset.utf8 === 18, - "Expected first tag to start at index 19.", - ); - assert.isTrue( - output.taggerResult!.entities[0].length.utf8 === 10, - "Expected first tag to be 10 characters long.", - ); - }, 10000); -}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test/public/sampleTest.spec.ts b/sdk/healthdataaiservices/azure-health-deidentification/test/public/sampleTest.spec.ts new file mode 100644 index 000000000000..d4919ac91ac5 --- /dev/null +++ b/sdk/healthdataaiservices/azure-health-deidentification/test/public/sampleTest.spec.ts @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { createRecorder } from "./utils/recordedClient.js"; +import { assert, beforeEach, afterEach, it, describe } from "vitest"; + +describe("My test", () => { + // let recorder: Recorder; + + beforeEach(async function () { + // recorder = await createRecorder(this); + }); + + afterEach(async function () { + // await recorder.stop(); + }); + + it("sample test", async function () { + assert.equal(1, 1); + }); +}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/test/public/utils/recordedClient.ts b/sdk/healthdataaiservices/azure-health-deidentification/test/public/utils/recordedClient.ts index cdfad48924c2..6e425fdcfdf9 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/test/public/utils/recordedClient.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/test/public/utils/recordedClient.ts @@ -1,41 +1,29 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { VitestTestContext } from "@azure-tools/test-recorder"; -import { Recorder, assertEnvironmentVariable, isPlaybackMode } from "@azure-tools/test-recorder"; -import type { TokenCredential } from "@azure/core-auth"; -import type { DeidentificationClient } from "../../../src/clientDefinitions.js"; -import createClient from "../../../src/deidentificationClient.js"; +import { + Recorder, + RecorderStartOptions, + VitestTestContext, +} from "@azure-tools/test-recorder"; + +const replaceableVariables: Record = { + SUBSCRIPTION_ID: "azure_subscription_id", +}; + +const recorderEnvSetup: RecorderStartOptions = { + envSetupForPlayback: replaceableVariables, +}; /** * creates the recorder and reads the environment variables from the `.env` file. * Should be called first in the test suite to make sure environment variables are * read before they are being used. */ -export async function createRecorder(testContext: VitestTestContext): Promise { - return new Recorder(testContext); -} - -export function getStorageAccountLocation(): string { - return `https://${assertEnvironmentVariable("STORAGE_ACCOUNT_NAME")}.blob.core.windows.net/${assertEnvironmentVariable("STORAGE_CONTAINER_NAME")}`; -} - -export function getTestEnvironment(): string { - if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) { - return "node"; - } - - return "browser"; -} - -export async function createRecordedDeidentificationClient( - recorder: Recorder, - credentials: TokenCredential, -): Promise { - const endpoint = isPlaybackMode() - ? "example.com" - : assertEnvironmentVariable("DEID_SERVICE_ENDPOINT"); - const client = await createClient(endpoint, credentials, recorder.configureClientOptions({})); - - return client; +export async function createRecorder( + context: VitestTestContext, +): Promise { + const recorder = new Recorder(context); + await recorder.start(recorderEnvSetup); + return recorder; } diff --git a/sdk/healthdataaiservices/azure-health-deidentification/tests.yml b/sdk/healthdataaiservices/azure-health-deidentification/tests.yml deleted file mode 100644 index f27af5d776b4..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/tests.yml +++ /dev/null @@ -1,8 +0,0 @@ -trigger: none - - -extends: - template: /eng/pipelines/templates/stages/archetype-sdk-tests.yml - parameters: - PackageName: "@azure-rest/health-deidentification" - ServiceDirectory: healthdataaiservices diff --git a/sdk/healthdataaiservices/azure-health-deidentification/tsconfig.json b/sdk/healthdataaiservices/azure-health-deidentification/tsconfig.json index b495c1a46b90..a6575847a41e 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/tsconfig.json +++ b/sdk/healthdataaiservices/azure-health-deidentification/tsconfig.json @@ -1,19 +1,16 @@ { - "extends": "../../../tsconfig.json", + "extends": "../../../tsconfig", "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext", "rootDir": ".", - "paths": { - "@azure/health-deidentification": ["./src/index"] - } + "skipLibCheck": true }, "include": [ "./src/**/*.ts", "./src/**/*.mts", "./src/**/*.cts", "test/**/*.ts", - "./test/**/*.ts", - "./samples-dev/**/*.ts" + "./test/**/*.ts" ] -} +} \ No newline at end of file diff --git a/sdk/healthdataaiservices/azure-health-deidentification/tsdoc.json b/sdk/healthdataaiservices/azure-health-deidentification/tsdoc.json deleted file mode 100644 index 81c5a8a2aa2f..000000000000 --- a/sdk/healthdataaiservices/azure-health-deidentification/tsdoc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", - "extends": ["../../../tsdoc.json"] -} diff --git a/sdk/healthdataaiservices/azure-health-deidentification/tsp-location.yaml b/sdk/healthdataaiservices/azure-health-deidentification/tsp-location.yaml index bc53597e9692..9c98e8b8ba5c 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/tsp-location.yaml +++ b/sdk/healthdataaiservices/azure-health-deidentification/tsp-location.yaml @@ -1,5 +1,4 @@ -repo: Azure/azure-rest-api-specs -additionalDirectories: [] -commit: dc4f9f316f20e45231df187971a4dad2e5dd8964 directory: specification/healthdataaiservices/HealthDataAIServices.DeidServices - +commit: 26af8eff710ea634da1b33fed369967d1c39b689 +repo: /mnt/vss/_work/1/s/azure-rest-api-specs +additionalDirectories: diff --git a/sdk/healthdataaiservices/azure-health-deidentification/vitest.browser.config.ts b/sdk/healthdataaiservices/azure-health-deidentification/vitest.browser.config.ts index 03b41edc2d8a..5e0dc418cfa2 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/vitest.browser.config.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/vitest.browser.config.ts @@ -1,17 +1,37 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { defineConfig, mergeConfig } from "vitest/config"; -import viteConfig from "../../../vitest.browser.shared.config.ts"; +import { defineConfig } from "vitest/config"; +import { relativeRecordingsPath } from "@azure-tools/test-recorder"; -export default mergeConfig( - viteConfig, - defineConfig({ - test: { - include: [ - "dist-test/browser/test/internal/**/*.spec.js", - "dist-test/browser/test/public/**/*.spec.js", - ], +process.env.RECORDINGS_RELATIVE_PATH = relativeRecordingsPath(); + +export default defineConfig({ + define: { + "process.env": process.env, + }, + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.spec.js"], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", }, - }), -); + testTimeout: 1200000, + }, +}); diff --git a/sdk/healthdataaiservices/azure-health-deidentification/vitest.config.ts b/sdk/healthdataaiservices/azure-health-deidentification/vitest.config.ts index b60f0effa527..f8ab2a758bf9 100644 --- a/sdk/healthdataaiservices/azure-health-deidentification/vitest.config.ts +++ b/sdk/healthdataaiservices/azure-health-deidentification/vitest.config.ts @@ -1,14 +1,33 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { defineConfig, mergeConfig } from "vitest/config"; -import viteConfig from "../../../vitest.shared.config.ts"; +import { defineConfig } from "vitest/config"; +import { relativeRecordingsPath } from "@azure-tools/test-recorder"; -export default mergeConfig( - viteConfig, - defineConfig({ - test: { - include: ["test/internal/**/*.spec.ts", "test/public/**/*.spec.ts"], +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", }, - }), -); + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + testTimeout: 1200000, + }, +}); diff --git a/sdk/healthdataaiservices/ci.yml b/sdk/healthdataaiservices/ci.yml index a95529288f3d..a859aa1b01ca 100644 --- a/sdk/healthdataaiservices/ci.yml +++ b/sdk/healthdataaiservices/ci.yml @@ -1,5 +1,5 @@ # NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. - + trigger: branches: include: @@ -9,7 +9,6 @@ trigger: paths: include: - sdk/healthdataaiservices - pr: branches: include: @@ -17,20 +16,18 @@ pr: - feature/* - release/* - hotfix/* + exclude: + - feature/v4 paths: include: - sdk/healthdataaiservices - parameters: - # Switch to canary to test canary 1es branch. 1es template validation will set this parameter - # to canary on run. - name: oneESTemplateTag type: string default: release values: - release - canary - extends: template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml parameters: