@fleetless/contracts 1.0.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/CHANGELOG.md +26 -0
- package/LICENSE +202 -0
- package/NOTICE +17 -0
- package/README.md +88 -0
- package/artifacts/constants.json +24 -0
- package/artifacts/openapi.json +17219 -0
- package/artifacts/routes.json +4605 -0
- package/artifacts/schema/accept-team-invite-request.schema.json +22 -0
- package/artifacts/schema/action-config.schema.json +198 -0
- package/artifacts/schema/alert-list-response.schema.json +172 -0
- package/artifacts/schema/api-error.schema.json +20 -0
- package/artifacts/schema/app-auth-config.schema.json +106 -0
- package/artifacts/schema/app-invitation-list-response.schema.json +57 -0
- package/artifacts/schema/app-invitation.schema.json +69 -0
- package/artifacts/schema/app-list-response.schema.json +82 -0
- package/artifacts/schema/app-mail-template-list-response.schema.json +68 -0
- package/artifacts/schema/app-mail-template.schema.json +54 -0
- package/artifacts/schema/app-oidc-provider-list-response.schema.json +93 -0
- package/artifacts/schema/app-oidc-provider.schema.json +80 -0
- package/artifacts/schema/app-user-list-response.schema.json +111 -0
- package/artifacts/schema/app-user.schema.json +98 -0
- package/artifacts/schema/app.schema.json +69 -0
- package/artifacts/schema/apply-error.schema.json +41 -0
- package/artifacts/schema/asset-list-response.schema.json +288 -0
- package/artifacts/schema/asset-sync-request.schema.json +17 -0
- package/artifacts/schema/asset-sync-response.schema.json +16 -0
- package/artifacts/schema/asset-sync-status.schema.json +136 -0
- package/artifacts/schema/asset.schema.json +68 -0
- package/artifacts/schema/audit-actor.schema.json +32 -0
- package/artifacts/schema/audit-event.schema.json +119 -0
- package/artifacts/schema/audit-list-response.schema.json +144 -0
- package/artifacts/schema/audit-query.schema.json +79 -0
- package/artifacts/schema/auth-error.schema.json +23 -0
- package/artifacts/schema/auth-me-response.schema.json +99 -0
- package/artifacts/schema/auth-ok.schema.json +115 -0
- package/artifacts/schema/authorization-server-metadata.schema.json +80 -0
- package/artifacts/schema/bridge-asset-progress.schema.json +99 -0
- package/artifacts/schema/bridge-assets-available.schema.json +25 -0
- package/artifacts/schema/bridge-camera-state.schema.json +78 -0
- package/artifacts/schema/bridge-config-applied.schema.json +67 -0
- package/artifacts/schema/bridge-hello.schema.json +65 -0
- package/artifacts/schema/bridge-introspect.schema.json +114 -0
- package/artifacts/schema/bridge-job-lost.schema.json +22 -0
- package/artifacts/schema/bridge-job-update.schema.json +100 -0
- package/artifacts/schema/bridge-pong.schema.json +19 -0
- package/artifacts/schema/bridge-pressure.schema.json +292 -0
- package/artifacts/schema/bridge-state.schema.json +24 -0
- package/artifacts/schema/bridge-type-definitions.schema.json +169 -0
- package/artifacts/schema/busy-details.schema.json +115 -0
- package/artifacts/schema/camera-descriptor.schema.json +45 -0
- package/artifacts/schema/camera-list-response.schema.json +58 -0
- package/artifacts/schema/camera-source.schema.json +240 -0
- package/artifacts/schema/cancel-request.schema.json +20 -0
- package/artifacts/schema/client-accept-invitation-request.schema.json +35 -0
- package/artifacts/schema/client-auth.schema.json +18 -0
- package/artifacts/schema/client-cancel.schema.json +45 -0
- package/artifacts/schema/client-identity.schema.json +103 -0
- package/artifacts/schema/client-invoke.schema.json +45 -0
- package/artifacts/schema/client-login-request.schema.json +29 -0
- package/artifacts/schema/client-logout-request.schema.json +14 -0
- package/artifacts/schema/client-mcp-interaction-decision-response.schema.json +15 -0
- package/artifacts/schema/client-mcp-interaction.schema.json +59 -0
- package/artifacts/schema/client-oidc-callback-query.schema.json +28 -0
- package/artifacts/schema/client-oidc-exchange-request.schema.json +21 -0
- package/artifacts/schema/client-oidc-start-query.schema.json +36 -0
- package/artifacts/schema/client-password-reset-confirm-request.schema.json +22 -0
- package/artifacts/schema/client-password-reset-request.schema.json +24 -0
- package/artifacts/schema/client-provider-list-query.schema.json +17 -0
- package/artifacts/schema/client-provider-list-response.schema.json +34 -0
- package/artifacts/schema/client-publish.schema.json +40 -0
- package/artifacts/schema/client-refresh-request.schema.json +14 -0
- package/artifacts/schema/client-register-request.schema.json +44 -0
- package/artifacts/schema/client-resend-verification-request.schema.json +24 -0
- package/artifacts/schema/client-subscribe.schema.json +43 -0
- package/artifacts/schema/client-unsubscribe.schema.json +26 -0
- package/artifacts/schema/client-verify-email-request.schema.json +15 -0
- package/artifacts/schema/cloud-asset-request.schema.json +37 -0
- package/artifacts/schema/cloud-camera-start.schema.json +41 -0
- package/artifacts/schema/cloud-camera-stop.schema.json +26 -0
- package/artifacts/schema/cloud-cancel.schema.json +33 -0
- package/artifacts/schema/cloud-config.schema.json +1635 -0
- package/artifacts/schema/cloud-hello-error.schema.json +23 -0
- package/artifacts/schema/cloud-hello-ok.schema.json +19 -0
- package/artifacts/schema/cloud-introspect-request.schema.json +19 -0
- package/artifacts/schema/cloud-invoke.schema.json +40 -0
- package/artifacts/schema/cloud-ping.schema.json +19 -0
- package/artifacts/schema/cloud-publish.schema.json +28 -0
- package/artifacts/schema/cloud-type-request.schema.json +30 -0
- package/artifacts/schema/command-result.schema.json +175 -0
- package/artifacts/schema/config-draft-response.schema.json +1695 -0
- package/artifacts/schema/config-state.schema.json +124 -0
- package/artifacts/schema/config-version-response.schema.json +1641 -0
- package/artifacts/schema/config-versions-response.schema.json +33 -0
- package/artifacts/schema/create-app-invitation-request.schema.json +40 -0
- package/artifacts/schema/create-app-oidc-provider-request.schema.json +70 -0
- package/artifacts/schema/create-app-request.schema.json +30 -0
- package/artifacts/schema/create-app-user-request.schema.json +42 -0
- package/artifacts/schema/create-robot-request.schema.json +14 -0
- package/artifacts/schema/create-robot-response.schema.json +44 -0
- package/artifacts/schema/create-server-key-response.schema.json +65 -0
- package/artifacts/schema/create-team-invite-request.schema.json +43 -0
- package/artifacts/schema/datapoint-alert-row.schema.json +160 -0
- package/artifacts/schema/datapoint-config.schema.json +366 -0
- package/artifacts/schema/datapoint-display.schema.json +31 -0
- package/artifacts/schema/datapoint-event.schema.json +34 -0
- package/artifacts/schema/datapoint-frame.schema.json +28 -0
- package/artifacts/schema/datapoint-list-response.schema.json +61 -0
- package/artifacts/schema/datapoint-value.schema.json +28 -0
- package/artifacts/schema/developer-login-request.schema.json +19 -0
- package/artifacts/schema/dynamic-client-registration-request.schema.json +60 -0
- package/artifacts/schema/dynamic-client-registration-response.schema.json +68 -0
- package/artifacts/schema/error-frame.schema.json +23 -0
- package/artifacts/schema/exposure-counts.schema.json +39 -0
- package/artifacts/schema/exposure-list-response.schema.json +43 -0
- package/artifacts/schema/fetch-types-request.schema.json +19 -0
- package/artifacts/schema/fetch-types-response.schema.json +163 -0
- package/artifacts/schema/fleetless-user-list-response.schema.json +73 -0
- package/artifacts/schema/fleetless-user.schema.json +60 -0
- package/artifacts/schema/history-buckets-response.schema.json +79 -0
- package/artifacts/schema/history-query.schema.json +58 -0
- package/artifacts/schema/history-response.schema.json +150 -0
- package/artifacts/schema/history-samples-response.schema.json +68 -0
- package/artifacts/schema/introspection-response.schema.json +118 -0
- package/artifacts/schema/invoke-or-service-response.schema.json +141 -0
- package/artifacts/schema/invoke-request.schema.json +23 -0
- package/artifacts/schema/invoke-response.schema.json +125 -0
- package/artifacts/schema/job-actor.schema.json +34 -0
- package/artifacts/schema/job-event.schema.json +158 -0
- package/artifacts/schema/job-response.schema.json +123 -0
- package/artifacts/schema/job-run-list-response.schema.json +222 -0
- package/artifacts/schema/job-run-query.schema.json +95 -0
- package/artifacts/schema/job-run-summary-query.schema.json +23 -0
- package/artifacts/schema/job-run-summary.schema.json +33 -0
- package/artifacts/schema/job-run.schema.json +195 -0
- package/artifacts/schema/job-state.schema.json +11 -0
- package/artifacts/schema/job.schema.json +106 -0
- package/artifacts/schema/latency-bucket.schema.json +63 -0
- package/artifacts/schema/live-session-response.schema.json +41 -0
- package/artifacts/schema/mail-outcome.schema.json +20 -0
- package/artifacts/schema/mail-template-preview-request.schema.json +35 -0
- package/artifacts/schema/mail-template-preview-response.schema.json +31 -0
- package/artifacts/schema/mail-template-problem-details.schema.json +24 -0
- package/artifacts/schema/mcp-consent-grant-list-response.schema.json +52 -0
- package/artifacts/schema/mcp-consent-grant.schema.json +39 -0
- package/artifacts/schema/mcp-robot-datasheet.schema.json +115 -0
- package/artifacts/schema/mcp-role-preview-response.schema.json +134 -0
- package/artifacts/schema/missing-asset-query.schema.json +11 -0
- package/artifacts/schema/oauth-authorize-query.schema.json +47 -0
- package/artifacts/schema/oauth-redirect-response.schema.json +15 -0
- package/artifacts/schema/oauth-token-request.schema.json +47 -0
- package/artifacts/schema/oauth-token-response.schema.json +38 -0
- package/artifacts/schema/org-alerts-query.schema.json +15 -0
- package/artifacts/schema/org-event-dropped.schema.json +26 -0
- package/artifacts/schema/org-event-replay.schema.json +97 -0
- package/artifacts/schema/org-event-subscribe.schema.json +14 -0
- package/artifacts/schema/org-event-unsubscribe.schema.json +14 -0
- package/artifacts/schema/org-event.schema.json +75 -0
- package/artifacts/schema/org-firing-alerts-response.schema.json +178 -0
- package/artifacts/schema/org-health-query.schema.json +13 -0
- package/artifacts/schema/org-latency-query.schema.json +42 -0
- package/artifacts/schema/org-latency-response.schema.json +124 -0
- package/artifacts/schema/org-quota-usage-counts.schema.json +42 -0
- package/artifacts/schema/org-quota-usage.schema.json +102 -0
- package/artifacts/schema/org-quotas.schema.json +51 -0
- package/artifacts/schema/org-usage-query.schema.json +19 -0
- package/artifacts/schema/org-usage-response.schema.json +77 -0
- package/artifacts/schema/org.schema.json +30 -0
- package/artifacts/schema/parameter-invalid-details.schema.json +37 -0
- package/artifacts/schema/parameter-spec.schema.json +120 -0
- package/artifacts/schema/parameter-violation.schema.json +24 -0
- package/artifacts/schema/password-change-request.schema.json +21 -0
- package/artifacts/schema/password-reset-confirm.schema.json +19 -0
- package/artifacts/schema/password-reset-request.schema.json +14 -0
- package/artifacts/schema/patch-app-oidc-provider-request.schema.json +50 -0
- package/artifacts/schema/patch-app-user-request.schema.json +34 -0
- package/artifacts/schema/patch-auth-me-request.schema.json +22 -0
- package/artifacts/schema/patch-fleetless-user-request.schema.json +20 -0
- package/artifacts/schema/patch-org-request.schema.json +15 -0
- package/artifacts/schema/patch-org-response.schema.json +40 -0
- package/artifacts/schema/patch-robot-request.schema.json +15 -0
- package/artifacts/schema/patch-robot-response.schema.json +40 -0
- package/artifacts/schema/pending-team-invite-list-response.schema.json +52 -0
- package/artifacts/schema/pending-team-invite.schema.json +39 -0
- package/artifacts/schema/protected-resource-metadata.schema.json +41 -0
- package/artifacts/schema/publish-config-response.schema.json +21 -0
- package/artifacts/schema/publish-request.schema.json +17 -0
- package/artifacts/schema/publisher-config.schema.json +285 -0
- package/artifacts/schema/put-app-auth-config-request.schema.json +93 -0
- package/artifacts/schema/put-app-mail-template-request.schema.json +35 -0
- package/artifacts/schema/put-config-draft-request.schema.json +13 -0
- package/artifacts/schema/put-datapoint-display-request.schema.json +31 -0
- package/artifacts/schema/put-robot-details-request.schema.json +41 -0
- package/artifacts/schema/put-robot-details-response.schema.json +43 -0
- package/artifacts/schema/rate-limit-details.schema.json +15 -0
- package/artifacts/schema/refresh-request.schema.json +13 -0
- package/artifacts/schema/release-live-query.schema.json +13 -0
- package/artifacts/schema/rename-slug-request.schema.json +23 -0
- package/artifacts/schema/rename-slug-response.schema.json +24 -0
- package/artifacts/schema/resource-health-event.schema.json +72 -0
- package/artifacts/schema/resource-health-list-response.schema.json +80 -0
- package/artifacts/schema/resource-health-state.schema.json +68 -0
- package/artifacts/schema/robot-config-doc.schema.json +1616 -0
- package/artifacts/schema/robot-delete-query.schema.json +12 -0
- package/artifacts/schema/robot-deletion-summary.schema.json +63 -0
- package/artifacts/schema/robot-detail-response.schema.json +262 -0
- package/artifacts/schema/robot-details-doc.schema.json +33 -0
- package/artifacts/schema/robot-jobs-response.schema.json +119 -0
- package/artifacts/schema/robot-latency-series.schema.json +81 -0
- package/artifacts/schema/robot-list-item.schema.json +94 -0
- package/artifacts/schema/robot-list-response.schema.json +106 -0
- package/artifacts/schema/robot.schema.json +30 -0
- package/artifacts/schema/role-list-response.schema.json +48 -0
- package/artifacts/schema/role-permissions.schema.json +61 -0
- package/artifacts/schema/role.schema.json +35 -0
- package/artifacts/schema/ros-graph.schema.json +99 -0
- package/artifacts/schema/server-key-list-response.schema.json +64 -0
- package/artifacts/schema/server-key.schema.json +51 -0
- package/artifacts/schema/service-call-response.schema.json +13 -0
- package/artifacts/schema/service-config.schema.json +198 -0
- package/artifacts/schema/session-tokens.schema.json +28 -0
- package/artifacts/schema/sign-up-request.schema.json +26 -0
- package/artifacts/schema/sign-up-response.schema.json +127 -0
- package/artifacts/schema/slug-usage-response.schema.json +32 -0
- package/artifacts/schema/snapshot-header.schema.json +44 -0
- package/artifacts/schema/snapshot-meta-response.schema.json +85 -0
- package/artifacts/schema/subscribe-error.schema.json +31 -0
- package/artifacts/schema/team-invite.schema.json +57 -0
- package/artifacts/schema/tier-change-request.schema.json +17 -0
- package/artifacts/schema/type-definition.schema.json +144 -0
- package/artifacts/schema/types-response.schema.json +156 -0
- package/artifacts/schema/update-app-request.schema.json +32 -0
- package/artifacts/schema/urdf-completeness.schema.json +50 -0
- package/artifacts/schema/validation-issue.schema.json +43 -0
- package/artifacts/schema/waitlist-request.schema.json +15 -0
- package/artifacts/schema-outgoing/bridge-asset-progress.schema.json +102 -0
- package/artifacts/schema-outgoing/bridge-assets-available.schema.json +26 -0
- package/artifacts/schema-outgoing/bridge-camera-state.schema.json +80 -0
- package/artifacts/schema-outgoing/bridge-config-applied.schema.json +69 -0
- package/artifacts/schema-outgoing/bridge-hello.schema.json +68 -0
- package/artifacts/schema-outgoing/bridge-introspect.schema.json +119 -0
- package/artifacts/schema-outgoing/bridge-job-lost.schema.json +23 -0
- package/artifacts/schema-outgoing/bridge-job-update.schema.json +102 -0
- package/artifacts/schema-outgoing/bridge-pong.schema.json +20 -0
- package/artifacts/schema-outgoing/bridge-type-definitions.schema.json +174 -0
- package/artifacts/schema-outgoing/datapoint-frame.schema.json +29 -0
- package/artifacts/schema-outgoing/snapshot-header.schema.json +45 -0
- package/dist/alerts.d.ts +255 -0
- package/dist/alerts.js +193 -0
- package/dist/app-users.d.ts +606 -0
- package/dist/app-users.js +696 -0
- package/dist/apps.d.ts +175 -0
- package/dist/apps.js +267 -0
- package/dist/assets.d.ts +434 -0
- package/dist/assets.js +546 -0
- package/dist/audit.d.ts +129 -0
- package/dist/audit.js +238 -0
- package/dist/client-auth.d.ts +409 -0
- package/dist/client-auth.js +487 -0
- package/dist/common.d.ts +186 -0
- package/dist/common.js +199 -0
- package/dist/config-issues.d.ts +175 -0
- package/dist/config-issues.js +339 -0
- package/dist/config.d.ts +862 -0
- package/dist/config.js +1988 -0
- package/dist/errors.d.ts +52 -0
- package/dist/errors.js +786 -0
- package/dist/identity.d.ts +549 -0
- package/dist/identity.js +503 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +51 -0
- package/dist/introspection.d.ts +99 -0
- package/dist/introspection.js +97 -0
- package/dist/jobs.d.ts +334 -0
- package/dist/jobs.js +345 -0
- package/dist/mcp.d.ts +239 -0
- package/dist/mcp.js +153 -0
- package/dist/oauth.d.ts +344 -0
- package/dist/oauth.js +488 -0
- package/dist/protocol.d.ts +781 -0
- package/dist/protocol.js +715 -0
- package/dist/realtime.d.ts +494 -0
- package/dist/realtime.js +512 -0
- package/dist/rest.d.ts +1989 -0
- package/dist/rest.js +1963 -0
- package/dist/routes.d.ts +94 -0
- package/dist/routes.js +2298 -0
- package/package.json +61 -0
package/dist/identity.js
ADDED
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* **Fleetless users: the org's team, and the only people who reach the
|
|
5
|
+
* console** (spec `2026-09-05-app-user-auth`, D1).
|
|
6
|
+
*
|
|
7
|
+
* There are two identity spaces now and **nothing joins them**:
|
|
8
|
+
*
|
|
9
|
+
* - *Fleetless users*, this file. The people who configure robots in the
|
|
10
|
+
* console. Email globally unique, tier `owner | developer`, a Fleetless
|
|
11
|
+
* password, login through the auth portal. They always have MCP access, at
|
|
12
|
+
* the one central endpoint.
|
|
13
|
+
* - *app users*, `app-users.ts`. The people who use a developer's app. One app
|
|
14
|
+
* each, email unique per app, authenticated through the JSON client-auth
|
|
15
|
+
* API that the developer's own UI calls.
|
|
16
|
+
*
|
|
17
|
+
* A Fleetless user who wants to use an app registers or is invited like
|
|
18
|
+
* anybody else; there is no path from one space to the other.
|
|
19
|
+
*
|
|
20
|
+
* **What that deleted, with no successor** (D1): groups and the Org Admins
|
|
21
|
+
* group, app assignments, impersonation, the per-user MCP override and the
|
|
22
|
+
* org-level federation policy. The 2026-08-29 model had put developers and end
|
|
23
|
+
* users into one pool per org and connected them with all of the above; in use
|
|
24
|
+
* it turned out to model the wrong thing — the two populations have different
|
|
25
|
+
* lifecycles, and every mechanism joining them was cost without a product
|
|
26
|
+
* reason.
|
|
27
|
+
*
|
|
28
|
+
* What did **not** change: the password rules, the session and token shapes,
|
|
29
|
+
* and the enumeration-oracle reasoning on password reset. None of those was
|
|
30
|
+
* ever a statement about which space a person lived in.
|
|
31
|
+
*
|
|
32
|
+
* **Email is globally unique here** — `lower(email)` unique across all orgs, so
|
|
33
|
+
* one address is exactly one Fleetless user in exactly one org. Every shape
|
|
34
|
+
* that identifies a person by a bare address (`developerLoginRequest`,
|
|
35
|
+
* `passwordResetRequest`) therefore resolves to at most one account with no org
|
|
36
|
+
* context needed. App users are the opposite and say so on their own shape:
|
|
37
|
+
* unique **per app**, so one address may be several unrelated app accounts.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* The password rule, stated once so the cloud, the console and the SDK refuse
|
|
41
|
+
* the same inputs for the same reason. Length only: a rule a user cannot
|
|
42
|
+
* predict is a rule they work around.
|
|
43
|
+
*
|
|
44
|
+
* Shared by both identity spaces on purpose. A weaker rule for app users would
|
|
45
|
+
* be a second policy for one decision, and the weaker one always wins by
|
|
46
|
+
* accident.
|
|
47
|
+
*/
|
|
48
|
+
export const password = z.string().min(12).max(256);
|
|
49
|
+
/** The bound on a Fleetless user's display name; `APP_USER_DISPLAY_NAME_MAX` matches it, so a rename cannot be legal in one space and refused in the other. */
|
|
50
|
+
export const USER_DISPLAY_NAME_MAX = 120;
|
|
51
|
+
/**
|
|
52
|
+
* **The two tiers a Fleetless user can hold** (D1). Owner-exclusive: delete
|
|
53
|
+
* the org, edit org settings, promote to owner, and later billing. Everything
|
|
54
|
+
* else a Fleetless user may do, a `developer` may do.
|
|
55
|
+
*
|
|
56
|
+
* `member` was renamed to `developer` in the 2026-08-29 redesign and is **not**
|
|
57
|
+
* accepted as an alias anywhere — a wire that took both would leave two names
|
|
58
|
+
* for one tier in every log, every audit detail and every console fixture, and
|
|
59
|
+
* the older one would keep arriving forever.
|
|
60
|
+
*
|
|
61
|
+
* **Every Fleetless user has one.** It used to be optional, because the pool
|
|
62
|
+
* also held people who were not org admins and had no console powers to grade.
|
|
63
|
+
* That pool is gone: a Fleetless user *is* a member of the team, so the field
|
|
64
|
+
* is required and an absent one is a mapper bug rather than a state.
|
|
65
|
+
*/
|
|
66
|
+
export const orgAdminTier = z.enum(['owner', 'developer']);
|
|
67
|
+
export const org = z.object({
|
|
68
|
+
id: z.uuid().meta({
|
|
69
|
+
description: 'The organisation. Every developer route is scoped to the caller\'s org already, so a client rarely has to send this anywhere.',
|
|
70
|
+
}),
|
|
71
|
+
name: z.string().min(1).max(120).meta({
|
|
72
|
+
description: 'The organisation\'s display name. Free text, changed through `PATCH /api/org`.',
|
|
73
|
+
}),
|
|
74
|
+
created_at: z.iso.datetime().meta({
|
|
75
|
+
description: 'When the organisation was created, as an ISO 8601 timestamp.',
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
78
|
+
/** What `PATCH /api/org` answers: the org as it now stands. */
|
|
79
|
+
export const patchOrgResponse = z.object({
|
|
80
|
+
org: org.meta({
|
|
81
|
+
description: 'The organisation as it now stands, after the patch was applied. The whole resource comes back, not only the fields that changed.',
|
|
82
|
+
}),
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* **A member of the org's team.** Console access, a tier, a Fleetless
|
|
86
|
+
* password, and no relationship whatsoever to any app's users.
|
|
87
|
+
*
|
|
88
|
+
* `email` is **globally unique** — `lower(email)` unique across every org, a
|
|
89
|
+
* constraint the cloud enforces in the database; a schema cannot see two rows
|
|
90
|
+
* at once and this one makes no claim to. One address is one Fleetless user:
|
|
91
|
+
* no two orgs may hold the same one.
|
|
92
|
+
*
|
|
93
|
+
* **What this shape lost with the two-space cut**: `group_id` (there are no
|
|
94
|
+
* groups), `mcp_access` (a Fleetless user always has MCP access, at the
|
|
95
|
+
* central endpoint), and `has_password`. The last is the interesting one — it
|
|
96
|
+
* existed because a pool user might have been provisioned by an identity
|
|
97
|
+
* provider and hold no Fleetless credential. A Fleetless user always holds
|
|
98
|
+
* one: the console is password-only by design (D1), which removes the
|
|
99
|
+
* IdP-lockout class entirely, so a field reporting whether the credential
|
|
100
|
+
* exists would have exactly one value forever.
|
|
101
|
+
*/
|
|
102
|
+
export const fleetlessUser = z.object({
|
|
103
|
+
id: z.uuid().meta({
|
|
104
|
+
description: 'The Fleetless user in the API, assigned by the cloud and stable for the life of the account.',
|
|
105
|
+
}),
|
|
106
|
+
org_id: z.uuid().meta({
|
|
107
|
+
description: 'The organisation this person belongs to. Every developer route is already scoped to the caller\'s org, so this confirms what a client is looking at rather than being a filter it applies.',
|
|
108
|
+
}),
|
|
109
|
+
email: z.email().meta({
|
|
110
|
+
description: 'The address the account is identified by, **globally unique** across every organisation. Immutable after creation: it is what every invitation, reset link and audit line names.',
|
|
111
|
+
}),
|
|
112
|
+
display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable().meta({
|
|
113
|
+
description: 'Optional human name, shown by the console instead of the address where present. Self-service through `PATCH /api/auth/me`; never used for authentication. `null` when the person never supplied one.',
|
|
114
|
+
}),
|
|
115
|
+
tier: orgAdminTier.meta({
|
|
116
|
+
description: 'The console powers this person holds. **Required** — every Fleetless user is a member of the team and has a tier; the optional version of this field existed only while the org also held people with no console powers to grade, and that pool is gone.',
|
|
117
|
+
}),
|
|
118
|
+
created_at: z.iso.datetime().meta({
|
|
119
|
+
description: 'When the account was created, as an ISO 8601 timestamp.',
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
/** `GET /api/org/users` — the whole team. Never null: an org always has at least its owner. */
|
|
123
|
+
export const fleetlessUserListResponse = z.object({
|
|
124
|
+
users: z.array(fleetlessUser).meta({
|
|
125
|
+
description: 'Every Fleetless user of the caller\'s organisation. This is the team, not an app\'s users — those are listed per app.',
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
/**
|
|
129
|
+
* Access plus refresh (spec §3.4). The access token is short-lived; the
|
|
130
|
+
* refresh token rotates on every use, so a stolen one is detectable when the
|
|
131
|
+
* original is presented again.
|
|
132
|
+
*
|
|
133
|
+
* One shape for both identity spaces: a session is a session, and the claims
|
|
134
|
+
* inside the token are what differ.
|
|
135
|
+
*/
|
|
136
|
+
export const sessionTokens = z.object({
|
|
137
|
+
access_token: z.string().min(1).meta({
|
|
138
|
+
description: 'The token to send as `Authorization: Bearer <token>` on every call. Short-lived: read `expires_in` rather than assuming a lifetime.',
|
|
139
|
+
}),
|
|
140
|
+
refresh_token: z.string().min(1).meta({
|
|
141
|
+
description: 'The token that buys the next access token. It rotates on every use, so a value presented twice is detectable theft and ends the whole family.',
|
|
142
|
+
}),
|
|
143
|
+
expires_in: z.number().int().positive().meta({
|
|
144
|
+
description: 'How long the access token stays valid, in **seconds** from now. Not a timestamp, and not milliseconds.',
|
|
145
|
+
}),
|
|
146
|
+
});
|
|
147
|
+
export const refreshRequest = z.object({ refresh_token: z.string().min(1) });
|
|
148
|
+
/**
|
|
149
|
+
* Registering an org creates the org and its first owner in one step
|
|
150
|
+
* (André, 2026-08-10): whoever registers the organisation is the owner.
|
|
151
|
+
*/
|
|
152
|
+
export const signUpRequest = z.object({
|
|
153
|
+
org_name: z.string().min(1).max(120),
|
|
154
|
+
email: z.email(),
|
|
155
|
+
password,
|
|
156
|
+
});
|
|
157
|
+
/**
|
|
158
|
+
* Registering answers with the founding **Fleetless user**, tier `owner`.
|
|
159
|
+
*
|
|
160
|
+
* The key is `user` rather than `member` or `owner`, and it has stayed `user`
|
|
161
|
+
* through two identity redesigns deliberately: a renamed shape under a
|
|
162
|
+
* renamed key would typecheck in every consumer that reads `.user.id` and mean
|
|
163
|
+
* something subtly different, which is the quietest way for a cut like this to
|
|
164
|
+
* go wrong.
|
|
165
|
+
*/
|
|
166
|
+
export const signUpResponse = z.object({
|
|
167
|
+
org,
|
|
168
|
+
user: fleetlessUser,
|
|
169
|
+
tokens: sessionTokens,
|
|
170
|
+
});
|
|
171
|
+
/**
|
|
172
|
+
* The landing page's waiting list (public site, 2026-09-04): one address,
|
|
173
|
+
* posted from fleetless.dev while sign-up is closed. The route answers
|
|
174
|
+
* `202` whether or not the address was already listed.
|
|
175
|
+
*
|
|
176
|
+
* The address is bounded at 254 characters, the RFC 5321 forward-path limit.
|
|
177
|
+
* `z.email()` alone is length-unbounded, and `waitlist.email` carries a unique
|
|
178
|
+
* btree index, which raises above roughly 2704 bytes — so an unbounded address
|
|
179
|
+
* turns an unauthenticated public route into a `500`.
|
|
180
|
+
*/
|
|
181
|
+
export const waitlistRequest = z.object({ email: z.email().max(254) });
|
|
182
|
+
/**
|
|
183
|
+
* Console login. Fleetless users only, always the Fleetless password — the
|
|
184
|
+
* console has no federated door at all (D1), which removes the IdP-lockout
|
|
185
|
+
* class entirely.
|
|
186
|
+
*
|
|
187
|
+
* This resolves a person by address alone, and a Fleetless user's email is
|
|
188
|
+
* **globally unique**, so a bare address names at most one account and no org
|
|
189
|
+
* context is needed to disambiguate. An org selector was never needed and
|
|
190
|
+
* would have told an unauthenticated caller which org an address belongs to.
|
|
191
|
+
*
|
|
192
|
+
* **It cannot be reached by an app user**, whatever their address: the two
|
|
193
|
+
* spaces have separate tables and separate routes, and a credential from one
|
|
194
|
+
* never authenticates the other.
|
|
195
|
+
*/
|
|
196
|
+
export const developerLoginRequest = z.object({
|
|
197
|
+
email: z.email(),
|
|
198
|
+
password: z.string().min(1),
|
|
199
|
+
});
|
|
200
|
+
/**
|
|
201
|
+
* What happened to the mail, in four words instead of one (W6c).
|
|
202
|
+
*
|
|
203
|
+
* `mail_sent: boolean` could not tell **"we have no SMTP configured"** from
|
|
204
|
+
* **"we tried and the server refused"**, so the console had to pick a sentence
|
|
205
|
+
* for a cause it could not know — and picked the reassuring one, because a
|
|
206
|
+
* link-only invitation is a normal outcome and a bounced one is not. The two
|
|
207
|
+
* need opposite actions from whoever reads them: configure a mail server, or
|
|
208
|
+
* go and look at why the existing one rejected the message.
|
|
209
|
+
*
|
|
210
|
+
* - `sent` — the SMTP server accepted the message. Not "delivered":
|
|
211
|
+
* no sender can promise that, and this value must never
|
|
212
|
+
* be rendered as if it could.
|
|
213
|
+
* - `not_requested` — no mail was attempted: the caller asked for none
|
|
214
|
+
* (`send_mail: false`), or there was no link for one to
|
|
215
|
+
* carry (the app has configured no `invite_url`, which
|
|
216
|
+
* the `null` `accept_url` beside it says). **A fourth
|
|
217
|
+
* word rather than a reuse of `not_configured`**: the
|
|
218
|
+
* deployment's mailer is irrelevant in both cases, and a
|
|
219
|
+
* console reading "mail server not configured" beside an
|
|
220
|
+
* invitation whose mail checkbox was off would send a
|
|
221
|
+
* developer to fix something that is not broken.
|
|
222
|
+
* - `not_configured` — no SMTP is set up. **An expected state, not a failure**
|
|
223
|
+
* (invitations work without mail; the link is the primary
|
|
224
|
+
* path). The console must not show it as an error.
|
|
225
|
+
* - `failed` — SMTP was configured, was tried, and refused or was
|
|
226
|
+
* unreachable. This one is worth someone's attention.
|
|
227
|
+
*
|
|
228
|
+
* Shared with `appInvitation`, which answers the same four facts about the
|
|
229
|
+
* same mailer.
|
|
230
|
+
*/
|
|
231
|
+
export const mailStatus = z.enum(['sent', 'not_requested', 'not_configured', 'failed']);
|
|
232
|
+
/* ----------------------------------------------------- the team invite --
|
|
233
|
+
* One invitation family, for Fleetless users. The app-user invitation lives in
|
|
234
|
+
* `app-users.ts` and is a different thing with a different link: this one
|
|
235
|
+
* points at the Fleetless auth portal, that one points into the developer's
|
|
236
|
+
* own app.
|
|
237
|
+
*/
|
|
238
|
+
/**
|
|
239
|
+
* **Inviting somebody onto the team** — the only way a Fleetless user appears.
|
|
240
|
+
*
|
|
241
|
+
* `tier` is **required**, and that is the one decision this shape exists to
|
|
242
|
+
* force. An optional tier would make *"I did not think about it"* and *"I meant
|
|
243
|
+
* developer"* the same request, on the field that decides who can remove whom.
|
|
244
|
+
* Inviting an owner is owner-only, checked by the route: the response hands
|
|
245
|
+
* back the accept link, so an owner-tier invitation is a promotion with one
|
|
246
|
+
* extra step.
|
|
247
|
+
*/
|
|
248
|
+
export const createTeamInviteRequest = z
|
|
249
|
+
.object({
|
|
250
|
+
email: z.email().meta({
|
|
251
|
+
description: 'The address to invite. Globally unique across Fleetless users, so an address already on another org\'s team is refused with `email_taken`.',
|
|
252
|
+
}),
|
|
253
|
+
display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable().optional().meta({
|
|
254
|
+
description: 'An optional name to pre-fill the account with; the invitee can change it afterwards.',
|
|
255
|
+
}),
|
|
256
|
+
tier: orgAdminTier.meta({
|
|
257
|
+
description: 'The tier the invitee holds on acceptance. **Required, not defaulted** — "I did not think about it" and "I meant developer" would otherwise be the same request, on the field that decides who can remove whom. Inviting an owner requires the owner tier.',
|
|
258
|
+
}),
|
|
259
|
+
send_mail: z.boolean().meta({
|
|
260
|
+
description: 'Whether Fleetless mails the invitation. The link in the answer is the primary path either way: a deployment with no SMTP still issues invitations and says so through `mail`.',
|
|
261
|
+
}),
|
|
262
|
+
})
|
|
263
|
+
.strict();
|
|
264
|
+
/**
|
|
265
|
+
* The invitation as issued. The **link is the primary path** and mail is the
|
|
266
|
+
* second, so this is complete and usable with `mail: 'not_configured'` — a
|
|
267
|
+
* deployment with no SMTP still issues invitations, it just cannot send them
|
|
268
|
+
* and says so.
|
|
269
|
+
*/
|
|
270
|
+
export const teamInvite = z.object({
|
|
271
|
+
id: z.uuid().meta({ description: 'The invitation, as listed and revoked by the team.' }),
|
|
272
|
+
email: z.email().meta({ description: 'The address the invitation was addressed to.' }),
|
|
273
|
+
tier: orgAdminTier.meta({ description: 'The tier the invitee holds on acceptance, fixed when the invitation was created.' }),
|
|
274
|
+
expires_at: z.iso.datetime().meta({ description: 'When the token stops working. Seven days from issue; an expired token answers exactly as an unknown one does.' }),
|
|
275
|
+
accept_url: z.url().max(500).meta({
|
|
276
|
+
description: 'The link to give the invitee, on the Fleetless auth portal. Bounded like `idpIssuer`: an unbounded URL on a shape that gets mailed, logged and rendered is a size nobody chose. Unlike an app invitation\'s link this is never `null` — the portal is a page Fleetless does serve.',
|
|
277
|
+
}),
|
|
278
|
+
mail: mailStatus.meta({ description: 'What happened to the mail. `not_configured` is an expected state and not a failure; the link above is the primary path.' }),
|
|
279
|
+
});
|
|
280
|
+
/**
|
|
281
|
+
* A pending invitation as the team sees it in the list — **without its
|
|
282
|
+
* `accept_url`**, and that omission is the point.
|
|
283
|
+
*
|
|
284
|
+
* The list exists so a team can see what is outstanding and revoke it. Neither
|
|
285
|
+
* needs the token, and a list that carries it turns every screenshot, every log
|
|
286
|
+
* line and every browser history entry of that page into live credentials for
|
|
287
|
+
* somebody else's account. It is the same rule `auditEvent.details` already
|
|
288
|
+
* states — never credentials, never tokens — applied to a read surface.
|
|
289
|
+
*
|
|
290
|
+
* There is no escalation either way: an owner can already create an invitation
|
|
291
|
+
* for any address. The reason to withhold it is not what an owner could do with
|
|
292
|
+
* it, but that a page nobody thinks of as sensitive stops being sensitive.
|
|
293
|
+
*
|
|
294
|
+
* `mail` is omitted for a duller reason: it described what happened at creation
|
|
295
|
+
* time, and re-serving it in a list invites a reader to take it as current.
|
|
296
|
+
*/
|
|
297
|
+
export const pendingTeamInvite = z.object({
|
|
298
|
+
id: z.uuid().meta({ description: 'The invitation, as revoked and re-issued by the team.' }),
|
|
299
|
+
email: z.email().meta({ description: 'The address the invitation was addressed to.' }),
|
|
300
|
+
tier: orgAdminTier.meta({ description: 'The tier the invitee would hold. Visible so an owner can spot an owner-tier invitation they did not authorise.' }),
|
|
301
|
+
expires_at: z.iso.datetime().meta({ description: 'When the token stops working.' }),
|
|
302
|
+
});
|
|
303
|
+
export const pendingTeamInviteListResponse = z.object({
|
|
304
|
+
invitations: z.array(pendingTeamInvite).meta({
|
|
305
|
+
description: 'Pending invitations only. An accepted invitation is history, not something to revoke.',
|
|
306
|
+
}),
|
|
307
|
+
});
|
|
308
|
+
/** Accepting it: the token proves the invitation, the password creates the login. */
|
|
309
|
+
export const acceptTeamInviteRequest = z
|
|
310
|
+
.object({
|
|
311
|
+
token: z.string().min(1).meta({
|
|
312
|
+
description: 'The opaque invitation token from the link. Unknown, expired and already-accepted all collapse into `410 token_spent` — telling them apart would say whether a token ever existed.',
|
|
313
|
+
}),
|
|
314
|
+
password: password.meta({
|
|
315
|
+
description: 'The password the new Fleetless account will use. At least 12 characters.',
|
|
316
|
+
}),
|
|
317
|
+
})
|
|
318
|
+
.strict();
|
|
319
|
+
/**
|
|
320
|
+
* `PATCH /api/org/users/:id` — **what an admin may change about a team member,
|
|
321
|
+
* and the two things that are absent rather than merely un-required.**
|
|
322
|
+
*
|
|
323
|
+
* `email` is not here. It is the identifier of the account, the value every
|
|
324
|
+
* invitation, reset link and audit line names, and a PATCH that could change it
|
|
325
|
+
* is both an account-takeover surface and a uniqueness race. *Immutable after
|
|
326
|
+
* create* is a sentence a strict schema can actually keep: offering `email` is
|
|
327
|
+
* a refusal, not a silently ignored field — which is the failure mode this
|
|
328
|
+
* project has already paid for once (`toHaveBeenCalledWith` could not tell
|
|
329
|
+
* *field sent* from *field missing*).
|
|
330
|
+
*
|
|
331
|
+
* `tier` is not here either. A tier change is owner-only with a last-owner
|
|
332
|
+
* guard (`tierChangeRequest`), and merging it in would give one route two
|
|
333
|
+
* refusal reasons and one audit event.
|
|
334
|
+
*
|
|
335
|
+
* So exactly one field remains, and the shape is kept rather than collapsed
|
|
336
|
+
* into a bare string: the next thing a team member gains will be optional here,
|
|
337
|
+
* and a route whose body is a naked value has nowhere to put it.
|
|
338
|
+
*/
|
|
339
|
+
export const patchFleetlessUserRequest = z
|
|
340
|
+
.object({
|
|
341
|
+
display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable().optional().meta({
|
|
342
|
+
description: 'The member\'s display name. Absent leaves it alone; an explicit `null` clears it.',
|
|
343
|
+
}),
|
|
344
|
+
})
|
|
345
|
+
.strict();
|
|
346
|
+
/**
|
|
347
|
+
* `PUT /api/org/users/:id/tier` — **owner-only, and the last owner is
|
|
348
|
+
* neither demotable nor deletable** (refused with 409 `last_owner`).
|
|
349
|
+
*
|
|
350
|
+
* `tier_required` keeps its exact semantics — it says what the *caller's* tier
|
|
351
|
+
* is and what was needed, and nothing about the target.
|
|
352
|
+
*/
|
|
353
|
+
export const tierChangeRequest = z.object({ tier: orgAdminTier }).strict();
|
|
354
|
+
/**
|
|
355
|
+
* What a `forbidden` refusal carries when the reason is the caller's **tier**
|
|
356
|
+
* rather than a missing grant (W6c).
|
|
357
|
+
*
|
|
358
|
+
* §3.3 makes `forbidden` deliberately silent about *existence*, and that stays
|
|
359
|
+
* true — this says nothing about what the target is. But "your role does not
|
|
360
|
+
* permit this" and "there is no such thing" are the same answer today, and a
|
|
361
|
+
* developer cannot tell *ask an owner* from *you have the wrong id*. Naming
|
|
362
|
+
* the required tier reveals only what the caller could read off the docs.
|
|
363
|
+
*/
|
|
364
|
+
export const tierRequiredDetails = z.object({
|
|
365
|
+
required: orgAdminTier,
|
|
366
|
+
/** The caller's own tier — theirs to know, and it is what makes the message actionable. */
|
|
367
|
+
actual: orgAdminTier,
|
|
368
|
+
});
|
|
369
|
+
/**
|
|
370
|
+
* Changing your own password while logged in.
|
|
371
|
+
*
|
|
372
|
+
* `current_password` is required even though the session already proves
|
|
373
|
+
* identity: it is what makes a stolen *session* insufficient to take the
|
|
374
|
+
* *account*. Every other session is revoked on success; the one that made the
|
|
375
|
+
* change survives, because logging someone out of the tab they just used is
|
|
376
|
+
* indistinguishable from the change having failed.
|
|
377
|
+
*
|
|
378
|
+
* Shared with the app-user surface (`POST /api/client/password/change`): the
|
|
379
|
+
* argument is about credentials and sessions, not about which space the person
|
|
380
|
+
* lives in.
|
|
381
|
+
*/
|
|
382
|
+
export const passwordChangeRequest = z.object({
|
|
383
|
+
current_password: z.string().min(1).meta({
|
|
384
|
+
description: 'The password in use right now. It is required even though the session already proves identity: it is what makes a stolen *session* insufficient to take the *account*.',
|
|
385
|
+
}),
|
|
386
|
+
new_password: password.meta({
|
|
387
|
+
description: 'The replacement password. Every other session is revoked when it is accepted, while the session that made the change survives — logging somebody out of the tab they just used is indistinguishable from the change having failed.',
|
|
388
|
+
}),
|
|
389
|
+
});
|
|
390
|
+
/**
|
|
391
|
+
* Asking for a reset link, **as a Fleetless user**.
|
|
392
|
+
*
|
|
393
|
+
* **The response never says whether the address exists.** It is unauthenticated
|
|
394
|
+
* and would otherwise be an account-enumeration oracle — the one place where
|
|
395
|
+
* §3.3's "reveal nothing about what exists" is not a preference but the whole
|
|
396
|
+
* point. So this answers the same way for a known and an unknown address, in
|
|
397
|
+
* status, body **and timing**, and any consumer that renders "no such account"
|
|
398
|
+
* from it has reintroduced the oracle.
|
|
399
|
+
*
|
|
400
|
+
* A bare address resolves to at most one account: a Fleetless user's email is
|
|
401
|
+
* **globally unique**, so the reset mails the one match, if any, with a token
|
|
402
|
+
* bound to that account.
|
|
403
|
+
*
|
|
404
|
+
* The app-user equivalent is `clientPasswordResetRequest` in `client-auth.ts`
|
|
405
|
+
* and carries an `app_identifier`, because on that surface a person is
|
|
406
|
+
* identified by app *and* address. Two shapes rather than one, because the two
|
|
407
|
+
* surfaces identify a person differently — not because the reasoning differs.
|
|
408
|
+
*/
|
|
409
|
+
export const passwordResetRequest = z.object({
|
|
410
|
+
email: z.email(),
|
|
411
|
+
});
|
|
412
|
+
/**
|
|
413
|
+
* Using the link. The token is **single-use and expires**; spending it revokes
|
|
414
|
+
* every session of that subject, because a forgotten password is one of the
|
|
415
|
+
* two states where somebody else may be holding one. `token_spent` covers used
|
|
416
|
+
* and expired alike — telling them apart tells a stranger whether a token ever
|
|
417
|
+
* existed.
|
|
418
|
+
*/
|
|
419
|
+
export const passwordResetConfirm = z.object({
|
|
420
|
+
token: z.string().min(1),
|
|
421
|
+
new_password: password,
|
|
422
|
+
});
|
|
423
|
+
/**
|
|
424
|
+
* An IdP issuer URL — **an attacker-supplied string that decides where the
|
|
425
|
+
* *server* connects.**
|
|
426
|
+
*
|
|
427
|
+
* `redirectUri` in `oauth.ts` got a parsed scheme check and an explicit
|
|
428
|
+
* loopback allow-list, with the reasoning written down, because it decides
|
|
429
|
+
* where a *credential* goes. This field got `z.url()` — in the same file, in
|
|
430
|
+
* the same wave. Argus-W7b found it and stored `file:///etc/passwd`,
|
|
431
|
+
* `http://169.254.169.254/latest/meta-data` and `http://infra-postgres-1:5432`
|
|
432
|
+
* through the app's IdP route, then caught the outbound discovery fetch on a
|
|
433
|
+
* listener he stood up. **That is this project's own question — which rules
|
|
434
|
+
* have we already written down, and where else do they apply — answered badly,
|
|
435
|
+
* one field over.**
|
|
436
|
+
*
|
|
437
|
+
* **What this shape can decide, it now decides:** http(s) only (so no `file:`,
|
|
438
|
+
* `gopher:`, `data:`), no credentials in the URL, no fragment, no query. RFC
|
|
439
|
+
* 8414 §3 builds the discovery URL from the issuer's path, so a query string
|
|
440
|
+
* there is meaningless and a `@` is a redirect trick.
|
|
441
|
+
*
|
|
442
|
+
* **What it cannot decide, stated rather than implied:** it cannot tell
|
|
443
|
+
* `http://localhost:8081/realms/fleetless-test` — the dev IdP this project
|
|
444
|
+
* ships — from `http://127.0.0.1:5432`. Both are loopback http. So **this is
|
|
445
|
+
* not the SSRF defence and must not be mistaken for one.** The defence belongs
|
|
446
|
+
* at the fetch, in the cloud: refuse loopback, link-local and private ranges
|
|
447
|
+
* unless something explicitly opts in for development, and it names DNS
|
|
448
|
+
* rebinding as its own residual. A schema that quietly looked sufficient here
|
|
449
|
+
* would be worse than one that says where the real check has to live.
|
|
450
|
+
*
|
|
451
|
+
* It lives in this file rather than beside its one consumer because it is a
|
|
452
|
+
* rule about URLs the server dereferences, and the next such field should find
|
|
453
|
+
* it already written down. `appOidcProvider` is that consumer today.
|
|
454
|
+
*/
|
|
455
|
+
export const idpIssuer = z
|
|
456
|
+
.url()
|
|
457
|
+
.max(500)
|
|
458
|
+
.refine((v) => {
|
|
459
|
+
let url;
|
|
460
|
+
try {
|
|
461
|
+
url = new URL(v);
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
if (!['http:', 'https:'].includes(url.protocol))
|
|
467
|
+
return false;
|
|
468
|
+
if (url.username !== '' || url.password !== '')
|
|
469
|
+
return false;
|
|
470
|
+
if (url.hash !== '' || url.search !== '')
|
|
471
|
+
return false;
|
|
472
|
+
return url.hostname.length > 0;
|
|
473
|
+
}, { message: 'issuer must be an http(s) URL with no credentials, query or fragment' });
|
|
474
|
+
/**
|
|
475
|
+
* **The federated callback error vocabulary is deleted, with no successor
|
|
476
|
+
* here.** `oidcCallbackErrorCode` and `oidcCallbackError` described the page
|
|
477
|
+
* `GET /mcp/oauth/idp-callback` rendered when a group's identity provider sent
|
|
478
|
+
* a browser back — `jit_disabled` and `email_collision` name provisioning steps
|
|
479
|
+
* only a group provider had. D1 makes Fleetless users password-only and deletes
|
|
480
|
+
* group providers, so the flow that produced these codes cannot start; the
|
|
481
|
+
* route is gone from this manifest and from the cloud.
|
|
482
|
+
*
|
|
483
|
+
* The per-app OIDC vocabulary is `clientOidcErrorCode` in `client-auth.ts`: a
|
|
484
|
+
* different list, for a different flow, redirected to the developer's own page
|
|
485
|
+
* rather than rendered by Fleetless. Two callback error enums coexisting is how
|
|
486
|
+
* the wrong one gets picked up by the train that adds per-app OIDC, which is
|
|
487
|
+
* why this one is deleted rather than left standing for it.
|
|
488
|
+
*/
|
|
489
|
+
/**
|
|
490
|
+
* `GET /api/auth/me` — named so the console can validate it.
|
|
491
|
+
*
|
|
492
|
+
* `user` is a `fleetlessUser`, and its `tier` is required, so this response
|
|
493
|
+
* always states the caller's console powers. It used to be an `orgUser` whose
|
|
494
|
+
* tier was optional and *always present in practice on this route* — a
|
|
495
|
+
* guarantee the route made and the schema could not, which is exactly the kind
|
|
496
|
+
* of gap this file keeps finding. The two-space cut closed it by making the
|
|
497
|
+
* field required on the shape itself.
|
|
498
|
+
*/
|
|
499
|
+
export const authMeResponse = z.object({ org, user: fleetlessUser });
|
|
500
|
+
/** `PATCH /api/org` — rename the org. Owner only. Same bounds as signup's `org_name`. */
|
|
501
|
+
export const patchOrgRequest = z.object({ name: z.string().min(1).max(120) }).strict();
|
|
502
|
+
/** `PATCH /api/auth/me` — the caller updates their own display name (null clears it). */
|
|
503
|
+
export const patchAuthMeRequest = z.object({ display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable() }).strict();
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export { SLUG_RULE, ROS_NAME_RULE, ROS_TYPE_NAME_RULE, FIELD_PATH_RULE, slug, rosName, rosTypeName, fieldPath, wireSeqCursor, wireTimestampMs, applyErrorKind, applyError, } from './common.js';
|
|
2
|
+
export type { ApplyErrorKind, ApplyError } from './common.js';
|
|
3
|
+
export { MCP_PROTOCOL_VERSION, MCP_ENDPOINT_PATH, mcpAppEndpointPath, MCP_APP_PATHS, MCP_TOOL_NAME_MAX, MCP_ASSET_LINK_PATH, MCP_ASSET_LINK_TTL_MS, mcpToolNamePattern, mcpToolKind, mcpExposure, mcpCapabilities, mcpRobotDatasheet, mcpRolePreviewResponse, } from './mcp.js';
|
|
4
|
+
export type { McpAppPaths, McpToolKind, McpExposure, McpCapabilities, McpRobotDatasheet, McpRolePreviewResponse, } from './mcp.js';
|
|
5
|
+
export { PROTOCOL_VERSION, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, datapointFrame, bridgeState, bridgePressure, PRESSURE_SLUG, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED, bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress, activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, } from './protocol.js';
|
|
6
|
+
export type { BridgeHello, CloudHelloOk, CloudHelloError, CloudPing, BridgePong, DatapointFrame, BridgeState, BridgePressure, CloudConfig, BridgeConfigApplied, CloudIntrospectRequest, BridgeIntrospect, CloudTypeRequest, BridgeTypeDefinitions, CloudInvoke, CloudCancel, CloudPublish, BridgeJobUpdate, BridgeJobLost, SnapshotHeader, CloudCameraStart, CloudCameraStop, BridgeCameraState, ActiveJob, BridgeAssetsAvailable, CloudAssetRequest, BridgeAssetProgress, } from './protocol.js';
|
|
7
|
+
export { jobState, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
|
|
8
|
+
export type { JobState, Job, JobEvent, BusyDetails, PublisherBusyDetails, JobQueueFullDetails, } from './jobs.js';
|
|
9
|
+
export { JOB_RUN_PAGE_MAX, JOB_RUN_RETENTION_DAYS, jobActor, jobRunKind, jobRun, jobRunQuery, jobRunListResponse, jobRunSummaryQuery, jobRunSummary, } from './jobs.js';
|
|
10
|
+
export type { JobActor, JobRunKind, JobRun, JobRunQuery, JobRunListResponse, JobRunSummary } from './jobs.js';
|
|
11
|
+
export { FLEETLESS_FORMAT_VERSION, RESERVED_SLUGS, parameterType, parameterSpec, parameterMap, serviceDescription, parameterDescription, messageTemplate, messageRef, messageBody, messageMap, PLACEHOLDER_RE, placeholderNames, actionConfig, serviceConfig, publisherConfig, cameraConfig, alertCondition, datapointAlert, rateThrottleHz, datapointNumeric, datapointRetention, datapointChart, datapointConfig, robotConfigDoc, validationIssue, configState, snapshotIntervalSeconds, ALERT_SEVERITY_DEFAULT, ALERT_ENABLED_DEFAULT, RETENTION_INTERVAL_SECONDS_DEFAULT, CHART_WINDOW_MINUTES_DEFAULT, cameraSource, cameraCredentials, } from './config.js';
|
|
12
|
+
export type { CameraSource } from './config.js';
|
|
13
|
+
export type { ParameterType, ParameterSpec, ActionConfig, ServiceConfig, PublisherConfig, CameraConfig, CameraCredentials, AlertCondition, DatapointAlert, DatapointNumeric, DatapointRetention, DatapointChart, DatapointConfig, RobotConfigDoc, ValidationIssue, ConfigState, } from './config.js';
|
|
14
|
+
/**
|
|
15
|
+
* FL-005 — the one account of what is wrong with a document, shared by the
|
|
16
|
+
* cloud and the console. The cloud held a second copy for one wave; it was
|
|
17
|
+
* deleted in wave 2 task 8 (cloud `a307e18`, 2026-09-03). See
|
|
18
|
+
* `config-issues.ts`'s header for what that window cost.
|
|
19
|
+
*/
|
|
20
|
+
export { DOCUMENT_ROOT_PATH, EXPOSURE_SECTIONS, schemaIssues, formatPath, splitFormatPath, configSchemaHash, } from './config-issues.js';
|
|
21
|
+
export type { SchemaIssue, ExposureSection } from './config-issues.js';
|
|
22
|
+
export { rosGraphEntry, rosGraph, typeField, typeDefinition, parameterFieldsOf } from './introspection.js';
|
|
23
|
+
export type { RosGraphEntry, RosGraph, TypeField, TypeDefinition } from './introspection.js';
|
|
24
|
+
export { robot, patchRobotResponse, robotToken, createRobotRequest, createRobotResponse, exposureCounts, robotListItem, robotListResponse, datapointValue, robotDetailResponse, configDraftResponse, putConfigDraftRequest, publishConfigResponse, configVersionsResponse, configVersionResponse, introspectionResponse, typesResponse, fetchTypesRequest, fetchTypesResponse, datapointDescriptor, datapointListResponse, robotDetailsDoc, putRobotDetailsResponse, putRobotDetailsRequest, invokeRequest, invokeResponse, cancelRequest, releaseLiveQuery, serviceCallResponse, invokeOrServiceResponse, publishRequest, jobResponse, robotJobsResponse, rateLimitDetails, exposure, exposureListResponse, SNAPSHOT_HEADERS, ASSET_UPLOAD_HEADERS, cameraDescriptor, cameraListResponse, liveSessionResponse, snapshotMetaResponse, historyQuery, historySamplesResponse, historyBucketsResponse, historyResponse, orgQuotas, orgQuotaUsage, orgQuotaUsageCounts, robotDeletionSummary, RESOURCE_HEALTH_STATES, resourceHealthState, resourceHealthListResponse, orgHealthQuery, robotDeleteQuery, patchRobotRequest, renameSlugRequest, renameSlugResponse, slugUsageResponse, } from './rest.js';
|
|
25
|
+
export type { HistoryQuery, HistorySamplesResponse, HistoryResponse, HistoryBucketsResponse, OrgQuotas, OrgQuotaUsage, OrgQuotaUsageCounts, RobotDeletionSummary, ResourceHealthState, ResourceHealthListResponse, OrgHealthQuery, RobotDeleteQuery, PatchRobotRequest, RenameSlugRequest, RenameSlugResponse, SlugUsageResponse, } from './rest.js';
|
|
26
|
+
export { LATENCY_BUCKET_MS, BRIDGE_LATENCY_RETENTION_DAYS, MAX_LATENCY_BUCKETS_PER_RESPONSE, latencyBucket, robotLatencySeries, orgLatencyQuery, orgLatencyResponse, USAGE_WINDOW_MAX_DAYS, usageMetric, usageDay, orgUsageQuery, usageRow, orgUsageResponse, } from './rest.js';
|
|
27
|
+
export type { LatencyBucket, RobotLatencySeries, OrgLatencyResponse } from './rest.js';
|
|
28
|
+
export type { UsageMetric, OrgUsageQuery, UsageRow, OrgUsageResponse } from './rest.js';
|
|
29
|
+
export type { Robot, PatchRobotResponse, CreateRobotRequest, CreateRobotResponse, ExposureCounts, RobotListItem, RobotListResponse, DatapointValue, RobotDetailResponse, ConfigDraftResponse, PutConfigDraftRequest, PublishConfigResponse, ConfigVersionsResponse, ConfigVersionResponse, IntrospectionResponse, TypesResponse, FetchTypesRequest, FetchTypesResponse, DatapointDescriptor, DatapointListResponse, RobotDetailsDoc, PutRobotDetailsResponse, PutRobotDetailsRequest, InvokeRequest, InvokeResponse, CancelRequest, ReleaseLiveQuery, ServiceCallResponse, InvokeOrServiceResponse, PublishRequest, JobResponse, RobotJobsResponse, RateLimitDetails, Exposure, ExposureListResponse, CameraDescriptor, CameraListResponse, LiveSessionResponse, SnapshotMetaResponse, } from './rest.js';
|
|
30
|
+
export { clientAuth, authOk, authError, clientInvoke, clientCancel, clientPublish, commandResult, errorFrame, clientSubscribe, clientUnsubscribe, subscribeError, datapointEvent, resourceHealthEvent, resourceHealthCleared, liveSessionEndReason, liveSessionEvent, ORG_EVENT_SAMPLE_INTERVAL_MS, ORG_EVENT_ORG_CEILING_PER_SECOND, ORG_EVENT_BUFFER_SIZE, ORG_EVENT_BUFFER_IDLE_MS, ORG_EVENT_DETAIL_MAX_BYTES, orgEventKind, orgEventSeverity, orgEvent, orgEventSubscribe, orgEventUnsubscribe, orgEventReplay, orgEventDropped, } from './realtime.js';
|
|
31
|
+
export type { ClientAuth, AuthOk, AuthError, ClientInvoke, ClientCancel, ClientPublish, CommandResult, ErrorFrame, ClientSubscribe, ClientUnsubscribe, SubscribeError, DatapointEvent, ResourceHealthEvent, ResourceHealthCleared, LiveSessionEndReason, LiveSessionEvent, OrgEventKind, OrgEventSeverity, OrgEvent, OrgEventSubscribe, OrgEventUnsubscribe, OrgEventReplay, OrgEventDropped, } from './realtime.js';
|
|
32
|
+
export { password, org, patchOrgResponse, sessionTokens, refreshRequest, signUpRequest, signUpResponse, waitlistRequest, developerLoginRequest, USER_DISPLAY_NAME_MAX, orgAdminTier, fleetlessUser, fleetlessUserListResponse, createTeamInviteRequest, teamInvite, pendingTeamInvite, pendingTeamInviteListResponse, acceptTeamInviteRequest, patchFleetlessUserRequest, tierChangeRequest, mailStatus, tierRequiredDetails, passwordChangeRequest, passwordResetRequest, passwordResetConfirm, idpIssuer, authMeResponse, patchOrgRequest, patchAuthMeRequest, } from './identity.js';
|
|
33
|
+
export type { Org, PatchOrgResponse, SessionTokens, RefreshRequest, SignUpRequest, SignUpResponse, WaitlistRequest, DeveloperLoginRequest, OrgAdminTier, FleetlessUser, FleetlessUserListResponse, CreateTeamInviteRequest, TeamInvite, PendingTeamInvite, PendingTeamInviteListResponse, AcceptTeamInviteRequest, PatchFleetlessUserRequest, TierChangeRequest, MailStatus, TierRequiredDetails, PasswordChangeRequest, PasswordResetRequest, PasswordResetConfirm, IdpIssuer, AuthMeResponse, PatchOrgRequest, PatchAuthMeRequest, } from './identity.js';
|
|
34
|
+
export { appIdentifier, app, appListResponse, createAppRequest, updateAppRequest, serverKeyToken, serverKey, serverKeyListResponse, createServerKeyResponse, role, roleListResponse, rolePermissions, } from './apps.js';
|
|
35
|
+
export type { App, AppListResponse, CreateAppRequest, UpdateAppRequest, ServerKey, ServerKeyListResponse, CreateServerKeyResponse, Role, RoleListResponse, RolePermissions, } from './apps.js';
|
|
36
|
+
export { clientLoginRequest, clientRefreshRequest, clientLogoutRequest, clientRegisterRequest, clientVerifyEmailRequest, clientResendVerificationRequest, clientPasswordResetRequest, clientPasswordResetConfirmRequest, clientAcceptInvitationRequest, CLIENT_OIDC_CALLBACK_PATH, clientProviderListQuery, clientProviderListResponse, clientOidcStartQuery, clientOidcCallbackQuery, clientOidcExchangeRequest, clientOidcErrorCode, clientMcpInteraction, clientMcpInteractionDecisionResponse, mcpConsentGrant, mcpConsentGrantListResponse, clientIdentity, } from './client-auth.js';
|
|
37
|
+
export type { ClientLoginRequest, ClientRefreshRequest, ClientLogoutRequest, ClientRegisterRequest, ClientVerifyEmailRequest, ClientResendVerificationRequest, ClientPasswordResetRequest, ClientPasswordResetConfirmRequest, ClientAcceptInvitationRequest, ClientProviderListQuery, ClientProviderListResponse, ClientOidcStartQuery, ClientOidcCallbackQuery, ClientOidcExchangeRequest, ClientOidcErrorCode, ClientMcpInteraction, ClientMcpInteractionDecisionResponse, McpConsentGrant, McpConsentGrantListResponse, ClientIdentity, } from './client-auth.js';
|
|
38
|
+
export { APP_USER_DISPLAY_NAME_MAX, APP_URL_PLACEHOLDERS, MAIL_TEMPLATE_VARIABLES, DEFAULT_MAIL_TEMPLATES, providerSlug, appUserStatus, appUser, appUserListResponse, createAppUserRequest, patchAppUserRequest, createAppInvitationRequest, appInvitation, pendingAppInvitation, appInvitationListResponse, appOidcProvider, appOidcProviderListResponse, createAppOidcProviderRequest, patchAppOidcProviderRequest, appUrlTemplate, allowedOrigin, emailDomain, appAuthConfig, putAppAuthConfigRequest, mailTemplateKind, appMailTemplate, appMailTemplateListResponse, putAppMailTemplateRequest, mailTemplatePreviewRequest, mailTemplatePreviewResponse, mailTemplateProblemDetails, mailOutcome, } from './app-users.js';
|
|
39
|
+
export type { AppUserStatus, AppUser, AppUserListResponse, CreateAppUserRequest, PatchAppUserRequest, CreateAppInvitationRequest, AppInvitation, PendingAppInvitation, AppInvitationListResponse, AppOidcProvider, AppOidcProviderListResponse, CreateAppOidcProviderRequest, PatchAppOidcProviderRequest, AppAuthConfig, PutAppAuthConfigRequest, MailTemplateKind, AppMailTemplate, AppMailTemplateListResponse, PutAppMailTemplateRequest, MailTemplatePreviewRequest, MailTemplatePreviewResponse, MailTemplateProblemDetails, MailOutcome, } from './app-users.js';
|
|
40
|
+
export { assetKind, URDF_ASSET_NAME, asset, urdfCompleteness, assetListResponse, missingAssetQuery, assetSyncRequest, assetSyncResponse, assetSyncState, assetSyncStatus, assetFailure, assetFailureKind, assetTooLargeDetails, assetSyncBusyDetails, ASSET_UPLOAD_MAX_BYTES, } from './assets.js';
|
|
41
|
+
export type { AssetKind, Asset, UrdfCompleteness, AssetListResponse, MissingAssetQuery, AssetSyncRequest, AssetSyncResponse, AssetSyncState, AssetSyncStatus, AssetFailure, AssetFailureKind, AssetTooLargeDetails, AssetSyncBusyDetails, } from './assets.js';
|
|
42
|
+
export { auditActor, auditEvent, auditQuery, auditListResponse, AUDIT_CSV_COLUMNS, AUDIT_RETENTION_DAYS } from './audit.js';
|
|
43
|
+
export type { AuditActor, AuditEvent, AuditQuery, AuditListResponse } from './audit.js';
|
|
44
|
+
export { alertRowCondition, alertSeverity, alertState, datapointAlertRow, alertListResponse, orgFiringAlertsResponse, orgAlertsQuery, datapointDisplay, putDatapointDisplayRequest, } from './alerts.js';
|
|
45
|
+
export type { AlertRowCondition, AlertSeverity, AlertState, DatapointAlertRow, AlertListResponse, OrgFiringAlertsResponse, OrgAlertsQuery, DatapointDisplay, PutDatapointDisplayRequest, } from './alerts.js';
|
|
46
|
+
export { apiError, parameterViolation, parameterInvalidDetails, ERROR_CODES } from './errors.js';
|
|
47
|
+
export type { ApiError, ParameterViolation, ParameterInvalidDetails, ErrorCode } from './errors.js';
|
|
48
|
+
export { oauthErrorCode, oauthError, oauthRedirectResponse, oauthTokenRequest, oauthTokenResponse, redirectUri, codeChallengeMethod, oauthAuthorizeQuery, dynamicClientRegistrationRequest, MCP_DCR_MAX_REDIRECT_URIS, dynamicClientRegistrationResponse, authorizationServerMetadata, protectedResourceMetadata, } from './oauth.js';
|
|
49
|
+
export type { OauthErrorCode, OauthError, OauthRedirectResponse, OauthTokenRequest, OauthTokenResponse, RedirectUri, OauthAuthorizeQuery, DynamicClientRegistrationRequest, DynamicClientRegistrationResponse, AuthorizationServerMetadata, ProtectedResourceMetadata, } from './oauth.js';
|
|
50
|
+
export { ROUTES, ROUTE_SECTIONS, IN_HANDLER_ROUTES } from './routes.js';
|
|
51
|
+
export type { RouteEntry, RouteParam, RouteAudience, RouteAuth, RouteSection, RouteMethod, RouteTransport, } from './routes.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
export { SLUG_RULE, ROS_NAME_RULE, ROS_TYPE_NAME_RULE, FIELD_PATH_RULE, slug, rosName, rosTypeName, fieldPath, wireSeqCursor, wireTimestampMs, applyErrorKind, applyError, } from './common.js';
|
|
3
|
+
export { MCP_PROTOCOL_VERSION, MCP_ENDPOINT_PATH, mcpAppEndpointPath, MCP_APP_PATHS, MCP_TOOL_NAME_MAX, MCP_ASSET_LINK_PATH, MCP_ASSET_LINK_TTL_MS, mcpToolNamePattern, mcpToolKind, mcpExposure, mcpCapabilities, mcpRobotDatasheet, mcpRolePreviewResponse, } from './mcp.js';
|
|
4
|
+
export { PROTOCOL_VERSION, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, datapointFrame, bridgeState, bridgePressure, PRESSURE_SLUG, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED,
|
|
5
|
+
// W7 — assets.
|
|
6
|
+
bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress,
|
|
7
|
+
// W6b — addressing.
|
|
8
|
+
activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, } from './protocol.js';
|
|
9
|
+
export { jobState, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
|
|
10
|
+
export { JOB_RUN_PAGE_MAX, JOB_RUN_RETENTION_DAYS, jobActor, jobRunKind, jobRun, jobRunQuery, jobRunListResponse, jobRunSummaryQuery, jobRunSummary, } from './jobs.js';
|
|
11
|
+
export { FLEETLESS_FORMAT_VERSION, RESERVED_SLUGS, parameterType, parameterSpec, parameterMap, serviceDescription, parameterDescription, messageTemplate, messageRef, messageBody, messageMap, PLACEHOLDER_RE, placeholderNames, actionConfig, serviceConfig, publisherConfig, cameraConfig, alertCondition, datapointAlert, rateThrottleHz, datapointNumeric, datapointRetention, datapointChart, datapointConfig, robotConfigDoc, validationIssue, configState, snapshotIntervalSeconds,
|
|
12
|
+
// FL-002 — the defaults the format names, so nobody invents them twice.
|
|
13
|
+
ALERT_SEVERITY_DEFAULT, ALERT_ENABLED_DEFAULT, RETENTION_INTERVAL_SECONDS_DEFAULT, CHART_WINDOW_MINUTES_DEFAULT,
|
|
14
|
+
// W6
|
|
15
|
+
cameraSource, cameraCredentials, } from './config.js';
|
|
16
|
+
/**
|
|
17
|
+
* FL-005 — the one account of what is wrong with a document, shared by the
|
|
18
|
+
* cloud and the console. The cloud held a second copy for one wave; it was
|
|
19
|
+
* deleted in wave 2 task 8 (cloud `a307e18`, 2026-09-03). See
|
|
20
|
+
* `config-issues.ts`'s header for what that window cost.
|
|
21
|
+
*/
|
|
22
|
+
export { DOCUMENT_ROOT_PATH, EXPOSURE_SECTIONS, schemaIssues, formatPath, splitFormatPath, configSchemaHash, } from './config-issues.js';
|
|
23
|
+
export { rosGraphEntry, rosGraph, typeField, typeDefinition, parameterFieldsOf } from './introspection.js';
|
|
24
|
+
export { robot, patchRobotResponse, robotToken, createRobotRequest, createRobotResponse, exposureCounts, robotListItem, robotListResponse, datapointValue, robotDetailResponse, configDraftResponse, putConfigDraftRequest, publishConfigResponse, configVersionsResponse, configVersionResponse, introspectionResponse, typesResponse, fetchTypesRequest, fetchTypesResponse, datapointDescriptor, datapointListResponse, robotDetailsDoc, putRobotDetailsResponse, putRobotDetailsRequest, invokeRequest, invokeResponse,
|
|
25
|
+
// W6b — addressing.
|
|
26
|
+
cancelRequest, releaseLiveQuery, serviceCallResponse, invokeOrServiceResponse, publishRequest, jobResponse, robotJobsResponse, rateLimitDetails, exposure, exposureListResponse, SNAPSHOT_HEADERS, ASSET_UPLOAD_HEADERS, cameraDescriptor, cameraListResponse, liveSessionResponse, snapshotMetaResponse,
|
|
27
|
+
// W6 — retention, history, quotas.
|
|
28
|
+
historyQuery, historySamplesResponse, historyBucketsResponse, historyResponse, orgQuotas, orgQuotaUsage, orgQuotaUsageCounts, robotDeletionSummary, RESOURCE_HEALTH_STATES, resourceHealthState, resourceHealthListResponse, orgHealthQuery, robotDeleteQuery,
|
|
29
|
+
// W3a — robot rename, slug rename.
|
|
30
|
+
patchRobotRequest, renameSlugRequest, renameSlugResponse, slugUsageResponse, } from './rest.js';
|
|
31
|
+
export { LATENCY_BUCKET_MS, BRIDGE_LATENCY_RETENTION_DAYS, MAX_LATENCY_BUCKETS_PER_RESPONSE, latencyBucket, robotLatencySeries, orgLatencyQuery, orgLatencyResponse, USAGE_WINDOW_MAX_DAYS, usageMetric, usageDay, orgUsageQuery, usageRow, orgUsageResponse, } from './rest.js';
|
|
32
|
+
export { clientAuth, authOk, authError, clientInvoke, clientCancel, clientPublish, commandResult, errorFrame, clientSubscribe, clientUnsubscribe, subscribeError, datapointEvent, resourceHealthEvent, resourceHealthCleared, liveSessionEndReason, liveSessionEvent, ORG_EVENT_SAMPLE_INTERVAL_MS, ORG_EVENT_ORG_CEILING_PER_SECOND, ORG_EVENT_BUFFER_SIZE, ORG_EVENT_BUFFER_IDLE_MS, ORG_EVENT_DETAIL_MAX_BYTES, orgEventKind, orgEventSeverity, orgEvent, orgEventSubscribe, orgEventUnsubscribe, orgEventReplay, orgEventDropped, } from './realtime.js';
|
|
33
|
+
export { password, org, patchOrgResponse, sessionTokens, refreshRequest, signUpRequest, signUpResponse,
|
|
34
|
+
// 2026-09-04 — the public site (closed beta).
|
|
35
|
+
waitlistRequest, developerLoginRequest,
|
|
36
|
+
// 2026-09-05 — the two identity spaces (app-user-auth, D1).
|
|
37
|
+
USER_DISPLAY_NAME_MAX, orgAdminTier, fleetlessUser, fleetlessUserListResponse, createTeamInviteRequest, teamInvite, pendingTeamInvite, pendingTeamInviteListResponse, acceptTeamInviteRequest, patchFleetlessUserRequest, tierChangeRequest,
|
|
38
|
+
// W6c — identity.
|
|
39
|
+
mailStatus, tierRequiredDetails, passwordChangeRequest, passwordResetRequest, passwordResetConfirm, idpIssuer,
|
|
40
|
+
// W3a — auth/me, org and member patches.
|
|
41
|
+
authMeResponse, patchOrgRequest, patchAuthMeRequest, } from './identity.js';
|
|
42
|
+
export { appIdentifier, app, appListResponse, createAppRequest, updateAppRequest, serverKeyToken, serverKey, serverKeyListResponse, createServerKeyResponse, role, roleListResponse, rolePermissions, } from './apps.js';
|
|
43
|
+
export { clientLoginRequest, clientRefreshRequest, clientLogoutRequest, clientRegisterRequest, clientVerifyEmailRequest, clientResendVerificationRequest, clientPasswordResetRequest, clientPasswordResetConfirmRequest, clientAcceptInvitationRequest, CLIENT_OIDC_CALLBACK_PATH, clientProviderListQuery, clientProviderListResponse, clientOidcStartQuery, clientOidcCallbackQuery, clientOidcExchangeRequest, clientOidcErrorCode, clientMcpInteraction, clientMcpInteractionDecisionResponse, mcpConsentGrant, mcpConsentGrantListResponse, clientIdentity, } from './client-auth.js';
|
|
44
|
+
// 2026-09-05 — the per-app identity space (app-user-auth, D1/D3/D4/D5).
|
|
45
|
+
export { APP_USER_DISPLAY_NAME_MAX, APP_URL_PLACEHOLDERS, MAIL_TEMPLATE_VARIABLES, DEFAULT_MAIL_TEMPLATES, providerSlug, appUserStatus, appUser, appUserListResponse, createAppUserRequest, patchAppUserRequest, createAppInvitationRequest, appInvitation, pendingAppInvitation, appInvitationListResponse, appOidcProvider, appOidcProviderListResponse, createAppOidcProviderRequest, patchAppOidcProviderRequest, appUrlTemplate, allowedOrigin, emailDomain, appAuthConfig, putAppAuthConfigRequest, mailTemplateKind, appMailTemplate, appMailTemplateListResponse, putAppMailTemplateRequest, mailTemplatePreviewRequest, mailTemplatePreviewResponse, mailTemplateProblemDetails, mailOutcome, } from './app-users.js';
|
|
46
|
+
export { assetKind, URDF_ASSET_NAME, asset, urdfCompleteness, assetListResponse, missingAssetQuery, assetSyncRequest, assetSyncResponse, assetSyncState, assetSyncStatus, assetFailure, assetFailureKind, assetTooLargeDetails, assetSyncBusyDetails, ASSET_UPLOAD_MAX_BYTES, } from './assets.js';
|
|
47
|
+
export { auditActor, auditEvent, auditQuery, auditListResponse, AUDIT_CSV_COLUMNS, AUDIT_RETENTION_DAYS } from './audit.js';
|
|
48
|
+
export { alertRowCondition, alertSeverity, alertState, datapointAlertRow, alertListResponse, orgFiringAlertsResponse, orgAlertsQuery, datapointDisplay, putDatapointDisplayRequest, } from './alerts.js';
|
|
49
|
+
export { apiError, parameterViolation, parameterInvalidDetails, ERROR_CODES } from './errors.js';
|
|
50
|
+
export { oauthErrorCode, oauthError, oauthRedirectResponse, oauthTokenRequest, oauthTokenResponse, redirectUri, codeChallengeMethod, oauthAuthorizeQuery, dynamicClientRegistrationRequest, MCP_DCR_MAX_REDIRECT_URIS, dynamicClientRegistrationResponse, authorizationServerMetadata, protectedResourceMetadata, } from './oauth.js';
|
|
51
|
+
export { ROUTES, ROUTE_SECTIONS, IN_HANDLER_ROUTES } from './routes.js';
|