70 lines
2.9 KiB
Markdown
70 lines
2.9 KiB
Markdown
# @bitsquare/nopy-cubes
|
|
|
|
The authoring surface for [nopy](https://www.npmjs.com/package/@bitsquare/nopy)
|
|
cubes — the `Manifest` factory, the `Cube` class, and the types around them.
|
|
|
|
A cube manifest ships nothing but data, so it should not have to depend on a CLI
|
|
to describe itself. This package is what a **cube bundle** depends on: no
|
|
`commander`, no `inquirer`, no `execa`, no process spawning. `@bitsquare/nopy`
|
|
re-exports everything here, so a manifest that already imports from
|
|
`@bitsquare/nopy` keeps working unchanged.
|
|
|
|
## Install
|
|
|
|
```sh
|
|
pnpm add @bitsquare/nopy-cubes zod
|
|
```
|
|
|
|
`zod` is a **peer dependency** on purpose: the manifest, the schema it builds and
|
|
the `Manifest` factory should all see the same copy.
|
|
|
|
## Writing a manifest
|
|
|
|
```js
|
|
// cubes/net/tailscale/manifest.mjs
|
|
import { Manifest } from '@bitsquare/nopy-cubes';
|
|
import { z } from 'zod';
|
|
|
|
export default Manifest({
|
|
id: 'net:tailscale',
|
|
name: 'Tailscale',
|
|
schema: z.object({
|
|
AUTH_KEY: z.string().describe('Tailscale auth key'),
|
|
ACCEPT_ROUTES: z.boolean().describe('Accept advertised routes').default(true),
|
|
}),
|
|
secrets: ['AUTH_KEY'],
|
|
dependencies: (vars) => (vars.ACCEPT_ROUTES ? ['net:ip-forwarding'] : []),
|
|
before: [async (ctx, vars) => ctx.exec('apt:essentials', {})],
|
|
});
|
|
```
|
|
|
|
Every schema field should carry a `.describe()` — nopy uses it as the prompt
|
|
label — and a `.default()` wherever a sensible one exists, so `--use-defaults`
|
|
can run the cube without prompting.
|
|
|
|
`secrets` names the schema keys that hold sensitive values. Nopy keeps those out
|
|
of session and history files and masks them in every command it prints; it does
|
|
not infer them, so a key nothing declares is recorded and printed in the clear.
|
|
Each entry must be a key of `schema` — naming anything else is a manifest error.
|
|
Give a secret a placeholder `.default()` rather than a real credential: a default
|
|
lives in the manifest, where none of that protection reaches it.
|
|
|
|
The manifest lives next to a `deploy.py` in the same directory; together they
|
|
make a cube. See the
|
|
[nopy README](https://www.npmjs.com/package/@bitsquare/nopy) for the full cube
|
|
contract and for how to publish a directory of cubes as a bundle.
|
|
|
|
## Exports
|
|
|
|
| Export | What it is |
|
|
| ----------------------------------- | -------------------------------------------------------------- |
|
|
| `Manifest(opts)` | Builds a manifest, filling in `id`, `schema`, `secrets`, `before`, `after` |
|
|
| `createManifest` / `manifest` | Aliases of `Manifest` |
|
|
| `Cube` | A loaded manifest plus its directory; `getDefaults()`, `requiredKeys()`, `secrets`, `isSecret()` |
|
|
| `zodKind` / `zodInner` | Instance-agnostic zod introspection, safe across zod copies |
|
|
| `AnyObjectSchema`, `CubeVariables`, `DependencySpec`, `Hook`, `HookContext`, `CubeSource`, `LoadResult` | types |
|
|
|
|
## License
|
|
|
|
MIT
|