### 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(),
});
```