|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Guidance for coding agents (Claude Code, Cursor, GitHub Copilot, …) working in or against |
| 4 | +this repository, and a condensed reference for agents integrating `expedy-sdk-node` into |
| 5 | +someone else's codebase. |
| 6 | + |
| 7 | +## What this is |
| 8 | + |
| 9 | +Official Node.js SDK + API documentation for the **Expedy Print API v2**. It sends print |
| 10 | +jobs to two kinds of hardware: |
| 11 | + |
| 12 | +| Resource | Hardware | Print method | |
| 13 | +| --- | --- | --- | |
| 14 | +| `printers` | Expedy cloud thermal receipt printer (own internet connection) | `client.printers.createPrintJob(printerUid, { printer_msg, ... })` | |
| 15 | +| `devices` | Raspberry Pi gateway + a third-party USB printer plugged into it | `client.devices.usb.createPrintJob(deviceUid, usbPort, { usb_msg, ... })` | |
| 16 | + |
| 17 | +Read [`docs/concepts/printers-vs-devices.md`](docs/concepts/printers-vs-devices.md) before |
| 18 | +writing code against either endpoint — picking the wrong one is the most common mistake. |
| 19 | + |
| 20 | +`displays` and `medias` are **out of scope** for this repository. |
| 21 | + |
| 22 | +## Non-obvious things to get right |
| 23 | + |
| 24 | +- **Authentication is not Bearer.** The `Authorization` header is the raw |
| 25 | + `<API_SID>:<API_TOKEN>` value, colon-separated, **no prefix**. `ExpedyClient` builds this |
| 26 | + automatically — never hand-construct the header. |
| 27 | +- **`printer_han` for Chinese/Japanese/Korean.** Without this field, CJK characters are |
| 28 | + silently replaced with `?` **before the job reaches the printer** — no error is raised. |
| 29 | + If a user asks to print non-Latin text and the code doesn't set `printer_han`, that's a |
| 30 | + bug. See [`docs/receipt-layout/asian-characters.md`](docs/receipt-layout/asian-characters.md). |
| 31 | + Values: `"cn"` Chinese, `"kr"` Korean, `"jp"` Japanese. Omit for Latin scripts. |
| 32 | +- **`200` means accepted, not printed.** Both print endpoints are asynchronous. Don't tell a |
| 33 | + user "your ticket printed" based on the SDK call resolving — see |
| 34 | + [`docs/concepts/delivery-and-idempotency.md`](docs/concepts/delivery-and-idempotency.md). |
| 35 | +- **No de-duplication.** Retrying a print request after a network error can produce two |
| 36 | + physical tickets. Track `request_uid` if you add retry logic. |
| 37 | +- **`printer_msg` / `usb_msg` carries an XML-like tag language**, not HTML — `<C>`, `<BOLD>`, |
| 38 | + `<IMG>`, `<QR>`, `<CUT/>`, `<PULSE/>`, plus one-shot provisioning tags |
| 39 | + (`<SETWIFI>`, `<SETSNTP>`, `<SETAPN>`, `<SETKEEPALIVE>`, `<UNSETBEEP/>`). Full reference: |
| 40 | + [`docs/receipt-layout/text-layout-tags.md`](docs/receipt-layout/text-layout-tags.md). |
| 41 | +- **`printer_status` is an activation flag**, not connectivity. `"0"` means suspended by |
| 42 | + ExpedyPRINT (usually billing), not "printer is offline". |
| 43 | +- Errors are `ExpedyError` (network/config) or `ExpedyApiError` (`status`, `rawBody`, |
| 44 | + `requestUid`), both exported from the package root. Always read `err.message` / |
| 45 | + `rawBody.message` rather than branching on `status` alone. |
| 46 | + |
| 47 | +## Where to look |
| 48 | + |
| 49 | +- **Full API reference**: [`docs/README.md`](docs/README.md) — reading order included. |
| 50 | +- **Machine-readable spec**: [`openapi.yaml`](openapi.yaml) — all 16 operations, request/ |
| 51 | + response schemas, `printer_han` enum. |
| 52 | +- **Runnable examples**: [`examples/`](examples/) — one file per feature, each a complete |
| 53 | + standalone script (`node --experimental-strip-types examples/<name>.ts`). |
| 54 | +- **SDK source**: `src/client.ts` (HTTP layer, ~130 lines), `src/resources/*.ts` (one |
| 55 | + method per endpoint), `src/types/*.ts` (request/response shapes with JSDoc). |
| 56 | +- **Canonical docs site**: <https://docs.expedy.io/> — same content as `docs/`, plus |
| 57 | + hardware setup guides and ~190 integration guides out of this repo's scope (see |
| 58 | + [`docs/integrations.md`](docs/integrations.md) for the index). |
| 59 | + |
| 60 | +## Working on this repository |
| 61 | + |
| 62 | +- `npm run typecheck` — type-check `src/` only. |
| 63 | +- `npm run build` — compile to `dist/`. |
| 64 | +- `npm run typecheck:examples` — type-check `examples/` against the compiled types. |
| 65 | +- `npm test` — build, then run the test suite (`node --test`, no test framework |
| 66 | + dependency). |
| 67 | +- Touching a field in `src/types/*.ts`? Update the matching schema in `openapi.yaml` and the |
| 68 | + matching page under `docs/api/` in the same change — see |
| 69 | + [`CONTRIBUTING.md`](CONTRIBUTING.md). |
| 70 | +- This is a **public** repository. Never commit real credentials, UIDs, or internal URLs — |
| 71 | + use the placeholder values already used throughout `docs/` and `examples/` |
| 72 | + (`WP0RGS1SEDZ`, `MMAAZ112PI`, `example.com`, …). |
0 commit comments