GithubHelp home page GithubHelp logo

apollographql / apollo-utils Goto Github PK

View Code? Open in Web Editor NEW
32.0 32.0 10.0 1.94 MB

Monorepo of common utilities related to Apollo and GraphQL

License: MIT License

TypeScript 97.67% JavaScript 2.33%

apollo-utils's People

Contributors

apollo-bot2 avatar dependabot[bot] avatar github-actions[bot] avatar glasser avatar hishamali81 avatar hoonoh avatar ivangoncharov avatar jerelmiller avatar peakematt avatar renovate-bot avatar renovate[bot] avatar rportugal avatar simenb avatar svc-secops avatar trevor-scheer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apollo-utils's Issues

Package READMEs

Introduce READMEs for each package

Update directory in package.json files, maybe that fixes the reference / homepage link on npmjs website.

[keyvaluecache] Cannot use 'in' operator to search for 'Symbol(prefixesAreUnnecessaryForIsolation)' in bounded

Hi,
in the last version of @apollo/utils.keyvaluecache package there is this line return prefixesAreUnnecessaryForIsolationSymbol in c; which breaks our apollo server instance (tested on node v16 and v18).

It throws this error:

TypeError: Cannot use 'in' operator to search for 'Symbol(prefixesAreUnnecessaryForIsolation)' in bounded
    at Function.prefixesAreUnnecessaryForIsolation (/app/node_modules/@apollo/server/node_modules/@apollo/utils.keyvaluecache/dist/PrefixingKeyValueCache.js:27:57)
    at new PrefixingKeyValueCache (/app/node_modules/@apollo/server/node_modules/@apollo/utils.keyvaluecache/dist/PrefixingKeyValueCache.js:9:36)
    at new ApolloServer (/app/node_modules/@apollo/server/dist/cjs/ApolloServer.js:110:28)

I was testing it on @apollo/server version 4.2.1 which creates object PrefixingKeyValueCache like this:

new utils_keyvaluecache_1.PrefixingKeyValueCache(config.persistedQueries?.cache ?? this.cache, requestPipeline_js_1.APQ_CACHE_PREFIX),

With these params:

console.log(
  config.persistedQueries?.cache, // undefined
  this.cache, //  bounded
  requestPipeline_js_1.APQ_CACHE_PREFIX //  apq:
); 

Where constructor on line 22:

if (PrefixingKeyValueCache.prefixesAreUnnecessaryForIsolation(wrapped)) {

Uses mentioned function prefixesAreUnnecessaryForIsolation called with "bounded" string in params which turns into faulty code Symbol(prefixesAreUnnecessaryForIsolation) in "bounded".

Is it a problem of @apollo/server or of @apollo/utils.keyvaluecache? With previous version of utils.keyvaluecache (v2.0.1) everything worked fine.

Granular backcompat testing

This repo expects graphql@14+ support for all packages. This isn't intentional, just a matter of simplicity in implementation. At some point, we'll likely want to allow packages to specify whether or not they should be tested for graphql backcompat and against which versions.

Redis KeyvAdapter DataLoader throws TypeError because the result is undefined

When using the Redis Keyv and if the Redis client is unable to connect to the Redis cluster, the keyv.get() function will returned undefined.

This in turn would cause the DataLoader used by the KeyvAdapter to throw the following error since returning undefined violates the DataLoader contract:

DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: undefined.

Would suggest changing the following KeyvAdapter code to better handle this error scenario:

this.dataLoader = options?.disableBatchReads
      ? undefined
      : new DataLoader(
          (keys) => this.keyv.get([...keys]),
          // We're not actually using `DataLoader` for its caching
          // capabilities, we're only interested in batching functionality
          { cache: false },
        );

For example, to something like this:

this.dataLoader = options?.disableBatchReads
      ? undefined
      : new DataLoader(
          async (keys) => (await this.keyv.get([...keys])) ?? keys.map(() => null),
          // We're not actually using `DataLoader` for its caching
          // capabilities, we're only interested in batching functionality
          { cache: false },
        );

I haven't tested this with other Keyv implementations so this issue exist with other caches besides Redis. I've also only noticed this issue occurring when Redis can't connect to the cluster, but could possible occur for other type of Redis errors as well.

Provide esm version

With more and more build tools (vite, nuxt, etc) going towards an esm-first build, it would be nice if a proper esm interface could be provided, i.e. transpile and distribute esm version, including correct export declaration in package.json.

[KeyvAdapter] Allow return "undefined" when cache backend is unavailable

I am using @apollo/utils.keyvadapter to implement redis cache backend. The adapter makes redis or other cache backend a hard dependency. This means when the apollo server lost connection to redis server, any incoming requests will fail. It would be good to allow the redis client to retry connection. At the same time, any queries with cache control should still function by bypassing cache.

Meanwhile, I use the following code to achieve the goal.

class BetterKeyvAdapter extends KeyvAdapter {
  // this will allow the query to bypass the cache if cache backend is not available
  async get(key) {
    try {
      return await super.get(key);
    } catch (e) {
      return undefined;
    }
  }
}

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Repository problems

These problems occurred while renovating this repository. View logs.

  • WARN: Using npm packages for Renovate presets is now deprecated. Please migrate to repository-based presets instead.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

npm
package.json
  • @apollo/client 3.8.9
  • @changesets/changelog-github 0.5.0
  • @changesets/cli 2.27.1
  • @jest/types 29.6.3
  • @types/bunyan 1.8.11
  • @types/glob 8.1.0
  • @types/jest 29.5.11
  • @types/lodash.sortby 4.7.9
  • @types/make-fetch-happen 10.0.4
  • @types/node 16.18.70
  • @types/node-fetch 2.6.10
  • @typescript-eslint/eslint-plugin 6.18.1
  • @typescript-eslint/parser 6.18.1
  • bunyan 1.8.15
  • crypto-hash 1.3.0
  • eslint 8.56.0
  • graphql 16.8.1
  • graphql-tag 2.12.6
  • jest 29.7.0
  • jest-junit 16.0.0
  • log4js 6.9.1
  • loglevel 1.8.1
  • make-fetch-happen 13.0.0
  • node-fetch 2.7.0
  • prettier 3.2.2
  • prettier-2 2.8.8
  • ts-expect 1.3.0
  • ts-jest 29.1.1
  • ts-node 10.9.2
  • typescript 5.3.3
  • undici 5.28.2
  • winston 3.11.0
  • winston-transport 4.6.0
  • node >=16
  • npm >=8
  • node 20.11.0
  • npm 10.3.0
packages/createHash/package.json
  • sha.js ^2.4.11
  • node >=16
packages/dropUnusedDefinitions/package.json
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/fetcher/package.json
  • node >=16
packages/generate-persisted-query-manifest/package.json
  • @graphql-tools/graphql-tag-pluck ^8.0.0
  • chalk ^4.1.2
  • commander ^11.0.0
  • cosmiconfig ^8.1.3
  • cosmiconfig-typescript-loader ^5.0.0
  • globby ^11.1.0
  • lodash ^4.17.21
  • vfile ^4.2.1
  • vfile-reporter ^6.0.2
  • @gmrchk/cli-testing-library 0.1.2
  • @wry/equality 0.5.7
  • @apollo/client ^3.7.0 || ^3.8.0-alpha
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/isNodeLike/package.json
  • node >=16
packages/jestGraphQLASTSerializer/package.json
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/keyValueCache/package.json
  • lru-cache ^10.0.0
  • node >=16.14
packages/keyvAdapter/package.json
  • dataloader ^2.1.0
  • keyv ^4.4.0
  • node >=16
packages/logger/package.json
  • node >=16
packages/operationRegistrySignature/package.json
  • node >=16
packages/persisted-query-lists/package.json
  • @apollo/client ^3.2.0 || ^3.8.0-alpha
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/printWithReducedWhitespace/package.json
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/removeAliases/package.json
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/sortAST/package.json
  • lodash.sortby ^4.7.0
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/stripSensitiveLiterals/package.json
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/usageReporting/package.json
  • @apollo/usage-reporting-protobuf ^4.1.0
  • graphql 14.x || 15.x || 16.x
  • node >=16
packages/withRequired/package.json
  • node >=16

  • Check this box to trigger a request for Renovate to run again on this repository

Add esm info to utils.withrequired

Trying to build a project using utils.withrequired with rollup fails:

Error building /workspaces/apollo-server-integration-h3: SyntaxError: Unexpected token (1:7) in /workspaces/apollo-server-integration-h3/node_modules/.pnpm/@[email protected]/node_modules/@apollo/utils.withrequired/dist/index.d.ts
SyntaxError: Unexpected token (1:7) in /workspaces/apollo-server-integration-h3/node_modules/.pnpm/@[email protected]/node_modules/@apollo/utils.withrequired/dist/index.d.ts
    at pp$4.raise (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:19420:13)
    at pp$9.unexpected (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:16714:8)
    at pp$9.expect (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:16708:26)
    at pp$8.parseExportSpecifiers (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:17729:8)
    at pp$8.parseExport (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:17644:28)
    at pp$8.parseStatement (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:16890:74)
    at pp$8.parseTopLevel (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:16771:21)
    at Parser.parse (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:16543:15)
    at Function.parse (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:16593:35)
    at Graph.contextParse (file:///workspaces/apollo-server-integration-h3/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:22959:38) {
  pos: 7,
  loc: {
    column: 7,
    file: '/workspaces/apollo-server-integration-h3/node_modules/.pnpm/@[email protected]/node_modules/@apollo/utils.withrequired/dist/index.d.ts',
    line: 1
  },
  raisedAt: 14,
  frame: '1: export declare type WithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;\n' +
    '          ^\n' +
    '2: //# sourceMappingURL=index.d.ts.map',
  id: '/workspaces/apollo-server-integration-h3/node_modules/.pnpm/@[email protected]/node_modules/@apollo/utils.withrequired/dist/index.d.ts',
  hook: 'resolveId',
  code: 'PLUGIN_ERROR',
  plugin: 'commonjs--resolver',
  watchFiles: [
    '/workspaces/apollo-server-integration-h3/src/index.ts',
    '/workspaces/apollo-server-integration-h3/node_modules/.pnpm/@[email protected]/node_modules/@apollo/utils.withrequired/dist/index.d.ts'
  ]
}

I think the issue is that the package doesn't specify a) the type and b) its exports (which should be empty mjs and cjs files).

Support FetcherRequestInit.signal

The official RequestInit supports a signal?: AbortSignal property to allow aborting a request https://fetch.spec.whatwg.org/#requestinit. I tried a few options to add it to our custom FetcherRequestInit, but ran into snags (details below).

Any suggestions on any of these attempts (I think the errors can be worked around, but each has tradeoffs), or other ways we might solve this?

Add DOM to tsconfig.base.json's lib

node-fetch@2 doesn't support the interface completely

packages/fetcher/src/__tests__/index.test.ts:10:14 - error TS2345: Argument of type 'typeof fetch' is not assignable to parameter of type 'Fetcher'.
    Types of parameters 'init' and 'init' are incompatible.
    Type 'FetcherRequestInit | undefined' is not assignable to type 'RequestInit | undefined'.
        Type 'FetcherRequestInit' is not assignable to type 'RequestInit'.
        The types of 'signal.addEventListener' are incompatible between these types.
            Type '{ <K extends "abort">(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | ... 1 more ... | undefined): void; }' is not assignable to type '(type: "abort", listener: (this: AbortSignal, event: any) => any, options?: boolean | { capture?: boolean | undefined; once?: boolean | undefined; passive?: boolean | undefined; } | undefined) => void'.
            Types of parameters 'options' and 'options' are incompatible.
                Type 'boolean | { capture?: boolean | undefined; once?: boolean | undefined; passive?: boolean | undefined; } | undefined' is not assignable to type 'boolean | AddEventListenerOptions | undefined'.
                Type '{ capture?: boolean | undefined; once?: boolean | undefined; passive?: boolean | undefined; }' is not assignable to type 'boolean | AddEventListenerOptions | undefined'.
                    Type '{ capture?: boolean | undefined; once?: boolean | undefined; passive?: boolean | undefined; }' is not assignable to type 'AddEventListenerOptions' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
                    Types of property 'once' are incompatible.
                        Type 'boolean | undefined' is not assignable to type 'boolean'.
                        Type 'undefined' is not assignable to type 'boolean'.

10   isAFetcher(nodeFetch);

Upgrade to node-fetch@3

Attempting to update to node-fetch@3 causes the make-fetch-happen test to fail

packages/fetcher/src/__tests__/index.test.ts:14:14 - error TS2345: Argument of type 'FetchInterface' is not assignable to parameter of type 'Fetcher'.
    Types of parameters 'opts' and 'init' are incompatible.
    Type 'FetcherRequestInit | undefined' is not assignable to type 'FetchOptions | undefined'.
        Type 'FetcherRequestInit' is not assignable to type 'FetchOptions' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
        Property 'timeout' is missing in type 'FetcherRequestInit' but required in type 'NodeFetchOptions'.

14   isAFetcher(makeFetchHappen);

Copy-pasta defs for AbortSignal

I also tried copy-pasta'ing AbortSignal from the typescript defs but that's a whole lotta extra stuff we have to bring along (also need to make modifications to support aforementioned node-fetch error). Using the node-fetch type defs doesn't work (incompatibility with undici). the undici type defs assume a DOM-compatible global.

[KeyvAdapter] The Array of values must be the same length as the Array of keys

We have this error when the queries are not yet cached: DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.

const server = new ApolloServer({
  ...,
  cache: new KeyvAdapter(new Keyv(process.env.CACHE_REDIS_URL)),
}

See https://github.com/apollographql/apollo-utils/blob/main/packages/keyvAdapter/src/index.ts#L27
As mentioned in the DataLoader documentation, the Array of values must be the same length as the Array of keys. And it seems this.keyv.get does not ensure that. We should probably ensure that in the KeyvAdapter.

Workaround: set disableBatchReads to true

Error: All sentinels are unreachable. Retrying from scratch after 10ms ....but crashes

I have a load balanced redis sentinels running in kuberenetes, however every hour I get this error below and this "warning" is causing my application to crash. I am still investigating, why this code thinks they are unavailable (which they aren't), but is there a way to catch this application as it looks like ioredis wants to retry in 10ms.

const redis = new Redis({
sentinels: [{ host: process.env.REDIS_HOST, port: 26379 }],
name: 'mymaster',
});
const keyvRedis = new KeyvRedis(redis);
cache = new KeyvAdapter(new Keyv({ store: keyvRedis }));

/node_modules/standard-as-callback/built/index.js:6
        throw e;
Error: All sentinels are unreachable. Retrying from scratch after 10ms.
    at SentinelConnector.<anonymous> (/node_modules/ioredis/built/connectors/SentinelConnector/index.js:73:31)
    at Generator.next (<anonymous>)
    at /node_modules/ioredis/built/connectors/SentinelConnector/index.js:8:71
    at new Promise (<anonymous>)
    at __awaiter (/node_modules/ioredis/built/connectors/SentinelConnector/index.js:4:12)
    at connectToNext (/node_modules/ioredis/built/connectors/SentinelConnector/index.js:59:37)
    at SentinelConnector.connect (/node_modules/ioredis/built/connectors/SentinelConnector/index.js:128:16)
    at /node_modules/ioredis/built/redis/index.js:292:55
    at new Promise (<anonymous>)
    at Redis.connect (/node_modules/ioredis/built/redis/index.js:265:21)
Emitted 'error' event on Keyv instance at:
    at KeyvRedis.<anonymous> (/node_modules/keyv/src/index.js:61:46)
    at KeyvRedis.emit (node:events:390:28)
    at Redis.<anonymous> (/node_modules/@keyv/redis/src/index.js:18:40)
    at Redis.emit (node:events:390:28)
    at Redis.silentEmit (/node_modules/ioredis/built/redis/index.js:553:26)
    at /node_modules/ioredis/built/redis/index.js:297:23
    at tryCatcher (/node_modules/standard-as-callback/built/utils.js:12:23)
    at /node_modules/standard-as-callback/built/index.js:33:51
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    ```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.