diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8bc3a41 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: 'npm' + directory: '/' + schedule: + interval: 'daily' + commit-message: + prefix: 'deps: ' + target-branch: 'main' \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..601006c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,19 @@ +name: ci +on: + pull_request: + branches: + - main + workflow_call: + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/hydrogen + cache: "npm" + - run: npm install + - run: npm run test + - run: npm run build \ No newline at end of file diff --git a/.gitignore b/.gitignore index 953ef57..2330ea0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ node_modules temp etc lib -dist \ No newline at end of file +dist + +.DS_Store \ No newline at end of file diff --git a/api-extractor.json b/api-extractor.json deleted file mode 100644 index f4d2d7c..0000000 --- a/api-extractor.json +++ /dev/null @@ -1,434 +0,0 @@ -/** - * Config file for API Extractor. For more info, please visit: https://api-extractor.com - */ -{ - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - - /** - * Optionally specifies another JSON config file that this file extends from. This provides a way for - * standard settings to be shared across multiple projects. - * - * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains - * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be - * resolved using NodeJS require(). - * - * SUPPORTED TOKENS: none - * DEFAULT VALUE: "" - */ - // "extends": "./shared/api-extractor-base.json" - // "extends": "my-package/include/api-extractor-base.json" - - /** - * Determines the "" token that can be used with other config file settings. The project folder - * typically contains the tsconfig.json and package.json config files, but the path is user-defined. - * - * The path is resolved relative to the folder of the config file that contains the setting. - * - * The default value for "projectFolder" is the token "", which means the folder is determined by traversing - * parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder - * that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error - * will be reported. - * - * SUPPORTED TOKENS: - * DEFAULT VALUE: "" - */ - // "projectFolder": "..", - - /** - * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor - * analyzes the symbols exported by this module. - * - * The file extension must be ".d.ts" and not ".ts". - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - */ - "mainEntryPointFilePath": "/lib/index.d.ts", - - /** - * A list of NPM package names whose exports should be treated as part of this package. - * - * For example, suppose that Webpack is used to generate a distributed bundle for the project "library1", - * and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part - * of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly - * imports library2. To avoid this, we might specify: - * - * "bundledPackages": [ "library2" ], - * - * This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been - * local files for library1. - * - * The "bundledPackages" elements may specify glob patterns using minimatch syntax. To ensure deterministic - * output, globs are expanded by matching explicitly declared top-level dependencies only. For example, - * the pattern below will NOT match "@my-company/example" unless it appears in a field such as "dependencies" - * or "devDependencies" of the project's package.json file: - * - * "bundledPackages": [ "@my-company/*" ], - */ - "bundledPackages": [], - - /** - * Specifies what type of newlines API Extractor should use when writing output files. By default, the output files - * will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead. - * To use the OS's default newline kind, specify "os". - * - * DEFAULT VALUE: "crlf" - */ - // "newlineKind": "crlf", - - /** - * Set to true when invoking API Extractor's test harness. When `testMode` is true, the `toolVersion` field in the - * .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests. - * - * DEFAULT VALUE: "false" - */ - // "testMode": false, - - /** - * Specifies how API Extractor sorts members of an enum when generating the .api.json file. By default, the output - * files will be sorted alphabetically, which is "by-name". To keep the ordering in the source code, specify - * "preserve". - * - * DEFAULT VALUE: "by-name" - */ - // "enumMemberOrder": "by-name", - - /** - * Determines how the TypeScript compiler engine will be invoked by API Extractor. - */ - "compiler": { - /** - * Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project. - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * Note: This setting will be ignored if "overrideTsconfig" is used. - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "/tsconfig.json" - */ - // "tsconfigFilePath": "/tsconfig.json", - /** - * Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk. - * The object must conform to the TypeScript tsconfig schema: - * - * http://json.schemastore.org/tsconfig - * - * If omitted, then the tsconfig.json file will be read from the "projectFolder". - * - * DEFAULT VALUE: no overrideTsconfig section - */ - // "overrideTsconfig": { - // . . . - // } - /** - * This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended - * and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when - * dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses - * for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck. - * - * DEFAULT VALUE: false - */ - // "skipLibCheck": true, - }, - - /** - * Configures how the API report file (*.api.md) will be generated. - */ - "apiReport": { - /** - * (REQUIRED) Whether to generate an API report. - */ - "enabled": true - - /** - * The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce - * a full file path. - * - * The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/". - * - * SUPPORTED TOKENS: , - * DEFAULT VALUE: ".api.md" - */ - // "reportFileName": ".api.md", - - /** - * Specifies the folder where the API report file is written. The file name portion is determined by - * the "reportFileName" setting. - * - * The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy, - * e.g. for an API review. - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "/temp/" - */ - // "reportFolder": "/temp/", - - /** - * Specifies the folder where the temporary report file is written. The file name portion is determined by - * the "reportFileName" setting. - * - * After the temporary file is written to disk, it is compared with the file in the "reportFolder". - * If they are different, a production build will fail. - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "/temp/" - */ - // "reportTempFolder": "/temp/", - - /** - * Whether "forgotten exports" should be included in the API report file. Forgotten exports are declarations - * flagged with `ae-forgotten-export` warnings. See https://api-extractor.com/pages/messages/ae-forgotten-export/ to - * learn more. - * - * DEFAULT VALUE: "false" - */ - // "includeForgottenExports": false - }, - - /** - * Configures how the doc model file (*.api.json) will be generated. - */ - "docModel": { - /** - * (REQUIRED) Whether to generate a doc model file. - */ - "enabled": true - - /** - * The output path for the doc model file. The file extension should be ".api.json". - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "/temp/.api.json" - */ - // "apiJsonFilePath": "/temp/.api.json", - - /** - * Whether "forgotten exports" should be included in the doc model file. Forgotten exports are declarations - * flagged with `ae-forgotten-export` warnings. See https://api-extractor.com/pages/messages/ae-forgotten-export/ to - * learn more. - * - * DEFAULT VALUE: "false" - */ - // "includeForgottenExports": false, - - /** - * The base URL where the project's source code can be viewed on a website such as GitHub or - * Azure DevOps. This URL path corresponds to the `` path on disk. - * - * This URL is concatenated with the file paths serialized to the doc model to produce URL file paths to individual API items. - * For example, if the `projectFolderUrl` is "https://github.com/microsoft/rushstack/tree/main/apps/api-extractor" and an API - * item's file path is "api/ExtractorConfig.ts", the full URL file path would be - * "https://github.com/microsoft/rushstack/tree/main/apps/api-extractor/api/ExtractorConfig.js". - * - * Can be omitted if you don't need source code links in your API documentation reference. - * - * SUPPORTED TOKENS: none - * DEFAULT VALUE: "" - */ - // "projectFolderUrl": "http://github.com/path/to/your/projectFolder" - }, - - /** - * Configures how the .d.ts rollup file will be generated. - */ - "dtsRollup": { - /** - * (REQUIRED) Whether to generate the .d.ts rollup file. - */ - "enabled": true, - - /** - * Specifies the output path for a .d.ts rollup file to be generated without any trimming. - * This file will include all declarations that are exported by the main entry point. - * - * If the path is an empty string, then this file will not be written. - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "/dist/.d.ts" - */ - "untrimmedFilePath": "/dist/types/index.d.ts" - - /** - * Specifies the output path for a .d.ts rollup file to be generated with trimming for an "alpha" release. - * This file will include only declarations that are marked as "@public", "@beta", or "@alpha". - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "" - */ - // "alphaTrimmedFilePath": "/dist/-alpha.d.ts", - - /** - * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release. - * This file will include only declarations that are marked as "@public" or "@beta". - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "" - */ - // "betaTrimmedFilePath": "/dist/-beta.d.ts", - - /** - * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release. - * This file will include only declarations that are marked as "@public". - * - * If the path is an empty string, then this file will not be written. - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "" - */ - // "publicTrimmedFilePath": "/dist/-public.d.ts", - - /** - * When a declaration is trimmed, by default it will be replaced by a code comment such as - * "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the - * declaration completely. - * - * DEFAULT VALUE: false - */ - // "omitTrimmingComments": true - }, - - /** - * Configures how the tsdoc-metadata.json file will be generated. - */ - "tsdocMetadata": { - /** - * Whether to generate the tsdoc-metadata.json file. - * - * DEFAULT VALUE: true - */ - // "enabled": true, - /** - * Specifies where the TSDoc metadata file should be written. - * - * The path is resolved relative to the folder of the config file that contains the setting; to change this, - * prepend a folder token such as "". - * - * The default value is "", which causes the path to be automatically inferred from the "tsdocMetadata", - * "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup - * falls back to "tsdoc-metadata.json" in the package folder. - * - * SUPPORTED TOKENS: , , - * DEFAULT VALUE: "" - */ - // "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" - }, - - /** - * Configures how API Extractor reports error and warning messages produced during analysis. - * - * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages. - */ - "messages": { - /** - * Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing - * the input .d.ts files. - * - * TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551" - * - * DEFAULT VALUE: A single "default" entry with logLevel=warning. - */ - "compilerMessageReporting": { - /** - * Configures the default routing for messages that don't match an explicit rule in this table. - */ - "default": { - /** - * Specifies whether the message should be written to the the tool's output log. Note that - * the "addToApiReportFile" property may supersede this option. - * - * Possible values: "error", "warning", "none" - * - * Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail - * and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes - * the "--local" option), the warning is displayed but the build will not fail. - * - * DEFAULT VALUE: "warning" - */ - "logLevel": "warning" - - /** - * When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md), - * then the message will be written inside that file; otherwise, the message is instead logged according to - * the "logLevel" option. - * - * DEFAULT VALUE: false - */ - // "addToApiReportFile": false - } - - // "TS2551": { - // "logLevel": "warning", - // "addToApiReportFile": true - // }, - // - // . . . - }, - - /** - * Configures handling of messages reported by API Extractor during its analysis. - * - * API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag" - * - * DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings - */ - "extractorMessageReporting": { - "default": { - "logLevel": "warning" - // "addToApiReportFile": false - } - - // "ae-extra-release-tag": { - // "logLevel": "warning", - // "addToApiReportFile": true - // }, - // - // . . . - }, - - /** - * Configures handling of messages reported by the TSDoc parser when analyzing code comments. - * - * TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text" - * - * DEFAULT VALUE: A single "default" entry with logLevel=warning. - */ - "tsdocMessageReporting": { - "default": { - "logLevel": "warning" - // "addToApiReportFile": false - } - - // "tsdoc-link-tag-unescaped-text": { - // "logLevel": "warning", - // "addToApiReportFile": true - // }, - // - // . . . - } - } -} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..4630049 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,75 @@ +**@globus/react-auth-context** • **Docs** + +*** + +[![npm](https://img.shields.io/npm/v/@globus/react-auth-context?style=flat-square&logo=npm&color=000&label)](https://www.npmjs.com/package/@globus/react-auth-context) + +# `@globus/react-auth-context` + +A simple React context for managing Globus-related authentication state. + +## Usage + +```tsx +import React, { useEffect } from "react"; +import { Provider, useGlobusAuth } from '@globus/react-auth-context'; + +const ExampleComponent = () => { + const { isAuthenticated, authorization } = useGlobusAuth(); + useEffect(() => { + async function attempt() { + if (!isAuthenticated) { + await instance?.handleCodeRedirect({ + shouldReplace: false, + }); + } + } + attempt(); + }, [authorization, authorization?.handleCodeRedirect, isAuthenticated]); + + return ( +
+ {isAuthenticated ? ( + + ) : ( + + )} +
+ ); +}; + +/** + * Your registered Globus Client ID. + */ +const client = '645b6bfb-4195-4010-83f5-a71332bd4761'; +/** + * Scopes required for your application on login. + */ +const scopes = 'urn:globus:auth:scope:transfer.api.globus.org:all'; +/** + * Redirect URL that will complete the OAuth2 flow. + */ +const redirect = '/'; + +const App = () => ( + + + +); +``` + +## Type Aliases + +- [GlobusAuthContextProps](type-aliases/GlobusAuthContextProps.md) +- [GlobusAuthState](type-aliases/GlobusAuthState.md) +- [Props](type-aliases/Props.md) + +## Variables + +- [initialState](variables/initialState.md) + +## Functions + +- [Provider](functions/Provider.md) +- [reducer](functions/reducer.md) +- [useGlobusAuth](functions/useGlobusAuth.md) diff --git a/docs/functions/Provider.md b/docs/functions/Provider.md new file mode 100644 index 0000000..a1ce308 --- /dev/null +++ b/docs/functions/Provider.md @@ -0,0 +1,21 @@ +[**@globus/react-auth-context**](../README.md) • **Docs** + +*** + +[@globus/react-auth-context](../README.md) / Provider + +# Function: Provider() + +> **Provider**(`__namedParameters`): `Element` + +## Parameters + +• **\_\_namedParameters**: [`Props`](../type-aliases/Props.md) + +## Returns + +`Element` + +## Defined in + +[Provider.tsx:24](https://github.com/globus/react-auth-context/blob/8f79b283008ddbbf08560a9d933d93f2184363e6/src/Provider.tsx#L24) diff --git a/docs/functions/reducer.md b/docs/functions/reducer.md new file mode 100644 index 0000000..e9b6bf2 --- /dev/null +++ b/docs/functions/reducer.md @@ -0,0 +1,23 @@ +[**@globus/react-auth-context**](../README.md) • **Docs** + +*** + +[@globus/react-auth-context](../README.md) / reducer + +# Function: reducer() + +> **reducer**(`state`, `action`): [`GlobusAuthState`](../type-aliases/GlobusAuthState.md) + +## Parameters + +• **state**: [`GlobusAuthState`](../type-aliases/GlobusAuthState.md) + +• **action**: `Action` + +## Returns + +[`GlobusAuthState`](../type-aliases/GlobusAuthState.md) + +## Defined in + +[reducer.ts:5](https://github.com/globus/react-auth-context/blob/8f79b283008ddbbf08560a9d933d93f2184363e6/src/reducer.ts#L5) diff --git a/docs/functions/useGlobusAuth.md b/docs/functions/useGlobusAuth.md new file mode 100644 index 0000000..d4d3913 --- /dev/null +++ b/docs/functions/useGlobusAuth.md @@ -0,0 +1,17 @@ +[**@globus/react-auth-context**](../README.md) • **Docs** + +*** + +[@globus/react-auth-context](../README.md) / useGlobusAuth + +# Function: useGlobusAuth() + +> **useGlobusAuth**(): [`GlobusAuthState`](../type-aliases/GlobusAuthState.md) + +## Returns + +[`GlobusAuthState`](../type-aliases/GlobusAuthState.md) + +## Defined in + +[useGlobusAuth.ts:4](https://github.com/globus/react-auth-context/blob/8f79b283008ddbbf08560a9d933d93f2184363e6/src/useGlobusAuth.ts#L4) diff --git a/docs/type-aliases/GlobusAuthContextProps.md b/docs/type-aliases/GlobusAuthContextProps.md new file mode 100644 index 0000000..c010075 --- /dev/null +++ b/docs/type-aliases/GlobusAuthContextProps.md @@ -0,0 +1,13 @@ +[**@globus/react-auth-context**](../README.md) • **Docs** + +*** + +[@globus/react-auth-context](../README.md) / GlobusAuthContextProps + +# Type Alias: GlobusAuthContextProps + +> **GlobusAuthContextProps**: [`GlobusAuthState`](GlobusAuthState.md) + +## Defined in + +[Context.ts:7](https://github.com/globus/react-auth-context/blob/8f79b283008ddbbf08560a9d933d93f2184363e6/src/Context.ts#L7) diff --git a/docs/type-aliases/GlobusAuthState.md b/docs/type-aliases/GlobusAuthState.md new file mode 100644 index 0000000..bea7b5f --- /dev/null +++ b/docs/type-aliases/GlobusAuthState.md @@ -0,0 +1,31 @@ +[**@globus/react-auth-context**](../README.md) • **Docs** + +*** + +[@globus/react-auth-context](../README.md) / GlobusAuthState + +# Type Alias: GlobusAuthState + +> **GlobusAuthState**: `object` + +## Type declaration + +### authorization + +> **authorization**: `AuthorizationManager` \| `undefined` + +### error + +> **error**: `Error` \| `undefined` + +### events + +> **events**: `AuthorizationManager`\[`"events"`\] \| `undefined` + +### isAuthenticated + +> **isAuthenticated**: `boolean` + +## Defined in + +[State.ts:3](https://github.com/globus/react-auth-context/blob/8f79b283008ddbbf08560a9d933d93f2184363e6/src/State.ts#L3) diff --git a/docs/type-aliases/Props.md b/docs/type-aliases/Props.md new file mode 100644 index 0000000..6047474 --- /dev/null +++ b/docs/type-aliases/Props.md @@ -0,0 +1,13 @@ +[**@globus/react-auth-context**](../README.md) • **Docs** + +*** + +[@globus/react-auth-context](../README.md) / Props + +# Type Alias: Props + +> **Props**: `React.PropsWithChildren`\<`AuthorizationManagerConfiguration` & `object`\> + +## Defined in + +[Provider.tsx:14](https://github.com/globus/react-auth-context/blob/8f79b283008ddbbf08560a9d933d93f2184363e6/src/Provider.tsx#L14) diff --git a/docs/variables/initialState.md b/docs/variables/initialState.md new file mode 100644 index 0000000..db0ae8f --- /dev/null +++ b/docs/variables/initialState.md @@ -0,0 +1,13 @@ +[**@globus/react-auth-context**](../README.md) • **Docs** + +*** + +[@globus/react-auth-context](../README.md) / initialState + +# Variable: initialState + +> `const` **initialState**: [`GlobusAuthState`](../type-aliases/GlobusAuthState.md) + +## Defined in + +[State.ts:10](https://github.com/globus/react-auth-context/blob/8f79b283008ddbbf08560a9d933d93f2184363e6/src/State.ts#L10) diff --git a/package-lock.json b/package-lock.json index e17d806..714f1e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@globus/react-auth-context", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@globus/react-auth-context", - "version": "0.0.1", + "version": "0.0.2", "license": "Apache-2.0", "devDependencies": { - "@globus/sdk": "^3.4.1", + "@globus/sdk": "^4.0.0-rc.1", "@testing-library/dom": "^10.1.0", "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.0", @@ -17,7 +17,6 @@ "@types/jest": "^29.5.12", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "api-extractor": "^99.99.99", "esbuild": "0.21.5", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", @@ -26,10 +25,12 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "ts-jest": "^29.1.5", + "typedoc": "^0.26.6", + "typedoc-plugin-markdown": "^4.2.6", "typescript": "^5.4.5" }, "peerDependencies": { - "@globus/sdk": "^3.4.1", + "@globus/sdk": "^4.0.0-rc.1", "react": ">=18", "react-dom": ">=18" } @@ -990,9 +991,9 @@ } }, "node_modules/@globus/sdk": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@globus/sdk/-/sdk-3.4.1.tgz", - "integrity": "sha512-ec9FXfug0CGKSX9jZmk0N7nx3wFFzXdYF2xWRUljnaqgrzecZfTE2pkaCXq3ebz/NPaUAg/BLCusQYLeJOSYVw==", + "version": "4.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@globus/sdk/-/sdk-4.0.0-rc.1.tgz", + "integrity": "sha512-WLUkzYPDmexJggkxZGjaVaYCfH5fZ94E9lLpwCV0cXDKcLHJS4FnuLBuFwhBeYOVsjGFR8RzitiBFB+9mrwcLg==", "dev": true, "dependencies": { "cross-fetch": "^4.0.0", @@ -1283,16 +1284,6 @@ "node": ">=8" } }, - "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@jest/reporters/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1485,6 +1476,22 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@shikijs/core": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.16.1.tgz", + "integrity": "sha512-aI0hBtw+a6KsJp2jcD4YuQqKpeCbURMZbhHVozDknJpm+KJqeMRkEnfBC8BaKE/5XC+uofPgCLsa/TkTk0Ba0w==", + "dev": true, + "dependencies": { + "@shikijs/vscode-textmate": "^9.2.0", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.2.0.tgz", + "integrity": "sha512-5FinaOp6Vdh/dl4/yaOTh0ZeKch+rYS8DUb38V3GMKYVkdqzxw53lViRKUYkVILRiVQT7dcPC7VvAKOR73zVtQ==", + "dev": true + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1690,6 +1697,15 @@ "@types/node": "*" } }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -1813,6 +1829,12 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, "node_modules/@types/yargs": { "version": "17.0.32", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", @@ -1924,12 +1946,6 @@ "node": ">= 8" } }, - "node_modules/api-extractor": { - "version": "99.99.99", - "resolved": "https://registry.npmjs.org/api-extractor/-/api-extractor-99.99.99.tgz", - "integrity": "sha512-TQsQin3HleX8L15qyPw4J1CIHpo4cRAkDCNnXg5MIs87iN1dPXhNhmui+YTx8svMMDc/2hOSeJSy6rYLHnLEgw==", - "dev": true - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2067,6 +2083,16 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -2712,16 +2738,6 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -3213,15 +3229,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-reports": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", @@ -3428,16 +3435,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-config/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/jest-config/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3971,16 +3968,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/jest-runtime/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -4386,6 +4373,15 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -4422,6 +4418,12 @@ "loose-envify": "cli.js" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/lz-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", @@ -4473,6 +4475,35 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4879,6 +4910,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -5070,6 +5110,17 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.16.1.tgz", + "integrity": "sha512-tCJIMaxDVB1mEIJ5TvfZU7kCPB5eo9fli5+21Olc/bmyv+w8kye3JOp+LZRmGkAyT71hrkefQhTiY+o9mBikRQ==", + "dev": true, + "dependencies": { + "@shikijs/core": "1.16.1", + "@shikijs/vscode-textmate": "^9.2.0", + "@types/hast": "^3.0.4" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -5091,6 +5142,15 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -5101,15 +5161,6 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -5257,16 +5308,6 @@ "node": ">=8" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/test-exclude/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5422,6 +5463,64 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typedoc": { + "version": "0.26.6", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.6.tgz", + "integrity": "sha512-SfEU3SH3wHNaxhFPjaZE2kNl/NFtLNW5c1oHsg7mti7GjmUj1Roq6osBQeMd+F4kL0BoRBBr8gQAuqBlfFu8LA==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "shiki": "^1.9.1", + "yaml": "^2.4.5" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x" + } + }, + "node_modules/typedoc-plugin-markdown": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.2.6.tgz", + "integrity": "sha512-k33o2lZSGpL3GjH28eW+RsujzCYFP0L5GNqpK+wa4CBcMOxpj8WV7SydNRLS6eSa2UvaPvNVJTaAZ6Tm+8GXoA==", + "dev": true, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "typedoc": "0.26.x" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", @@ -5435,6 +5534,12 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -5631,6 +5736,18 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 286d464..b03a969 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@globus/react-auth-context", - "version": "0.0.1", + "version": "0.0.2", "description": "A React context for integrating Globus Auth into your application using the Globus JavaScript SDK", "main": "dist/umd/index.js", "types": "dist/types/index.d.ts", @@ -17,18 +17,19 @@ ], "scripts": { "build": "node scripts/build.js && npm run build:types", - "build:types": "tsc --emitDeclarationOnly && api-extractor run", - "test": "jest" + "build:types": "tsc --emitDeclarationOnly", + "test": "jest", + "docs": "npx typedoc" }, "author": "Joe Bottigliero", "license": "Apache-2.0", "peerDependencies": { - "@globus/sdk": "^3.4.1", + "@globus/sdk": "^4.0.0-rc.1", "react": ">=18", "react-dom": ">=18" }, "devDependencies": { - "@globus/sdk": "^3.4.1", + "@globus/sdk": "^4.0.0-rc.1", "@testing-library/dom": "^10.1.0", "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.0", @@ -36,7 +37,6 @@ "@types/jest": "^29.5.12", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "api-extractor": "^99.99.99", "esbuild": "0.21.5", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", @@ -45,6 +45,8 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "ts-jest": "^29.1.5", + "typedoc": "^0.26.6", + "typedoc-plugin-markdown": "^4.2.6", "typescript": "^5.4.5" } } diff --git a/src/Context.ts b/src/Context.ts index fb99f2c..ddac0b8 100644 --- a/src/Context.ts +++ b/src/Context.ts @@ -1,6 +1,12 @@ import { createContext } from "react"; import type { GlobusAuthState } from "./State"; +/** + * @public + */ export type GlobusAuthContextProps = GlobusAuthState; +/** + * @public + */ export default createContext(undefined); diff --git a/src/Provider.tsx b/src/Provider.tsx index 24f15c0..4bb45d1 100644 --- a/src/Provider.tsx +++ b/src/Provider.tsx @@ -9,8 +9,7 @@ import { initialState } from "./State"; import { reducer } from "./reducer"; import { authorization } from "@globus/sdk"; -import type { AuthorizationManagerConfiguration } from "@globus/sdk/esm/lib/core/authorization/AuthorizationManager"; - +import type { AuthorizationManagerConfiguration } from "@globus/sdk/core/authorization/AuthorizationManager"; export type Props = React.PropsWithChildren +/** + * @public + */ export const Provider = ({ environment, children, @@ -30,43 +32,47 @@ export const Provider = ({ } const [state, dispatch] = useReducer(reducer, initialState); const [instance, setInstance] = useState< - ReturnType | undefined - >(undefined); + ReturnType + >(); + const handleAuthenticated = ({ + isAuthenticated, + }: { + isAuthenticated: boolean; + }) => { + dispatch({ type: "AUTHENTICATED", payload: isAuthenticated }); + }; + + const handleRevoke = () => { + dispatch({ type: "REVOKE" }); + }; + + + const { + redirect, + scopes, + client + } = authorizationManagerConfigruation; + useEffect(() => { const i = authorization.create({ + redirect, + scopes, + client, useRefreshTokens: true, - ...authorizationManagerConfigruation + events: { + authenticated: handleAuthenticated, + revoke: handleRevoke, + }, }); - setInstance(i); - }, []); - /** - * Register event listeners for the authorization instance. - */ - useEffect(() => { - if (!instance) return; - - const handleRevoke = () => { - dispatch({ type: "REVOKE" }); - }; - - instance.events.revoke.addListener(handleRevoke); - - const handleAuthenticated = ({ - isAuthenticated, - }: { - isAuthenticated: boolean; - }) => { - dispatch({ type: "AUTHENTICATED", payload: isAuthenticated }); - }; - instance.events.authenticated.addListener(handleAuthenticated); + setInstance(i); return () => { - instance.events.revoke.removeListener(handleRevoke); - instance.events.authenticated.removeListener(handleAuthenticated); + i.events.revoke.removeListener(handleRevoke); + i.events.authenticated.removeListener(handleAuthenticated); }; - }, [instance]); + }, [redirect, scopes, client]); return (