Skip to content

Commit

Permalink
🚀 add new:do script to create do boilerplate
Browse files Browse the repository at this point in the history
  • Loading branch information
Girish21 committed Jun 12, 2022
1 parent c50f112 commit bf6feba
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 67 deletions.
85 changes: 18 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ wrangler login
Let's install the dependencies.

```sh
npm i
npm install
```

Now we can set up the project.
Expand All @@ -59,9 +59,9 @@ git push
### Recap 🌀

```sh
npm i @cloudflare/wrangler -g
npm install @cloudflare/wrangler -g
wrangler login
npm i
npm install
npm run setup
# configure CF_API_TOKEN action secret
git add -A -m "<message>"
Expand All @@ -76,70 +76,19 @@ This starter template comes with a simple DO implementation to keep track of the

If you're starting with DO and not sure what it is, go through the official docs on [Durable Objects](https://developers.cloudflare.com/workers/runtime-apis/durable-objects/) will be a good start! And checkout [using durable objects](https://developers.cloudflare.com/workers/learning/using-durable-objects/) for more applications of DO.

### Defining a DO Class

To create a new DO class, create a new directory inside `packages`. Create four files,

1. `package.json`

```json
{
"name": "<DO name>",
"version": "0.0.0",
"license": "MIT",
"main": "index.ts",
"types": "index.ts",
"scripts": {
"lint": "eslint .",
"typecheck": "tsc -b"
},
"devDependencies": {
"@cloudflare/workers-types": "^3.10.0",
"eslint": "^8.15.0",
"eslint-config-custom": "*",
"tsconfig": "*",
"typescript": "^4.6.4"
}
}
```

2. `tsconfig.json`

```json
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "tsconfig/base.json",
"compilerOptions": {
"target": "ES2019",
"types": ["@cloudflare/workers-types"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"resolveJsonModule": true,
"isolatedModules": true,
"moduleResolution": "node"
},
"include": ["**/*.ts"],
"exclude": ["node_modules"]
}
```

3. `eslintrc.js`

```js
module.exports = {
root: true,
extends: ['custom'],
}
```

4. `index.ts`
Define your Durable Object class here.
### Defining a Durable Object

This template comes with a script to create the boilerplate for a new Durable Object class.

```sh
npm run new:do
```

The script will have instructions to initialise the DO with the worker. Don't forget to follow them!

#### More information on DO

> You can skip this section if you have used the script to generate the DO class. Continue for more information on DO :)
To define a DO class, check out the [docs](https://developers.cloudflare.com/workers/runtime-apis/durable-objects/#durable-object-class-definition).

Expand All @@ -151,6 +100,8 @@ bindings = [
{name = "<DO_BINDING_NAME>", class_name = "<DO_CLASS_NAME>"},
]

For development add the following to [`wrangler.dev.toml`](packages/worker/wrangler.dev.toml)

[env.dev.durable_objects]
bindings = [
{name = "<DO_BINDING_NAME>", class_name = "<DO_CLASS_NAME>"},
Expand Down
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

100 changes: 100 additions & 0 deletions scripts/new-do.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import fs from 'fs-extra'
import path from 'path'
import inquirer from 'inquirer'

function format(str: string) {
let lowercase = str.toLowerCase()
let uppercase = str.toUpperCase()

return {
capitalize: lowercase.charAt(0).toUpperCase() + lowercase.slice(1),
lowercase,
uppercase,
}
}

async function run() {
let answer = await inquirer.prompt<{ name: string }>([
{
name: 'name',
type: 'input',
message: 'What is the name of the Durable Object?',
validate: (input: string) => {
if (input.length === 0) {
return 'Please enter a name for the Durable Object.'
}
return true
},
},
])
let { capitalize, lowercase, uppercase } = format(answer.name)
let projectName = `${lowercase}-do`
let outputDir = path.join(process.cwd(), `packages/${projectName}`)
if (fs.existsSync(outputDir)) {
console.error(`\n🚨 Directory '${outputDir}' already exists.\n`)
throw new Error(`Directory ${outputDir} already exists.`)
}
await fs.mkdirp(outputDir)

let baseDir = path.join(process.cwd(), 'scripts/new-do')
let [eslintrc, packageJson, tsconfig] = await Promise.all([
fs.readFile(path.join(baseDir, 'tmp-eslintrc.js'), 'utf8'),
fs.readFile(path.join(baseDir, 'tmp-package.json'), 'utf8'),
fs.readFile(path.join(baseDir, 'tmp-tsconfig.json'), 'utf8'),
])
let parsedPackageJson = JSON.parse(packageJson)
parsedPackageJson.name = projectName
let index = `export default class ${capitalize}DurableObject {
constructor(private state: DurableObjectState) {}
}
`
await Promise.all([
fs.writeFile(path.join(outputDir, '.eslintrc.js'), eslintrc),
fs.writeFile(
path.join(outputDir, 'package.json'),
JSON.stringify(parsedPackageJson, null, 2),
),
fs.writeFile(path.join(outputDir, 'tsconfig.json'), tsconfig),
fs.writeFile(path.join(outputDir, 'index.ts'), index),
])

console.error(`\n🔨 Created ${projectName} package.\n
Now we need to add the Durable Objects bindings to your worker configuration file.
1. Open 'package.json' of 'packages/worker', and add the following to the 'dependencies' section:\n
"${projectName}": "*"\n
2. Open 'packages/worker/wrangler.toml' and add the following to the 'durable_objects' section:\n
{name = "${uppercase}", class_name = "${capitalize}DurableObject"}\n
3. Open 'packages/worker/wrangler.dev.toml' and add the following to the 'durable_objects' section:\n
{name = "${uppercase}", class_name = "${capitalize}DurableObject"}\n
4. We also need to add a migration for the Durable Object in the 'migrations' section of 'packages/worker/wrangler.toml' and as well as 'packages/worker/wrangler.dev.toml'.\n
[[migrations]]
tag = "vx"
new_classes = ["${capitalize}DurableObject"]\n
5. Now, open 'packages/worker/src/index.ts' and add the following export at the top of the file.\n
export { default as ${capitalize}DurableObject } from '${projectName}'\n
6. Great, just one last thing. Open 'config/cloudflare-env/index.d.ts' and add the following for types\n
${uppercase}: DurableObjectNamespace\n
6. Now from the project root run 'npm install'
`)

console.error(
`\n🚨 Be sure to checkout the instructions specified above\n🎉 Successfully created "${projectName}"`,
)

console.error(
`\ncd ${path.relative(
process.cwd(),
path.join(outputDir, 'index.ts'),
)} and create awsome things!\n`,
)
console.error(
'Visit https://developers.cloudflare.com/workers/learning/using-durable-objects/ for more information.',
)
}

run().catch(e => {
console.error(e)
process.exit(1)
})

export {}
4 changes: 4 additions & 0 deletions scripts/new-do/tmp-eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ['custom'],
}
18 changes: 18 additions & 0 deletions scripts/new-do/tmp-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "new-do",
"version": "0.0.0",
"license": "MIT",
"main": "index.ts",
"types": "index.ts",
"scripts": {
"lint": "eslint .",
"typecheck": "tsc -b"
},
"devDependencies": {
"@cloudflare/workers-types": "^3.10.0",
"eslint": "^8.15.0",
"eslint-config-custom": "*",
"tsconfig": "*",
"typescript": "^4.6.4"
}
}
21 changes: 21 additions & 0 deletions scripts/new-do/tmp-tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "tsconfig/base.json",
"compilerOptions": {
"target": "ES2019",
"types": ["@cloudflare/workers-types"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"resolveJsonModule": true,
"isolatedModules": true,
"moduleResolution": "node"
},
"include": ["**/*.ts"],
"exclude": ["node_modules"]
}
8 changes: 8 additions & 0 deletions scripts/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ async function run() {
)

console.error('\n🎉 Done!')

console.error('\nAvailable commands:')
console.error('npm run dev - Starts the development server')
console.error('npm run build - Builds the monorepo')
console.error('npm run lint - Lints the monorepo')
console.error('npm run format - Formats the monorepo')
console.error('npm run typecheck - Typechecks the monorepo')
console.error('npm run new:do - Creates a new Durable Object class file')
}

run().catch(e => {
Expand Down

0 comments on commit bf6feba

Please sign in to comment.