@digital-science-dsl/dimensions-analytics-mcp 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/README.md +152 -0
- package/bin/dimensions-analytics-mcp-http.js +2 -0
- package/bin/dimensions-analytics-mcp.js +2 -0
- package/dist/client/auth/config-loaders.d.ts +22 -0
- package/dist/client/auth/config-loaders.d.ts.map +1 -0
- package/dist/client/auth/config-loaders.js +68 -0
- package/dist/client/auth/config-loaders.js.map +1 -0
- package/dist/client/auth/decorators/index.d.ts +7 -0
- package/dist/client/auth/decorators/index.d.ts.map +1 -0
- package/dist/client/auth/decorators/index.js +6 -0
- package/dist/client/auth/decorators/index.js.map +1 -0
- package/dist/client/auth/decorators/with-caching.d.ts +81 -0
- package/dist/client/auth/decorators/with-caching.d.ts.map +1 -0
- package/dist/client/auth/decorators/with-caching.js +168 -0
- package/dist/client/auth/decorators/with-caching.js.map +1 -0
- package/dist/client/auth/factory.d.ts +13 -0
- package/dist/client/auth/factory.d.ts.map +1 -0
- package/dist/client/auth/factory.js +29 -0
- package/dist/client/auth/factory.js.map +1 -0
- package/dist/client/auth/index.d.ts +7 -0
- package/dist/client/auth/index.d.ts.map +1 -0
- package/dist/client/auth/index.js +6 -0
- package/dist/client/auth/index.js.map +1 -0
- package/dist/client/auth/jwt-utils.d.ts +17 -0
- package/dist/client/auth/jwt-utils.d.ts.map +1 -0
- package/dist/client/auth/jwt-utils.js +33 -0
- package/dist/client/auth/jwt-utils.js.map +1 -0
- package/dist/client/auth/node.d.ts +16 -0
- package/dist/client/auth/node.d.ts.map +1 -0
- package/dist/client/auth/node.js +15 -0
- package/dist/client/auth/node.js.map +1 -0
- package/dist/client/auth/providers/index.d.ts +2 -0
- package/dist/client/auth/providers/index.d.ts.map +1 -0
- package/dist/client/auth/providers/index.js +2 -0
- package/dist/client/auth/providers/index.js.map +1 -0
- package/dist/client/auth/providers/jwt-auth-provider.d.ts +70 -0
- package/dist/client/auth/providers/jwt-auth-provider.d.ts.map +1 -0
- package/dist/client/auth/providers/jwt-auth-provider.js +134 -0
- package/dist/client/auth/providers/jwt-auth-provider.js.map +1 -0
- package/dist/client/auth/schemas.d.ts +19 -0
- package/dist/client/auth/schemas.d.ts.map +1 -0
- package/dist/client/auth/schemas.js +23 -0
- package/dist/client/auth/schemas.js.map +1 -0
- package/dist/client/auth/types.d.ts +25 -0
- package/dist/client/auth/types.d.ts.map +1 -0
- package/dist/client/auth/types.js +9 -0
- package/dist/client/auth/types.js.map +1 -0
- package/dist/client/command.d.ts +44 -0
- package/dist/client/command.d.ts.map +1 -0
- package/dist/client/command.js +23 -0
- package/dist/client/command.js.map +1 -0
- package/dist/client/config/index.d.ts +11 -0
- package/dist/client/config/index.d.ts.map +1 -0
- package/dist/client/config/index.js +8 -0
- package/dist/client/config/index.js.map +1 -0
- package/dist/client/config/loader.d.ts +27 -0
- package/dist/client/config/loader.d.ts.map +1 -0
- package/dist/client/config/loader.js +128 -0
- package/dist/client/config/loader.js.map +1 -0
- package/dist/client/config/node.d.ts +18 -0
- package/dist/client/config/node.d.ts.map +1 -0
- package/dist/client/config/node.js +17 -0
- package/dist/client/config/node.js.map +1 -0
- package/dist/client/config/schemas.d.ts +23 -0
- package/dist/client/config/schemas.d.ts.map +1 -0
- package/dist/client/config/schemas.js +24 -0
- package/dist/client/config/schemas.js.map +1 -0
- package/dist/client/config/types.d.ts +37 -0
- package/dist/client/config/types.d.ts.map +1 -0
- package/dist/client/config/types.js +6 -0
- package/dist/client/config/types.js.map +1 -0
- package/dist/client/config/unified-loader.d.ts +41 -0
- package/dist/client/config/unified-loader.d.ts.map +1 -0
- package/dist/client/config/unified-loader.js +86 -0
- package/dist/client/config/unified-loader.js.map +1 -0
- package/dist/client/config.d.ts +43 -0
- package/dist/client/config.d.ts.map +1 -0
- package/dist/client/config.js +56 -0
- package/dist/client/config.js.map +1 -0
- package/dist/client/deployment-config.d.ts +36 -0
- package/dist/client/deployment-config.d.ts.map +1 -0
- package/dist/client/deployment-config.js +79 -0
- package/dist/client/deployment-config.js.map +1 -0
- package/dist/client/errors.d.ts +180 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +253 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/http-client.d.ts +215 -0
- package/dist/client/http-client.d.ts.map +1 -0
- package/dist/client/http-client.js +419 -0
- package/dist/client/http-client.js.map +1 -0
- package/dist/client/index.d.ts +28 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +18 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/internal-dsl-client.d.ts +30 -0
- package/dist/client/internal-dsl-client.d.ts.map +1 -0
- package/dist/client/internal-dsl-client.js +101 -0
- package/dist/client/internal-dsl-client.js.map +1 -0
- package/dist/client/rate-limiter.d.ts +79 -0
- package/dist/client/rate-limiter.d.ts.map +1 -0
- package/dist/client/rate-limiter.js +118 -0
- package/dist/client/rate-limiter.js.map +1 -0
- package/dist/client/resolve-api-key-user.d.ts +24 -0
- package/dist/client/resolve-api-key-user.d.ts.map +1 -0
- package/dist/client/resolve-api-key-user.js +80 -0
- package/dist/client/resolve-api-key-user.js.map +1 -0
- package/dist/client/types.d.ts +44 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +10 -0
- package/dist/client/types.js.map +1 -0
- package/dist/dsl/client.d.ts +330 -0
- package/dist/dsl/client.d.ts.map +1 -0
- package/dist/dsl/client.js +433 -0
- package/dist/dsl/client.js.map +1 -0
- package/dist/dsl/commands/apply-filters.d.ts +15 -0
- package/dist/dsl/commands/apply-filters.d.ts.map +1 -0
- package/dist/dsl/commands/apply-filters.js +29 -0
- package/dist/dsl/commands/apply-filters.js.map +1 -0
- package/dist/dsl/commands/facet/index.d.ts +6 -0
- package/dist/dsl/commands/facet/index.d.ts.map +1 -0
- package/dist/dsl/commands/facet/index.js +6 -0
- package/dist/dsl/commands/facet/index.js.map +1 -0
- package/dist/dsl/commands/facet/schemas.d.ts +71 -0
- package/dist/dsl/commands/facet/schemas.d.ts.map +1 -0
- package/dist/dsl/commands/facet/schemas.js +84 -0
- package/dist/dsl/commands/facet/schemas.js.map +1 -0
- package/dist/dsl/commands/functions/ClassifyCommand.d.ts +96 -0
- package/dist/dsl/commands/functions/ClassifyCommand.d.ts.map +1 -0
- package/dist/dsl/commands/functions/ClassifyCommand.js +95 -0
- package/dist/dsl/commands/functions/ClassifyCommand.js.map +1 -0
- package/dist/dsl/commands/functions/ExtractAffiliationsCommand.d.ts +86 -0
- package/dist/dsl/commands/functions/ExtractAffiliationsCommand.d.ts.map +1 -0
- package/dist/dsl/commands/functions/ExtractAffiliationsCommand.js +131 -0
- package/dist/dsl/commands/functions/ExtractAffiliationsCommand.js.map +1 -0
- package/dist/dsl/commands/functions/ExtractConceptsCommand.d.ts +73 -0
- package/dist/dsl/commands/functions/ExtractConceptsCommand.d.ts.map +1 -0
- package/dist/dsl/commands/functions/ExtractConceptsCommand.js +110 -0
- package/dist/dsl/commands/functions/ExtractConceptsCommand.js.map +1 -0
- package/dist/dsl/commands/functions/ExtractGrantsCommand.d.ts +66 -0
- package/dist/dsl/commands/functions/ExtractGrantsCommand.d.ts.map +1 -0
- package/dist/dsl/commands/functions/ExtractGrantsCommand.js +87 -0
- package/dist/dsl/commands/functions/ExtractGrantsCommand.js.map +1 -0
- package/dist/dsl/commands/functions/index.d.ts +10 -0
- package/dist/dsl/commands/functions/index.d.ts.map +1 -0
- package/dist/dsl/commands/functions/index.js +10 -0
- package/dist/dsl/commands/functions/index.js.map +1 -0
- package/dist/dsl/commands/index.d.ts +8 -0
- package/dist/dsl/commands/index.d.ts.map +1 -0
- package/dist/dsl/commands/index.js +7 -0
- package/dist/dsl/commands/index.js.map +1 -0
- package/dist/dsl/commands/validate-input.d.ts +18 -0
- package/dist/dsl/commands/validate-input.d.ts.map +1 -0
- package/dist/dsl/commands/validate-input.js +27 -0
- package/dist/dsl/commands/validate-input.js.map +1 -0
- package/dist/dsl/create-client.d.ts +32 -0
- package/dist/dsl/create-client.d.ts.map +1 -0
- package/dist/dsl/create-client.js +58 -0
- package/dist/dsl/create-client.js.map +1 -0
- package/dist/dsl/fluent-query-builder.d.ts +439 -0
- package/dist/dsl/fluent-query-builder.d.ts.map +1 -0
- package/dist/dsl/fluent-query-builder.js +534 -0
- package/dist/dsl/fluent-query-builder.js.map +1 -0
- package/dist/dsl/index.d.ts +32 -0
- package/dist/dsl/index.d.ts.map +1 -0
- package/dist/dsl/index.js +31 -0
- package/dist/dsl/index.js.map +1 -0
- package/dist/dsl/pagination.d.ts +82 -0
- package/dist/dsl/pagination.d.ts.map +1 -0
- package/dist/dsl/pagination.js +135 -0
- package/dist/dsl/pagination.js.map +1 -0
- package/dist/dsl/query-builder.d.ts +456 -0
- package/dist/dsl/query-builder.d.ts.map +1 -0
- package/dist/dsl/query-builder.js +994 -0
- package/dist/dsl/query-builder.js.map +1 -0
- package/dist/dsl/response-parser.d.ts +111 -0
- package/dist/dsl/response-parser.d.ts.map +1 -0
- package/dist/dsl/response-parser.js +210 -0
- package/dist/dsl/response-parser.js.map +1 -0
- package/dist/dsl/schema/cache.d.ts +52 -0
- package/dist/dsl/schema/cache.d.ts.map +1 -0
- package/dist/dsl/schema/cache.js +97 -0
- package/dist/dsl/schema/cache.js.map +1 -0
- package/dist/dsl/schema/extract.d.ts +18 -0
- package/dist/dsl/schema/extract.d.ts.map +1 -0
- package/dist/dsl/schema/extract.js +41 -0
- package/dist/dsl/schema/extract.js.map +1 -0
- package/dist/dsl/schema/index.d.ts +13 -0
- package/dist/dsl/schema/index.d.ts.map +1 -0
- package/dist/dsl/schema/index.js +12 -0
- package/dist/dsl/schema/index.js.map +1 -0
- package/dist/dsl/schema/load.d.ts +41 -0
- package/dist/dsl/schema/load.d.ts.map +1 -0
- package/dist/dsl/schema/load.js +119 -0
- package/dist/dsl/schema/load.js.map +1 -0
- package/dist/dsl/schema/store.d.ts +137 -0
- package/dist/dsl/schema/store.d.ts.map +1 -0
- package/dist/dsl/schema/store.js +204 -0
- package/dist/dsl/schema/store.js.map +1 -0
- package/dist/dsl/schema/structured-entities.d.ts +21 -0
- package/dist/dsl/schema/structured-entities.d.ts.map +1 -0
- package/dist/dsl/schema/structured-entities.js +39 -0
- package/dist/dsl/schema/structured-entities.js.map +1 -0
- package/dist/dsl/schema/summary.d.ts +51 -0
- package/dist/dsl/schema/summary.d.ts.map +1 -0
- package/dist/dsl/schema/summary.js +61 -0
- package/dist/dsl/schema/summary.js.map +1 -0
- package/dist/dsl/schema/types.d.ts +36 -0
- package/dist/dsl/schema/types.d.ts.map +1 -0
- package/dist/dsl/schema/types.js +6 -0
- package/dist/dsl/schema/types.js.map +1 -0
- package/dist/dsl/schema/validation.d.ts +21 -0
- package/dist/dsl/schema/validation.d.ts.map +1 -0
- package/dist/dsl/schema/validation.js +44 -0
- package/dist/dsl/schema/validation.js.map +1 -0
- package/dist/dsl/types/buckets.d.ts +18 -0
- package/dist/dsl/types/buckets.d.ts.map +1 -0
- package/dist/dsl/types/buckets.js +6 -0
- package/dist/dsl/types/buckets.js.map +1 -0
- package/dist/dsl/types/common.d.ts +91 -0
- package/dist/dsl/types/common.d.ts.map +1 -0
- package/dist/dsl/types/common.js +6 -0
- package/dist/dsl/types/common.js.map +1 -0
- package/dist/dsl/types/entities.d.ts +35 -0
- package/dist/dsl/types/entities.d.ts.map +1 -0
- package/dist/dsl/types/entities.js +11 -0
- package/dist/dsl/types/entities.js.map +1 -0
- package/dist/dsl/types/index.d.ts +12 -0
- package/dist/dsl/types/index.d.ts.map +1 -0
- package/dist/dsl/types/index.js +7 -0
- package/dist/dsl/types/index.js.map +1 -0
- package/dist/dsl/types/return-clauses.d.ts +107 -0
- package/dist/dsl/types/return-clauses.d.ts.map +1 -0
- package/dist/dsl/types/return-clauses.js +22 -0
- package/dist/dsl/types/return-clauses.js.map +1 -0
- package/dist/dsl/types/special-functions.d.ts +175 -0
- package/dist/dsl/types/special-functions.d.ts.map +1 -0
- package/dist/dsl/types/special-functions.js +25 -0
- package/dist/dsl/types/special-functions.js.map +1 -0
- package/dist/dsl/types/vocabulary.d.ts +21 -0
- package/dist/dsl/types/vocabulary.d.ts.map +1 -0
- package/dist/dsl/types/vocabulary.js +44 -0
- package/dist/dsl/types/vocabulary.js.map +1 -0
- package/dist/dsl/usage-policy.d.ts +87 -0
- package/dist/dsl/usage-policy.d.ts.map +1 -0
- package/dist/dsl/usage-policy.js +133 -0
- package/dist/dsl/usage-policy.js.map +1 -0
- package/dist/dsl/utils/escape.d.ts +24 -0
- package/dist/dsl/utils/escape.d.ts.map +1 -0
- package/dist/dsl/utils/escape.js +124 -0
- package/dist/dsl/utils/escape.js.map +1 -0
- package/dist/dsl/utils/sanitize.d.ts +13 -0
- package/dist/dsl/utils/sanitize.d.ts.map +1 -0
- package/dist/dsl/utils/sanitize.js +19 -0
- package/dist/dsl/utils/sanitize.js.map +1 -0
- package/dist/dsl/utils/string-utils.d.ts +35 -0
- package/dist/dsl/utils/string-utils.d.ts.map +1 -0
- package/dist/dsl/utils/string-utils.js +145 -0
- package/dist/dsl/utils/string-utils.js.map +1 -0
- package/dist/dsl/utils/validate-field-name.d.ts +11 -0
- package/dist/dsl/utils/validate-field-name.d.ts.map +1 -0
- package/dist/dsl/utils/validate-field-name.js +18 -0
- package/dist/dsl/utils/validate-field-name.js.map +1 -0
- package/dist/examples/dsl-examples.d.ts +11 -0
- package/dist/examples/dsl-examples.d.ts.map +1 -0
- package/dist/examples/dsl-examples.js +49 -0
- package/dist/examples/dsl-examples.js.map +1 -0
- package/dist/examples/usage-scenarios.d.ts +22 -0
- package/dist/examples/usage-scenarios.d.ts.map +1 -0
- package/dist/examples/usage-scenarios.js +173 -0
- package/dist/examples/usage-scenarios.js.map +1 -0
- package/dist/funder-org-names.d.ts +12 -0
- package/dist/funder-org-names.d.ts.map +1 -0
- package/dist/funder-org-names.js +30 -0
- package/dist/funder-org-names.js.map +1 -0
- package/dist/http-main.d.ts +7 -0
- package/dist/http-main.d.ts.map +1 -0
- package/dist/http-main.js +36 -0
- package/dist/http-main.js.map +1 -0
- package/dist/http.d.ts +29 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +173 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/kwq/build-query.d.ts +26 -0
- package/dist/kwq/build-query.d.ts.map +1 -0
- package/dist/kwq/build-query.js +37 -0
- package/dist/kwq/build-query.js.map +1 -0
- package/dist/kwq/concept-groups.d.ts +49 -0
- package/dist/kwq/concept-groups.d.ts.map +1 -0
- package/dist/kwq/concept-groups.js +55 -0
- package/dist/kwq/concept-groups.js.map +1 -0
- package/dist/kwq/dsl-assembler.d.ts +28 -0
- package/dist/kwq/dsl-assembler.d.ts.map +1 -0
- package/dist/kwq/dsl-assembler.js +124 -0
- package/dist/kwq/dsl-assembler.js.map +1 -0
- package/dist/kwq/ensemble.d.ts +38 -0
- package/dist/kwq/ensemble.d.ts.map +1 -0
- package/dist/kwq/ensemble.js +107 -0
- package/dist/kwq/ensemble.js.map +1 -0
- package/dist/kwq/index.d.ts +16 -0
- package/dist/kwq/index.d.ts.map +1 -0
- package/dist/kwq/index.js +14 -0
- package/dist/kwq/index.js.map +1 -0
- package/dist/kwq/types.d.ts +120 -0
- package/dist/kwq/types.d.ts.map +1 -0
- package/dist/kwq/types.js +11 -0
- package/dist/kwq/types.js.map +1 -0
- package/dist/lambda.d.ts +10 -0
- package/dist/lambda.d.ts.map +1 -0
- package/dist/lambda.js +4 -0
- package/dist/lambda.js.map +1 -0
- package/dist/main.d.ts +8 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +33 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/batch-fetch.d.ts +89 -0
- package/dist/mcp/batch-fetch.d.ts.map +1 -0
- package/dist/mcp/batch-fetch.js +178 -0
- package/dist/mcp/batch-fetch.js.map +1 -0
- package/dist/mcp/examples/dsl-examples.d.ts +21 -0
- package/dist/mcp/examples/dsl-examples.d.ts.map +1 -0
- package/dist/mcp/examples/dsl-examples.js +61 -0
- package/dist/mcp/examples/dsl-examples.js.map +1 -0
- package/dist/mcp/examples/usage-scenarios.d.ts +20 -0
- package/dist/mcp/examples/usage-scenarios.d.ts.map +1 -0
- package/dist/mcp/examples/usage-scenarios.js +169 -0
- package/dist/mcp/examples/usage-scenarios.js.map +1 -0
- package/dist/mcp/export-format.d.ts +43 -0
- package/dist/mcp/export-format.d.ts.map +1 -0
- package/dist/mcp/export-format.js +92 -0
- package/dist/mcp/export-format.js.map +1 -0
- package/dist/mcp/funder-org-names.d.ts +12 -0
- package/dist/mcp/funder-org-names.d.ts.map +1 -0
- package/dist/mcp/funder-org-names.js +30 -0
- package/dist/mcp/funder-org-names.js.map +1 -0
- package/dist/mcp/http-server.d.ts +20 -0
- package/dist/mcp/http-server.d.ts.map +1 -0
- package/dist/mcp/http-server.js +118 -0
- package/dist/mcp/http-server.js.map +1 -0
- package/dist/mcp/middleware/field-aliases.d.ts +97 -0
- package/dist/mcp/middleware/field-aliases.d.ts.map +1 -0
- package/dist/mcp/middleware/field-aliases.js +208 -0
- package/dist/mcp/middleware/field-aliases.js.map +1 -0
- package/dist/mcp/resources/schema.d.ts +13 -0
- package/dist/mcp/resources/schema.d.ts.map +1 -0
- package/dist/mcp/resources/schema.js +262 -0
- package/dist/mcp/resources/schema.js.map +1 -0
- package/dist/mcp/schema/context.d.ts +10 -0
- package/dist/mcp/schema/context.d.ts.map +1 -0
- package/dist/mcp/schema/context.js +6 -0
- package/dist/mcp/schema/context.js.map +1 -0
- package/dist/mcp/schema/index.d.ts +8 -0
- package/dist/mcp/schema/index.d.ts.map +1 -0
- package/dist/mcp/schema/index.js +6 -0
- package/dist/mcp/schema/index.js.map +1 -0
- package/dist/mcp/server.d.ts +56 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +168 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/shared-schema.d.ts +13 -0
- package/dist/mcp/shared-schema.d.ts.map +1 -0
- package/dist/mcp/shared-schema.js +28 -0
- package/dist/mcp/shared-schema.js.map +1 -0
- package/dist/mcp/tools/analytics-filters.d.ts +18 -0
- package/dist/mcp/tools/analytics-filters.d.ts.map +1 -0
- package/dist/mcp/tools/analytics-filters.js +35 -0
- package/dist/mcp/tools/analytics-filters.js.map +1 -0
- package/dist/mcp/tools/analytics.d.ts +16 -0
- package/dist/mcp/tools/analytics.d.ts.map +1 -0
- package/dist/mcp/tools/analytics.js +381 -0
- package/dist/mcp/tools/analytics.js.map +1 -0
- package/dist/mcp/tools/concept-profile.d.ts +14 -0
- package/dist/mcp/tools/concept-profile.d.ts.map +1 -0
- package/dist/mcp/tools/concept-profile.js +130 -0
- package/dist/mcp/tools/concept-profile.js.map +1 -0
- package/dist/mcp/tools/dataset-profile.d.ts +15 -0
- package/dist/mcp/tools/dataset-profile.d.ts.map +1 -0
- package/dist/mcp/tools/dataset-profile.js +194 -0
- package/dist/mcp/tools/dataset-profile.js.map +1 -0
- package/dist/mcp/tools/fetch-search-pages.d.ts +15 -0
- package/dist/mcp/tools/fetch-search-pages.d.ts.map +1 -0
- package/dist/mcp/tools/fetch-search-pages.js +237 -0
- package/dist/mcp/tools/fetch-search-pages.js.map +1 -0
- package/dist/mcp/tools/functions.d.ts +14 -0
- package/dist/mcp/tools/functions.d.ts.map +1 -0
- package/dist/mcp/tools/functions.js +87 -0
- package/dist/mcp/tools/functions.js.map +1 -0
- package/dist/mcp/tools/impact-chain.d.ts +15 -0
- package/dist/mcp/tools/impact-chain.d.ts.map +1 -0
- package/dist/mcp/tools/impact-chain.js +96 -0
- package/dist/mcp/tools/impact-chain.js.map +1 -0
- package/dist/mcp/tools/kwq.d.ts +19 -0
- package/dist/mcp/tools/kwq.d.ts.map +1 -0
- package/dist/mcp/tools/kwq.js +156 -0
- package/dist/mcp/tools/kwq.js.map +1 -0
- package/dist/mcp/tools/lookup.d.ts +14 -0
- package/dist/mcp/tools/lookup.d.ts.map +1 -0
- package/dist/mcp/tools/lookup.js +146 -0
- package/dist/mcp/tools/lookup.js.map +1 -0
- package/dist/mcp/tools/policy-profile.d.ts +15 -0
- package/dist/mcp/tools/policy-profile.d.ts.map +1 -0
- package/dist/mcp/tools/policy-profile.js +174 -0
- package/dist/mcp/tools/policy-profile.js.map +1 -0
- package/dist/mcp/tools/profile.d.ts +14 -0
- package/dist/mcp/tools/profile.d.ts.map +1 -0
- package/dist/mcp/tools/profile.js +349 -0
- package/dist/mcp/tools/profile.js.map +1 -0
- package/dist/mcp/tools/query.d.ts +16 -0
- package/dist/mcp/tools/query.d.ts.map +1 -0
- package/dist/mcp/tools/query.js +75 -0
- package/dist/mcp/tools/query.js.map +1 -0
- package/dist/mcp/tools/schema.d.ts +23 -0
- package/dist/mcp/tools/schema.d.ts.map +1 -0
- package/dist/mcp/tools/schema.js +124 -0
- package/dist/mcp/tools/schema.js.map +1 -0
- package/dist/mcp/tools/search-entity-metadata.d.ts +18 -0
- package/dist/mcp/tools/search-entity-metadata.d.ts.map +1 -0
- package/dist/mcp/tools/search-entity-metadata.js +221 -0
- package/dist/mcp/tools/search-entity-metadata.js.map +1 -0
- package/dist/mcp/tools/search-input.d.ts +58 -0
- package/dist/mcp/tools/search-input.d.ts.map +1 -0
- package/dist/mcp/tools/search-input.js +76 -0
- package/dist/mcp/tools/search-input.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +24 -0
- package/dist/mcp/tools/search.d.ts.map +1 -0
- package/dist/mcp/tools/search.js +115 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/mcp/utils.d.ts +82 -0
- package/dist/mcp/utils.d.ts.map +1 -0
- package/dist/mcp/utils.js +126 -0
- package/dist/mcp/utils.js.map +1 -0
- package/dist/middleware/field-aliases.d.ts +97 -0
- package/dist/middleware/field-aliases.d.ts.map +1 -0
- package/dist/middleware/field-aliases.js +208 -0
- package/dist/middleware/field-aliases.js.map +1 -0
- package/dist/resources/schema.d.ts +13 -0
- package/dist/resources/schema.d.ts.map +1 -0
- package/dist/resources/schema.js +204 -0
- package/dist/resources/schema.js.map +1 -0
- package/dist/schema/context.d.ts +10 -0
- package/dist/schema/context.d.ts.map +1 -0
- package/dist/schema/context.js +6 -0
- package/dist/schema/context.js.map +1 -0
- package/dist/schema/index.d.ts +9 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +6 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/load.d.ts +43 -0
- package/dist/schema/load.d.ts.map +1 -0
- package/dist/schema/load.js +139 -0
- package/dist/schema/load.js.map +1 -0
- package/dist/schema/store.d.ts +112 -0
- package/dist/schema/store.d.ts.map +1 -0
- package/dist/schema/store.js +173 -0
- package/dist/schema/store.js.map +1 -0
- package/dist/schema/structured-entities.d.ts +21 -0
- package/dist/schema/structured-entities.d.ts.map +1 -0
- package/dist/schema/structured-entities.js +39 -0
- package/dist/schema/structured-entities.js.map +1 -0
- package/dist/schema/types.d.ts +36 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +6 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/server.d.ts +57 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +144 -0
- package/dist/server.js.map +1 -0
- package/dist/telemetry.d.ts +172 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +233 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/tools/analytics-filters.d.ts +18 -0
- package/dist/tools/analytics-filters.d.ts.map +1 -0
- package/dist/tools/analytics-filters.js +35 -0
- package/dist/tools/analytics-filters.js.map +1 -0
- package/dist/tools/analytics.d.ts +16 -0
- package/dist/tools/analytics.d.ts.map +1 -0
- package/dist/tools/analytics.js +381 -0
- package/dist/tools/analytics.js.map +1 -0
- package/dist/tools/concept-profile.d.ts +14 -0
- package/dist/tools/concept-profile.d.ts.map +1 -0
- package/dist/tools/concept-profile.js +130 -0
- package/dist/tools/concept-profile.js.map +1 -0
- package/dist/tools/dataset-profile.d.ts +15 -0
- package/dist/tools/dataset-profile.d.ts.map +1 -0
- package/dist/tools/dataset-profile.js +194 -0
- package/dist/tools/dataset-profile.js.map +1 -0
- package/dist/tools/functions.d.ts +14 -0
- package/dist/tools/functions.d.ts.map +1 -0
- package/dist/tools/functions.js +294 -0
- package/dist/tools/functions.js.map +1 -0
- package/dist/tools/impact-chain.d.ts +15 -0
- package/dist/tools/impact-chain.d.ts.map +1 -0
- package/dist/tools/impact-chain.js +96 -0
- package/dist/tools/impact-chain.js.map +1 -0
- package/dist/tools/kwq.d.ts +19 -0
- package/dist/tools/kwq.d.ts.map +1 -0
- package/dist/tools/kwq.js +156 -0
- package/dist/tools/kwq.js.map +1 -0
- package/dist/tools/lookup.d.ts +14 -0
- package/dist/tools/lookup.d.ts.map +1 -0
- package/dist/tools/lookup.js +213 -0
- package/dist/tools/lookup.js.map +1 -0
- package/dist/tools/policy-profile.d.ts +15 -0
- package/dist/tools/policy-profile.d.ts.map +1 -0
- package/dist/tools/policy-profile.js +174 -0
- package/dist/tools/policy-profile.js.map +1 -0
- package/dist/tools/profile.d.ts +14 -0
- package/dist/tools/profile.d.ts.map +1 -0
- package/dist/tools/profile.js +349 -0
- package/dist/tools/profile.js.map +1 -0
- package/dist/tools/query.d.ts +16 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +53 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/tools/schema.d.ts +23 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +124 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/tools/search-entity-metadata.d.ts +18 -0
- package/dist/tools/search-entity-metadata.d.ts.map +1 -0
- package/dist/tools/search-entity-metadata.js +221 -0
- package/dist/tools/search-entity-metadata.js.map +1 -0
- package/dist/tools/search.d.ts +23 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +110 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/solr-fields.d.ts +39 -0
- package/dist/tools/solr-fields.d.ts.map +1 -0
- package/dist/tools/solr-fields.js +40 -0
- package/dist/tools/solr-fields.js.map +1 -0
- package/dist/utils.d.ts +70 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +104 -0
- package/dist/utils.js.map +1 -0
- package/package.json +41 -0
- package/src/client/auth/config-loaders.ts +81 -0
- package/src/client/auth/decorators/index.ts +7 -0
- package/src/client/auth/decorators/with-caching.ts +237 -0
- package/src/client/auth/factory.ts +34 -0
- package/src/client/auth/index.ts +6 -0
- package/src/client/auth/jwt-utils.ts +36 -0
- package/src/client/auth/node.ts +16 -0
- package/src/client/auth/providers/index.ts +1 -0
- package/src/client/auth/providers/jwt-auth-provider.ts +153 -0
- package/src/client/auth/schemas.ts +25 -0
- package/src/client/auth/types.ts +30 -0
- package/src/client/command.ts +54 -0
- package/src/client/config/index.ts +15 -0
- package/src/client/config/loader.ts +155 -0
- package/src/client/config/node.ts +22 -0
- package/src/client/config/schemas.ts +28 -0
- package/src/client/config/types.ts +39 -0
- package/src/client/config/unified-loader.ts +118 -0
- package/src/client/config.ts +69 -0
- package/src/client/deployment-config.ts +98 -0
- package/src/client/errors.ts +295 -0
- package/src/client/http-client.ts +577 -0
- package/src/client/index.ts +68 -0
- package/src/client/internal-dsl-client.ts +128 -0
- package/src/client/rate-limiter.ts +139 -0
- package/src/client/resolve-api-key-user.ts +99 -0
- package/src/client/types.ts +44 -0
- package/src/dsl/client.ts +538 -0
- package/src/dsl/commands/apply-filters.ts +35 -0
- package/src/dsl/commands/facet/index.ts +12 -0
- package/src/dsl/commands/facet/schemas.ts +101 -0
- package/src/dsl/commands/functions/ClassifyCommand.ts +129 -0
- package/src/dsl/commands/functions/ExtractAffiliationsCommand.ts +163 -0
- package/src/dsl/commands/functions/ExtractConceptsCommand.ts +141 -0
- package/src/dsl/commands/functions/ExtractGrantsCommand.ts +112 -0
- package/src/dsl/commands/functions/index.ts +31 -0
- package/src/dsl/commands/index.ts +29 -0
- package/src/dsl/commands/validate-input.ts +29 -0
- package/src/dsl/create-client.ts +80 -0
- package/src/dsl/fluent-query-builder.ts +684 -0
- package/src/dsl/index.ts +206 -0
- package/src/dsl/pagination.ts +202 -0
- package/src/dsl/query-builder.ts +1120 -0
- package/src/dsl/response-parser.ts +299 -0
- package/src/dsl/schema/cache.ts +124 -0
- package/src/dsl/schema/extract.ts +44 -0
- package/src/dsl/schema/index.ts +50 -0
- package/src/dsl/schema/load.ts +160 -0
- package/src/dsl/schema/store.ts +253 -0
- package/src/dsl/schema/structured-entities.ts +44 -0
- package/src/dsl/schema/summary.ts +94 -0
- package/src/dsl/schema/types.ts +40 -0
- package/src/dsl/schema/validation.ts +56 -0
- package/src/dsl/types/buckets.ts +22 -0
- package/src/dsl/types/common.ts +99 -0
- package/src/dsl/types/entities.ts +43 -0
- package/src/dsl/types/index.ts +63 -0
- package/src/dsl/types/return-clauses.ts +147 -0
- package/src/dsl/types/special-functions.ts +220 -0
- package/src/dsl/types/vocabulary.ts +82 -0
- package/src/dsl/usage-policy.ts +219 -0
- package/src/dsl/utils/escape.ts +123 -0
- package/src/dsl/utils/sanitize.ts +21 -0
- package/src/dsl/utils/string-utils.ts +147 -0
- package/src/dsl/utils/validate-field-name.ts +19 -0
- package/src/http-main.ts +41 -0
- package/src/index.ts +14 -0
- package/src/main.ts +40 -0
- package/src/mcp/batch-fetch.ts +255 -0
- package/src/mcp/examples/dsl-examples.ts +66 -0
- package/src/mcp/examples/usage-scenarios.ts +185 -0
- package/src/mcp/export-format.ts +113 -0
- package/src/mcp/funder-org-names.ts +30 -0
- package/src/mcp/http-server.ts +148 -0
- package/src/mcp/middleware/field-aliases.ts +274 -0
- package/src/mcp/resources/schema.ts +364 -0
- package/src/mcp/schema/context.ts +11 -0
- package/src/mcp/schema/index.ts +38 -0
- package/src/mcp/server.ts +247 -0
- package/src/mcp/shared-schema.ts +34 -0
- package/src/mcp/tools/analytics-filters.ts +46 -0
- package/src/mcp/tools/analytics.ts +453 -0
- package/src/mcp/tools/fetch-search-pages.ts +329 -0
- package/src/mcp/tools/functions.ts +105 -0
- package/src/mcp/tools/lookup.ts +182 -0
- package/src/mcp/tools/query.ts +91 -0
- package/src/mcp/tools/schema.ts +147 -0
- package/src/mcp/tools/search-entity-metadata.ts +253 -0
- package/src/mcp/tools/search-input.ts +87 -0
- package/src/mcp/tools/search.ts +168 -0
- package/src/mcp/utils.ts +199 -0
- package/test/client/auth/config-loaders.test.ts +92 -0
- package/test/client/auth/decorators/with-caching.test.ts +482 -0
- package/test/client/auth/factory.test.ts +68 -0
- package/test/client/auth/providers/jwt-auth-provider.test.ts +398 -0
- package/test/client/auth/types.test.ts +18 -0
- package/test/client/command.test.ts +163 -0
- package/test/client/config/loader.test.ts +377 -0
- package/test/client/config/unified-loader.test.ts +136 -0
- package/test/client/deployment-config.test.ts +69 -0
- package/test/client/errors/index.test.ts +408 -0
- package/test/client/helpers/mock-fetch.ts +42 -0
- package/test/client/http-client.test.ts +1148 -0
- package/test/client/integration/auth-providers.integration.test.ts +186 -0
- package/test/client/internal-dsl-client.test.ts +76 -0
- package/test/client/rate-limiter.test.ts +204 -0
- package/test/client/resolve-api-key-user.test.ts +87 -0
- package/test/dsl/client.special-functions.test.ts +387 -0
- package/test/dsl/client.test.ts +457 -0
- package/test/dsl/commands/apply-filters.test.ts +147 -0
- package/test/dsl/commands/functions/ClassifyCommand.test.ts +170 -0
- package/test/dsl/commands/functions/ExtractAffiliationsCommand.test.ts +306 -0
- package/test/dsl/commands/functions/ExtractConceptsCommand.test.ts +136 -0
- package/test/dsl/commands/functions/ExtractGrantsCommand.test.ts +202 -0
- package/test/dsl/commands/search/filters.test.ts +42 -0
- package/test/dsl/fluent-query-builder.test.ts +865 -0
- package/test/dsl/integration/client.integration.test.ts +294 -0
- package/test/dsl/integration/facet-api.integration.test.ts +276 -0
- package/test/dsl/integration/field-existence.integration.test.ts +148 -0
- package/test/dsl/integration/fluent-api-docs-examples.integration.test.ts +988 -0
- package/test/dsl/integration/fluent-api.integration.test.ts +615 -0
- package/test/dsl/integration/search-helpers.ts +27 -0
- package/test/dsl/integration/special-functions.integration.test.ts +224 -0
- package/test/dsl/integration/test-config.ts +52 -0
- package/test/dsl/pagination.test.ts +86 -0
- package/test/dsl/query-builder.test.ts +1775 -0
- package/test/dsl/response-parser.test.ts +520 -0
- package/test/dsl/schema/cache.test.ts +53 -0
- package/test/dsl/schema/load.test.ts +165 -0
- package/test/dsl/schema/summary.test.ts +61 -0
- package/test/dsl/schema/validation.test.ts +46 -0
- package/test/dsl/time-series.test.ts +135 -0
- package/test/dsl/unnest.test.ts +151 -0
- package/test/dsl/usage-policy.test.ts +100 -0
- package/test/dsl/utils/escape.property.test.ts +109 -0
- package/test/dsl/utils/escape.test.ts +140 -0
- package/test/dsl/utils/validate-field-name.property.test.ts +99 -0
- package/test/dsl/utils/validate-field-name.test.ts +55 -0
- package/test/examples/dsl-examples.test.ts +29 -0
- package/test/examples/usage-scenarios.test.ts +90 -0
- package/test/fixtures/describe-schema.json +4000 -0
- package/test/funder-org-names.test.ts +20 -0
- package/test/helpers/schema-fixture.ts +18 -0
- package/test/helpers/tool-test-harness.ts +114 -0
- package/test/integration/assertions.ts +263 -0
- package/test/integration/env.ts +108 -0
- package/test/integration/harness.ts +307 -0
- package/test/integration/hosted-client.ts +56 -0
- package/test/integration/hosted-mocks.ts +81 -0
- package/test/integration/hosted-run.ts +86 -0
- package/test/integration/hosted.e2e.test.ts +101 -0
- package/test/integration/reporter.ts +100 -0
- package/test/integration/run.ts +74 -0
- package/test/integration/suites/analytics.integration.ts +72 -0
- package/test/integration/suites/functions.integration.ts +37 -0
- package/test/integration/suites/hosted-smoke.integration.ts +38 -0
- package/test/integration/suites/index.ts +22 -0
- package/test/integration/suites/lookup.integration.ts +57 -0
- package/test/integration/suites/query.integration.ts +49 -0
- package/test/integration/suites/resources.integration.ts +68 -0
- package/test/integration/suites/search.integration.ts +80 -0
- package/test/integration/types.ts +92 -0
- package/test/integration/verify-usage-scenarios.ts +162 -0
- package/test/mcp/export-format.test.ts +67 -0
- package/test/mcp/http-server.test.ts +80 -0
- package/test/middleware/field-aliases.test.ts +287 -0
- package/test/resources/schema.test.ts +28 -0
- package/test/schema/describe-contract.test.ts +24 -0
- package/test/schema/store.test.ts +45 -0
- package/test/server.test.ts +170 -0
- package/test/tools/analytics-filters.test.ts +35 -0
- package/test/tools/analytics.test.ts +419 -0
- package/test/tools/fetch-search-pages.test.ts +200 -0
- package/test/tools/functions.test.ts +153 -0
- package/test/tools/lookup.test.ts +296 -0
- package/test/tools/query.test.ts +100 -0
- package/test/tools/schema.test.ts +37 -0
- package/test/tools/search.test.ts +415 -0
- package/test/utils.test.ts +45 -0
- package/tsconfig.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { withCaching } from "../../../../src/client/auth/decorators/with-caching.js";
|
|
3
|
+
import type { AuthProvider } from "../../../../src/client/auth/types.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a mock auth provider for testing.
|
|
7
|
+
*/
|
|
8
|
+
function createMockProvider(
|
|
9
|
+
headers: Record<string, string> = { Authorization: "Bearer test" },
|
|
10
|
+
): AuthProvider & {
|
|
11
|
+
getHeaders: ReturnType<typeof vi.fn>;
|
|
12
|
+
refresh: ReturnType<typeof vi.fn>;
|
|
13
|
+
invalidate: ReturnType<typeof vi.fn>;
|
|
14
|
+
initialize: ReturnType<typeof vi.fn>;
|
|
15
|
+
} {
|
|
16
|
+
return {
|
|
17
|
+
type: "jwt",
|
|
18
|
+
initialize: vi.fn().mockResolvedValue(undefined),
|
|
19
|
+
getHeaders: vi.fn().mockResolvedValue(headers),
|
|
20
|
+
refresh: vi.fn().mockResolvedValue(undefined),
|
|
21
|
+
invalidate: vi.fn(),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe("withCaching", () => {
|
|
26
|
+
describe("basic caching", () => {
|
|
27
|
+
it("caches headers and reuses them", async () => {
|
|
28
|
+
const mockProvider = createMockProvider();
|
|
29
|
+
// Use cache duration longer than minimum buffer (60s) to ensure caching works
|
|
30
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
31
|
+
cacheDurationMs: 300000, // 5 minutes
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// First call should fetch headers
|
|
35
|
+
await cachedProvider.getHeaders();
|
|
36
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
37
|
+
|
|
38
|
+
// Second call should use cache (within TTL)
|
|
39
|
+
await cachedProvider.getHeaders();
|
|
40
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
41
|
+
|
|
42
|
+
// Third call still cached
|
|
43
|
+
await cachedProvider.getHeaders();
|
|
44
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("returns correct headers", async () => {
|
|
48
|
+
const mockProvider = createMockProvider({ Authorization: "Bearer xyz" });
|
|
49
|
+
const cachedProvider = withCaching(mockProvider);
|
|
50
|
+
|
|
51
|
+
const headers = await cachedProvider.getHeaders();
|
|
52
|
+
|
|
53
|
+
expect(headers).toEqual({ Authorization: "Bearer xyz" });
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("concurrent request deduplication", () => {
|
|
58
|
+
it("deduplicates concurrent getHeaders calls", async () => {
|
|
59
|
+
const mockProvider = createMockProvider();
|
|
60
|
+
// Add delay to simulate network request
|
|
61
|
+
mockProvider.getHeaders.mockImplementation(
|
|
62
|
+
() =>
|
|
63
|
+
new Promise((resolve) => setTimeout(() => resolve({ Authorization: "Bearer test" }), 50)),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Use cache duration longer than minimum buffer (60s)
|
|
67
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
68
|
+
cacheDurationMs: 300000,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Fire multiple concurrent requests
|
|
72
|
+
const [result1, result2, result3] = await Promise.all([
|
|
73
|
+
cachedProvider.getHeaders(),
|
|
74
|
+
cachedProvider.getHeaders(),
|
|
75
|
+
cachedProvider.getHeaders(),
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
// All should return same result
|
|
79
|
+
expect(result1).toEqual(result2);
|
|
80
|
+
expect(result2).toEqual(result3);
|
|
81
|
+
|
|
82
|
+
// But getHeaders should only be called once
|
|
83
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("refresh method", () => {
|
|
88
|
+
it("clears cache and forces re-fetch", async () => {
|
|
89
|
+
const mockProvider = createMockProvider();
|
|
90
|
+
// Use cache duration longer than minimum buffer (60s)
|
|
91
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
92
|
+
cacheDurationMs: 300000,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await cachedProvider.getHeaders();
|
|
96
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
97
|
+
|
|
98
|
+
await cachedProvider.refresh();
|
|
99
|
+
|
|
100
|
+
await cachedProvider.getHeaders();
|
|
101
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(2);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe("invalidate method", () => {
|
|
106
|
+
it("clears cache and calls underlying invalidate", async () => {
|
|
107
|
+
const mockProvider = createMockProvider();
|
|
108
|
+
// Use cache duration longer than minimum buffer (60s)
|
|
109
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
110
|
+
cacheDurationMs: 300000,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await cachedProvider.getHeaders();
|
|
114
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
115
|
+
|
|
116
|
+
cachedProvider.invalidate();
|
|
117
|
+
expect(mockProvider.invalidate).toHaveBeenCalledTimes(1);
|
|
118
|
+
|
|
119
|
+
// Next getHeaders should fetch again (cache was cleared)
|
|
120
|
+
await cachedProvider.getHeaders();
|
|
121
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(2);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe("initialize method", () => {
|
|
126
|
+
it("delegates to underlying provider", async () => {
|
|
127
|
+
const mockProvider = createMockProvider();
|
|
128
|
+
const cachedProvider = withCaching(mockProvider);
|
|
129
|
+
|
|
130
|
+
await cachedProvider.initialize();
|
|
131
|
+
|
|
132
|
+
expect(mockProvider.initialize).toHaveBeenCalledTimes(1);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe("type property", () => {
|
|
137
|
+
it("returns underlying provider type", () => {
|
|
138
|
+
const mockProvider = createMockProvider();
|
|
139
|
+
const cachedProvider = withCaching(mockProvider);
|
|
140
|
+
|
|
141
|
+
expect(cachedProvider.type).toBe("jwt");
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe("fetchHeaders does not call refresh", () => {
|
|
146
|
+
it("only calls provider.getHeaders(), not provider.refresh()", async () => {
|
|
147
|
+
const mockProvider = createMockProvider();
|
|
148
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
149
|
+
cacheDurationMs: 300000,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
await cachedProvider.getHeaders();
|
|
153
|
+
|
|
154
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
155
|
+
expect(mockProvider.refresh).not.toHaveBeenCalled();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe("error propagation", () => {
|
|
160
|
+
it("propagates errors from underlying provider", async () => {
|
|
161
|
+
const mockProvider = createMockProvider();
|
|
162
|
+
mockProvider.getHeaders.mockRejectedValue(new Error("Auth failed"));
|
|
163
|
+
|
|
164
|
+
const cachedProvider = withCaching(mockProvider);
|
|
165
|
+
|
|
166
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("Auth failed");
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("does not cache failed requests", async () => {
|
|
170
|
+
const mockProvider = createMockProvider();
|
|
171
|
+
mockProvider.getHeaders
|
|
172
|
+
.mockRejectedValueOnce(new Error("Auth failed"))
|
|
173
|
+
.mockResolvedValueOnce({ Authorization: "Bearer test" });
|
|
174
|
+
|
|
175
|
+
const cachedProvider = withCaching(mockProvider);
|
|
176
|
+
|
|
177
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("Auth failed");
|
|
178
|
+
|
|
179
|
+
// Retry should work
|
|
180
|
+
const headers = await cachedProvider.getHeaders();
|
|
181
|
+
expect(headers).toEqual({ Authorization: "Bearer test" });
|
|
182
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(2);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe("failure backoff", () => {
|
|
187
|
+
afterEach(() => {
|
|
188
|
+
vi.useRealTimers();
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("returns stale cache during backoff period after failure", async () => {
|
|
192
|
+
vi.useFakeTimers();
|
|
193
|
+
const mockProvider = createMockProvider();
|
|
194
|
+
// Use very short cache that expires quickly (expiryBuffer=0.9 means 10% of 100ms = 10ms effective)
|
|
195
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
196
|
+
cacheDurationMs: 100,
|
|
197
|
+
expiryBuffer: 0.9, // Cache expires after ~10ms
|
|
198
|
+
failureBackoffMs: 200,
|
|
199
|
+
failureBackoffJitter: 0,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// First call populates cache
|
|
203
|
+
await cachedProvider.getHeaders();
|
|
204
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(1);
|
|
205
|
+
|
|
206
|
+
// Advance past cache expiry
|
|
207
|
+
vi.advanceTimersByTime(120);
|
|
208
|
+
|
|
209
|
+
// Make getHeaders fail on next call
|
|
210
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("Auth failed"));
|
|
211
|
+
|
|
212
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("Auth failed");
|
|
213
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(2);
|
|
214
|
+
|
|
215
|
+
// During backoff, should return stale cache (no new fetch attempt)
|
|
216
|
+
const headers = await cachedProvider.getHeaders();
|
|
217
|
+
expect(headers).toEqual({ Authorization: "Bearer test" });
|
|
218
|
+
// Should NOT have called getHeaders again (within backoff)
|
|
219
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(2);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it("allows retry after backoff period expires", async () => {
|
|
223
|
+
vi.useFakeTimers();
|
|
224
|
+
const mockProvider = createMockProvider();
|
|
225
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
226
|
+
cacheDurationMs: 100,
|
|
227
|
+
expiryBuffer: 0.9,
|
|
228
|
+
failureBackoffMs: 50,
|
|
229
|
+
failureBackoffJitter: 0,
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// First call populates cache
|
|
233
|
+
await cachedProvider.getHeaders();
|
|
234
|
+
|
|
235
|
+
// Advance past cache expiry
|
|
236
|
+
vi.advanceTimersByTime(120);
|
|
237
|
+
|
|
238
|
+
// Make getHeaders fail on next call
|
|
239
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("Auth failed"));
|
|
240
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("Auth failed");
|
|
241
|
+
|
|
242
|
+
// Advance past backoff period
|
|
243
|
+
vi.advanceTimersByTime(60);
|
|
244
|
+
|
|
245
|
+
// Now it should retry
|
|
246
|
+
mockProvider.getHeaders.mockResolvedValueOnce({
|
|
247
|
+
Authorization: "Bearer new-token",
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const headers = await cachedProvider.getHeaders();
|
|
251
|
+
expect(headers).toEqual({ Authorization: "Bearer new-token" });
|
|
252
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(3);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("invalidate() clears backoff state", async () => {
|
|
256
|
+
vi.useFakeTimers();
|
|
257
|
+
const mockProvider = createMockProvider();
|
|
258
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
259
|
+
cacheDurationMs: 100,
|
|
260
|
+
expiryBuffer: 0.9,
|
|
261
|
+
failureBackoffMs: 500, // Long backoff that we'll clear
|
|
262
|
+
failureBackoffJitter: 0,
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// First call populates cache
|
|
266
|
+
await cachedProvider.getHeaders();
|
|
267
|
+
|
|
268
|
+
// Advance past cache expiry
|
|
269
|
+
vi.advanceTimersByTime(120);
|
|
270
|
+
|
|
271
|
+
// Make getHeaders fail on next call
|
|
272
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("Auth failed"));
|
|
273
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("Auth failed");
|
|
274
|
+
|
|
275
|
+
// Invalidate should clear backoff
|
|
276
|
+
cachedProvider.invalidate();
|
|
277
|
+
|
|
278
|
+
// Should retry immediately (backoff cleared)
|
|
279
|
+
mockProvider.getHeaders.mockResolvedValueOnce({
|
|
280
|
+
Authorization: "Bearer new-token",
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
const headers = await cachedProvider.getHeaders();
|
|
284
|
+
expect(headers).toEqual({ Authorization: "Bearer new-token" });
|
|
285
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(3);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("refresh() clears backoff state", async () => {
|
|
289
|
+
vi.useFakeTimers();
|
|
290
|
+
const mockProvider = createMockProvider();
|
|
291
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
292
|
+
cacheDurationMs: 100,
|
|
293
|
+
expiryBuffer: 0.9,
|
|
294
|
+
failureBackoffMs: 500, // Long backoff that we'll clear
|
|
295
|
+
failureBackoffJitter: 0,
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// First call populates cache
|
|
299
|
+
await cachedProvider.getHeaders();
|
|
300
|
+
|
|
301
|
+
// Advance past cache expiry
|
|
302
|
+
vi.advanceTimersByTime(120);
|
|
303
|
+
|
|
304
|
+
// Make getHeaders fail on next call
|
|
305
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("Auth failed"));
|
|
306
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("Auth failed");
|
|
307
|
+
|
|
308
|
+
// Manual refresh should clear backoff
|
|
309
|
+
await cachedProvider.refresh();
|
|
310
|
+
|
|
311
|
+
// Should retry immediately (backoff cleared)
|
|
312
|
+
mockProvider.getHeaders.mockResolvedValueOnce({
|
|
313
|
+
Authorization: "Bearer new-token",
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const headers = await cachedProvider.getHeaders();
|
|
317
|
+
expect(headers).toEqual({ Authorization: "Bearer new-token" });
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("increases backoff exponentially on consecutive failures", async () => {
|
|
321
|
+
vi.useFakeTimers();
|
|
322
|
+
const mockProvider = createMockProvider();
|
|
323
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
324
|
+
cacheDurationMs: 100,
|
|
325
|
+
expiryBuffer: 0.9,
|
|
326
|
+
failureBackoffMs: 1000,
|
|
327
|
+
failureBackoffFactor: 2,
|
|
328
|
+
failureBackoffJitter: 0,
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Populate cache then expire it
|
|
332
|
+
await cachedProvider.getHeaders();
|
|
333
|
+
vi.advanceTimersByTime(120);
|
|
334
|
+
|
|
335
|
+
// Failure 1: backoff = 1000ms
|
|
336
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
337
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
338
|
+
|
|
339
|
+
// Still in backoff at 999ms — returns stale cache
|
|
340
|
+
vi.advanceTimersByTime(999);
|
|
341
|
+
const stale1 = await cachedProvider.getHeaders();
|
|
342
|
+
expect(stale1).toEqual({ Authorization: "Bearer test" });
|
|
343
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(2);
|
|
344
|
+
|
|
345
|
+
// Past first backoff (1001ms total) — failure 2: backoff = 2000ms
|
|
346
|
+
vi.advanceTimersByTime(2);
|
|
347
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
348
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
349
|
+
|
|
350
|
+
// Still in backoff at 1999ms — returns stale cache
|
|
351
|
+
vi.advanceTimersByTime(1999);
|
|
352
|
+
const stale2 = await cachedProvider.getHeaders();
|
|
353
|
+
expect(stale2).toEqual({ Authorization: "Bearer test" });
|
|
354
|
+
expect(mockProvider.getHeaders).toHaveBeenCalledTimes(3);
|
|
355
|
+
|
|
356
|
+
// Past second backoff — success
|
|
357
|
+
vi.advanceTimersByTime(2);
|
|
358
|
+
mockProvider.getHeaders.mockResolvedValueOnce({ Authorization: "Bearer new" });
|
|
359
|
+
const fresh = await cachedProvider.getHeaders();
|
|
360
|
+
expect(fresh).toEqual({ Authorization: "Bearer new" });
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("caps backoff at failureBackoffMaxMs", async () => {
|
|
364
|
+
vi.useFakeTimers();
|
|
365
|
+
const mockProvider = createMockProvider();
|
|
366
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
367
|
+
cacheDurationMs: 100,
|
|
368
|
+
expiryBuffer: 0.9,
|
|
369
|
+
failureBackoffMs: 1000,
|
|
370
|
+
failureBackoffMaxMs: 4000,
|
|
371
|
+
failureBackoffFactor: 2,
|
|
372
|
+
failureBackoffJitter: 0,
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
await cachedProvider.getHeaders();
|
|
376
|
+
vi.advanceTimersByTime(120);
|
|
377
|
+
|
|
378
|
+
// 3 failures: windows of 1000ms, 2000ms, 4000ms (hits cap)
|
|
379
|
+
for (let i = 0; i < 3; i++) {
|
|
380
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
381
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
382
|
+
vi.advanceTimersByTime(5000); // advance past each window
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// 4th failure — window should still be 4000ms (capped)
|
|
386
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
387
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
388
|
+
|
|
389
|
+
// Still in backoff at 3999ms
|
|
390
|
+
vi.advanceTimersByTime(3999);
|
|
391
|
+
const stale = await cachedProvider.getHeaders();
|
|
392
|
+
expect(stale).toEqual({ Authorization: "Bearer test" });
|
|
393
|
+
|
|
394
|
+
// Past cap — success
|
|
395
|
+
vi.advanceTimersByTime(2);
|
|
396
|
+
mockProvider.getHeaders.mockResolvedValueOnce({ Authorization: "Bearer new" });
|
|
397
|
+
const fresh = await cachedProvider.getHeaders();
|
|
398
|
+
expect(fresh).toEqual({ Authorization: "Bearer new" });
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it("resets failure count after successful fetch", async () => {
|
|
402
|
+
vi.useFakeTimers();
|
|
403
|
+
const mockProvider = createMockProvider();
|
|
404
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
405
|
+
cacheDurationMs: 100,
|
|
406
|
+
expiryBuffer: 0.9,
|
|
407
|
+
failureBackoffMs: 1000,
|
|
408
|
+
failureBackoffFactor: 2,
|
|
409
|
+
failureBackoffJitter: 0,
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
await cachedProvider.getHeaders();
|
|
413
|
+
vi.advanceTimersByTime(120);
|
|
414
|
+
|
|
415
|
+
// Two failures escalate: 1000ms, then 2000ms
|
|
416
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
417
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
418
|
+
vi.advanceTimersByTime(1001);
|
|
419
|
+
|
|
420
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
421
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
422
|
+
vi.advanceTimersByTime(2001);
|
|
423
|
+
|
|
424
|
+
// Success — resets failure count
|
|
425
|
+
mockProvider.getHeaders.mockResolvedValueOnce({ Authorization: "Bearer ok" });
|
|
426
|
+
await cachedProvider.getHeaders();
|
|
427
|
+
|
|
428
|
+
// Expire new cache
|
|
429
|
+
vi.advanceTimersByTime(120);
|
|
430
|
+
|
|
431
|
+
// Next failure should be back to 1000ms (not 4000ms)
|
|
432
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
433
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
434
|
+
|
|
435
|
+
// Still in 1000ms backoff at 999ms
|
|
436
|
+
vi.advanceTimersByTime(999);
|
|
437
|
+
const stale = await cachedProvider.getHeaders();
|
|
438
|
+
expect(stale).toEqual({ Authorization: "Bearer ok" });
|
|
439
|
+
|
|
440
|
+
// Past 1000ms — retries
|
|
441
|
+
vi.advanceTimersByTime(2);
|
|
442
|
+
mockProvider.getHeaders.mockResolvedValueOnce({ Authorization: "Bearer fresh" });
|
|
443
|
+
const fresh = await cachedProvider.getHeaders();
|
|
444
|
+
expect(fresh).toEqual({ Authorization: "Bearer fresh" });
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it("respects custom failureBackoffFactor", async () => {
|
|
448
|
+
vi.useFakeTimers();
|
|
449
|
+
const mockProvider = createMockProvider();
|
|
450
|
+
const cachedProvider = withCaching(mockProvider, {
|
|
451
|
+
cacheDurationMs: 100,
|
|
452
|
+
expiryBuffer: 0.9,
|
|
453
|
+
failureBackoffMs: 1000,
|
|
454
|
+
failureBackoffFactor: 3, // 1000ms, 3000ms, 9000ms...
|
|
455
|
+
failureBackoffJitter: 0,
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
await cachedProvider.getHeaders();
|
|
459
|
+
vi.advanceTimersByTime(120);
|
|
460
|
+
|
|
461
|
+
// Failure 1: 1000ms window
|
|
462
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
463
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
464
|
+
vi.advanceTimersByTime(1001);
|
|
465
|
+
|
|
466
|
+
// Failure 2: 3000ms window (factor=3)
|
|
467
|
+
mockProvider.getHeaders.mockRejectedValueOnce(new Error("fail"));
|
|
468
|
+
await expect(cachedProvider.getHeaders()).rejects.toThrow("fail");
|
|
469
|
+
|
|
470
|
+
// Still in backoff at 2999ms
|
|
471
|
+
vi.advanceTimersByTime(2999);
|
|
472
|
+
const stale = await cachedProvider.getHeaders();
|
|
473
|
+
expect(stale).toEqual({ Authorization: "Bearer test" });
|
|
474
|
+
|
|
475
|
+
// Past 3000ms — success
|
|
476
|
+
vi.advanceTimersByTime(2);
|
|
477
|
+
mockProvider.getHeaders.mockResolvedValueOnce({ Authorization: "Bearer new" });
|
|
478
|
+
const fresh = await cachedProvider.getHeaders();
|
|
479
|
+
expect(fresh).toEqual({ Authorization: "Bearer new" });
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { createAuthProvider } from "../../../src/client/auth/factory.js";
|
|
3
|
+
import { ValidationError } from "../../../src/client/errors.js";
|
|
4
|
+
|
|
5
|
+
describe("createAuthProvider", () => {
|
|
6
|
+
const originalFetch = globalThis.fetch;
|
|
7
|
+
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
globalThis.fetch = originalFetch;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("creates JWT provider with caching", async () => {
|
|
13
|
+
const mockFetch = vi.fn().mockResolvedValue({
|
|
14
|
+
ok: true,
|
|
15
|
+
json: () => Promise.resolve({ token: "eyJhbGc.eyJzdWI.dGVzdA" }),
|
|
16
|
+
});
|
|
17
|
+
globalThis.fetch = mockFetch;
|
|
18
|
+
|
|
19
|
+
const provider = createAuthProvider({
|
|
20
|
+
type: "jwt",
|
|
21
|
+
apiKey: "test-api-key",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(provider.type).toBe("jwt");
|
|
25
|
+
|
|
26
|
+
const headers = await provider.getHeaders();
|
|
27
|
+
expect(headers.Authorization).toBe("JWT eyJhbGc.eyJzdWI.dGVzdA");
|
|
28
|
+
|
|
29
|
+
await provider.getHeaders();
|
|
30
|
+
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("passes auth URL to provider", async () => {
|
|
34
|
+
const mockFetch = vi.fn().mockResolvedValue({
|
|
35
|
+
ok: true,
|
|
36
|
+
json: () => Promise.resolve({ token: "eyJhbGc.eyJzdWI.dGVzdA" }),
|
|
37
|
+
});
|
|
38
|
+
globalThis.fetch = mockFetch;
|
|
39
|
+
|
|
40
|
+
const provider = createAuthProvider({
|
|
41
|
+
type: "jwt",
|
|
42
|
+
apiKey: "test-api-key",
|
|
43
|
+
authUrl: "https://custom.auth.com/token",
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await provider.getHeaders();
|
|
47
|
+
expect(mockFetch).toHaveBeenCalledWith("https://custom.auth.com/token", expect.any(Object));
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("throws ValidationError for missing API key", () => {
|
|
51
|
+
expect(() =>
|
|
52
|
+
createAuthProvider({
|
|
53
|
+
type: "jwt",
|
|
54
|
+
apiKey: "",
|
|
55
|
+
}),
|
|
56
|
+
).toThrow(ValidationError);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("throws ValidationError for invalid auth URL", () => {
|
|
60
|
+
expect(() =>
|
|
61
|
+
createAuthProvider({
|
|
62
|
+
type: "jwt",
|
|
63
|
+
apiKey: "valid-key",
|
|
64
|
+
authUrl: "not-a-valid-url",
|
|
65
|
+
}),
|
|
66
|
+
).toThrow(ValidationError);
|
|
67
|
+
});
|
|
68
|
+
});
|