Skip to content

Commit 2ffc70a

Browse files
committed
refactor: move create-keystone-app inside monorepo
1 parent 3b6ba78 commit 2ffc70a

File tree

18 files changed

+1819
-231
lines changed

18 files changed

+1819
-231
lines changed

packages/create/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Thinkmill Labs Pty Ltd
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/create/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# @keystone-6/create
2+
3+
Keystone-6 is the latest version of Keystone.
4+
To get help with this package join the conversation in [Slack](https://community.keystonejs.com/), or [Github](https://github.com/keystonejs/keystone/).
5+
6+
Visit <https://keystonejs.com/> for docs, and [follow @keystonejs on Twitter](https://twitter.com/keystonejs) for the latest updates.

packages/create/cli.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env node
2+
import './dist/create-keystone-app.esm.js'

packages/create/package.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name": "create-keystone-app",
3+
"version": "9.0.1",
4+
"license": "MIT",
5+
"type": "module",
6+
"main": "dist/create-keystone-app.cjs.js",
7+
"module": "dist/create-keystone-app.esm.js",
8+
"repository": "https://github.com/keystonejs/keystone/tree/main/packages/create",
9+
"bin": "./cli.js",
10+
"exports": {
11+
".": {
12+
"module": "./dist/create-keystone-app.esm.js",
13+
"default": "./dist/create-keystone-app.cjs.js"
14+
},
15+
"./package.json": "./package.json"
16+
},
17+
"preconstruct": {
18+
"entrypoints": [
19+
"index.ts"
20+
]
21+
},
22+
"dependencies": {
23+
"chalk": "^4.1.2",
24+
"enquirer": "^2.4.1",
25+
"execa": "^5.1.1",
26+
"fs-extra": "^11.0.0",
27+
"meow": "^9.0.0",
28+
"ora": "^8.0.1",
29+
"package-json": "^10.0.0",
30+
"path": "^0.12.7",
31+
"semver": "^7.6.0",
32+
"terminal-link": "^3.0.0"
33+
},
34+
"devDependencies": {
35+
"@types/fs-extra": "^11.0.0",
36+
"@types/semver": "^7.5.8"
37+
},
38+
"files": [
39+
"dist",
40+
"starter",
41+
"cli.js"
42+
]
43+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import getPackageJson from 'package-json';
2+
import currentPkgJson from '../package.json';
3+
import * as semver from 'semver';
4+
5+
export async function checkVersion() {
6+
try {
7+
const { version } = await getPackageJson('create-keystone-app');
8+
if (typeof version !== 'string') {
9+
throw new Error(
10+
'version from package metadata was expected to be a string but was not'
11+
);
12+
}
13+
if (semver.lt(currentPkgJson.version, version)) {
14+
console.error(
15+
`⚠️ You're running an old version of create-keystone-app, please update to ${version}`
16+
);
17+
}
18+
} catch (err) {
19+
console.error(
20+
'A problem occurred fetching the latest version of create-keystone-app'
21+
);
22+
console.error(err);
23+
}
24+
}

packages/create/src/index.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import fs from 'fs-extra';
2+
import path from 'path';
3+
import meow from 'meow';
4+
import enquirer from 'enquirer';
5+
import execa from 'execa';
6+
import ora from 'ora';
7+
import c from 'chalk';
8+
import terminalLink from 'terminal-link';
9+
import { checkVersion } from './checkVersion';
10+
import { UserError } from './utils';
11+
import { fileURLToPath } from 'url';
12+
13+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
14+
const starterDir = path.normalize(`${__dirname}/../starter`);
15+
16+
const cli = meow(
17+
`
18+
Usage
19+
$ create-keystone-app [directory]
20+
`
21+
);
22+
23+
type Args = {
24+
directory: string;
25+
};
26+
27+
const versionInfo = () => {
28+
process.stdout.write('\n');
29+
console.log(`✨ You're about to generate a project using ${c.bold(
30+
'Keystone 6'
31+
)} packages.
32+
`);
33+
};
34+
35+
async function normalizeArgs(): Promise<Args> {
36+
let directory = cli.input[0];
37+
if (!directory) {
38+
({ directory } = await enquirer.prompt({
39+
type: 'input',
40+
name: 'directory',
41+
message:
42+
'What directory should create-keystone-app generate your app into?',
43+
validate: (x) => !!x,
44+
}));
45+
process.stdout.write('\n');
46+
}
47+
return {
48+
directory: path.resolve(directory),
49+
};
50+
}
51+
52+
function pkgManagerFromUserAgent(userAgent: string | undefined) {
53+
if (!userAgent) return 'npm';
54+
const pkgSpec = userAgent.split(' ')[0];
55+
const [name, _version] = pkgSpec.split('/');
56+
return name ?? 'npm';
57+
}
58+
59+
const installDeps = async (cwd: string): Promise<string> => {
60+
const pkgManager = pkgManagerFromUserAgent(process.env.npm_config_user_agent);
61+
const spinner = ora(
62+
`Installing dependencies with ${pkgManager}. This may take a few minutes.`
63+
).start();
64+
try {
65+
await execa(pkgManager, ['install'], { cwd });
66+
spinner.succeed(`Installed dependencies with ${pkgManager}.`);
67+
return pkgManager;
68+
} catch (err) {
69+
spinner.fail(`Failed to install with ${pkgManager}.`);
70+
throw err;
71+
}
72+
};
73+
74+
(async () => {
75+
versionInfo();
76+
await checkVersion();
77+
const normalizedArgs = await normalizeArgs();
78+
await fs.mkdir(normalizedArgs.directory);
79+
await Promise.all([
80+
...[
81+
'_gitignore',
82+
'schema.ts',
83+
'package.json',
84+
'tsconfig.json',
85+
'schema.graphql',
86+
'schema.prisma',
87+
'keystone.ts',
88+
'auth.ts',
89+
'README.md',
90+
].map((filename) =>
91+
fs.copyFile(
92+
path.join(starterDir, filename),
93+
path.join(normalizedArgs.directory, filename.replace(/^_/, '.'))
94+
)
95+
),
96+
]);
97+
const packageManager = await installDeps(normalizedArgs.directory);
98+
const relativeProjectDir = path.relative(
99+
process.cwd(),
100+
normalizedArgs.directory
101+
);
102+
process.stdout.write('\n');
103+
console.log(`🎉 Keystone created a starter project in: ${c.bold(
104+
relativeProjectDir
105+
)}
106+
107+
${c.bold('To launch your app, run:')}
108+
109+
- cd ${relativeProjectDir}
110+
- ${packageManager} run dev
111+
112+
${c.bold('Next steps:')}
113+
114+
- Read ${c.bold(
115+
`${relativeProjectDir}${path.sep}README.md`
116+
)} for additional getting started details.
117+
- Edit ${c.bold(
118+
`${relativeProjectDir}${path.sep}keystone.ts`
119+
)} to customize your app.
120+
- ${terminalLink('Open the Admin UI', 'http://localhost:3000')}
121+
- ${terminalLink('Open the Graphql API', 'http://localhost:3000/api/graphql')}
122+
- ${terminalLink('Read the docs', 'https://keystonejs.com')}
123+
- ${terminalLink(
124+
'Star Keystone on GitHub',
125+
'https://github.com/keystonejs/keystone'
126+
)}
127+
`);
128+
})().catch((err) => {
129+
if (err instanceof UserError) {
130+
console.error(err.message);
131+
} else {
132+
console.error(err);
133+
}
134+
process.exit(1);
135+
});

packages/create/src/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export class UserError extends Error {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# keystone-app
2+
3+
## 1.0.2
4+
5+
### Patch Changes
6+
7+
- [`3b4360a`](https://github.com/keystonejs/create-keystone-app/commit/3b4360a114f00094e40fdc89dd4c82e1456b9ae5) Thanks [@dcousens](https://github.com/dcousens)! - Fix graphql@^15.8.0 and [email protected] as pseudo-peer dependencies until next `@keystone-6/core` release
8+
9+
## 1.0.1
10+
11+
### Patch Changes
12+
13+
- [#278](https://github.com/keystonejs/create-keystone-app/pull/278) [`26f9a79`](https://github.com/keystonejs/create-keystone-app/commit/26f9a79ef913915bac85657884f85ff7e4da46c2) Thanks [@Noviny](https://github.com/Noviny)! - Improve schema options for linking authors to posts:
14+
- Add `inlineConnect: true` to the post's relationship to users
15+
- Remove authors from being inline-creatable
16+
17+
* [#319](https://github.com/keystonejs/create-keystone-app/pull/319) [`94a859e`](https://github.com/keystonejs/create-keystone-app/commit/94a859e43123d2f348d5e21551d59bd7e257aa81) Thanks [@Achisingh](https://github.com/Achisingh)! - Fix dependencies and update schemas for the latest `keystone-6` release

packages/create/starter/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Keystone Project Starter
2+
3+
Welcome to Keystone!
4+
5+
Run
6+
7+
```
8+
yarn dev
9+
```
10+
11+
To view the config for your new app, look at [./keystone.ts](./keystone.ts)
12+
13+
This project starter is designed to give you a sense of the power Keystone can offer you, and show off some of its main features. It's also a pretty simple setup if you want to build out from it.
14+
15+
We recommend you use this alongside our [getting started walkthrough](https://keystonejs.com/docs/walkthroughs/getting-started-with-create-keystone-app) which will walk you through what you get as part of this starter.
16+
17+
If you want an overview of all the features Keystone offers, check out our [features](https://keystonejs.com/why-keystone#features) page.
18+
19+
## Some Quick Notes On Getting Started
20+
21+
### Changing the database
22+
23+
We've set you up with an [SQLite database](https://keystonejs.com/docs/apis/config#sqlite) for ease-of-use. If you're wanting to use PostgreSQL, you can!
24+
25+
Just change the `db` property on line 16 of the Keystone file [./keystone.ts](./keystone.ts) to
26+
27+
```typescript
28+
db: {
29+
provider: 'postgresql',
30+
url: process.env.DATABASE_URL || 'DATABASE_URL_TO_REPLACE',
31+
}
32+
```
33+
34+
And provide your database url from PostgreSQL.
35+
36+
For more on database configuration, check out or [DB API Docs](https://keystonejs.com/docs/apis/config#db)
37+
38+
### Auth
39+
40+
We've put auth into its own file to make this humble starter easier to navigate. To explore it without auth turned on, comment out the `isAccessAllowed` on line 21 of the Keystone file [./keystone.ts](./keystone.ts).
41+
42+
For more on auth, check out our [Authentication API Docs](https://keystonejs.com/docs/apis/auth#authentication-api)
43+
44+
### Adding a frontend
45+
46+
As a Headless CMS, Keystone can be used with any frontend that uses GraphQL. It provides a GraphQL endpoint you can write queries against at `/api/graphql` (by default [http://localhost:3000/api/graphql](http://localhost:3000/api/graphql)). At Thinkmill, we tend to use [Next.js](https://nextjs.org/) and [Apollo GraphQL](https://www.apollographql.com/docs/react/get-started/) as our frontend and way to write queries, but if you have your own favourite, feel free to use it.
47+
48+
A walkthrough on how to do this is forthcoming, but in the meantime our [todo example](https://github.com/keystonejs/keystone-react-todo-demo) shows a Keystone set up with a frontend. For a more full example, you can also look at an example app we built for [Prisma Day 2021](https://github.com/keystonejs/prisma-day-2021-workshop)
49+
50+
### Embedding Keystone in a Next.js frontend
51+
52+
While Keystone works as a standalone app, you can embed your Keystone app into a [Next.js](https://nextjs.org/) app. This is quite a different setup to the starter, and we recommend checking out our walkthrough for that [here](https://keystonejs.com/docs/walkthroughs/embedded-mode-with-sqlite-nextjs#how-to-embed-keystone-sq-lite-in-a-next-js-app).

packages/create/starter/_gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
.keystone/
3+
keystone.db
4+
*.log

0 commit comments

Comments
 (0)