The most powerful headless CMS for Node.js β€” built with GraphQL and React

Overview


A scalable platform and CMS to build Node.js applications.

schema => ({ GraphQL, AdminUI })


Keystone Next is a preview of the next major release of KeystoneJS, the most powerful headless content management system around.

Looking for Keystone 5? Head over to keystone-5.

Contents

What's new?

Keystone Next is a preview of the next major release of KeystoneJS, the most powerful headless content management system around. We've substantially rewritten the CLI, Schema config, and Admin UI to make them more powerful and easier to use than ever before.

To learn more, check out our What's next for KeystoneJS announcement post.

You can learn more about the next version, which is now in preview.

Keystone 5

The Keystone 5 codebase is now in active maintenance mode and now lives at keystonejs/keystone-5.

For more information please read our Keystone 5 and beyond post.

Documentation

The Keystone Next website contains a documentation preview.

In the next month you'll see a new project starter and getting started guide, as well as a new set of example projects demoing how to use Keystone Next features.

Feedback

We'd love to hear your feedback, reach out on Twitter at KeystoneJS and subscribe to be notified of our progress.

Code of Conduct

KeystoneJS adheres to the Contributor Covenant Code of Conduct.

License

Copyright (c) 2021 Thinkmill Labs Pty Ltd. Licensed under the MIT License.

Comments
  • Warning log: validateDOMNesting(...): <head> cannot appear as a child of <div>

    Warning log: validateDOMNesting(...): cannot appear as a child of

    1. Create a keystone app and run npm run dev (same as keystone dev)
    2. Open dev server on your browser
    3. Create a user and restart dev server
    4. Open browser again and refresh
    5. Open devtools and head to console tab
    6. Warning with an error log is shown

    No error

    Screenshot_20221231_164452

    Package.json

    {
      "name": "keystone-app",
      "version": "1.0.0",
      "private": true,
      "scripts": {
        "dev": "keystone dev",
        "start": "keystone start",
        "build": "keystone build",
        "postinstall": "keystone postinstall",
      },
      "dependencies": {
        "@keystone-6/auth": "^6.0.0",
        "@keystone-6/core": "^4.0.1",
        "@keystone-6/fields-document": "^6.0.0",
        "typescript": "^4.9.4"
      }
    }
    

    Error log

    next-dev.js?36dd:20 Warning: validateDOMNesting(...): <head> cannot appear as a child of <div>.
        at head
        at div
        at SigninContainer (webpack-internal:///../../node_modules/@keystone-6/auth/dist/useFromRedirect-048776a2.esm.js:17:5)
        at SigninPage (webpack-internal:///../../node_modules/@keystone-6/auth/pages/SigninPage/dist/keystone-6-auth-pages-SigninPage.esm.js:34:5)
        at ErrorBoundary (webpack-internal:///../../node_modules/@keystone-6/core/dist/Errors-f59723d8.esm.js:20:5)
        at DrawerProvider (webpack-internal:///../../node_modules/@keystone-ui/modals/dist/keystone-ui-modals.esm.js:54:5)
        at ToastProvider (webpack-internal:///../../node_modules/@keystone-ui/toast/dist/keystone-ui-toast.esm.js:41:5)
        at InternalKeystoneProvider (webpack-internal:///../../node_modules/@keystone-6/core/admin-ui/context/dist/keystone-6-core-admin-ui-context.esm.js:310:5)
        at ApolloProvider (webpack-internal:///../../node_modules/@apollo/client/react/context/ApolloProvider.js:12:21)
        at KeystoneProvider (webpack-internal:///../../node_modules/@keystone-6/core/admin-ui/context/dist/keystone-6-core-admin-ui-context.esm.js:356:14)
        at Core (webpack-internal:///../../node_modules/@keystone-ui/core/dist/keystone-ui-core.esm.js:1304:5)
        at eval (webpack-internal:///../../node_modules/@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/dist/keystone-6-core-___internal-do-not-use-will-break-in-patch-admin-ui-pages-App.esm.js:84:5)
        at PathnameContextProviderAdapter (webpack-internal:///../../node_modules/next/dist/shared/lib/router/adapters.js:62:11)
        at ErrorBoundary (webpack-internal:///../../node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:301:63)
        at ReactDevOverlay (webpack-internal:///../../node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:850:919)
        at Container (webpack-internal:///../../node_modules/next/dist/client/index.js:61:1)
        at AppContainer (webpack-internal:///../../node_modules/next/dist/client/index.js:171:11)
        at Root (webpack-internal:///../../node_modules/next/dist/client/index.js:346:11)
    
    opened by devmor-j 1
  • Dataloader error when querying to-one relationship to which there is no access

    Dataloader error when querying to-one relationship to which there is no access

    Steps to Reproduce

    1. Run 'blog' example and seed database (yarn dev --seed-data)
    2. Run keystone (yarn dev)
    3. Change 'Author' access to denyAll like https://github.com/marekryb/keystone/commit/29fcc9b6ba2bbd3a44b376ff47db9fef3e48c46b
    4. Run following query
    query {
      posts {
       author {
        name
       }
      }
    }
    
    1. Observe that the output (data) is correct, but for each item returned there is also following error
    {
      "errors": [
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            0,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
    
    Full output
    {
      "errors": [
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            0,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        },
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            1,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        },
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            2,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        },
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            3,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        },
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            4,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        },
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            5,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        },
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            6,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        },
        {
          "message": "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.\n\nKeys:\nclbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl\n\nValues:\n",
          "locations": [
            {
              "line": 3,
              "column": 5
            }
          ],
          "path": [
            "posts",
            7,
            "author"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "stacktrace": [
                "TypeError: 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.",
                "",
                "Keys:",
                "clbwzx1jo00028txkgnyek5yb,clbwzx1k300118txkkms5ey04,clbwzx1ki00208txksj6om4pm,clbwzx1ki00208txksj6om4pm,clbwzx1lf00318txk68x8t7kv,clbwzx1lf00318txk68x8t7kv,clbwzx1m100428txkotvccn9l,clbwzx1mg00518txk2jjpjhpl",
                "",
                "Values:",
                "",
                "    at /home/exar/os/my_keystone/node_modules/dataloader/index.js:294:13",
                "    at runMicrotasks (<anonymous>)",
                "    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
              ]
            }
          }
        }
      ],
      "data": {
        "posts": [
          {
            "author": null
          },
          {
            "author": null
          },
          {
            "author": null
          },
          {
            "author": null
          },
          {
            "author": null
          },
          {
            "author": null
          },
          {
            "author": null
          },
          {
            "author": null
          }
        ]
      }
    }
    

    Expected Behavior

    No errors are thrown

    Additional information

    • Issue does not happen if relation is to-many (many: true)
    • As a workaround, adding access restriction to relationship field like: author: relationship({ ref: 'Author.posts', many: false, access: denyAll }), makes the error go away. However such duplication of access restrictions seems 'no-no'.
    opened by marekryb 0
  • Cannot find module 'next/dist/shared/lib/constants.js'

    Cannot find module 'next/dist/shared/lib/constants.js'

    To reproduce, run Keystone inside a docker container in dev mode with the following Dockerfile:

    FROM node:14.21.1
    
    RUN npm install -g pnpm
    
    WORKDIR /backend
    
    COPY package.json pnpm-lock.yaml ./
    
    COPY . .
    
    RUN pnpm install --frozen-lockfile
    
    CMD [ "pnpm", "run", "dev" ]
    

    The app works without any issues locally, however when running it in Docker, the following error happens:

    Server Error
    Error: Cannot find module 'next/dist/shared/lib/constants.js'
    Require stack:
    - /backend/.keystone/admin/.next/server/pages/_document.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/dev/next-dev-server.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/dist/createAdminUIMiddleware-c41a0fb3.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/cli/dist/keystone-6-core-scripts-cli.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/bin/cli.js
    
    This error happened while generating the page. Any console logs will be displayed in the terminal window.
    Call Stack
    Function.Module._resolveFilename
    internal/modules/cjs/loader.js (902:15)
    Function.mod._resolveFilename
    file:///backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/build/webpack/require-hook.js (23:32)
    Function.Module._load
    internal/modules/cjs/loader.js (746:27)
    Module.require
    internal/modules/cjs/loader.js (974:19)
    require
    internal/modules/cjs/helpers.js (101:18)
    Object.../shared/lib/constants
    file:///backend/.keystone/admin/.next/server/pages/_document.js (82:18)
    __webpack_require__
    file:///backend/.keystone/admin/.next/server/webpack-runtime.js (33:42)
    require
    ../node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/pages/_document.js (9:17)
    Object.../../node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/pages/_document.js
    file:///backend/.keystone/admin/.next/server/pages/_document.js (22:1)
    __webpack_require__
    file:///backend/.keystone/admin/.next/server/webpack-runtime.js (33:42)
    __webpack_exec__
    file:///backend/.keystone/admin/.next/server/pages/_document.js (122:39)
    <unknown>
    file:///backend/.keystone/admin/.next/server/pages/_document.js (123:28)
    Object.<anonymous>
    file:///backend/.keystone/admin/.next/server/pages/_document.js (126:3)
    Module._compile
    internal/modules/cjs/loader.js (1085:14)
    Object.Module._extensions..js
    internal/modules/cjs/loader.js (1114:10)
    Module.load
    internal/modules/cjs/loader.js (950:32)
    Function.Module._load
    internal/modules/cjs/loader.js (790:12)
    Module.require
    internal/modules/cjs/loader.js (974:19)
    require
    internal/modules/cjs/helpers.js (101:18)
    Object.requirePage
    file:///backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js (88:12)
    <unknown>
    file:///backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/load-components.js (33:54)
    processTicksAndRejections
    internal/process/task_queues.js (95:5)
    async Object.loadComponents
    file:///backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/load-components.js (32:33)
    async DevServer.findPageComponents
    file:///backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js (561:36)
    

    I've tried deleting the .keystone directory as I figured it may have been a cache issue, it didn't resolve it. I haven't tried building the app and running it that way yet, and it would probably work. I just wanted to have it in docker to easily develop as i'll be having a frontend connected to this later.

    This is my package.json:

    {
      "name": "keystone-app",
      "version": "1.0.2",
      "private": true,
      "scripts": {
        "dev": "keystone dev",
        "start": "keystone start",
        "build": "keystone build",
        "postinstall": "keystone postinstall"
      },
      "dependencies": {
        "@aws-sdk/abort-controller": "^3.226.0",
        "@babel/core": "^7.20.5",
        "@keystone-6/auth": "^6.0.0",
        "@keystone-6/core": "^4.0.1",
        "@keystone-6/fields-document": "^6.0.0",
        "@prisma/client": "4.3.1",
        "@prisma/generator-helper": "^4.7.1",
        "body-parser": "1.20.1",
        "dotenv": "^16.0.3",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "typescript": "^4.8.0",
        "ws": "^8.11.0"
      },
      "devDependencies": {
        "@types/body-parser": "^1.19.2",
        "@types/node": "18.11.17",
        "@types/react": "18.0.26",
        "@types/ws": "^8.5.3",
        "prisma": "4.3.1"
      }
    }
    

    and this is my config:

    export default withAuth(
      config({
        db: {
          // we're using sqlite for the fastest startup experience
          //   for more information on what database might be appropriate for you
          //   see https://keystonejs.com/docs/guides/choosing-a-database#title
          provider: 'sqlite',
          url: databaseUrl,
        },
        lists,
        session,
        server: {
          port: serverPort(),
          extendExpressApp: (app, ctx) => {
            app.use(json( { limit: '50mb' } ));
            // rest stuff
            app.get("/api/users", async (req, res) => {
              const context = await ctx.withRequest(req, res);
              const users = await context.query.User.findMany({query: 'id name email posts { id title }'});
              res.json(users);
            });
            //other endpoints for crud
          },
        },
        graphql: {
          path: '/graphql',
          playground: true,
          apolloConfig: {
            introspection: true,
            allowBatchedHttpRequests: true,
          },
        },
      })
    );
    

    Only thing I could find with a similar error is in issue #6583, however, from what I know, the only copy of next I have installed is in the keystone modules and the only time it's referenced inside pnpm-lock is in @keystone/core dependencies. I could have completely misunderstood that issue though.

    E: Forgot to add logs from the container:

    error - Error: Cannot find module 'next/dist/shared/lib/constants.js'
    Require stack:
    - /backend/.keystone/admin/.next/server/pages/_document.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/dev/next-dev-server.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/dist/createAdminUIMiddleware-c41a0fb3.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/cli/dist/keystone-6-core-scripts-cli.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/bin/cli.js
        at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
        at Function.mod._resolveFilename (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/build/webpack/require-hook.js:23:32)
        at Function.Module._load (internal/modules/cjs/loader.js:746:27)
        at Module.require (internal/modules/cjs/loader.js:974:19)
        at require (internal/modules/cjs/helpers.js:101:18)
        at Object.../shared/lib/constants (/backend/.keystone/admin/.next/server/pages/_document.js:82:18)
        at __webpack_require__ (/backend/.keystone/admin/.next/server/webpack-runtime.js:33:42)
        at eval (webpack-internal:///../../node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/pages/_document.js:9:18)
        at Object.../../node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/pages/_document.js (/backend/.keystone/admin/.next/server/pages/_document.js:22:1)
        at __webpack_require__ (/backend/.keystone/admin/.next/server/webpack-runtime.js:33:42)
        at __webpack_exec__ (/backend/.keystone/admin/.next/server/pages/_document.js:122:39)
        at /backend/.keystone/admin/.next/server/pages/_document.js:123:28
        at Object.<anonymous> (/backend/.keystone/admin/.next/server/pages/_document.js:126:3)
        at Module._compile (internal/modules/cjs/loader.js:1085:14)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        at Module.load (internal/modules/cjs/loader.js:950:32)
        at Function.Module._load (internal/modules/cjs/loader.js:790:12)
        at Module.require (internal/modules/cjs/loader.js:974:19)
        at require (internal/modules/cjs/helpers.js:101:18)
        at Object.requirePage (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js:88:12)
        at /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/load-components.js:33:54
        at async Promise.all (index 0)
        at async Object.loadComponents (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/load-components.js:32:33)
        at async DevServer.findPageComponents (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js:561:36) {
      code: 'MODULE_NOT_FOUND',
      requireStack: [
        '/backend/.keystone/admin/.next/server/pages/_document.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/dev/next-dev-server.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/dist/createAdminUIMiddleware-c41a0fb3.cjs.dev.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/cli/dist/keystone-6-core-scripts-cli.cjs.dev.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.dev.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/bin/cli.js'
      ],
      page: '/signin'
    }
    Error: Cannot find module 'next/dist/shared/lib/constants.js'
    Require stack:
    - /backend/.keystone/admin/.next/server/pages/_document.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/dev/next-dev-server.js
    - /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/dist/createAdminUIMiddleware-c41a0fb3.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/cli/dist/keystone-6-core-scripts-cli.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.dev.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.js
    - /backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/bin/cli.js
        at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
        at Function.mod._resolveFilename (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/build/webpack/require-hook.js:23:32)
        at Function.Module._load (internal/modules/cjs/loader.js:746:27)
        at Module.require (internal/modules/cjs/loader.js:974:19)
        at require (internal/modules/cjs/helpers.js:101:18)
        at Object.../shared/lib/constants (/backend/.keystone/admin/.next/server/pages/_document.js:82:18)
        at __webpack_require__ (/backend/.keystone/admin/.next/server/webpack-runtime.js:33:42)
        at eval (webpack-internal:///../../node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/pages/_document.js:9:18)
        at Object.../../node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/pages/_document.js (/backend/.keystone/admin/.next/server/pages/_document.js:22:1)
        at __webpack_require__ (/backend/.keystone/admin/.next/server/webpack-runtime.js:33:42)
        at __webpack_exec__ (/backend/.keystone/admin/.next/server/pages/_document.js:122:39)
        at /backend/.keystone/admin/.next/server/pages/_document.js:123:28
        at Object.<anonymous> (/backend/.keystone/admin/.next/server/pages/_document.js:126:3)
        at Module._compile (internal/modules/cjs/loader.js:1085:14)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        at Module.load (internal/modules/cjs/loader.js:950:32)
        at Function.Module._load (internal/modules/cjs/loader.js:790:12)
        at Module.require (internal/modules/cjs/loader.js:974:19)
        at require (internal/modules/cjs/helpers.js:101:18)
        at Object.requirePage (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js:88:12)
        at /backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/load-components.js:33:54
        at async Promise.all (index 0)
        at async Object.loadComponents (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/load-components.js:32:33)
        at async DevServer.findPageComponents (/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js:561:36) {
      code: 'MODULE_NOT_FOUND',
      requireStack: [
        '/backend/.keystone/admin/.next/server/pages/_document.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/require.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next-server.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/dev/next-dev-server.js',
        '/backend/node_modules/.pnpm/[email protected]_672uxklweod7ene3nqtsh262ca/node_modules/next/dist/server/next.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/dist/createAdminUIMiddleware-c41a0fb3.cjs.dev.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/cli/dist/keystone-6-core-scripts-cli.cjs.dev.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.dev.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.js',
        '/backend/node_modules/.pnpm/@[email protected]_b4eyluiibtzggrslc7q5mbsxbu/node_modules/@keystone-6/core/bin/cli.js'
      ]
    }
    
    opened by beccauwu 1
  • File upload does not work in 'keystone-in-nextjs' example

    File upload does not work in 'keystone-in-nextjs' example

    Thank you for providing new example (https://github.com/keystonejs/keystone/pull/8148) and other changes leading into it. I tried embedded-nextjs example in the past, but abandoned it after realising that uploading files does not work and there is no easy way to replace generated 'withKeystone' with something else. This new way looks much brighter, but file upload functionality also does not work out-of-the-box.

    Steps to Reproduce

    1. Add some image/file field to the schema. Eg. https://github.com/marekryb/keystone/commit/2aca0fedb5e085f67c9d3c078b8ac4c13a1e0a5e
    2. Run the keystone server in standalone mode (port 3000)

    yarn keystone:dev

    1. Run mutation that uploads a file NOTE: Standard playground does not support file uploads, so I am using curl. You can also use Altair GraphQL client or do it programatically.

    curl localhost:3000/api/graphql \ -F operations='{ "query": "mutation Test($id: ID!, $file: Upload!) {updateUser(where:{id:$id},data:{avatar:{upload:$file}}) { id } }", "variables": { "id": "{{USER_ID}}", "file": null } }' \ -F map='{ "0": ["variables.file"] }' \ -F 0=@{{FILE_NAME}}

    Need to replace USER_ID and FILE_NAME in above. In my case final query is eg.

    curl localhost:3000/api/graphql \ -F operations='{ "query": "mutation Test($id: ID!, $file: Upload!) {updateUser(where:{id:$id},data:{avatar:{upload:$file}}) { id } }", "variables": { "id": "clbafdgom00135y3upyadgilw", "file": null } }' \ -F map='{ "0": ["variables.file"] }' \ -F [email protected]

    Result is as expected

    {"data":{"updateUser":{"id":"clbafdgom00135y3upyadgilw"}}}

    1. Run nextjs with embedded keystone (port 4000)

    yarn next:dev

    1. Run same mutation as in point 3, but for port 4000

    curl localhost:4000/api/graphql \ -F operations='{ "query": "mutation Test($id: ID!, $file: Upload!) {updateUser(where:{id:$id},data:{avatar:{upload:$file}}) { id } }", "variables": { "id": "clbafdgom00135y3upyadgilw", "file": null } }' \ -F map='{ "0": ["variables.file"] }' \ -F [email protected]

    1. Observe error

    {"errors":[{"message":"Variable "$file" got invalid value {}; Upload value invalid.","locations":[{"line":1,"column":25}]}]}

    Expected Behavior

    File upload should also work in embedded mode.

    Possible Solution

    You can fix this problem by manually pre-processing requests with graphql-upload, before passing them to Yoga. See: https://github.com/marekryb/keystone/commit/bae9841622d237a2c9b40b248c34a66fd0a49447

    • Is there some way to make yoga work with keystone upload type by default?
    • Would you like my changelist as PR to keystone-in-nextjs example?
    opened by marekryb 9
  • fix(deps): update dependency esbuild to ^0.16.0

    fix(deps): update dependency esbuild to ^0.16.0

    Mend Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | esbuild | ^0.15.13 -> ^0.16.0 | age | adoption | passing | confidence |


    Release Notes

    evanw/esbuild

    v0.16.11

    Compare Source

    • Avoid a syntax error in the presence of direct eval (#​2761)

      The behavior of nested function declarations in JavaScript depends on whether the code is run in strict mode or not. It would be problematic if esbuild preserved nested function declarations in its output because then the behavior would depend on whether the output was run in strict mode or not instead of respecting the strict mode behavior of the original source code. To avoid this, esbuild transforms nested function declarations to preserve the intended behavior of the original source code regardless of whether the output is run in strict mode or not:

      // Original code
      if (true) {
        function foo() {}
        console.log(!!foo)
        foo = null
        console.log(!!foo)
      }
      console.log(!!foo)
      
      // Transformed code
      if (true) {
        let foo2 = function() {
        };
        var foo = foo2;
        console.log(!!foo2);
        foo2 = null;
        console.log(!!foo2);
      }
      console.log(!!foo);
      

      In the above example, the original code should print true false true because it's not run in strict mode (it doesn't contain "use strict" and is not an ES module). The code that esbuild generates has been transformed such that it prints true false true regardless of whether it's run in strict mode or not.

      However, this transformation is impossible if the code contains direct eval because direct eval "poisons" all containing scopes by preventing anything in those scopes from being renamed. That prevents esbuild from splitting up accesses to foo into two separate variables with different names. Previously esbuild still did this transformation but with two variables both named foo, which is a syntax error. With this release esbuild will now skip doing this transformation when direct eval is present to avoid generating code with a syntax error. This means that the generated code may no longer behave as intended since the behavior depends on the run-time strict mode setting instead of the strict mode setting present in the original source code. To fix this problem, you will need to remove the use of direct eval.

    • Fix a bundling scenario involving multiple symlinks (#​2773, #​2774)

      This release contains a fix for a bundling scenario involving an import path where multiple path segments are symlinks. Previously esbuild was unable to resolve certain import paths in this scenario, but these import paths should now work starting with this release. This fix was contributed by @​onebytegone.

    v0.16.10

    Compare Source

    • Change the default "legal comment" behavior again (#​2745)

      The legal comments feature automatically gathers comments containing @license or @preserve and puts the comments somewhere (either in the generated code or in a separate file). This behavior used to be on by default but was disabled by default in version 0.16.0 because automatically inserting comments is potentially confusing and misleading. These comments can appear to be assigning the copyright of your code to another entity. And this behavior can be especially problematic if it happens automatically by default since you may not even be aware of it happening. For example, if you bundle the TypeScript compiler the preserving legal comments means your source code would contain this comment, which appears to be assigning the copyright of all of your code to Microsoft:

      /*! *****************************************************************************
      Copyright (c) Microsoft Corporation. All rights reserved.
      Licensed under the Apache License, Version 2.0 (the "License"); you may not use
      this file except in compliance with the License. You may obtain a copy of the
      License at http://www.apache.org/licenses/LICENSE-2.0
      
      THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
      WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
      MERCHANTABLITY OR NON-INFRINGEMENT.
      
      See the Apache Version 2.0 License for specific language governing permissions
      and limitations under the License.
      ***************************************************************************** */
      

      However, people have asked for this feature to be re-enabled by default. To resolve the confusion about what these comments are applying to, esbuild's default behavior will now be to attempt to describe which package the comments are coming from. So while this feature has been re-enabled by default, the output will now look something like this instead:

      /*! Bundled license information:
      
      typescript/lib/typescript.js:
        (*! *****************************************************************************
        Copyright (c) Microsoft Corporation. All rights reserved.
        Licensed under the Apache License, Version 2.0 (the "License"); you may not use
        this file except in compliance with the License. You may obtain a copy of the
        License at http://www.apache.org/licenses/LICENSE-2.0
      
        THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
        KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
        WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
        MERCHANTABLITY OR NON-INFRINGEMENT.
      
        See the Apache Version 2.0 License for specific language governing permissions
        and limitations under the License.
        ***************************************************************************** *)
      */
      

      Note that you can still customize this behavior with the --legal-comments= flag. For example, you can use --legal-comments=none to turn this off, or you can use --legal-comments=linked to put these comments in a separate .LEGAL.txt file instead.

    • Enable external legal comments with the transform API (#​2390)

      Previously esbuild's transform API only supported none, inline, or eof legal comments. With this release, external legal comments are now also supported with the transform API. This only applies to the JS and Go APIs, not to the CLI, and looks like this:

      • JS:

        const { code, legalComments } = await esbuild.transform(input, {
          legalComments: 'external',
        })
        
      • Go:

        result := api.Transform(input, api.TransformOptions{
          LegalComments: api.LegalCommentsEndOfFile,
        })
        code := result.Code
        legalComments := result.LegalComments
        
    • Fix duplicate function declaration edge cases (#​2757)

      The change in the previous release to forbid duplicate function declarations in certain cases accidentally forbid some edge cases that should have been allowed. Specifically duplicate function declarations are forbidden in nested blocks in strict mode and at the top level of modules, but are allowed when they are declared at the top level of function bodies. This release fixes the regression by re-allowing the last case.

    • Allow package subpaths with alias (#​2715)

      Previously the names passed to the alias feature had to be the name of a package (with or without a package scope). With this release, you can now also use the alias feature with package subpaths. So for example you can now create an alias that substitutes @org/pkg/lib with something else.

    v0.16.9

    Compare Source

    • Update to Unicode 15.0.0

      The character tables that determine which characters form valid JavaScript identifiers have been updated from Unicode version 14.0.0 to the newly-released Unicode version 15.0.0. I'm not putting an example in the release notes because all of the new characters will likely just show up as little squares since fonts haven't been updated yet. But you can read https://www.unicode.org/versions/Unicode15.0.0/#Summary for more information about the changes.

    • Disallow duplicate lexically-declared names in nested blocks and in strict mode

      In strict mode or in a nested block, it's supposed to be a syntax error to declare two symbols with the same name unless all duplicate entries are either function declarations or all var declarations. However, esbuild was overly permissive and allowed this when duplicate entries were either function declarations or var declarations (even if they were mixed). This check has now been made more restrictive to match the JavaScript specification:

      // JavaScript allows this
      var a
      function a() {}
      {
        var b
        var b
        function c() {}
        function c() {}
      }
      
      // JavaScript doesn't allow this
      {
        var d
        function d() {}
      }
      
    • Add a type declaration for the new empty loader (#​2755)

      I forgot to add this in the previous release. It has now been added.

      This fix was contributed by @​fz6m.

    • Add support for the v flag in regular expression literals

      People are currently working on adding a v flag to JavaScript regular expresions. You can read more about this flag here: https://v8.dev/features/regexp-v-flag. This release adds support for parsing this flag, so esbuild will now no longer consider regular expression literals with this flag to be a syntax error. If the target is set to something other than esnext, esbuild will transform regular expression literals containing this flag into a new RegExp() constructor call so the resulting code doesn't have a syntax error. This enables you to provide a polyfill for RegExp that implements the v flag to get your code to work at run-time. While esbuild doesn't typically adopt proposals until they're already shipping in a real JavaScript run-time, I'm adding it now because a) esbuild's implementation doesn't need to change as the proposal evolves, b) this isn't really new syntax since regular expression literals already have flags, and c) esbuild's implementation is a trivial pass-through anyway.

    • Avoid keeping the name of classes with static name properties

      The --keep-names property attempts to preserve the original value of the name property for functions and classes even when identifiers are renamed by the minifier or to avoid a name collision. This is currently done by generating code to assign a string to the name property on the function or class object. However, this should not be done for classes with a static name property since in that case the explicitly-defined name property overwrites the automatically-generated class name. With this release, esbuild will now no longer attempt to preserve the name property for classes with a static name property.

    v0.16.8

    Compare Source

    • Allow plugins to resolve injected files (#​2754)

      Previously paths passed to the inject feature were always interpreted as file system paths. This meant that onResolve plugins would not be run for them and esbuild's default path resolver would always be used. This meant that the inject feature couldn't be used in the browser since the browser doesn't have access to a file system. This release runs paths passed to inject through esbuild's full path resolution pipeline so plugins now have a chance to handle them using onResolve callbacks. This makes it possible to write a plugin that makes esbuild's inject work in the browser.

    • Add the empty loader (#​1541, #​2753)

      The new empty loader tells esbuild to pretend that a file is empty. So for example --loader:.css=empty effectively skips all imports of .css files in JavaScript so that they aren't included in the bundle, since import "./some-empty-file" in JavaScript doesn't bundle anything. You can also use the empty loader to remove asset references in CSS files. For example --loader:.png=empty causes esbuild to replace asset references such as url(image.png) with url() so that they are no longer included in the resulting style sheet.

    • Fix </script> and </style> escaping for non-default targets (#​2748)

      The change in version 0.16.0 to give control over </script> escaping via --supported:inline-script=false or --supported:inline-script=true accidentally broke automatic escaping of </script> when an explicit target setting is specified. This release restores the correct automatic escaping of </script> (which should not depend on what target is set to).

    • Enable the exports field with NODE_PATHS (#​2752)

      Node has a rarely-used feature where you can extend the set of directories that node searches for packages using the NODE_PATHS environment variable. While esbuild supports this too, previously it only supported the old main field path resolution but did not support the new exports field package resolution. This release makes the path resolution rules the same again for both node_modules directories and NODE_PATHS directories.

    v0.16.7

    Compare Source

    • Include file loader strings in metafile imports (#​2731)

      Bundling a file with the file loader copies that file to the output directory and imports a module with the path to the copied file in the default export. Previously when bundling with the file loader, there was no reference in the metafile from the JavaScript file containing the path string to the copied file. With this release, there will now be a reference in the metafile in the imports array with the kind file-loader:

       {
         ...
         "outputs": {
           "out/image-55CCFTCE.svg": {
             ...
           },
           "out/entry.js": {
             "imports": [
      +        {
      +          "path": "out/image-55CCFTCE.svg",
      +          "kind": "file-loader"
      +        }
             ],
             ...
           }
         }
       }
      
    • Fix byte counts in metafile regarding references to other output files (#​2071)

      Previously files that contained references to other output files had slightly incorrect metadata for the byte counts of input files which contributed to that output file. So for example if app.js imports image.png using the file loader and esbuild generates out.js and image-LSAMBFUD.png, the metadata for how many bytes of out.js are from app.js was slightly off (the metadata for the byte count of out.js was still correct). The reason is because esbuild substitutes the final paths for references between output files toward the end of the build to handle cyclic references, and the byte counts needed to be adjusted as well during the path substitution. This release fixes these byte counts (specifically the bytesInOutput values).

    • The alias feature now strips a trailing slash (#​2730)

      People sometimes add a trailing slash to the name of one of node's built-in modules to force node to import from the file system instead of importing the built-in module. For example, importing util imports node's built-in module called util but importing util/ tries to find a package called util on the file system. Previously attempting to use esbuild's package alias feature to replace imports to util with a specific file would fail because the file path would also gain a trailing slash (e.g. mapping util to ./file.js turned util/ into ./file.js/). With this release, esbuild will now omit the path suffix if it's a single trailing slash, which should now allow you to successfully apply aliases to these import paths.

    v0.16.6

    Compare Source

    • Do not mark subpath imports as external with --packages=external (#​2741)

      Node has a feature called subpath imports where special import paths that start with # are resolved using the imports field in the package.json file of the enclosing package. The intent of the newly-added --packages=external setting is to exclude a package's dependencies from the bundle. Since a package's subpath imports are only accessible within that package, it's wrong for them to be affected by --packages=external. This release changes esbuild so that --packages=external no longer affects subpath imports.

    • Forbid invalid numbers in JSON files

      Previously esbuild parsed numbers in JSON files using the same syntax as JavaScript. But starting from this release, esbuild will now parse them with JSON syntax instead. This means the following numbers are no longer allowed by esbuild in JSON files:

      • Legacy octal literals (non-zero integers starting with 0)
      • The 0b, 0o, and 0x numeric prefixes
      • Numbers containing _ such as 1_000
      • Leading and trailing . such as 0. and .0
      • Numbers with a space after the - such as - 1
    • Add external imports to metafile (#​905, #​1768, #​1933, #​1939)

      External imports now appear in imports arrays in the metafile (which is present when bundling with metafile: true) next to normal imports, but additionally have external: true to set them apart. This applies both to files in the inputs section and the outputs section. Here's an example:

       {
         "inputs": {
           "style.css": {
             "bytes": 83,
             "imports": [
      +        {
      +          "path": "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css",
      +          "kind": "import-rule",
      +          "external": true
      +        }
             ]
           },
           "app.js": {
             "bytes": 100,
             "imports": [
      +        {
      +          "path": "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js",
      +          "kind": "import-statement",
      +          "external": true
      +        },
               {
                 "path": "style.css",
                 "kind": "import-statement"
               }
             ]
           }
         },
         "outputs": {
           "out/app.js": {
             "imports": [
      +        {
      +          "path": "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js",
      +          "kind": "require-call",
      +          "external": true
      +        }
             ],
             "exports": [],
             "entryPoint": "app.js",
             "cssBundle": "out/app.css",
             "inputs": {
               "app.js": {
                 "bytesInOutput": 113
               },
               "style.css": {
                 "bytesInOutput": 0
               }
             },
             "bytes": 528
           },
           "out/app.css": {
             "imports": [
      +        {
      +          "path": "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css",
      +          "kind": "import-rule",
      +          "external": true
      +        }
             ],
             "inputs": {
               "style.css": {
                 "bytesInOutput": 0
               }
             },
             "bytes": 100
           }
         }
       }
      

      One additional useful consequence of this is that the imports array is now populated when bundling is disabled. So you can now use esbuild with bundling disabled to inspect a file's imports.

    v0.16.5

    Compare Source

    • Make it easy to exclude all packages from a bundle (#​1958, #​1975, #​2164, #​2246, #​2542)

      When bundling for node, it's often necessary to exclude npm packages from the bundle since they weren't designed with esbuild bundling in mind and don't work correctly after being bundled. For example, they may use __dirname and run-time file system calls to load files, which doesn't work after bundling with esbuild. Or they may compile a native .node extension that has similar expectations about the layout of the file system that are no longer true after bundling (even if the .node extension is copied next to the bundle).

      The way to get this to work with esbuild is to use the --external: flag. For example, the fsevents package contains a native .node extension and shouldn't be bundled. To bundle code that uses it, you can pass --external:fsevents to esbuild to exclude it from your bundle. You will then need to ensure that the fsevents package is still present when you run your bundle (e.g. by publishing your bundle to npm as a package with a dependency on fsevents).

      It was possible to automatically do this for all of your dependencies, but it was inconvenient. You had to write some code that read your package.json file and passed the keys of the dependencies, devDependencies, peerDependencies, and/or optionalDependencies maps to esbuild as external packages (either that or write a plugin to mark all package paths as external). Previously esbuild's recommendation for making this easier was to do --external:./node_modules/* (added in version 0.14.13). However, this was a bad idea because it caused compatibility problems with many node packages as it caused esbuild to mark the post-resolve path as external instead of the pre-resolve path. Doing that could break packages that are published as both CommonJS and ESM if esbuild's bundler is also used to do a module format conversion.

      With this release, you can now do the following to automatically exclude all packages from your bundle:

      • CLI:

        esbuild --bundle --packages=external
        
      • JS:

        esbuild.build({
          bundle: true,
          packages: 'external',
        })
        
      • Go:

        api.Build(api.BuildOptions{
          Bundle:   true,
          Packages: api.PackagesExternal,
        })
        

      Doing --external:./node_modules/* is still possible and still has the same behavior, but is no longer recommended. I recommend that you use the new packages feature instead.

    • Fix some subtle bugs with tagged template literals

      This release fixes a bug where minification could incorrectly change the value of this within tagged template literal function calls:

      // Original code
      function f(x) {
        let z = y.z
        return z``
      }
      
      // Old output (with --minify)
      function f(n){return y.z``}
      
      // New output (with --minify)
      function f(n){return(0,y.z)``}
      

      This release also fixes a bug where using optional chaining with --target=es2019 or earlier could incorrectly change the value of this within tagged template literal function calls:

      // Original code
      var obj = {
        foo: function() {
          console.log(this === obj);
        }
      };
      (obj?.foo)``;
      
      // Old output (with --target=es6)
      var obj = {
        foo: function() {
          console.log(this === obj);
        }
      };
      (obj == null ? void 0 : obj.foo)``;
      
      // New output (with --target=es6)
      var __freeze = Object.freeze;
      var __defProp = Object.defineProperty;
      var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(raw || cooked.slice()) }));
      var _a;
      var obj = {
        foo: function() {
          console.log(this === obj);
        }
      };
      (obj == null ? void 0 : obj.foo).call(obj, _a || (_a = __template([""])));
      
    • Some slight minification improvements

      The following minification improvements were implemented:

      • if (~a !== 0) throw x; => if (~a) throw x;
      • if ((a | b) !== 0) throw x; => if (a | b) throw x;
      • if ((a & b) !== 0) throw x; => if (a & b) throw x;
      • if ((a ^ b) !== 0) throw x; => if (a ^ b) throw x;
      • if ((a << b) !== 0) throw x; => if (a << b) throw x;
      • if ((a >> b) !== 0) throw x; => if (a >> b) throw x;
      • if ((a >>> b) !== 0) throw x; => if (a >>> b) throw x;
      • if (!!a || !!b) throw x; => if (a || b) throw x;
      • if (!!a && !!b) throw x; => if (a && b) throw x;
      • if (a ? !!b : !!c) throw x; => if (a ? b : c) throw x;

    v0.16.4

    Compare Source

    • Fix binary downloads from the @esbuild/ scope for Deno (#​2729)

      Version 0.16.0 of esbuild moved esbuild's binary executables into npm packages under the @esbuild/ scope, which accidentally broke the binary downloader script for Deno. This release fixes this script so it should now be possible to use esbuild version 0.16.4+ with Deno.

    v0.16.3

    Compare Source

    • Fix a hang with the JS API in certain cases (#​2727)

      A change that was made in version 0.15.13 accidentally introduced a case when using esbuild's JS API could cause the node process to fail to exit. The change broke esbuild's watchdog timer, which detects if the parent process no longer exists and then automatically exits esbuild. This hang happened when you ran node as a child process with the stderr stream set to pipe instead of inherit, in the child process you call esbuild's JS API and pass incremental: true but do not call dispose() on the returned rebuild object, and then call process.exit(). In that case the parent node process was still waiting for the esbuild process that was created by the child node process to exit. The change made in version 0.15.13 was trying to avoid using Go's sync.WaitGroup API incorrectly because the API is not thread-safe. Instead of doing this, I have now reverted that change and implemented a thread-safe version of the sync.WaitGroup API for esbuild to use instead.

    v0.16.2

    Compare Source

    • Fix process.env.NODE_ENV substitution when transforming (#​2718)

      Version 0.16.0 introduced an unintentional regression that caused process.env.NODE_ENV to be automatically substituted with either "development" or "production" when using esbuild's transform API. This substitution is a necessary feature of esbuild's build API because the React framework crashes when you bundle it without doing this. But the transform API is typically used as part of a larger build pipeline so the benefit of esbuild doing this automatically is not as clear, and esbuild previously didn't do this.

      However, version 0.16.0 switched the default value of the platform setting for the transform API from neutral to browser, both to align it with esbuild's documentation (which says browser is the default value) and because escaping the </script> character sequence is now tied to the browser platform (see the release notes for version 0.16.0 for details). That accidentally enabled automatic substitution of process.env.NODE_ENV because esbuild always did that for code meant for the browser. To fix this regression, esbuild will now only automatically substitute process.env.NODE_ENV when using the build API.

    • Prevent define from substituting constants into assignment position (#​2719)

      The define feature lets you replace certain expressions with constants. For example, you could use it to replace references to the global property reference window.DEBUG with false at compile time, which can then potentially help esbuild remove unused code from your bundle. It's similar to DefinePlugin in Webpack.

      However, if you write code such as window.DEBUG = true and then defined window.DEBUG to false, esbuild previously generated the output false = true which is a syntax error in JavaScript. This behavior is not typically a problem because it doesn't make sense to substitute window.DEBUG with a constant if its value changes at run-time (Webpack's DefinePlugin also generates false = true in this case). But it can be alarming to have esbuild generate code with a syntax error.

      So with this release, esbuild will no longer substitute define constants into assignment position to avoid generating code with a syntax error. Instead esbuild will generate a warning, which currently looks like this:

      β–² [WARNING] Suspicious assignment to defined constant "window.DEBUG" [assign-to-define]
      
          example.js:1:0:
            1 β”‚ window.DEBUG = true
              β•΅ ~~~~~~~~~~~~
      
        The expression "window.DEBUG" has been configured to be replaced with a constant using the
        "define" feature. If this expression is supposed to be a compile-time constant, then it doesn't
        make sense to assign to it here. Or if this expression is supposed to change at run-time, this
        "define" substitution should be removed.
      
    • Fix a regression with npm install --no-optional (#​2720)

      Normally when you install esbuild with npm install, npm itself is the tool that downloads the correct binary executable for the current platform. This happens because of how esbuild's primary package uses npm's optionalDependencies feature. However, if you deliberately disable this with npm install --no-optional then esbuild's install script will attempt to repair the installation by manually downloading and extracting the binary executable from the package that was supposed to be installed.

      The change in version 0.16.0 to move esbuild's nested packages into the @esbuild/ scope unintentionally broke this logic because of how npm's URL structure is different for scoped packages vs. normal packages. It was actually already broken for a few platforms earlier because esbuild already had packages for some platforms in the @esbuild/ scope, but I didn't discover this then because esbuild's integration tests aren't run on all platforms. Anyway, this release contains some changes to the install script that should hopefully get this scenario working again.

    v0.16.1

    Compare Source

    • Avoid a syntax error in the presence of direct eval (#​2761)

      The behavior of nested function declarations in JavaScript depends on whether the code is run in strict mode or not. It would be problematic if esbuild preserved nested function declarations in its output because then the behavior would depend on whether the output was run in strict mode or not instead of respecting the strict mode behavior of the original source code. To avoid this, esbuild transforms nested function declarations to preserve the intended behavior of the original source code regardless of whether the output is run in strict mode or not:

      // Original code
      if (true) {
        function foo() {}
        console.log(!!foo)
        foo = null
        console.log(!!foo)
      }
      console.log(!!foo)
      
      // Transformed code
      if (true) {
        let foo2 = function() {
        };
        var foo = foo2;
        console.log(!!foo2);
        foo2 = null;
        console.log(!!foo2);
      }
      console.log(!!foo);
      

      In the above example, the original code should print true false true because it's not run in strict mode (it doesn't contain "use strict" and is not an ES module). The code that esbuild generates has been transformed such that it prints true false true regardless of whether it's run in strict mode or not.

      However, this transformation is impossible if the code contains direct eval because direct eval "poisons" all containing scopes by preventing anything in those scopes from being renamed. That prevents esbuild from splitting up accesses to foo into two separate variables with different names. Previously esbuild still did this transformation but with two variables both named foo, which is a syntax error. With this release esbuild will now skip doing this transformation when direct eval is present to avoid generating code with a syntax error. This means that the generated code may no longer behave as intended since the behavior depends on the run-time strict mode setting instead of the strict mode setting present in the original source code. To fix this problem, you will need to remove the use of direct eval.

    • Fix a bundling scenario involving multiple symlinks (#​2773, #​2774)

      This release contains a fix for a bundling scenario involving an import path where multiple path segments are symlinks. Previously esbuild was unable to resolve certain import paths in this scenario, but these import paths should now work starting with this release. This fix was contributed by @​onebytegone.

    v0.16.0

    Compare Source

    This release deliberately contains backwards-incompatible changes. To avoid automatically picking up releases like this, you should either be pinning the exact version of esbuild in your package.json file (recommended) or be using a version range syntax that only accepts patch upgrades such as ^0.15.0 or ~0.15.0. See npm's documentation about semver for more information.

    • Move all binary executable packages to the @esbuild/ scope

      Binary package executables for esbuild are published as individual packages separate from the main esbuild package so you only have to download the relevant one for the current platform when you install esbuild. This release moves all of these packages under the @esbuild/ scope to avoid collisions with 3rd-party packages. It also changes them to a consistent naming scheme that uses the os and cpu names from node.

      The package name changes are as follows:

      • @esbuild/linux-loong64 => @esbuild/linux-loong64 (no change)
      • esbuild-android-64 => @esbuild/android-x64
      • esbuild-android-arm64 => @esbuild/android-arm64
      • esbuild-darwin-64 => @esbuild/darwin-x64
      • esbuild-darwin-arm64 => @esbuild/darwin-arm64
      • esbuild-freebsd-64 => @esbuild/freebsd-x64
      • esbuild-freebsd-arm64 => @esbuild/freebsd-arm64
      • esbuild-linux-32 => @esbuild/linux-ia32
      • esbuild-linux-64 => @esbuild/linux-x64
      • esbuild-linux-arm => @esbuild/linux-arm
      • esbuild-linux-arm64 => @esbuild/linux-arm64
      • esbuild-linux-mips64le => @esbuild/linux-mips64el
      • esbuild-linux-ppc64le => @esbuild/linux-ppc64
      • esbuild-linux-riscv64 => @esbuild/linux-riscv64
      • esbuild-linux-s390x => @esbuild/linux-s390x
      • esbuild-netbsd-64 => @esbuild/netbsd-x64
      • esbuild-openbsd-64 => @esbuild/openbsd-x64
      • esbuild-sunos-64 => @esbuild/sunos-x64
      • esbuild-wasm => esbuild-wasm (no change)
      • esbuild-windows-32 => @esbuild/win32-ia32
      • esbuild-windows-64 => @esbuild/win32-x64
      • esbuild-windows-arm64 => @esbuild/win32-arm64
      • esbuild => esbuild (no change)

      Normal usage of the esbuild and esbuild-wasm packages should not be affected. These name changes should only affect tools that hard-coded the individual binary executable package names into custom esbuild downloader scripts.

      This change was not made with performance in mind. But as a bonus, installing esbuild with npm may potentially happen faster now. This is because npm's package installation protocol is inefficient: it always downloads metadata for all past versions of each package even when it only needs metadata about a single version. This makes npm package downloads O(n) in the number of published versions, which penalizes packages like esbuild that are updated regularly. Since most of esbuild's package names have now changed, npm will now need to download much less data when installing esbuild (8.72mb of package manifests before this change β†’ 0.06mb of package manifests after this change). However, this is only a temporary improvement. Installing esbuild will gradually get slower again as further versions of esbuild are published.

    • Publish a shell script that downloads esbuild directly

      In addition to all of the existing ways to install esbuild, you can now also download esbuild directly like this:

      curl -fsSL https://esbuild.github.io/dl/latest | sh
      

      This runs a small shell script that downloads the latest esbuild binary executable to the current directory. This can be convenient on systems that don't have npm installed or when you just want to get a copy of esbuild quickly without any extra steps. If you want a specific version of esbuild (starting with this version onward), you can provide that version in the URL instead of latest:

      curl -fsSL https://esbuild.github.io/dl/v0.16.0 | sh
      

      Note that the download script needs to be able to access registry.npmjs.org to be able to complete the download. This download script doesn't yet support all of the platforms that esbuild supports because I lack the necessary testing environments. If the download script doesn't work for you because you're on an unsupported platform, please file an issue on the esbuild repo so we can add support for it.

    • Fix some parameter names for the Go API

      This release changes some parameter names for the Go API to be consistent with the JavaScript and CLI APIs:

      • OutExtensions => OutExtension
      • JSXMode => JSX
    • Add additional validation of API parameters

      The JavaScript API now does some additional validation of API parameters to catch incorrect uses of esbuild's API. The biggest impact of this is likely that esbuild now strictly only accepts strings with the define parameter. This would already have been a type error with esbuild's TypeScript type definitions, but it was previously not enforced for people using esbuild's API JavaScript without TypeScript.

      The define parameter appears at first glance to take a JSON object if you aren't paying close attention, but this actually isn't true. Values for define are instead strings of JavaScript code. This means you have to use define: { foo: '"bar"' } to replace foo with the string "bar". Using define: { foo: 'bar' } actually replaces foo with the identifier bar. Previously esbuild allowed you to pass define: { foo: false } and false was automatically converted into a string, which made it more confusing to understand what define actually represents. Starting with this release, passing non-string values such as with define: { foo: false } will no longer be allowed. You will now have to write define: { foo: 'false' } instead.

    • Generate shorter data URLs if possible (#​1843)

      Loading a file with esbuild's dataurl loader generates a JavaScript module with a data URL for that file in a string as a single default export. Previously the data URLs generated by esbuild all used base64 encoding. However, this is unnecessarily long for most textual data (e.g. SVG images). So with this release, esbuild's dataurl loader will now use percent encoding instead of base64 encoding if the result will be shorter. This can result in ~25% smaller data URLs for large SVGs. If you want the old behavior, you can use the base64 loader instead and then construct the data URL yourself.

    • Avoid marking entry points as external (#​2382)

      Previously you couldn't specify --external:* to mark all import paths as external because that also ended up making the entry point itself external, which caused the build to fail. With this release, esbuild's external API parameter no longer applies to entry points so using --external:* is now possible.

      One additional consequence of this change is that the kind parameter is now required when calling the resolve() function in esbuild's plugin API. Previously the kind parameter defaulted to entry-point, but that no longer interacts with external so it didn't seem wise for this to continue to be the default. You now have to specify kind so that the path resolution mode is explicit.

    • Disallow non-default imports when assert { type: 'json' } is present

      There is now standard behavior for importing a JSON file into an ES module using an import statement. However, it requires you to place the assert { type: 'json' } import assertion after the import path. This import assertion tells the JavaScript runtime to throw an error if the import does not end up resolving to a JSON file. On the web, the type of a file is determined by the Content-Type HTTP header instead of by the file extension. The import assertion prevents security problems on the web where a .json file may actually resolve to a JavaScript file containing malicious code, which is likely not expected for an import that is supposed to only contain pure side-effect free data.

      By default, esbuild uses the file extension to determine the type of a file, so this import assertion is unnecessary with esbuild. However, esbuild's JSON import feature has a non-standard extension that allows you to import top-level properties of the JSON object as named imports. For example, esbuild lets you do this:

      import { version } from './package.json'
      

      This is useful for tree-shaking when bundling because it means esbuild will only include the the version field of package.json in your bundle. This is non-standard behavior though and doesn't match the behavior of what happens when you import JSON in a real JavaScript runtime (after adding assert { type: 'json' }). In a real JavaScript runtime the only thing you can import is the default import. So with this release, esbuild will now prevent you from importing non-default import names if assert { type: 'json' } is present. This ensures that code containing assert { type: 'json' } isn't relying on non-standard behavior that won't work everywhere. So the following code is now an error with esbuild when bundling:

      import { version } from './package.json' assert { type: 'json' }
      

      In addition, adding assert { type: 'json' } to an import statement now means esbuild will generate an error if the loader for the file is anything other than json, which is required by the import assertion specification.

    • Provide a way to disable automatic escaping of </script> (#​2649)

      If you inject esbuild's output into a script tag in an HTML file, code containing the literal characters </script> will cause the tag to be ended early which will break the code:

      <script>
        console.log("</script>");
      </script>
      

      To avoid this, esbuild automatically escapes these strings in generated JavaScript files (e.g. "</script>" becomes "<\/script>" instead). This also applies to </style> in generated CSS files. Previously this always happened and there wasn't a way to turn this off.

      With this release, esbuild will now only do this if the platform setting is set to browser (the default value). Setting platform to node or neutral will disable this behavior. This behavior can also now be disabled with --supported:inline-script=false (for JS) and --supported:inline-style=false (for CSS).

    • Throw an early error if decoded UTF-8 text isn't a Uint8Array (#​2532)

      If you run esbuild's JavaScript API in a broken JavaScript environment where new TextEncoder().encode("") instanceof Uint8Array is false, then esbuild's API will fail with a confusing serialization error message that makes it seem like esbuild has a bug even though the real problem is that the JavaScript environment itself is broken. This can happen when using the test framework called Jest. With this release, esbuild's API will now throw earlier when it detects that the environment is unable to encode UTF-8 text correctly with an error message that makes it more clear that this is not a problem with esbuild.

    • Change the default "legal comment" behavior

      The legal comments feature automatically gathers comments containing @license or @preserve and puts the comments somewhere (either in the generated code or in a separate file). People sometimes want this to happen so that the their dependencies' software licenses are retained in the generated output code. By default esbuild puts these comments at the end of the file when bundling. However, people sometimes find this confusing because these comments can be very generic and may not mention which library they come from. So with this release, esbuild will now discard legal comments by default. You now have to opt-in to preserving them if you want this behavior.

    • Enable the module condition by default (#​2417)

      Package authors want to be able to use the new exports field in package.json to provide tree-shakable ESM code for ESM-aware bundlers while simultaneously providing fallback CommonJS code for other cases.

      Node's proposed way to do this involves using the import and require export conditions so that you get the ESM code if you use an import statement and the CommonJS code if you use a require call. However, this has a major drawback: if some code in the bundle uses an import statement and other code in the bundle uses a require call, then you'll get two copies of the same package in the bundle. This is known as the dual package hazard and can lead to bloated bundles or even worse to subtle logic bugs.

      Webpack supports an alternate solution: an export condition called module that takes effect regardless of whether the package was imported using an import statement or a require call. This works because bundlers such as Webpack support importing a ESM using a require call (something node doesn't support). You could already do this with esbuild using --conditions=module but you previously had to explicitly enable this. Package authors are concerned that esbuild users won't know to do this and will get suboptimal output with their package, so they have requested for esbuild to do this automatically.

      So with this release, esbuild will now automatically add the module condition when there aren't any custom conditions already configured. You can disable this with --conditions= or conditions: [] (i.e. explicitly clearing all custom conditions).

    • Rename the master branch to main

      The primary branch for this repository was previously called master but is now called main. This change mirrors a similar change in many other projects.

    • Remove esbuild's _exit(0) hack for WebAssembly (#​714)

      Node had an unfortunate bug where the node process is unnecessarily kept open while a WebAssembly module is being optimized: https://github.com/nodejs/node/issues/36616. This means cases where running esbuild should take a few milliseconds can end up taking many seconds instead.

      The workaround was to force node to exit by ending the process early. This was done by esbuild in one of two ways depending on the exit code. For non-zero exit codes (i.e. when there is a build error), the esbuild command could just call process.kill(process.pid) to avoid the hang. But for zero exit codes, esbuild had to load a N-API native node extension that calls the operating system's exit(0) function.

      However, this problem has essentially been fixed in node starting with version 18.3.0. So I have removed this hack from esbuild. If you are using an earlier version of node with esbuild-wasm and you don't want the esbuild command to hang for a while when exiting, you can upgrade to node 18.3.0 or higher to remove the hang.

      The fix came from a V8 upgrade: this commit enabled dynamic tiering for WebAssembly by default for all projects that use V8's WebAssembly implementation. Previously all functions in the WebAssembly module were optimized in a single batch job but with dynamic tiering, V8 now optimizes individual WebAssembly functions as needed. This avoids unnecessary WebAssembly compilation which allows node to exit on time.

    v0.15.18

    Compare Source

    • Performance improvements for both JS and CSS

      This release brings noticeable performance improvements for JS parsing and for CSS parsing and printing. Here's an example benchmark for using esbuild to pretty-print a single large minified CSS file and JS file:

      | Test case | Previous release | This release | |----------------|------------------|--------------------| | 4.8mb CSS file | 19ms | 11ms (1.7x faster) | | 5.8mb JS file | 36ms | 32ms (1.1x faster) |

      The performance improvements were very straightforward:

      • Identifiers were being scanned using a generic character advancement function instead of using custom inline code. Advancing past each character involved UTF-8 decoding as well as updating multiple member variables. This was sped up using loop that skips UTF-8 decoding entirely and that only updates member variables once at the end. This is faster because identifiers are plain ASCII in the vast majority of cases, so Unicode decoding is almost always unnecessary.

      • CSS identifiers and CSS strings were still being printed one character at a time. Apparently I forgot to move this part of esbuild's CSS infrastructure beyond the proof-of-concept stage. These were both very obvious in the profiler, so I think maybe I have just never profiled esbuild's CSS printing before?

      • There was unnecessary work being done that was related to source maps when source map output was disabled. I likely haven't observed this before because esbuild's benchmarks always have source maps enabled. This work is now disabled when it's not going to be used.

      I definitely should have caught these performance issues earlier. Better late than never I suppose.

    v0.15.17

    Compare Source

    • Search for missing source map code on the file system (#​2711)

      Source maps are JSON files that map from compiled code back to the original code. They provide the original source code using two arrays: sources (required) and sourcesContent (optional). When bundling is enabled, esbuild is able to bundle code with source maps that was compiled by other tools (e.g. with Webpack) and emit source maps that map all the way back to the original code (e.g. before Webpack compiled it).

      Previously if the input source maps omitted the optional sourcesContent array, esbuild would use null for the source content in the source map that it generates (since the source content isn't available). However, sometimes the original source code is actually still present on the file system. With this release, esbuild will now try to find the original source code using the path in the sources array and will use that instead of null if it was found.

    • Fix parsing bug with TypeScript infer and extends (#​2712)

      This release fixes a bug where esbuild incorrectly failed to parse valid TypeScript code that nests extends inside infer inside extends, such as in the example below:

      type A<T> = {};
      type B = {} extends infer T extends {} ? A<T> : never;
      

      TypeScript code that does this should now be parsed correctly.

    • Use WebAssembly.instantiateStreaming if available (#​1036, #​1900)

      Currently the WebAssembly version of esbuild uses fetch to download esbuild.wasm and then WebAssembly.instantiate to compile it. There is a newer API called WebAssembly.instantiateStreaming that both downloads and compiles at the same time, which can be a performance improvement if both downloading and compiling are slow. With this release, esbuild now attempts to use WebAssembly.instantiateStreaming and falls back to the original approach if that fails.

      The implementation for this builds on a PR by @​lbwa.

    • Preserve Webpack comments inside constructor calls (#​2439)

      This improves the use of esbuild as a faster TypeScript-to-JavaScript frontend for Webpack, which has special magic comments inside new Worker() expressions that affect Webpack's behavior.

    v0.15.16

    Compare Source

    • Add a package alias feature (#​2191)

      With this release, you can now easily substitute one package for another at build time with the new alias feature. For example, --alias:oldpkg=newpkg replaces all imports of oldpkg with newpkg. One use case for this is easily replacing a node-only package with a browser-friendly package in 3rd-party code that you don't control. These new substitutions happen first before all of esbuild's existing path resolution logic.

      Note that when an import path is substituted using an alias, the resulting import path is resolved in the working directory instead of in the directory containing the source file with the import path. If needed, the working directory can be set with the cd command when using the CLI or with the absWorkingDir setting when using the JS or Go APIs.

    • Fix crash when pretty-printing minified JSX with object spread of object literal with computed property (#​2697)

      JSX elements are translated to JavaScript function calls and JSX element attributes are translated to properties on a JavaScript object literal. These properties are always either strings


    Configuration

    πŸ“… Schedule: Branch creation - "before 7am on Tuesday,before 7am on Wednesday" in timezone Australia/Sydney, Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 3
Releases(2022-12-07)
  • 2022-12-07(Dec 6, 2022)

  • 2022-12-06(Dec 6, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    

    Breaking Changes

    • [core] Removes createContext, createRequestContext - replace any relevant usage with context.sudo(), context.withSession() or context.withRequest() (#8073) @borisno2

    New Features

    • [core, fields-document] Adds Project and Device Telemetry events to the keystone dev script (#8118) @borisno2
    • [core] Adds HOST as an environment variable for keystone dev and keystone start, with higher precedence than config.server.options.host (#8132) @fkrauthan
    • [core] Next.js 13 Upgrade (#8061) @AliceRossa
    • [fields-document] Adds a new structure field type, a composable JSON data structure with a powerful GraphQL API (#7936) @emmatown

    Bug Fixes

    • [core] Fixes inline related item form submitting the parent form (#8123) @januzis
    • [auth] Fixes initFirstItem bypass when ui.isAccessAllowed is defined (#8115) @dcousens

    :seedling: New Contributors

    Thanks to the following developers for making their first contributions to the project!

    :blue_heart: Acknowledgements

    Lastly, thanks to @dcousens (#8127,#8125,#8122,#8120,#8104,#8108,#8108,#8108), @borisno2 (#8134), @flexdinesh (#8124,#8119), @renovate (#8072,#8116,#8109), @emmatown (#8099) for changes not shown above, but none-the-less appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 2022-11-25(Nov 25, 2022)

  • 2022-11-21(Nov 21, 2022)

  • 2022-11-18(Nov 18, 2022)

  • 2022-11-17(Nov 16, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    

    New Features

    • [core] Adds a new group function for grouping fields in the Admin UI (#8088) @emmatown
    • [core] Adds ui.searchFields for the relationship field (#8074) @dcousens
    • [core] Adds fieldPosition to field ui.itemView, for moving a field to the sidebar (#8075) @borisno2
    • [core] Adds context.withRequest, a method to derive an updated context from an incoming request and response (#8013) @borisno2

    Bug Fixes

    • [core] Fix the startup message to use the configured http.options host instead of assuming localhost (#8078) @u-ishii
    • [core, fields-document] Fix relationship fields not using their ui.labelField configuration (#8049) @georgekrax
    • [auth, cloudinary, core, document-renderer, fields-document] Adds exports field to package.json (#8054) @emmatown

    :seedling: New Contributors

    Thanks to the following developers for making their first contributions to the project!

    :blue_heart: Acknowledgements

    Lastly, thanks to @keystonejs-release-bot (#8064,#8064,#8064) for changes not shown above, but none-the-less appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 2022-11-03(Nov 3, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    @keystone-6/[email protected]
    

    Bug Fixes

    • [core] Improves performance of querying to-one relationships (#8000) @mitchellhamilton
    • [core] Fixes in and not_in filter views for integer, bigInt, decimal and float fields (#7930) @nya1
    • [core] Fixes issue where the custom field view controller was not being used. You should be able to override field controller when setting ui.views parameter in fields. (#8034) @gautamsi
    • [core] Fixes changes to session/ui.publicPages/ui.isValidSession/ui.pageMiddleware not being updated in live reloads (#8038) @mitchellhamilton
    • [core] Fixes platform configuration for esbuild (#8031) @mmachatschek
    • [fields-document] Fixes selection for component blocks without child fields (#8021) @mitchellhamilton

    :seedling: New Contributors

    Thanks to the following developers for making their first contributions to the project!

    :blue_heart: Acknowledgements

    Lastly, thanks to @mitchellhamilton (#8063,#8059,#8027), @renovate (#8056,#8055,#8053,#8045,#8041,#8036,#7974), @flexdinesh (#8060,#8039,#8048), @bladey (#8057), @dcousens (#8026) for changes not shown above, but none-the-less appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 2022-10-19-afternoon(Oct 19, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    

    Bug Fixes

    • [core] Fixes the inputData field type for FieldCreateItemAccessArgs (#8017) @acburdine

    :blue_heart: Acknowledgements

    Lastly, thanks to @dcousens (#8016) for changes not shown above, but none-the-less appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 2022-10-19(Oct 18, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    

    Breaking Changes

    • [core] Changes access-control error messages to only show the list key and operation (#7914) @dcousens
    • [core] Replaces @keystone-6/core/testing exports with { resetDatabase }, for a context use getContext instead (#7968) @mitchellhamilton
    • [core] Removes @keystone-6/core/artifacts from our exports (#7972) @mitchellhamilton
    • [core] Removes disconnect from SessionStrategy (#7971) @mitchellhamilton
    • [core] Removes isLiveReload flag from createSystem (#7969) @mitchellhamilton
    • [core] Removes the @graphql-tools/schema wrapping functions graphQLSchemaExtension and gql. Developers should import @graphql-tools/schema themselves, or use graphql (as exported by @keystone-6/core). (#7943) @borisno2
    • [core] Removes filters export from @keystone-6/core/types (#7919) @mitchellhamilton
    • [core] Removes experimental.generateNodeAPI, use getContext instead (#7957) @dcousens
    • [core] db.onConnect is now called with an unprivileged context, not sudo. Use context.sudo() if you need to bypass access control (#7955) @dcousens
    • [core] Removes the parameters for getAdminMeta when writing field types, and the respective types AdminMetaRootVal, ListMetaRootVal and FieldMetaRootVal therein. (#7913) @mitchellhamilton
    • [core] Removes createSessionContext export from @keystone-6/core/session (#7912) @mitchellhamilton
    • [core] Changes default Apollo Server configuration to use cache: "bounded" and persistedQueries: false (#7888) @mitchellhamilton
    • [core] Changes .access control on list to required, with new allowAll and denyAll functions for easy shorthand. (#7848) @Noviny
    • [core] Upgrade to graphql@16 (#7817) @mitchellhamilton
    • [core] Changes field .views module resolution, from a path, to a module path that is resolved from where keystone start is run (#7805) @mitchellhamilton
    • [core] Changes the return type for the resolveInput hook with json fields. Previously you may have used 'DbNull' or 'JsonNull' as respective null magic values - you can now always use a Javascript null value. Unlike previous behaviour, a null value will now consistently map to a Prisma.DbNull. (#7671) @renovate

    New Features

    • [core] Adds [list].graphql.maxTake, a list configuration option to enforce the maximum take value in findMany queries for that list (#7963) @dcousens
    • [core] Adds new getContext function (from @keystone-6/core/context) for working with a Keystone configuration directly (#7954) @dcousens
    • [core] Adds a search input field to the list view, resulting in a contains query across ui.searchFields joined with the list view filters (#7841) @Noviny
    • [core] Adds a new isSingleton property for configuring Singleton lists (#7863) @mitchellhamilton

    Bug Fixes

    • [core] Fixes JSON field type view assuming the empty string is equivalent to null (#7982) @dcousens
    • [auth] Adds type refinement for withAuth using a TypeInfo type parameter (#7831) @dcousens
    • [core] Removes experimental.enableNextJsGraphqlApiEndpoint (#7910) @mitchellhamilton
    • [core] Changed platform compilation to use esbuild, previously used next.js (#7809) @mitchellhamilton
    • [core] Removes prettier from formatting the generated schema.graphql (#7874) @mitchellhamilton

    :seedling: New Contributors

    Thanks to the following developers for making their first contributions to the project!

    :blue_heart: Acknowledgements

    Lastly, thanks to @dcousens (#8012,#7998,#7997,#7995,#7981,#7979,#7973,#7897,#7895,#7894,#7864), @renovate (#8008,#7988,#7976,#7938,#7854,#7892,#7886,#7885,#7868), @flexdinesh (#8004,#8002,#7987,#7994,#7983,#7937,#7813), @mitchellhamilton (#7999,#7990,#7991,#7960,#7951,#7953,#7928,#7921,#7911,#7903,#7882,#7887,#7871,#7872,#7845,#7844), @Tekipeps (#7989), @Noviny (#7941) for changes not shown above, but none-the-less appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 2022-10-18(Oct 17, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    

    Security Updates

    We have identified and fixed 1 security vulnerabilities

    • GHSA-6mhr-52mv-6v6f - The multiselect field is vulnerable to a field-level access-control bypass. We have patched the vulnerability in this release.

    Bug Fixes

    • [core] Fixes the multiselect field type not using the provided label, access, graphql, isFilterable or isOrderable configuration options (#8007) @marekryb
    • [core] Fixes BigInt values throwing on deserialisation in the item view (#8005) @dcousens

    :seedling: New Contributors

    Thanks to the following developers for making their first contributions to the project!

    Source code(tar.gz)
    Source code(zip)
  • 2022-09-20(Sep 20, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    

    Bug Fixes

    • [fields-document] Fixes a broken code path for conditional component-blocks when fields are missing - this previously resulted in invalid data structures within the document editor (#7922) @mitchellhamilton
    Source code(tar.gz)
    Source code(zip)
  • 2022-09-15(Sep 15, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    @keystone-6/[email protected]
    

    New Features

    • [core] Fixes return types for context.graphql so that correct types are returned when using a TypedDocumentNode (#7878) @borisno2

    Bug Fixes

    • [fields-document] Fixes expand/collapse button in the editor (#7926) @mitchellhamilton
    • [core] Adds contextualised types when using the graphql export for GraphQL schema extensions (#7877) @dcousens
    • [core] Fixes nullable and non-nullable calendarDay fields existing in the same schema creating a GraphQL schema with two different types with the same name (#7866) @acburdine
    • [core] Fixes types for resolvedData, and the return types for resolveInput hooks. (#7833) @Noviny

    :seedling: New Contributors

    Thanks to the following developers for making their first contributions to the project!

    :blue_heart: Acknowledgements

    Lastly, thanks to @dcousens (#7876,#7839,#7832,#7819), @mitchellhamilton (#7875,#7873,#7847,#7830,#7828,#7818,#7928), @dependabot[bot] (#7869), @renovate[bot] (#7862,#7860,#7826,#7825,#7823,#7824), @renovate (#7721,#7812) and @moselhy (#7843) for changes not shown above, but none-the-less appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 2022-08-19(Aug 18, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    

    New Features

    • [core] Adds cli functions as exports to @keystone-6/core/scripts/cli, assume to be an experimental unstable export and may change in a patch release. (#5645) @gautamsi
    • [core] Adds 'graphql' schema to extendHttpServer. (#7722) @borisno2
    • [core] Adds the ability to set additional Prisma datasource fields in the schema.prisma file, for example, referentialIntegrity by adding options to db.additionalPrismaDatasourceProperties (#7747) @willemmulder
    • [core] Adds http.Server options as configuration server.options (#7324) @dcousens
    • [core] Adds a new multiselect field type (#7683) @Achisingh
    • [core] Adds calendarDay field to store a date without a time or timezone attached (#7658) @Achisingh
    • [core] Adds ui.displayMode: 'radio' as an option for the select field. (#7752) @Achisingh
    • [fields-document] Changes the editors default overflow behaviour to align with other multi-line text inputs, supporting scrolling instead of an unbounded height for the field. (#7729) @Achisingh
    • [core] Adds a new bigInt field type, an integer of width 8 bytes (64 bits), analogous with Prisma's BigInt. (#5175) @MurzNN

    Bug Fixes

    • [core] Removes wrong types for resolveInput hooks until actual types are provided (#7801) @dcousens
    • [auth, cloudinary, core, document-renderer, fields-document, session-store-redis] Removes node .engines restrictions (#7804) @dcousens
    • [cloudinary, core] Updates graphql-upload to 15.0.2 (#7803) @mitchellhamilton
    • [core] Fixes environment variable PORT= precedence; PORT= now takes priority over the configured server.port (#7787) @dcousens
    • [fields-document] Fixes the document editor erroring when handling HTML in certain cases (#7764) @mitchellhamilton
    • [fields-document] Fixes long lines in code blocks in the document editor overflowing the editor (#7783) @mitchellhamilton
    • [fields-document] Fixes pasting plain text in the document editor removing markdown link definition and usages (#null) @mitchellhamilton
    • [session-store-redis] Fixes errors not being thrown by your @redis/client on connect (#7771) @Noviny
    • [fields-document] Adds support for pasting a url onto text to create a link (#7766) @mitchellhamilton
    • [core] Updates @apollo/client to 3.6.9 (#7744) @mitchellhamilton
    • [core] Updates @graphql-ts/schema to 0.5.3 (#7742) @mitchellhamilton
    • [core] Fixes return type of findOne to support null, which is returned if no item is found (#7731) @nderkim

    :rotating_light: Security Updates

    We have identified and fixed 1 upstream security vulnerability

    • CVE-2022-24434 - An upstream transitive dependency dicer is vulnerable to a complete denial-of-service attack. We have upgraded to a version of graphql-upload package to a version that doesn't use dicer.

    :seedling: New Contributors

    Thanks to the following developers for making their first contributions to the project!

    :blue_heart: Acknowledgements

    Lastly, thanks to @mitchellhamilton (#7786,#7785,#7784,#7769,#7745), @renovate (#7797,#7798,#7670,#7780,#7781,#7779,#7755,#7487,#7725), @dcousens (#7713,#7743,#7739,#7730), @Noviny (#7770), @Achisingh (#7757), @dependabot (#7728) for changes not shown above, but none-the-less appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 2022-07-14(Jul 14, 2022)

    The following packages have been updated

    @keystone-6/[email protected]
    

    Bug Fixes

    • [fields-document] Updates slate and slate-react to ^0.81.1 (#7701) @mitchellhamilton
    • [fields-document] Fixes inline relationships being removed when loading/saving an item in the Admin UI (#7685, #7700) @mitchellhamilton

    Acknowledgements :blue_heart:

    Thanks to @Skulek (#7695) for their first contribution to the project.

    Source code(tar.gz)
    Source code(zip)
  • 2022-06-30(Jun 30, 2022)

    30 June 2022

    Feature release.

    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    @keystone-6/[email protected]
    

    Adds MySQL Support

    Keystone now supports MySQL by setting mysql in your db.provider see pull request #7538 for further information.

    :warning: There are some differences in how Postgres and MySQL operate so be sure to checkout our new choosing the right database guide.

    Admin UI Improvements

    • :heavy_plus_sign: Adds ui.description for fields to show a description below the label in the Admin UI - #7578
    • :heavy_plus_sign: Adds the ability to set ambiguous plurals - like Firmware or Shrimp - as list names without receiving an error. This builds on the existing graphql.plural configuration by adding the configuration options of ui.label, ui.singular, ui.plural and ui.path to change the auto-generated names of lists used in the Admin UI #7657
    • Fixes the inconsistent spacing in the Admin UI on relationships fields using the cards display mode - #7616
    • Fixes the semantic-based browser input behaviour for inline create and edit forms on relationship fields when using the cards display mode - #7629
    • Fixes the layout and component block floating toolbars from being shown behind other elements - #7604
    • Moves the remove button in component block array fields from inside a menu on the drag handle to the right of the drag handle - #7626
    • Fixes the document editor from breaking when the underlying schema for a component has a new field added. Please note that new fields will still be missing for existing data when fetched from GraphQL - #7674
    • Changes segmented control to not show a clear button if isRequired is set - #7639 Thanks @u-ishii

    Other Improvements :sparkles:

    • :heavy_plus_sign: Changes the cloudinaryImage GraphQL output type to be exported for developer usage, for example in virtual fields - #7607 Thanks @mmachatschek!
    • :heavy_plus_sign: Adds support for Prisma's shadowDatabaseUrl option with db.shadowDatabaseUrl. Your Prisma schemas will now always include shadowDatabaseUrl = env("SHADOW_DATABASE_URL"), though using db.shadowDatabaseUrl is optional - #7350 Thanks @chelkyl and @jlarmstrongiv!
    • :heavy_plus_sign: Adds support for BigInt autoincrement id fields with idField: { kind: 'autoincrement', type: 'BigInt' } - #7188 Thanks @MurzNN!
    • Fixes for graphQLSchemaExtension, custom resolvers, if replacing default resolvers, were previously broken - #7644
    • :heavy_plus_sign: Adds db.nativeType option to the text field to customise the database type - #7538
    • Fixes the generation of an invalid Prisma schema when {field}.isIndexed: true and {field}.db.map are set - #7666 Thanks @TonnyORG!

    Acknowledgements :blue_heart:

    Big shoutout to the following community members for their help in improving our documentation with their contributions:

    Thanks to @mmachatschek (#7607), @ratson (#7627), @chelkyl (#7350) and @u-ishii (#7639) for making their first contributions to the project!

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect with Keystone on Twitter and in Slack.

    Verbose Changelog :scroll:

    You can also view the verbose changelog or compare via GitHub since 2022-06-09

    Source code(tar.gz)
    Source code(zip)
  • 2022-06-09(Jun 9, 2022)

    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-ui/[email protected]
    πŸ¦‹  @keystone-6/[email protected]
    πŸ¦‹  @keystone-6/[email protected]
    πŸ¦‹  @keystone-6/[email protected]
    πŸ¦‹  @keystone-6/[email protected]
    πŸ¦‹  @keystone-6/[email protected]
    πŸ¦‹  @keystone-6/[email protected]
    

    New Features

    Array Fields and Components Blocks

    Warning: This new feature includes breaking changes that may affect you

    Changes to the underlying document-editor component block interfaces, with the addition of array fields. The breaking changes are only for defining components, no database migration is needed.

    The breaking changes for @keystone-6/fields-document/component-blocks are:

    • :warning: For the arguments of the component function, rename component to preview
    • :warning: For the arguments of the component function, rename props to schema
    • :warning: For your component .schema (previously .props), rename props.{innerFieldName} to props.fields.{innerFieldName}.
    • :warning: When rendering child field React components, change props.{innerFieldName} to props.{innerFieldName}.element.

    For example, use props.fields.title instead of props.title. For a nested example, use props.fields.someObject.fields.title instead of props.someObject.title.

    See pull request #7428 for information on how to upgrade and solutions to common problems. If you have any other questions, please don't hesitate to open a GitHub discussion.

    Images and Files

    Warning: This new feature includes breaking changes that may affect you

    The image and files configuration options have been removed from Keystone's configuration, and a new storage configuration object introduced.

    • :heavy_plus_sign: Amazon S3 (and other compatible providers) are now supported when uploading images and files
    • :heavy_plus_sign: New Guide coming - see #7563 will be merged soon but check it out if you are keen
    • :rotating_light: Images and files are now - DELETED BY DEFAULT from the underlying storage provider when replaced or deleted from the database
      • Note: A preserve flag has been added to the new storage configurations to default back to the previous behaviour

    • :warning: If you were previously using refs in your application, you need to migrate your database

    See pull request #7070 for information on how to upgrade and solutions to common problems. If you have any other questions, please don't hesitate to open a GitHub discussion.

    Other Improvements

    Major Dependency Upgrades

    If you can't upgrade your dependencies for any reason and you think Keystone might be able to help, please open a GitHub discussion so we can try and help you.

    React 18.1.0

    We have updated React to version 18 (pull request #7410).

    Redis 4

    Our @keystone-6/session-store-redis package has been upgraded to use @redis/[email protected]/[email protected] (pull request #7051).

    Configuration

    Added support for body-parser options when configuring GraphQL #7591

    Admin UI

    The following changes include a number of accessibility and quality of life improvements for users of the admin interface.

    • List descriptions now display in the Admin UI - #7537
    • Fixed the viewport sometimes shifting when opening the date picker in the create drawer - #7543
    • Removed all Keystone Links, i.e. API explorer, GitHub repository and Keystone documentation, from the popover and replacing the popover button with Sign out button in production - #7546
    • Fixed document editor preventing tabbing out of the editor - #7547
    • The label shown for a text field in the Admin UI is now associated with the input so the label can be read by screen readers - #7548
    • The document editor label is now associated with the editable element so the label can be read by screen readers - #7549
    • Fixed z-index issues occurring when pop-overs in document editor text-area or the toolbar overlapped other fields and buttons - #7556
    • Alert dialogs are now centered in the Admin UI - #7561
    • The reset changes button on the item view now presents a confirmation modal before resetting changes and it has been moved to the right of the bottom bar so it is next to the delete button. - #7562
    • Fixed splitting text with marks/inlines into multiple list items when turning a paragraph into a list and splitting a single list item with marks/inlines into multiple paragraphs when turning a list into paragraphs - #7565
    • Replaced create item drawer with a page when creating an item from the list view or dashboard - #7594
    • Fixed the Admin UI crashing when saving an item with a relationship field using the cards display mode when another item is added to the relationship (e.g. by another user or a hook) since the item was initially loaded - #7598

    Could not find prisma-fmt binaries

    A number of users have reported problems with the Prisma binaries not being installed properly by their package manager.

    As part of pull request #7595 the Prisma binaries are now downloaded just before they're needed. Note this should not happen in production, they should still be downloaded before as part of your deployment step.

    Acknowledgements

    Big shoutout to the following community members for their help in improving our documentation with their contributions:

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect with Keystone on Twitter and in Slack.

    Changelog

    You can also view the verbose changelog in this pull request.

    Source code(tar.gz)
    Source code(zip)
  • 2022-05-12(May 12, 2022)

    Maintenance release.

    "@keystone-6/core": "1.1.1"
    "@keystone-6/fields-document": "2.0.1"
    

    Core changes βš™οΈ

    • Fixed decimal validation.min not being respected and validation.max being used as the min if provided.

    Admin UI – quality of life improvements ✨

    • The Admin UI now prompts users to confirm they want to navigate away when there are unsaved changes.
    • Fixed the JSON field not showing any formatting when the field mode is read-only
    • Updated the list page to show the reset to default button when any sorting, or other field value filters are provided
    • Updated the styling for the relationship select to be less confusing when the field mode is read-only
    • Improvements to the document editor toolbar:
      • the toolbar is now hidden when the field mode is read-only
      • fixed a z-index issue
    • Fixed read only view for segmented control display mode in the select field. When a segmented-control select field is in read mode, the values no longer appear editable.

    Dependencies ⬆️

    • Upgrade react-day-picker to v8

    New team members πŸ₯³

    We’re proud to announce that two new members have joined the team:

    • @Achi06 is a Software Developer who focuses on Front End. Achi has worked as an Angular Developer for HCL at Coles, an on several government projects including TAC and Queensland Health.
    • @borisno2 – the author behind the Keystone next auth plugin is now an official part of team Keystone. An awesome example of the power of OSS communities πŸ’™

    If you’re an AU or NZ based developer or designer looking to work on projects like Keystone, feel free to send your CV through to us at Thinkmill.

    Community Contributors

    • Thanks @moselhy! - Fixed React key warning when showing GraphQL errors
    • Thanks @MurzNN! - Added sandbox configs for all examples, so now all our examples can be launched on the codesandbox.io service. Give it a try in our blog example πŸš€

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect to Keystone on Twitter and in Slack.

    Changelog

    You can also view the verbose changelog in this pull request.

    Source code(tar.gz)
    Source code(zip)
  • 2022-03-25(Mar 25, 2022)

    Maintenance release.

    "@keystone-6/auth": "2.0.0",
    "@keystone-6/cloudinary": "2.0.0",
    "@keystone-6/core": "1.1.0",
    "@keystone-6/fields-document": "2.0.0",
    "@keystone-6/session-store-redis": "2.0.0",
    

    ⚠️   This release contains a breaking change! Please read the instructions below.

    Core βš™οΈ

    Date Selection Issue

    When selecting a date, the date picker sometimes changed to the previous day, this is now resolved.

    The root of the problem as highlighted in https://github.com/keystonejs/keystone/issues/6115 is the inconsistency in how browsers handle new Date(value) where value is some string representation of a Date.

    Year, month, and day to Date is now explicitly passed in for more deterministic behaviour.

    Thanks @ChuckJonas and community members for reporting this issue.

    Relationships in Component Blocks

    ⚠️   Breaking change! Please follow the guidance below.

    We've moved the configuration for relationships in component blocks, if you have relationships in component blocks, you'll need to update your configuration.

    This configuration has moved so that it's configured at the relationship prop rather than in the relationships key on the document field config.

    The relationships key in the document field config now exclusively refers to inline relationships.

    We have also added documentation for child fields and early validation for checking that relationships in the document field (both inline relationships and props in component blocks) refer to lists that actually exist.

    Before:

    import { config, list } from '@keystone-6/core';
    import { document } from '@keystone-6/fields-document';
    export default config({
      lists: {
        ListName: list({
          fields: {
            fieldName: document({
              relationships: {
                featuredAuthors: {
                  kind: 'prop',
                  listKey: 'Author',
                  selection: 'id name posts { title }',
                  many: true,
                },
              },
              /* ... */
            }),
            /* ... */
          },
        }),
        /* ... */
      },
      /* ... */
    });
    
    import { fields } from '@keystone-6/fields-document/component-blocks';
    fields.relationship({ label: 'Authors', relationship: 'featuredAuthors' });
    

    After:

    import { fields } from '@keystone-6/fields-document/component-blocks';
    fields.relationship({
      label: 'Authors',
      listKey: 'Author',
      selection: 'id name posts { title }',
      many: true,
    });
    

    Miscellaneous

    • Added support for extending the underlying Node.js http server, thanks @lachieh!
    • Fixed issues with float field filtering when the field is required with default value, thanks @gautamsi!
    • Bumped Next.js from 12.0.7 to 12.1.0, which fixed using require.resolve to get the paths to views not working with newer versions of Next.js
    • Updated Prisma to 3.9.2

    Admin UI πŸ‘€

    • Fixes a bug where headings would appear in shortcut menu even when they were disabled
    • Fixes a bug where the shortcuts menu would clip behind the styles menu - it is now always above the styles menu
    • Fixed Popover component to toggle open and closed on click of the trigger, previously trigger click would only open the dialog. This is necessary because the Admin UI has limited usability on mobile phones, and when certain dialogs open, it is difficult to close by clicking outside. This adds the option of closing it by clicking the menu button again.
    • Fixed cards view in the relationship field not showing up for many relationships in the create view
    • Improved how stacking contexts are organised in the Admin UI
    • Minor a11y improvement to table browsing

    Documentation ✏️

    • Fixed invalid field value for Selection in docs for Component Block Relationship Fields, thanks @nizhu!

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect to Keystone on Twitter and in Slack.

    Changelog

    You can also view the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/7219) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2022-01-10(Jan 10, 2022)

    This patch release is related to security advisory CVE-2022-0087.

    "@keystone-6/auth": "1.0.2"
    

    Security Advisory πŸ”’

    This patch is relating to a security advisory that removes the capability for an attacker to exploit a reflected cross-site scripting vulnerability when using a previous version of the @keystone-6/auth package. The original security advisory is located here.

    Impact

    The vulnerability can impact users of the administration user interface when following an untrusted link to the signin or init page. This is a targeted attack and may present itself in the form of phishing and or chained in conjunction with some other vulnerability.

    Mitigation

    Please upgrade to @keystone-6/auth >= 1.0.2 (this patch), where this vulnerability has been closed. If you are using @keystone-next/auth, we strongly recommend you upgrade to @keystone-6.

    Workarounds

    If for some reason you cannot upgrade the dependencies in software, you could alternatively

    • disable the administration user interface, or
    • if using a reverse-proxy, strip query parameters when accessing the administration interface

    References

    https://owasp.org/www-community/attacks/xss/

    Credits

    Thanks to Shivansh Khari (@Shivansh-Khari) for discovering and reporting this vulnerability.

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect to Keystone on Twitter and in Slack.

    Changelog

    You can also view the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/7156) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-12-22(Dec 22, 2021)

    Patch release.

    "@keystone-6/auth": "1.0.1",
    "@keystone-6/core": "1.0.1",
    

    Miscellaneous Fixes βš™οΈ

    • Page titles now reflect the page you are on: item view shows the item's label, list view shows the list name, other pages show Keystone
    • Refactoring of TypeScript type generation
    • Fixed the inferred type of a field resolveInput hook to support returning undefined
    • Explicitly disable caching for redirect responses in the Admin UI
    • Fixed error You must await server.start() before calling server.createHandler() when using the generateNextGraphqlAPI experimental option
    • Fixed setting db.enableLoggingto false erroring
    • Removed redundant fast-glob dependency
    • Updated Prisma monorepo to v3.6.0
    • Fixed Lists import in artifacts types, thanks @SerWonka!

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect to Keystone on Twitter and in Slack.

    Changelog

    You can also view the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/7044) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-12-01(Dec 1, 2021)

    This release marks the achievement of General Availability status for Keystone 6! πŸš€

    We've also included a range of improvements to Keystone's TypeScript DX since shipping last week's release candidate.

    Keystone 6 ⚑️

    With this major release, the project has moved to the @keystone-6 namespace on npm, and our version numbers have been reset.

    We highly recommend you upgrade your existing Keystone Next projects to Keystone 6 with the packages below:

    "@keystone-6/auth": "1.0.0",
    "@keystone-6/cloudinary": "1.0.0",
    "@keystone-6/document-renderer": "1.0.0",
    "@keystone-6/fields-document": "1.0.0",
    "@keystone-6/core": "1.0.0",
    "@keystone-6/session-store-redis": "1.0.0",
    

    Note: @keystone-next/keystone has been changed to @keystone-6/core

    Among other internal naming changes, our CLI commands have switched from keystone-next to simply keystone, please ensure you update your startup scripts to suit!

    Note: To learn more about this major release and what's in store for the road ahead, checkout our official general availability announcement and updated roadmap.

    Type Enhancements ✨

    We've shipped a significant update to our generated TypeScript types.

    The types for your schema are stricter when your lists are contextually typed by the newly provided Lists types from .keystone/types. This results in a smoother, type-safe auto-complete experience and stricter types for your access control, hooks, and any other code that uses a Keystone context.

    For example, if you write all your lists in one object:

    import { Lists } from '.keystone/types'
    
    export const lists: Lists = {
      Blah: list({...})
    }
    

    If you're defining your lists separately, you can do this:

    import { Lists } from '.keystone/types'
    
    export const Blah: Lists.Blah = list({
      ...
    })
    

    For a more in-depth view of what TypeScript types have been changed, see below:

    • The following types have been renamed:
      • BaseGeneratedListTypes β†’ BaseListTypeInfo
      • ItemRootValue β†’ BaseItem
      • ListInfo β†’ ListGraphQLTypes
      • TypesForList β†’ GraphQLTypesForList
      • FieldTypeFunc now has a required type parameter which must satisfy BaseListTypeInfo
    • The following types now have a required type parameter which must satisfy BaseKeystoneTypeInfo:
      • ServerConfig
      • CreateRequestContext
      • AdminUIConfig
      • DatabaseConfig
      • ListOperationAccessControl
      • MaybeSessionFunction
      • MaybeItemFunction
    • GraphQLResolver and GraphQLSchemaExtension now have a required type parameter which must satisfy KeystoneContext
    • KeystoneGraphQLAPI no longer has a type parameter
    • The first parameter to the resolver in a virtual field will be typed as the item type if the list is typed with Keystone.Lists or Keystone.Lists.ListKey, otherwise it will be typed as unknown
    • The item/originalItem arguments in hooks/access control will now receive the Item type if the list is typed with Keystone.Lists or Keystone.Lists.ListKey, otherwise it will be typed as BaseItem
    • args has been removed from BaseListTypeInfo
    • inputs.orderBy and all has been added to BaseListTypeInfo
    • In .keystone/types:
      • ListKeyListTypeInfo has been moved to Lists.ListKey.TypeInfo
      • KeystoneContext has been renamed to Context

    Credits πŸ’«

    This release would not have been possible without the support and feedback of such an awesome developer community.

    We're grateful for the ideas you bring, the help you give others, and the code contributions the you've made to get Keystone to where it is today.

    Like this release? Give us a star on GitHub!

    Changelog

    You can view the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/7018) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-11-24(Nov 24, 2021)

    The Release Candidate for Keystone 6 General Availability has arrived! Within you'll find numerous improvements across the project. ⭐️

    After this release, we will be moving Keystone 6 to General Availability and promoting the project to the @keystone-6 namespace on npm.

    We highly recommend you upgrade to this release:

    "@keystone-next/auth": "37.0.0",
    "@keystone-next/cloudinary": "12.0.0",
    "@keystone-next/document-renderer": "5.0.0",
    "@keystone-next/fields-document": "14.0.0",
    "@keystone-next/keystone": "29.0.0",
    "@keystone-next/session-store-redis": "9.0.0",
    

    ⚠️   This release contains breaking changes! Please backup your data before upgrading and read the instructions below.

    Shorter Relationship Names 🀏

    Warning: ⚠️ Breaking change! Please follow the guidance below to avoid losing data.

    The names of one-sided and two-sided, many-many relationships has been shortened. Two-sided many-many relationship names contain only the left-hand side names now; and the _many suffix has been dropped from one-sided many-many relationships.

    This reduces the probability that you will exceed PostgreSQL's 63 character limit for identifiers with typical usage.

    There are two different ways you can update your schema:

    • Explicitly set the db.relationName on many-to-many relations, allowing your database to remain unchanged.

    • Rename your many-to-many relations and tables using a migration, changing your database.

    Set db.relationName on many to many relations

    Rather than doing a migration, you can set the new field property db.relationName, for either side of a many-to-many relationship field.

    If set to the existing relation name, your database will remain unchanged.

    For example, given a schema like this:

    Post: list({
      fields: {
        tags: relationship({ ref: 'Tag.posts', many: true }),
      },
    }),
    Tag: list({
      fields: {
        posts: relationship({ ref: 'Post.tags', many: true }),
      },
    }),
    

    Before this release, the generated Prisma schema looked like this:

    // This file is automatically generated by Keystone, do not modify it manually.
    // Modify your Keystone config when you want to change this.
    
    datasource postgresql {
      url      = env("DATABASE_URL")
      provider = "postgresql"
    }
    
    generator client {
      provider   = "prisma-client-js"
      output     = "node_modules/.prisma/client"
      engineType = "binary"
    }
    
    model Post {
      id   String @id @default(cuid())
      tags Tag[]  @relation("Post_tags_Tag_posts")
    }
    
    model Tag {
      id    String @id @default(cuid())
      posts Post[] @relation("Post_tags_Tag_posts")
    }
    

    By adding db: { relationName: 'Post_tags_Tag_posts' } to one side of the many-to-many relationship; you can preclude yourself from a migration.

    Note: It doesn't matter which side of the relationship you put this property, but it should be only on one side; otherwise you will receive an error.

    Post: list({
      fields: {
        tags: relationship({ ref: 'Tag.posts', many: true, db: { relationName: 'Post_tags_Tag_posts' } }),
      },
    }),
    Tag: list({
      fields: {
        posts: relationship({ ref: 'Post.tags', many: true }),
      },
    }),
    

    Rename your many relation tables using a migration

    For example, given a schema like this:

    Post: list({
      fields: {
        tags: relationship({ ref: 'Tag.posts', many: true }),
      },
    }),
    Tag: list({
      fields: {
        posts: relationship({ ref: 'Post.tags', many: true }),
      },
    }),
    

    When updating to this change, and running yarn dev, Keystone will prompt you to update your schema.

    Warning: ⚠️ Warning: DO NOT APPLY THE AUTOMATICALLY GENERATED MIGRATION!
    You will lose your data. Only apply the migration if you want to DROP your data.

    If using useMigrations: true, Keystone will follow the typical migration flow and offer to apply an automatically generated migration.

    If using useMigrations: false, Keystone will follow the typical flow and offer to automatically migrate your schema.

    On PostgreSQL, Prisma will generate a migration that looks something like this:

    /*
      Warnings:
    
      - You are about to drop the `_Post_tags_Tag_posts` table. If the table is not empty, all the data it contains will be lost.
    
    */
    -- DropForeignKey
    ALTER TABLE "_Post_tags_Tag_posts" DROP CONSTRAINT "_Post_tags_Tag_posts_A_fkey";
    
    -- DropForeignKey
    ALTER TABLE "_Post_tags_Tag_posts" DROP CONSTRAINT "_Post_tags_Tag_posts_B_fkey";
    
    -- DropTable
    DROP TABLE "_Post_tags_Tag_posts";
    
    -- CreateTable
    CREATE TABLE "_Post_tags" (
        "A" TEXT NOT NULL,
        "B" TEXT NOT NULL
    );
    
    -- CreateIndex
    CREATE UNIQUE INDEX "_Post_tags_AB_unique" ON "_Post_tags"("A", "B");
    
    -- CreateIndex
    CREATE INDEX "_Post_tags_B_index" ON "_Post_tags"("B");
    
    -- AddForeignKey
    ALTER TABLE "_Post_tags" ADD FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
    
    -- AddForeignKey
    ALTER TABLE "_Post_tags" ADD FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
    

    You need to modify it so that it looks like this with the old and new table names for your schema substituted:

    ALTER TABLE "_Post_tags_Tag_posts" RENAME TO "_Post_tags";
    ALTER INDEX "_Post_tags_Tag_posts_AB_unique" RENAME TO "_Post_tags_AB_unique";
    ALTER INDEX "_Post_tags_Tag_posts_B_index" RENAME TO "_Post_tags_B_index";
    ALTER TABLE "_Post_tags" RENAME CONSTRAINT "_Post_tags_Tag_posts_A_fkey" TO "_Post_tags_A_fkey";
    ALTER TABLE "_Post_tags" RENAME CONSTRAINT "_Post_tags_Tag_posts_B_fkey" TO "_Post_tags_B_fkey";
    

    On SQLite, Prisma will generate a migration that looks something like this:

    /*
      Warnings:
    
      - You are about to drop the `_Post_tags_Tag_posts` table. If the table is not empty, all the data it contains will be lost.
    
    */
    -- DropTable
    PRAGMA foreign_keys=off;
    DROP TABLE "_Post_tags_Tag_posts";
    PRAGMA foreign_keys=on;
    
    -- CreateTable
    CREATE TABLE "_Post_tags" (
        "A" TEXT NOT NULL,
        "B" TEXT NOT NULL,
        FOREIGN KEY ("A") REFERENCES "Post" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
        FOREIGN KEY ("B") REFERENCES "Tag" ("id") ON DELETE CASCADE ON UPDATE CASCADE
    );
    
    -- CreateIndex
    CREATE UNIQUE INDEX "_Post_tags_AB_unique" ON "_Post_tags"("A", "B");
    
    -- CreateIndex
    CREATE INDEX "_Post_tags_B_index" ON "_Post_tags"("B");
    

    You need to modify it so that it looks like this with the old and new table names for your schema substituted:

    ALTER TABLE "_Post_tags_Tag_posts" RENAME TO "_Post_tags";
    DROP INDEX "_Post_tags_Tag_posts_AB_unique";
    DROP INDEX "_Post_tags_Tag_posts_B_index";
    CREATE UNIQUE INDEX "_Post_tags_AB_unique" ON "_Post_tags"("A", "B");
    CREATE INDEX "_Post_tags_B_index" ON "_Post_tags"("B");
    

    Query Engine Switch πŸš‚

    Keystone now uses Prisma's Node-API Query Engine instead of the Binary Query Engine. This should improve the performance of operations using Prisma.

    From our initial testing, performance has increased significantly when getting large amounts of data and is marginally better for smaller amounts.

    See the Prisma docs for more details.

    Node Engines πŸ’½

    Keystone officially supports running on LTS versions of Node.js - this is currently version 14 and 16. We've updated our engine values throughout the project to reflect this.

    Note: We recommend you run Node.js ^14.15 or ^16.13 for the best Keystone experience.

    Miscellaneous Fixes βš™οΈ

    • Fixed the init/sign in page showing for a short amount of time after submitting on the init/sign in page and seeing a loading spinner.

    • Fixed clear button not removing inline relationships when used in the document field.

    • Relationship field now respects ui.displayMode: 'cards' in the create view.

    • The Set as Authenticated Item/Add Authenticated Item button is now hidden if the relationship field already has the authenticated item.

    • Fixed ui.isAccessAllowed not being respected in the admin meta query when no session strategy was defined.

    • The item page in the Admin UI no longer crashes when failing to fetch an item.

    • The admin meta query now bypasses ui.isAccessAllowed for sudo contexts.

    • Fixed doing multiple writes at the same time on SQLite causing an timeout immediately.

    Credits πŸ’«

    Like this release? Give us a star on GitHub!

    Changelog

    You can view the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/6943) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-11-15(Nov 17, 2021)

    Expanded unique filters, customisable table and column names support and a new example featuring Nexus as we continue to finalise our GA release. πŸͺ’

    "@keystone-next/auth": "36.0.0",
    "@keystone-next/cloudinary": "11.0.0",
    "@keystone-next/fields-document": "13.0.0",
    "@keystone-next/keystone": "28.0.0",
    "@keystone-next/session-store-redis": "8.0.0",
    

    Like this release? Give us a star on GitHub!

    Expanded Unique Filters πŸ”Ž

    select, timestamp, float and decimal fields with isIndexed: 'unique' now have unique filters via ListWhereUniqueInput which text, integer and the id field already support.

    For example, if you added isIndexed: 'unique' to a select field in a theoretical Settings list, you can now run the following query:

    query {
      setting ( where: { provider: "github" } ) {
        id
        token
      }
    }
    

    This is instead of running a settings query where you would have received a list back, and have had to check for results and get the first element:

    query {
      settings ( where: { provider: { equals: "github" } } ) {
        id
        token
      }
    }
    

    Customisable Table and Column Names πŸ“‡

    You may now use different table and column names to those automatically chosen by Keystone for your list and field keys. This is powered by Prisma's @map and @@map attributes. You can read more about this concept in Prisma's documentation.

    This is useful if you do not want to modify your existing database (such as a read-only database) and use it with Keystone.

    For example if you wanted to refer to a table named stories but you refer to it in Keystone as Posts provide config.db.map to a list or field key such as:

    Post: list({
      db: {
        map: 'stories',
      },
      fields: {
        ...
      }
    })
    

    Nexus Example πŸͺ’

    We've got a new example using Nexus, a declarative, code-first and strongly typed GraphQL schema construction for TypeScript & JavaScript.

    Using Nexus you can extend the GraphQL API provided by Keystone with custom queries and mutations.

    In the example below we expose a mutation called nexusPosts which pulls out items from our Posts list that have been published within the past 7 days (by default), with an optional author filter.

    export const PostQuery = extendType({
      type: "Query",
      definition(t) {
        t.field("nexusPosts", {
          type: nonNull(list("NexusPost")),
          args: {
            authorId: stringArg(),
            days: nonNull(intArg({ default: 7 })),
          },
          async resolve(root, { authorId, days }, context) {
            const cutoff = new Date(
              new Date().setUTCDate(new Date().getUTCDate() - days)
            ).toISOString();
    
            return await context.prisma.post.findMany({
              where: {
                ...(authorId ? { author: { id: authorId } } : null),
                publishDate: { gt: cutoff },
              },
            });
          },
        });
      },
    });
    
    

    Check out the example in Keystone's examples directory.

    Miscellaneous Fixes βš™οΈ

    • The format of the date shown in the DatePicker now uses the user's locale.
    • When the sessionData option is invalid, the error will now be thrown on startup instead of silently ignored.

    Changelog

    You can also the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/6914) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-11-10(Nov 17, 2021)

    Patch release.

    "@keystone-next/keystone": "27.0.2",
    

    Miscellaneous Fixes βš™οΈ

    • Fixed importing packages that provide Node ESM
    • Local images and files are no longer restricted behind ui.isAccessAllowed
    • Updated Prisma monorepo to v3.4.0

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect to Keystone on Twitter and in Slack.

    Changelog

    You can also view the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/6892) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-11-03(Nov 17, 2021)

    Patch release.

    "@keystone-next/keystone": "27.0.1",
    

    Miscellaneous Fixes βš™οΈ

    • Fixed files with names including things like [...rest] created using ui.getAdditionalFiles being deleted after being written in dev.
    • Runtime type errors from Prisma are now actually returned instead of being returned as Prisma error:
    • Fixed Schema must contain uniquely named types but contains multiple types named "OrderDirection". error when running keystone-next build.

    Enjoying Keystone?

    Star this repo 🌟 ☝️ or connect to Keystone on Twitter and in Slack.

    Changelog

    You can also view the verbose changelog in the related PR (https://github.com/keystonejs/keystone/pull/6871) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-11-02(Nov 2, 2021)

    Server-side Live Reloading is here! πŸš€ Plus more updates as we finalise the Keystone 6 GA release.

    "keystone-next/auth": "35.0.0",
    "keystone-next/cloudinary": "10.0.0",
    "keystone-next/fields-document": "12.0.0",
    "keystone-next/keystone": "27.0.0",
    "keystone-next/session-store-redis": "7.0.0",
    

    Like this release? Give us a star on GitHub!

    Warning: ⚠️  This release contains breaking changes, please see below!

    Server-side Live Reloading πŸš€

    Keystone now supports live reloading with keystone-next dev.

    You can now update your GraphQL schema, change your hooks and access control, log errors and see how your data returns, then immediately use the playground to test it and iterate.

    This is in addition to the current support for live reloading changes to custom views in the Admin UI.

    How it works

    When you run keystone-next dev now, it will start watching for changes to your config and schema. When changes are detected, Keystone will reload your config and schema and hot-swap the GraphQL endpoint.

    To balance performance and predictability, Keystone does not do a complete restart when changes are made. The things to know are:

    Prisma Schema Changes

    The Prisma Client is not reloaded as you make changes to the Keystone Schema. If you make changes that affect your Prisma schema, Keystone will exit the process and wait for you to run keystone-next dev again.

    This is because making database schema changes involves generating database migrations, and can result in data loss if those migrations are automatically run against your current database.

    When adding or removing lists and fields (except virtual fields), we recommend you finish making your changes then start the dev process again. This will generate a single migration for all the changes you’ve made, and interactively prompt you to resolve any migrations that can't be run safely.

    onConnect is not hot reloaded

    The db.onConnect function (if specified) will only be run once when Keystone is started, and not when your config is hot reloaded.

    This is because onConnect is typically used to run data seeding and other once-off processes that should be executed once before the Keystone server comes online. Re-running it whenever a file is changed could result in a heavy database load, harming overall dev performance and introducing unpredictable behaviour.

    If you make changes to the onConnect function, you need to manually stop the dev process and start it again for your changes to take effect.

    GraphQL Playground and Apollo Sandbox 🏝

    In the last release we upgraded to Apollo Server 3 which brought Apollo Sandbox as the default development UI for testing your GraphQL queries.

    This surfaced a number of issues as Apollo Sandbox is hosted remotely rather than locally, including CORS issues and security concerns, making it a bad default.

    With this in mind, Keystone will now go back to using the GraphQL Playground by default instead of Apollo Sandbox as it did prior to updating to Apollo Server 3.

    We have now introduced the graphql.playground config option, with three possible settings:

    • true will configure Apollo Server plugins to enable the GraphQL Playground
    • false will configure Apollo Server plugins to disable any GET requests to the GraphQL endpoint
    • 'apollo' will add no plugins to Apollo Server, enabling the new Apollo Sandbox behaviour

    graphql.playground defaults to process.env.NODE_ENV !== 'production' which matches the previous Keystone 6 behaviour before the October update and Apollo Server 3.

    Next.js Update ✨

    We've updated our Next.js dependency from 11.x to 12.x! This latest release of Next.js includes a new Rust powered compiler with faster refresh and build rates, making your Keystone dev experience even faster.

    Check out the Next.js blog for more details.

    Relationship Filtering ❀️

    If you have hundreds of items in your relationship fields, the Admin UI was sometimes displaying duplicate entries and/or missing entries.

    We've made a series of improvements to fetching data resulting in a performance boost, as well as filtering fixes. We also changed the way we detect when an ID is pasted into the field allowing you to select a related item quickly.

    CORS Configuration 🌐

    We've removed the graphql.cors option, we had one too many ways to configure CORS and it was proving to be confusing.

    You should now exclusively configure cors with the server.cors option.

    Renamed src in Image and File Fields πŸ—„οΈ

    ⚠️   Breaking Change

    The src field on the output of image and file fields has been renamed to url.

    Subsequently the getSrc function on ImagesContext and FilesContext has been renamed to getUrl.

    Removed resolveFields 🚧

    The deprecated resolveFields from context.query has been removed.

    If you were still using it, you should switch to providing the query option to context.query or use context.db if you were providing false.

    The context.query functions will now also throw an error if an empty string is passed to query rather than silently returning what the context.db functions return, you must select at least one field or omit the query option to default to selecting the id.

    Internal Types Renamed ✏️

    We have updated @graphql-ts/schema to 0.5.0.

    The __rootVal properties on ObjectType, InterfaceType and UnionType have been renamed to __source, this is intended to be internal but you may have depended on it, if you were using it, rename __rootVal to __source.

    In addition the fields property on InterfaceType has been renamed to __fields and it will no longer exist at runtime like the other types.

    GraphQL Schema Reorder πŸ›—

    We've made internal changes to the endSession field on the Mutation type and the keystone field on the Query type. This may result in re-ordering in your generated schema.graphql file.

    Miscellaneous Fixes βš™οΈ

    • The sessionSchema export of @keystone-next/keystone/session has been removed.
    • context.session no longer has a value if the session is invalid.
    • text, integer, float and decimal on the item view now render correctly when using ui.itemView.fieldMode: 'read'.
    • Admin UI home page now respects ui.hideCreate and won't show a plus button when create is disabled.
    • Read-only arrays are now accepted where previously mutable arrays were required. Using as const when writing an array and then passing it to various APIs in Keystone will now work.
    • Fixed bug in LinkToRelatedItems button for double sided relationships.
    • Updated minor typos in GraphQL errors.

    Prisma Update πŸ—ƒ

    We've updated our Prisma dependency from 3.1.1 to 3.3.0!

    Check out the Prisma releases page for more details.

    Credits πŸ’«

    • Added a short plain-text display to document fields in the List view as well as a rendered document view in CardValue. Thanks @oplik0!

    • We now support extensions with numerical characters when generating safe filenames. Thanks @Zlitus!

    Changelog

    You can view the verbose change log in the related PR (https://github.com/keystonejs/keystone/pull/6762) for this release.

    Source code(tar.gz)
    Source code(zip)
  • 2021-10-05(Oct 5, 2021)

    We're nearly at Gold Master status for the Keystone 6 GA release! Here's what's new:

    • Fields Overhaul with lots of tweaks and additions πŸš€
    • Hook Updates bringing consolidation and clearer naming πŸͺ
    • Removal of unused return types and unused values 🚫
    • Renaming of options for consistency πŸ“›
    • Apollo Server Upgrade to version 3 πŸ‘©β€πŸš€
    • Improved Error Messaging πŸ“Ÿ
    • Performance updates for a faster Admin UI πŸƒβ€β™€οΈ
    • REST API Example using the new createContext inside extendExpressApp πŸ‘©β€πŸ«
    • Other Notable Changes to be aware of πŸ›ŽοΈ
    • Prisma Update from 2.x to 3.x πŸ—ƒ

    We've got further improvements to error messaging and performance to come in the next release!

    Warning: This release contains breaking changes, please see below!

    "@keystone-next/auth": "33.0.0",
    "@keystone-next/cloudinary": "8.0.0",
    "@keystone-next/fields-document": "10.0.0",
    "@keystone-next/keystone": "26.0.1",
    "@keystone-next/session-store-redis": "5.0.0",
    

    Upgrade Guide πŸ‘‡

    Be sure to read the entire release notes below for everything you need to know about this new release.

    The main things to keep in mind are:

    • defaultValue config is now static, if you have dynamic defaults, use the resolveInput hook
    • isRequired for fields is now validation: { isRequired } and we have new validation options such as min and max for some fields
    • We've made it clearer which fields are nullable in the database and tweaked the defaults, you now have more control but may need to migrate your database (more details below)
    • The hooks API has new arguments, and we've consolidated update and delete events into beforeOperation and afterOperation
    • context.lists has been renamed to context.query

    Fields Overhaul πŸš€

    Keystone's field types have been given a big overhaul - including several breaking changes, read on to understand what has changed.

    Warning: Some of these API changes are breaking and you will be required to update your project.

    text

    • defaultValue is now a static value
    • isRequired has moved to validation.isRequired
    • Now requires that the value has a length of at least one
    • New validation.length.min, validation.length.max and validation.match options

    float

    • defaultValue is now a static number
    • isRequired has moved to validation.isRequired
    • New validation.min and validation.max options

    integer

    • defaultValue is now a static number or { kind: 'autoincrement' }
    • isRequired has moved to validation.isRequired
    • New validation.min and validation.max options

    The autoIncrement field has also been removed, use the integer field with a defaultValue of { kind: 'autoincrement' }.

    decimal

    • defaultValue is now a static number written as a string
    • isRequired has moved to validation.isRequired
    • Now requires the input isn't NaN
    • New validation.min and validation.max options

    timestamp

    • defaultValue is now a static date time value in an ISO8601 string or { kind: 'now' }
    • isRequired has moved to validation.isRequired

    The field can also be automatically set to the current time on a create/update by setting db.updatedAt: true, this will add Prisma's @updatedAt attribute to the field.

    The timestamp field also now uses a custom GraphQL scalar type named DateTime which requires inputs as full ISO8601 date-time strings such as "2021-01-30T00:00:00.000Z". Using new Date().toISOString() will give you a string in the correct format.

    select

    • dataType has been renamed to type
    • defaultValue is now a static value
    • isRequired has moved to validation.isRequired

    The select can now also be cleared in the Admin UI when ui.displayMode is segmented-control.

    password

    • defaultValue has been removed
    • isRequired has moved to validation.isRequired
    • rejectCommon has moved to validation.rejectCommon
    • minLength has moved to validation.length.min
    • New validation.length.max and validation.match options

    validation.length.min also must be 1 or above, though it still defaults to 8.

    If workFactor is outside of the range of 6 to 31, an error will now be thrown instead of the previous behaviour of clamping the value to 4 to 31 and warning if it's below 6.

    image

    • Removed isRequired
    • Removed defaultValue

    If you were using these options, the same behaviour can be re-created with the validateInput and resolveInput hooks respectively.

    file

    • Removed isRequired
    • Removed defaultValue

    If you were using these options, the same behaviour can be re-created with the validateInput and resolveInput hooks respectively.

    cloudinaryImage

    • Removed isRequired
    • Removed defaultValue

    If you were using these options, the same behaviour can be re-created with the validateInput and resolveInput hooks respectively.

    json

    • Removed isRequired
    • defaultValue can no longer be dynamic in the json field

    If you were using isRequired, the same behaviour can be re-created with the validateInput hook.

    relationship

    • Removed defaultValue
    • Removed undocumented withMeta option

    To re-create defaultValue, you can use resolveInput though note that if you're using autoincrement ids, you need to return the id as number, not a string like you would provide to GraphQL, e.g. { connect: { id: 1 } } rather than { connect: { id: "1" } }.

    If you were using withMeta: false, please open an issue with your use case.

    checkbox

    The checkbox field is now non-nullable in the database, if you need three states, you should use the select field.

    The field no longer accepts dynamic default values and it will default to false unless a different defaultValue is specified.

    If you're using SQLite, Prisma will generate a migration that makes the column non-nullable and sets any rows that have null values to the defaultValue.

    If you're using PostgreSQL, Prisma will generate a migration but you'll need to modify it if you have nulls in a checkbox field. Keystone will say that the migration cannot be executed:

    ✨ Starting Keystone
    ⭐️ Dev Server Ready on http://localhost:3000
    ✨ Generating GraphQL and Prisma schemas
    ✨ There has been a change to your Keystone schema that requires a migration
    
    ⚠️ We found changes that cannot be executed:
    
      β€’ Made the column `isAdmin` on table `User` required, but there are 1 existing NULL values.
    
    βœ” Name of migration … make-is-admin-non-null
    ✨ A migration has been created at migrations/20210906053141_make_is_admin_non_null
    Please edit the migration and run keystone-next dev again to apply the migration
    

    The generated migration will look like this:

    /*
      Warnings:
    
      - Made the column `isAdmin` on table `User` required. This step will fail if there are existing NULL values in that column.
    
    */
    -- AlterTable
    ALTER TABLE "User" ALTER COLUMN "isAdmin" SET NOT NULL,
    ALTER COLUMN "isAdmin" SET DEFAULT false;
    

    To make it set any null values to false in your database, you need to modify it so that it looks like this but with the table and column names replaced.

    ALTER TABLE "User" ALTER COLUMN "isAdmin" SET DEFAULT false;
    UPDATE "User" SET "isAdmin" = DEFAULT WHERE "isAdmin" IS NULL;
    ALTER TABLE "User" ALTER COLUMN "isAdmin" SET NOT NULL;
    

    document

    The document field is now non-nullable in the database. The field no longer has defaultValue or isRequired options.

    The same behaviour can be re-created with the validateInput and resolveInput hooks respectively.

    The field will default to [{ "type": "paragraph", "children": [{ "text": "" }] }]. The output type has also been renamed to ListKey_fieldKey_Document

    If you're using SQLite, Prisma will generate a migration that makes the column non-nullable and sets any rows that have null values to an empty paragraph.

    If you're using PostgreSQL, Prisma will generate a migration but you'll need to modify it if you have nulls in a document field.

    Keystone will say that the migration cannot be executed:

    ✨ Starting Keystone
    ⭐️ Dev Server Ready on http://localhost:3000
    ✨ Generating GraphQL and Prisma schemas
    ✨ There has been a change to your Keystone schema that requires a migration
    
    ⚠️ We found changes that cannot be executed:
    
      β€’ Made the column `content` on table `Post` required, but there are 1 existing NULL values.
    
    βœ” Name of migration … make_document_field_non_null
    ✨ A migration has been created at migrations/20210915050920_make_document_field_non_null
    Please edit the migration and run keystone-next dev again to apply the migration
    

    The generated migration will look like this:

    /*
      Warnings:
    
      - Made the column `content` on table `Post` required. This step will fail if there are existing NULL values in that column.
    
    */
    -- AlterTable
    ALTER TABLE "Post" ALTER COLUMN "content" SET NOT NULL,
    ALTER COLUMN "content" SET DEFAULT E'[{"type":"paragraph","children":[{"text":""}]}]';
    

    To make it set any null values to an empty paragraph in your database, you need to modify it so that it looks like this but with the table and column names replaced.

    ALTER TABLE "Post" ALTER COLUMN "content" SET DEFAULT E'[{"type":"paragraph","children":[{"text":""}]}]';
    UPDATE "Post" SET "content" = DEFAULT WHERE "content" IS NULL;
    ALTER TABLE "Post" ALTER COLUMN "content" SET NOT NULL;
    

    general

    text, float, integer, decimal, timestamp, select, password can be made non-nullable at the database-level with the isNullable option which defaults to true, except for text which defaults to false.

    All fields above except password can also have:

    • graphql.read.isNonNull set if the field has isNullable: false and you have no read access control and you don't intend to add any in the future, it will make the GraphQL output field non-nullable.

    • graphql.create.isNonNull set if you have no create access control and you don't intend to add any in the future, it will make the GraphQL create input field non-nullable.

    Keep in mind, checkbox is now always non-nullable.

    Hook Updates πŸͺ

    We've consolidated the beforeChange/beforeDelete and afterChange/afterDelete hooks into beforeOperation and afterOperation.

    Additionaly, we've renamed:

    • originalInput for access control functions to inputData

    • originalInput for hook functions to inputData

    • existingItem for all hooks (except afterOperation) to item

    • existingItem for afterOperation to originalItem

    • updatedItem for afterOperation to item

    See the Hooks API docs for a complete reference for the updated API!

    Removals 🚫

    Some unused return types and unused values from enum definitions have been removed:

    • sendUserPasswordResetLink and sendUserMagicAuthLink only ever return null, so now have return types of Boolean.
    • UserAuthenticationWithPasswordFailure no longer has a code value.
    • MagicLinkRedemptionErrorCode and PasswordResetRedemptionErrorCode no longer have the values IDENTITY_NOT_FOUND, MULTIPLE_IDENTITY_MATCHES, TOKEN_NOT_SET, or TOKEN_MISMATCH.

    If you were using the createSchema function, you can also remove the call to createSchema and pass the lists directly to the lists property.

    Before:

    import { config, createSchema, list } from '@keystone-next/keystone';
    
    config({
      lists: createSchema({
       User: list({ ... }),
      }),
    })
    

    After:

    import { config, list } from '@keystone-next/keystone';
    
    config({
      lists: {
       User: list({ ... }),
      },
     })
    

    We've removed the deprecated config.db.adapter option. Please use config.db.provider to indicate the database provider for your system.

    Finally, the internal protectIdentities variable which was previously hardcoded to true to protect user data, there are no immediate plans to implement this as a configurable option.

    Renames πŸ“‡

    The API context.lists has been renamed to context.query, and context.db.lists has been renamed to context.db.

    The skipAccessControl argument to createContext to sudo for consistency with context.sudo().

    When using the experimental option config.experimental.generateNodeAPI, the api module now exports query rather than lists.

    Renamed graphQLReturnFragment to ui.query in the virtual field options. The virtual field now checks if ui.query is required for the GraphQL output type, and throws an error if it is missing. If you don't want want the Admin UI to fetch the field, you can set ui.itemView.fieldMode and ui.listView.fieldMode to 'hidden' instead of providing ui.query.

    Also, we've moved the graphql export of @keystone-next/keystone/types to @keystone-next/keystone.

    Improved Error Messaging πŸ“Ÿ

    Error messages have been improved across the board, in summary:

    • On startup, we now output where the GraphQL API is located
    • If access is denied errors are thrown, we now state which operation isn't permitted
    • Bad relationship field inputs are detected and outputed
    • Clearer distinction if a user input is invalid
    • If access control functions return invalid values we state what we got and what we expected
    • Improved the error messages provided from the GraphQL API when extension code (e.g access control functions, hooks, etc) throws exceptions
    • Better formatting of GraphQL error messages resulting from Prisma errors
    • Clearer sign-in errors when logging into the Admin UI
    • Improved error messages when returning bad filters from filter access control

    Performance πŸš…

    Field Mode

    We've optimised the itemView field mode fetching - we now only fetch the item once to determine the field modes rather than once per field.

    The Admin UI will also skip fetching fields that have a statically set itemView.fieldMode: 'hidden' on the itemView.

    The id argument to the KeystoneAdminUIFieldMeta.itemView GraphQL field can now be omitted which will make KeystoneAdminUIFieldMetaItemView.fieldMode return null when there isn't a static field mode.

    The itemView also no longer uses a sudo context when fetching the item in the KeystoneAdminUIFieldMetaItemView.fieldMode. Previously, if someone had access to the Admin UI(ui.isAccessAllowed) and a field had a itemView.fieldMode function that used the item argument, someone could bypass access control to determine whether or not an item with a given id exists.

    Query Generation Performance

    Query generation performance has been improved when querying single relationships without filter-based access control.

    When resolving related items, we often have a foreign key available to us that we can use to help optimise the subsequent related item query. If, on top of this, there are no filter-based access control rules in place, then we can use the Prisma findUnique operation, which will group all the operations into a single database query. This solves the GraphQL N+1 query problem in this specific instance.

    REST API Example πŸ‘©β€πŸ«

    This release also adds createContext to the extendExpressApp function giving you access to the full context API from Keystone.

    In a new example we demonstate how to create REST endpoints by extending Keystone's express app and using the Query API to execute queries against the schema.

    Note: You can find all of our examples in our examples folder on GitHub.

    Other Notable Changes πŸ›ŽοΈ

    • The KeystoneAdminUIFieldMeta.isOrderable and KeystoneAdminUIFieldMeta.isFilterable fields are no longer statically resolvable and will now take into account the context/session. This also means isOrderable and isFilterable are no longer accessible on useList().fields[fieldKey].isOrderable/isFilterable, they can be fetched through GraphQL if you need them in the Admin UI.

    • The sendItemMagicAuthLink and sendItemPasswordResetLink mutations now always return true instead of always returning null

    • Added support for dynamic isFilterable and isOrderable field config values. If a function is provided for these config option, it will be dynamically evaluated each time the field is used for filtering and ordering, and an error will be returned if the function returns false.

    Apollo Server Upgrade πŸ‘©β€πŸš€

    Apollo Server has had a major upgrade to Version 3.

    The Apollo documentation contains a full list of breaking changes introduced by this update.

    You can configure the Apollo Server provided by Keystone using the graphql.apolloConfig configuration option.

    The most prominent change for most users will be that the GraphQL Playground has been replaced by the Apollo Sandbox.

    If you prefer to keep the GraphQL Playground, you can configure your server by following these instructions.

    Prisma Update πŸ—ƒ

    We've updated our Prisma dependency from 2.30.2 to 3.1.1!

    Note that Keystone continues to use the "binary" query engine, rather than the new "node-API" query engine, which is now the Prisma default. We are still performing tests to ensure that the node-API query engine will work well with Keystone.

    Check out the Prisma releases page for more details on this major update.

    Credits πŸ’«

    • Exported Field types to help in updating contrib packages. Thanks @gautamsi!

    • Fixed remaining windows issue where it creates invalid import path. This removes some duplicate code which caused this. Thanks @gautamsi!

    • Added support for Prisma preview features via the config.db.prismaPreviewFeatures configuration option. Thanks @Nikitoring!

    Changelog

    You can view the verbose change log in the related PR (https://github.com/keystonejs/keystone/pull/6483) for this release.

    Source code(tar.gz)
    Source code(zip)
Owner
KeystoneJS
A node.js CMS and Web Application Framework
KeystoneJS
Modern framework for fast, powerful React apps

FUSION.JS Modern framework for fast, powerful React apps What is it? fuΒ·sion β€” noun The process or result of joining two or more things together to fo

Fusion.js 1.5k Dec 30, 2022
:zap: RAN! React . GraphQL . Next.js Toolkit :zap: - SEO-Ready, Production-Ready, SSR, Hot-Reload, CSS-in-JS, Caching, CLI commands and more...

RAN : React . GraphQL . Next.js Toolkit New version is coming... Follow up here: https://github.com/Sly777/ran/issues/677 Features Hot-Reload Ready fo

Ilker Guller 2.2k Jan 3, 2023
A Programming Environment for TypeScript & Node.js built on top of VS Code

Programming Environment for TypeScript & Node.js A battery-included TypeScript framework built on top of Visual Studio Code Website Kretes is a progra

Kretes 677 Dec 11, 2022
Noderlang - Erlang node in Node.js

Noderlang allows Node.js programs to easily operate in BEAM environments

devsnek 2 Mar 31, 2022
wolkenkit is an open-source CQRS and event-sourcing framework based on Node.js, and it supports JavaScript and TypeScript.

wolkenkit wolkenkit is a CQRS and event-sourcing framework based on Node.js. It empowers you to build and run scalable distributed web and cloud servi

the native web 1.1k Dec 26, 2022
Clock and task scheduler for node.js applications, providing extensive control of time and callback scheduling in prod and test code

#zeit A node.js clock and scheduler, intended to take place of the global V8 object for manipulation of time and task scheduling which would be handle

David Denton 12 Dec 21, 2021
Elegant and all-inclusive Node.Js web framework based on TypeScript. :rocket:.

https://foalts.org What is Foal? Foal (or FoalTS) is a Node.JS framework for creating web applications. It provides a set of ready-to-use components s

FoalTS 1.7k Jan 4, 2023
Micro type-safe wrapper for Node.js AMQP library and RabbitMQ management.

Micro type-safe wrapper for AMQP library and RabbitMQ management Description Section in progress. Getting Started Qupi can be installed by Yarn or NPM

Grzegorz Lenczuk 2 Oct 5, 2021
DDD/Clean Architecture inspired boilerplate for Node web APIs

Node API boilerplate An opinionated boilerplate for Node web APIs focused on separation of concerns and scalability. Features Multilayer folder struct

Talysson de Oliveira Cassiano 3k Dec 30, 2022
πŸš€ A RESTful API generator for Node.js

A RESTful API generator rest-hapi is a hapi plugin that generates RESTful API endpoints based on mongoose schemas. It provides a powerful combination

Justin Headley 1.2k Dec 31, 2022
nact β‡’ node.js + actors β‡’ your services have never been so Β΅

nact β‡’ node.js + actors your services have never been so Β΅ Any and all feedback, comments and suggestions are welcome. Please open an issue if you fin

Natalie Cuthbert 1k Dec 28, 2022
Full stack CQRS, DDD, Event Sourcing framework for Node.js

reSolve is a full stack functional JavaScript framework. CQRS - independent Command and Query sides. DDD Aggregate support. Event sourcing - using eve

ReImagined 709 Dec 27, 2022
In-memory filesystem with Node's API

In-memory filesystem with Node's API

Vadim Dalecky 1.4k Jan 4, 2023
A simple boilerplate generator for your node express backend project! πŸš€

A simple boilerplate generator for your node express backend project! ??

Gunvant Sarpate 35 Sep 26, 2022
A nodejs module for local and remote Inter Process Communication with full support for Linux, Mac and Windows

A nodejs module for local and remote Inter Process Communication with full support for Linux, Mac and Windows

Rifa Achrinza 15 Sep 28, 2022
Actionhero is a realtime multi-transport nodejs API Server with integrated cluster capabilities and delayed tasks

Actionhero The reusable, scalable, and quick node.js API server for stateless and stateful applications NPM | Web Site | Latest Docs | GitHub | Slack

Actionhero 2.3k Dec 29, 2022
Fast and type-safe full stack framework, for TypeScript

Fast and type-safe full stack framework, for TypeScript Why frourio ? Even if you write both the frontend and backend in TypeScript, you can't statica

frourio 1.1k Dec 26, 2022
A tool to develop and improve a student’s programming skills by introducing the earliest lessons of coding.

teachcode A tool to develop and improve a student’s programming skills by introducing the earliest lessons of coding. Chat: Telegram Donate: PayPal, P

madlabsinc 346 Oct 25, 2022