├── .azure-pipelines
├── ci-build-production.yml
└── common-templates
│ ├── security-post-checks.yml
│ └── security-pre-checks.yml
├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── 01-sdk-bug.yml
│ ├── 02-sdk-feature-request.yml
│ ├── 03-blank-issue.md
│ └── config.yml
├── dependabot.yml
├── policies
│ ├── msgraph-sdk-javascript-branch-protection.yml
│ └── resourceManagement.yml
├── pull_request_template.md
└── workflows
│ ├── ci_validation.yml
│ ├── codeql-analysis.yml
│ └── project-auto-add.yml
├── .gitignore
├── .huskyrc
├── .jshintrc
├── .lintstagedrc
├── .npmignore
├── .prettierignore
├── .prettierrc
├── .travis.yml
├── .vscode
├── launch.json
└── tasks.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README-Localized
├── README-es-es.md
├── README-fr-fr.md
├── README-ja-jp.md
├── README-pt-br.md
├── README-ru-ru.md
└── README-zh-cn.md
├── README.md
├── THIRD PARTY NOTICES
├── _config.yml
├── authProviderOptions
├── ReadMe.md
├── authCodeMsalBrowser
│ └── index.ts
├── azureTokenCredentials
│ └── index.ts
└── es
│ ├── authCodeMsalBrowser
│ └── index.ts
│ └── azureTokenCredentials
│ └── index.ts
├── babel.config.js
├── changelogs
└── v3-upgrade-guide.md
├── design
├── kiota-e2e.md
├── large-file-upload-task-design.md
└── publishing.md
├── docs
├── Actions.md
├── AuthCodeMSALBrowserAuthenticationProvider.md
├── CallingPattern.md
├── CancellingAHTTPRequest.md
├── ChaosHandlerSamples.md
├── CreatingClientInstance.md
├── CustomAuthenticationProvider.md
├── CustomMiddlewareChain.md
├── GettingRawResponse.md
├── OtherAPIs.md
├── QueryParameters.md
├── TokenCredentialAuthenticationProvider.md
├── content
│ └── Batching.md
└── tasks
│ ├── LargeFileUploadTask.md
│ └── PageIterator.md
├── gulpfile.js
├── karma.conf.js
├── lib
└── .npmignore
├── msgraph-sdk-javascript.yml
├── package-lock.json
├── package.json
├── rollup.config.js
├── sample.png
├── samples
├── javascript
│ ├── SampleRequests.js
│ ├── clientInitialization
│ │ ├── ClientWithOptions.js
│ │ └── tokenCredentialAuthenticationProvider
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ └── secrets.js
│ └── tasks
│ │ ├── LargeFileUploadTask.js
│ │ └── OneDriveLargeFileUploadTask.js
├── package-lock.json
├── package.json
├── tsconfig.json
└── typescript
│ ├── clientInitialization
│ ├── ClientWithOptions.ts
│ └── tokenCredentialAuthenticationProvider
│ │ └── index.ts
│ └── tasks
│ ├── LargeFileUploadTask.ts
│ └── OneDriveLargeFileUploadTask.ts
├── scripts
└── src
│ ├── AddGithubUser.ps1
│ ├── CalculateNewPreviewVersion.ps1
│ ├── CalculateNewProductionVersion.ps1
│ ├── CommitAndPushChangesToGithub.ps1
│ ├── GetLatestCommitSHA.ps1
│ ├── GetPackageVersion.ps1
│ ├── HasNewCommitsAfterLastProductionRelease.ps1
│ ├── HasNewCommitsAfterLastRelease.ps1
│ ├── MergeChangesTillLastestRelease.ps1
│ ├── MergeVersionChangesBackToPreviewBranch.ps1
│ └── RemoveGithubUser.ps1
├── shims.d.ts
├── src
├── Client.ts
├── Constants.ts
├── CustomAuthenticationProvider.ts
├── GraphClientError.ts
├── GraphError.ts
├── GraphErrorHandler.ts
├── GraphRequest.ts
├── GraphRequestUtil.ts
├── GraphResponseHandler.ts
├── HTTPClient.ts
├── HTTPClientFactory.ts
├── IAuthProvider.ts
├── IAuthProviderCallback.ts
├── IAuthenticationProvider.ts
├── IAuthenticationProviderOptions.ts
├── IClientOptions.ts
├── IContext.ts
├── IFetchOptions.ts
├── IGraphRequestCallback.ts
├── IOptions.ts
├── RequestMethod.ts
├── ResponseType.ts
├── ValidatePolyFilling.ts
├── Version.ts
├── authentication
│ ├── azureTokenCredentials
│ │ ├── ITokenCredentialAuthenticationProviderOptions.ts
│ │ ├── TokenCredentialAuthenticationProvider.ts
│ │ └── index.ts
│ ├── msal-browser
│ │ ├── AuthCodeMSALBrowserAuthenticationProvider.ts
│ │ └── index.ts
│ └── msalOptions
│ │ └── MSALAuthenticationProviderOptions.ts
├── browser
│ └── index.ts
├── content
│ ├── BatchRequestContent.ts
│ └── BatchResponseContent.ts
├── index.ts
├── middleware
│ ├── AuthenticationHandler.ts
│ ├── ChaosHandler.ts
│ ├── HTTPMessageHandler.ts
│ ├── IMiddleware.ts
│ ├── MiddlewareControl.ts
│ ├── MiddlewareFactory.ts
│ ├── MiddlewareUtil.ts
│ ├── RedirectHandler.ts
│ ├── RetryHandler.ts
│ ├── TelemetryHandler.ts
│ └── options
│ │ ├── AuthenticationHandlerOptions.ts
│ │ ├── ChaosHandlerData.ts
│ │ ├── ChaosHandlerOptions.ts
│ │ ├── ChaosStrategy.ts
│ │ ├── IMiddlewareOptions.ts
│ │ ├── RedirectHandlerOptions.ts
│ │ ├── RetryHandlerOptions.ts
│ │ └── TelemetryHandlerOptions.ts
└── tasks
│ ├── FileUploadTask
│ ├── FileObjectClasses
│ │ ├── FileUpload.ts
│ │ └── StreamUpload.ts
│ ├── Interfaces
│ │ └── IUploadEventHandlers.ts
│ ├── Range.ts
│ └── UploadResult.ts
│ ├── LargeFileUploadTask.ts
│ ├── OneDriveLargeFileUploadTask.ts
│ ├── OneDriveLargeFileUploadTaskUtil.ts
│ └── PageIterator.ts
├── test-esm
├── README.md
├── package-lock.json
├── package.json
├── tests
│ └── testESM.ts
└── tsconfig.json
├── test
├── DummyAuthenticationProvider.ts
├── DummyHTTPMessageHandler.ts
├── DummyHandlerOptions.ts
├── Tests.md
├── browser
│ ├── BrowserTests.md
│ └── core
│ │ └── GraphResponseHandler.ts
├── common
│ ├── authentication
│ │ └── AuthCodeMSALBrowserAuthenticationProvider.ts
│ ├── content
│ │ ├── BatchRequestContent.ts
│ │ └── BatchResponseContent.ts
│ ├── core
│ │ ├── Client.ts
│ │ ├── GraphClientError.ts
│ │ ├── GraphErrorHandler.ts
│ │ ├── GraphRequestUtil.ts
│ │ ├── GraphResponseHandler.ts
│ │ ├── HTTPClient.ts
│ │ ├── HTTPClientFactory.ts
│ │ ├── Range.ts
│ │ ├── urlGeneration.ts
│ │ └── urlParsing.ts
│ ├── middleware
│ │ ├── AuthenticationHandler.ts
│ │ ├── AuthenticationHandlerOptions.ts
│ │ ├── ChaosHandler.ts
│ │ ├── MiddlewareControl.ts
│ │ ├── MiddlewareFactory.ts
│ │ ├── MiddlewareUtil.ts
│ │ ├── RedirectHandler.ts
│ │ ├── RedirectHandlerOptions.ts
│ │ ├── RetryHandler.ts
│ │ ├── RetryHandlerOptions.ts
│ │ ├── TelemetryHandler.ts
│ │ └── TelemetryHandlerOptions.ts
│ └── tasks
│ │ ├── LargeFileUploadTask.ts
│ │ ├── OneDriveLargeFileUploadTask.ts
│ │ ├── OneDriveLargeFileUploadTaskUtil.ts
│ │ ├── PageIterator.ts
│ │ └── StreamUpload.ts
├── development
│ ├── DevelopmentTests.md
│ ├── HardCodedAuthenticationProvider.ts
│ ├── secrets.sample.ts
│ ├── test-helper.ts
│ └── workload
│ │ ├── OneNote.ts
│ │ ├── PageIterator.ts
│ │ ├── delta-query.ts
│ │ ├── excel.ts
│ │ ├── groups.ts
│ │ ├── insights.ts
│ │ ├── largeFileUpload.ts
│ │ ├── open-extensions.ts
│ │ └── users.ts
├── node
│ ├── NodeTests.md
│ ├── authentication
│ │ └── TokenCredentialAuthenticationProvider.ts
│ ├── content
│ │ └── BatchRequestContent.ts
│ └── tasks
│ │ └── StreamUpload.ts
├── sample_files
│ ├── empty-spreadsheet.xlsx
│ ├── onenotepage.html
│ ├── onenotepage_fileattachment.html
│ └── sample_image.jpg
├── test-helper.ts
└── tsconfig-test-development.json
├── tsconfig-base.json
├── tsconfig-cjs.json
├── tsconfig-es.json
├── tsconfig-sub-cjs.json
├── tsconfig-sub-es.json
└── types-demo.PNG
/.azure-pipelines/ci-build-production.yml:
--------------------------------------------------------------------------------
1 | # Node.js
2 | # Build a general Node.js project with npm.
3 | # Add steps that analyze code, save build artifacts, deploy, and more:
4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
5 |
6 | name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
7 |
8 | trigger:
9 | branches:
10 | include:
11 | - main
12 |
13 | pr: none
14 |
15 | stages:
16 | - stage: "Test"
17 | jobs:
18 | - job:
19 | pool:
20 | vmImage: windows-latest
21 | strategy:
22 | matrix:
23 | Node 14:
24 | NODE_VERSION: '14.x'
25 | Node 16:
26 | NODE_VERSION: '16.x'
27 | Node 18:
28 | NODE_VERSION: '18.x'
29 | Node 20:
30 | NODE_VERSION: '20.x'
31 | maxParallel: 2
32 | steps:
33 | - template: ./common-templates/security-pre-checks.yml
34 | - task: NodeTool@0
35 | inputs:
36 | versionSpec: $(NODE_VERSION)
37 | displayName: 'Install Node.js'
38 |
39 | - script: npm ci
40 | displayName: 'npm install for tests'
41 | - script: npm run build
42 | displayName: 'npm build for tests'
43 | - script: npm run test
44 | displayName: 'Run the node tests'
45 | - script: npm run karma
46 | displayName: 'Run karma tests'
47 |
48 | - task: PublishTestResults@2
49 | displayName: 'Publish Unit Test Results'
50 | inputs:
51 | testResultsFormat: 'JUnit'
52 | testResultsFiles: '**/testResult.xml'
53 | failTaskOnFailedTests: true
54 |
55 | - template: ./common-templates/security-post-checks.yml
56 |
57 | - stage: "Build"
58 | jobs:
59 | - job:
60 |
61 | pool:
62 | vmImage: ubuntu-latest
63 | steps:
64 | - task: NodeTool@0
65 | inputs:
66 | versionSpec: '16.x'
67 | displayName: 'Install Node.js'
68 |
69 | - script: |
70 | npm ci
71 | npm run build
72 | displayName: 'Build for production artifact'
73 | - task: CopyFiles@2
74 | inputs:
75 | sourceFolder: '$(Build.SourcesDirectory)'
76 | targetFolder: $(Build.ArtifactStagingDirectory)
77 | Contents: |
78 | **/*
79 | !.azure-pipelines/**
80 | !.github/**
81 | !.git/**
82 | !.vscode/**
83 | displayName: 'Copy npm package'
84 |
85 | - task: PublishBuildArtifacts@1
86 | inputs:
87 | pathtoPublish: $(Build.ArtifactStagingDirectory)
88 | artifactName: "release-drop"
89 | displayName: 'Publish artifacts'
90 |
91 |
--------------------------------------------------------------------------------
/.azure-pipelines/common-templates/security-post-checks.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Microsoft Corporation. All rights reserved.
2 | # Licensed under the MIT License.
3 | steps:
4 | - task: CodesignValidation@0
5 |
6 | - task: SdtReport@1
7 | displayName: "Security Analysis Report"
8 | continueOnError: true
9 | condition: succeededOrFailed()
10 | inputs:
11 | AllTools: false
12 | APIScan: false
13 | BinSkim: false
14 | BinSkimBreakOn: "WarningAbove"
15 | CodesignValidation: true
16 | CodesignValidationBreakOn: "WarningAbove"
17 | CredScan: true
18 | FortifySCA: false
19 | FxCop: false
20 | ModernCop: false
21 | MSRD: false
22 | PoliCheck: true
23 | PoliCheckBreakOn: "Severity1"
24 | RoslynAnalyzers: true
25 | RoslynAnalyzersBreakOn: "WarningAbove"
26 | SDLNativeRules: false
27 | Semmle: false
28 | TSLint: false
29 | TSLintBreakOn: "WarningAbove"
30 | ToolLogsNotFoundAction: "Standard"
31 |
32 | - task: PublishSecurityAnalysisLogs@3
33 | displayName: "Publish Security Analysis Logs"
34 | inputs:
35 | ArtifactName: "CodeAnalysisLogs"
36 | ArtifactType: "Container"
37 | AllTools: false
38 | AntiMalware: false
39 | APIScan: false
40 | BinSkim: false
41 | CodesignValidation: true
42 | CredScan: true
43 | FortifySCA: false
44 | FxCop: false
45 | ModernCop: true
46 | MSRD: false
47 | PoliCheck: true
48 | RoslynAnalyzers: true
49 | SDLNativeRules: false
50 | Semmle: false
51 | TSLint: false
52 | WebScout: false
53 | ToolLogsNotFoundAction: "Standard"
--------------------------------------------------------------------------------
/.azure-pipelines/common-templates/security-pre-checks.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Microsoft Corporation. All rights reserved.
2 | # Licensed under the MIT License.
3 | steps:
4 | - task: CredScan@2
5 | displayName: "Run CredScan"
6 | inputs:
7 | debugMode: false
8 | batchSize: 20
9 | toolMajorVersion: "V2"
10 | searchersFileType: "Skype"
11 |
12 | - task: PoliCheck@1
13 | displayName: "Run PoliCheck"
14 | condition: and(succeeded(), eq(eq(variables['Build.SourceBranch'], 'refs/heads/main'), false))
15 | inputs:
16 | targetType: F
17 | SOMEnabled: true
18 | optionsFC: 0
19 | optionsXS: 0
20 | optionsHMENABLE: 0
21 | continueOnError: true
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | *.js
2 | *.js.map
3 | *.d.ts
4 |
5 | node_modules
6 | lib
7 | spec/development
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.js linguist-language=TypeScript
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @microsoftgraph/msgraph-devx-typescript-write
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/02-sdk-feature-request.yml:
--------------------------------------------------------------------------------
1 | name: SDK Feature request
2 | description: Request a new feature on the SDK
3 | labels: ["type:feature", "status:waiting-for-triage"]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | **Thank you for taking the time to fill out this feature request form!**
9 | 💥Please search to see if an issue already exists for the feature you are requesting.
10 | - type: textarea
11 | attributes:
12 | label: Is your feature request related to a problem? Please describe the problem.
13 | description: A clear and concise description of what the problem is.
14 | placeholder: I am trying to do [...] but [...]
15 | validations:
16 | required: false
17 | - type: textarea
18 | attributes:
19 | label: Describe the solution you'd like.
20 | description: |
21 | A clear and concise description of what you want to happen. Include any alternative solutions you've considered.
22 | validations:
23 | required: true
24 | - type: textarea
25 | attributes:
26 | label: Additional context?
27 | description: |
28 | Add any other context or screenshots about the feature request here.
29 | validations:
30 | required: false
31 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/03-blank-issue.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Blank issue
3 | about: Something that doesn't fit the other categories
4 | title: ''
5 | labels: ["status:waiting-for-triage"]
6 | assignees: ''
7 |
8 | ---
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Question on use of graph sdk
4 | url: https://github.com/microsoftgraph/msgraph-sdk-javascript/discussions
5 | about: Please add your question in the discussions section of the repo
6 | - name: Question on use of kiota
7 | url: https://github.com/microsoft/kiota/discussions
8 | about: Please add your question in the discussions section of the repo
9 | - name: Question or Feature Request for the MS Graph API?
10 | url: https://aka.ms/msgraphsupport
11 | about: Report an issue or limitation with the MS Graph service APIs
12 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: weekly
7 | open-pull-requests-limit: 10
8 | groups:
9 | eslint:
10 | patterns:
11 | - "*eslint*"
12 | sinon:
13 | patterns:
14 | - "*sinon*"
15 | chai:
16 | patterns:
17 | - "*chai*"
18 | karma:
19 | patterns:
20 | - "*karma*"
21 | mocha:
22 | patterns:
23 | - "*mocha*"
24 | babel:
25 | patterns:
26 | - "*babel*"
27 | - package-ecosystem: github-actions
28 | directory: "/"
29 | schedule:
30 | interval: weekly
31 | open-pull-requests-limit: 10
32 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | A similar PR may already be submitted! Please search among the [Pull request](https://github.com/microsoftgraph/msgraph-sdk-javascript/pulls) before creating one.
2 |
3 | Thanks for submitting a pull request! Please provide enough information so that others can review your pull request.
4 |
5 | **NOTE: PR's will be accepted only in case of appropriate information is provided below**
6 |
7 | ## Summary
8 |
9 |
10 |
11 | ## Motivation
12 |
13 | Explain the **motivation** for making this change. What existing problem does the pull request solve?
14 |
15 |
16 |
17 | ## Test plan
18 |
19 | Demonstrate the code is solid. Example: The exact commands you ran and their output.
20 |
21 |
22 |
23 | ## Closing issues
24 |
25 |
26 |
27 | Fixes #
28 |
29 | ## Types of changes
30 |
31 |
32 |
33 | - [ ] Bug fix (non-breaking change which fixes an issue)
34 | - [ ] New feature (non-breaking change which adds functionality)
35 | - [ ] Breaking change (fix or feature that would cause existing functionality to change)
36 |
37 | ## Checklist
38 |
39 | - [ ] I have read the **CONTRIBUTING** document.
40 | - [ ] My code follows the code style of this project.
41 | - [ ] My change requires a change to the documentation.
42 | - [ ] I have updated the documentation accordingly.
43 | - [ ] I have added tests to cover my changes.
44 | - [ ] All new and existing tests passed.
45 |
--------------------------------------------------------------------------------
/.github/workflows/ci_validation.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Graph JS SDK CI
5 |
6 | on: [pull_request]
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: ubuntu-latest
12 |
13 | strategy:
14 | matrix:
15 | node-version: [16.x, 18.x, 20.x]
16 | steps:
17 | - uses: actions/checkout@v4
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v4
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 | - name: Install dependencies
23 | run: npm ci
24 |
25 | - name: Build for node 16, 18 & 20
26 | run: npm run build
27 |
28 | - name: Run unit tests
29 | run: npm test
30 |
31 | - name: Verify ESM compatibility
32 | working-directory: './test-esm'
33 | run: |
34 | npm ci
35 | npm test
36 |
37 | # The check-build-matrix returns success if all matrix jobs in build are successful; otherwise, it returns a failure.
38 | # Use this as a PR status check for GitHub Policy Service instead of individual matrix entry checks.
39 | check-build-matrix:
40 | runs-on: ubuntu-latest
41 | needs: build
42 | if: always()
43 | steps:
44 | - name: All build matrix options are successful
45 | if: ${{ !(contains(needs.*.result, 'failure')) }}
46 | run: exit 0
47 | - name: One or more build matrix options failed
48 | if: ${{ contains(needs.*.result, 'failure') }}
49 | run: exit 1
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ dev, 3.0.0, main, support/v2, v2/dev ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ dev ]
20 | schedule:
21 | - cron: '23 15 * * 4'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v4
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v3
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54 | # If this step fails, then you should remove it and run the build manually (see below)
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v3
57 |
58 | # ℹ️ Command-line programs to run using the OS shell.
59 | # 📚 https://git.io/JvXDl
60 |
61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62 | # and modify them (or add more) to build your code if your project
63 | # uses a compiled language
64 |
65 | #- run: |
66 | # make bootstrap
67 | # make release
68 |
69 | - name: Perform CodeQL Analysis
70 | uses: github/codeql-action/analyze@v3
71 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.vscode/*
2 | !/.vscode/launch.json
3 | !/.vscode/tasks.json
4 |
5 | .DS_Store
6 | .tmp
7 | tmp
8 | node_modules
9 | typings
10 | coverage
11 | **/*.tgz
12 | npm-debug.log
13 |
14 | /lib/*
15 | !/lib/.npmignore
16 |
17 | /authProviders/*
18 |
19 | src/**/*.js
20 | src/**/*.js.map
21 | src/**/*.d.ts
22 |
23 | samples/**/secrets.ts
24 | samples/node_modules/**
25 | samples/lib/
26 |
27 | test/development/secrets.ts
28 |
29 | .nyc_output/*
30 |
31 | .idea/*
32 |
33 | testResult.xml
34 | test-results.xml
35 |
36 | test-esm/lib/*
37 |
--------------------------------------------------------------------------------
/.huskyrc:
--------------------------------------------------------------------------------
1 | {
2 | "hooks": {
3 | "pre-commit": "npm run pre-build && git add src/Version.ts && lint-staged && npm run lint && npm run test"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esnext": "true"
3 | }
4 |
--------------------------------------------------------------------------------
/.lintstagedrc:
--------------------------------------------------------------------------------
1 | {
2 | "*.css": ["npm run format:css", "git add"],
3 | "*.html": ["npm run format:html", "git add"],
4 | "*.js": ["npm run format:js", "git add"],
5 | "*.json": ["npm run format:json", "git add"],
6 | "*.md": ["npm run format:md", "git add"],
7 | ".*rc": ["npm run format:rc", "git add"],
8 | "*.ts": ["npm run format:ts", "git add"]
9 | }
10 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src/
2 | scripts/
3 | design/
4 | changelogs/
5 | testResult.xml
6 | test-esm/
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | lib/
2 |
3 | scripts/**/*
4 |
5 | src/**/*.js
6 | src/**/*.js.map
7 | src/**/*.d.ts
8 |
9 | test/**/*.js
10 | test/**/*.js.map
11 | test/**/*.d.ts
12 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "arrowParens": "always",
3 | "bracketSpacing": true,
4 | "jsxBracketSameLine": true,
5 | "jsxSingleQuote": false,
6 | "printWidth": 5000,
7 | "proseWrap": "never",
8 | "semi": true,
9 | "singleQuote": false,
10 | "tabWidth": 4,
11 | "trailingComma": "all",
12 | "useTabs": true
13 | }
14 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "node"
4 | - "lts/*"
5 | - "10.15.1"
6 | - "10.0.0"
7 | - "9.11.2"
8 | - "9.0.0"
9 | - "8.15.0"
10 | - "8.0.0"
11 | - "7.10.1"
12 | - "7.0.0"
13 | - "6.16.0"
14 | - "6.0.0"
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "node",
9 | "request": "launch",
10 | "name": "Run Node samples",
11 | "program": "${workspaceRoot}/samples/node/main.js",
12 | "cwd": "${workspaceRoot}",
13 | "outFiles": [],
14 | "internalConsoleOptions": "openOnSessionStart"
15 | },
16 | {
17 | "type": "node",
18 | "request": "launch",
19 | "name": "Run Content tests",
20 | "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
21 | "args": ["${workspaceRoot}/lib/test/common/**/*.js"],
22 | "cwd": "${workspaceRoot}",
23 | "preLaunchTask": "Run Compile",
24 | "outFiles": [],
25 | "internalConsoleOptions": "openOnSessionStart"
26 | },
27 | {
28 | "type": "node",
29 | "request": "launch",
30 | "name": "Run Core tests",
31 | "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
32 | "args": ["${workspaceRoot}/lib/test/common/core/*.js"],
33 | "cwd": "${workspaceRoot}",
34 | "preLaunchTask": "Run Compile",
35 | "outFiles": [],
36 | "internalConsoleOptions": "openOnSessionStart"
37 | },
38 | {
39 | "type": "node",
40 | "request": "launch",
41 | "name": "Run Middleware tests",
42 | "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
43 | "args": ["${workspaceRoot}/lib/test/common/middleware/*.js"],
44 | "cwd": "${workspaceRoot}",
45 | "preLaunchTask": "Run Compile",
46 | "outFiles": [],
47 | "internalConsoleOptions": "openOnSessionStart"
48 | },
49 | {
50 | "type": "node",
51 | "request": "launch",
52 | "name": "Run Tasks tests",
53 | "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
54 | "args": ["${workspaceRoot}/lib/test/common/tasks/*.js"],
55 | "cwd": "${workspaceRoot}",
56 | "preLaunchTask": "Run Compile",
57 | "outFiles": [],
58 | "internalConsoleOptions": "openOnSessionStart"
59 | },
60 | {
61 | "type": "node",
62 | "request": "launch",
63 | "name": "Run Workload tests",
64 | "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
65 | "args": ["${workspaceRoot}/test/common/development/workload/*.js"],
66 | "cwd": "${workspaceRoot}",
67 | "preLaunchTask": "Run Compile",
68 | "outFiles": [],
69 | "internalConsoleOptions": "openOnSessionStart"
70 | }
71 | ]
72 | }
73 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "Run Compile",
8 | "type": "typescript",
9 | "tsconfig": "tsconfig-cjs.json",
10 | "group": "build"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.4.0
4 |
5 | New Features
6 |
7 | - Added Search query param functionality
8 |
9 | Bug Fixes
10 |
11 | - https://github.com/microsoftgraph/msgraph-sdk-javascript/issues/115
12 | - https://github.com/microsoftgraph/msgraph-sdk-javascript/issues/107
13 |
14 | ## 1.3.0
15 |
16 | New Features
17 |
18 | - Support for Large File upload [[#1](https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/driveitem_createuploadsession), [#2](https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/tasks/LargeFileUploadTask.md)]
19 | - Batching made easy [[#1](https://developer.microsoft.com/en-us/graph/docs/concepts/json_batching), [#2](https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/content/Batching.md)]
20 |
21 | Bug Fixes
22 |
23 | - https://github.com/microsoftgraph/msgraph-sdk-javascript/issues/97
24 | - https://github.com/microsoftgraph/msgraph-sdk-javascript/issues/110
25 | - https://github.com/microsoftgraph/msgraph-sdk-javascript/issues/39
26 | - https://github.com/microsoftgraph/msgraph-sdk-javascript/issues/111
27 |
28 | ## 1.2.0
29 |
30 | Updates
31 |
32 | - Two output js files, one with polyfills for Fetch-API and ES6-Promises lib/graph-js-sdk-web.js and one without lib/graph-js-sdk-core.js [Refer [README.md](https://github.com/microsoftgraph/msgraph-sdk-javascript#browser) for usage]
33 | - Enum for ResponseType, which lists down the available ResponseType options in autocomplete
34 |
35 | Bug Fix
36 |
37 | - Cannot access the property "request-id" of undefined in GraphError handling
38 |
39 | ## 1.1.0
40 |
41 | New Features
42 |
43 | - Support for Multipart POST request
44 |
45 | Updates
46 |
47 | - Light weight FetchAPI dependency (in replacement for SuperAgent)
48 |
49 | Bug Fixes
50 |
51 | - Updated putStream and getStream to work for all sized files
52 | - Added obfuscation for output js file (graph-js-sdk-web.js)
53 | - Updated versions of mocha and chai to 5.2.0 and 4.1.2 to fix security vulnerability in growl (which is a dependency of mocha)
54 | - Running unit test files under types directory
55 | - Compiling ts files
56 |
57 | ## 1.0.0
58 |
59 | - Added tests for new Graph functionality - Delta query, Extensibility, OneNote, and more.
60 |
61 | ## 0.4.0
62 |
63 | - Add support for ES5. Make sure to use `graph-js-sdk-web.js` for web apps
64 | - Removed iterator helper method.
65 |
66 | ## 0.3.1
67 |
68 | - Support for Node.js versions 4 and 5
69 |
70 | ## 0.3.0
71 |
72 | - Migrated away from typings in client library core and TypeScript sample
73 |
74 | ## 0.2.2
75 |
76 | - Updated SuperAgent to version `3.3.0`
77 |
78 | ## 0.2.0
79 |
80 | - **Breaking change for existing apps** - Initialize the client library with `MicrosoftGraph.Client.init({...})`. See the updated usage section below for code samples.
81 | - Added response handling tests to simulate Graph calls
82 | - Added type declarations file for core client library, which adds intellisense for chained methods.
83 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support)
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Microsoft Corporation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/THIRD PARTY NOTICES:
--------------------------------------------------------------------------------
1 | This file is based on or incorporates material from the projects listed below (Third Party OSS). The original copyright notice and the license under which Microsoft received such Third Party OSS, are set forth below. Such licenses and notices are provided for informational purposes only. Microsoft licenses the Third Party OSS to you under the licensing terms for the Microsoft product or service. Microsoft
2 | reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise.
3 |
4 | tslib
5 |
6 | isomorphic-fetch
7 |
8 | es6-promise
9 |
10 | Provided for Informational Purposes Only
11 |
12 | MIT License
13 |
14 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/authProviderOptions/ReadMe.md:
--------------------------------------------------------------------------------
1 | The authProviderOptions/ folders contains barrels for exporting Authentication Provider options such as MSAL and Azure Identity Token Credentials.
2 |
3 | [tsconfig-sub-cjs.json](../tsconfig-sub-es.json) and [tsconfig-sub-cjs.json](../tsconfig-sub-es.json) contains the config for transpiling the files to authProviders/ output folder.
4 |
5 | This approach is used because of the limitations of creating a submodule structure - References - https://github.com/microsoft/TypeScript/issues/8305 https://github.com/microsoft/TypeScript/issues/33079
6 |
--------------------------------------------------------------------------------
/authProviderOptions/authCodeMsalBrowser/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | export * from "../../lib/src/authentication/msal-browser/AuthCodeMSALBrowserAuthenticationProvider";
8 | export * from "../../lib/src/authentication/msalOptions/MSALAuthenticationProviderOptions";
9 |
--------------------------------------------------------------------------------
/authProviderOptions/azureTokenCredentials/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | export * from "../../lib/src/authentication/azureTokenCredentials/TokenCredentialAuthenticationProvider";
8 | export * from "../../lib/src/authentication/azureTokenCredentials/ITokenCredentialAuthenticationProviderOptions";
9 |
--------------------------------------------------------------------------------
/authProviderOptions/es/authCodeMsalBrowser/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | export * from "../../../lib/es/src/authentication/msal-browser/AuthCodeMSALBrowserAuthenticationProvider";
8 | export * from "../../../lib/es/src/authentication/msalOptions/MSALAuthenticationProviderOptions";
9 |
--------------------------------------------------------------------------------
/authProviderOptions/es/azureTokenCredentials/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | export * from "../../../lib/es/src/authentication/azureTokenCredentials/TokenCredentialAuthenticationProvider";
8 | export * from "../../../lib/es/src/authentication/azureTokenCredentials/ITokenCredentialAuthenticationProviderOptions";
9 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | const presets = [
4 | [
5 | "@babel/preset-env",
6 | {
7 | targets: {
8 | ie: 11,
9 | },
10 | },
11 | ],
12 | ];
13 |
14 | const plugins = [
15 | [
16 | "@babel/plugin-transform-runtime",
17 | {
18 | absoluteRuntime: false,
19 | corejs: false,
20 | helpers: true,
21 | regenerator: true,
22 | useESModules: false,
23 | },
24 | ],
25 | ];
26 | return {
27 | presets,
28 | plugins,
29 | };
30 | };
31 |
--------------------------------------------------------------------------------
/docs/AuthCodeMSALBrowserAuthenticationProvider.md:
--------------------------------------------------------------------------------
1 | #### Creating an instance of AuthCodeMSALBrowserAuthenticationProvider for a browser application
2 |
3 | **Note**: The `AuthCodeMSALBrowserAuthenticationProvider` is introduced in version 3.0.0 of Microsoft Graph Client Library
4 |
5 | ###### Links for more information -
6 |
7 | - [npm - @azure/msal-browser](https://www.npmjs.com/package/@azure/msal-browser)
8 | - [github - @azure/msal-browser](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/README.md)
9 |
10 | Steps to use `AuthCodeMSALBrowserAuthenticationProvider`;
11 |
12 | 1. Installation
13 |
14 | - Using npm: `npm install @azure/msal-browser @microsoft/microsoft-graph-client`
15 |
16 | - Using CDN:
17 |
18 | ```html
19 |
20 |
21 |
22 |
23 | ```
24 | Reference : [MSAL Browser CDN usage](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/cdn-usage.md)
25 |
26 | 2. Initialize the `msal-browser` `PublicClientApplication` instance: Learn more [how to initialize msal](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/initialization.md)
27 |
28 | 3. Following sample shows how to initialize a Microsoft Graph SDK `Client` instance,
29 |
30 | Using npm:
31 |
32 | ```typescript
33 | import { PublicClientApplication, InteractionType, AccountInfo } from "@azure/msal-browser";
34 |
35 | import { AuthCodeMSALBrowserAuthenticationProvider, AuthCodeMSALBrowserAuthenticationProviderOptions } from "@microsoft/microsoft-graph-client/authProviders/authCodeMsalBrowser";
36 | import { Client } from "@microsoft/microsoft-graph-client";
37 |
38 | const options: AuthCodeMSALBrowserAuthenticationProviderOptions = {
39 | account: account, // the AccountInfo instance to acquire the token for.
40 | interactionType: InteractionType.Popup, // msal-browser InteractionType
41 | scopes: ["user.read", "mail.send"] // example of the scopes to be passed
42 | };
43 |
44 | // Pass the PublicClientApplication instance from step 2 to create AuthCodeMSALBrowserAuthenticationProvider instance
45 | const authProvider = new AuthCodeMSALBrowserAuthenticationProvider(publicClientApplication, options);
46 |
47 |
48 | // Initialize the Graph client
49 | const graphClient = Client.initWithMiddleware({
50 | authProvider
51 | });
52 |
53 | ```
54 |
55 | Using CDN or script:
56 |
57 | ```javascript
58 | const msalClient = new msal.PublicClientApplication(msalConfig);
59 |
60 | const authProvider = new MSGraphAuthCodeMSALBrowserAuthProvider.AuthCodeMSALBrowserAuthenticationProvider(msalClient, {
61 | account, // the AccountInfo instance to acquire the token for
62 | scopes: ["user.read", "mail.send"],
63 | interactionType: msal.InteractionType.Popup,
64 | });
65 |
66 | // Initialize the Graph client
67 | const graphClient = MicrosoftGraph.Client.initWithMiddleware({ authProvider });
68 | ```
69 |
--------------------------------------------------------------------------------
/docs/CallingPattern.md:
--------------------------------------------------------------------------------
1 | # Calling Pattern
2 |
3 | All calls to Microsoft Graph are chained together starting with **.api()**, then chain [query parameters](./QueryParameters.md) and end with an [action](./Actions.md).
4 |
5 | ## Path supports the following formats
6 |
7 | - `me`
8 | - `/me`
9 | - `https://graph.microsoft.com/v1.0/me`
10 | - `https://graph.microsoft.com/beta/me`
11 | - `me/events?$filter=startswith(subject, "Adventure")`
12 |
13 | ## Promise based calling
14 |
15 | Getting user details with `async`/`await`,
16 |
17 | ```typescript
18 | try {
19 | let res = await client.api("/me").get();
20 | console.log(res);
21 | } catch (error) {
22 | throw error;
23 | }
24 | ```
25 |
26 | Getting user details with `then`/`catch`,
27 |
28 | ```typescript
29 | client
30 | .api("/me")
31 | .get()
32 | .then((res) => {
33 | console.log(res);
34 | })
35 | .catch((err) => {
36 | console.log(err);
37 | });
38 | ```
39 |
40 | ## Callback based calling
41 |
42 | Getting user details by passing `callback`,
43 |
44 | ```typescript
45 | client.api("/me").get((err, res) => {
46 | console.log(res);
47 | });
48 | ```
49 |
--------------------------------------------------------------------------------
/docs/CancellingAHTTPRequest.md:
--------------------------------------------------------------------------------
1 | # Cancel a HTTP request
2 |
3 | > The `abort()` method of the AbortController interface aborts a DOM request (e.g. a Fetch request)
4 | >
5 | > -- [AbortController interface](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
6 |
7 | References -
8 | * [AbortController interface](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
9 | * [abortcontroller npm](https://www.npmjs.com/package/abort-controller)
10 | * [abortcontroller-polyfill](https://www.npmjs.com/package/abortcontroller-polyfill)
11 | * [Example of the AbortController implementation](https://github.com/node-fetch/node-fetch#request-cancellation-with-abortsignal)
12 |
13 | #### Following is how canceling a fetch call works:
14 |
15 | * Create an AbortController instance.
16 | * That instance has a signal property.
17 | * Pass the signal as a fetch option for signal.
18 | * Call the AbortController's abort property to cancel all fetches that use that signal.
19 |
20 | #### Setting the AbortController.signal as a fetch option while creating the MSGraph SDK Client instance:
21 |
22 | ```typescript
23 | import { Client,FetchOptions } from "@microsoft/microsoft-graph-client";
24 | import { AbortController } from "abort-controller"; // <- import when using the abort-controller npm package.
25 |
26 | const controller = new AbortController();
27 |
28 | const timeout = setTimeout(() => {
29 | controller.abort();
30 | }, 150);
31 |
32 | const fetchOptions: FetchOptions = {
33 | signal: controller.signal;
34 | }
35 |
36 | const client = Client.initWithMiddleware({
37 | fetchOptions, // Pass the FetchOptions value where the AbortController.signal is set
38 | authProvider,
39 | ...
40 | });
41 | ```
42 |
--------------------------------------------------------------------------------
/docs/ChaosHandlerSamples.md:
--------------------------------------------------------------------------------
1 | # Testing Handler
2 |
3 | ### How to include
4 |
5 | > Uses [Custom Middleware Chain](https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomMiddlewareChain.md), it's not included in default middleware chain
6 |
7 | ### Modes in Chaos Handler
8 |
9 | - Manual mode - Setting the Response code manually. - Global/Client Level - Provide a map declared manually containing response code for the requests. - Request Level - Providing response code per request. This would be overriding the Global level response code (if any).
10 | - Random mode - We get a random Response code from a set of response code defined for each method.
11 |
12 | **A request Passes through to the Graph, if there is no entry for the request**
13 |
14 | **Note - Always add ChaosHandler before HttpMessageHandler in the middlewareChain**
15 |
16 | ### Samples
17 |
18 | ```js
19 | require("isomorphic-fetch");
20 | const MicrosoftGraph = require("../../lib/src/index.js");
21 | const secrets = require("./secrets");
22 | const fs = require("fs");
23 | // Initialising the client
24 | const client = MicrosoftGraph.Client.init({
25 | defaultVersion: "v1.0",
26 | debugLogging: true,
27 | authProvider: (done) => {
28 | done(null, secrets.accessToken);
29 | },
30 | });
31 |
32 | /*
33 | Create a custom MiddlewareChain passing information in this way
34 |
35 | const manualMap = new Map([["/me/messages/.*", new Map([["GET", 429], ["PATCH", 429]])], ["/me", new Map([["POST", 502]])]]);
36 | const chaosHandler = new MicrosoftGraph.ChaosHandler(new MicrosoftGraph.ChaosHandlerOptions(MicrosoftGraph.ChaosStrategy.MANUAL), manualMap);
37 | */
38 |
39 | // This request would use the Map (Manual mode)
40 | const mail = {
41 | subject: "Chaos Handler Samples",
42 | toRecipients: [
43 | {
44 | emailAddress: {
45 | address: "admin@M365x003297.OnMicrosoft.com",
46 | },
47 | },
48 | ],
49 | body: {
50 | content: "
Testing Handler Samples Sample
https://github.com/microsoftgraph/msgraph-sdk-javascript",
51 | contentType: "html",
52 | },
53 | };
54 | client
55 | .api("/users/me/sendMail")
56 | .post({
57 | message: mail,
58 | })
59 | .then((res) => {
60 | console.log(res, "This is for sendMail");
61 | })
62 | .catch((err) => {
63 | console.log(err, "This is for sendMail in error case");
64 | });
65 |
66 | // OverRiding to Random mode, providing the chaos percentage as 60(percentage times the error would be generated from handler)
67 | client
68 | .api("/me")
69 | .middlewareOptions([new MicrosoftGraph.ChaosHandlerOptions(MicrosoftGraph.ChaosStrategy.RANDOM, "I generated the error", undefined, 60)])
70 | .get()
71 | .then((res) => {
72 | console.log(res);
73 | })
74 | .catch((err) => {
75 | console.log(err);
76 | });
77 |
78 | // This request is passed to the graph and gets a response from the graph, as no entry for /me GET request in the Map
79 | client
80 | .api("/me")
81 | .get()
82 | .then((res) => {
83 | console.log("Found", res, "users");
84 | })
85 | .catch((err) => {
86 | console.log(err, "!!!!!!!!!");
87 | });
88 |
89 | // Using Manual Map with regex matching
90 | client
91 | .api("/me/messages/hjdlfslod-fdssdkjfs-6zdkmghs-sadhsu2")
92 | .header("content-type", "application/json")
93 | .update({
94 | birthday: "1908-12-22T00:00:00Z",
95 | })
96 | .then((res) => {
97 | console.log("This is regex matching... Updated Bday");
98 | })
99 | .catch((err) => {
100 | console.log(err, "matched");
101 | });
102 | ```
103 |
--------------------------------------------------------------------------------
/docs/CustomAuthenticationProvider.md:
--------------------------------------------------------------------------------
1 | # Using Custom Authentication Provider
2 |
3 | Using preferred choice of Authentication library for authenticating with Microsoft is possible.
4 |
5 | ## Step by step procedure
6 |
7 | ### Implement AuthenticationProvider
8 |
9 | Create own implementation of Authentication provider which implements [AuthenticationProvider](../src/IAuthenticationProvider.ts) interface.
10 |
11 | ```typescript
12 | // MyAuthenticationProvider.ts
13 | import { AuthenticationProvider } from "@microsoft/microsoft-graph-client";
14 |
15 | class MyAuthenticationProvider implements AuthenticationProvider {
16 | /**
17 | * This method will get called before every request to the msgraph server
18 | * This should return a Promise that resolves to an accessToken (in case of success) or rejects with error (in case of failure)
19 | * Basically this method will contain the implementation for getting and refreshing accessTokens
20 | */
21 | public async getAccessToken(): Promise {}
22 | }
23 | ```
24 |
25 | ### Initialize Client
26 |
27 | Pass instance of MyAuthenticationProvider while initializing.
28 |
29 | ```typescript
30 | import { MyAuthenticationProvider } from "./MyAuthenticationProvider";
31 |
32 | let clientOptions: ClientOptions = {
33 | authProvider: new MyAuthenticationProvider(),
34 | };
35 | const client = Client.initWithMiddleware(clientOptions);
36 | ```
37 |
--------------------------------------------------------------------------------
/docs/GettingRawResponse.md:
--------------------------------------------------------------------------------
1 | # Getting Raw Response
2 |
3 | Steps for getting the raw response [i.e [Response Object](https://developer.mozilla.org/en-US/docs/Web/API/Response)]
4 |
5 | ## Initialize the Client
6 |
7 | Refer [this documentation](./CreatingClientInstance.md) for initializing the client.
8 |
9 | ## Getting Raw Response by setting ResponseType
10 |
11 | To get the raw response set the responseType of a request to ResponseType.RAW.
12 |
13 | ```typescript
14 | const rawResponse = await client
15 | .api("/me")
16 | .select("displayName")
17 | .responseType(ResponseType.RAW)
18 | .get();
19 | console.log(rawResponse);
20 | ```
21 |
22 | Using callback method,
23 |
24 | ```typescript
25 | client
26 | .api("/me")
27 | .select("displayName")
28 | .responseType(ResponseType.RAW)
29 | .get((error, rawResponse) => {
30 | console.log(rawResponse);
31 | });
32 | ```
33 |
--------------------------------------------------------------------------------
/docs/tasks/PageIterator.md:
--------------------------------------------------------------------------------
1 | # PageIterator
2 |
3 | For a variety of reasons, collections of entities are often split into pages and each page is returned with a URL to the next page. Sometimes, page granularity provided by the API does not match the requirements of the consumer. PageIterator simplifies consuming of paged collections.
4 |
5 | ## Iterate over all the messages
6 |
7 | ```typescript
8 | async function callingPattern() {
9 | try {
10 | // Makes request to fetch mails list. Which is expected to have multiple pages of data.
11 | let response: PageCollection = await client.api("/me/messages").get();
12 | // A callback function to be called for every item in the collection. This call back should return boolean indicating whether not to continue the iteration process.
13 | let callback: PageIteratorCallback = (data) => {
14 | console.log(data);
15 | return true;
16 | };
17 | // Creating a new page iterator instance with client a graph client instance, page collection response from request and callback
18 | let pageIterator = new PageIterator(client, response, callback);
19 | // This iterates the collection until the nextLink is drained out.
20 | await pageIterator.iterate();
21 | } catch (e) {
22 | throw e;
23 | }
24 | }
25 | ```
26 |
27 | ## Stopping and Resuming the iteration
28 |
29 | ```typescript
30 | // Populating custom size pages if the api restricts to some maximum size. Lazy loading more data on user prompt or something, stop and resume will do the trick.
31 | async function customSize() {
32 | try {
33 | let response: PageCollection = await client.api("/me/messages").get();
34 | let size = 1000;
35 | let count = 0;
36 | let callback: PageIteratorCallback = (data) => {
37 | console.log(data);
38 | count++;
39 | if (count === size) {
40 | count = 0;
41 | return false;
42 | }
43 | return true;
44 | };
45 | let pageIterator = new PageIterator(client, response, callback);
46 | // This stops iterating over for 1000 entities.
47 | await pageIterator.iterate();
48 |
49 | // Resuming will do start from where it left off and iterate for next 1000 entities.
50 | // Check and resume is likely to be called in any user interaction requiring to load more data.
51 | if (!pageIterator.isComplete()) {
52 | await pageIterator.resume();
53 | }
54 | } catch (e) {
55 | throw e;
56 | }
57 | }
58 | ```
59 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const { series } = require("gulp");
2 |
3 | const licenseStr = `/**
4 | * -------------------------------------------------------------------------------------------
5 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
6 | * See License in the project root for license information.
7 | * -------------------------------------------------------------------------------------------
8 | */
9 | `;
10 |
11 | const moduleHeader = `/**
12 | * @module Version
13 | */
14 | `;
15 |
16 | const versionFile = `${licenseStr}
17 | // THIS FILE IS AUTO GENERATED
18 | // ANY CHANGES WILL BE LOST DURING BUILD
19 |
20 | ${moduleHeader}
21 | export const PACKAGE_VERSION = "[VERSION]";
22 | `;
23 |
24 | function setVersion(cb) {
25 | var pkg = require("./package.json");
26 | var fs = require("fs");
27 | fs.writeFileSync("src/Version.ts", versionFile.replace("[VERSION]", pkg.version));
28 | cb();
29 | }
30 |
31 | exports.setVersion = setVersion;
32 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 | config.set({
3 | frameworks: ["mocha", "chai", "karma-typescript"],
4 | files: ["test/common/**/*.ts", "src/**/!(azureTokenCredentials)/*.ts", "src/*.ts", "test/browser/**/*.ts", "test/*.ts"],
5 | preprocessors: {
6 | "**/*.ts": ["karma-typescript"],
7 | },
8 | karmaTypescriptConfig: {
9 | tsconfig: "./tsconfig-cjs.json",
10 | },
11 | browsers: ["ChromeHeadless"],
12 | });
13 | };
14 |
--------------------------------------------------------------------------------
/lib/.npmignore:
--------------------------------------------------------------------------------
1 | .npmignore
2 | test/
3 | **/*.tsbuildinfo
4 | es/test/
--------------------------------------------------------------------------------
/msgraph-sdk-javascript.yml:
--------------------------------------------------------------------------------
1 | page_type: sample
2 | products:
3 | - office-365
4 | - ms-graph
5 | languages:
6 | - javascript
7 | - typescript
8 | extensions:
9 | contentType: sdks
10 | technologies:
11 | - Microsoft Graph
12 | - Microsoft identity platform
13 | createdDate: '9/22/2016 2:44:49 PM'
14 | title: Microsoft Graph JavaScript Client Library
15 | description: Microsoft Graph client library for JavaScript
16 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import terser from "@rollup/plugin-terser";
9 | import resolve from "@rollup/plugin-node-resolve";
10 | import babel from "@rollup/plugin-babel";
11 | import commonjs from "@rollup/plugin-commonjs";
12 |
13 | const copyRight = `/**
14 | * -------------------------------------------------------------------------------------------
15 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
16 | * See License in the project root for license information.
17 | * -------------------------------------------------------------------------------------------
18 | */`;
19 |
20 | const config = [
21 | {
22 | input: ["lib/es/src/browser/index.js"],
23 | output: {
24 | file: "lib/graph-js-sdk.js",
25 | format: "iife",
26 | name: "MicrosoftGraph",
27 | },
28 | plugins: [
29 | resolve({
30 | browser: true,
31 | preferBuiltins: false,
32 | }),
33 | babel({
34 | babelHelpers: "runtime",
35 | exclude: "node_modules/**",
36 | }),
37 | commonjs({ include: "node_modules/**" }),
38 | terser({
39 | format: {
40 | comments: false,
41 | preamble: copyRight,
42 | },
43 | }),
44 | ],
45 | },
46 | {
47 | input: ["authProviders/es/azureTokenCredentials/index.js"],
48 | output: {
49 | file: "lib/graph-client-tokenCredentialAuthProvider.js",
50 | format: "iife",
51 | name: "MicrosoftGraphTokenCredentialAuthProvider",
52 | },
53 | plugins: [
54 | resolve({
55 | browser: true,
56 | preferBuiltins: false,
57 | }),
58 | babel({
59 | babelHelpers: "runtime",
60 | exclude: "node_modules/**",
61 | }),
62 | commonjs({ include: "node_modules/**" }),
63 | terser({
64 | format: {
65 | comments: false,
66 | preamble: copyRight,
67 | },
68 | }),
69 | ],
70 | },
71 | {
72 | input: ["lib/es/src/authentication/msal-browser/AuthCodeMSALBrowserAuthenticationProvider.js"],
73 | external: ["@azure/msal-browser"],
74 | output: {
75 | file: "lib/graph-client-msalBrowserAuthProvider.js",
76 | format: "iife",
77 | name: "MSGraphAuthCodeMSALBrowserAuthProvider",
78 | globals: {
79 | "@azure/msal-browser": "msal",
80 | },
81 | },
82 | plugins: [
83 | resolve({
84 | browser: true,
85 | preferBuiltins: false,
86 | }),
87 | babel({
88 | babelHelpers: "runtime",
89 | exclude: "node_modules/**",
90 | }),
91 | commonjs({ include: "node_modules/**" }),
92 | terser({
93 | format: {
94 | comments: false,
95 | preamble: copyRight,
96 | },
97 | }),
98 | ],
99 | },
100 | ];
101 |
102 | export default config;
103 |
--------------------------------------------------------------------------------
/sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-javascript/db1757abe7a4cad310f0cd4d7d2a83b961390cce/sample.png
--------------------------------------------------------------------------------
/samples/javascript/clientInitialization/ClientWithOptions.js:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | const { Client } = require("@microsoft/microsoft-graph-client");
9 | require("isomorphic-fetch");
10 |
11 | const error = "error throw by the authentication handler";
12 |
13 | const client = Client.init({
14 | defaultVersion: "v1.0",
15 | debugLogging: true,
16 | authProvider: (done) => {
17 | done(error, "ACCESS_TOKEN");
18 | },
19 | });
20 |
21 | client
22 | .api("/me")
23 | .select("displayName")
24 | .get()
25 | .then((res) => {
26 | console.log(res);
27 | })
28 | .catch((err) => {
29 | console.log(err);
30 | });
31 |
32 | module.exports = {
33 | client: client,
34 | };
35 |
--------------------------------------------------------------------------------
/samples/javascript/clientInitialization/tokenCredentialAuthenticationProvider/README.md:
--------------------------------------------------------------------------------
1 | # Sample of passing a ClientSecretCredential to the Javascript Client Library
2 |
3 | 1. Register your application to enable authentication to Azure Active Directory using the client secret credential. For more details, please check the following links
4 |
5 | - [Register an application](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app)
6 |
7 | - [Documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application).
8 |
9 | 2. Update your `clientId`, `tenantId`, `scopes`, `clientSecret`, `port` in the index.js .
10 |
11 | ## Run Sample
12 |
13 | 1. Navigate to project home [../../]
14 |
15 | 2. Run `npm install` to install the application.
16 |
17 | 3. Run `npm run build` to build the library files.
18 |
19 | 4. Navigate to the samples folder [./samples]and run `npm install`
20 |
21 | 5. Navigate to secrets.js[./secrets] and populate all the values (tenantId, clientId, clientSecret, scopes)
22 |
23 | 6. Navigate to tokenCredentialAuthenticationProvider[./samples/javascript/clientInitialization/tokenCredentialAuthenticationProvider] in the samples directory.
24 |
25 | 7. For running this javascript sample, run `node index.js`
26 |
--------------------------------------------------------------------------------
/samples/javascript/clientInitialization/tokenCredentialAuthenticationProvider/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | const { Client } = require("@microsoft/microsoft-graph-client");
9 | const { TokenCredentialAuthenticationProvider } = require("@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials");
10 | const { ClientSecretCredential } = require("@azure/identity");
11 | const { clientId, clientSecret, scopes, tenantId } = require("./secrets");
12 |
13 | require("isomorphic-fetch");
14 |
15 | const port = "";
16 | const redirectUri = `http://localhost:${port}/authresponse`;
17 | const authorityHost = "https://login.microsoftonline.com";
18 |
19 | const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
20 | const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: [scopes] });
21 | const client = Client.initWithMiddleware({
22 | debugLogging: true,
23 | authProvider,
24 | });
25 |
26 | client
27 | .api("/me")
28 | .select("displayName")
29 | .get()
30 | .then((res) => {
31 | console.log(res);
32 | })
33 | .catch((err) => {
34 | console.log(err);
35 | });
36 |
37 | module.exports = {
38 | client: client,
39 | };
40 |
--------------------------------------------------------------------------------
/samples/javascript/clientInitialization/tokenCredentialAuthenticationProvider/secrets.js:
--------------------------------------------------------------------------------
1 | const tenantId = "";
2 | const clientId = "";
3 | const clientSecret = "";
4 | const scopes = "";
5 |
6 | module.exports = {
7 | tenantId: tenantId,
8 | clientId: clientId,
9 | clientSecret: clientSecret,
10 | scopes: scopes
11 | }
--------------------------------------------------------------------------------
/samples/javascript/tasks/LargeFileUploadTask.js:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | // First, create an instance of the Microsoft Graph JS SDK Client class
8 | const { client } = require("../clientInitialization/ClientWithOptions");
9 | /**
10 | * OR
11 | * const { client } = require("../clientInitialization/TokenCredentialAuthenticationProvider");
12 | * OR
13 | * require or import client created using an custom authentication provider
14 | */
15 | const fs = require("fs");
16 | const { LargeFileUploadTask } = require("@microsoft/microsoft-graph-types");
17 | require("isomorphic-fetch");
18 |
19 | async function upload() {
20 | const fileName = "FILE_NAME";
21 | const file = fs.createReadStream(`./${fileName}`);
22 |
23 | const stats = fs.statSync(`./${fileName}`);
24 | const totalSize = stats.size;
25 |
26 | const progress = (range, extraCallbackParam) => {
27 | // Implement the progress callback here
28 | console.log("uploading range: ", range);
29 | console.log(extraCallbackParam);
30 | };
31 |
32 | const uploadEventHandlers = {
33 | progress,
34 | extraCallbackParam: "Any parameter needed by the callback implementation",
35 | };
36 |
37 | const options = {
38 | rangeSize: 1024 * 1024,
39 | uploadEventHandlers,
40 | };
41 |
42 | // Create upload session for OneDrive or SharePoint Upload"
43 | const payload = {
44 | item: {
45 | "@microsoft.graph.conflictBehavior": "rename",
46 | },
47 | };
48 |
49 | const uploadSession = await new LargeFileUploadTask.createUploadSession(client, "https://graph.microsoft.com/v1.0/sites/root/drive/items/{item-id}/createuploadsession", payload);
50 |
51 | // OR
52 | // Create upload session for Outlook API
53 | // const uploadSessionURL = `me/messages/${messageId}/attachments/createUploadSession`;
54 | // const payload = {
55 | // AttachmentItem: {
56 | // attachmentType: 'file',
57 | // name: "FILE_NAME",
58 | // size: totalSize,
59 | // }
60 | // }
61 |
62 | const fileObject = new StreamUpload(file, fileName, totalSize);
63 |
64 | // OR
65 | // You can also use a FileUpload instance
66 | // const file = fs.readFileSync();
67 | // const fileObject = new FileUpload(file, fileName, totalSize);
68 |
69 | // OR
70 | // You can also create an object from a custom implementation of the FileObject interface
71 | const task = new MicrosoftGraph.LargeFileUploadTask(client, fileObject, uploadSession, options);
72 | const uploadResult = await task.upload();
73 | return uploadResult;
74 | }
75 |
76 | upload()
77 | .then((uploadResult) => console.log(uploadResult))
78 | .catch((error) => console.log(error));
79 |
--------------------------------------------------------------------------------
/samples/javascript/tasks/OneDriveLargeFileUploadTask.js:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | // First, create an instance of the Microsoft Graph JS SDK Client class.
9 |
10 | const { client } = require("../clientInitialization/ClientWithOptions");
11 | /**
12 | * OR
13 | * const { client } = require("../clientInitialization/TokenCredentialAuthenticationProvider");
14 | * OR
15 | * require or import client created using an custom authentication provider
16 | */
17 |
18 | const fs = require("fs");
19 | const { OneDriveLargeFileUploadTask, StreamUpload } = require("@microsoft/microsoft-graph-client");
20 | require("isomorphic-fetch");
21 |
22 | async function upload() {
23 | const fileName = "FILE_NAME";
24 | const file = fs.createReadStream(`./${fileName}`);
25 | const totalsize = stats.size;
26 |
27 | const progress = (range, extraCallbackParam) => {
28 | // implement the progress callback here
29 | console.log("uploading range: ", range);
30 | console.log(extraCallbackParam);
31 | return true;
32 | };
33 |
34 | const uploadEventHandlers = {
35 | progress,
36 | extraCallbackParam: "any parameter needed by the callback implementation",
37 | };
38 |
39 | const options = {
40 | fileName,
41 | conflictBehavior: "rename",
42 | rangeSize: 1024 * 1024,
43 | uploadEventHandlers,
44 | };
45 |
46 | const fileObject = new StreamUpload(file, fileName, totalsize);
47 | //OR
48 | // You can also use a FileUpload instance
49 | //const file = fs.readFileSync();
50 | //const fileObject = new FileUpload(file, fileName, totalsize);
51 |
52 | //OR
53 | // You can also create an object from a custom implementation of the FileObject interface
54 | const task = await OneDriveLargeFileUploadTask.createTaskWithFileObject(client, fileObject, options);
55 | const uploadResult = await task.upload();
56 | return uploadResult;
57 | }
58 |
59 | upload()
60 | .then((uploadResult) => console.log(uploadResult))
61 | .catch((error) => console.log(error));
62 |
--------------------------------------------------------------------------------
/samples/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "samples",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build:typescript": "tsc"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "@azure/identity": "^3.1.2",
14 | "@microsoft/microsoft-graph-client": "file:../",
15 | "isomorphic-fetch": "^3.0.0",
16 | "ts-node": "^9.1.1",
17 | "typescript": "^4.2.4"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "strict": true,
6 | "outDir": "lib"
7 | },
8 | "include": ["typescript/"]
9 | }
10 |
--------------------------------------------------------------------------------
/samples/typescript/clientInitialization/ClientWithOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { Client } from "@microsoft/microsoft-graph-client";
9 |
10 | const error = "error throw by the authentication handler";
11 |
12 | export const client = Client.init({
13 | defaultVersion: "v1.0",
14 | debugLogging: true,
15 | authProvider: (done) => {
16 | done(error, "ACCESS_TOKEN");
17 | },
18 | });
19 |
20 | // Following is the example of how to make requests to the Microsoft Graph API using the client instance
21 |
22 | client
23 | .api("/me")
24 | .select("displayName")
25 | .get()
26 | .then((res) => {
27 | console.log(res);
28 | })
29 | .catch((err) => {
30 | console.log(err);
31 | });
32 |
--------------------------------------------------------------------------------
/samples/typescript/clientInitialization/tokenCredentialAuthenticationProvider/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | /* eslint-disable @typescript-eslint/no-unused-vars*/
8 |
9 | import "isomorphic-fetch";
10 |
11 | import { ClientSecretCredential } from "@azure/identity";
12 | import { Client } from "@microsoft/microsoft-graph-client";
13 | import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials";
14 |
15 | const port = "";
16 | const tenantId = "";
17 | const clientId = "";
18 | const clientSecret = "";
19 | const scopes = "";
20 | const redirectUri = `http://localhost:${port}/authresponse`;
21 | const authorityHost = "https://login.microsoftonline.com";
22 |
23 | async function runExample() {
24 | const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
25 | const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: [scopes] });
26 | const client = Client.initWithMiddleware({
27 | debugLogging: true,
28 | authProvider,
29 | });
30 | const res = await client.api("/users/").get();
31 | console.log(res);
32 | }
33 |
34 | runExample().catch((err) => {
35 | console.log("Encountered an error:\n\n", err);
36 | });
37 |
--------------------------------------------------------------------------------
/samples/typescript/tasks/LargeFileUploadTask.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | /* eslint-disable @typescript-eslint/no-unused-vars*/
8 | /* eslint-disable simple-import-sort/imports*/
9 |
10 | // First, create an instance of the Microsoft Graph JS SDK Client class
11 |
12 | import { LargeFileUploadSession, LargeFileUploadTask, LargeFileUploadTaskOptions, Range, StreamUpload, UploadEventHandlers, UploadResult } from "@microsoft/microsoft-graph-client";
13 | import * as fs from "fs";
14 | import { client } from "../clientInitialization/ClientWithOptions";
15 | /**
16 | * OR
17 | * import { client } from ("../clientInitialization/TokenCredentialAuthenticationProvider");
18 | * OR
19 | * require or import client created using an custom authentication provider
20 | */
21 |
22 | async function upload(): Promise {
23 | const file = fs.createReadStream("./test.pdf");
24 |
25 | const stats = fs.statSync(`./test.pdf`);
26 | const totalSize = stats.size;
27 |
28 | const progress = (range?: Range, extraCallbackParam?: unknown) => {
29 | // Implement the progress callback here
30 |
31 | console.log("uploading range: ", range);
32 | console.log(extraCallbackParam);
33 | };
34 |
35 | const uploadEventHandlers: UploadEventHandlers = {
36 | progress,
37 | extraCallbackParam: "any parameter needed by the callback implementation",
38 | };
39 |
40 | const options: LargeFileUploadTaskOptions = {
41 | rangeSize: 1024 * 1024,
42 | uploadEventHandlers,
43 | };
44 |
45 | // Create upload session for OneDrive or SharePoint Upload"
46 | const payload = {
47 | item: {
48 | "@microsoft.graph.conflictBehavior": "rename",
49 | },
50 | };
51 |
52 | const uploadSession: LargeFileUploadSession = await LargeFileUploadTask.createUploadSession(client, "https://graph.microsoft.com/v1.0/sites/root/drive/items/{item-id}/createuploadsession", payload);
53 |
54 | // OR
55 | // Create upload session for Outlook API
56 | // const uploadSessionURL = `me/messages/${messageId}/attachments/createUploadSession`;
57 | // const payload = {
58 | // AttachmentItem: {
59 | // attachmentType: 'file',
60 | // name: "FILE_NAME",
61 | // size: totalSize,
62 | // }
63 | // }
64 |
65 | const fileObject = new StreamUpload(file, "test.pdf", totalSize);
66 |
67 | // OR
68 | // You can also use a FileUpload instance
69 | // const file = fs.readFileSync();
70 | // const fileObject = new FileUpload(file, 'test.pdf', totalSize);
71 |
72 | // OR
73 | // You can also create an object from a custom implementation of FileObject
74 | const task = new LargeFileUploadTask(client, fileObject, uploadSession, options);
75 | const uploadResult = await task.upload();
76 | return uploadResult;
77 | }
78 |
79 | upload()
80 | .then((uploadResult) => console.log(uploadResult))
81 | .catch((error) => console.log(error));
82 |
--------------------------------------------------------------------------------
/samples/typescript/tasks/OneDriveLargeFileUploadTask.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | // First, create an instance of the Microsoft Graph JS SDK Client class
9 | /* eslint-disable simple-import-sort/imports*/
10 |
11 | import { OneDriveLargeFileUploadOptions, OneDriveLargeFileUploadTask, Range, StreamUpload, UploadEventHandlers, UploadResult } from "@microsoft/microsoft-graph-client";
12 | import * as fs from "fs";
13 | import { Readable } from "stream";
14 | import { client } from "../clientInitialization/ClientWithOptions";
15 | /**
16 | * OR
17 | * import { client } from ("../clientInitialization/TokenCredentialAuthenticationProvider");
18 | * OR
19 | * require or import client created using an custom authentication provider
20 | */
21 |
22 | async function upload() {
23 | const file = fs.createReadStream("./test.pdf");
24 | const fileName = "FILENAME";
25 | const fileDescription = "FILEDESCRIPTION";
26 | const stats = fs.statSync(`./test.pdf`);
27 | const totalSize = stats.size;
28 |
29 | const progress = (range?: Range, extraCallBackParam?: unknown) => {
30 | console.log("uploading range: ", range);
31 | console.log(extraCallBackParam);
32 | return true;
33 | };
34 |
35 | const uploadEventHandlers: UploadEventHandlers = {
36 | progress,
37 | extraCallbackParam: "any parameter needed by the callback implementation",
38 | };
39 |
40 | const options: OneDriveLargeFileUploadOptions = {
41 | fileName,
42 | fileDescription,
43 | conflictBehavior: "rename",
44 | rangeSize: 1024 * 1024,
45 | uploadEventHandlers,
46 | };
47 |
48 | const stream = new StreamUpload(file, "test.pdf", totalSize);
49 | const task = await OneDriveLargeFileUploadTask.createTaskWithFileObject(client, stream, options);
50 | const uploadResult: UploadResult = await task.upload();
51 | return uploadResult;
52 | }
53 |
54 | upload()
55 | .then((uploadResult) => console.log(uploadResult))
56 | .catch((error) => console.log(error));
57 |
--------------------------------------------------------------------------------
/scripts/src/AddGithubUser.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$gitUserName,
3 | [string]$gitUserEmailId,
4 | [string]$gitRepoRoot
5 | )
6 |
7 | Write-Host "Configuring Github User:" -ForegroundColor Magenta;
8 |
9 | Set-Location -Path $gitRepoRoot;
10 | Write-Host "Location changed to Git Repo Root '$(Get-Location)'" -ForegroundColor Green;
11 |
12 | git config user.name $gitUserName
13 | git config user.email $gitUserEmailId
14 | Write-Host "Git user.name=$($gitUserName) and user.email=$($gitUserEmailId) is set." -ForegroundColor Green;
--------------------------------------------------------------------------------
/scripts/src/CalculateNewPreviewVersion.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$owner,
3 | [string]$repo,
4 | [string]$previewStr
5 | )
6 |
7 | Write-Host "Calculating new Preview Version:" -ForegroundColor Magenta;
8 |
9 | $newVersionStr;
10 |
11 | $releasesUrl = "https://api.github.com/repos/$($owner)/$($repo)/releases";
12 |
13 | Write-Host "Getting list of releases with '$($releasesUrl)'" -ForegroundColor Blue;
14 | $releasesJSON = Invoke-RestMethod -Uri $releasesUrl -Method Get;
15 |
16 | if ($releasesJSON.Count -eq 0) {
17 | Write-Host "Unable to get releases list with '$($releasesUrl)'" -ForegroundColor Red;
18 | Write-Host "NOTE: This Script cannot handle the first release" -ForegroundColor Cyan;
19 | EXIT 1;
20 | }
21 |
22 | $lastReleaseJSON = $releasesJSON[0];
23 | $lastReleaseVersionStr = $lastReleaseJSON.tag_name;
24 | $isPreRelease = $lastReleaseJSON.prerelease;
25 |
26 | if ([string]::IsNullOrEmpty($lastReleaseVersionStr)) {
27 | Write-Host "Unable read the last release tag name" -ForegroundColor Red;
28 | Write-Host "Last Release Data:" -ForegroundColor Cyan;
29 | Write-Host -Object $lastReleaseJSON -ForegroundColor Cyan;
30 | EXIT 1;
31 | }
32 |
33 | if ([string]::IsNullOrEmpty($isPreRelease)) {
34 | Write-Host "Unable read the last release is pre-release or not" -ForegroundColor Red;
35 | Write-Host "Last Release Data:" -ForegroundColor Cyan;
36 | Write-Host -Object $lastReleaseJSON -ForegroundColor Cyan;
37 | EXIT 1;
38 | }
39 |
40 | $isPreRelease = $isPreRelease -as [bool];
41 | $versionArr = $lastReleaseVersionStr.split(".");
42 | if ($isPreRelease) {
43 | if (!$versionArr[2].Contains("-$($previewStr)")) {
44 | Write-Host "Lastest release '$($lastReleaseVersionStr)' is mentioned as pre-release but '$($previewStr)' is missing in version string" -ForegroundColor Red;
45 | Write-Host "Last Release Data:" -ForegroundColor Cyan;
46 | Write-Host -Object $lastReleaseJSON -ForegroundColor Cyan;
47 | EXIT 1;
48 | }
49 | $previewVersionStr = $versionArr[$versionArr.Count - 1];
50 | $previewVersion = $previewVersionStr -as [int];
51 | $newPreviewVersion = $previewVersion + 1;
52 | $versionArr[$versionArr.Count - 1] = $newPreviewVersion;
53 | $newVersionStr = $versionArr -join ".";
54 | Write-Host "Current version is '$($lastReleaseVersionStr)'" -ForegroundColor Blue;
55 | Write-Host "New calculated version is '$($newVersionStr)'" -ForegroundColor Green;
56 | }
57 | else {
58 | if ($versionArr[2].Contains("-$($previewStr)")) {
59 | Write-Host "Lastest release '$($lastReleaseVersionStr)' is mentioned as production release but version string has '$($previewStr)'" -ForegroundColor Red;
60 | Write-Host "Last Release Data:" -ForegroundColor Cyan;
61 | Write-Host -Object $lastReleaseJSON -ForegroundColor Cyan;
62 | EXIT 1;
63 | }
64 | $minorVersionStr = $versionArr[1];
65 | $minorVersion = $minorVersionStr -as [int];
66 | $newMinorVersion = $minorVersion + 1;
67 | $newPatchVersion = 0;
68 | $newPreviewVersion = 1;
69 | $versionArr[1] = $newMinorVersion;
70 | $versionArr[2] = "$($newPatchVersion)-$($previewStr).$($newPreviewVersion)";
71 | $newVersionStr = $versionArr -join ".";
72 | Write-Host "Current version is '$($lastReleaseVersionStr)'" -ForegroundColor Blue;
73 | Write-Host "New calculated version is '$($newVersionStr)'" -ForegroundColor Green;
74 | }
75 |
76 | Write-Host "##vso[task.setvariable variable=NEW_VERSION_STRING]$($newVersionStr)";
77 |
78 | Write-Host "Updated new version in global variable" -ForegroundColor Green;
--------------------------------------------------------------------------------
/scripts/src/CalculateNewProductionVersion.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$owner,
3 | [string]$repo,
4 | [string]$previewStr
5 | )
6 |
7 | Write-Host "Calculating new Production Version:" -ForegroundColor Magenta;
8 |
9 | $newVersionStr;
10 |
11 | $releasesUrl = "https://api.github.com/repos/$($owner)/$($repo)/releases";
12 |
13 | Write-Host "Getting list of releases with '$($releasesUrl)'" -ForegroundColor Blue;
14 | $releasesJSON = Invoke-RestMethod -Uri $releasesUrl -Method Get;
15 |
16 | if ($releasesJSON.Count -eq 0) {
17 | Write-Host "Unable to get releases list with '$($releasesUrl)'" -ForegroundColor Red;
18 | Write-Host "NOTE: This Script cannot handle the first release" -ForegroundColor Cyan;
19 | EXIT 1;
20 | }
21 |
22 | $latestReleaseJSON = $releasesJSON[0];
23 | $latestReleaseVersionStr = $latestReleaseJSON.tag_name;
24 | $isPreRelease = $latestReleaseJSON.prerelease;
25 |
26 | if ([string]::IsNullOrEmpty($latestReleaseVersionStr)) {
27 | Write-Host "Unable read the latest release tag name" -ForegroundColor Red;
28 | Write-Host "Latest Release Data:" -ForegroundColor Cyan;
29 | Write-Host -Object $latestReleaseJSON -ForegroundColor Cyan;
30 | EXIT 1;
31 | }
32 |
33 | if ([string]::IsNullOrEmpty($isPreRelease)) {
34 | Write-Host "Unable read the latest release is pre-release or not" -ForegroundColor Red;
35 | Write-Host "Latest Release Data:" -ForegroundColor Cyan;
36 | Write-Host -Object $latestReleaseJSON -ForegroundColor Cyan;
37 | EXIT 1;
38 | }
39 |
40 | $isPreRelease = $isPreRelease -as [bool];
41 |
42 | if (!$isPreRelease) {
43 | Write-Host "Preview is not released for the latest changes in '$($branchName)' branch" -ForegroundColor Red;
44 | Write-Host "Latest Release Data:" -ForegroundColor Cyan;
45 | Write-Host -Object $latestReleaseJSON -ForegroundColor Cyan;
46 | EXIT 1;
47 | }
48 |
49 | $versionArr = $latestReleaseVersionStr.split("-");
50 |
51 | if ([string]::IsNullOrEmpty($versionArr[1])) {
52 | Write-Host "Latest release is a Preview release but the '$($previewStr)' is missing in version string $($latestReleaseVersionStr)" -ForegroundColor Red;
53 | Write-Host "Latest Release Data:" -ForegroundColor Cyan;
54 | Write-Host -Object $latestReleaseJSON -ForegroundColor Cyan;
55 | EXIT 1;
56 | }
57 |
58 | $newVersionStr = $versionArr[0];
59 |
60 | Write-Host "Current version is '$($latestReleaseVersionStr)'" -ForegroundColor Blue;
61 | Write-Host "New calculated version is '$($newVersionStr)'" -ForegroundColor Green;
62 |
63 | Write-Host "##vso[task.setvariable variable=NEW_VERSION_STRING]$($newVersionStr)";
64 |
65 | Write-Host "Updated new version in global variable" -ForegroundColor Green;
--------------------------------------------------------------------------------
/scripts/src/CommitAndPushChangesToGithub.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$owner,
3 | [string]$repo,
4 | [string]$branchName,
5 | [string]$newVersion,
6 | [string]$gitPat
7 | )
8 |
9 | Write-Host "Pushing Version bump change to Github:" -ForegroundColor Magenta;
10 |
11 | Write-Host "Adding Changes." -ForegroundColor Blue;
12 | git add . | Write-Host;
13 | Write-Host "Changes added to the '$($branchName)' branch." -ForegroundColor Green;
14 |
15 | Write-Host "Committing Changes." -ForegroundColor Blue;
16 | git commit -m "Bumped version to '$($newVersion)'" | Write-Host;
17 | Write-Host "Committed the changes to the '$($branchName)' branch." -ForegroundColor Green;
18 |
19 | Write-Host "Pushing changes." -ForegroundColor Blue;
20 | git push "https://$($gitPat)@github.com/$($owner)/$($repo).git" HEAD:$branchName | Write-Host;
21 | Write-Host "Pushed the changes to the '$($branchName)' branch." -ForegroundColor Green;
--------------------------------------------------------------------------------
/scripts/src/GetLatestCommitSHA.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$owner,
3 | [string]$repo,
4 | [string]$branchName
5 | )
6 |
7 | Write-Host "Getting the latest commit SHA for $($branchName):" -ForegroundColor Magenta;
8 |
9 | $latestCommitUrl = "https://api.github.com/repos/$($owner)/$($repo)/commits/$($branchName)";
10 |
11 | Write-Host "Getting latest commit with '$($latestCommitUrl)'" -ForegroundColor Blue;
12 | $latestCommitData = Invoke-RestMethod -Uri $latestCommitUrl -Method Get;
13 |
14 | if ($latestCommitData.Count -eq 0) {
15 | Write-Host "Unable to get latest commit with '$($latestCommitUrl)'" -ForegroundColor Red;
16 | EXIT 1;
17 | }
18 |
19 | if ([string]::IsNullOrEmpty($latestCommitData.sha)) {
20 | Write-Host "SHA is not present in the latest commit that is fetched" -ForegroundColor Red;
21 | Write-Host "Latest Commit Data:" -ForegroundColor Cyan;
22 | Write-Host -Object $latestCommitData -ForegroundColor Cyan;
23 | EXIT 1;
24 | }
25 |
26 | Write-Host "Latest Commit SHA is '$($latestCommitData.sha)'" -ForegroundColor Green;
27 |
28 | Write-Host "##vso[task.setvariable variable=LASTEST_COMMIT_SHA]$($latestCommitData.sha)";
29 |
30 | Write-Host "Updated latest commit sha in global variable" -ForegroundColor Green;
--------------------------------------------------------------------------------
/scripts/src/GetPackageVersion.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$gitRepoRoot
3 | )
4 |
5 | Write-Host "Get package version and update it in the global varaible:" -ForegroundColor Magenta;
6 |
7 | $pathToPackageJson = "$($gitRepoRoot)/package.json";
8 | $packageJson = Get-Content -Path $pathToPackageJson -Raw | ConvertFrom-Json;
9 | Write-Host "Package version is '$($packageJson.version)'" -ForegroundColor Green;
10 |
11 | Write-Host "##vso[task.setvariable variable=VERSION_STRING]$($packageJson.version)";
12 |
13 | Write-Host "Updated version in global variable" -ForegroundColor Green;
14 |
--------------------------------------------------------------------------------
/scripts/src/HasNewCommitsAfterLastRelease.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$owner,
3 | [string]$repo,
4 | [string]$branchName
5 | )
6 |
7 | Write-Host "Checking for availability of new commits after last release:" -ForegroundColor Magenta;
8 | $releasesUrl = "https://api.github.com/repos/$($owner)/$($repo)/releases";
9 |
10 | Write-Host "Getting list of releases with '$($releasesUrl)'" -ForegroundColor Blue;
11 | $releasesJSON = Invoke-RestMethod -Uri $releasesUrl -Method Get;
12 |
13 | if ($releasesJSON.Count -eq 0) {
14 | Write-Host "Unable to get releases list with '$($releasesUrl)'" -ForegroundColor Red;
15 | Write-Host "NOTE: This Script cannot handle the first release!" -ForegroundColor Cyan;
16 | EXIT 1;
17 | }
18 |
19 | $lastReleaseJSON = $releasesJSON[0];
20 | $publishedTime = $lastReleaseJSON.published_at;
21 | $lastReleaseTag = $lastReleaseJSON.tag_name;
22 |
23 | if ([string]::IsNullOrEmpty($publishedTime)) {
24 | Write-Host "Unable read the last release published time" -ForegroundColor Red;
25 | Write-Host "Last Release Data:" -ForegroundColor Red;
26 | Write-Host -Object $lastReleaseJSON -ForegroundColor Red;
27 | EXIT 1;
28 | }
29 |
30 | if ([string]::IsNullOrEmpty($lastReleaseTag)) {
31 | Write-Host "Unable read the last release tag name" -ForegroundColor Red;
32 | Write-Host "Last Release Data:" -ForegroundColor Red;
33 | Write-Host -Object $lastReleaseJSON -ForegroundColor Red;
34 | EXIT 1;
35 | }
36 |
37 | $newCommitsUrl = "https://api.github.com/repos/$($owner)/$($repo)/commits?sha=$($branchName)&since=$($publishedTime)";
38 |
39 | Write-Host "Getting commits after last release with '$($newCommitsUrl)'" -ForegroundColor Blue;
40 | $newCommitsJSON = Invoke-RestMethod -Uri $newCommitsUrl -Method Get;
41 |
42 | if ($newCommitsJSON.Count -gt 0) {
43 | Write-Host "There are atleast '$($newCommitsJSON.Length)' Commits in '$($branchName)' branch after last release with tag $'($lastReleaseTag)'" -ForegroundColor Green;
44 | EXIT 0;
45 | }
46 | else {
47 | Write-Host "Unable to get commits after last release with '$($newCommitsUrl)'" -ForegroundColor Red;
48 | Write-Host "NOTE: Possibly, there are no commits in '$($branchName)' branch after last release with tag '$($lastReleaseTag)'" -ForegroundColor Cyan;
49 | Write-Host "To verify there are not commits, make a request by pasting '$($newCommitsUrl)' in your browser" -ForegroundColor Cyan;
50 | EXIT 1;
51 | }
--------------------------------------------------------------------------------
/scripts/src/MergeChangesTillLastestRelease.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$owner,
3 | [string]$repo,
4 | [string]$branchName,
5 | [string]$gitPat
6 | )
7 | Write-Host "Merge and Commit the changes into '$($branchName)' till last release:" -ForegroundColor Magenta;
8 |
9 | Write-Host "Checking out '$($branchName)'" -ForegroundColor Blue;
10 | git checkout main | Write-Host;
11 | Write-Host "Checked out" -ForegroundColor Green;
12 |
13 | Write-Host "Pulling '$($branchName)'" -ForegroundColor Blue;
14 | git pull origin main --allow-unrelated-histories | Write-Host;
15 | Write-Host "Pulled '$($branchName)'" -ForegroundColor Green;
16 |
17 | Write-Host "Getting SHA for last commit in the latest release" -ForegroundColor Blue;
18 | $latestReleaseCommitSHA = git rev-list --tags --max-count=1;
19 |
20 | if([string]::IsNullOrEmpty($latestReleaseCommitSHA)) {
21 | Write-Host "Unable to get the SHA for last commit in latest release" -ForegroundColor Red;
22 | EXIT 1;
23 | }
24 |
25 | Write-Host "SHA for last commit in the latest release is '$($latestReleaseCommitSHA)'" -ForegroundColor Green;
26 |
27 | Write-Host "Merging Changes till '$($latestReleaseCommitSHA)'" -ForegroundColor Blue;
28 | git merge $latestReleaseCommitSHA | Write-Host;
29 |
30 | Write-Host "Checking Conflicted Files";
31 | $conflictedFiles = git diff --name-only --diff-filter=U;
32 |
33 | if (-Not [string]::IsNullOrEmpty($conflictedFiles)) {
34 | Write-Host "Unable to Merge" -ForegroundColor Red;
35 | Write-Host "There are conflicts in below files:" -ForegroundColor Cyan;
36 | Write-Host -Object $conflictedFiles -ForegroundColor Cyan;
37 | EXIT 1;
38 | }
39 |
40 | Write-Host "Merged changes to '$($branchName)'" -ForegroundColor Green;
41 |
42 | Write-Host "Pushing changes." -ForegroundColor Blue;
43 | git push "https://$($gitPat)@github.com/$($owner)/$($repo).git" HEAD:$branchName | Write-Host;
44 | Write-Host "Pushed changes to the $($branchName) branch." -ForegroundColor Green;
45 |
--------------------------------------------------------------------------------
/scripts/src/MergeVersionChangesBackToPreviewBranch.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$owner,
3 | [string]$repo,
4 | [string]$branchName,
5 | [string]$previewBranchName,
6 | [string]$gitPat
7 | )
8 |
9 | Write-Host "Merge and Commit the version changes from '$($branchName)' to '$($previewBranchName)':" -ForegroundColor Magenta;
10 |
11 | Write-Host "Starting checkout '$($previewBranchName)'" -ForegroundColor Blue;
12 | git checkout $previewBranchName | Write-Host;
13 | Write-Host "Checked out '$($previewBranchName)'" -ForegroundColor Green;
14 |
15 | Write-Host "Merging the changes from '$($branchName)' to '$($previewBranchName)'" -ForegroundColor Blue;
16 | git merge $branchName | Write-Host;
17 |
18 | $conflictedFiles = git diff --name-only --diff-filter=U;
19 |
20 | if (-Not ([string]::IsNullOrEmpty($conflictedFiles))) {
21 | Write-Host "Unable to Merge" -ForegroundColor Red;
22 | Write-Host "There are conflicts in below files:" -ForegroundColor Cyan;
23 | Write-Host -Object $conflictedFiles -ForegroundColor Cyan;
24 | EXIT 1;
25 | }
26 |
27 | Write-Host "Merged changes from '$($branchName)' to '$($previewBranchName)'" -ForegroundColor Green;
28 |
29 | Write-Host "Pushing changes." -ForegroundColor Blue;
30 | git push "https://$($gitPat)@github.com/$($owner)/$($repo).git" HEAD:$previewBranchName | Write-Host
31 | Write-Host "Pushed changes to the '$($previewBranchName)' branch." -ForegroundColor Green;
32 |
--------------------------------------------------------------------------------
/scripts/src/RemoveGithubUser.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$gitRepoRoot
3 | )
4 |
5 | Write-Host "Removing Github User:" -ForegroundColor Magenta;
6 |
7 | Set-Location -Path $gitRepoRoot;
8 | Write-Host "Location changed to Git Repo Root $(Get-Location)" -ForegroundColor Green;
9 |
10 | git config --unset user.name
11 | git config --unset user.email
12 | Write-Host "Git user.name and user.email is unset." -ForegroundColor Green;
--------------------------------------------------------------------------------
/shims.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * Shim for Node stream interface.
10 | */
11 | interface NodeStream {
12 | /**
13 | * Shim for Node stream interface when the environment does not use @types/node.
14 | * Using @types/node appends the ambient Node definition to the global scope which is not desirable.
15 | * https://github.com/microsoftgraph/msgraph-sdk-javascript/issues/600
16 | */
17 | readable: boolean;
18 | readableLength: number;
19 | read(size?: number): any;
20 | on(event: string | symbol, listener: (...args: any[]) => void): this;
21 | }
22 |
23 | interface Headers{}
--------------------------------------------------------------------------------
/src/Constants.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module Constants
10 | */
11 |
12 | /**
13 | * @constant
14 | * A Default API endpoint version for a request
15 | */
16 | export const GRAPH_API_VERSION = "v1.0";
17 |
18 | /**
19 | * @constant
20 | * A Default base url for a request
21 | */
22 | export const GRAPH_BASE_URL = "https://graph.microsoft.com/";
23 |
24 | /**
25 | * To hold list of the service root endpoints for Microsoft Graph and Graph Explorer for each national cloud.
26 | * Set(iterable:Object) is not supported in Internet Explorer. The consumer is recommended to use a suitable polyfill.
27 | */
28 | export const GRAPH_URLS = new Set(["graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn", "canary.graph.microsoft.com"]);
29 |
--------------------------------------------------------------------------------
/src/CustomAuthenticationProvider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module CustomAuthenticationProvider
10 | */
11 |
12 | import { GraphClientError } from "./GraphClientError";
13 | import { AuthenticationProvider } from "./IAuthenticationProvider";
14 | import { AuthProvider } from "./IAuthProvider";
15 |
16 | /**
17 | * @class
18 | * Class representing CustomAuthenticationProvider
19 | * @extends AuthenticationProvider
20 | */
21 | export class CustomAuthenticationProvider implements AuthenticationProvider {
22 | /**
23 | * @private
24 | * A member to hold authProvider callback
25 | */
26 | private provider: AuthProvider;
27 |
28 | /**
29 | * @public
30 | * @constructor
31 | * Creates an instance of CustomAuthenticationProvider
32 | * @param {AuthProviderCallback} provider - An authProvider function
33 | * @returns An instance of CustomAuthenticationProvider
34 | */
35 | public constructor(provider: AuthProvider) {
36 | this.provider = provider;
37 | }
38 |
39 | /**
40 | * @public
41 | * @async
42 | * To get the access token
43 | * @returns The promise that resolves to an access token
44 | */
45 | public async getAccessToken(): Promise {
46 | return new Promise((resolve: (accessToken: string) => void, reject: (error: any) => void) => {
47 | this.provider(async (error: any, accessToken: string | null) => {
48 | if (accessToken) {
49 | resolve(accessToken);
50 | } else {
51 | if (!error) {
52 | const invalidTokenMessage = "Access token is undefined or empty.\
53 | Please provide a valid token.\
54 | For more help - https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md";
55 | error = new GraphClientError(invalidTokenMessage);
56 | }
57 | const err = await GraphClientError.setGraphClientError(error);
58 | reject(err);
59 | }
60 | });
61 | });
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/GraphClientError.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module GraphClientError
10 | */
11 |
12 | /**
13 | * @class
14 | * Create GraphClientError object to handle client-side errors
15 | * encountered within the JavaScript Client SDK.
16 | * Whereas GraphError Class should be used to handle errors in the response from the Graph API.
17 | */
18 |
19 | export class GraphClientError extends Error {
20 | /**
21 | * @public
22 | * A custom error. This property should set be when the error is not of instanceOf Error/GraphClientError.
23 | * Example =
24 | * const client = MicrosoftGraph.Client.init({
25 | * defaultVersion: "v1.0",
26 | * authProvider: (done) => { done({TokenError:"AccessToken cannot be null"}, "");
27 | * });
28 | */
29 | public customError?: any;
30 |
31 | /**
32 | * @public
33 | * @static
34 | * @async
35 | * To set the GraphClientError object
36 | * @param {any} error - The error returned encountered by the Graph JavaScript Client SDK while processing request
37 | * @returns GraphClientError object set to the error passed
38 | */
39 | public static setGraphClientError(error: any): GraphClientError {
40 | let graphClientError: GraphClientError;
41 | if (error instanceof Error) {
42 | graphClientError = error;
43 | } else {
44 | graphClientError = new GraphClientError();
45 | graphClientError.customError = error;
46 | }
47 | return graphClientError;
48 | }
49 |
50 | /**
51 | * @public
52 | * @constructor
53 | * Creates an instance of GraphClientError
54 | * @param {string} message? - Error message
55 | * @returns An instance of GraphClientError
56 | */
57 | public constructor(message?: string) {
58 | super(message);
59 | Object.setPrototypeOf(this, GraphClientError.prototype);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/GraphError.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module GraphError
10 | */
11 |
12 | /**
13 | * @class
14 | * Class for GraphError
15 | * @NOTE: This is NOT what is returned from the Graph
16 | * GraphError is created from parsing JSON errors returned from the graph
17 | * Some fields are renamed ie, "request-id" => requestId so you can use dot notation
18 | */
19 |
20 | export class GraphError extends Error {
21 | /**
22 | * @public
23 | * A member holding status code of the error
24 | */
25 | public statusCode: number;
26 |
27 | /**
28 | * @public
29 | * A member holding code i.e name of the error
30 | */
31 | public code: string | null;
32 |
33 | /**
34 | * @public
35 | * A member holding request-id i.e identifier of the request
36 | */
37 | public requestId: string | null;
38 |
39 | /**
40 | * @public
41 | * A member holding processed date and time of the request
42 | */
43 | public date: Date;
44 |
45 | public headers?: Headers;
46 |
47 | /**
48 | * @public
49 | * A member holding original error response by the graph service
50 | */
51 | public body: any;
52 |
53 | /**
54 | * @public
55 | * @constructor
56 | * Creates an instance of GraphError
57 | * @param {number} [statusCode = -1] - The status code of the error
58 | * @param {string} [message] - The message of the error
59 | * @param {Error} [baseError] - The base error
60 | * @returns An instance of GraphError
61 | */
62 | public constructor(statusCode = -1, message?: string, baseError?: Error) {
63 | super(message || (baseError && baseError.message));
64 | // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
65 | Object.setPrototypeOf(this, GraphError.prototype);
66 | this.statusCode = statusCode;
67 | this.code = null;
68 | this.requestId = null;
69 | this.date = new Date();
70 | this.body = null;
71 | this.stack = baseError ? baseError.stack : this.stack;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/HTTPClient.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module HTTPClient
10 | */
11 |
12 | import { Context } from "./IContext";
13 | import { Middleware } from "./middleware/IMiddleware";
14 |
15 | /**
16 | * @class
17 | * Class representing HTTPClient
18 | */
19 | export class HTTPClient {
20 | /**
21 | * @private
22 | * A member holding first middleware of the middleware chain
23 | */
24 | private middleware: Middleware;
25 |
26 | /**
27 | * @public
28 | * @constructor
29 | * Creates an instance of a HTTPClient
30 | * @param {...Middleware} middleware - The first middleware of the middleware chain or a sequence of all the Middleware handlers
31 | */
32 | public constructor(...middleware: Middleware[]) {
33 | if (!middleware || !middleware.length) {
34 | const error = new Error();
35 | error.name = "InvalidMiddlewareChain";
36 | error.message = "Please provide a default middleware chain or custom middleware chain";
37 | throw error;
38 | }
39 | this.setMiddleware(...middleware);
40 | }
41 |
42 | /**
43 | * @private
44 | * Processes the middleware parameter passed to set this.middleware property
45 | * The calling function should validate if middleware is not undefined or not empty.
46 | * @param {...Middleware} middleware - The middleware passed
47 | * @returns Nothing
48 | */
49 | private setMiddleware(...middleware: Middleware[]): void {
50 | if (middleware.length > 1) {
51 | this.parseMiddleWareArray(middleware);
52 | } else {
53 | this.middleware = middleware[0];
54 | }
55 | }
56 |
57 | /**
58 | * @private
59 | * Processes the middleware array to construct the chain
60 | * and sets this.middleware property to the first middleware handler of the array
61 | * The calling function should validate if middleware is not undefined or not empty
62 | * @param {Middleware[]} middlewareArray - The array of middleware handlers
63 | * @returns Nothing
64 | */
65 | private parseMiddleWareArray(middlewareArray: Middleware[]) {
66 | middlewareArray.forEach((element, index) => {
67 | if (index < middlewareArray.length - 1) {
68 | element.setNext(middlewareArray[index + 1]);
69 | }
70 | });
71 | this.middleware = middlewareArray[0];
72 | }
73 |
74 | /**
75 | * @public
76 | * @async
77 | * To send the request through the middleware chain
78 | * @param {Context} context - The context of a request
79 | * @returns A promise that resolves to the Context
80 | */
81 | public async sendRequest(context: Context): Promise {
82 | if (typeof context.request === "string" && context.options === undefined) {
83 | const error = new Error();
84 | error.name = "InvalidRequestOptions";
85 | error.message = "Unable to execute the middleware, Please provide valid options for a request";
86 | throw error;
87 | }
88 | await this.middleware.execute(context);
89 | return context;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/IAuthProvider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { AuthProviderCallback } from "./IAuthProviderCallback";
9 |
10 | /**
11 | * @interface
12 | * Signature that holds authProvider
13 | * @callback - The anonymous callback function which takes a single param
14 | */
15 | export type AuthProvider = (done: AuthProviderCallback) => void;
16 |
--------------------------------------------------------------------------------
/src/IAuthProviderCallback.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @interface
10 | * Signature that defines callback for an authentication provider
11 | * @callback - The anonymous callback function which takes two params
12 | */
13 | export type AuthProviderCallback = (error: any, accessToken: string | null) => void;
14 |
--------------------------------------------------------------------------------
/src/IAuthenticationProvider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { AuthenticationProviderOptions } from "./IAuthenticationProviderOptions";
9 |
10 | /**
11 | * @interface
12 | * A signature representing Authentication provider
13 | * @property {Function} getAccessToken - The function to get the access token from the authentication provider
14 | */
15 | export interface AuthenticationProvider {
16 | /**
17 | * To get access token from the authentication provider
18 | * @param {AuthenticationProviderOptions} [authenticationProviderOptions] - The authentication provider options instance
19 | * @returns A promise that resolves to an access token
20 | */
21 | getAccessToken: (authenticationProviderOptions?: AuthenticationProviderOptions) => Promise;
22 | }
23 |
--------------------------------------------------------------------------------
/src/IAuthenticationProviderOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @interface
10 | * A signature represents the Authentication provider options
11 | * @property {string[]} [scopes] - The array of scopes
12 | */
13 | export interface AuthenticationProviderOptions {
14 | scopes?: string[];
15 | }
16 |
--------------------------------------------------------------------------------
/src/IClientOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { AuthenticationProvider } from "./IAuthenticationProvider";
9 | import { FetchOptions } from "./IFetchOptions";
10 | import { Middleware } from "./middleware/IMiddleware";
11 |
12 | /**
13 | * @interface
14 | * Options for initializing the Graph Client
15 | * @property {Function} [authProvider] - The authentication provider instance
16 | * @property {string} [baseUrl] - Base url that needs to be appended to every request
17 | * @property {boolean} [debugLogging] - The boolean to enable/disable debug logging
18 | * @property {string} [defaultVersion] - The default version that needs to be used while making graph api request
19 | * @property {FetchOptions} [fetchOptions] - The options for fetch request
20 | * @property {Middleware| Middleware[]} [middleware] - The first middleware of the middleware chain or an array of the Middleware handlers
21 | * @property {Set}[customHosts] - A set of custom host names. Should contain hostnames only.
22 | */
23 |
24 | export interface ClientOptions {
25 | authProvider?: AuthenticationProvider;
26 | baseUrl?: string;
27 | debugLogging?: boolean;
28 | defaultVersion?: string;
29 | fetchOptions?: FetchOptions;
30 | middleware?: Middleware | Middleware[];
31 | /**
32 | * Example - If URL is "https://test_host/v1.0", then set property "customHosts" as "customHosts: Set(["test_host"])"
33 | */
34 | customHosts?: Set;
35 | }
36 |
--------------------------------------------------------------------------------
/src/IContext.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { FetchOptions } from "./IFetchOptions";
9 | import { MiddlewareControl } from "./middleware/MiddlewareControl";
10 |
11 | /**
12 | * @interface
13 | * @property {RequestInfo} request - The request url string or the Request instance
14 | * @property {FetchOptions} [options] - The options for the request
15 | * @property {Response} [response] - The response content
16 | * @property {MiddlewareControl} [middlewareControl] - The options for the middleware chain
17 | * @property {Set}[customHosts] - A set of custom host names. Should contain hostnames only.
18 | *
19 | */
20 |
21 | export interface Context {
22 | request: RequestInfo;
23 | options?: FetchOptions;
24 | response?: Response;
25 | middlewareControl?: MiddlewareControl;
26 | /**
27 | * Example - If URL is "https://test_host", then set property "customHosts" as "customHosts: Set(["test_host"])"
28 | */
29 | customHosts?: Set;
30 | }
31 |
--------------------------------------------------------------------------------
/src/IFetchOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @interface {@link https://github.com/bitinn/node-fetch/#options}
10 | * Signature to define the fetch request options for node environment
11 | * @property {number} [follow] - node-fetch option: maximum redirect count. 0 to not follow redirect
12 | * @property {number} [compress] - node-fetch option: support gzip/deflate content encoding. false to disable
13 | * @property {number} [size] - node-fetch option: maximum response body size in bytes. 0 to disable
14 | * @property {any} [agent] - node-fetch option: HTTP(S).Agent instance, allows custom proxy, certificate, lookup, family etc.
15 | * @property {number} [highWaterMark] - node-fetch option: maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource.
16 | * @property {boolean} [insecureHTTPParser] - node-fetch option: use an insecure HTTP parser that accepts invalid HTTP headers when `true`.
17 | */
18 | export interface NodeFetchInit {
19 | follow?: number;
20 | compress?: boolean;
21 | size?: number;
22 | agent?: any;
23 | highWaterMark?: number;
24 | insecureHTTPParser?: boolean;
25 | }
26 |
27 | /**
28 | * @interface
29 | * Signature to define the fetch api options which includes both fetch standard options and also the extended node fetch options
30 | * @extends RequestInit @see {@link https://fetch.spec.whatwg.org/#requestinit}
31 | * @extends NodeFetchInit
32 | */
33 | export interface FetchOptions extends RequestInit, NodeFetchInit {}
34 |
--------------------------------------------------------------------------------
/src/IGraphRequestCallback.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { GraphError } from "./GraphError";
9 | /**
10 | * @interface
11 | * Signature to define the GraphRequest callback
12 | * @callback - The anonymous callback function
13 | */
14 | export type GraphRequestCallback = (error: GraphError, response: any, rawResponse?: any) => void;
15 |
--------------------------------------------------------------------------------
/src/IOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { AuthProvider } from "./IAuthProvider";
9 | import { FetchOptions } from "./IFetchOptions";
10 |
11 | /**
12 | * @interface
13 | * Options for initializing the Graph Client
14 | * @property {AuthProvider} authProvider - The function to get the authentication token
15 | * @property {string} [baseUrl] - Base url that needs to be appended to every request
16 | * @property {boolean} [debugLogging] - The boolean to enable/disable debug logging
17 | * @property {string} [defaultVersion] - The default version that needs to be used while making graph api request
18 | * @property {FetchOptions} [fetchOptions] - The options for fetch request
19 | * @property {Set}[customHosts] - A set of custom host names. Should contain hostnames only.
20 | */
21 | export interface Options {
22 | authProvider: AuthProvider;
23 | baseUrl?: string;
24 | debugLogging?: boolean;
25 | defaultVersion?: string;
26 | fetchOptions?: FetchOptions;
27 | /**
28 | * Example - If URL is "https://test_host/v1.0", then set property "customHosts" as "customHosts: Set(["test_host"])"
29 | */
30 | customHosts?: Set;
31 | }
32 |
--------------------------------------------------------------------------------
/src/RequestMethod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @enum
10 | * Enum for RequestMethods
11 | * @property {string} GET - The get request type
12 | * @property {string} PATCH - The patch request type
13 | * @property {string} POST - The post request type
14 | * @property {string} PUT - The put request type
15 | * @property {string} DELETE - The delete request type
16 | */
17 | export enum RequestMethod {
18 | GET = "GET",
19 | PATCH = "PATCH",
20 | POST = "POST",
21 | PUT = "PUT",
22 | DELETE = "DELETE",
23 | }
24 |
--------------------------------------------------------------------------------
/src/ResponseType.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @enum
10 | * Enum for ResponseType values
11 | * @property {string} ARRAYBUFFER - To download response content as an [ArrayBuffer]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer}
12 | * @property {string} BLOB - To download content as a [binary/blob] {@link https://developer.mozilla.org/en-US/docs/Web/API/Blob}
13 | * @property {string} DOCUMENT - This downloads content as a document or stream
14 | * @property {string} JSON - To download response content as a json
15 | * @property {string} STREAM - To download response as a [stream]{@link https://nodejs.org/api/stream.html}
16 | * @property {string} TEXT - For downloading response as a text
17 | */
18 |
19 | export enum ResponseType {
20 | ARRAYBUFFER = "arraybuffer",
21 | BLOB = "blob",
22 | DOCUMENT = "document",
23 | JSON = "json",
24 | RAW = "raw",
25 | STREAM = "stream",
26 | TEXT = "text",
27 | }
28 |
--------------------------------------------------------------------------------
/src/ValidatePolyFilling.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @constant
10 | * @function
11 | * Validates availability of Promise and fetch in global context
12 | * @returns The true in case the Promise and fetch available, otherwise throws error
13 | */
14 |
15 | export const validatePolyFilling = (): boolean => {
16 | if (typeof Promise === "undefined" && typeof fetch === "undefined") {
17 | const error = new Error("Library cannot function without Promise and fetch. So, please provide polyfill for them.");
18 | error.name = "PolyFillNotAvailable";
19 | throw error;
20 | } else if (typeof Promise === "undefined") {
21 | const error = new Error("Library cannot function without Promise. So, please provide polyfill for it.");
22 | error.name = "PolyFillNotAvailable";
23 | throw error;
24 | } else if (typeof fetch === "undefined") {
25 | const error = new Error("Library cannot function without fetch. So, please provide polyfill for it.");
26 | error.name = "PolyFillNotAvailable";
27 | throw error;
28 | }
29 | return true;
30 | };
31 |
--------------------------------------------------------------------------------
/src/Version.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | // THIS FILE IS AUTO GENERATED
9 | // ANY CHANGES WILL BE LOST DURING BUILD
10 |
11 | /**
12 | * @module Version
13 | */
14 |
15 | export const PACKAGE_VERSION = "3.0.7";
16 |
--------------------------------------------------------------------------------
/src/authentication/azureTokenCredentials/ITokenCredentialAuthenticationProviderOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | import { GetTokenOptions } from "@azure/identity";
8 |
9 | import { AuthenticationProviderOptions } from "../../IAuthenticationProviderOptions";
10 |
11 | /**
12 | * @interface
13 | * A signature represents the Authentication provider options for Token Credentials
14 | * @property {getTokenOptions} [GetTokenOptions] - Defines options for TokenCredential.getToken.
15 | */
16 | export interface TokenCredentialAuthenticationProviderOptions extends AuthenticationProviderOptions {
17 | getTokenOptions?: GetTokenOptions;
18 | }
19 |
--------------------------------------------------------------------------------
/src/authentication/azureTokenCredentials/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | export type { TokenCredentialAuthenticationProviderOptions } from "./ITokenCredentialAuthenticationProviderOptions";
8 | export { TokenCredentialAuthenticationProvider } from "./TokenCredentialAuthenticationProvider";
9 |
--------------------------------------------------------------------------------
/src/authentication/msal-browser/AuthCodeMSALBrowserAuthenticationProvider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module AuthCodeMSALBrowserAuthenticationProvider
10 | */
11 |
12 | import { AuthenticationResult, InteractionRequiredAuthError, InteractionType, PublicClientApplication } from "@azure/msal-browser";
13 |
14 | import { GraphClientError } from "../../GraphClientError";
15 | import { AuthenticationProvider } from "../../IAuthenticationProvider";
16 | import { AuthCodeMSALBrowserAuthenticationProviderOptions } from "../msalOptions/MSALAuthenticationProviderOptions";
17 |
18 | /**
19 | * an AuthenticationProvider implementation supporting msal-browser library.
20 | * This feature is introduced in Version 3.0.0
21 | * @class
22 | * @extends AuthenticationProvider
23 | */
24 | export class AuthCodeMSALBrowserAuthenticationProvider implements AuthenticationProvider {
25 | /**
26 | * @public
27 | * @constructor
28 | * Creates an instance of ImplicitMSALAuthenticationProvider
29 | * @param {PublicClientApplication} msalApplication - An instance of MSAL PublicClientApplication
30 | * @param {AuthCodeMSALBrowserAuthenticationProviderOptions} options - An instance of MSALAuthenticationProviderOptions
31 | * @returns An instance of ImplicitMSALAuthenticationProvider
32 | */
33 | public constructor(private publicClientApplication: PublicClientApplication, private options: AuthCodeMSALBrowserAuthenticationProviderOptions) {
34 | if (!options || !publicClientApplication) {
35 | throw new GraphClientError("Please pass valid PublicClientApplication instance and AuthCodeMSALBrowserAuthenticationProviderOptions instance to instantiate MSALBrowserAuthenticationProvider");
36 | }
37 | }
38 |
39 | /**
40 | * @public
41 | * @async
42 | * To get the access token for the request
43 | * @returns The promise that resolves to an access token
44 | */
45 | public async getAccessToken(): Promise {
46 | const scopes = this.options && this.options.scopes;
47 | const account = this.options && this.options.account;
48 | const error = new GraphClientError();
49 | if (!scopes || scopes.length === 0) {
50 | error.name = "Empty Scopes";
51 | error.message = "Scopes cannot be empty, Please provide scopes";
52 | throw error;
53 | }
54 | try {
55 | const response: AuthenticationResult = await this.publicClientApplication.acquireTokenSilent({
56 | scopes,
57 | account,
58 | });
59 | if (!response || !response.accessToken) {
60 | error.name = "Access token is undefined";
61 | error.message = "Received empty access token from PublicClientApplication";
62 | throw error;
63 | }
64 | return response.accessToken;
65 | } catch (error) {
66 | if (error instanceof InteractionRequiredAuthError) {
67 | if (this.options.interactionType === InteractionType.Redirect) {
68 | this.publicClientApplication.acquireTokenRedirect({ scopes });
69 | } else if (this.options.interactionType === InteractionType.Popup) {
70 | const response: AuthenticationResult = await this.publicClientApplication.acquireTokenPopup({ scopes });
71 | return response.accessToken;
72 | }
73 | } else {
74 | throw error;
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/authentication/msal-browser/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | export { AuthCodeMSALBrowserAuthenticationProvider } from "./AuthCodeMSALBrowserAuthenticationProvider";
8 |
--------------------------------------------------------------------------------
/src/authentication/msalOptions/MSALAuthenticationProviderOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module MSALAuthenticationProviderOptions
10 | */
11 |
12 | import { AccountInfo, InteractionType } from "@azure/msal-browser";
13 |
14 | import { AuthenticationProviderOptions } from "../../IAuthenticationProviderOptions";
15 |
16 | export interface AuthCodeMSALBrowserAuthenticationProviderOptions extends AuthenticationProviderOptions {
17 | scopes: string[];
18 | account: AccountInfo;
19 | interactionType: InteractionType;
20 | }
21 |
--------------------------------------------------------------------------------
/src/middleware/HTTPMessageHandler.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module HTTPMessageHandler
10 | */
11 |
12 | import { Context } from "../IContext";
13 | import { Middleware } from "./IMiddleware";
14 |
15 | /**
16 | * @class
17 | * @implements Middleware
18 | * Class for HTTPMessageHandler
19 | */
20 | export class HTTPMessageHandler implements Middleware {
21 | /**
22 | * @public
23 | * @async
24 | * To execute the current middleware
25 | * @param {Context} context - The request context object
26 | * @returns A promise that resolves to nothing
27 | */
28 | public async execute(context: Context): Promise {
29 | context.response = await fetch(context.request, context.options);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/middleware/IMiddleware.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { Context } from "../IContext";
9 |
10 | /**
11 | * @interface
12 | * @property {Function} execute - The method to execute the middleware
13 | * @property {Function} [setNext] - A method to set the next middleware in the chain
14 | */
15 | export interface Middleware {
16 | execute: (context: Context) => Promise;
17 | setNext?: (middleware: Middleware) => void;
18 | }
19 |
--------------------------------------------------------------------------------
/src/middleware/MiddlewareControl.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module MiddlewareControl
10 | */
11 |
12 | import { MiddlewareOptions } from "./options/IMiddlewareOptions";
13 |
14 | /**
15 | * @class
16 | * Class representing MiddlewareControl
17 | */
18 | export class MiddlewareControl {
19 | /**
20 | * @private
21 | * A member holding map of MiddlewareOptions
22 | */
23 | private middlewareOptions: Map;
24 |
25 | /**
26 | * @public
27 | * @constructor
28 | * Creates an instance of MiddlewareControl
29 | * @param {MiddlewareOptions[]} [middlewareOptions = []] - The array of middlewareOptions
30 | * @returns The instance of MiddlewareControl
31 | */
32 | public constructor(middlewareOptions: MiddlewareOptions[] = []) {
33 | this.middlewareOptions = new Map();
34 | for (const option of middlewareOptions) {
35 | const fn = option.constructor;
36 | this.middlewareOptions.set(fn, option);
37 | }
38 | }
39 |
40 | /**
41 | * @public
42 | * To get the middleware option using the class of the option
43 | * @param {Function} fn - The class of the strongly typed option class
44 | * @returns The middleware option
45 | * @example
46 | * // if you wanted to return the middleware option associated with this class (MiddlewareControl)
47 | * // call this function like this:
48 | * getMiddlewareOptions(MiddlewareControl)
49 | */
50 | public getMiddlewareOptions(fn: Function): MiddlewareOptions {
51 | return this.middlewareOptions.get(fn);
52 | }
53 |
54 | /**
55 | * @public
56 | * To set the middleware options using the class of the option
57 | * @param {Function} fn - The class of the strongly typed option class
58 | * @param {MiddlewareOptions} option - The strongly typed middleware option
59 | * @returns nothing
60 | */
61 | public setMiddlewareOptions(fn: Function, option: MiddlewareOptions): void {
62 | this.middlewareOptions.set(fn, option);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/middleware/MiddlewareFactory.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module MiddlewareFactory
10 | */
11 |
12 | import { AuthenticationProvider } from "../IAuthenticationProvider";
13 | import { AuthenticationHandler } from "./AuthenticationHandler";
14 | import { HTTPMessageHandler } from "./HTTPMessageHandler";
15 | import { Middleware } from "./IMiddleware";
16 | import { RedirectHandlerOptions } from "./options/RedirectHandlerOptions";
17 | import { RetryHandlerOptions } from "./options/RetryHandlerOptions";
18 | import { RedirectHandler } from "./RedirectHandler";
19 | import { RetryHandler } from "./RetryHandler";
20 | import { TelemetryHandler } from "./TelemetryHandler";
21 |
22 | /**
23 | * @private
24 | * To check whether the environment is node or not
25 | * @returns A boolean representing the environment is node or not
26 | */
27 | const isNodeEnvironment = (): boolean => {
28 | return typeof process === "object" && typeof require === "function";
29 | };
30 |
31 | /**
32 | * @class
33 | * Class containing function(s) related to the middleware pipelines.
34 | */
35 | export class MiddlewareFactory {
36 | /**
37 | * @public
38 | * @static
39 | * Returns the default middleware chain an array with the middleware handlers
40 | * @param {AuthenticationProvider} authProvider - The authentication provider instance
41 | * @returns an array of the middleware handlers of the default middleware chain
42 | */
43 | public static getDefaultMiddlewareChain(authProvider: AuthenticationProvider): Middleware[] {
44 | const middleware: Middleware[] = [];
45 | const authenticationHandler = new AuthenticationHandler(authProvider);
46 | const retryHandler = new RetryHandler(new RetryHandlerOptions());
47 | const telemetryHandler = new TelemetryHandler();
48 | const httpMessageHandler = new HTTPMessageHandler();
49 |
50 | middleware.push(authenticationHandler);
51 | middleware.push(retryHandler);
52 | if (isNodeEnvironment()) {
53 | const redirectHandler = new RedirectHandler(new RedirectHandlerOptions());
54 | middleware.push(redirectHandler);
55 | }
56 | middleware.push(telemetryHandler);
57 | middleware.push(httpMessageHandler);
58 |
59 | return middleware;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/middleware/options/AuthenticationHandlerOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module AuthenticationHandlerOptions
10 | */
11 |
12 | import { AuthenticationProvider } from "../../IAuthenticationProvider";
13 | import { AuthenticationProviderOptions } from "../../IAuthenticationProviderOptions";
14 | import { MiddlewareOptions } from "./IMiddlewareOptions";
15 |
16 | /**
17 | * @class
18 | * @implements MiddlewareOptions
19 | * Class representing AuthenticationHandlerOptions
20 | */
21 | export class AuthenticationHandlerOptions implements MiddlewareOptions {
22 | /**
23 | * @public
24 | * A member holding an instance of an authentication provider
25 | */
26 | public authenticationProvider: AuthenticationProvider;
27 |
28 | /**
29 | * @public
30 | * A member holding an instance of authentication provider options
31 | */
32 | public authenticationProviderOptions: AuthenticationProviderOptions;
33 |
34 | /**
35 | * @public
36 | * @constructor
37 | * To create an instance of AuthenticationHandlerOptions
38 | * @param {AuthenticationProvider} [authenticationProvider] - The authentication provider instance
39 | * @param {AuthenticationProviderOptions} [authenticationProviderOptions] - The authentication provider options instance
40 | * @returns An instance of AuthenticationHandlerOptions
41 | */
42 | public constructor(authenticationProvider?: AuthenticationProvider, authenticationProviderOptions?: AuthenticationProviderOptions) {
43 | this.authenticationProvider = authenticationProvider;
44 | this.authenticationProviderOptions = authenticationProviderOptions;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/middleware/options/ChaosHandlerData.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module ChaosHandlerData
10 | */
11 |
12 | /**
13 | * Contains RequestMethod to corresponding array of possible status codes, used for Random mode
14 | */
15 | export const methodStatusCode: { [key: string]: number[] } = {
16 | GET: [429, 500, 502, 503, 504],
17 | POST: [429, 500, 502, 503, 504, 507],
18 | PUT: [429, 500, 502, 503, 504, 507],
19 | PATCH: [429, 500, 502, 503, 504],
20 | DELETE: [429, 500, 502, 503, 504, 507],
21 | };
22 |
23 | /**
24 | * Contains statusCode to statusMessage map
25 | */
26 | export const httpStatusCode: { [key: number]: string } = {
27 | 100: "Continue",
28 | 101: "Switching Protocols",
29 | 102: "Processing",
30 | 103: "Early Hints",
31 | 200: "OK",
32 | 201: "Created",
33 | 202: "Accepted",
34 | 203: "Non-Authoritative Information",
35 | 204: "No Content",
36 | 205: "Reset Content",
37 | 206: "Partial Content",
38 | 207: "Multi-Status",
39 | 208: "Already Reported",
40 | 226: "IM Used",
41 | 300: "Multiple Choices",
42 | 301: "Moved Permanently",
43 | 302: "Found",
44 | 303: "See Other",
45 | 304: "Not Modified",
46 | 305: "Use Proxy",
47 | 307: "Temporary Redirect",
48 | 308: "Permanent Redirect",
49 | 400: "Bad Request",
50 | 401: "Unauthorized",
51 | 402: "Payment Required",
52 | 403: "Forbidden",
53 | 404: "Not Found",
54 | 405: "Method Not Allowed",
55 | 406: "Not Acceptable",
56 | 407: "Proxy Authentication Required",
57 | 408: "Request Timeout",
58 | 409: "Conflict",
59 | 410: "Gone",
60 | 411: "Length Required",
61 | 412: "Precondition Failed",
62 | 413: "Payload Too Large",
63 | 414: "URI Too Long",
64 | 415: "Unsupported Media Type",
65 | 416: "Range Not Satisfiable",
66 | 417: "Expectation Failed",
67 | 421: "Misdirected Request",
68 | 422: "Unprocessable Entity",
69 | 423: "Locked",
70 | 424: "Failed Dependency",
71 | 425: "Too Early",
72 | 426: "Upgrade Required",
73 | 428: "Precondition Required",
74 | 429: "Too Many Requests",
75 | 431: "Request Header Fields Too Large",
76 | 451: "Unavailable For Legal Reasons",
77 | 500: "Internal Server Error",
78 | 501: "Not Implemented",
79 | 502: "Bad Gateway",
80 | 503: "Service Unavailable",
81 | 504: "Gateway Timeout",
82 | 505: "HTTP Version Not Supported",
83 | 506: "Variant Also Negotiates",
84 | 507: "Insufficient Storage",
85 | 508: "Loop Detected",
86 | 510: "Not Extended",
87 | 511: "Network Authentication Required",
88 | };
89 |
--------------------------------------------------------------------------------
/src/middleware/options/ChaosHandlerOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module ChaosHandlerOptions
10 | */
11 |
12 | import { ChaosStrategy } from "./ChaosStrategy";
13 | import { MiddlewareOptions } from "./IMiddlewareOptions";
14 |
15 | /**
16 | * Class representing ChaosHandlerOptions
17 | * @class
18 | * Class
19 | * @implements MiddlewareOptions
20 | */
21 | export class ChaosHandlerOptions implements MiddlewareOptions {
22 | /**
23 | * Specifies the startegy used for the Testing Handler -> RANDOM/MANUAL
24 | *
25 | * @public
26 | */
27 | public chaosStrategy: ChaosStrategy;
28 |
29 | /**
30 | * Status code to be returned in the response
31 | *
32 | * @public
33 | */
34 | public statusCode: number;
35 |
36 | /**
37 | * The Message to be returned in the response
38 | *
39 | * @public
40 | */
41 | public statusMessage: string;
42 |
43 | /**
44 | * The percentage of randomness/chaos in the handler
45 | *
46 | * Setting the default value as 10%
47 | * @public
48 | */
49 | public chaosPercentage: number;
50 |
51 | /**
52 | * The response body to be returned in the response
53 | *
54 | * @public
55 | */
56 | public responseBody: any;
57 |
58 | /**
59 | * The response headers to be returned in the response
60 | *
61 | * @public
62 | */
63 | public headers: Headers;
64 |
65 | /**
66 | * @public
67 | * @constructor
68 | * To create an instance of Testing Handler Options
69 | * @param {ChaosStrategy} chaosStrategy - Specifies the startegy used for the Testing Handler -> RAMDOM/MANUAL
70 | * @param {string} statusMessage - The Message to be returned in the response
71 | * @param {number?} statusCode - The statusCode to be returned in the response
72 | * @param {number?} chaosPercentage - The percentage of randomness/chaos in the handler
73 | * @param {any?} responseBody - The response body to be returned in the response
74 | * @returns An instance of ChaosHandlerOptions
75 | */
76 | public constructor(chaosStrategy: ChaosStrategy = ChaosStrategy.RANDOM, statusMessage = "Some error Happened", statusCode?: number, chaosPercentage?: number, responseBody?: any, headers?: Headers) {
77 | this.chaosStrategy = chaosStrategy;
78 | this.statusCode = statusCode;
79 | this.statusMessage = statusMessage;
80 | this.chaosPercentage = chaosPercentage !== undefined ? chaosPercentage : 10;
81 | this.responseBody = responseBody;
82 | this.headers = headers;
83 | if (this.chaosPercentage > 100) {
84 | throw new Error("Error Pecentage can not be more than 100");
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/middleware/options/ChaosStrategy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module ChaosStrategy
10 | */
11 |
12 | /**
13 | * Strategy used for Testing Handler
14 | * @enum
15 | */
16 | export enum ChaosStrategy {
17 | MANUAL,
18 | RANDOM,
19 | }
20 |
--------------------------------------------------------------------------------
/src/middleware/options/IMiddlewareOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @interface
10 | * Signature representing the middleware options
11 | */
12 |
13 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
14 | export interface MiddlewareOptions {}
15 |
--------------------------------------------------------------------------------
/src/middleware/options/RedirectHandlerOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module RedirectHandlerOptions
10 | */
11 |
12 | import { MiddlewareOptions } from "./IMiddlewareOptions";
13 |
14 | /**
15 | * @type
16 | * A type declaration for shouldRetry callback
17 | */
18 | export type ShouldRedirect = (response: Response) => boolean;
19 |
20 | /**
21 | * @class
22 | * @implements MiddlewareOptions
23 | * A class representing RedirectHandlerOptions
24 | */
25 | export class RedirectHandlerOptions implements MiddlewareOptions {
26 | /**
27 | * @private
28 | * @static
29 | * A member holding default max redirects value
30 | */
31 | private static DEFAULT_MAX_REDIRECTS = 5;
32 |
33 | /**
34 | * @private
35 | * @static
36 | * A member holding maximum max redirects value
37 | */
38 | private static MAX_MAX_REDIRECTS = 20;
39 |
40 | /**
41 | * @public
42 | * A member holding max redirects value
43 | */
44 | public maxRedirects: number;
45 |
46 | /**
47 | * @public
48 | * A member holding shouldRedirect callback
49 | */
50 | public shouldRedirect: ShouldRedirect;
51 |
52 | /**
53 | * @private
54 | * A member holding default shouldRedirect callback
55 | */
56 | private static defaultShouldRedirect: ShouldRedirect = () => true;
57 |
58 | /**
59 | * @public
60 | * @constructor
61 | * To create an instance of RedirectHandlerOptions
62 | * @param {number} [maxRedirects = RedirectHandlerOptions.DEFAULT_MAX_REDIRECTS] - The max redirects value
63 | * @param {ShouldRedirect} [shouldRedirect = RedirectHandlerOptions.DEFAULT_SHOULD_RETRY] - The should redirect callback
64 | * @returns An instance of RedirectHandlerOptions
65 | */
66 | public constructor(maxRedirects: number = RedirectHandlerOptions.DEFAULT_MAX_REDIRECTS, shouldRedirect: ShouldRedirect = RedirectHandlerOptions.defaultShouldRedirect) {
67 | if (maxRedirects > RedirectHandlerOptions.MAX_MAX_REDIRECTS) {
68 | const error = new Error(`MaxRedirects should not be more than ${RedirectHandlerOptions.MAX_MAX_REDIRECTS}`);
69 | error.name = "MaxLimitExceeded";
70 | throw error;
71 | }
72 | if (maxRedirects < 0) {
73 | const error = new Error(`MaxRedirects should not be negative`);
74 | error.name = "MinExpectationNotMet";
75 | throw error;
76 | }
77 | this.maxRedirects = maxRedirects;
78 | this.shouldRedirect = shouldRedirect;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/middleware/options/TelemetryHandlerOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module TelemetryHandlerOptions
10 | */
11 |
12 | import { Context } from "../../IContext";
13 | import { MiddlewareControl } from "../MiddlewareControl";
14 | import { MiddlewareOptions } from "./IMiddlewareOptions";
15 |
16 | /**
17 | * @enum
18 | * @property {number} NONE - The hexadecimal flag value for nothing enabled
19 | * @property {number} REDIRECT_HANDLER_ENABLED - The hexadecimal flag value for redirect handler enabled
20 | * @property {number} RETRY_HANDLER_ENABLED - The hexadecimal flag value for retry handler enabled
21 | * @property {number} AUTHENTICATION_HANDLER_ENABLED - The hexadecimal flag value for the authentication handler enabled
22 | */
23 |
24 | export enum FeatureUsageFlag {
25 | /* eslint-disable @typescript-eslint/naming-convention */
26 | NONE = 0x0,
27 | REDIRECT_HANDLER_ENABLED = 0x1,
28 | RETRY_HANDLER_ENABLED = 0x2,
29 | AUTHENTICATION_HANDLER_ENABLED = 0x4,
30 | /* eslint-enable @typescript-eslint/naming-convention */
31 | }
32 |
33 | /**
34 | * @class
35 | * @implements MiddlewareOptions
36 | * Class for TelemetryHandlerOptions
37 | */
38 |
39 | export class TelemetryHandlerOptions implements MiddlewareOptions {
40 | /**
41 | * @private
42 | * A member to hold the OR of feature usage flags
43 | */
44 | private featureUsage: FeatureUsageFlag = FeatureUsageFlag.NONE;
45 |
46 | /**
47 | * @public
48 | * @static
49 | * To update the feature usage in the context object
50 | * @param {Context} context - The request context object containing middleware options
51 | * @param {FeatureUsageFlag} flag - The flag value
52 | * @returns nothing
53 | */
54 | public static updateFeatureUsageFlag(context: Context, flag: FeatureUsageFlag): void {
55 | let options: TelemetryHandlerOptions;
56 | if (context.middlewareControl instanceof MiddlewareControl) {
57 | options = context.middlewareControl.getMiddlewareOptions(TelemetryHandlerOptions) as TelemetryHandlerOptions;
58 | } else {
59 | context.middlewareControl = new MiddlewareControl();
60 | }
61 | if (typeof options === "undefined") {
62 | options = new TelemetryHandlerOptions();
63 | context.middlewareControl.setMiddlewareOptions(TelemetryHandlerOptions, options);
64 | }
65 | options.setFeatureUsage(flag);
66 | }
67 |
68 | /**
69 | * @private
70 | * To set the feature usage flag
71 | * @param {FeatureUsageFlag} flag - The flag value
72 | * @returns nothing
73 | */
74 | private setFeatureUsage(flag: FeatureUsageFlag): void {
75 | this.featureUsage = this.featureUsage | flag;
76 | }
77 |
78 | /**
79 | * @public
80 | * To get the feature usage
81 | * @returns A feature usage flag as hexadecimal string
82 | */
83 | public getFeatureUsage(): string {
84 | return this.featureUsage.toString(16);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/tasks/FileUploadTask/FileObjectClasses/FileUpload.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { GraphClientError } from "../../../GraphClientError";
9 | import { FileObject, SliceType } from "../../LargeFileUploadTask";
10 | import { Range } from "../Range";
11 |
12 | /**
13 | * @class
14 | * Class used for creating LargeFileUploadTask fileobject.
15 | * This class accepts files of type ArrayBuffer, Blob, Uint8Array.
16 | */
17 | export class FileUpload implements FileObject {
18 | /**
19 | * @public
20 | * @constructor
21 | * @param {ArrayBuffer | Blob | Uint8Array} content - The file to be uploaded
22 | * @param {string} name - The name of the file to be uploaded
23 | * @param {number} size - The total size of the file to be uploaded
24 | * @returns An instance of the FileUpload class
25 | */
26 | public constructor(public content: ArrayBuffer | Blob | Uint8Array, public name: string, public size: number) {
27 | if (!content || !name || !size) {
28 | throw new GraphClientError("Please provide the upload content, name of the file and size of the file");
29 | }
30 | }
31 |
32 | /**
33 | * @public
34 | * Slices the file content to the given range
35 | * @param {Range} range - The range value
36 | * @returns The sliced file part
37 | */
38 | public sliceFile(range: Range): ArrayBuffer | Blob | Uint8Array {
39 | return this.content.slice(range.minValue, range.maxValue + 1);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/tasks/FileUploadTask/Interfaces/IUploadEventHandlers.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/type-annotation-spacing */
2 | import { Range } from "../Range";
3 |
4 | /**
5 | * Interface enabling progress handling with callbacks.
6 | */
7 | export interface UploadEventHandlers {
8 | /**
9 | * Parameters that are passed into the progress, completed, failure callback options.
10 | */
11 | extraCallbackParam?: unknown;
12 | /**
13 | * Callback function called on each slice upload during the LargeFileUploadTask.upload() process
14 | */
15 | progress?: (range?: Range, extraCallbackParam?: unknown) => void;
16 | }
17 |
--------------------------------------------------------------------------------
/src/tasks/FileUploadTask/Range.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module Range
10 | */
11 |
12 | /**
13 | * @class
14 | * Class representing Range
15 | */
16 | export class Range {
17 | /**
18 | * @public
19 | * The minimum value of the range
20 | */
21 | public minValue: number;
22 |
23 | /**
24 | * @public
25 | * The maximum value of the range
26 | */
27 | public maxValue: number;
28 |
29 | /**
30 | * @public
31 | * @constructor
32 | * Creates a range for given min and max values
33 | * @param {number} [minVal = -1] - The minimum value.
34 | * @param {number} [maxVal = -1] - The maximum value.
35 | * @returns An instance of a Range
36 | */
37 | public constructor(minVal = -1, maxVal = -1) {
38 | this.minValue = minVal;
39 | this.maxValue = maxVal;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/tasks/FileUploadTask/UploadResult.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * Class representing a successful file upload result
10 | */
11 | export class UploadResult {
12 | /**
13 | * @private
14 | * Location value looked up in the response header
15 | */
16 | private _location: string;
17 |
18 | /**
19 | * @private
20 | * Response body of the final raw response
21 | */
22 | private _responseBody: unknown;
23 |
24 | /**
25 | * @public
26 | * Get of the location value.
27 | * Location value is looked up in the response header
28 | */
29 | public get location(): string {
30 | return this._location;
31 | }
32 |
33 | /**
34 | * @public
35 | * Set the location value
36 | * Location value is looked up in the response header
37 | */
38 | public set location(location: string) {
39 | this._location = location;
40 | }
41 |
42 | /**
43 | * @public
44 | * Get The response body from the completed upload response
45 | */
46 | public get responseBody() {
47 | return this._responseBody;
48 | }
49 |
50 | /**
51 | * @public
52 | * Set the response body from the completed upload response
53 | */
54 | public set responseBody(responseBody: unknown) {
55 | this._responseBody = responseBody;
56 | }
57 |
58 | /**
59 | * @public
60 | * @param {responseBody} responsebody - The response body from the completed upload response
61 | * @param {location} location - The location value from the headers from the completed upload response
62 | */
63 | public constructor(responseBody: unknown, location: string) {
64 | // Response body or the location parameter can be undefined.
65 | this._location = location;
66 | this._responseBody = responseBody;
67 | }
68 |
69 | /**
70 | * @public
71 | * @param {responseBody} responseBody - The response body from the completed upload response
72 | * @param {responseHeaders} responseHeaders - The headers from the completed upload response
73 | */
74 | public static CreateUploadResult(responseBody?: unknown, responseHeaders?: Headers) {
75 | return new UploadResult(responseBody, responseHeaders.get("location"));
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/tasks/OneDriveLargeFileUploadTaskUtil.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module OneDriveLargeFileUploadTaskUtil
10 | */
11 |
12 | /**
13 | * @constant
14 | * Default value for the rangeSize
15 | * Recommended size is between 5 - 10 MB {@link https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/driveitem_createuploadsession#best-practices}
16 | */
17 | const DEFAULT_FILE_SIZE: number = 5 * 1024 * 1024;
18 |
19 | /**
20 | * @constant
21 | * Rounds off the given value to a multiple of 320 KB
22 | * @param {number} value - The value
23 | * @returns The rounded off value
24 | */
25 | const roundTo320KB = (value: number): number => {
26 | if (value > 320 * 1024) {
27 | value = Math.floor(value / (320 * 1024)) * 320 * 1024;
28 | }
29 | return value;
30 | };
31 |
32 | /**
33 | * @constant
34 | * Get the valid rangeSize for a file slicing (validity is based on the constrains mentioned in here
35 | * {@link https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/driveitem_createuploadsession#upload-bytes-to-the-upload-session})
36 | *
37 | * @param {number} [rangeSize = DEFAULT_FILE_SIZE] - The rangeSize value.
38 | * @returns The valid rangeSize
39 | */
40 | export const getValidRangeSize = (rangeSize: number = DEFAULT_FILE_SIZE): number => {
41 | const sixtyMB = 60 * 1024 * 1024;
42 | if (rangeSize > sixtyMB) {
43 | rangeSize = sixtyMB;
44 | }
45 | return roundTo320KB(rangeSize);
46 | };
47 |
--------------------------------------------------------------------------------
/test-esm/README.md:
--------------------------------------------------------------------------------
1 | The test-esm project verifies if the Graph JS Client compiles with ESM projects successfully.
--------------------------------------------------------------------------------
/test-esm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-esm",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "test": "tsc && npx mocha ./lib/testESM.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "@microsoft/microsoft-graph-client": "file:../",
15 | "@types/chai": "^4.3.4",
16 | "@types/mocha": "^10.0.1",
17 | "chai": "^4.3.7",
18 | "isomorphic-fetch": "^3.0.0",
19 | "mocha": "^10.2.0",
20 | "ts-node": "^9.1.1",
21 | "typescript": "^4.2.4"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test-esm/tests/testESM.ts:
--------------------------------------------------------------------------------
1 | import "isomorphic-fetch";
2 |
3 | import { ChaosHandler, ChaosHandlerOptions, ChaosStrategy, Client, ClientOptions } from "@microsoft/microsoft-graph-client";
4 | import { assert } from "chai";
5 |
6 | const middleware = new ChaosHandler();
7 | const clientOptions: ClientOptions = {
8 | middleware,
9 | };
10 |
11 | export const TestClient = Client.initWithMiddleware(clientOptions);
12 |
13 | describe("", () => {
14 | it("should work", async () => {
15 | const responseBody = {
16 | "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
17 | businessPhones: ["+1 412 555 0109"],
18 | displayName: "Megan Bowen",
19 | givenName: "Megan",
20 | userPrincipalName: "MeganB@M365x214355.onmicrosoft.com",
21 | id: "48d31887-5fad-4d73-a9f5-3c356e68a038",
22 | };
23 |
24 | const middlewareOptions = [new ChaosHandlerOptions(ChaosStrategy.MANUAL, "middleware options", 200, 0, JSON.stringify(responseBody)), new Headers({ "Content-Type": "application/json", "content-length": "100" })];
25 |
26 | const response = JSON.parse(await TestClient.api("/me").middlewareOptions(middlewareOptions).get());
27 | assert.isDefined(response);
28 | assert.isDefined(response["id"]);
29 | assert.equal(response["displayName"], responseBody.displayName);
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/test-esm/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "ES6",
4 | "target": "es6",
5 | "outDir": "lib",
6 | "moduleResolution": "node"
7 | },
8 | "exclude": [
9 | "node_modules"
10 | ]
11 | }
--------------------------------------------------------------------------------
/test/DummyAuthenticationProvider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module DummyAuthenticationProvider
10 | */
11 |
12 | import { AuthenticationProvider } from "../src/IAuthenticationProvider";
13 |
14 | /**
15 | * @class
16 | * @implements AuthenticationProvider
17 | * Class representing DummyAuthenticationProvider
18 | */
19 | export class DummyAuthenticationProvider implements AuthenticationProvider {
20 | /**
21 | * @public
22 | * @async
23 | * To get the access token
24 | * @returns The promise that resolves to an access token
25 | */
26 | public async getAccessToken(): Promise {
27 | const token = "DUMMY_TOKEN";
28 | return Promise.resolve(token);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test/DummyHTTPMessageHandler.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module DummyHTTPMessageHandler
10 | */
11 |
12 | import { Context } from "../src/IContext";
13 | import { Middleware } from "../src/middleware/IMiddleware";
14 |
15 | /**
16 | * @class
17 | * @implements Middleware
18 | * Class representing DummyHTTPMessageHandler
19 | */
20 | export class DummyHTTPMessageHandler implements Middleware {
21 | /**
22 | * @private
23 | * A member holding the array of response objects
24 | */
25 | private responses: Response[];
26 |
27 | /**
28 | * @public
29 | * @constructor
30 | * To create an instance of DummyHTTPMessageHandler
31 | * @param {Response[]} [responses = []] - The array of response objects
32 | * @returns An instance of DummyHTTPMessageHandler
33 | */
34 | public constructor(responses: Response[] = []) {
35 | this.responses = responses;
36 | }
37 |
38 | /**
39 | * @public
40 | * To set the array of responses
41 | * @param {Response[]} response - The array of responses
42 | * @returns Nothing
43 | */
44 | public setResponses(responses: Response[]): void {
45 | this.responses = responses;
46 | }
47 |
48 | /**
49 | * @public
50 | * @async
51 | * To execute the current middleware
52 | * @param {Context} context - The request context object
53 | * @returns A promise that resolves to nothing
54 | */
55 | public async execute(context: Context) {
56 | context.response = this.responses.shift();
57 | return;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/test/DummyHandlerOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module DummyHandlerOptions
10 | */
11 |
12 | import { MiddlewareOptions } from "../src/middleware/options/IMiddlewareOptions";
13 |
14 | /**
15 | * @class
16 | * @implements MiddlewareOptions
17 | * Class for DummyHandlerOptions
18 | */
19 |
20 | export class DummyHandlerOptions implements MiddlewareOptions {
21 | /**
22 | * @public
23 | * A member holding a dummy string
24 | */
25 | public dummyString: string;
26 |
27 | /**
28 | * @public
29 | * @async
30 | * To create an instance of DummyHandlerOptions
31 | * @param {string} dummyString - The dummy string
32 | * @returns An instance of DummyHandlerOptions
33 | */
34 | public constructor(dummyString = "dummy") {
35 | this.dummyString = dummyString;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/test/Tests.md:
--------------------------------------------------------------------------------
1 | The /test folder consists of unit tests written using the following testing tools
2 |
3 | - mocha
4 | - chai
5 | - karma
6 | - @istanbuljs/nyc-config-typescript
7 |
8 | Scripts used
9 |
10 | - `npm run test` - To run unit tests in test/common and test/node.
11 | - `npm run test:cjs` - To run unit tests in test/common and test/node compiled as CommonJS modules.
12 | - `npm run test:esm` - To run unit tests in test/common and test/node compiled as ESM modules.
13 | - `npm run test:development` - To run tests in test/development folder.
14 | - `npm run test:coverage` - To get the test code coverage after running the tests.
15 | - `npm run karma` - To run the units tests in test/common and test/browser folders on a headless browser.
16 |
--------------------------------------------------------------------------------
/test/browser/BrowserTests.md:
--------------------------------------------------------------------------------
1 | This folder contains unit tests which are browser-specific. Example - The tests in [GraphResponseHandler](./core/GraphResponseHandler.ts) requires the DOMParser which is a browser functionality.
2 |
3 | Karma is used for testing the code in browsers. To run the unit tests using karma run the following steps -
4 |
5 | - Run the script `npm install`.
6 | - Run the script `npm run karma`.
7 |
--------------------------------------------------------------------------------
/test/browser/core/GraphResponseHandler.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { DocumentType, GraphResponseHandler } from "../../../src/GraphResponseHandler";
11 | import { ResponseType } from "../../../src/ResponseType";
12 |
13 | /**
14 | * References - https://fetch.spec.whatwg.org/#responses
15 | */
16 | describe("GraphResponseHandler.ts", () => {
17 | const htmlString = `
18 |
19 |
20 |
21 | Testing Document
22 |
23 |
24 | Testing
25 |
26 | `;
27 | const status200 = {
28 | status: 200,
29 | statusText: "OK",
30 | };
31 |
32 | /* tslint:disable: no-string-literal */
33 | describe("parseDocumentResponse", () => {
34 | it("Should return the html string", async () => {
35 | const response = new Response(htmlString, status200);
36 | const dom = await GraphResponseHandler["parseDocumentResponse"](response, DocumentType.TEXT_HTML);
37 | assert.isDefined(dom);
38 | assert.instanceOf(dom, Document);
39 | });
40 |
41 | it("Should return response value as text for text/html return type", async () => {
42 | const response = new Response(htmlString, status200);
43 | const responseValue = await GraphResponseHandler["convertResponse"](response, ResponseType.DOCUMENT);
44 | assert.isDefined(responseValue);
45 | assert.instanceOf(responseValue, Document);
46 | });
47 | });
48 | /* tslint:enable: no-string-literal */
49 | });
50 |
--------------------------------------------------------------------------------
/test/common/core/GraphClientError.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { GraphClientError } from "../../../src/GraphClientError";
11 |
12 | describe("GraphClientError", () => {
13 | const message = "test";
14 | const name = "test_name";
15 | it("Should return GraphClientError error with message set", () => {
16 | const gError = new GraphClientError(message);
17 | assert.equal(gError.message, message);
18 | });
19 |
20 | it("Should return GraphClientError when Error object is passed", () => {
21 | const errorParameter = new Error(message);
22 | errorParameter.name = name;
23 | const gError = GraphClientError.setGraphClientError(errorParameter);
24 | assert.equal(gError.message, message);
25 | assert.equal(gError.name, name);
26 | });
27 |
28 | it("Should return GraphClientError when custom error object is passed", () => {
29 | const customErrorParameter = { errorName: name, errorMessage: message };
30 | const gError = GraphClientError.setGraphClientError(customErrorParameter);
31 | assert.isDefined(gError.customError);
32 | assert.equal(gError.customError, customErrorParameter);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/test/common/core/GraphRequestUtil.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { serializeContent, urlJoin } from "../../../src/GraphRequestUtil";
11 |
12 | describe("GraphRequestUtil.ts", () => {
13 | describe("urlJoin", () => {
14 | const output = "host/version/path";
15 |
16 | it("Should append parts with /", () => {
17 | const joined = urlJoin(["host", "version", "path"]);
18 | assert.equal(joined, output);
19 | });
20 |
21 | it("Should append parts with / by removing / from start", () => {
22 | const joined = urlJoin(["host", "/version", "/path"]);
23 | assert.equal(joined, output);
24 | });
25 |
26 | it("Should append parts with / by removing / from end", () => {
27 | const joined = urlJoin(["host/", "version/", "path"]);
28 | assert.equal(joined, output);
29 | });
30 |
31 | it("Should append parts with / by removing / from start and end", () => {
32 | const joined = urlJoin(["host/", "/version/", "/path"]);
33 | assert.equal(joined, output);
34 | });
35 | });
36 |
37 | describe("serializeContent", () => {
38 | it("Should return Buffer/Blob/File/FormData/String as it is", () => {
39 | const str = "Content";
40 | assert.equal(serializeContent(str), str);
41 | const buffer = Buffer.alloc(2, "Buffer");
42 | assert.equal(serializeContent(buffer), buffer);
43 | });
44 |
45 | it("Should convert it to string", () => {
46 | const data = 123;
47 | const str = "123";
48 | assert.equal(serializeContent(data), str);
49 | });
50 |
51 | it("Should throw error for objects that cannot be converted to string", () => {
52 | const node1 = {
53 | data: 1,
54 | link: undefined,
55 | };
56 | const node2 = {
57 | data: 2,
58 | link: undefined,
59 | };
60 | node1.link = node2;
61 | node2.link = node1;
62 | try {
63 | serializeContent(node1);
64 | throw new Error("Test Failed - Something wrong with the serialize content, it should not stringify cyclic referenced objects");
65 | } catch (error) {
66 | assert.equal(error.message, "Unable to stringify the content");
67 | }
68 | });
69 |
70 | it("Should return undefined for the case of undefined content value", () => {
71 | const val = undefined;
72 | assert.equal(serializeContent(val), undefined);
73 | });
74 |
75 | it("Should return 'null' for the case of null content value", () => {
76 | const val = null;
77 | assert.equal(serializeContent(val), "null");
78 | });
79 | });
80 | });
81 |
--------------------------------------------------------------------------------
/test/common/core/HTTPClient.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { HTTPClient } from "../../../src/HTTPClient";
11 | import { Context } from "../../../src/IContext";
12 | import { FetchOptions } from "../../../src/IFetchOptions";
13 | import { DummyHTTPMessageHandler } from "../../DummyHTTPMessageHandler";
14 | import { DUMMY_BASE_URL } from "../../test-helper";
15 |
16 | describe("HTTPClient.ts", () => {
17 | const httpMessageHandler: DummyHTTPMessageHandler = new DummyHTTPMessageHandler();
18 | const httpClient: HTTPClient = new HTTPClient(httpMessageHandler);
19 | describe("constructor", () => {
20 | it("Should create an instance and populate middleware member", () => {
21 | assert.isDefined(httpClient["middleware"]);
22 | assert.equal(httpClient["middleware"], httpMessageHandler);
23 | });
24 |
25 | it("Should create an instance and populate middleware member when passing a middleware array", () => {
26 | const client = new HTTPClient(...[httpMessageHandler]);
27 | assert.isDefined(client["middleware"]);
28 | assert.equal(client["middleware"], httpMessageHandler);
29 | });
30 |
31 | it("Should throw an error if middleware is undefined", () => {
32 | try {
33 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
34 | const client = new HTTPClient();
35 | throw new Error("Test failed - Expected error was not thrown");
36 | } catch (error) {
37 | assert.equal(error.name, "InvalidMiddlewareChain");
38 | }
39 | });
40 |
41 | it("Should throw an error if middleware is passed as an empty array", () => {
42 | try {
43 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
44 | const client = new HTTPClient(...[]);
45 | throw new Error("Test failed - Expected error was not thrown");
46 | } catch (error) {
47 | assert.equal(error.name, "InvalidMiddlewareChain");
48 | }
49 | });
50 | });
51 |
52 | describe("sendRequest", async () => {
53 | it("Should throw error for invalid request options incase if the url and options are passed", async () => {
54 | try {
55 | const url = "dummy_url";
56 | const context: Context = {
57 | request: url,
58 | };
59 | await httpClient.sendRequest(context);
60 | throw new Error("Test Failed - Something wrong with the context validation");
61 | } catch (error) {
62 | assert.equal(error.name, "InvalidRequestOptions");
63 | }
64 | });
65 |
66 | it("Should execute for context object with Request instance", async () => {
67 | const request: Request = new Request(DUMMY_BASE_URL + "/dummy_url", {
68 | method: "GET",
69 | });
70 | const context: Context = {
71 | request,
72 | };
73 | await httpClient.sendRequest(context);
74 | });
75 |
76 | it("Should execute for context object with request uri and options", async () => {
77 | const url = "dummy_url";
78 | const options: FetchOptions = {
79 | method: "GET",
80 | };
81 | const context: Context = {
82 | request: url,
83 | options,
84 | };
85 | await httpClient.sendRequest(context);
86 | });
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/test/common/core/HTTPClientFactory.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { HTTPClient } from "../../../src/HTTPClient";
11 | import { HTTPClientFactory } from "../../../src/HTTPClientFactory";
12 | import { DummyAuthenticationProvider } from "../../DummyAuthenticationProvider";
13 | import { DummyHTTPMessageHandler } from "../../DummyHTTPMessageHandler";
14 |
15 | describe("HTTPClientFactory.ts", () => {
16 | describe("createWithAuthenticationProvider", () => {
17 | const dummyAuthProvider = new DummyAuthenticationProvider();
18 | const dummyHTTPHandler = new DummyHTTPMessageHandler();
19 | it("Should create an HTTPClient instance with default middleware chain", () => {
20 | const client: HTTPClient = HTTPClientFactory.createWithAuthenticationProvider(dummyAuthProvider);
21 | assert.isTrue(client instanceof HTTPClient);
22 | assert.isDefined(client["middleware"]);
23 | });
24 |
25 | it("Should create an HTTPClient with given middleware chain", () => {
26 | const client: HTTPClient = HTTPClientFactory.createWithMiddleware(dummyHTTPHandler);
27 | assert.isTrue(client instanceof HTTPClient);
28 | assert.isDefined(client["middleware"]);
29 | });
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/test/common/core/Range.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { Range } from "../../../src/tasks/FileUploadTask/Range";
11 |
12 | describe("Range.ts", () => {
13 | describe("Constructor", () => {
14 | const defaultValue = -1;
15 |
16 | it("Should create a Range instance with given min and max values", () => {
17 | const min = 1;
18 | const max = 10;
19 | const range = new Range(min, max);
20 | assert.equal(range.minValue, min);
21 | assert.equal(range.maxValue, max);
22 | });
23 |
24 | it("Should create a range instance with default values", () => {
25 | const range = new Range();
26 | assert.equal(range.minValue, defaultValue);
27 | assert.equal(range.maxValue, defaultValue);
28 | });
29 |
30 | it("Should create a range instance with default max value", () => {
31 | const min = 1;
32 | const range = new Range(min);
33 | assert.equal(range.minValue, min);
34 | assert.equal(range.maxValue, defaultValue);
35 | });
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/test/common/middleware/AuthenticationHandler.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { ChaosHandler, ChaosHandlerOptions, ChaosStrategy } from "../../../src";
11 | import { GRAPH_BASE_URL } from "../../../src/Constants";
12 | import { Context } from "../../../src/IContext";
13 | import { AuthenticationHandler } from "../../../src/middleware/AuthenticationHandler";
14 | import { DummyAuthenticationProvider } from "../../DummyAuthenticationProvider";
15 | import { DUMMY_BASE_URL } from "../../test-helper";
16 |
17 | const dummyAuthProvider = new DummyAuthenticationProvider();
18 | const authHandler = new AuthenticationHandler(dummyAuthProvider);
19 | const chaosHandler = new ChaosHandler(new ChaosHandlerOptions(ChaosStrategy.MANUAL, "TEST_MESSAGE", 200));
20 |
21 | describe("AuthenticationHandler.ts", async () => {
22 | describe("Constructor", () => {
23 | it("Should return an AuthenticationHandler for given AuthenticationProvider", () => {
24 | assert.isTrue(authHandler instanceof AuthenticationHandler);
25 | assert.equal(authHandler["authenticationProvider"], dummyAuthProvider);
26 | });
27 | });
28 | describe("Auth Headers", () => {
29 | it("Should delete Auth header when Request object is passed with non Graph URL", async () => {
30 | const request = new Request(DUMMY_BASE_URL + "/test_url");
31 | const context: Context = {
32 | request,
33 | options: {
34 | headers: {
35 | Authorization: "TEST_VALUE",
36 | },
37 | },
38 | };
39 | authHandler.setNext(chaosHandler);
40 | await authHandler.execute(context);
41 | assert.equal(context.options.headers["Authorization"], undefined);
42 | });
43 |
44 | it("Should contain Auth header when Request object is passed with custom URL", async () => {
45 | const request = new Request("https://custom/");
46 | const context: Context = {
47 | request,
48 | customHosts: new Set(["custom"]),
49 | options: {
50 | headers: {},
51 | },
52 | };
53 | const accessToken = "Bearer DUMMY_TOKEN";
54 |
55 | await authHandler.execute(context);
56 | assert.equal((request as Request).headers.get("Authorization"), accessToken);
57 | });
58 |
59 | it("Should contain Auth header when Request object is passed with a valid Graph URL", async () => {
60 | const request = new Request(GRAPH_BASE_URL);
61 | const context: Context = {
62 | request,
63 | customHosts: new Set(["custom"]),
64 | options: {
65 | headers: {},
66 | },
67 | };
68 | const accessToken = "Bearer DUMMY_TOKEN";
69 | await authHandler.execute(context);
70 | assert.equal((request as Request).headers.get("Authorization"), accessToken);
71 | });
72 | });
73 | });
74 |
--------------------------------------------------------------------------------
/test/common/middleware/AuthenticationHandlerOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { AuthenticationHandlerOptions } from "../../../src/middleware/options/AuthenticationHandlerOptions";
11 | import { DummyAuthenticationProvider } from "../../DummyAuthenticationProvider";
12 |
13 | describe("AuthenticationHandlerOptions.ts", () => {
14 | const dummyAuthProvider = new DummyAuthenticationProvider();
15 | const authOptions = { scopes: ["test"] };
16 | it("Should create an instance with all the given options", () => {
17 | const options = new AuthenticationHandlerOptions(dummyAuthProvider, authOptions);
18 | assert.equal(options.authenticationProvider, dummyAuthProvider);
19 | assert.equal(options.authenticationProviderOptions, authOptions);
20 | });
21 |
22 | it("Should be undefined value if no value is passed", () => {
23 | const options = new AuthenticationHandlerOptions(undefined, authOptions);
24 | assert.isUndefined(options.authenticationProvider);
25 | assert.equal(options.authenticationProviderOptions, authOptions);
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/test/common/middleware/MiddlewareControl.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module MiddlewareControl
10 | */
11 |
12 | import "isomorphic-fetch";
13 |
14 | import { assert } from "chai";
15 |
16 | import { MiddlewareControl } from "../../../src/middleware/MiddlewareControl";
17 | import { DummyHandlerOptions } from "../../DummyHandlerOptions";
18 |
19 | describe("MiddlewareControl.ts", () => {
20 | const dummyHandlerOption = new DummyHandlerOptions();
21 |
22 | describe("constructor", () => {
23 | it("Should populate its middleware options map", () => {
24 | const middlewareControl = new MiddlewareControl([dummyHandlerOption]);
25 | assert.isDefined(middlewareControl["middlewareOptions"]);
26 | assert.equal(middlewareControl["middlewareOptions"].size, 1);
27 | });
28 |
29 | it("Should create empty middleware options map by default", () => {
30 | const middlewareControl = new MiddlewareControl();
31 | assert.isDefined(middlewareControl["middlewareOptions"]);
32 | assert.equal(middlewareControl["middlewareOptions"].size, 0);
33 | });
34 | });
35 |
36 | describe("getMiddlewareOption", () => {
37 | it("Should return the middleware option for a given class name", () => {
38 | const middlewareControl = new MiddlewareControl([dummyHandlerOption]);
39 | const retryOptions: DummyHandlerOptions = middlewareControl.getMiddlewareOptions(dummyHandlerOption.constructor as () => any) as DummyHandlerOptions;
40 | assert.isDefined(retryOptions);
41 | assert.equal(dummyHandlerOption, retryOptions);
42 | });
43 |
44 | it("Should return undefined for unknown class name", () => {
45 | const middlewareControl = new MiddlewareControl([dummyHandlerOption]);
46 | const retryOptions = middlewareControl.getMiddlewareOptions(() => "NotAvailableHandlerOption");
47 | assert.isUndefined(retryOptions);
48 | });
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/test/common/middleware/MiddlewareFactory.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { AuthenticationHandler, CustomAuthenticationProvider, HTTPMessageHandler, RedirectHandler, RetryHandler, TelemetryHandler } from "../../../src";
11 | import { AuthProvider } from "../../../src/IAuthProvider";
12 | import { MiddlewareFactory } from "../../../src/middleware/MiddlewareFactory";
13 |
14 | describe("MiddlewareFactory", () => {
15 | it("Should return the default pipeline", () => {
16 | const provider: AuthProvider = (done) => {
17 | done(null, "dummy_token");
18 | };
19 | const defaultMiddleWareArray = MiddlewareFactory.getDefaultMiddlewareChain(new CustomAuthenticationProvider(provider));
20 |
21 | assert.isTrue(defaultMiddleWareArray[0] instanceof AuthenticationHandler);
22 | assert.isTrue(defaultMiddleWareArray[1] instanceof RetryHandler);
23 | assert.isTrue(defaultMiddleWareArray[2] instanceof RedirectHandler);
24 | assert.isTrue(defaultMiddleWareArray[3] instanceof TelemetryHandler);
25 | assert.isTrue(defaultMiddleWareArray[4] instanceof HTTPMessageHandler);
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/test/common/middleware/RedirectHandlerOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { RedirectHandlerOptions } from "../../../src/middleware/options/RedirectHandlerOptions";
11 |
12 | describe("RedirectHandlerOptions.ts", () => {
13 | describe("constructor", () => {
14 | it("Should initialize the instance with given options", () => {
15 | const shouldRedirect = (response: Response) => {
16 | if (response.status === 301) {
17 | return true;
18 | }
19 | return false;
20 | };
21 | const maxRedirects = 5;
22 | const options = new RedirectHandlerOptions(maxRedirects, shouldRedirect);
23 | assert.equal(options.maxRedirects, maxRedirects);
24 | assert.equal(options.shouldRedirect, shouldRedirect);
25 | });
26 |
27 | it("Should throw error for setting max redirects more than allowed", () => {
28 | try {
29 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
30 | const options = new RedirectHandlerOptions(100);
31 | throw new Error("Test Failed - Something wrong with the max redirects value redirection");
32 | } catch (error) {
33 | assert.equal(error.name, "MaxLimitExceeded");
34 | }
35 | });
36 | it("Should throw error for setting max redirects to negative", () => {
37 | try {
38 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
39 | const options = new RedirectHandlerOptions(-10);
40 | throw new Error(" Test Failed - Something wrong with the max redirects value redirection");
41 | } catch (error) {
42 | assert.equal(error.name, "MinExpectationNotMet");
43 | }
44 | });
45 |
46 | it("Should initialize instance with default options", () => {
47 | const options = new RedirectHandlerOptions();
48 | assert.equal(options.maxRedirects, RedirectHandlerOptions["DEFAULT_MAX_REDIRECTS"]);
49 | assert.equal(options.shouldRedirect, RedirectHandlerOptions["defaultShouldRedirect"]);
50 | });
51 | });
52 | });
53 |
--------------------------------------------------------------------------------
/test/common/tasks/OneDriveLargeFileUploadTask.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import { OneDriveLargeFileUploadTask } from "../../../src/tasks/OneDriveLargeFileUploadTask";
11 |
12 | describe("OneDriveLargeFileUploadTask.ts", () => {
13 | describe("constructCreateSessionUrl", () => {
14 | const spaceFileName = " test.png ";
15 | const fileName = "test.png";
16 | const specialFileName = "test file.png";
17 | const encodedFileName = "test%20file.png";
18 |
19 | it("Should trim the extra spaces in the filename", () => {
20 | assert.equal(`/me/drive/root:/${fileName}:/createUploadSession`, OneDriveLargeFileUploadTask["constructCreateSessionUrl"](spaceFileName));
21 | });
22 |
23 | it("Should encode space in the filename", () => {
24 | assert.equal(`/me/drive/root:/${encodedFileName}:/createUploadSession`, OneDriveLargeFileUploadTask["constructCreateSessionUrl"](specialFileName));
25 | });
26 |
27 | it("Should return url with default root value", () => {
28 | assert.equal(`/me/drive/root:/${fileName}:/createUploadSession`, OneDriveLargeFileUploadTask["constructCreateSessionUrl"](fileName));
29 | });
30 |
31 | it("Should return url with default root value for an empty path string", () => {
32 | assert.equal(`/me/drive/root:/${fileName}:/createUploadSession`, OneDriveLargeFileUploadTask["constructCreateSessionUrl"](fileName, ""));
33 | });
34 |
35 | it("Should add / in front of the path", () => {
36 | assert.equal(`/me/drive/root:/Documents/${fileName}:/createUploadSession`, OneDriveLargeFileUploadTask["constructCreateSessionUrl"](fileName, "Documents/"));
37 | });
38 |
39 | it("Should add / in back of the path", () => {
40 | assert.equal(`/me/drive/root:/Documents/${fileName}:/createUploadSession`, OneDriveLargeFileUploadTask["constructCreateSessionUrl"](fileName, "/Documents"));
41 | });
42 |
43 | it("Should trim the extra spaces in the path", () => {
44 | assert.equal(`/me/drive/root:/Documents/${fileName}:/createUploadSession`, OneDriveLargeFileUploadTask["constructCreateSessionUrl"](fileName, " /Documents/ "));
45 | });
46 | });
47 |
48 | describe("getFileInfo", () => {
49 | /* tslint:disable: no-string-literal */
50 | it("Should return file content info for Buffer", () => {
51 | const bytes = [1, 2, 3, 4, 5];
52 | const buffer = Buffer.from(bytes);
53 | const fileContent = OneDriveLargeFileUploadTask["getFileInfo"](buffer, "test.png");
54 | const arrayBuffer = new ArrayBuffer(bytes.length);
55 | const typedArray = new Uint8Array(arrayBuffer);
56 | for (let i = 0; i < bytes.length; i++) {
57 | typedArray[i] = bytes[i];
58 | }
59 | assert.deepEqual(fileContent, { content: arrayBuffer as Buffer, size: bytes.length });
60 | });
61 | /* tslint:enable: no-string-literal */
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/test/common/tasks/OneDriveLargeFileUploadTaskUtil.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { assert } from "chai";
9 |
10 | import * as OneDriveLargeFileUploadTaskUtil from "../../../src/tasks/OneDriveLargeFileUploadTaskUtil";
11 |
12 | describe("OneDriveLargeFileUploadTaskUtil", () => {
13 | describe("getValidRangeSize", () => {
14 | it("Should return size in multiple of 320KB for the size not a multiple of 320KB", (done) => {
15 | assert.equal(327680, OneDriveLargeFileUploadTaskUtil.getValidRangeSize(327685));
16 | done();
17 | });
18 | it("Should return same size for the size less than 320 KB", (done) => {
19 | assert.equal(100, OneDriveLargeFileUploadTaskUtil.getValidRangeSize(100));
20 | done();
21 | });
22 | it("Should return size in multiple of 320KB with max range of 60 MB for file size more than 60 MB", (done) => {
23 | assert.equal(62914560, OneDriveLargeFileUploadTaskUtil.getValidRangeSize(104857600));
24 | done();
25 | });
26 | it("Should return size in multiple of 320KB for the size multiple of 320 KB", (done) => {
27 | assert.equal(1638400, OneDriveLargeFileUploadTaskUtil.getValidRangeSize(1638400));
28 | done();
29 | });
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/test/common/tasks/StreamUpload.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | /* eslint-disable @typescript-eslint/no-unused-vars */
8 | import "isomorphic-fetch";
9 |
10 | import { assert } from "chai";
11 | import { Readable } from "stream";
12 |
13 | import { GraphClientError } from "../../../src";
14 | import { StreamUpload } from "../../../src/tasks/FileUploadTask/FileObjectClasses/StreamUpload";
15 |
16 | const fileName = "Test_File_Name";
17 | describe("StreamUpload.test", () => {
18 | it("Should return slice with defined size less than complete range size", async () => {
19 | const totalRangesize = 36;
20 | const sliceSize = 20;
21 | const buf = Buffer.alloc(totalRangesize, "a");
22 | const readStream = new Readable({
23 | read() {
24 | this.push(buf);
25 | this.push(null);
26 | },
27 | });
28 |
29 | const upload = new StreamUpload(readStream, fileName, totalRangesize);
30 |
31 | const slice = await upload.sliceFile({ minValue: 0, maxValue: sliceSize - 1 });
32 |
33 | assert.isDefined(slice);
34 | assert.equal(sliceSize, (slice as Buffer).length);
35 | assert.equal(readStream.readableLength, 16);
36 | });
37 | });
38 |
39 | it("Should return slice ", async () => {
40 | const totalRangesize = 36;
41 | const buf = Buffer.alloc(totalRangesize, "a");
42 | const readStream = new Readable({
43 | read() {
44 | this.push(buf);
45 | this.push(null);
46 | },
47 | });
48 | const upload = new StreamUpload(readStream, fileName, totalRangesize);
49 | const slice = await upload.sliceFile({ minValue: 0, maxValue: totalRangesize - 1 });
50 | assert.isDefined(slice);
51 | assert.equal(totalRangesize, (slice as Buffer).length);
52 | assert.equal(readStream.readableLength, 0);
53 | });
54 |
55 | it("Should throw error if stream ends before complete range size is read", async () => {
56 | const totalsize = 6;
57 | const sliceSize = 20;
58 | const buf = Buffer.alloc(totalsize, "a");
59 | const readStream = new Readable({
60 | read() {
61 | this.push(buf);
62 | this.push(null);
63 | },
64 | });
65 | try {
66 | const upload = new StreamUpload(readStream, fileName, totalsize);
67 | const slice = await upload.sliceFile({ minValue: 0, maxValue: sliceSize - 1 });
68 | if (slice) {
69 | throw Error("Test failed. Expected error now thrown");
70 | }
71 | } catch (err) {
72 | assert.instanceOf(err, GraphClientError);
73 | assert.equal(err.message, "Stream ended before reading required range size");
74 | }
75 | });
76 |
--------------------------------------------------------------------------------
/test/development/DevelopmentTests.md:
--------------------------------------------------------------------------------
1 | This folder contains test which are real-time.
2 |
3 | Following are the steps to run the tests in the test/development folder.
4 |
5 | 1. Rename the [secrets.sample.ts](../secrets.sample.ts) to secrets.ts
6 | 2. Go to Graph Explorer.
7 | 3. Login with the account you want to use to run the unit tests.
8 | 4. Click on the Access token tab option to get an access token.
9 | 5. Copy the access token and put it into the secrets.ts file and save.
10 | 6. Run the script `npm run test:development`.
11 |
--------------------------------------------------------------------------------
/test/development/HardCodedAuthenticationProvider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | /**
9 | * @module HardCodedAuthenticationProvider
10 | */
11 |
12 | import { AuthenticationProvider } from "../../src/IAuthenticationProvider";
13 | import { AccessToken } from "./secrets";
14 |
15 | /**
16 | * @class
17 | * @implements AuthenticationProvider
18 | * Class representing HardCodedAuthenticationProvider
19 | */
20 | export class HardCodedAuthenticationProvider implements AuthenticationProvider {
21 | /**
22 | * @public
23 | * @async
24 | * To get the access token
25 | * @returns The promise that resolves to an access token
26 | */
27 | public async getAccessToken(): Promise {
28 | return Promise.resolve(AccessToken);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test/development/secrets.sample.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file
3 | * Defines access token exporting structure
4 | *
5 | * To use authentication based(making real requests to the graph service) testing populate this access token's value and rename this file as secrets.ts
6 | */
7 | export const AccessToken = "";
8 |
--------------------------------------------------------------------------------
/test/development/test-helper.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import "isomorphic-fetch";
9 |
10 | import { Client } from "../../src/index";
11 | import { HardCodedAuthenticationProvider } from "./HardCodedAuthenticationProvider";
12 |
13 | export function getClient(): Client {
14 | return Client.initWithMiddleware({
15 | authProvider: new HardCodedAuthenticationProvider(),
16 | });
17 | }
18 |
19 | export function randomString() {
20 | return Math.random()
21 | .toString(36)
22 | .substring(7);
23 | }
24 |
--------------------------------------------------------------------------------
/test/development/workload/PageIterator.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { Event } from "@microsoft/microsoft-graph-types";
9 | import { assert } from "chai";
10 |
11 | import { GraphRequestOptions, PageIterator, PageIteratorCallback } from "../../../src/tasks/PageIterator";
12 | import { getClient } from "../test-helper";
13 | const client = getClient();
14 | describe("PageIterator", () => {
15 | const pstHeader = { Prefer: 'outlook.timezone= "pacific standard time"' };
16 | const utc = "UTC";
17 | const pst = "Pacific Standard Time";
18 | const testURL = "/me/events";
19 |
20 | before(async function() {
21 | this.timeout(20000);
22 |
23 | const response = await client.api(testURL + "?count=true").get();
24 | const numberOfEvents = 4;
25 | const existingEventsCount = response.value["@odata.count"];
26 |
27 | if (existingEventsCount >= numberOfEvents) {
28 | return;
29 | }
30 | const eventSubject = '"subject": "Test event ';
31 | const eventTimeZone = '"timeZone": "UTC"';
32 | const eventStartDateTime = '"start": { "dateTime":"' + new Date().toISOString() + '",' + eventTimeZone + "}";
33 | const eventEndDateTime = '"end": { "dateTime":"' + new Date().toISOString() + '",' + eventTimeZone + "}";
34 |
35 | for (let i = 1; i <= numberOfEvents - existingEventsCount; i++) {
36 | const eventBody = "{" + eventSubject + "" + 1 + '",' + eventStartDateTime + "," + eventEndDateTime + "}";
37 | const response = await client.api(testURL).post(eventBody);
38 | if (response.error) {
39 | throw response.error;
40 | }
41 | }
42 | });
43 |
44 | it("same headers passed with pageIterator", async () => {
45 | const response = await client
46 | .api(`${testURL}?$top=2`)
47 | .headers(pstHeader)
48 | .select("id,start,end")
49 | .get();
50 |
51 | const callback: PageIteratorCallback = (eventResponse) => {
52 | const event = eventResponse as Event;
53 | assert.equal(event.start.timeZone, pst);
54 | return true;
55 | };
56 | const requestOptions: GraphRequestOptions = { options: { headers: pstHeader } };
57 | if (response["@odata.nextLink"]) {
58 | const pageIterator = new PageIterator(client, response, callback, requestOptions);
59 | await pageIterator.iterate();
60 | assert.isTrue(pageIterator.isComplete());
61 | }
62 | }).timeout(30 * 1000);
63 |
64 | it("different headers passed with pageIterator", async () => {
65 | const response = await client
66 | .api(`${testURL}?$top=2`)
67 | .headers({ Prefer: `outlook.timezone= "${utc}"` })
68 | .select("id,start,end")
69 | .get();
70 |
71 | let counter = 0;
72 | const callback: PageIteratorCallback = (eventResponse) => {
73 | const event = eventResponse as Event;
74 | if (counter < 2) {
75 | assert.equal(event.start.timeZone, utc);
76 | counter++;
77 | } else {
78 | assert.equal(event.start.timeZone, pst);
79 | }
80 | return true;
81 | };
82 |
83 | const requestOptions = { headers: pstHeader };
84 | if (response["@odata.nextLink"]) {
85 | const pageIterator = new PageIterator(client, response, callback, requestOptions);
86 | await pageIterator.iterate();
87 | assert.isTrue(pageIterator.isComplete());
88 | }
89 | }).timeout(30 * 1000);
90 | });
91 |
--------------------------------------------------------------------------------
/test/development/workload/delta-query.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import "isomorphic-fetch";
9 |
10 | import { Event } from "@microsoft/microsoft-graph-types";
11 | import { assert } from "chai";
12 |
13 | import { getClient, randomString } from "../test-helper";
14 |
15 | const client = getClient();
16 |
17 | describe("Delta Query", function() {
18 | this.timeout(10 * 1000);
19 | const today = new Date();
20 | const tomorrow = new Date(today.getTime() + 1 * 24 * 60 * 60 * 1000);
21 | const nextWeek = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000);
22 |
23 | let deltaLink: string;
24 |
25 | const subject: string = randomString();
26 |
27 | const mockEvent: Event = {
28 | originalStartTimeZone: tomorrow.toISOString(),
29 | originalEndTimeZone: tomorrow.toISOString(),
30 | reminderMinutesBeforeStart: 99,
31 | isReminderOn: true,
32 | subject,
33 | };
34 |
35 | it("Gets the delta link for the initial calendar view list", async () => {
36 | let res = await client
37 | .api("/me/calendarview/delta")
38 | .query({
39 | startdatetime: today.toISOString(),
40 | enddatetime: nextWeek.toISOString(),
41 | })
42 | .get();
43 | while (res["@odata.nextLink"] !== undefined) {
44 | res = await client.api(res["@odata.nextLink"]).get();
45 | }
46 | assert.isDefined(res["@odata.deltaLink"]);
47 | deltaLink = res["@odata.deltaLink"];
48 | });
49 |
50 | it("Creates a calendar event to see changes in the delta response", async () => {
51 | const response = await client.api("/me/events").post(mockEvent);
52 | assert.isDefined(response.id);
53 | assert.equal(response.subject, subject);
54 | });
55 |
56 | it("Uses delta token to see changed calendar view", async () => {
57 | let found = false;
58 | if (typeof deltaLink !== "undefined") {
59 | const res = await client.api(deltaLink).get();
60 | const events: Event[] = res.value;
61 | for (const event of events) {
62 | if (event.subject === mockEvent.subject) {
63 | found = true;
64 | }
65 | }
66 | }
67 | assert.isTrue(found);
68 | });
69 | });
70 |
--------------------------------------------------------------------------------
/test/development/workload/excel.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { WorkbookRange, WorkbookWorksheet } from "@microsoft/microsoft-graph-types";
9 | import { assert } from "chai";
10 | import * as fs from "fs";
11 |
12 | import { getClient, randomString } from "../test-helper";
13 |
14 | const client = getClient();
15 |
16 | const ExcelFilename = `empty-spreadsheet-${randomString()}.xlsx`;
17 |
18 | describe("Excel", function() {
19 | this.timeout(10 * 1000);
20 | beforeEach((done) => {
21 | setTimeout(() => {
22 | done();
23 | }, 1000);
24 | });
25 | it("Uploads an Excel file to OneDrive", async () => {
26 | const file = fs.readFileSync("./test/sample_files/empty-spreadsheet.xlsx");
27 | const res = await client.api(`/me/drive/root/children/${ExcelFilename}/content`).put(file);
28 | assert.isDefined(res.id);
29 | });
30 |
31 | it("Lists the worksheets in an excel file", async () => {
32 | const res = await client.api(`/me/drive/root:/${ExcelFilename}:/workbook/worksheets`).get();
33 | const worksheets = res.value as WorkbookWorksheet[];
34 | const sheet1 = worksheets[0];
35 | assert.isNumber(sheet1.position);
36 | assert.isString(sheet1.visibility);
37 | assert.isString(sheet1.id);
38 | assert.isUndefined(sheet1["random fake property that should be null"]);
39 | });
40 |
41 | it("Updates workbook worksheet range", async () => {
42 | const sampleData: WorkbookRange = {
43 | values: [
44 | ["cell a1", "cell a2"],
45 | ["cell b1", "cell b2"],
46 | ],
47 | };
48 | const response = await client.api(`/me/drive/root:/${ExcelFilename}:/workbook/worksheets/Sheet1/range(address='A1:B2')`).patch(sampleData);
49 | assert.isDefined(response["@odata.id"]);
50 | assert.isDefined(response.values);
51 | });
52 |
53 | it("GETs the used range of the worksheet", async () => {
54 | const res: WorkbookRange = await client.api(`/me/drive/root:/${ExcelFilename}:/workbook/worksheets/Sheet1/range/usedrange`).get();
55 | assert.isNumber(res.cellCount);
56 | assert.isString(res.address);
57 | assert.isUndefined(res["random fake property that should be null"]);
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/test/development/workload/groups.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { Group } from "@microsoft/microsoft-graph-types";
9 | import { assert } from "chai";
10 |
11 | import { getClient, randomString } from "../test-helper";
12 |
13 | const client = getClient();
14 |
15 | describe("Groups", function() {
16 | this.timeout(10 * 1000);
17 | it("Fetch a list of groups and access properties on a collection item", async () => {
18 | const res = await client.api("/groups").get();
19 | const group = res.value[0] as Group;
20 | assert.isDefined(group.displayName);
21 | assert.isDefined(group.mail);
22 | assert.isDefined(group.id);
23 | assert.isUndefined(group["random fake property that should be null"]);
24 | });
25 |
26 | it("Create a group and validate properties were set", async () => {
27 | const group: Group = {
28 | displayName: randomString(),
29 | description: randomString(),
30 | groupTypes: ["Unified"],
31 | mailEnabled: true,
32 | mailNickname: randomString(),
33 | securityEnabled: true,
34 | };
35 | const res = await client.api("/groups").post(group);
36 | const createdGroup = res as Group;
37 | assert.equal(createdGroup.displayName, group.displayName);
38 | assert.equal(createdGroup.description, group.description);
39 | assert.equal(createdGroup.mailEnabled, group.mailEnabled);
40 | assert.isString(createdGroup.id);
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/test/development/workload/insights.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { Person } from "@microsoft/microsoft-graph-types";
9 | import { assert } from "chai";
10 |
11 | import { getClient } from "../test-helper";
12 |
13 | const client = getClient();
14 |
15 | describe("Social and Insights", function() {
16 | this.timeout(10 * 1000);
17 | it("Fetch a list of people", async () => {
18 | const res = await client.api("/me/people").get();
19 | const person = res.value[0] as Person;
20 | assert.isDefined(person.displayName);
21 | assert.isDefined(person.surname);
22 | assert.isDefined(person.id);
23 | assert.isUndefined(person["random fake property that should be null"]);
24 | });
25 |
26 | it("Searches the people list", async () => {
27 | await client
28 | .api("/me/people")
29 | .query("$search=j")
30 | .get();
31 | });
32 |
33 | it("Searches the people list with a topic", async () => {
34 | await client
35 | .api("/me/people")
36 | .query(`$search="topic: planning"`)
37 | .get();
38 | });
39 |
40 | it("Finds items trending around me", async () => {
41 | await client
42 | .api("/me/insights/trending")
43 | .version("beta")
44 | .get();
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/test/development/workload/largeFileUpload.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import "isomorphic-fetch";
9 |
10 | import { assert } from "chai";
11 | import * as fs from "fs";
12 |
13 | import { getClient } from "../test-helper";
14 | const client = getClient();
15 |
16 | import { OneDriveLargeFileUploadOptions, OneDriveLargeFileUploadTask, Range, StreamUpload, UploadEventHandlers } from "../../../src/index";
17 |
18 | describe("LargeFileUpload", () => {
19 | const fileName = "sample_image.jpg";
20 | const stats = fs.statSync(`./test/sample_files/${fileName}`);
21 | const totalsize = stats.size;
22 | it("Test OneDrive stream upload with progress callback options", async () => {
23 | let isProgressReportCalled = false;
24 |
25 | const progress = (range?: Range, extraCallBackParams?: unknown) => {
26 | assert.isTrue(extraCallBackParams);
27 | assert.isDefined(range);
28 | isProgressReportCalled = true;
29 | };
30 |
31 | const uploadEventHandlers: UploadEventHandlers = {
32 | progress,
33 | extraCallbackParam: true,
34 | };
35 |
36 | const options: OneDriveLargeFileUploadOptions = {
37 | path: "/Documents",
38 | fileName,
39 | rangeSize: 1024 * 1024,
40 | uploadEventHandlers,
41 | };
42 | const readStream = fs.createReadStream(`./test/sample_files/${fileName}`);
43 | const file = new StreamUpload(readStream, fileName, totalsize);
44 | const uploadTask = await OneDriveLargeFileUploadTask.createTaskWithFileObject(client, file, options);
45 | const response = await uploadTask.upload();
46 | assert.isDefined(response.responseBody["id"]);
47 | assert.isTrue(isProgressReportCalled);
48 | }).timeout(30 * 1000);
49 |
50 | it("Test OneDrive File Upload", async () => {
51 | const options: OneDriveLargeFileUploadOptions = {
52 | path: "/Documents",
53 | fileName,
54 | rangeSize: 1024 * 1024,
55 | };
56 | const file = fs.readFileSync(`./test/sample_files/${fileName}`);
57 | const uploadTask = await OneDriveLargeFileUploadTask.create(client, file, options);
58 | const response = await uploadTask.upload();
59 | assert.isDefined(response.responseBody["id"]);
60 | }).timeout(30 * 1000);
61 |
62 | it("Test OneDrive File Upload to custom url", async () => {
63 | const options: OneDriveLargeFileUploadOptions = {
64 | path: "/Documents",
65 | fileName,
66 | rangeSize: 1024 * 1024,
67 | uploadSessionURL: `https://graph.microsoft.com/v1.0/me/drive/special/approot:/sampleTest/${fileName}:/createUploadSession`,
68 | };
69 | const file = fs.readFileSync(`./test/sample_files/${fileName}`);
70 | const uploadTask = await OneDriveLargeFileUploadTask.create(client, file, options);
71 | const response = await uploadTask.upload();
72 | assert.isDefined(response.responseBody["id"]);
73 | }).timeout(30 * 1000);
74 | });
75 |
--------------------------------------------------------------------------------
/test/development/workload/open-extensions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { OpenTypeExtension } from "@microsoft/microsoft-graph-types";
9 | import { assert } from "chai";
10 |
11 | import { getClient, randomString } from "../test-helper";
12 |
13 | const client = getClient();
14 |
15 | interface ColorOpenExtension extends OpenTypeExtension {
16 | color: string;
17 | }
18 |
19 | let extension: ColorOpenExtension = {
20 | extensionName: `com.javascript.extension-${randomString()}`,
21 | color: randomString(),
22 | };
23 |
24 | describe("Open Extensions", function() {
25 | this.timeout(10 * 1000);
26 |
27 | it("Use open extensions to add a field to users", async () => {
28 | const response = await client.api("/me/extensions").post(extension);
29 | const createdExtension = response as ColorOpenExtension;
30 | assert.isDefined(createdExtension.id);
31 | assert.equal(createdExtension.color, extension.color);
32 | assert.equal(createdExtension.extensionName, extension.extensionName);
33 | assert.isUndefined(createdExtension["random fake property that should be null"]);
34 | // save this createdExtension for later tests (id)
35 | extension = createdExtension;
36 | });
37 |
38 | it("Deletes the created open extension", async () => {
39 | await client.api(`/me/extensions/${extension.id}`).delete();
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/test/development/workload/users.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import "isomorphic-fetch";
9 |
10 | import { User } from "@microsoft/microsoft-graph-types";
11 | import { assert } from "chai";
12 |
13 | import { getClient, randomString } from "../test-helper";
14 |
15 | const client = getClient();
16 |
17 | describe("Users", function() {
18 | this.timeout(10 * 1000);
19 |
20 | it("Fetch the authenticated user and access entity properties", async () => {
21 | const res = await client.api("/me").get();
22 | const user = res as User;
23 | assert.isDefined(user.displayName);
24 | assert.isDefined(user.mail);
25 | assert.isDefined(user.id);
26 |
27 | assert.isDefined(user.surname);
28 | assert.isDefined(user.userPrincipalName);
29 |
30 | assert.isArray(user.businessPhones);
31 | assert.isUndefined(user["random fake property that should be null"]);
32 | });
33 |
34 | it("Fetch the authenticated user and access entity properties", async () => {
35 | const res = await client.api("/me").get();
36 | const user = res as User;
37 | assert.isDefined(user.displayName);
38 | assert.isDefined(user.mail);
39 | assert.isDefined(user.id);
40 |
41 | assert.isDefined(user.surname);
42 | assert.isDefined(user.userPrincipalName);
43 |
44 | assert.isArray(user.businessPhones);
45 | assert.isUndefined(user["random fake property that should be null"]);
46 | });
47 |
48 | it("Modify and verify officeLocation property", async () => {
49 | const officeLocation = randomString();
50 | await client.api("/me").patch({ officeLocation });
51 | const res = await client.api("/me").get();
52 | const user = res as User;
53 | assert.equal(user.officeLocation, officeLocation);
54 | });
55 |
56 | it("Modify and verify givenName property", async () => {
57 | const givenName = randomString();
58 | await client.api("/me").patch({ givenName });
59 | const res = await client.api("/me").get();
60 | const user = res as User;
61 | assert.equal(user.givenName, givenName);
62 | });
63 |
64 | it("Fetch a list of users and access properties on a collection item", async () => {
65 | const collection = await client.api("/users").get();
66 | const users: User[] = collection.value;
67 | assert.isDefined(users[0].displayName);
68 | assert.isDefined(users[0].id);
69 | assert.isDefined(users[0].mail);
70 | });
71 |
72 | it("Filters on users list", async () => {
73 | await client
74 | .api("/users")
75 | .filter("Department eq 'Finance'")
76 | .get();
77 | });
78 | });
79 |
--------------------------------------------------------------------------------
/test/node/NodeTests.md:
--------------------------------------------------------------------------------
1 | This folder contains unit tests which are node-specific.
2 |
3 | Karma is used for testing the code in browsers. To run the unit tests using karma run the following steps -
4 |
5 | - Run the script `npm install`
6 | - Run the script `npm run test`
7 |
--------------------------------------------------------------------------------
/test/node/authentication/TokenCredentialAuthenticationProvider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 | /*tslint:disable*/
8 | import { AccessToken, ClientSecretCredential } from "@azure/identity";
9 | import { assert } from "chai";
10 | import * as sinon from "sinon";
11 |
12 | import { TokenCredentialAuthenticationProviderOptions } from "../../../src/authentication/azureTokenCredentials/ITokenCredentialAuthenticationProviderOptions";
13 | import { TokenCredentialAuthenticationProvider } from "../../../src/authentication/azureTokenCredentials/TokenCredentialAuthenticationProvider";
14 | describe("TokenCredentialAuthenticationProvider.ts", () => {
15 | const tenantId = "0000-1111-0000-1111";
16 | const clientId = "CLIENT_ID";
17 | const clientSecret = "CLIENT_SECRET";
18 | const scopes = ["test_scopes"];
19 | it("AccessToken is returned correctly from getToken function", async () => {
20 | const client = new ClientSecretCredential(tenantId, clientId, clientSecret);
21 | if (typeof client.getToken !== "function") {
22 | throw new Error("Method definition for getToken is not found");
23 | }
24 |
25 | const authProviderOptions: TokenCredentialAuthenticationProviderOptions = {
26 | getTokenOptions: null,
27 | scopes,
28 | };
29 | const accessToken: AccessToken = { token: "dummy_valid_token", expiresOnTimestamp: 1 };
30 |
31 | const moq = sinon.mock(client);
32 | moq.expects("getToken").resolves(accessToken);
33 | const tokenCredentialAuthenticationProvider = new TokenCredentialAuthenticationProvider(client, authProviderOptions);
34 | const access = await tokenCredentialAuthenticationProvider.getAccessToken();
35 | assert.equal(access, accessToken.token);
36 | });
37 |
38 | it("Error is thrown when accessToken cannot be retrieved from getToken function", async () => {
39 | let expectedError;
40 | try {
41 | const client = new ClientSecretCredential(tenantId, clientId, clientSecret);
42 | if (typeof client.getToken !== "function") {
43 | throw new Error("Method definition for getToken is not found");
44 | }
45 | const authProviderOptions: TokenCredentialAuthenticationProviderOptions = {
46 | getTokenOptions: null,
47 | scopes,
48 | };
49 | const accessToken: AccessToken = undefined;
50 |
51 | const moq = sinon.mock(client);
52 | moq.expects("getToken").resolves(accessToken);
53 | const tokenCredentialAuthenticationProvider = new TokenCredentialAuthenticationProvider(client, authProviderOptions);
54 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
55 | const access = await tokenCredentialAuthenticationProvider.getAccessToken();
56 | } catch (err) {
57 | expectedError = err;
58 | }
59 | assert.equal(expectedError.name, "Access token is undefined");
60 | });
61 | });
62 |
--------------------------------------------------------------------------------
/test/node/content/BatchRequestContent.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import "isomorphic-fetch";
9 |
10 | import { assert } from "chai";
11 | import * as fs from "fs";
12 |
13 | import { BatchRequestContent } from "../../../src/content/BatchRequestContent";
14 | import { GRAPH_BASE_URL } from "../../../src/Constants";
15 |
16 | describe("BatchRequestContent.ts", () => {
17 | describe("getContent", () => {
18 | it("Should return image's base64 string", async () => {
19 | const fileName = "sample_image.jpg";
20 | fs.readFile(`./test/sample_files/${fileName}`, {}, async (err, file) => {
21 | if (err) {
22 | throw err;
23 | }
24 | const uploadOneDriveFile = {
25 | id: "1",
26 | request: new Request(`${GRAPH_BASE_URL}me/drive/root:/Documents/${fileName}:/content`, {
27 | method: "PUT",
28 | headers: {
29 | "Content-type": "image/jpg",
30 | },
31 | body: file,
32 | }),
33 | };
34 | const batchReq = new BatchRequestContent([uploadOneDriveFile]);
35 | const content = await batchReq.getContent();
36 | assert.isDefined(content.requests[0].body);
37 | });
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/test/sample_files/empty-spreadsheet.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-javascript/db1757abe7a4cad310f0cd4d7d2a83b961390cce/test/sample_files/empty-spreadsheet.xlsx
--------------------------------------------------------------------------------
/test/sample_files/onenotepage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Page
5 |
6 |
7 |
8 | Created a OneNote page from HTML
9 |
10 |
11 |
--------------------------------------------------------------------------------
/test/sample_files/onenotepage_fileattachment.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | A page with rendered file attachment
5 |
6 |
7 |
8 | Here is an attached file:
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/sample_files/sample_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-javascript/db1757abe7a4cad310f0cd4d7d2a83b961390cce/test/sample_files/sample_image.jpg
--------------------------------------------------------------------------------
/test/test-helper.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * -------------------------------------------------------------------------------------------
3 | * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4 | * See License in the project root for license information.
5 | * -------------------------------------------------------------------------------------------
6 | */
7 |
8 | import { Client } from "../src/index";
9 | import { DummyAuthenticationProvider } from "./DummyAuthenticationProvider";
10 |
11 | export function getClient(): Client {
12 | return Client.initWithMiddleware({
13 | authProvider: new DummyAuthenticationProvider(),
14 | });
15 | }
16 |
17 | export function randomString() {
18 | return Math.random()
19 | .toString(36)
20 | .substring(7);
21 | }
22 |
23 | export const DUMMY_BASE_URL = "https://localhost";
24 |
--------------------------------------------------------------------------------
/test/tsconfig-test-development.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./../tsconfig-base.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "target": "es5",
6 | "esModuleInterop": true,
7 | "noEmitOnError": true,
8 | "lib": ["dom", "esnext"],
9 | "outDir": "../lib/"
10 | },
11 | "include": ["./development/", "../src/"]
12 | }
13 |
--------------------------------------------------------------------------------
/tsconfig-base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "importHelpers": true,
4 | "noEmitOnError": true,
5 | "noImplicitAny": false,
6 | "moduleResolution": "node",
7 | "removeComments": false,
8 | "sourceMap": true,
9 | "declaration": true,
10 | }
11 | }
--------------------------------------------------------------------------------
/tsconfig-cjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig-base.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "target": "es5",
6 | "lib": ["dom", "esnext"],
7 | "outDir": "lib",
8 | "composite": true
9 | },
10 | "exclude": ["node_modules", "lib", "samples", "test/development"],
11 | "include": ["./src/**/*.ts", "./test"]
12 | }
13 |
--------------------------------------------------------------------------------
/tsconfig-es.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig-base.json",
3 | "compilerOptions": {
4 | "module": "es6",
5 | "target": "es6",
6 | "lib": ["dom", "esnext"],
7 | "outDir": "lib/es",
8 | "composite": true
9 | },
10 | "exclude": ["node_modules", "lib", "samples", "test/development"],
11 | "include": ["./src/**/*.ts", "./test/**/*.ts"]
12 | }
13 |
--------------------------------------------------------------------------------
/tsconfig-sub-cjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig-base.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "target": "es5",
6 | "lib": ["dom", "esnext"],
7 | "outDir": "authProviders"
8 | },
9 | "exclude": ["node_modules", "lib", "samples", "test/", "src"],
10 | "include": ["authProviderOptions/azureTokenCredentials/", "authProviderOptions/authCodeMsalBrowser"],
11 | "references": [
12 | {
13 | "path": "./tsconfig-cjs.json"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/tsconfig-sub-es.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig-base.json",
3 | "compilerOptions": {
4 | "module": "es6",
5 | "target": "es6",
6 | "lib": ["dom", "esnext"],
7 | "outDir": "authProviders/es"
8 | },
9 | "exclude": ["node_modules", "lib", "samples", "test/**", "src"],
10 | "include": ["authProviderOptions/es/**/*.ts"],
11 | "references": [
12 | {
13 | "path": "./tsconfig-es.json"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/types-demo.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-javascript/db1757abe7a4cad310f0cd4d7d2a83b961390cce/types-demo.PNG
--------------------------------------------------------------------------------