@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,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response parser for Dimensions API facet results.
|
|
3
|
+
* Transforms raw API responses into typed facet result structures.
|
|
4
|
+
* @module response-parser
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { ValidationError } from "../client/index.js";
|
|
9
|
+
import type { BaseBucket } from "./types/buckets.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Schema for validating bucket objects in facet results.
|
|
13
|
+
* Buckets must have an id (string or number) and a non-negative count.
|
|
14
|
+
*/
|
|
15
|
+
const BaseBucketSchema = z
|
|
16
|
+
.object({
|
|
17
|
+
id: z.union([z.string(), z.number()]),
|
|
18
|
+
count: z.number().int().nonnegative(),
|
|
19
|
+
})
|
|
20
|
+
.passthrough();
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Schema for validating _stats object in API responses.
|
|
24
|
+
*/
|
|
25
|
+
const StatsSchema = z
|
|
26
|
+
.object({
|
|
27
|
+
total_count: z.number().int().nonnegative(),
|
|
28
|
+
})
|
|
29
|
+
.passthrough();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Configuration for a facet field, including optional aggregation indicators.
|
|
33
|
+
*/
|
|
34
|
+
export interface FacetFieldConfig {
|
|
35
|
+
/** Optional array of aggregation indicator names to validate */
|
|
36
|
+
readonly indicators?: readonly string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Parses entity data from a Dimensions API response.
|
|
41
|
+
* Validates that the entity array is properly structured.
|
|
42
|
+
* Falls back to data.length if _stats.total_count is not available.
|
|
43
|
+
*
|
|
44
|
+
* @template T - The entity type
|
|
45
|
+
* @param response - Raw API response object
|
|
46
|
+
* @param entityKey - The entity type key (e.g., "publications")
|
|
47
|
+
* @returns Entity result with data array and totalCount
|
|
48
|
+
* @throws {ValidationError} If entity data is not an array
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const result = parseEntityResponse<Publication>(response, "publications");
|
|
53
|
+
* console.log(result.data.length, result.totalCount);
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function parseEntityResponse<T>(
|
|
57
|
+
response: Record<string, unknown>,
|
|
58
|
+
entityKey: string,
|
|
59
|
+
): EntityResult<T> {
|
|
60
|
+
const entityData = response[entityKey];
|
|
61
|
+
|
|
62
|
+
// If entity key is missing, return empty result
|
|
63
|
+
if (entityData === undefined) {
|
|
64
|
+
return { data: [], totalCount: 0 };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Validate entity data is an array
|
|
68
|
+
if (!Array.isArray(entityData)) {
|
|
69
|
+
throw new ValidationError(`Entity key "${entityKey}" must be an array`, {
|
|
70
|
+
entityKey,
|
|
71
|
+
actualType: typeof entityData,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const entityArray = entityData as T[];
|
|
76
|
+
|
|
77
|
+
// Try to get total_count from stats, fallback to data length
|
|
78
|
+
const statsResult = StatsSchema.safeParse(response._stats);
|
|
79
|
+
const totalCount = statsResult.success ? statsResult.data.total_count : entityArray.length;
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
data: entityArray,
|
|
83
|
+
totalCount,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Cache for bucket schemas keyed by sorted indicator combination.
|
|
89
|
+
* Avoids rebuilding the same ZodObject on every transformResponse call.
|
|
90
|
+
*/
|
|
91
|
+
const bucketSchemaCache = new Map<string, z.ZodObject<z.ZodRawShape>>();
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Creates a bucket schema that validates both base fields and aggregation indicators.
|
|
95
|
+
* Caches schemas by indicator combination to avoid repeated allocations.
|
|
96
|
+
* @param indicators - Array of indicator names that must be present as numbers
|
|
97
|
+
* @returns Zod schema for bucket validation
|
|
98
|
+
*/
|
|
99
|
+
function createBucketSchema(indicators?: readonly string[]) {
|
|
100
|
+
if (!indicators || indicators.length === 0) {
|
|
101
|
+
return BaseBucketSchema;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const cacheKey = [...indicators].sort().join(",");
|
|
105
|
+
const cached = bucketSchemaCache.get(cacheKey);
|
|
106
|
+
if (cached) {
|
|
107
|
+
return cached;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Build a schema that requires each indicator to be a number
|
|
111
|
+
const indicatorSchema: Record<string, z.ZodNumber> = {};
|
|
112
|
+
for (const indicator of indicators) {
|
|
113
|
+
indicatorSchema[indicator] = z.number();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const schema = BaseBucketSchema.extend(indicatorSchema);
|
|
117
|
+
bucketSchemaCache.set(cacheKey, schema);
|
|
118
|
+
return schema;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Typed facet result with bucket array.
|
|
123
|
+
* @template TBucket - The bucket type for this facet
|
|
124
|
+
*/
|
|
125
|
+
export interface TypedFacetResult<TBucket extends BaseBucket = BaseBucket> {
|
|
126
|
+
readonly field: string;
|
|
127
|
+
readonly buckets: readonly TBucket[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Entity data result with array and total count.
|
|
132
|
+
* @template T - The entity type
|
|
133
|
+
*/
|
|
134
|
+
export interface EntityResult<T> {
|
|
135
|
+
readonly data: readonly T[];
|
|
136
|
+
readonly totalCount: number;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Combined result for queries with facets and/or entities.
|
|
141
|
+
* @template T - The entity type
|
|
142
|
+
* @template TFacets - Record of facet field names to their typed results
|
|
143
|
+
*/
|
|
144
|
+
export interface FacetQueryResult<
|
|
145
|
+
T,
|
|
146
|
+
TFacets extends Record<string, TypedFacetResult> = Record<string, TypedFacetResult>,
|
|
147
|
+
> {
|
|
148
|
+
readonly entities?: EntityResult<T>;
|
|
149
|
+
readonly facets: TFacets;
|
|
150
|
+
/** Raw API response. Optional to avoid doubling memory for large responses. */
|
|
151
|
+
readonly _raw?: Record<string, unknown>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Options for parsing facet responses.
|
|
156
|
+
*/
|
|
157
|
+
export interface ParseFacetOptions {
|
|
158
|
+
/**
|
|
159
|
+
* Whether to include the raw API response in the result.
|
|
160
|
+
* Set to false to avoid doubling memory usage for large responses.
|
|
161
|
+
* @default true
|
|
162
|
+
*/
|
|
163
|
+
readonly includeRaw?: boolean;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Parses a Dimensions API response into typed facet results.
|
|
168
|
+
* Extracts entity data and facet buckets from the response.
|
|
169
|
+
*
|
|
170
|
+
* @template T - The entity type
|
|
171
|
+
* @template TFacets - Record of facet field names to their typed results
|
|
172
|
+
* @param response - Raw API response object
|
|
173
|
+
* @param entityKey - The entity type key (e.g., "publications")
|
|
174
|
+
* @param facetFields - Array of facet field names or record of field configs
|
|
175
|
+
* @param options - Optional parsing configuration
|
|
176
|
+
* @returns Typed result with entities and facets
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* // Simple facets (field names only)
|
|
181
|
+
* const result = parseFacetResponse<Publication>(
|
|
182
|
+
* response,
|
|
183
|
+
* "publications",
|
|
184
|
+
* ["year", "type"]
|
|
185
|
+
* );
|
|
186
|
+
*
|
|
187
|
+
* // Aggregated facets (with indicator validation)
|
|
188
|
+
* const result = parseFacetResponse<Publication>(
|
|
189
|
+
* response,
|
|
190
|
+
* "publications",
|
|
191
|
+
* {
|
|
192
|
+
* year: {},
|
|
193
|
+
* funders: { indicators: ["rcr_avg", "citations_avg"] }
|
|
194
|
+
* }
|
|
195
|
+
* );
|
|
196
|
+
*
|
|
197
|
+
* // Exclude raw response to save memory
|
|
198
|
+
* const result = parseFacetResponse<Publication>(
|
|
199
|
+
* response,
|
|
200
|
+
* "publications",
|
|
201
|
+
* ["year"],
|
|
202
|
+
* { includeRaw: false }
|
|
203
|
+
* );
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
export function parseFacetResponse<
|
|
207
|
+
T,
|
|
208
|
+
TFacets extends Record<string, TypedFacetResult> = Record<string, TypedFacetResult>,
|
|
209
|
+
>(
|
|
210
|
+
response: Record<string, unknown>,
|
|
211
|
+
entityKey: string,
|
|
212
|
+
facetFields: readonly string[] | Record<string, FacetFieldConfig>,
|
|
213
|
+
options: ParseFacetOptions = {},
|
|
214
|
+
): FacetQueryResult<T, TFacets> {
|
|
215
|
+
const { includeRaw = true } = options;
|
|
216
|
+
const facets: Record<string, TypedFacetResult> = {};
|
|
217
|
+
|
|
218
|
+
// Normalize facetFields to a record
|
|
219
|
+
const facetConfigs: Record<string, FacetFieldConfig> = Array.isArray(facetFields)
|
|
220
|
+
? Object.fromEntries(facetFields.map((f) => [f, {}]))
|
|
221
|
+
: facetFields;
|
|
222
|
+
|
|
223
|
+
// Parse and validate entity data if present
|
|
224
|
+
let entities: EntityResult<T> | undefined;
|
|
225
|
+
if (response[entityKey] !== undefined) {
|
|
226
|
+
if (!Array.isArray(response[entityKey])) {
|
|
227
|
+
throw new ValidationError(`Entity key "${entityKey}" must be an array`, {
|
|
228
|
+
entityKey,
|
|
229
|
+
actualType: typeof response[entityKey],
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const entityArray = response[entityKey] as T[];
|
|
234
|
+
if (entityArray.length > 0) {
|
|
235
|
+
const statsResult = StatsSchema.safeParse(response._stats);
|
|
236
|
+
if (!statsResult.success) {
|
|
237
|
+
throw new ValidationError("API response missing _stats.total_count for entity results", {
|
|
238
|
+
entityKey,
|
|
239
|
+
statsErrors: statsResult.error.issues,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
entities = {
|
|
243
|
+
data: entityArray,
|
|
244
|
+
totalCount: statsResult.data.total_count,
|
|
245
|
+
};
|
|
246
|
+
} else {
|
|
247
|
+
// Empty array - use 0 as totalCount
|
|
248
|
+
entities = {
|
|
249
|
+
data: entityArray,
|
|
250
|
+
totalCount: 0,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Parse and validate facet data
|
|
256
|
+
for (const [field, config] of Object.entries(facetConfigs)) {
|
|
257
|
+
const fieldData = response[field];
|
|
258
|
+
|
|
259
|
+
if (fieldData === undefined) {
|
|
260
|
+
throw new ValidationError(`Missing facet field "${field}" in API response`, {
|
|
261
|
+
requestedFields: Object.keys(facetConfigs),
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!Array.isArray(fieldData)) {
|
|
266
|
+
throw new ValidationError(`Facet field "${field}" must be an array`, {
|
|
267
|
+
field,
|
|
268
|
+
actualType: typeof fieldData,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Validate bucket structure (including indicators if specified)
|
|
273
|
+
const bucketSchema = createBucketSchema(config.indicators);
|
|
274
|
+
const parseResult = z.array(bucketSchema).safeParse(fieldData);
|
|
275
|
+
if (!parseResult.success) {
|
|
276
|
+
throw new ValidationError(`Invalid bucket data for facet "${field}"`, {
|
|
277
|
+
field,
|
|
278
|
+
indicators: config.indicators,
|
|
279
|
+
errors: parseResult.error.issues,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
facets[field] = {
|
|
284
|
+
field,
|
|
285
|
+
buckets: parseResult.data as BaseBucket[],
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const result: FacetQueryResult<T, TFacets> = {
|
|
290
|
+
entities,
|
|
291
|
+
facets: facets as TFacets,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
if (includeRaw) {
|
|
295
|
+
return { ...result, _raw: response };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disk cache helpers for describe schema responses.
|
|
3
|
+
* @module schema/cache
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
7
|
+
import { extractDescribeSchema } from "./extract.js";
|
|
8
|
+
import type { DescribeSchemaResponse } from "./types.js";
|
|
9
|
+
|
|
10
|
+
/** Default cache TTL: 24 hours. */
|
|
11
|
+
export const DEFAULT_SCHEMA_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
12
|
+
|
|
13
|
+
/** On-disk cache envelope with metadata. */
|
|
14
|
+
export type SchemaCacheEnvelope = {
|
|
15
|
+
readonly cachedAt: string;
|
|
16
|
+
readonly version?: string;
|
|
17
|
+
readonly schema: DescribeSchemaResponse;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Parsed cache entry with normalized timestamps. */
|
|
21
|
+
export type SchemaCacheEntry = {
|
|
22
|
+
readonly response: DescribeSchemaResponse;
|
|
23
|
+
readonly cachedAt: Date | undefined;
|
|
24
|
+
readonly version: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Returns whether a cache entry is within the configured TTL.
|
|
29
|
+
* @param cachedAt - When the cache was written
|
|
30
|
+
* @param ttlMs - Maximum cache age in milliseconds
|
|
31
|
+
* @returns True when the entry is still fresh
|
|
32
|
+
*/
|
|
33
|
+
export function isCacheFresh(cachedAt: Date | undefined, ttlMs: number): boolean {
|
|
34
|
+
if (cachedAt == null || !Number.isFinite(ttlMs) || ttlMs <= 0) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return Date.now() - cachedAt.getTime() < ttlMs;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Reads a schema cache file (envelope or legacy bare describe payload).
|
|
42
|
+
* @param cachePath - Path to JSON cache file
|
|
43
|
+
* @returns Parsed cache entry or undefined when missing/invalid
|
|
44
|
+
*/
|
|
45
|
+
export async function readSchemaCacheFile(
|
|
46
|
+
cachePath: string,
|
|
47
|
+
): Promise<SchemaCacheEntry | undefined> {
|
|
48
|
+
try {
|
|
49
|
+
const text = await readFile(cachePath, "utf8");
|
|
50
|
+
const parsed = JSON.parse(text) as unknown;
|
|
51
|
+
return parseCachePayload(parsed);
|
|
52
|
+
} catch {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Parses cache JSON as an envelope or legacy describe response.
|
|
59
|
+
* @param parsed - Parsed JSON value
|
|
60
|
+
* @returns Normalized cache entry
|
|
61
|
+
*/
|
|
62
|
+
export function parseCachePayload(parsed: unknown): SchemaCacheEntry | undefined {
|
|
63
|
+
if (typeof parsed !== "object" || parsed == null) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const record = parsed as Record<string, unknown>;
|
|
68
|
+
|
|
69
|
+
if ("schema" in record) {
|
|
70
|
+
try {
|
|
71
|
+
const response = extractDescribeSchema(record.schema);
|
|
72
|
+
const cachedAt = typeof record.cachedAt === "string" ? new Date(record.cachedAt) : undefined;
|
|
73
|
+
const version = typeof record.version === "string" ? record.version : undefined;
|
|
74
|
+
return { response, cachedAt, version };
|
|
75
|
+
} catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const response = extractDescribeSchema(parsed);
|
|
82
|
+
return { response, cachedAt: undefined, version: undefined };
|
|
83
|
+
} catch {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Writes describe schema to a cache file with metadata envelope.
|
|
90
|
+
* @param cachePath - Path to JSON cache file
|
|
91
|
+
* @param response - Schema response to persist
|
|
92
|
+
* @param version - Optional DSL version
|
|
93
|
+
*/
|
|
94
|
+
export async function writeSchemaCacheFile(
|
|
95
|
+
cachePath: string,
|
|
96
|
+
response: DescribeSchemaResponse,
|
|
97
|
+
version?: string,
|
|
98
|
+
): Promise<void> {
|
|
99
|
+
const envelope: SchemaCacheEnvelope = {
|
|
100
|
+
cachedAt: new Date().toISOString(),
|
|
101
|
+
...(version != null ? { version } : {}),
|
|
102
|
+
schema: response,
|
|
103
|
+
};
|
|
104
|
+
await writeFile(cachePath, JSON.stringify(envelope), "utf8");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Resolves cache TTL from options or environment.
|
|
109
|
+
* @param overrideMs - Explicit TTL from caller
|
|
110
|
+
* @returns TTL in milliseconds
|
|
111
|
+
*/
|
|
112
|
+
export function resolveCacheTtlMs(overrideMs?: number): number {
|
|
113
|
+
if (overrideMs != null && Number.isFinite(overrideMs) && overrideMs > 0) {
|
|
114
|
+
return overrideMs;
|
|
115
|
+
}
|
|
116
|
+
const raw = process.env.SCHEMA_CACHE_TTL_MS;
|
|
117
|
+
if (raw != null && raw.trim() !== "") {
|
|
118
|
+
const value = Number.parseInt(raw, 10);
|
|
119
|
+
if (Number.isFinite(value) && value > 0) {
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return DEFAULT_SCHEMA_CACHE_TTL_MS;
|
|
124
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes raw `describe` API responses.
|
|
3
|
+
* @module schema/extract
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DescribeSchemaResponse, DescribeVersionResponse } from "./types.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extracts describe schema payload from a raw API response.
|
|
10
|
+
* @param raw - Raw DSL API response
|
|
11
|
+
* @returns Normalized describe schema object
|
|
12
|
+
*/
|
|
13
|
+
export function extractDescribeSchema(raw: unknown): DescribeSchemaResponse {
|
|
14
|
+
if (typeof raw !== "object" || raw === null) {
|
|
15
|
+
throw new Error("Invalid describe schema response: expected object");
|
|
16
|
+
}
|
|
17
|
+
const record = raw as Record<string, unknown>;
|
|
18
|
+
if ("sources" in record || "entities" in record) {
|
|
19
|
+
return {
|
|
20
|
+
sources: (record.sources as DescribeSchemaResponse["sources"]) ?? {},
|
|
21
|
+
entities: (record.entities as DescribeSchemaResponse["entities"]) ?? {},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
throw new Error("Invalid describe schema response: missing sources/entities");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Extracts version string from `describe version` response.
|
|
29
|
+
* @param raw - Raw DSL API response
|
|
30
|
+
* @returns Version string or undefined
|
|
31
|
+
*/
|
|
32
|
+
export function extractDescribeVersion(raw: unknown): string | undefined {
|
|
33
|
+
if (typeof raw !== "object" || raw === null) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const record = raw as DescribeVersionResponse & Record<string, unknown>;
|
|
37
|
+
if (typeof record.version === "string") {
|
|
38
|
+
return record.version;
|
|
39
|
+
}
|
|
40
|
+
if (typeof record.release === "string") {
|
|
41
|
+
return record.release;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime schema from `describe schema` / `describe version`.
|
|
3
|
+
* @module schema
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
DEFAULT_SCHEMA_CACHE_TTL_MS,
|
|
8
|
+
isCacheFresh,
|
|
9
|
+
parseCachePayload,
|
|
10
|
+
type SchemaCacheEntry,
|
|
11
|
+
type SchemaCacheEnvelope,
|
|
12
|
+
} from "./cache.js";
|
|
13
|
+
export { extractDescribeSchema, extractDescribeVersion } from "./extract.js";
|
|
14
|
+
export {
|
|
15
|
+
clearSchemaCache,
|
|
16
|
+
getCachedSchemaStore,
|
|
17
|
+
getOrLoadSchema,
|
|
18
|
+
type LoadSchemaOptions,
|
|
19
|
+
loadSchema,
|
|
20
|
+
} from "./load.js";
|
|
21
|
+
export {
|
|
22
|
+
createSchemaStoreFromResponse,
|
|
23
|
+
SCHEMA_LIMITS,
|
|
24
|
+
type SchemaLoadSource,
|
|
25
|
+
SchemaStore,
|
|
26
|
+
type SchemaStoreMetadata,
|
|
27
|
+
} from "./store.js";
|
|
28
|
+
export {
|
|
29
|
+
STRUCTURED_ENTITY_TYPES,
|
|
30
|
+
type StructuredEntityType,
|
|
31
|
+
searchResultKey,
|
|
32
|
+
searchToolName,
|
|
33
|
+
} from "./structured-entities.js";
|
|
34
|
+
export {
|
|
35
|
+
buildSchemaSummary,
|
|
36
|
+
SCHEMA_RESOURCE_URIS,
|
|
37
|
+
type SchemaSourceSummary,
|
|
38
|
+
type SchemaSummary,
|
|
39
|
+
} from "./summary.js";
|
|
40
|
+
export type {
|
|
41
|
+
DescribeField,
|
|
42
|
+
DescribeSchemaResponse,
|
|
43
|
+
DescribeVersionResponse,
|
|
44
|
+
EntityDescribe,
|
|
45
|
+
SourceDescribe,
|
|
46
|
+
} from "./types.js";
|
|
47
|
+
export {
|
|
48
|
+
assertValidEntity,
|
|
49
|
+
assertValidSearchIndex,
|
|
50
|
+
} from "./validation.js";
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load schema from the Dimensions API or optional disk cache.
|
|
3
|
+
* @module schema/load
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DimensionsClient } from "../client.js";
|
|
7
|
+
import {
|
|
8
|
+
isCacheFresh,
|
|
9
|
+
readSchemaCacheFile,
|
|
10
|
+
resolveCacheTtlMs,
|
|
11
|
+
writeSchemaCacheFile,
|
|
12
|
+
} from "./cache.js";
|
|
13
|
+
import { extractDescribeSchema, extractDescribeVersion } from "./extract.js";
|
|
14
|
+
import { createSchemaStoreFromResponse, type SchemaStore } from "./store.js";
|
|
15
|
+
|
|
16
|
+
let moduleCache: SchemaStore | undefined;
|
|
17
|
+
let moduleLoadPromise: Promise<SchemaStore> | undefined;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns the module-level cached schema store, if loaded.
|
|
21
|
+
* @returns Cached store or undefined before first load
|
|
22
|
+
*/
|
|
23
|
+
export function getCachedSchemaStore(): SchemaStore | undefined {
|
|
24
|
+
return moduleCache;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Clears the module-level schema cache (for tests and refresh).
|
|
29
|
+
*/
|
|
30
|
+
export function clearSchemaCache(): void {
|
|
31
|
+
moduleCache = undefined;
|
|
32
|
+
moduleLoadPromise = undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type LoadSchemaOptions = {
|
|
36
|
+
/** Optional cache file path (defaults to `SCHEMA_CACHE_PATH` env) */
|
|
37
|
+
cachePath?: string;
|
|
38
|
+
/** Cache TTL in milliseconds (defaults to `SCHEMA_CACHE_TTL_MS` env or 24h) */
|
|
39
|
+
cacheTtlMs?: number;
|
|
40
|
+
/** Skip fresh cache and fetch from the API (stale fallback still applies on failure) */
|
|
41
|
+
forceRefresh?: boolean;
|
|
42
|
+
/** Log load stats to stderr (default true) */
|
|
43
|
+
log?: boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Fetches schema from the Dimensions API, with TTL-aware cache and stale fallback.
|
|
48
|
+
* @param client - Authenticated Dimensions client
|
|
49
|
+
* @param options - Cache path, TTL, and logging options
|
|
50
|
+
* @returns Loaded schema store
|
|
51
|
+
*/
|
|
52
|
+
export async function loadSchema(
|
|
53
|
+
client: DimensionsClient,
|
|
54
|
+
options?: LoadSchemaOptions | string,
|
|
55
|
+
): Promise<SchemaStore> {
|
|
56
|
+
const resolved =
|
|
57
|
+
typeof options === "string" ? { cachePath: options, log: true as const } : (options ?? {});
|
|
58
|
+
const cachePath = resolved.cachePath ?? process.env.SCHEMA_CACHE_PATH;
|
|
59
|
+
const log = resolved.log ?? true;
|
|
60
|
+
const cacheTtlMs = resolveCacheTtlMs(resolved.cacheTtlMs);
|
|
61
|
+
const forceRefresh = resolved.forceRefresh ?? false;
|
|
62
|
+
|
|
63
|
+
const cached = cachePath ? await readSchemaCacheFile(cachePath) : undefined;
|
|
64
|
+
const cacheFresh = cached != null && isCacheFresh(cached.cachedAt, cacheTtlMs);
|
|
65
|
+
|
|
66
|
+
if (!forceRefresh && cacheFresh && cached) {
|
|
67
|
+
const store = createSchemaStoreFromResponse(cached.response, cached.version, new Date(), {
|
|
68
|
+
loadSource: "cache",
|
|
69
|
+
stale: false,
|
|
70
|
+
cachedAt: cached.cachedAt,
|
|
71
|
+
});
|
|
72
|
+
moduleCache = store;
|
|
73
|
+
if (log) {
|
|
74
|
+
logSchemaLoaded(store, "cache (fresh)");
|
|
75
|
+
}
|
|
76
|
+
return store;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const started = performance.now();
|
|
81
|
+
const [schemaRaw, versionRaw] = await Promise.all([
|
|
82
|
+
client.rawQuery("describe schema"),
|
|
83
|
+
client.rawQuery("describe version").catch(() => undefined),
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
const response = extractDescribeSchema(schemaRaw);
|
|
87
|
+
const version = versionRaw ? extractDescribeVersion(versionRaw) : undefined;
|
|
88
|
+
|
|
89
|
+
if (cachePath) {
|
|
90
|
+
await writeSchemaCacheFile(cachePath, response, version);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const store = createSchemaStoreFromResponse(response, version, new Date(), {
|
|
94
|
+
loadSource: "api",
|
|
95
|
+
stale: false,
|
|
96
|
+
});
|
|
97
|
+
moduleCache = store;
|
|
98
|
+
if (log) {
|
|
99
|
+
const elapsed = Math.round(performance.now() - started);
|
|
100
|
+
logSchemaLoaded(store, `api (${elapsed}ms)`);
|
|
101
|
+
}
|
|
102
|
+
return store;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (cached) {
|
|
105
|
+
const store = createSchemaStoreFromResponse(cached.response, cached.version, new Date(), {
|
|
106
|
+
loadSource: "cache",
|
|
107
|
+
stale: true,
|
|
108
|
+
cachedAt: cached.cachedAt,
|
|
109
|
+
});
|
|
110
|
+
moduleCache = store;
|
|
111
|
+
if (log) {
|
|
112
|
+
const age =
|
|
113
|
+
cached.cachedAt != null
|
|
114
|
+
? `${Math.round((Date.now() - cached.cachedAt.getTime()) / 60_000)}m old`
|
|
115
|
+
: "legacy cache";
|
|
116
|
+
console.error(
|
|
117
|
+
`[schema] API unavailable; using stale cache (${age}). ` +
|
|
118
|
+
`Call refresh_schema when the API is reachable.`,
|
|
119
|
+
);
|
|
120
|
+
logSchemaLoaded(store, "cache (stale fallback)");
|
|
121
|
+
}
|
|
122
|
+
return store;
|
|
123
|
+
}
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Returns cached schema or loads once per process.
|
|
130
|
+
* @param client - Authenticated Dimensions client
|
|
131
|
+
* @param options - Cache path and logging options
|
|
132
|
+
* @returns Schema store
|
|
133
|
+
*/
|
|
134
|
+
export async function getOrLoadSchema(
|
|
135
|
+
client: DimensionsClient,
|
|
136
|
+
options?: LoadSchemaOptions | string,
|
|
137
|
+
): Promise<SchemaStore> {
|
|
138
|
+
if (moduleCache) {
|
|
139
|
+
return moduleCache;
|
|
140
|
+
}
|
|
141
|
+
if (!moduleLoadPromise) {
|
|
142
|
+
moduleLoadPromise = loadSchema(client, options).finally(() => {
|
|
143
|
+
moduleLoadPromise = undefined;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return moduleLoadPromise;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function logSchemaLoaded(store: SchemaStore, via: string): void {
|
|
150
|
+
const stats = store.stats();
|
|
151
|
+
const flags = [via, store.stale ? "stale" : undefined].filter(Boolean).join(", ");
|
|
152
|
+
console.error(
|
|
153
|
+
`[schema] loaded ${stats.sourceCount} sources, ${stats.entityCount} entities` +
|
|
154
|
+
(stats.dslVersion ? ` (DSL ${stats.dslVersion})` : "") +
|
|
155
|
+
` [${flags}]`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Re-export extract helpers for backward compatibility
|
|
160
|
+
export { extractDescribeSchema, extractDescribeVersion } from "./extract.js";
|