@fleetless/sdk 3.0.2 → 3.1.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fleetless/sdk",
3
- "version": "3.0.2",
4
- "description": "The official TypeScript SDK for Fleetless client apps \u2014 a ROS 2 robot as a REST and realtime API, cameras, jobs, and the app's own user accounts, federated sign-in and MCP consent.",
3
+ "version": "3.1.0",
4
+ "description": "The official TypeScript SDK for Fleetless client apps — a ROS 2 robot as a REST and realtime API, cameras, jobs, and the app's own user accounts, federated sign-in and MCP consent.",
5
5
  "license": "MIT",
6
6
  "author": {
7
7
  "name": "Dehne Robotik GmbH",
@@ -9,6 +9,10 @@
9
9
  "url": "https://dehne-robotik.de"
10
10
  },
11
11
  "homepage": "https://docs.fleetless.dev/reference/sdk/",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/fleetless/sdk"
15
+ },
12
16
  "bugs": {
13
17
  "email": "hello@fleetless.dev"
14
18
  },
@@ -51,8 +55,7 @@
51
55
  "CHANGELOG.md",
52
56
  "SECURITY.md",
53
57
  "CONTRIBUTING.md",
54
- "CODE_OF_CONDUCT.md",
55
- "RELEASING.md"
58
+ "CODE_OF_CONDUCT.md"
56
59
  ],
57
60
  "engines": {
58
61
  "node": ">=20"
@@ -61,6 +64,7 @@
61
64
  "scripts": {
62
65
  "build": "tsup && node scripts/stamp-dist.mjs",
63
66
  "prepare": "tsup && node scripts/stamp-dist.mjs",
67
+ "prepublishOnly": "node scripts/refuse-manual-publish.mjs",
64
68
  "typecheck": "tsc --noEmit",
65
69
  "test": "vitest run",
66
70
  "test:pack": "node scripts/verify-published-types.mjs",
@@ -72,7 +76,7 @@
72
76
  "zod": "^4.0.0"
73
77
  },
74
78
  "devDependencies": {
75
- "@fleetless/contracts": "1.0.5",
79
+ "@fleetless/contracts": "1.1.0",
76
80
  "@types/node": "^22.20.1",
77
81
  "tsup": "^8.3.0",
78
82
  "typedoc": "0.28.20",
package/RELEASING.md DELETED
@@ -1,195 +0,0 @@
1
- # Releasing `@fleetless/sdk`
2
-
3
- Maintainer notes: the development setup, the checks, and the release
4
- procedure. This file is not part of the published package.
5
-
6
- **CI runs on GitLab; the repository will mirror to GitHub.** The pipeline
7
- that verifies and publishes this package lives on an internal GitLab instance,
8
- and that is the only thing that publishes to npm. The public repository does not
9
- exist yet; when it does it is a mirror, where issues and pull requests arrive
10
- and no check runs. A contributor's pull request is verified by a maintainer
11
- running the same commands locally — see
12
- [CONTRIBUTING.md](CONTRIBUTING.md), which says so to the contributor as well.
13
-
14
- A mirror pushes what it is given, so **everything in a commit becomes public
15
- the moment it is pushed**, including the commit message and every file the
16
- branch touched.
17
- ## Development setup
18
-
19
- Node 22 via `nvm`, and pnpm through corepack:
20
-
21
- ```sh
22
- nvm use 22
23
- corepack enable
24
- pnpm install
25
- ```
26
-
27
- **That install needs nothing private.** `@fleetless/contracts` — the source
28
- of truth for every wire type this SDK reads or writes — is a devDependency on
29
- the public npm package, pinned to an exact version. It used to be a private
30
- `git+ssh://` URL that only somebody with GitLab group access could install;
31
- that is over. The published SDK is unaffected either way: `tsup` inlines
32
- contracts' types into `dist/`, so a consumer of `@fleetless/sdk` never
33
- resolves it.
34
-
35
- Never redefine a shape the SDK sends to or reads from the API. Import it from
36
- `@fleetless/contracts` instead.
37
-
38
- ## Checks
39
-
40
- | Command | What it does |
41
- |---|---|
42
- | `pnpm typecheck` | `tsc --noEmit` over the package. |
43
- | `pnpm test` | vitest. Most suites drive a fake `fetch` and a fake WebSocket; the three auth suites drive the SDK's own default `fetch` against a real `node:http` server (`test/local-api.ts`). No cloud needed. |
44
- | `pnpm build` | tsup into `dist/` — ESM, CJS and `.d.ts`. |
45
- | `pnpm run test:pack` | `npm pack`s the tarball, installs it into a bare project with nothing but `typescript`, and typechecks and runs real usage against it. This is what catches a `dist/index.d.ts` that still imports from `@fleetless/contracts` — a devDependency, so a consumer of the SDK never installs it. |
46
-
47
- Two further scripts check the built package against a **running** cloud
48
- (`./infra/dev.sh` in the umbrella repo). Each one runs against `dist/`, not
49
- `src/`, so run `pnpm build` first, and each fails by name on a missing
50
- variable rather than defaulting quietly.
51
-
52
- - `pnpm run verify:live` — a `busy` refusal carrying the job that is already
53
- running, `command_outcome_unknown` and its documented recovery, a
54
- `parameter_invalid` naming the flat key, job-id-addressed cancel, and
55
- per-session camera release. Needs `FLEETLESS_API_URL` (or `API`),
56
- `APP_IDENTIFIER`, `EMAIL`, `PASSWORD`, `ROBOT_ID`, `ACTION_SLUG`,
57
- `SERVICE_SLUG`, `CAMERA_SLUG`, and two optional identities:
58
- - `SECOND_EMAIL` — a second, distinct **app user** with the same role,
59
- without which the busy check only proves that a second request is refused,
60
- not that a different user's is.
61
- - `OBSERVER_EMAIL` — a **third** app user, and the one whose password check
62
- [6] rotates and restores. Leave it unset and the round trip runs on
63
- `EMAIL`, the identity every other check in the file signs in as; the
64
- script says so out loud when that happens. `infra/seed-dev.mjs --env`
65
- exports all three.
66
-
67
- Since 3.0.0 it also drives the client auth API as check [6]: `listProviders`
68
- without a session, `login`, `me` (kind, app, role, address), `logout`, the
69
- `changePassword` round trip with its restore, and the reset acknowledgement
70
- compared byte for byte across a known and an unknown address. What it does
71
- **not** drive is anything needing a mailed token — `register`,
72
- `verifyEmail`, `acceptInvitation`, `confirmPasswordReset` — or the federated
73
- and MCP-consent flows. Those are `infra/browser/app-auth-check.mjs`'s
74
- subject, which reads maildev and drives a real Keycloak.
75
- - `pnpm run verify:history` — a relative range and its absolute equivalent
76
- returning the same samples, aggregation matching arithmetic done here from
77
- the raw rows, and the `not_recorded` / `not_aggregatable` refusals. Needs
78
- `FLEETLESS_API_URL`, `APP_IDENTIFIER`, `EMAIL`, `PASSWORD`, `ROBOT_ID`,
79
- `RECORDED_NUMERIC_SLUG`, `LIVE_ONLY_SLUG`, and optionally
80
- `NON_NUMERIC_RECORDED_SLUG`.
81
- (`verify:hosted-login` is gone. The hosted login flow it drove —
82
- `beginHostedLogin` / `completeHostedLogin` and the app OAuth client behind
83
- them — was removed in 3.0.0 along with the script and its `package.json`
84
- entry.)
85
-
86
- `infra/seed-dev.mjs --env` in the umbrella repo exports most of those
87
- variables for a freshly seeded world.
88
-
89
- ## Commits
90
-
91
- [Conventional Commits](https://www.conventionalcommits.org/). English, for
92
- code, comments, commit messages and everything else that lands in the
93
- repository.
94
-
95
- ## Releasing
96
-
97
- Every version on npm is published by this repository's GitLab pipeline from a
98
- release tag. `npm publish` by hand is retired.
99
-
100
- 1. Add the version's entry to `CHANGELOG.md` and set `version` in
101
- `package.json` to the same number.
102
- 2. Commit (`chore(release): X.Y.Z`), push, and wait for the branch pipeline's
103
- `verify` job to go green.
104
- 3. `git tag vX.Y.Z && git push origin vX.Y.Z`. The tag pipeline runs `verify`
105
- again and then `publish`.
106
- 4. Check the registry yourself. The `publish` job already asserts the first
107
- line; this is the independent look, and the second line is the one that
108
- says which dist-tag moved.
109
-
110
- ```sh
111
- npm view @fleetless/sdk@X.Y.Z version # answers X.Y.Z
112
- npm view @fleetless/sdk dist-tags # latest -> X.Y.Z, or next -> X.Y.Z
113
- ```
114
-
115
- Name the version. A bare `npm view @fleetless/sdk version` resolves the
116
- `latest` dist-tag, so after a pre-release publish it answers the *previous*
117
- stable release and reads as a publish that did not happen.
118
-
119
- A pre-release tag — `vX.Y.Z-beta.1`, `vX.Y.Z-rc.2` — publishes under the npm
120
- dist-tag `next` instead of `latest`. Nothing else about it differs, and it is
121
- exactly why step 4 names the version.
122
-
123
- **A red `publish` job does not mean nothing was published.** The job runs
124
- `npm publish` and then looks the version up on the registry for about two
125
- minutes; npm answers reads from a replica that lags a publish, so the lookup
126
- can time out on a version that did land. The job says so itself, and it is
127
- worth repeating here because a red pipeline invites exactly one reaction —
128
- press retry — and that reaction cannot work: npm refuses to publish over an
129
- existing version, so the retry ends in a 403 that reads like a broken
130
- pipeline rather than like a release that already happened.
131
-
132
- > publish may have succeeded; the registry has not served the version yet; do
133
- > NOT retry this job (npm refuses to republish a version) — check
134
- > `npm view @fleetless/sdk@$VERSION` by hand
135
-
136
- If the hand check answers the version, the release is done: move the dist-tag
137
- by hand if it is wrong (`npm dist-tag add @fleetless/sdk@X.Y.Z latest`) and
138
- leave the job red. If it answers nothing after several minutes, the publish
139
- genuinely did not land and the job can be retried.
140
-
141
- **A red `publish` job that ends in `npm error code EOTP` published nothing.**
142
- npm is asking for a one-time password, which a pipeline cannot supply: the
143
- token in `NPM_TOKEN` does not bypass two-factor authentication, or the
144
- package's *Publishing access* setting on npmjs.com disallows tokens. Fix the
145
- token (a granular access token created with *Bypass two-factor
146
- authentication*) or the package setting (*Require two-factor authentication
147
- or an automation token*), then retry the job — nothing reached the registry,
148
- so a retry is safe here — measured on a pipeline that hit it.
149
-
150
- **The pipeline refuses a tag whose version disagrees with `package.json`.**
151
- `scripts/verify-version-tag.mjs` is the one place that rule lives; `verify`
152
- runs it first on a tag pipeline, so a mistyped tag fails in seconds and
153
- `publish` never starts (measured: `verify-version-tag: tag v9.9.9 names
154
- 9.9.9 but package.json says 1.0.0`, publish skipped).
155
-
156
- Removing that bad tag takes the API, not git. `v*` is a **protected** tag
157
- pattern, so a delete over git is refused by the server with nothing but
158
- `! [remote rejected] v9.9.9 (pre-receive hook declined)`:
159
-
160
- ```sh
161
- git tag -d vX.Y.Z # local
162
- glab api -X DELETE projects/37/repository/tags/vX.Y.Z # remote
163
- ```
164
-
165
- Then fix `package.json` and tag again.
166
-
167
- ### The one-time setting
168
-
169
- It is already in place; it is written down because nothing in this repository
170
- would tell you it exists if it were removed.
171
-
172
- There used to be a second one — `fleetless/fleetless-sdk` on the job-token
173
- allow-list of `fleetless/fleetless-contracts`, so the pipeline could rewrite
174
- the private `git+ssh://` contracts URL to HTTPS with `CI_JOB_TOKEN`. Contracts
175
- is a public npm package now, the rewrite is gone from `.gitlab-ci.yml`, and
176
- the allow-list entry buys this project nothing. Removing it is safe; leaving
177
- it is harmless.
178
-
179
- - **`NPM_TOKEN` is a protected, masked CI variable on this project**, holding
180
- an npm granular automation token with publish rights on `@fleetless/sdk`.
181
- Protected means an unprotected ref receives an *empty* value rather than no
182
- value, which is why the tag pattern `v*` is a protected tag and why the
183
- `publish` job's first action is to refuse an empty `NPM_TOKEN` by name.
184
-
185
- ```sh
186
- glab api projects/37/protected_tags # v*, create access: Maintainers
187
- ```
188
-
189
- The token reaches npm through an `.npmrc` written in the job's working
190
- directory holding `//registry.npmjs.org/:_authToken=${NPM_TOKEN}` **literally**
191
- — npm expands the variable when it reads the file, so the secret itself never
192
- lands on disk, and `after_script` removes the file either way. It cannot be
193
- passed as an environment assignment instead: `NPM_CONFIG_//registry…` is not a
194
- valid shell identifier, so both `bash` and `dash` parse it as a command name.
195
-