[READ-ONLY] Mirror of https://github.com/andrioid/n8n-nodes-atproto. atproto node for n8n
0

Configure Feed

Select the types of activity you want to include in your feed.

Update PLAN.md and DESIGN.md for Vite bundling

- Dependencies section: runtime → none, all bundled by Vite
- Tooling section: n8n-node build → vite build
- Decisions log: entries 13-14 (zero deps, uint8arrays patch)
- Distribution checklist: mark lint/test/build/dev as done
- File structure: add blob.ts, scripts/, vite config, CONTRIBUTING
- Bundle size table with per-chunk breakdown

+45 -33
+7 -3
DESIGN.md
··· 233 233 │ ├── operations.ts # CRUD operation logic 234 234 │ ├── lexicon.ts # Resolve + parse lexicon schemas 235 235 │ ├── fieldMapping.ts # Lexicon schema → ResourceMapperField[] 236 + │ ├── blob.ts # Blob upload for binary fields 236 237 │ ├── tid.ts # TID generation 237 238 │ └── atproto.svg # Node icon 238 239 ├── tests/ 240 + ├── scripts/ 241 + │ └── patch-node-js-exports.mjs # postinstall: fix uint8arrays for dev 239 242 ├── package.json 240 243 ├── tsconfig.json 241 - ├── oxlint.json 244 + ├── vite.config.build.ts # Vite library mode build config 242 245 ├── vitest.config.ts 243 246 ├── README.md 247 + ├── CONTRIBUTING.md 244 248 ├── DESIGN.md 245 - └── TODO.md 249 + └── PLAN.md 246 250 ``` 247 251 248 - Files live under `src/` so `n8n-node dev` can watch and hot-reload them. The `@n8n/node-cli` handles building, icon copying, and linking to n8n. 252 + Files live under `src/`. `n8n-node dev` watches and hot-reloads. `vite build` bundles everything into `dist/` with zero runtime dependencies. 249 253 250 254 ## Phasing 251 255
+38 -30
PLAN.md
··· 7 7 | Phase 0 — Scaffolding | ✅ Done | n/a | `d9c7329` | 8 8 | Phase 1 — Generic CRUD | ✅ Done | 35 | `d9c7329` | 9 9 | Phase 2 — Dynamic field mapping | ✅ Done | 57 | `31140d5`, `34a5e16` (review fixes) | 10 - | Phase 3 — Blob support | ✅ Done | 11 | — | 11 - | Distribution | ⏳ Not started | — | — | 10 + | Phase 3 — Blob support | ✅ Done | 11 | `8f468d7` | 11 + | Distribution — Bundling | ✅ Done | — | `00a4933`, `976ee7e` | 12 + | Distribution — Publish | ⏳ Not started | — | — | 12 13 13 - **Current totals:** 103 tests passing, lint clean, build clean. 14 + **Current totals:** 103 tests passing, lint clean, build clean (Vite, ~100ms). 14 15 15 16 ## Decisions Log 16 17 ··· 30 31 | 10 | `@atproto/api` XRPC validation rejects `record` type in `resolveLexicon` response | Call the typed client anyway; on `XRPCInvalidResponseError`, extract `responseBody.schema` and parse it. Future: replace with raw `fetch()` if upstream issue persists | The validation throws on a valid response. Catching the error and using its `responseBody` is pragmatic; the response data is still well-formed | 31 32 | 11 | Dotted-key un-flattening | `buildRecordFromNodeParams` runs `unflattenDottedKeys` over the resourceMapper value before sending to the PDS. Empty values are dropped | Refs and inline objects flatten to keys like `reply.root`, `reply.parent` for the UI; the PDS expects nested objects | 32 33 | 12 | Ref sub-field required propagation | `resolveRefProperties` returns `{ properties, required }`. A flattened sub-field is required iff the parent ref is required AND the resolved schema lists it as required | Otherwise optional refs would mark their sub-fields as required, confusing the user | 34 + | 13 | Zero runtime dependencies | Bundle `@atproto/api` and `@atproto/lexicon-resolver` into `dist/` with Vite. Published package has empty `dependencies`. Only `n8n-workflow` is externalized. | n8n verification guidelines require no runtime deps. Also fixes `n8n-node dev` crash — the dev symlink exposes `node_modules` and n8n’s glob picks up `uint8arrays/*.node.js` files | 35 + | 14 | `uint8arrays` `.node.js` files | `postinstall` script patches `uint8arrays`’ conditional exports to redirect `"node"` → `"import"` targets, then deletes the `.node.js` files | These platform-specific files (Buffer vs Uint8Array) crash n8n’s node loader during dev. The ESM fallbacks are functionally identical | 33 36 34 37 ## Tooling 35 38 36 39 | Purpose | Tool | Notes | 37 40 |---------|------|-------| 38 - | Dev server | `n8n-node dev` | Hot reload. Edit → save → auto-rebuild → refresh browser. | 39 - | Build | `n8n-node build` | Handles TypeScript + icon copying. No custom scripts. | 40 - | Lint | `oxlint` + `@n8n/eslint-plugin-community-nodes` via jsPlugins | Rust-native speed. jsPlugins is alpha (99.5% pass rate on popular plugins) — if it fails with this plugin, fall back to eslint for n8n rules only. | 41 + | Dev server | `n8n-node dev` | Hot reload. Symlinks project into n8n’s custom nodes dir. | 42 + | Build | `vite build` (library mode) | Bundles all deps into `dist/`. CJS output, ~100ms. Vite is already installed via vitest — no extra dependency. | 43 + | Lint | `oxlint` | Rust-native speed. | 41 44 | Format | `oxfmt` | Separate npm package (not bundled with oxlint). Config file: `.oxfmtrc.json`. | 42 45 | Test | `vitest` + `msw` | ESM-native. Mock XRPC server. | 43 46 | Publish | `n8n-node release` | Builds, lints, tags, publishes to npm with provenance. | 44 47 45 48 ## Dependencies 46 49 47 - ### Runtime (2 packages) 48 - 49 - ``` 50 - @atproto/api — CredentialSession, Agent, XRPC, DID resolution 51 - deps: @atproto/lexicon, @atproto/xrpc, @atproto/syntax, @atproto/common-web, multiformats, zod 52 - @atproto/lexicon-resolver — DNS-based lexicon resolution (fallback for Phase 2) 53 - deps: @atproto/lex, @atproto/lex-document, @atproto/repo, @atproto/syntax, @atproto/identity, @atproto-labs/fetch-node 54 - ``` 50 + ### Runtime: none 55 51 56 - They share only `@atproto/syntax`. The lexicon-resolver brings its own substantial dep tree — but it's only needed at editor-time (Phase 2 `resourceMapperMethod`), not on every execution. 52 + n8n verification guidelines require zero runtime dependencies. All packages are bundled into `dist/` by Vite at build time. 57 53 58 - ### Peer (1 package) 54 + ### Externalized (provided by n8n) 59 55 60 56 ``` 61 - n8n-workflow — provided by n8n at runtime 57 + n8n-workflow — node types, error classes (externalized in vite.config.build.ts) 62 58 ``` 63 59 64 - ### Dev (6 packages) 60 + ### Dev / bundled (all in devDependencies) 65 61 66 62 ``` 67 - typescript — compiler 68 - @n8n/node-cli — build + npm provenance 69 - oxlint — lint (jsPlugins alpha for ESLint plugin compat) 70 - oxfmt — format (separate package, Prettier-compatible) 71 - @n8n/eslint-plugin-community-nodes — n8n rules loaded via oxlint jsPlugins (fallback: eslint) 72 - vitest — test runner 73 - msw — mock XRPC server 63 + @atproto/api — CredentialSession, Agent, XRPC (bundled into dist) 64 + @atproto/lexicon-resolver — DNS-based lexicon fallback (bundled, lazy-loaded via import()) 65 + typescript — type-checking (tsc --watch in n8n-node dev) 66 + @n8n/node-cli — dev server + npm provenance 67 + vitest — test runner (also provides vite for building) 68 + msw — mock XRPC server 69 + oxlint — lint 70 + oxfmt — format 74 71 ``` 72 + 73 + ### Bundle size 74 + 75 + | Chunk | Raw | Gzipped | Notes | 76 + |-------|-----|---------|-------| 77 + | `Atproto.node.js` | 883 KB | 123 KB | Main entry. 91% is `@atproto/api` (barrel exports, not tree-shakeable) | 78 + | `_chunks/dist.js` | 213 KB | 49 KB | Shared: zod, multiformats, @atproto/syntax | 79 + | `_chunks/dist2.js` | 1,183 KB | 287 KB | **Lazy-loaded** via `import()` — only when DNS lexicon fallback fires. Contains undici (660 KB) | 80 + | **Eager total** | **1,096 KB** | **172 KB** | What loads at runtime | 75 81 76 82 --- 77 83 ··· 488 494 489 495 Before publishing: 490 496 491 - - [ ] `npm run lint` passes (oxlint + n8n community rules) 492 - - [ ] `npm test` passes (all vitest suites) 493 - - [ ] `npm run build` produces clean `dist/` 497 + - [x] `npm run lint` passes 498 + - [x] `npm test` passes (103 tests) 499 + - [x] `npm run build` produces clean `dist/` (Vite, ~100ms) 500 + - [x] Zero runtime `dependencies` in package.json 501 + - [x] Dev server starts without crashes (`npm run dev`) 494 502 - [ ] Manual test: full CRUD lifecycle against Bluesky 495 - - [ ] Manual test: field mapping with `app.bsky.feed.post` (Phase 2) 503 + - [ ] Manual test: field mapping with `app.bsky.feed.post` 496 504 - [ ] README has install instructions for community nodes panel 497 505 - [ ] `package.json` has correct `repository.url`, `author`, `description` 498 506 - [ ] Icon displays correctly in n8n node palette 499 - - [ ] Publish with `npm publish --provenance` (requires `@n8n/node-cli` ≥0.32.0) 507 + - [ ] Publish with `npm publish --provenance` via GitHub Actions 500 508 - [ ] Submit for n8n community node verification