notas 0.0.0 → 26.2.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 +115 -0
- package/bin/install.js +63 -0
- package/bin/install.sh +24 -0
- package/bin/notas +15 -0
- package/package.json +43 -4
- package/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# notas
|
|
2
|
+
|
|
3
|
+
Multi-provider notes & docs CLI. Notion is the first supported provider.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Homebrew
|
|
9
|
+
brew install circlesac/tap/notas
|
|
10
|
+
|
|
11
|
+
# npm
|
|
12
|
+
npx @circlesac/notas
|
|
13
|
+
|
|
14
|
+
# From source
|
|
15
|
+
bun install
|
|
16
|
+
bun run build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Authenticate (opens browser for OAuth)
|
|
23
|
+
notas notion auth login
|
|
24
|
+
|
|
25
|
+
# Or use an integration token
|
|
26
|
+
notas notion auth login --token ntn_xxx
|
|
27
|
+
|
|
28
|
+
# List databases
|
|
29
|
+
notas notion db list
|
|
30
|
+
|
|
31
|
+
# Query a database
|
|
32
|
+
notas notion db query <database-id>
|
|
33
|
+
|
|
34
|
+
# Search
|
|
35
|
+
notas notion search <query>
|
|
36
|
+
|
|
37
|
+
# Output as JSON
|
|
38
|
+
notas notion db list --output json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Commands
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
notas notion auth login, logout, status, refresh
|
|
45
|
+
notas notion databases list, get, query, create, update, delete
|
|
46
|
+
notas notion pages get, create, update, archive, restore
|
|
47
|
+
notas notion blocks list, get, append, update, delete
|
|
48
|
+
notas notion users list, get, me
|
|
49
|
+
notas notion search <query>
|
|
50
|
+
notas notion comments list, create
|
|
51
|
+
notas notion api <method> <endpoint> [--body json]
|
|
52
|
+
notas notion version
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`db` is an alias for `databases`.
|
|
56
|
+
|
|
57
|
+
## Development
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Run locally
|
|
61
|
+
bun run dev -- notion db list
|
|
62
|
+
|
|
63
|
+
# Lint (oxlint + eslint + prettier + biome + tsc)
|
|
64
|
+
bun run lint
|
|
65
|
+
|
|
66
|
+
# Type check
|
|
67
|
+
bun run type-check
|
|
68
|
+
|
|
69
|
+
# Test
|
|
70
|
+
bun run test
|
|
71
|
+
|
|
72
|
+
# Build native binary
|
|
73
|
+
bun run build
|
|
74
|
+
|
|
75
|
+
# Full pre-merge check
|
|
76
|
+
bun run pre-merge
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Project Structure
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
src/
|
|
83
|
+
index.ts CLI entry point
|
|
84
|
+
lib/ Shared utilities (credentials, output, errors)
|
|
85
|
+
platforms/notion/ Notion provider
|
|
86
|
+
auth/ login, logout, status, refresh
|
|
87
|
+
databases/ CRUD + query
|
|
88
|
+
pages/ CRUD + archive/restore
|
|
89
|
+
blocks/ CRUD + append
|
|
90
|
+
users/ list, get, me
|
|
91
|
+
search/ full-text search
|
|
92
|
+
comments/ list, create
|
|
93
|
+
api.ts raw API passthrough
|
|
94
|
+
client.ts Notion client factory
|
|
95
|
+
properties.ts property formatting
|
|
96
|
+
types/ shared types
|
|
97
|
+
worker/ Cloudflare Worker (OAuth callback relay at notas.circles.ac)
|
|
98
|
+
npm/ npm distribution (shim + installer)
|
|
99
|
+
homebrew/ Homebrew formula template
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Deploy
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Deploy OAuth callback worker
|
|
106
|
+
bun run deploy:worker
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Release
|
|
110
|
+
|
|
111
|
+
Releases are triggered via `workflow_dispatch` in GitHub Actions. The workflow runs tests, bumps the version (CalVer via `@circlesac/oneup`), builds native binaries for 4 platforms, creates a GitHub Release, publishes to npm, and updates the Homebrew formula.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
gh workflow run release.yml
|
|
115
|
+
```
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import https from "https";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import { createRequire } from "module";
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
const REPO = "circlesac/notas-cli";
|
|
12
|
+
|
|
13
|
+
const PLATFORMS = {
|
|
14
|
+
"darwin-x64": { artifact: "notas-darwin-x64", ext: ".tar.gz" },
|
|
15
|
+
"darwin-arm64": { artifact: "notas-darwin-arm64", ext: ".tar.gz" },
|
|
16
|
+
"linux-x64": { artifact: "notas-linux-x64", ext: ".tar.gz" },
|
|
17
|
+
"linux-arm64": { artifact: "notas-linux-arm64", ext: ".tar.gz" },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function download(url) {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
https.get(url, (res) => {
|
|
23
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
24
|
+
return download(res.headers.location).then(resolve).catch(reject);
|
|
25
|
+
}
|
|
26
|
+
if (res.statusCode !== 200) return reject(new Error(`HTTP ${res.statusCode}`));
|
|
27
|
+
const chunks = [];
|
|
28
|
+
res.on("data", (c) => chunks.push(c));
|
|
29
|
+
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
30
|
+
res.on("error", reject);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const nativeDir = path.join(__dirname, "native");
|
|
36
|
+
const binPath = path.join(nativeDir, "notas");
|
|
37
|
+
|
|
38
|
+
if (!fs.existsSync(binPath)) {
|
|
39
|
+
const { version } = require("../package.json");
|
|
40
|
+
if (version) {
|
|
41
|
+
const platform = `${process.platform}-${process.arch}`;
|
|
42
|
+
const info = PLATFORMS[platform];
|
|
43
|
+
if (!info) {
|
|
44
|
+
console.error(`Unsupported platform: ${platform}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { artifact, ext } = info;
|
|
49
|
+
const url = `https://github.com/${REPO}/releases/download/v${version}/${artifact}${ext}`;
|
|
50
|
+
console.info(`Downloading notas v${version} for ${platform}...`);
|
|
51
|
+
|
|
52
|
+
const data = await download(url);
|
|
53
|
+
fs.mkdirSync(nativeDir, { recursive: true });
|
|
54
|
+
|
|
55
|
+
const tmp = path.join(nativeDir, `tmp${ext}`);
|
|
56
|
+
fs.writeFileSync(tmp, data);
|
|
57
|
+
execSync(`tar xzf "${tmp}"`, { cwd: nativeDir });
|
|
58
|
+
fs.unlinkSync(tmp);
|
|
59
|
+
|
|
60
|
+
fs.chmodSync(binPath, 0o755);
|
|
61
|
+
console.info("Installed successfully.");
|
|
62
|
+
}
|
|
63
|
+
}
|
package/bin/install.sh
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
REPO="circlesac/notas-cli"
|
|
5
|
+
INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"
|
|
6
|
+
|
|
7
|
+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
8
|
+
ARCH=$(uname -m)
|
|
9
|
+
|
|
10
|
+
case "$OS-$ARCH" in
|
|
11
|
+
darwin-arm64) NAME="notas-darwin-arm64" ;;
|
|
12
|
+
darwin-x86_64) NAME="notas-darwin-x64" ;;
|
|
13
|
+
linux-aarch64) NAME="notas-linux-arm64" ;;
|
|
14
|
+
linux-x86_64) NAME="notas-linux-x64" ;;
|
|
15
|
+
*) echo "Unsupported platform: $OS-$ARCH"; exit 1 ;;
|
|
16
|
+
esac
|
|
17
|
+
|
|
18
|
+
VERSION=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name"' | cut -d'"' -f4)
|
|
19
|
+
URL="https://github.com/$REPO/releases/download/$VERSION/${NAME}.tar.gz"
|
|
20
|
+
|
|
21
|
+
echo "Installing notas $VERSION..."
|
|
22
|
+
curl -fsSL "$URL" | tar xz -C "$INSTALL_DIR"
|
|
23
|
+
chmod +x "$INSTALL_DIR/notas"
|
|
24
|
+
echo "Installed to $INSTALL_DIR/notas"
|
package/bin/notas
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from "child_process";
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const bin = path.join(__dirname, "native", "notas");
|
|
10
|
+
|
|
11
|
+
if (!existsSync(bin)) {
|
|
12
|
+
await import("./install.js");
|
|
13
|
+
}
|
|
14
|
+
const result = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
15
|
+
process.exit(result.status ?? 1);
|
package/package.json
CHANGED
|
@@ -1,7 +1,46 @@
|
|
|
1
1
|
{
|
|
2
|
+
"bin": {
|
|
3
|
+
"notas": "bin/notas"
|
|
4
|
+
},
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@notionhq/client": "^5.9.0",
|
|
7
|
+
"citty": "^0.2.1"
|
|
8
|
+
},
|
|
9
|
+
"description": "Multi-provider notes & docs CLI",
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@types/bun": "latest",
|
|
12
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
13
|
+
"vitest": "^4.0.18"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin",
|
|
17
|
+
"skills"
|
|
18
|
+
],
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"module": "src/index.ts",
|
|
2
21
|
"name": "notas",
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"typescript": "^5"
|
|
24
|
+
},
|
|
25
|
+
"pi": {
|
|
26
|
+
"skills": [
|
|
27
|
+
"./skills"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/circlesac/notas-cli"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "bun build --compile --outfile=dist/notas src/index.ts",
|
|
36
|
+
"deploy:worker": "cd worker && npx wrangler deploy",
|
|
37
|
+
"dev": "bun run src/index.ts",
|
|
38
|
+
"lint": "npx @circlesac/lint --all",
|
|
39
|
+
"postinstall": "node bin/install.js",
|
|
40
|
+
"pre-merge": "bun run lint && bun run type-check && bun run test && bun run build",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"type-check": "npx tsc --noEmit"
|
|
43
|
+
},
|
|
44
|
+
"type": "module",
|
|
45
|
+
"version": "26.2.0"
|
|
7
46
|
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|