### Install Dependencies and Start Development Source: https://github.com/open-condo-software/open-keystone/blob/main/README.md After cloning the repository, run these commands to install all project dependencies and start the local development server. ```shell yarn yarn dev ``` -------------------------------- ### Minimal Custom Server Setup Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/custom-server.md A basic setup for a custom server using `express` and KeystoneJS. This example demonstrates how to start a Keystone application with a custom server script. ```json { "scripts": { "start": "node server.js" } } ``` ```javascript const { Keystone } = require('@open-keystone/keystone'); const { GraphQLApp } = require('@open-keystone/app-graphql'); const keystone = new Keystone({...}); module.exports = { keystone, apps: [new GraphQLApp()], }; ``` ```javascript const express = require('express'); const { keystone, apps } = require('./index.js'); keystone .prepare({ apps: apps, dev: process.env.NODE_ENV !== 'production', }) .then(async ({ middlewares }) => { await keystone.connect(); const app = express(); app.use(middlewares).listen(3000); }); ``` -------------------------------- ### Install Dependencies and Start Todo-Knex Demo Source: https://github.com/open-condo-software/open-keystone/blob/main/examples/todo-knex/README.md Installs project dependencies and starts the Todo-Knex demo. Ensure you have PostgreSQL set up and a database named 'to-do' created. ```sh yarn yarn demo start todo-knex ``` -------------------------------- ### Run Blog Demo Project Source: https://github.com/open-condo-software/open-keystone/blob/main/examples/blog/README.md Installs dependencies and starts the Blog demo project. You can change the port by setting the PORT environment variable. ```sh yarn yarn start blog ``` ```sh PORT=5000 yarn start blog ``` -------------------------------- ### Clone and Install KeystoneJS Source: https://github.com/open-condo-software/open-keystone/blob/main/examples/README.md Clone the KeystoneJS repository and install dependencies. This is the initial setup step for running the demo projects. ```bash git clone https://github.com/keystonejs/keystone-5.git cd keystone-5 git checkout $(git describe --tags $(git rev-list --tags --max-count=1)) yarn ``` -------------------------------- ### Prisma Adapter Setup with Local PostgreSQL Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/adapter-prisma/README.md Shell commands to create a PostgreSQL database and user for Keystone, followed by a JavaScript example of the connection string. ```shell createdb -U postgres keystone psql keystone -U postgres -c "CREATE USER keystone5 PASSWORD 'change_me_plz'" psql keystone -U postgres -c "GRANT ALL ON DATABASE keystone TO keystone5;" ``` ```javascript const keystone = new Keystone({ adapter: new PrismaAdapter({ url: `postgres://keystone5:change_me_plz@localhost:5432/keystone` }), }); ``` -------------------------------- ### Adding AdminUIApp to Keystone Setup Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/apps.md This example shows how to pair the GraphQLApp with the AdminUIApp to provide both a GraphQL API and the Keystone Admin UI. ```javascript const { GraphQLApp } = require('@open-keystone/app-graphql'); const { Keystone } = require('@open-keystone/keystone'); const { AdminUIApp } = require('@open-keystone/app-admin-ui'); const keystone = new Keystone(); module.exports = { keystone, apps: [ new GraphQLApp(), new AdminUIApp(), ] } ``` -------------------------------- ### Complete Apollo and Keystone Setup with State Management Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/apollo-helpers/README.md An advanced setup demonstrating client-side state management with `withClientState`, `injectIsOptimisticFlag`, and automatic cache invalidation using `flattenApollo`. This example shows how mutations can trigger re-renders of dependent queries. ```javascript import gql from 'graphql-tag'; import React from 'react'; import ReactDOM from 'react-dom'; import { HttpLink } from 'apollo-link-http'; import { ApolloLink } from 'apollo-link'; import { ApolloClient } from 'apollo-client'; import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloProvider } from 'react-apollo'; import { withClientState } from 'apollo-link-state'; import { Query, Mutation, KeystoneProvider, injectIsOptimisticFlag, flattenApollo, } from '@open-keystone/apollo-helpers'; const cache = new InMemoryCache(); // Without this, we don't get the _isOptimistic flag on our datatypes const stateLink = withClientState( injectIsOptimisticFlag({ resolvers: { /* ... Add your local state resolvers here */ }, defaults: { /* ... Add your resolver defaults here */ }, cache, }) ); const client = new ApolloClient({ link: ApolloLink.from([stateLink, new HttpLink({ uri: /* ... */ })]), cache: cache, }); const GET_FOO_QUERY = gql`...` const UPDATE_FOO_MUTATION = gql`...` const ADD_FOO_MUTATION = gql`...` // NOTE: This format only works with the `Query`/`Mutation` components from this // module, not Apollo's `Query`/`Mutation` queries. For those, you'll have to // wrap each item in a function ({ render }) => {render} const GraphQL = flattenApollo({ foo: , // Note the `invalidateTypes` define the GraphQL types to invalidate within // the Apollo cache upon mutation updateFoo: , addFoo: , }) // Calling `updateFoo` or `addFoo` will trigger the cache invalidation, and so // will re-execute the `Query` (as it has queried a `Foo` type in the past), // which will trigger a re-render here. // In a more complicated app, _all_ `Query`'s which have queried a `Foo` type // will also be re-rendered without having to wire them up to these particular // mutations (decoupling FTW!) const App = () => ( {({ foo, updateFoo, addFoo }) => (
Foo:
{JSON.stringify(foo, null, 2)}
)}
); ReactDOM.render(, document.getElementById('root')); ``` -------------------------------- ### Basic Keystone Setup with GraphQLApp Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/apps.md This is the minimum setup for a Keystone application, including the essential GraphQL API. ```javascript const { GraphQLApp } = require('@open-keystone/app-graphql'); const { Keystone } = require('@open-keystone/keystone'); const keystone = new Keystone(); module.exports = { keystone, apps: [new GraphQLApp()], }; ``` -------------------------------- ### Build and Start Production Demo Project Source: https://github.com/open-condo-software/open-keystone/blob/main/examples/README.md Commands to create a production build and then start a specific demo project, like 'blog'. This is used for deploying or testing the production version. ```bash yarn demo blog build yarn demo blog start ``` -------------------------------- ### Start Arch UI Documentation Server Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/arch/README.md Run this command to start the local development server for the Arch UI documentation. ```shell cd docs yarn start ``` -------------------------------- ### Initialize Keystone with Knex Adapter Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/adapter-knex/README.md Basic usage example for initializing Keystone with the Knex adapter. Ensure you have the adapter installed and configured with your database connection details. ```javascript const { KnexAdapter } = require('@open-keystone/adapter-knex'); const keystone = new Keystone({ adapter: new KnexAdapter({...}), }); ``` -------------------------------- ### PostgreSQL Connection Output Example Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/quick-start/adapters.md This is an example of the output you should expect after successfully connecting to your PostgreSQL database. ```text psql (12.2, server 9.6.8) Type "help" for help. my-keystone-project=# ``` -------------------------------- ### Add Server Start Script to package.json Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/blog/introduction-to-graphql.md Defines a 'start:server' script in package.json to run the GraphQL server using Node.js. ```json "scripts": { "start:server": "node index.js" } ``` -------------------------------- ### Add Start Script to package.json Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/new-project.md Configure the 'start:dev' script in package.json to run the Keystone application. ```json "scripts": { "start:dev": "keystone" } ``` -------------------------------- ### Start Development Server Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/quick-start/README.md Launch the OpenKeystone development server to view your application and access the Admin UI. ```shell yarn dev # or npm run dev ``` -------------------------------- ### Install Alert Package Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/arch/packages/alert/README.md Install the Alert package using npm or yarn. ```bash npm install --save @open-arch-ui/alert # OR yarn add @open-arch-ui/alert ``` -------------------------------- ### Install Test Utils Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/test-utils/README.md Install the @open-keystone/test-utils package using yarn. ```shell yarn add @open-keystone/test-utils ``` -------------------------------- ### Install Apollo Helpers Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/apollo-helpers/README.md Install the @open-keystone/apollo-helpers package using yarn. ```shell yarn add @open-keystone/apollo-helpers ``` -------------------------------- ### Full Example: Seeding with Relationships Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/initial-data.md A complete example demonstrating how to initialize Keystone, reset the database, seed users, and then seed posts with relationships using the `connect` nested mutation. This ensures related items are created and linked correctly. ```javascript const keystone = new Keystone({ adapter: new MongooseAdapter({ mongoUri: 'mongodb://localhost/keystone' }), onConnect: async keystone => { // Reset the database each time for this example await keystone.adapter.dropDatabase(); // 1. Insert the user list first to obtain the user IDs const users = await createItems({ keystone, listKey: 'User', items: [ { data: { name: 'John Duck', email: 'john@duck.com', password: 'dolphins', }, }, { data: { name: 'Barry', email: 'bartduisters@bartduisters.com', password: 'dolphins', }, }, ], returnFields: 'id, name', }); // 2. Insert `Post` data, with the required relationships, via `connect` nested mutation. await createItems({ keystone, listKey: 'Post', items: [ { data: { title: 'Hello World', author: { // Extracting the id from `users` array connect: { id: users.find(user => user.name === 'John Duck').id, }, }, }, }, ], }); }, }); ``` -------------------------------- ### Start Keystone Development Server Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/new-project.md Execute the start script to run the Keystone application. Ensure MongoDB is running. ```shell yarn start:dev ``` -------------------------------- ### Start Todo Demo on Custom Port Source: https://github.com/open-condo-software/open-keystone/blob/main/examples/todo/README.md Run the Todo demo project on a custom port by setting the PORT environment variable before starting Keystone. ```sh PORT=5000 yarn start todo ``` -------------------------------- ### Start Apollo GraphQL Server Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/blog/introduction-to-graphql.md Initializes and starts an Apollo Server with the defined schema and resolvers. Logs the server URL to the console. ```javascript const server = new ApolloServer({ typeDefs: schema, resolvers }); server.listen().then(({ url }) => { console.log(`🚀 GraphQL server started at: ${url}`); }); ``` -------------------------------- ### Install Keystone and Mongoose Adapter Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/new-project.md Install the core Keystone package and the Mongoose adapter for MongoDB. ```shell yarn add @open-keystone/keystone @open-keystone/adapter-mongoose ``` -------------------------------- ### Add Client Start Script to package.json Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/blog/introduction-to-graphql.md Adds a 'start:client' script to package.json for serving static files, typically used for the client-side application. ```json "scripts": { "start:server": "node index.js", "start:client": "npx http-server ." } ``` -------------------------------- ### Run Default Demo Project Source: https://github.com/open-condo-software/open-keystone/blob/main/examples/README.md Command to run the default demo project, which is typically the 'todo' app. This starts the development server. ```bash yarn dev ``` -------------------------------- ### Install PostgreSQL with Homebrew Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/quick-start/adapters.md This command installs PostgreSQL on MacOS using Homebrew. Ensure Homebrew is installed first. ```shell brew install postgres ``` -------------------------------- ### Install GraphQL App Package Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/new-project.md Install the package required for the GraphQL API. ```shell yarn add @open-keystone/app-graphql ``` -------------------------------- ### Install Keystone Packages Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/initial-data.md Installs necessary packages for building a Keystone project with Mongoose, GraphQL, Admin UI, and password authentication. ```shell yarn add @open-keystone/keystone yarn add @open-keystone/adapter-mongoose yarn add @open-keystone/app-graphql yarn add @open-keystone/fields yarn add @open-keystone/app-admin-ui yarn add @open-keystone/auth-password yarn add @open-keystone/server-side-graphql-client ``` -------------------------------- ### Run OpenKeystone App Development Server Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/create-open-keystone-app/README.md After generating your app, navigate into the project directory and start the development server using this command. ```shell cd my-app yarn dev ``` -------------------------------- ### Install Apollo Server and HTTP Server Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/blog/introduction-to-graphql.md Installs the necessary npm packages for creating a GraphQL API with Apollo Server and serving static files with http-server. ```bash npm install apollo-server http-server ``` -------------------------------- ### Minimal Apollo and Keystone Setup Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/apollo-helpers/README.md A basic setup for Apollo and Keystone integration using ApolloProvider, KeystoneProvider, and the Query component. Ensure you have ApolloClient, HttpLink, and InMemoryCache configured. ```javascript import gql from 'graphql-tag'; import React from 'react'; import ReactDOM from 'react-dom'; import { HttpLink } from 'apollo-link-http'; import { ApolloClient } from 'apollo-client'; import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloProvider } from 'react-apollo'; import { Query, KeystoneProvider } from '@open-keystone/apollo-helpers'; const client = new ApolloClient({ link: new HttpLink({ uri: '...' }), cache: new InMemoryCache(), }); const App = () => ( {({ data }) => (
{JSON.stringify(data)}
)}
); ReactDOM.render(, document.getElementById('root')); ``` -------------------------------- ### Build and Version Packages for Backport Source: https://github.com/open-condo-software/open-keystone/blob/main/CONTRIBUTING.md Install dependencies, build the project, version packages, and format code before committing a backport. ```shell yarn fresh --prefer-offline && yarn build && yarn version-packages && yarn format && git add . && git commit -m "Backport fix" ``` -------------------------------- ### Basic GraphQL Playground App Setup Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/app-graphql-playground/README.md Integrates the GraphQL Playground App into a KeystoneJS application. Ensure GraphQLApp and GraphQLPlaygroundApp point to the same endpoint. This setup should precede GraphQLApp to correctly configure dev query middleware. ```javascript const { Keystone } = require('@open-keystone/keystone'); const { GraphQLApp } = require('@open-keystone/app-graphql'); const { GraphQLPlaygroundApp } = require('@open-keystone/app-graphql-playground'); const { AdminUIApp } = require('@open-keystone/app-admin-ui'); // Ensure that the GraphQLApp and GraphQLAppPlayground are referring to the same endpoint const apiPath = '/admin/api'; module.exports = { keystone: new Keystone(), apps: [ // This should come before the GraphQLApp, as it sets up the dev query middleware new GraphQLPlaygroundApp({ apiPath }) // Disable the default playground on this app new GraphQLApp({ apiPath, graphiqlPath: undefined }), new AdminUIApp() ], }; ``` -------------------------------- ### Example Changeset Content Source: https://github.com/open-condo-software/open-keystone/blob/main/CONTRIBUTING.md An example of a changeset markdown file. It includes package version bumps and a summary of changes, which will be written to the changelog on publish. ```markdown --- '@open-keystone/adapter-mongoose': patch '@open-keystone/keystone': minor --- A very useful description of the changes should be here. ``` -------------------------------- ### All-in-One Custom Server Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/custom-server.md An example of an all-in-one custom server where the Keystone instance and apps are declared directly in the `server.js` file. ```json { "scripts": { "start": "node server.js" } } ``` ```javascript const express = require('express'); const { Keystone } = require('@open-keystone/keystone'); const { GraphQLApp } = require('@open-keystone/app-graphql'); const keystone = new Keystone({...}); keystone .prepare({ apps: [new GraphQLApp()], dev: process.env.NODE_ENV !== 'production', }) .then(async ({ middlewares }) => { await keystone.connect(); const app = express(); app.use(middlewares).listen(3000); }); ``` -------------------------------- ### Schema Definition Example Source: https://github.com/open-condo-software/open-keystone/blob/main/README.md Illustrates a basic schema definition using GraphQL and AdminUI components. ```javascript schema => ({ GraphQL, AdminUI }) ``` -------------------------------- ### Connect to PostgreSQL Database Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/prisma.md Example command to verify connection to a PostgreSQL database using psql with provided credentials and connection URL. ```bash psql keystone -U postgres -c "CREATE USER keystone5 PASSWORD 'change_me_plz'" ``` -------------------------------- ### Configure Session Store with Connect-Mongo Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/keystone/README.md Integrate a custom session store, using connect-mongo as an example. ```javascript const expressSession = require('express-session'); const MongoStore = require('connect-mongo')(expressSession); const keystone = new Keystone({ sessionStore: new MongoStore({ url: 'mongodb://localhost/my-app' }), }); ``` -------------------------------- ### Initialize Keystone with Mongoose Adapter Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/adapter-mongoose/README.md Basic setup for initializing KeystoneJS with the Mongoose adapter. Ensure the adapter is imported correctly. ```javascript const { MongooseAdapter } = require('@open-keystone/adapter-mongoose'); const keystone = new Keystone({ adapter: new MongooseAdapter({...}), }); ``` -------------------------------- ### Check Development Environment Versions Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/quick-start/README.md Verify that Node.js, npm, and yarn are installed and meet the minimum version requirements. ```shell $ node --version v22.16.0 $ npm --version 10.9.2 $ yarn --version 3.8.7 ``` -------------------------------- ### Incorrect Animation Setup Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/arch/packages/example.md This example demonstrates an incorrect setup where `ReactCSSTransitionGroup` is mounted with new items, preventing transitions. Ensure the group is mounted before its children are added. ```javascript render() { const items = this.state.items.map((item, i) => (
this.handleRemove(i)}> {item}
)); return (
{items}
); } ``` -------------------------------- ### Navigate to Project Directory Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/quick-start/README.md After the project is set up, change into the newly created project directory to begin development. ```shell cd my-app ``` -------------------------------- ### Filter Users by Name Starting With (Case-Insensitive) Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/intro-to-graphql.md Example of a GraphQL query using the 'where' clause to filter users whose names start with a specific string, ignoring case. ```graphql query { allUsers(where: { name_starts_with_i: "A" }) { id } } ``` -------------------------------- ### Initialize Keystone with Prisma Adapter Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/adapter-prisma/README.md Basic usage example showing how to initialize Keystone with the Prisma adapter, providing a database connection URL. ```javascript const { PrismaAdapter } = require('@open-keystone/adapter-prisma'); const keystone = new Keystone({ adapter: new PrismaAdapter({ url: 'postgres://...' }), }); ``` -------------------------------- ### Setup Password Authentication Strategy Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/authentication.md Instantiate a PasswordAuthStrategy and create a User list for authentication. This configures the Admin UI to require login. ```javascript const { Keystone } = require('@open-keystone/keystone'); const { Text, Password } = require('@open-keystone/fields'); const { PasswordAuthStrategy } = require('@open-keystone/auth-password'); const { AdminUIApp } = require('@open-keystone/app-admin-ui'); const keystone = new Keystone(); keystone.createList('User', { fields: { username: { type: Text }, password: { type: Password }, }, }); const authStrategy = keystone.createAuthStrategy({ type: PasswordAuthStrategy, list: 'User', config: { identityField: 'username', // default: 'email' secretField: 'password', // default: 'password' }, }); // Enable Admin UI login by adding the authentication strategy const admin = new AdminUIApp({ authStrategy }); ``` -------------------------------- ### Create Project Directory and Initialize NPM Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/blog/introduction-to-graphql.md Commands to create a new project directory and initialize an NPM project within it. These are the initial setup steps for the GraphQL server. ```bash mkdir graphql-server-tutorial cd graphql-server-tutorial npm init --yes ``` -------------------------------- ### Create User List with DateTimeUtc Field Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/fields/src/types/DateTimeUtc/README.md Example of how to define a User list with a 'lastOnline' field using the DateTimeUtc type. Ensure '@open-keystone/fields' is installed. ```javascript const { DateTimeUtc } = require('@open-keystone/fields'); keystone.createList('User', { fields: { lastOnline: { type: DateTimeUtc }, }, }); ``` -------------------------------- ### Query Posts and Their Authors Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/discussions/relationships.md Example GraphQL query to retrieve all posts, including their titles, content, and the names of their authors. Assumes a one-sided relationship setup. ```graphql Query { allPosts { title content authors { name } } } ``` -------------------------------- ### Create Project Directory and Initialize Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/new-project.md Create a new directory for your project and initialize it using yarn. ```shell mkdir new-project cd new-project yarn init ``` -------------------------------- ### Install Markdown Field Package Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/fields-markdown/README.md Install the @open-keystone/fields-markdown package using yarn or npm. ```shell yarn add @open-keystone/fields-markdown # or npm install @open-keystone/fields-markdown ``` -------------------------------- ### Install Fields Package Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/new-project.md Install the package that provides various field types for Keystone lists. ```shell yarn add @open-keystone/fields ``` -------------------------------- ### Custom Server with Direct Middleware Preparation Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/custom-server.md This setup allows for fine-grained control by directly calling an app's `.prepareMiddleware()` function, bypassing `keystone.prepare()`. ```json { "scripts": { "start": "node server.js" } } ``` ```javascript const express = require('express'); const { Keystone } = require('@open-keystone/keystone'); const { GraphQLApp } = require('@open-keystone/app-graphql'); const { AdminUIApp } = require('@open-keystone/app-admin-ui'); const keystone = new Keystone({...}); const dev = process.env.NODE_ENV !== 'production'; const apps = [new GraphQLApp(), new AdminUIApp()]; const preparations = apps.map(app => app.prepareMiddleware({ keystone, dev }) ); Promise.all(preparations).then(async middlewares => { await keystone.connect(); const app = express(); app.use(middlewares).listen(3000); }); ``` -------------------------------- ### GraphQL Query Example Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/fields-cloudinary-image/README.md An example of how to query CloudinaryImage fields in GraphQL, including applying transformations. ```APIDOC ## GraphQL Query Example ### Description Demonstrates how to query an `Image` list entry and retrieve specific image fields, including a transformed image URL. ### Query ```graphql query getFirstCloudinaryImage { allImages(first: 1) { image { filename publicUrlTransformed(transformation: { width: "120", crop: "limit" }) } } } ``` ``` -------------------------------- ### Apply Plugins to List Configuration Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/create-list.md Use plugins to modify list configuration values. This example defines a 'setupUserList' plugin to add 'name' and 'password' fields. ```javascript const setupUserList = ({ fields, ...config }) => { return { ...config, fields: { ...fields, name: { type: Text }, password: { type: Password }, }, }; }; keystone.createList('User', { plugin: [setupUserList], }); ``` -------------------------------- ### Initialize Keystone with Mongoose Adapter Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/new-project.md Set up the main entry point for a Keystone app, instantiating Keystone with the Mongoose adapter and a MongoDB connection URI. ```javascript const { Keystone } = require('@open-keystone/keystone'); const { MongooseAdapter } = require('@open-keystone/adapter-mongoose'); const keystone = new Keystone({ adapter: new MongooseAdapter({ mongoUri: 'mongodb://localhost/keystone' }), }); ``` -------------------------------- ### Create a New OpenKeystone App Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/quick-start/README.md Use npm or yarn to initialize a new OpenKeystone project. Follow the prompts to configure your project name, starter template, database type, and connection string. ```shell npm init keystone-5-app my-app # or yarn create keystone-5-app my-app ``` -------------------------------- ### Create OpenKeystone App Interactively Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/create-open-keystone-app/README.md Use this command to start an interactive session for creating a new OpenKeystone app. Follow the on-screen prompts to configure your project. ```shell yarn create open-keystone-app my-app ``` -------------------------------- ### PostgreSQL Example Migration Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/relationship-migration.md Example SQL migration script for PostgreSQL to rename tables, columns, and drop obsolete ones based on relationship changes. ```sql ALTER TABLE public."Todo_reviewers" RENAME TO "Todo_reviewers_many"; ALTER TABLE public."Todo_reviewers_many" RENAME COLUMN "Todo_id" TO "Todo_left_id"; ALTER TABLE public."Todo_reviewers_many" RENAME COLUMN "User_id" TO "User_right_id"; ALTER TABLE public."User" DROP COLUMN "leadPost"; DROP TABLE public."User_published" DROP TABLE public."User_readPosts" ALTER TABLE public."Todo_readers" RENAME TO "Todo_readers_User_readPosts"; ALTER TABLE public."Todo_readers_User_readPosts" RENAME COLUMN "Todo_id" TO "Todo_left_id"; ALTER TABLE public."Todo_readers_User_readPosts" RENAME COLUMN "User_id" TO "User_right_id"; ``` -------------------------------- ### Run Keystone Development Server with Prisma Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/prisma.md Command to start the Keystone development server, setting the DATABASE_URL environment variable. This is required due to a known issue in Prisma. ```bash cd my-app DATABASE_URL=postgres://keystone5:change_me_plz@localhost:5432/keystone yarn dev ``` -------------------------------- ### Create a basic list Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/create-list.md Use `keystone.createList` to define a new list with a key and configuration object. ```javascript keystone.createList('ListKey', {...}); ``` -------------------------------- ### Multi-step Google Authentication Server Setup Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/auth-passport/README.md Sets up a custom server for multi-step Google authentication, including user data collection and error handling. ```javascript const { Keystone } = require('@open-keystone/keystone'); const { MongooseAdapter } = require('@open-keystone/adapter-mongoose'); const { GraphQLApp } = require('@open-keystone/app-graphql'); const { AdminUIApp } = require('@open-keystone/app-admin-ui'); const express = require('express'); const { GoogleAuthStrategy } = require('@open-keystone/auth-passport'); const cookieSecret = ''; const keystone = new Keystone({ adapter: new MongooseAdapter(), cookieSecret, }); keystone.createList('User', { fields: { name: { type: Text }, email: { type: Text }, // This field name must match the `idField` setting passed to the auth // strategy constructor below googleId: { type: Text }, }, }); const googleStrategy = keystone.createAuthStrategy({ type: GoogleAuthStrategy, list: 'User', config: { idField: 'googleId', appId: '', appSecret: '', loginPath: '/auth/google', callbackPath: '/auth/google/callback', callbackHost: 'http://localhost:3000', loginPathMiddleware: (req, res, next) => { // An express middleware executed before the Passport social signin flow // begins. Useful for setting cookies, etc. // Don't forget to call `next()`! next(); }, callbackPathMiddleware: (req, res, next) => { // An express middleware executed before the callback route is run. Useful // for logging, etc. // Don't forget to call `next()`! next(); }, // Called when there's no existing user for the given googleId // Default: resolveCreateData: () => ({}) resolveCreateData: ({ createData, actions: { pauseAuthentication } }, req, res) => { // If we don't have the right data to continue with a creation if (!createData.name) { // then we pause the flow pauseAuthentication(); // And redirect the user to a page where they can enter the data. // Later, the `resolveCreateData()` method will be re-executed this // time with the complete data. res.redirect(`/auth/google/step-2`); return; } return createData; }, // Once a user is found/created and successfully matched to the // googleId, they are authenticated, and the token is returned here. // NOTE: By default Keystone sets a `keystone.sid` which authenticates the // user for the API domain. If you want to authenticate via another domain, // you must pass the `token` as a Bearer Token to GraphQL requests. onAuthenticated: ({ token, item, isNewItem }, req, res) => { console.log(token); res.redirect('/'); }, // If there was an error during any of the authentication flow, this // callback is executed onError: (error, req, res) => { console.error(error); res.redirect('/?error=Uh-oh'); }, }, }); keystone .prepare({ apps: [ new GraphQLApp(), new AdminUIApp({ name: 'Login With Google Example', authStrategy: googleStrategy, }), ], dev: process.env.NODE_ENV !== 'production', }) .then(async ({ middlewares }) => { await keystone.connect(); const app = express(); app.use(middlewares); // Sample page to collect a name, submits to the completion step which will // create a user app.use(`/auth/google/step-2`, express.urlencoded({ extended: true }), (req, res, next) => { if (req.method === 'POST') { const { name } = req.body; // Continue the authentication flow with additional data the user // submitted. // This data is merged into other data required by Keystone and will // trigger the resolveCreateData() method again. return googleStrategy.resumeAuthentication({ name }, req, res, next); } res.send(`
`); }); app.listen(port, error => { if (error) throw error; console.log(`Ready. App available at http://localhost:${port}`); }); }) .catch(error => { console.error(error); process.exit(1); }); ``` -------------------------------- ### afterDelete Hook Example Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/hooks.md Example of an `afterDelete` hook. This hook is invoked after an item has been deleted. It receives details about the operation and the deleted item. Return values are ignored. ```javascript const afterDelete = ({ operation, existingItem, context, listKey, fieldPath, // Field hooks only }) => { // Perform side effects // Return values ignored }; ``` -------------------------------- ### GraphQL Mutation to Create User with OEmbed Portfolio Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/fields-oembed/README.md Demonstrates how to create a new User, providing a URL for the portfolio which will be transformed into an OEmbed type. ```graphql mutation { createUser(data: { portfolio: "https://flickr.com/foobar" }) { portfolio { __typename type originalUrl title thumbnail { url width height } provider { name } ... on OEmbedPhoto { url width height } ... on OEmbedVideo { html width height } ... on OEmbedRich { html width height } # NOTE: No OEmbedLink fragment - it doesn't specify any extra fields } } } ``` -------------------------------- ### MongoDB Example Migration Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/guides/relationship-migration.md Example migration script for MongoDB to handle relationship changes, including inserting data into new tables and removing old fields. ```javascript db.todos.find({}).forEach(function (doc) { (doc.reviewers || []).forEach(function (itemId) { db.todo_reviewers_manies.insert({ Todo_left_id: doc._id, User_right_id: itemId }); }); }); db.todos.updateMany({}, { $unset: { reviewers: 1 } }); db.users.updateMany({}, { $unset: { leadPost: 1 } }); db.users.updateMany({}, { $unset: { published: 1 } }); db.todos.find({}).forEach(function (doc) { (doc.readers || []).forEach(function (itemId) { db.todo_readers_user_readposts.insert({ Todo_left_id: doc._id, User_right_id: itemId }); }); }); db.todos.updateMany({}, { $unset: { readers: 1 } }); db.users.updateMany({}, { $unset: { readPosts: 1 } }); ``` -------------------------------- ### validateAuthInput Hook Example Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/hooks.md Example of a `validateAuthInput` hook. Used to verify `resolvedData` after `resolveAuthInput`. If errors are found, throw an error or call `addValidationError`. Return values are ignored. ```javascript const validateAuthInput = ({ operation, originalInput, resolvedData, context, addValidationError, listKey, }) => { // Validation logic here // Example: if (!resolvedData.someField) { // addValidationError('someField is required'); // } }; ``` -------------------------------- ### resolveAuthInput Hook Example Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/hooks.md Example of a `resolveAuthInput` hook. Used to modify `originalInput` to produce `resolvedData` for authenticate operations. The hook can return a Promise or an Object with the same structure as `originalInput`. ```javascript const resolveAuthInput = ({ operation, originalInput, context, listKey, }) => { // Input resolution logic // Object returned is used in place of resolvedData const resolvedData = originalInput; return resolvedData; }; ``` -------------------------------- ### Initialize LocalFileAdapter Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/file-adapters/README.md Instantiate the `LocalFileAdapter` with configuration options for local file storage. ```javascript const { LocalFileAdapter } = require('@open-keystone/file-adapters'); const fileAdapter = new LocalFileAdapter({...}); ``` -------------------------------- ### GraphQL File Upload Mutation Example Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/file-adapters/README.md An example GraphQL mutation for uploading files, demonstrating how to structure the query and variables. Requires client-side support like apollo-upload-client or urql. ```graphql // Query mutation uploadImageQuery ($file: Upload){ createUploadTest(data: { file: $file, }) { id file { publicUrl } } } // Variables variables: { file: // File path }, ``` -------------------------------- ### Setup Test Database for Knex Adapter Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/adapter-knex/README.md Shell commands to set up a PostgreSQL database named 'keystone' and a user 'keystone5' for testing purposes. This is a prerequisite for running Keystone with the Knex adapter in development. ```shell ./build-test-db.sh ``` -------------------------------- ### beforeAuth Hook Example Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/hooks.md Example of a `beforeAuth` hook. This hook is invoked after `validateAuthInput` and before the authentication strategy's `validate()` function. It's used for performing side effects before authentication. ```javascript const beforeAuth = ({ operation, originalInput, resolvedData, context, listKey, }) => { // Perform side effects // Return values ignored }; ``` -------------------------------- ### Initialize CloudinaryAdapter Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/file-adapters/README.md Instantiate the `CloudinaryAdapter` with required credentials for cloud-based file storage. ```javascript const { CloudinaryAdapter } = require('@open-keystone/file-adapters'); const fileAdapter = new CloudinaryAdapter({...}); ``` -------------------------------- ### Float Field Usage Example Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/fields/src/types/Float/README.md Demonstrates how to define a Float field within a KeystoneJS list configuration. This example shows setting up a 'SensorReading' list with 'temperature' and 'humidity' fields of type Float. ```javascript const { Float, DateTime } = require('@open-keystone/fields'); keystone.createList('SensorReading', { fields: { loggedAt: { type: DateTime }, temperature: { type: Float }, humidity: { type: Float }, }, }); ``` -------------------------------- ### connect() Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/keystone/README.md Manually connect Keystone to the adapter. This is typically only required for custom servers. ```APIDOC ## connect() ### Description Manually connect Keystone to the adapter. See [Custom Server](https://keystonejs.com/guides/custom-server). ### Method `connect()` ### Usage ```javascript keystone.connect(); ``` ### Notes `keystone.connect()` is only required for custom servers. Most example projects use the `keystone start` command to start a server and automatically connect. ``` -------------------------------- ### Creating an Authentication Strategy Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/authentication.md This example demonstrates how to create a password authentication strategy using the `createAuthStrategy` method and provide it to the Admin UI app. ```APIDOC ## Usage ```javascript title=index.js const { PasswordAuthStrategy } = require('@open-keystone/auth-password'); const keystone = new Keystone({...}); const authStrategy = keystone.createAuthStrategy({ type: PasswordAuthStrategy, list: 'User', config: {...}, hooks: {...}, plugins: [...], }); ``` You then provide `authStrategy` to apps that facilitate login (typically the Admin UI): ```javascript title=index.js module.exports = { keystone, apps: [new AdminUIApp({ authStrategy })], }; ``` ``` -------------------------------- ### afterAuth Hook Example Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/hooks.md Example of an `afterAuth` hook. This hook runs after the authentication operation completes, whether successful or not. It receives details about the authentication result, including the authenticated item, success status, message, token, and input data. ```javascript const afterAuth = ({ operation, item, success, message, token, originalInput, resolvedData, context, listKey, }) => { // Perform side effects // Return values ignored }; ``` -------------------------------- ### validateAuthInput Hook Example Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/api/hooks.md Example of a `validateAuthInput` hook. This hook is used to validate input before the authentication operation proceeds. It receives various arguments including operation details, input data, resolved data, context, and a function to add validation errors. ```javascript const validateAuthInput = ({ operation, originalInput, resolvedData, context, addFieldValidationError, listKey, }) => { // Throw error objects or register validation errors with addValidationError() // Return values ignored }; ``` -------------------------------- ### User List Setup with Password Authentication Source: https://github.com/open-condo-software/open-keystone/blob/main/docs/tutorials/initial-data.md Configures a 'User' list with name, email, isAdmin, and password fields, and sets up a PasswordAuthStrategy for authentication. ```javascript const { Keystone } = require('@open-keystone/keystone'); const { PasswordAuthStrategy } = require('@open-keystone/auth-password'); const { Text, Checkbox, Password } = require('@open-keystone/fields'); const { GraphQLApp } = require('@open-keystone/app-graphql'); const { AdminUIApp } = require('@open-keystone/app-admin-ui'); const { MongooseAdapter } = require('@open-keystone/adapter-mongoose'); const keystone = new Keystone({ adapter: new MongooseAdapter({ mongoUri: 'mongodb://localhost/keystone' }), }); keystone.createList('User', { fields: { name: { type: Text }, email: { type: Text, isUnique: true }, isAdmin: { type: Checkbox }, password: { type: Password }, }, }); const authStrategy = keystone.createAuthStrategy({ type: PasswordAuthStrategy, list: 'User', }); module.exports = { keystone, apps: [ new GraphQLApp(), new AdminUIApp({ name: 'example-project', enableDefaultRoute: true, authStrategy }), ], }; ``` -------------------------------- ### Initialize Keystone with a Database Adapter Source: https://github.com/open-condo-software/open-keystone/blob/main/packages/keystone/lib/adapters/README.md Provide an instance of your chosen database adapter when creating a new Keystone object. This adapter will back all lists in your system. ```javascript const keystone = new Keystone({ adapter: new MongooseAdapter(), }); ```