@automerge/create-repo-node-app 2.6.0-subduction.8 → 2.7.0-authors.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,19 +1,17 @@
1
1
  # Scaffolding for a node `automerge-repo` app
2
2
 
3
- This generates a simple javascript project with the necessary dependencies for a repo which synchronises over websockets and stores data in the filesystem.
3
+ This generates a simple TypeScript project with the dependencies for a repo that
4
+ synchronises over WebSockets and stores data on the filesystem.
4
5
 
5
6
  ## How to use
6
7
 
7
- ### NPM
8
-
9
8
  ```
10
9
  npm create @automerge/repo-node-app <your project name>
11
10
  ```
12
11
 
13
- ### Yarn
14
-
15
- ```
16
- yarn create @automerge/repo-node-app <your project name>
17
- ```
12
+ (or `pnpm create`, `yarn create`, `bun create` — the scaffold detects your
13
+ package manager.)
18
14
 
19
- Now change into the directory and start editing `index.js`
15
+ The project runs with Node's built-in TypeScript support, so there is no build
16
+ step. Change into the directory, install dependencies, and start editing
17
+ `index.ts`.
package/dist/index.js CHANGED
@@ -1,47 +1,78 @@
1
1
  #!/usr/bin/env node
2
- import fs from "fs";
3
- import path from "path";
4
- import child_process from "child_process";
5
- const execSync = child_process.execSync;
6
- function createPackageJson(projectName) {
7
- const packageJson = {
8
- name: projectName,
9
- version: "1.0.0",
10
- description: "",
11
- main: "index.js",
12
- type: "module",
13
- scripts: {
14
- start: "node index.js",
15
- },
16
- dependencies: {
17
- "@automerge/automerge-repo": "^1.0",
18
- "@automerge/automerge-repo-network-websocket": "^1.0",
19
- "@automerge/automerge-repo-storage-nodefs": "^1.0",
20
- },
21
- };
22
- fs.writeFileSync(path.join(projectName, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
23
- }
24
- function createIndexJs(projectName) {
25
- const indexJsContent = `import { Repo } from "@automerge/automerge-repo"
26
- import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket"
27
- import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs"
28
-
29
- const repo = new Repo({
30
- storage: new NodeFSStorageAdapter("./db"),
31
- network: [new WebSocketClientAdapter("wss://sync.automerge.org")]
32
- })
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { intro, outro, text, isCancel, cancel, log } from "@clack/prompts";
6
+ const detectPackageManager = () => {
7
+ const ua = process.env.npm_config_user_agent ?? "";
8
+ return ua.split(" ")[0]?.split("/")[0] || "npm";
9
+ };
10
+ const copy = (src, dest) => {
11
+ if (fs.statSync(src).isDirectory()) {
12
+ copyDir(src, dest);
13
+ }
14
+ else {
15
+ fs.copyFileSync(src, dest);
16
+ }
17
+ };
18
+ const copyDir = (srcDir, destDir) => {
19
+ fs.mkdirSync(destDir, { recursive: true });
20
+ for (const file of fs.readdirSync(srcDir)) {
21
+ copy(path.resolve(srcDir, file), path.resolve(destDir, file));
22
+ }
23
+ };
24
+ // Written here rather than shipped as a template file: npm strips files named
25
+ // .gitignore from published packages, so the template can't carry one directly.
26
+ const GITIGNORE = `node_modules
27
+ automerge-data
28
+ *.log
33
29
  `;
34
- fs.writeFileSync(path.join(projectName, "index.js"), indexJsContent);
35
- }
36
- function main() {
37
- const projectName = process.argv[2];
30
+ const main = async () => {
31
+ intro("create-repo-node-app · Automerge for Node");
32
+ let projectName = process.argv[2];
38
33
  if (!projectName) {
39
- console.error("Please provide a project name");
34
+ const answer = await text({
35
+ message: "Project name?",
36
+ placeholder: "my-automerge-app",
37
+ validate: value => value && value.trim().length > 0
38
+ ? undefined
39
+ : "Please enter a project name",
40
+ });
41
+ if (isCancel(answer)) {
42
+ cancel("Scaffolding cancelled.");
43
+ process.exit(0);
44
+ }
45
+ projectName = answer.trim();
46
+ }
47
+ const root = path.join(process.cwd(), projectName);
48
+ if (fs.existsSync(root)) {
49
+ cancel(`Directory "${projectName}" already exists.`);
40
50
  process.exit(1);
41
51
  }
42
- fs.mkdirSync(projectName);
43
- createPackageJson(projectName);
44
- createIndexJs(projectName);
45
- execSync(`cd ${projectName} && npm install`, { stdio: "inherit" });
46
- }
47
- main();
52
+ const templateDir = path.resolve(fileURLToPath(import.meta.url), "../../template");
53
+ fs.mkdirSync(root, { recursive: true });
54
+ for (const file of fs.readdirSync(templateDir)) {
55
+ if (file === "package.json")
56
+ continue;
57
+ copy(path.join(templateDir, file), path.join(root, file));
58
+ }
59
+ // Copy package.json with the chosen project name.
60
+ const pkg = JSON.parse(fs.readFileSync(path.join(templateDir, "package.json"), "utf-8"));
61
+ pkg.name = projectName;
62
+ fs.writeFileSync(path.join(root, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
63
+ fs.writeFileSync(path.join(root, ".gitignore"), GITIGNORE);
64
+ log.success(`Created ${projectName}`);
65
+ const pm = detectPackageManager();
66
+ const run = pm === "npm" ? "npm run" : pm;
67
+ outro([
68
+ "Next steps:",
69
+ ` cd ${projectName}`,
70
+ ` ${pm} install`,
71
+ ` ${run} start`,
72
+ ].join("\n"));
73
+ };
74
+ main().catch(error => {
75
+ console.error(error);
76
+ process.exit(1);
77
+ });
78
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,18 +1,36 @@
1
1
  {
2
2
  "name": "@automerge/create-repo-node-app",
3
- "version": "2.6.0-subduction.8",
3
+ "version": "2.7.0-authors.0",
4
4
  "description": "Create an automerge-repo app for node",
5
- "repository": "https://github.com/automerge/automerge-repo/tree/master/packages/create-repo-node-app",
5
+ "repository": "https://github.com/automerge/automerge-repo/tree/main/packages/create-repo-node-app",
6
6
  "author": "Alex Good <alex@memoryandthought.me>",
7
7
  "license": "MIT",
8
8
  "type": "module",
9
- "bin": "dist/index.js",
9
+ "files": [
10
+ "dist/index.js",
11
+ "template"
12
+ ],
10
13
  "publishConfig": {
11
14
  "access": "public",
12
15
  "tag": "subduction"
13
16
  },
17
+ "dependencies": {
18
+ "@clack/prompts": "^1.4.0"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^22.19.19",
22
+ "execa": "^9.6.1",
23
+ "typescript": "^6.0.3"
24
+ },
25
+ "engines": {
26
+ "node": ">=22.13"
27
+ },
14
28
  "scripts": {
15
29
  "build": "tsc",
16
- "postbuild": "node postbuild.js"
30
+ "postbuild": "node postbuild.js",
31
+ "test": "node test.js"
32
+ },
33
+ "bin": {
34
+ "create-repo-node-app": "dist/index.js"
17
35
  }
18
36
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": ["typescript", "import"],
4
+ "categories": {
5
+ "correctness": "error"
6
+ },
7
+ "ignorePatterns": ["dist"]
8
+ }
@@ -0,0 +1,28 @@
1
+ # Automerge node app
2
+
3
+ A starter [Automerge](https://automerge.org) app for Node. It keeps a repo of
4
+ documents on the local filesystem and syncs them with a WebSocket sync server.
5
+
6
+ ## Run
7
+
8
+ ```sh
9
+ pnpm install
10
+ pnpm start
11
+ ```
12
+
13
+ `pnpm start` runs `index.ts` directly using Node's built-in TypeScript support
14
+ (Node 22.18+), so there is no build step. Edit `index.ts` to build your app.
15
+
16
+ ## Type-check
17
+
18
+ ```sh
19
+ pnpm typecheck
20
+ ```
21
+
22
+ ## Lint
23
+
24
+ ```sh
25
+ pnpm lint
26
+ ```
27
+
28
+ Linting uses [oxlint](https://oxc.rs).
@@ -0,0 +1,20 @@
1
+ import { Repo } from "@automerge/automerge-repo"
2
+ import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket"
3
+ import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs"
4
+
5
+ // A repo that persists documents to the local filesystem and syncs them with a
6
+ // WebSocket sync server. Point the adapter at your own server for production.
7
+ const repo = new Repo({
8
+ storage: new NodeFSStorageAdapter("./automerge-data"),
9
+ network: [new WebSocketClientAdapter("wss://sync.automerge.org")],
10
+ })
11
+
12
+ // Create a document and make a change. Share `handle.url` with another peer
13
+ // (or load it elsewhere) to sync the same document.
14
+ const handle = repo.create<{ count: number }>({ count: 0 })
15
+ handle.change(doc => {
16
+ doc.count += 1
17
+ })
18
+
19
+ console.log(`Created document: ${handle.url}`)
20
+ console.log("Syncing… press Ctrl+C to stop.")
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "projectName",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=22.18"
8
+ },
9
+ "scripts": {
10
+ "start": "node index.ts",
11
+ "typecheck": "tsc",
12
+ "lint": "oxlint"
13
+ },
14
+ "dependencies": {
15
+ "@automerge/automerge-repo": "^2.5.6",
16
+ "@automerge/automerge-repo-network-websocket": "^2.5.6",
17
+ "@automerge/automerge-repo-storage-nodefs": "^2.5.6"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^22.19.0",
21
+ "oxlint": "^1.67.0",
22
+ "typescript": "^6.0.3"
23
+ }
24
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "nodenext",
6
+ "strict": true,
7
+ "skipLibCheck": true,
8
+ "noEmit": true,
9
+ "types": ["node"]
10
+ },
11
+ "include": ["*.ts"]
12
+ }
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/postbuild.js DELETED
@@ -1,3 +0,0 @@
1
- import fs from "fs"
2
-
3
- fs.chmodSync("dist/index.js", "755")
package/src/index.ts DELETED
@@ -1,57 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "fs"
4
- import path from "path"
5
- import child_process from "child_process"
6
-
7
- const execSync = child_process.execSync
8
-
9
- function createPackageJson(projectName: string) {
10
- const packageJson = {
11
- name: projectName,
12
- version: "1.0.0",
13
- description: "",
14
- main: "index.js",
15
- type: "module",
16
- scripts: {
17
- start: "node index.js",
18
- },
19
- dependencies: {
20
- "@automerge/automerge-repo": "^1.0",
21
- "@automerge/automerge-repo-network-websocket": "^1.0",
22
- "@automerge/automerge-repo-storage-nodefs": "^1.0",
23
- },
24
- }
25
- fs.writeFileSync(
26
- path.join(projectName, "package.json"),
27
- JSON.stringify(packageJson, null, 2) + "\n"
28
- )
29
- }
30
-
31
- function createIndexJs(projectName: string) {
32
- const indexJsContent = `import { Repo } from "@automerge/automerge-repo"
33
- import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket"
34
- import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs"
35
-
36
- const repo = new Repo({
37
- storage: new NodeFSStorageAdapter("./db"),
38
- network: [new WebSocketClientAdapter("wss://sync.automerge.org")]
39
- })
40
- `
41
- fs.writeFileSync(path.join(projectName, "index.js"), indexJsContent)
42
- }
43
-
44
- function main() {
45
- const projectName = process.argv[2]
46
- if (!projectName) {
47
- console.error("Please provide a project name")
48
- process.exit(1)
49
- }
50
-
51
- fs.mkdirSync(projectName)
52
- createPackageJson(projectName)
53
- createIndexJs(projectName)
54
- execSync(`cd ${projectName} && npm install`, { stdio: "inherit" })
55
- }
56
-
57
- main()
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "jsx": "react",
5
- "module": "NodeNext",
6
- "moduleResolution": "Node16",
7
- "declaration": true,
8
- "declarationMap": true,
9
- "outDir": "./dist",
10
- "esModuleInterop": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "strict": true,
13
- "skipLibCheck": true
14
- },
15
- "include": ["src/**/*.ts"],
16
- "exclude": ["dist"]
17
- }
package/vitest.config.ts DELETED
@@ -1,11 +0,0 @@
1
- import { defineConfig, mergeConfig } from "vitest/config"
2
- import rootConfig from "../../vitest.config"
3
-
4
- export default mergeConfig(
5
- rootConfig,
6
- defineConfig({
7
- test: {
8
- environment: "node",
9
- },
10
- })
11
- )