@loams/client 0.1.0-preview.2 → 0.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # The TypeScript SDK (`@loams/client`)
4
4
 
5
- > **Preview.** `0.1.0-preview.2` tracks the Loams preview server and may change between previews; pin an exact version. Installed with `npm install @loams/client@preview`.
5
+ > **Preview.** `0.1.0` tracks the Loams preview server and may change between previews; pin an exact version. Installed with `npm install @loams/client@preview`.
6
6
 
7
7
  Design §44 §7 and §10.2: the SDK is a `Loams` object with namespaced modules,
8
8
  generated from the `loams.options.v1` annotations on the protos, over the
@@ -23,6 +23,14 @@ sdks/typescript/
23
23
  generated package — as a workspace dependency and share one lockfile. The
24
24
  generator inputs stay outside the workspace, next to `proto/`.
25
25
 
26
+ ## Install
27
+
28
+ ```sh
29
+ npm i @loams/client # and @loams/live for Live's stubs
30
+ ```
31
+
32
+ `0.1.0` tracks Loams 0.1.0; in 0.x the API may change between minor versions. <!-- verify after publish -->
33
+
26
34
  ## Using it
27
35
 
28
36
  ```ts
@@ -10,7 +10,7 @@ import type { CallOptions } from '../runtime/call.js';
10
10
  import type { AddTeamMemberRequestSchema, AddTeamMemberResponse, CreateAgentRequestSchema, CreateAgentResponse, CreateEnvironmentRequestSchema, CreateEnvironmentResponse, CreateInvitationRequestSchema, CreateInvitationResponse, CreateKeyRequestSchema, CreateKeyResponse, CreateProjectRequestSchema, CreateProjectResponse, CreateServiceAccountRequestSchema, CreateServiceAccountResponse, CreateTeamRequestSchema, CreateTeamResponse, CreateTrustPolicyRequestSchema, CreateTrustPolicyResponse, GetAgentRequestSchema, GetAgentResponse, GetEnvironmentActivityRequestSchema, GetEnvironmentActivityResponse, GetEnvironmentRequestSchema, GetEnvironmentResponse, GetOrgRequestSchema, GetOrgResponse, GetProjectRequestSchema, GetProjectResponse, GetTeamRequestSchema, GetTeamResponse, GrantAccessRequestSchema, GrantAccessResponse, ListAccessRequestSchema, ListAccessResponse, ListAgentTokensRequestSchema, ListAgentTokensResponse, ListAgentsRequestSchema, ListAgentsResponse, ListAuditEventsRequestSchema, ListAuditEventsResponse, ListEnvironmentsRequestSchema, ListEnvironmentsResponse, ListInvitationsRequestSchema, ListInvitationsResponse, ListKeysRequestSchema, ListKeysResponse, ListMembersRequestSchema, ListMembersResponse, ListProjectsRequestSchema, ListProjectsResponse, ListServiceAccountsRequestSchema, ListServiceAccountsResponse, ListTeamsRequestSchema, ListTeamsResponse, ListTrustPoliciesRequestSchema, ListTrustPoliciesResponse, RemoveMemberRequestSchema, RemoveMemberResponse, ResumeAgentRequestSchema, ResumeAgentResponse, RevokeKeyRequestSchema, RevokeKeyResponse, RevokeTokenRequestSchema, RevokeTokenResponse, SuspendAgentRequestSchema, SuspendAgentResponse, UpdateAgentRequestSchema, UpdateAgentResponse, UpdateOrgRequestSchema, UpdateOrgResponse, WatchAuditEventsRequestSchema, WatchAuditEventsResponse } from '../vendor/proto/admin.js';
11
11
  import type { CompleteSetupRequestSchema, CompleteSetupResponse, CreateSessionRequestSchema, CreateSessionResponse, DecideConsentRequestSchema, DecideConsentResponse, DeleteSessionRequestSchema, DeleteSessionResponse, GetSessionRequestSchema, GetSessionResponse, ListProvidersRequestSchema, ListProvidersResponse } from '../vendor/proto/gen/loams/auth/v1/auth_pb.js';
12
12
  import type { GetInstanceRequestSchema, GetInstanceResponse, WhoAmIRequestSchema, WhoAmIResponse } from '../vendor/proto/gen/loams/instance/v1/instance_pb.js';
13
- import type { ActivateDeploymentRequestSchema, ActivateDeploymentResponse, DeployRequestSchema, DeployResponse, GetDeploymentRequestSchema, GetDeploymentResponse, GetIndexStatusRequestSchema, GetIndexStatusResponse, ListDeploymentsRequestSchema, ListDeploymentsResponse, ModifyQuerySetRequestSchema, ModifyQuerySetResponse, MutateRequestSchema, MutateResponse, QueryRequestSchema, QueryResponse, TailLogsRequestSchema, TailLogsResponse, Transition, WatchRequestSchema } from '@loams/live/live';
13
+ import type { ActivateDeploymentRequestSchema, ActivateDeploymentResponse, AuthenticateRequestSchema, AuthenticateResponse, CreateAppRequestSchema, CreateAppResponse, DeleteAppRequestSchema, DeleteAppResponse, DeployRequestSchema, DeployResponse, GetAppRequestSchema, GetAppResponse, GetDeploymentRequestSchema, GetDeploymentResponse, GetIndexStatusRequestSchema, GetIndexStatusResponse, ListAppsRequestSchema, ListAppsResponse, ListDeploymentsRequestSchema, ListDeploymentsResponse, ModifyQuerySetRequestSchema, ModifyQuerySetResponse, MutateRequestSchema, MutateResponse, QueryRequestSchema, QueryResponse, TailLogsRequestSchema, TailLogsResponse, Transition, UpdateAppRequestSchema, UpdateAppResponse, WatchRequestSchema } from '@loams/live/live';
14
14
  /**
15
15
  * `loams.admin.agents` — Agents, their tokens and trust policies, and service accounts.
16
16
  *
@@ -290,6 +290,10 @@ export interface LiveModule {
290
290
  readonly service: 'loams.live.v1.LiveService';
291
291
  /** Whether the package's wire contract may still change. */
292
292
  readonly unstable: true;
293
+ /**
294
+ * `loams.live.v1.LiveService/Authenticate`, retried: manual.
295
+ */
296
+ authenticate(request: MessageInitShape<typeof AuthenticateRequestSchema>, options?: CallOptions): Promise<AuthenticateResponse>;
293
297
  /**
294
298
  * `loams.live.v1.LiveService/ModifyQuerySet`, retried: manual.
295
299
  */
@@ -300,7 +304,7 @@ export interface LiveModule {
300
304
  watch(request: MessageInitShape<typeof WatchRequestSchema>, options?: CallOptions): AsyncIterable<Transition>;
301
305
  }
302
306
  /**
303
- * `loams.live.admin` — Live administration: deploy, roll back, index status and function logs.
307
+ * `loams.live.admin` — Live administration: apps, deploy, roll back, index status and function logs.
304
308
  *
305
309
  * Wraps `loams.live.v1.LiveAdminService`. Its wire contract may still change, so `buf breaking` skips it and an SDK marks it experimental (§44 §10.3).
306
310
  */
@@ -315,10 +319,22 @@ export interface LiveAdminModule {
315
319
  * `loams.live.v1.LiveAdminService/ActivateDeployment`, retried: manual.
316
320
  */
317
321
  activateDeployment(request: MessageInitShape<typeof ActivateDeploymentRequestSchema>, options?: CallOptions): Promise<ActivateDeploymentResponse>;
322
+ /**
323
+ * `loams.live.v1.LiveAdminService/CreateApp`, retried: manual.
324
+ */
325
+ createApp(request: MessageInitShape<typeof CreateAppRequestSchema>, options?: CallOptions): Promise<CreateAppResponse>;
326
+ /**
327
+ * `loams.live.v1.LiveAdminService/DeleteApp`, retried: manual.
328
+ */
329
+ deleteApp(request: MessageInitShape<typeof DeleteAppRequestSchema>, options?: CallOptions): Promise<DeleteAppResponse>;
318
330
  /**
319
331
  * `loams.live.v1.LiveAdminService/Deploy`, retried: manual.
320
332
  */
321
333
  deploy(request: MessageInitShape<typeof DeployRequestSchema>, options?: CallOptions): Promise<DeployResponse>;
334
+ /**
335
+ * `loams.live.v1.LiveAdminService/GetApp`, retried: safe.
336
+ */
337
+ getApp(request: MessageInitShape<typeof GetAppRequestSchema>, options?: CallOptions): Promise<GetAppResponse>;
322
338
  /**
323
339
  * `loams.live.v1.LiveAdminService/GetDeployment`, retried: safe.
324
340
  */
@@ -327,6 +343,10 @@ export interface LiveAdminModule {
327
343
  * `loams.live.v1.LiveAdminService/GetIndexStatus`, retried: safe.
328
344
  */
329
345
  getIndexStatus(request: MessageInitShape<typeof GetIndexStatusRequestSchema>, options?: CallOptions): Promise<GetIndexStatusResponse>;
346
+ /**
347
+ * `loams.live.v1.LiveAdminService/ListApps`, retried: safe. AIP-158: page with `apps` and follow `next_page_token` through `loams.paginate`.
348
+ */
349
+ listApps(request: MessageInitShape<typeof ListAppsRequestSchema>, options?: CallOptions): Promise<ListAppsResponse>;
330
350
  /**
331
351
  * `loams.live.v1.LiveAdminService/ListDeployments`, retried: safe. AIP-158: page with `deployments` and follow `next_page_token` through `loams.paginate`.
332
352
  */
@@ -335,6 +355,10 @@ export interface LiveAdminModule {
335
355
  * `loams.live.v1.LiveAdminService/TailLogs`, retried: manual.
336
356
  */
337
357
  tailLogs(request: MessageInitShape<typeof TailLogsRequestSchema>, options?: CallOptions): AsyncIterable<TailLogsResponse>;
358
+ /**
359
+ * `loams.live.v1.LiveAdminService/UpdateApp`, retried: manual.
360
+ */
361
+ updateApp(request: MessageInitShape<typeof UpdateAppRequestSchema>, options?: CallOptions): Promise<UpdateAppResponse>;
338
362
  }
339
363
  /**
340
364
  * A second facade name for the same RPCs, exposed as `loams.tables`.
@@ -406,7 +430,7 @@ export declare const PROTO_PACKAGES: readonly ["google.protobuf", "loams.admin.v
406
430
  * an API major version a reason is never renamed and never removed, so
407
431
  * this union only grows; a caller switching on it is exhaustive.
408
432
  */
409
- export declare const REASONS: readonly ["approval_expired", "approval_already_decided", "approval_stale_revision", "requester_cannot_approve", "decision_proof_invalid", "step_up_required", "reason_required", "invalid_decision", "pairing_expired", "pairing_used", "device_revoked", "push_target_unknown", "not_implemented", "feature_not_in_variant", "house_not_configured", "house_syntax_error", "house_unknown_table", "house_unknown_database", "house_access_denied", "house_read_only", "house_timeout", "house_memory_limit", "house_too_many_queries", "house_quota_exceeded", "house_disabled_function", "house_cancelled", "house_query_not_found", "house_query_failed", "project_not_found", "branch_has_children", "branch_protected", "lsn_out_of_retention", "endpoint_exists_for_branch", "compute_start_failed", "quota_exceeded", "storage_unavailable", "secret_already_issued", "repo_not_found", "repo_already_exists", "repo_deleting", "ref_stale", "ref_protected", "out_of_scope", "object_format_unsupported", "fork_too_deep", "sequencer_unavailable", "idempotency_key_reused", "workspace_not_found", "workspace_fenced", "workspace_read_only", "workspace_name_taken", "object_missing", "secret_detected", "env_unsealed", "env_access_denied", "env_foreign_reference", "live_bad_cursor", "live_worker_crashed", "live_deploy_conflict", "live_schema_violation", "live_index_not_ready", "role_required", "setup_required", "token_missing", "token_malformed", "token_revoked", "token_not_yet_valid", "token_bad_signature", "token_wrong_audience", "token_wrong_issuer", "token_unknown_key", "token_algorithm_not_allowed", "api_key_invalid", "credential_not_accepted", "credential_in_query_string", "csrf_token_invalid", "principal_not_allowed", "cors_origin_not_allowed", "auth_unavailable", "invalid_argument", "not_found", "already_exists", "permission_denied", "token_expired", "unauthenticated", "failed_precondition", "resource_exhausted", "unavailable", "deadline_exceeded", "aborted", "internal"];
433
+ export declare const REASONS: readonly ["approval_expired", "approval_already_decided", "approval_stale_revision", "requester_cannot_approve", "decision_proof_invalid", "step_up_required", "reason_required", "invalid_decision", "pairing_expired", "pairing_used", "device_revoked", "push_target_unknown", "not_implemented", "feature_not_in_variant", "house_not_configured", "house_syntax_error", "house_unknown_table", "house_unknown_database", "house_access_denied", "house_read_only", "house_timeout", "house_memory_limit", "house_too_many_queries", "house_quota_exceeded", "house_disabled_function", "house_cancelled", "house_query_not_found", "house_query_failed", "project_not_found", "branch_has_children", "branch_protected", "lsn_out_of_retention", "endpoint_exists_for_branch", "compute_start_failed", "quota_exceeded", "storage_unavailable", "secret_already_issued", "repo_not_found", "repo_already_exists", "repo_deleting", "ref_stale", "ref_protected", "out_of_scope", "object_format_unsupported", "fork_too_deep", "sequencer_unavailable", "idempotency_key_reused", "workspace_not_found", "workspace_fenced", "workspace_read_only", "workspace_name_taken", "object_missing", "secret_detected", "env_unsealed", "env_access_denied", "env_foreign_reference", "live_bad_cursor", "live_worker_crashed", "live_deploy_conflict", "live_schema_violation", "live_index_not_ready", "live_app_disabled", "live_app_exists", "live_function_error", "live_function_timeout", "live_function_out_of_memory", "live_limit_exceeded", "live_app_mismatch", "live_origin_not_allowed", "session_rotate", "session_gone", "node_draining", "role_required", "setup_required", "token_missing", "token_malformed", "token_revoked", "token_not_yet_valid", "token_bad_signature", "token_wrong_audience", "token_wrong_issuer", "token_unknown_key", "token_algorithm_not_allowed", "api_key_invalid", "credential_not_accepted", "credential_in_query_string", "csrf_token_invalid", "principal_not_allowed", "cors_origin_not_allowed", "auth_unavailable", "invalid_argument", "not_found", "already_exists", "permission_denied", "token_expired", "unauthenticated", "failed_precondition", "resource_exhausted", "unavailable", "deadline_exceeded", "aborted", "internal"];
410
434
  /** A stable, machine-readable cause of a failed RPC. */
411
435
  export type Reason = (typeof REASONS)[number];
412
436
  /** The Connect code each reason is raised under, from the same registry. */
@@ -140,24 +140,30 @@ export const MODULES = [
140
140
  unstable: true,
141
141
  derived: false,
142
142
  calls: [
143
+ { module: 'live', name: 'authenticate', protoName: 'authenticate', method: 'Authenticate', rpc: 'loams.live.v1.LiveService/Authenticate', service: 'loams.live.v1.LiveService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'unary', pagination: null },
143
144
  { module: 'live', name: 'modifyQuerySet', protoName: 'modifyQuerySet', method: 'ModifyQuerySet', rpc: 'loams.live.v1.LiveService/ModifyQuerySet', service: 'loams.live.v1.LiveService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'unary', pagination: null },
144
145
  { module: 'live', name: 'watch', protoName: 'watch', method: 'Watch', rpc: 'loams.live.v1.LiveService/Watch', service: 'loams.live.v1.LiveService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'server', pagination: null },
145
146
  ],
146
147
  },
147
148
  {
148
149
  name: 'live.admin',
149
- summary: 'Live administration: deploy, roll back, index status and function logs.',
150
+ summary: 'Live administration: apps, deploy, roll back, index status and function logs.',
150
151
  service: 'loams.live.v1.LiveAdminService',
151
152
  package: 'loams.live.v1',
152
153
  unstable: true,
153
154
  derived: false,
154
155
  calls: [
155
156
  { module: 'live.admin', name: 'activateDeployment', protoName: 'activateDeployment', method: 'ActivateDeployment', rpc: 'loams.live.v1.LiveAdminService/ActivateDeployment', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'unary', pagination: null },
157
+ { module: 'live.admin', name: 'createApp', protoName: 'createApp', method: 'CreateApp', rpc: 'loams.live.v1.LiveAdminService/CreateApp', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'unary', pagination: null },
158
+ { module: 'live.admin', name: 'deleteApp', protoName: 'deleteApp', method: 'DeleteApp', rpc: 'loams.live.v1.LiveAdminService/DeleteApp', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'unary', pagination: null },
156
159
  { module: 'live.admin', name: 'deploy', protoName: 'deploy', method: 'Deploy', rpc: 'loams.live.v1.LiveAdminService/Deploy', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'unary', pagination: null },
160
+ { module: 'live.admin', name: 'getApp', protoName: 'getApp', method: 'GetApp', rpc: 'loams.live.v1.LiveAdminService/GetApp', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'safe', streaming: 'unary', pagination: null },
157
161
  { module: 'live.admin', name: 'getDeployment', protoName: 'getDeployment', method: 'GetDeployment', rpc: 'loams.live.v1.LiveAdminService/GetDeployment', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'safe', streaming: 'unary', pagination: null },
158
162
  { module: 'live.admin', name: 'getIndexStatus', protoName: 'getIndexStatus', method: 'GetIndexStatus', rpc: 'loams.live.v1.LiveAdminService/GetIndexStatus', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'safe', streaming: 'unary', pagination: null },
163
+ { module: 'live.admin', name: 'listApps', protoName: 'listApps', method: 'ListApps', rpc: 'loams.live.v1.LiveAdminService/ListApps', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'safe', streaming: 'unary', pagination: { items: 'apps', nextPageToken: 'nextPageToken' } },
159
164
  { module: 'live.admin', name: 'listDeployments', protoName: 'listDeployments', method: 'ListDeployments', rpc: 'loams.live.v1.LiveAdminService/ListDeployments', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'safe', streaming: 'unary', pagination: { items: 'deployments', nextPageToken: 'nextPageToken' } },
160
165
  { module: 'live.admin', name: 'tailLogs', protoName: 'tailLogs', method: 'TailLogs', rpc: 'loams.live.v1.LiveAdminService/TailLogs', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'server', pagination: null },
166
+ { module: 'live.admin', name: 'updateApp', protoName: 'updateApp', method: 'UpdateApp', rpc: 'loams.live.v1.LiveAdminService/UpdateApp', service: 'loams.live.v1.LiveAdminService', package: 'loams.live.v1', idempotency: 'none', retry: 'manual', streaming: 'unary', pagination: null },
161
167
  ],
162
168
  },
163
169
  {
@@ -277,6 +283,17 @@ export const REASONS = [
277
283
  'live_deploy_conflict',
278
284
  'live_schema_violation',
279
285
  'live_index_not_ready',
286
+ 'live_app_disabled',
287
+ 'live_app_exists',
288
+ 'live_function_error',
289
+ 'live_function_timeout',
290
+ 'live_function_out_of_memory',
291
+ 'live_limit_exceeded',
292
+ 'live_app_mismatch',
293
+ 'live_origin_not_allowed',
294
+ 'session_rotate',
295
+ 'session_gone',
296
+ 'node_draining',
280
297
  'role_required',
281
298
  'setup_required',
282
299
  'token_missing',
@@ -371,6 +388,17 @@ export const REASON_CODES = {
371
388
  live_deploy_conflict: 'failed_precondition',
372
389
  live_schema_violation: 'invalid_argument',
373
390
  live_index_not_ready: 'failed_precondition',
391
+ live_app_disabled: 'failed_precondition',
392
+ live_app_exists: 'failed_precondition',
393
+ live_function_error: 'unknown',
394
+ live_function_timeout: 'deadline_exceeded',
395
+ live_function_out_of_memory: 'resource_exhausted',
396
+ live_limit_exceeded: 'resource_exhausted',
397
+ live_app_mismatch: 'permission_denied',
398
+ live_origin_not_allowed: 'permission_denied',
399
+ session_rotate: 'unavailable',
400
+ session_gone: 'not_found',
401
+ node_draining: 'unavailable',
374
402
  role_required: 'permission_denied',
375
403
  setup_required: 'failed_precondition',
376
404
  token_missing: 'unauthenticated',
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { Loams, type LoamsModules, type LoamsOptions } from './loams.js';
1
+ export { Loams, type AdminNamespace, type LiveNamespace, type LoamsModules, type LoamsOptions, } from './loams.js';
2
2
  export { SystemApi, type Catalogue, type SystemConfig, type VersionReport, } from './system.js';
3
3
  export { FEATURE_NOT_IN_VARIANT, MODULES, PROTO_PACKAGES, PROTO_REV, REASON_CODES, REASONS, SERVICE_DESCRIPTORS, type CallBinding, type InstanceModule, type LiveModule, type ModuleBinding, type Reason, type TablesModule, } from './gen/facade.js';
4
4
  export { CallInvoker, callWithRetry, withIdempotencyKey, type Attempt, type CallOptions, type ConsistencyOptions, type ConsistencyTokenStore, type RetryPlan, type Send, } from './runtime/call.js';
@@ -8,5 +8,5 @@ export { paginate, pageFields, type PageFetcher, type PageRequestOptions } from
8
8
  export { BASE_DELAY_MS, DEFAULT_MAX_RETRIES, MAX_DELAY_MS, MAX_SERVER_DELAY_MS, backoffMs, isRetryableCode, shouldRetry, sleep, } from './runtime/retry.js';
9
9
  export { watch, type CursorOf, type ResumeOptions, type StreamOpener } from './runtime/streams.js';
10
10
  export { apiKey, envToken, oidcExchange, refreshing, staticToken, type TokenSource, } from './runtime/token-source.js';
11
- export { createLoamsTransport, type TransportOptions } from './runtime/transports.js';
11
+ export { createLoamsTransport, headersInterceptor, type TransportOptions, } from './runtime/transports.js';
12
12
  export { uuidv7, uuidv7Time } from './runtime/uuidv7.js';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@
14
14
  // What a caller imports from here: the `Loams` client, the module types the
15
15
  // generator produced, the typed error hierarchy, the token sources, and the
16
16
  // reason registry as a type.
17
- export { Loams } from './loams.js';
17
+ export { Loams, } from './loams.js';
18
18
  export { SystemApi, } from './system.js';
19
19
  // The generated facade: the module interfaces, the binding table, the proto
20
20
  // revision, and the reason registry as a type. Everything here is written by
@@ -28,5 +28,5 @@ export { paginate, pageFields } from './runtime/pagination.js';
28
28
  export { BASE_DELAY_MS, DEFAULT_MAX_RETRIES, MAX_DELAY_MS, MAX_SERVER_DELAY_MS, backoffMs, isRetryableCode, shouldRetry, sleep, } from './runtime/retry.js';
29
29
  export { watch } from './runtime/streams.js';
30
30
  export { apiKey, envToken, oidcExchange, refreshing, staticToken, } from './runtime/token-source.js';
31
- export { createLoamsTransport } from './runtime/transports.js';
31
+ export { createLoamsTransport, headersInterceptor, } from './runtime/transports.js';
32
32
  export { uuidv7, uuidv7Time } from './runtime/uuidv7.js';
package/dist/loams.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Transport } from '@connectrpc/connect';
2
- import { type CallBinding, type InstanceModule, type LiveModule, type ModuleBinding, type TablesModule } from './gen/facade.js';
2
+ import { type AdminAgentsModule, type AdminAuditModule, type AdminKeysModule, type AdminOrgModule, type AdminProjectsModule, type AuthModule, type CallBinding, type InstanceModule, type LiveAdminModule, type LiveModule, type ModuleBinding, type TablesModule } from './gen/facade.js';
3
3
  import { type CallOptions, type ConsistencyTokenStore } from './runtime/call.js';
4
4
  import { type PageRequestOptions } from './runtime/pagination.js';
5
5
  import { SystemApi } from './system.js';
@@ -51,18 +51,38 @@ export interface LoamsModules {
51
51
  readonly tables: TablesModule;
52
52
  readonly [module: string]: unknown;
53
53
  }
54
+ /** `loams.live`: the session calls, with `loams.live.admin` under it. */
55
+ export type LiveNamespace = LiveModule & {
56
+ /** `loams.live.admin` — apps, deploy, roll back, index status and logs. */
57
+ readonly admin: LiveAdminModule;
58
+ };
59
+ /** `loams.admin`: the console's administration modules (design §44 §7.2). */
60
+ export interface AdminNamespace {
61
+ readonly agents: AdminAgentsModule;
62
+ readonly audit: AdminAuditModule;
63
+ readonly keys: AdminKeysModule;
64
+ readonly org: AdminOrgModule;
65
+ readonly projects: AdminProjectsModule;
66
+ }
54
67
  /** One SDK, over one instance. */
55
68
  export declare class Loams {
56
69
  #private;
57
70
  /** `loams.instance` — what this instance is, and who the caller is. */
58
71
  readonly instance: InstanceModule;
59
- /** `loams.live` — the live sync session half. Its package is `unstable`. */
60
- readonly live: LiveModule;
72
+ /** `loams.live` — the live sync session half, and `loams.live.admin`.
73
+ * Its package is `unstable`. */
74
+ readonly live: LiveNamespace;
61
75
  /** `loams.tables` — the table half of the same service (design §44 §7.2). */
62
76
  readonly tables: TablesModule;
77
+ /** `loams.admin` — org, projects, agents, keys and audit. */
78
+ readonly admin: AdminNamespace;
79
+ /** `loams.auth` — sessions and sign-in. */
80
+ readonly auth: AuthModule;
63
81
  /** The module catalogue, feature detection and the version check. */
64
82
  readonly system: SystemApi;
65
- /** Every generated module, by name: the catalogue a caller iterates. */
83
+ /** Every generated module, by its dotted name (`'live.admin'`): the
84
+ * catalogue a caller iterates. The same objects are reachable as
85
+ * properties, `loams.live.admin` for `'live.admin'`. */
66
86
  readonly modules: Readonly<Record<string, unknown>>;
67
87
  constructor(options: LoamsOptions);
68
88
  /** The session consistency token store, when `sessionConsistency` is on. */
package/dist/loams.js CHANGED
@@ -29,13 +29,20 @@ import { watch } from './runtime/streams.js';
29
29
  export class Loams {
30
30
  /** `loams.instance` — what this instance is, and who the caller is. */
31
31
  instance;
32
- /** `loams.live` — the live sync session half. Its package is `unstable`. */
32
+ /** `loams.live` — the live sync session half, and `loams.live.admin`.
33
+ * Its package is `unstable`. */
33
34
  live;
34
35
  /** `loams.tables` — the table half of the same service (design §44 §7.2). */
35
36
  tables;
37
+ /** `loams.admin` — org, projects, agents, keys and audit. */
38
+ admin;
39
+ /** `loams.auth` — sessions and sign-in. */
40
+ auth;
36
41
  /** The module catalogue, feature detection and the version check. */
37
42
  system;
38
- /** Every generated module, by name: the catalogue a caller iterates. */
43
+ /** Every generated module, by its dotted name (`'live.admin'`): the
44
+ * catalogue a caller iterates. The same objects are reachable as
45
+ * properties, `loams.live.admin` for `'live.admin'`. */
39
46
  modules;
40
47
  #invoker;
41
48
  #consistency;
@@ -54,9 +61,12 @@ export class Loams {
54
61
  this.#consistency = options.sessionConsistency === true ? new ConsistencySession() : undefined;
55
62
  this.#invoker = new CallInvoker(transport, tokenSource, options.maxRetries ?? DEFAULT_MAX_RETRIES, this.#consistency);
56
63
  this.modules = buildModules(this.#invoker);
57
- this.instance = this.modules.instance;
58
- this.live = this.modules.live;
59
- this.tables = this.modules.tables;
64
+ const tree = nestModules(this.modules);
65
+ this.instance = tree.instance;
66
+ this.live = tree.live;
67
+ this.tables = tree.tables;
68
+ this.admin = tree.admin;
69
+ this.auth = tree.auth;
60
70
  this.system = new SystemApi((request, callOptions) => this.instance.getInstance(request, callOptions), {
61
71
  endpoint: options.endpoint,
62
72
  maxRetries: options.maxRetries,
@@ -155,3 +165,39 @@ function buildModules(invoker) {
155
165
  }
156
166
  return modules;
157
167
  }
168
+ /**
169
+ * The module tree a dotted name implies: `'live.admin'` becomes `live.admin`
170
+ * and `'admin.org'` becomes `admin.org`.
171
+ *
172
+ * A child is attached to its parent module object when the parent exists
173
+ * (`live` is a module with calls of its own), and to a plain namespace object
174
+ * when it does not (`admin` has only children). The flat catalogue is left as
175
+ * it is; the tree reuses its objects, so `loams.live.admin` and
176
+ * `loams.modules['live.admin']` are the same object.
177
+ */
178
+ function nestModules(flat) {
179
+ const tree = {};
180
+ // Parents before children, so a module with calls of its own is the node
181
+ // its children hang from rather than being replaced by a namespace.
182
+ const names = Object.keys(flat).sort((a, b) => a.split('.').length - b.split('.').length);
183
+ for (const name of names) {
184
+ const path = name.split('.');
185
+ const leaf = path.pop();
186
+ let node = tree;
187
+ for (const part of path) {
188
+ let next = node[part];
189
+ if (next === undefined) {
190
+ next = {};
191
+ node[part] = next;
192
+ }
193
+ node = next;
194
+ }
195
+ if (leaf in node) {
196
+ throw new LoamsError(`the module ${name} collides with a call of the same name`, {
197
+ code: Code.Internal,
198
+ });
199
+ }
200
+ node[leaf] = flat[name];
201
+ }
202
+ return tree;
203
+ }
package/dist/node.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Transport } from '@connectrpc/connect';
2
- import type { TransportOptions } from './runtime/transports.js';
2
+ import { type TransportOptions } from './runtime/transports.js';
3
3
  export * from './index.js';
4
4
  /**
5
5
  * HTTP/2 gRPC, over `node:http2`.
package/dist/node.js CHANGED
@@ -20,6 +20,7 @@
20
20
  // down. Prefer this one on a loopback stack or inside the cluster; prefer the
21
21
  // default one in a browser, an edge function, or behind an HTTP/1.1 proxy.
22
22
  import { createGrpcTransport } from '@connectrpc/connect-node';
23
+ import { transportInterceptors } from './runtime/transports.js';
23
24
  export * from './index.js';
24
25
  /**
25
26
  * HTTP/2 gRPC, over `node:http2`.
@@ -30,13 +31,13 @@ export * from './index.js';
30
31
  * retries.
31
32
  */
32
33
  export function createNodeTransport(options = {}) {
34
+ const interceptors = transportInterceptors(options);
33
35
  return createGrpcTransport({
34
36
  baseUrl: options.baseUrl ?? '',
35
37
  useBinaryFormat: options.useBinaryFormat ?? true,
36
- ...(options.headers === undefined ? {} : { headers: options.headers }),
37
38
  ...(options.defaultTimeoutMs === undefined
38
39
  ? {}
39
40
  : { defaultTimeoutMs: options.defaultTimeoutMs }),
40
- ...(options.interceptors === undefined ? {} : { interceptors: options.interceptors }),
41
+ ...(interceptors.length === 0 ? {} : { interceptors }),
41
42
  });
42
43
  }
@@ -1,5 +1,5 @@
1
1
  import { createConnectTransport } from '@connectrpc/connect-web';
2
- import type { Transport } from '@connectrpc/connect';
2
+ import type { Interceptor, Transport } from '@connectrpc/connect';
3
3
  /** What a caller may configure on the transport. */
4
4
  export interface TransportOptions {
5
5
  /**
@@ -7,7 +7,13 @@ export interface TransportOptions {
7
7
  * `endpoint`, so a caller building a transport by hand rarely needs it.
8
8
  */
9
9
  baseUrl?: string;
10
- /** Extra headers on every request, for a gateway or a proxy. */
10
+ /**
11
+ * Extra headers on every request, unary and streaming: for a gateway, a
12
+ * proxy, or a routing header such as the Live app a call is for. They are
13
+ * attached by an interceptor (`headersInterceptor`), because neither
14
+ * connect-web's nor connect-node's transport has a `headers` option; a
15
+ * header the call already sets (a credential, a per-call header) wins.
16
+ */
11
17
  headers?: Record<string, string>;
12
18
  /**
13
19
  * `useBinaryFormat` picks the encoding: `true` is protobuf, `false` is the
@@ -37,3 +43,16 @@ export interface TransportOptions {
37
43
  * case, not a fallback: it is the default in every runtime.
38
44
  */
39
45
  export declare function createLoamsTransport(options?: TransportOptions): Transport;
46
+ /**
47
+ * An interceptor that sets `headers` on every request, unary and streaming.
48
+ *
49
+ * A header already on the request is left alone, so a per-call header or the
50
+ * credential the invoker attaches is never overwritten by a static default.
51
+ */
52
+ export declare function headersInterceptor(headers: Record<string, string>): Interceptor;
53
+ /**
54
+ * The interceptors a transport built from `options` runs: the static headers
55
+ * first (outermost), then the caller's own, so a caller's interceptor sees the
56
+ * headers and may still change them.
57
+ */
58
+ export declare function transportInterceptors(options: TransportOptions): Interceptor[];
@@ -26,13 +26,41 @@ import { createConnectTransport } from '@connectrpc/connect-web';
26
26
  * case, not a fallback: it is the default in every runtime.
27
27
  */
28
28
  export function createLoamsTransport(options = {}) {
29
+ const interceptors = transportInterceptors(options);
29
30
  return createConnectTransport({
30
31
  baseUrl: options.baseUrl ?? '',
31
32
  useBinaryFormat: options.useBinaryFormat ?? true,
32
- ...(options.headers === undefined ? {} : { headers: options.headers }),
33
33
  ...(options.defaultTimeoutMs === undefined
34
34
  ? {}
35
35
  : { defaultTimeoutMs: options.defaultTimeoutMs }),
36
- ...(options.interceptors === undefined ? {} : { interceptors: options.interceptors }),
36
+ ...(interceptors.length === 0 ? {} : { interceptors }),
37
37
  });
38
38
  }
39
+ /**
40
+ * An interceptor that sets `headers` on every request, unary and streaming.
41
+ *
42
+ * A header already on the request is left alone, so a per-call header or the
43
+ * credential the invoker attaches is never overwritten by a static default.
44
+ */
45
+ export function headersInterceptor(headers) {
46
+ const entries = Object.entries(headers);
47
+ return (next) => (request) => {
48
+ for (const [name, value] of entries) {
49
+ if (!request.header.has(name)) {
50
+ request.header.set(name, value);
51
+ }
52
+ }
53
+ return next(request);
54
+ };
55
+ }
56
+ /**
57
+ * The interceptors a transport built from `options` runs: the static headers
58
+ * first (outermost), then the caller's own, so a caller's interceptor sees the
59
+ * headers and may still change them.
60
+ */
61
+ export function transportInterceptors(options) {
62
+ const headers = options.headers === undefined || Object.keys(options.headers).length === 0
63
+ ? []
64
+ : [headersInterceptor(options.headers)];
65
+ return [...headers, ...(options.interceptors ?? [])];
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loams/client",
3
- "version": "0.1.0-preview.2",
3
+ "version": "0.1.0",
4
4
  "description": "The Loams SDK for TypeScript and JavaScript: one Loams object with namespaced modules over the unified Connect API, generated from proto/.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/ostrium-labs/loams/tree/dev/sdks/typescript",
@@ -43,7 +43,7 @@
43
43
  "@connectrpc/connect": "2.2.0",
44
44
  "@connectrpc/connect-node": "2.2.0",
45
45
  "@connectrpc/connect-web": "2.2.0",
46
- "@loams/live": "0.1.0-preview.2"
46
+ "@loams/live": "0.1.0"
47
47
  },
48
48
  "publishConfig": {
49
49
  "access": "public"