@qnsp/storage-sdk 0.0.1

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.
@@ -0,0 +1,5 @@
1
+
2
+ 
3
+ > @qnsp/storage-sdk@0.0.1 build /Volumes/ProjectQNSP/QNSP/packages/storage-sdk
4
+ > tsc --project tsconfig.build.json
5
+
@@ -0,0 +1,6 @@
1
+
2
+ 
3
+ > @qnsp/storage-sdk@0.0.1 lint /Volumes/ProjectQNSP/QNSP/packages/storage-sdk
4
+ > biome check .
5
+
6
+ Checked 7 files in 8ms. No fixes applied.
@@ -0,0 +1,41 @@
1
+
2
+ 
3
+ > @qnsp/storage-sdk@0.0.1 test /Volumes/ProjectQNSP/QNSP/packages/storage-sdk
4
+ > vitest run
5
+
6
+ [?25l
7
+ RUN v4.0.13 /Volumes/ProjectQNSP/QNSP/packages/storage-sdk
8
+
9
+ [?2026h
10
+ ❯ src/index.test.ts [queued]
11
+
12
+ Test Files 0 passed (1)
13
+ Tests 0 passed (0)
14
+ Start at 02:56:47
15
+ Duration 0ms
16
+ [?2026l[?2026h
17
+ ❯ src/index.test.ts 0/9
18
+
19
+ Test Files 0 passed (1)
20
+ Tests 0 passed (9)
21
+ Start at 02:56:47
22
+ Duration 201ms
23
+ [?2026l ✓ src/index.test.ts (9 tests) 15ms
24
+ ✓ StorageClient (8)
25
+ ✓ initiates an upload with authorization and sensible defaults 9ms
26
+ ✓ uploads binary parts using streaming semantics 1ms
27
+ ✓ parses ranged download responses and surfaces stream metadata 1ms
28
+ ✓ records telemetry for successful requests 0ms
29
+ ✓ records telemetry failures 1ms
30
+ ✓ records bytes for upload parts 0ms
31
+ ✓ updates and fetches document policies with x-tenant-id header 0ms
32
+ ✓ applies and releases legal holds 0ms
33
+ ✓ StorageEventsClient (1)
34
+ ✓ records telemetry when fetching events 1ms
35
+
36
+ Test Files 1 passed (1)
37
+ Tests 9 passed (9)
38
+ Start at 02:56:47
39
+ Duration 221ms (transform 59ms, setup 0ms, collect 130ms, tests 15ms, environment 0ms, prepare 2ms)
40
+
41
+ [?25h
@@ -0,0 +1,5 @@
1
+
2
+ 
3
+ > @qnsp/storage-sdk@0.0.1 typecheck /Volumes/ProjectQNSP/QNSP/packages/storage-sdk
4
+ > tsc --project tsconfig.json --noEmit
5
+
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @qnsp/storage-sdk
2
+
3
+ TypeScript SDK for the QNSP storage service. Supports multipart uploads, downloads, lifecycle
4
+ policies, legal holds, compliance metadata, and event subscriptions.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ pnpm add @qnsp/storage-sdk
10
+ ```
11
+
12
+ ## Authentication
13
+
14
+ Authenticate with a **service token** (issued by `auth-service` or the cloud portal API key UI) and
15
+ pass it to `apiKey`. Set `tenantId` to scope quotas and telemetry labels.
16
+
17
+ ```ts
18
+ import { StorageClient, createStorageClientTelemetry } from "@qnsp/storage-sdk";
19
+
20
+ const storage = new StorageClient({
21
+ baseUrl: "https://storage.qnsp.cuilabs.io",
22
+ apiKey: process.env.QNSP_SERVICE_TOKEN!,
23
+ tenantId: "tenant_123",
24
+ telemetry: createStorageClientTelemetry({
25
+ serviceName: "storage-uploader",
26
+ serviceVersion: "1.0.0",
27
+ otlpEndpoint: process.env.OTLP_ENDPOINT!,
28
+ }),
29
+ });
30
+ ```
31
+
32
+ ## Tier requirements
33
+
34
+ | Capability | Minimum tier | Notes |
35
+ |------------|--------------|-------|
36
+ | Upload/download, lifecycle, compliance | `free` | Included in Always Free tier (5GB, 2,000 API calls) |
37
+ | Extended storage quotas | Based on paid tier | Limits enforced by backend using `@qnsp/shared-kernel` |
38
+
39
+ All tenants can instantiate the SDK, but exceeding tier quotas triggers backend `TierError`
40
+ responses. Upgrade at <https://cloud.qnsp.cuilabs.io/billing>.
41
+
42
+ ## Usage example
43
+
44
+ ```ts
45
+ import {
46
+ StorageClient,
47
+ StorageEventsClient,
48
+ createStorageClientTelemetry,
49
+ } from "@qnsp/storage-sdk";
50
+
51
+ const client = new StorageClient({
52
+ baseUrl: "https://storage.example.com",
53
+ apiKey: process.env.QNSP_SERVICE_TOKEN!,
54
+ tenantId: "tenant_123",
55
+ });
56
+
57
+ const upload = await client.initiateUpload({
58
+ name: "document.pdf",
59
+ mimeType: "application/pdf",
60
+ sizeBytes: 1024 * 1024,
61
+ classification: "confidential",
62
+ });
63
+
64
+ await client.uploadPart(upload.uploadId, 1, part1Data);
65
+ await client.uploadPart(upload.uploadId, 2, part2Data);
66
+
67
+ const result = await client.completeUpload(upload.uploadId);
68
+ const stream = await client.downloadStream(result.documentId, result.version);
69
+
70
+ const events = new StorageEventsClient({ baseUrl: "https://storage.example.com" });
71
+ const replicationEvents = await events.fetchEvents("storage.document.replicated");
72
+ ```
73
+
74
+ ## Telemetry
75
+
76
+ Pass the optional `telemetry` property (either an instance or `createStorageClientTelemetry`
77
+ configuration) to emit OpenTelemetry metrics via OTLP HTTP exporter. Metrics include:
78
+
79
+ - `storage_sdk_requests_total`
80
+ - `storage_sdk_request_failures_total`
81
+ - `storage_sdk_request_duration_ms`
82
+ - `storage_sdk_bytes_total`
83
+
84
+ See `docs/observability/portal-dashboards.md` for dashboards powered by these metrics.
85
+
86
+ ## Related documentation
87
+
88
+ - [Developer onboarding guide](../../docs/guides/developer-onboarding.md#sdk-quick-links)
89
+ - [Storage service plan](../../docs/service-plans/storage-service-plan.md)
90
+ - [Tier limits](../shared-kernel/src/tier-limits.ts)
91
+
92
+ © 2025 QNSP - CUI LABS, Singapore
93
+
@@ -0,0 +1,47 @@
1
+ import type { EventEnvelope } from "@qnsp/events";
2
+ import type { StorageClientTelemetry, StorageClientTelemetryConfig } from "./observability.js";
3
+ type DocumentSearchEvent = EventEnvelope<{
4
+ documentId: string;
5
+ tenantId: string;
6
+ version: number;
7
+ checksumSha3: string;
8
+ occurredAt: string;
9
+ }>;
10
+ type UsageEvent = EventEnvelope<{
11
+ tenantId: string;
12
+ documentId?: string;
13
+ version?: number;
14
+ occurredAt: string;
15
+ operation: "upload" | "download";
16
+ sizeBytes: number;
17
+ tier: string;
18
+ durationMs?: number | null;
19
+ }>;
20
+ type BillingEvent = EventEnvelope<{
21
+ tenantId: string;
22
+ meterType: "storage" | "egress" | "api_call" | string;
23
+ quantity: number;
24
+ unit: string;
25
+ metadata?: Record<string, unknown>;
26
+ occurredAt: string;
27
+ }>;
28
+ export type StorageEvent = DocumentSearchEvent | UsageEvent | BillingEvent;
29
+ export interface StorageEventsConfig {
30
+ readonly baseUrl: string;
31
+ readonly apiKey?: string;
32
+ readonly timeoutMs?: number;
33
+ readonly telemetry?: StorageClientTelemetry | StorageClientTelemetryConfig;
34
+ }
35
+ export declare class StorageEventsClient {
36
+ private readonly config;
37
+ private readonly telemetry;
38
+ private readonly targetService;
39
+ constructor(config: StorageEventsConfig);
40
+ fetchEvents(topic: string, options?: {
41
+ since?: string;
42
+ limit?: number;
43
+ }): Promise<StorageEvent[]>;
44
+ private recordTelemetryEvent;
45
+ }
46
+ export {};
47
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EACX,sBAAsB,EACtB,4BAA4B,EAE5B,MAAM,oBAAoB,CAAC;AAG5B,KAAK,mBAAmB,GAAG,aAAa,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,KAAK,UAAU,GAAG,aAAa,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,QAAQ,GAAG,UAAU,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC,CAAC;AAEH,KAAK,YAAY,GAAG,aAAa,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3E,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,GAAG,4BAA4B,CAAC;CAC3E;AAQD,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,MAAM,EAAE,mBAAmB;IAoBjC,WAAW,CAChB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC1C,OAAO,CAAC,YAAY,EAAE,CAAC;IAuG1B,OAAO,CAAC,oBAAoB;CAM5B"}
package/dist/events.js ADDED
@@ -0,0 +1,124 @@
1
+ import { performance } from "node:perf_hooks";
2
+ import { createEventEnvelope } from "@qnsp/events";
3
+ import { createStorageClientTelemetry, isStorageClientTelemetry } from "./observability.js";
4
+ export class StorageEventsClient {
5
+ config;
6
+ telemetry;
7
+ targetService;
8
+ constructor(config) {
9
+ this.config = {
10
+ baseUrl: config.baseUrl.replace(/\/$/, ""),
11
+ apiKey: config.apiKey ?? "",
12
+ timeoutMs: config.timeoutMs ?? 15_000,
13
+ };
14
+ this.telemetry = config.telemetry
15
+ ? isStorageClientTelemetry(config.telemetry)
16
+ ? config.telemetry
17
+ : createStorageClientTelemetry(config.telemetry)
18
+ : null;
19
+ try {
20
+ this.targetService = new URL(this.config.baseUrl).host;
21
+ }
22
+ catch {
23
+ this.targetService = "storage-service";
24
+ }
25
+ }
26
+ async fetchEvents(topic, options) {
27
+ const params = new URLSearchParams();
28
+ if (options?.since)
29
+ params.set("since", options.since);
30
+ if (options?.limit)
31
+ params.set("limit", options.limit.toString());
32
+ const url = `${this.config.baseUrl}/storage/internal/events/${encodeURIComponent(topic)}${params.size > 0 ? `?${params}` : ""}`;
33
+ const headers = {
34
+ Accept: "application/json",
35
+ };
36
+ if (this.config.apiKey) {
37
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
38
+ }
39
+ const controller = new AbortController();
40
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeoutMs);
41
+ const start = performance.now();
42
+ let status = "ok";
43
+ let httpStatus;
44
+ let errorMessage;
45
+ let bytesReceived;
46
+ const route = "/storage/internal/events/:topic";
47
+ try {
48
+ const response = await fetch(url, {
49
+ method: "GET",
50
+ headers,
51
+ signal: controller.signal,
52
+ });
53
+ clearTimeout(timeoutId);
54
+ httpStatus = response.status;
55
+ if (!response.ok) {
56
+ status = "error";
57
+ const errorText = await response.text().catch(() => "unknown error");
58
+ errorMessage = errorText;
59
+ throw new Error(`Event fetch failed: ${response.status} ${response.statusText} - ${errorText}`);
60
+ }
61
+ bytesReceived = Number.parseInt(response.headers.get("Content-Length") ?? "0", 10);
62
+ const payload = (await response.json());
63
+ return payload.map((entry) => {
64
+ const metadataSource = entry.metadata && typeof entry.metadata === "object" ? entry.metadata : undefined;
65
+ const normalizedMetadata = metadataSource !== undefined
66
+ ? {
67
+ timestamp: typeof metadataSource["timestamp"] === "string"
68
+ ? metadataSource["timestamp"]
69
+ : new Date().toISOString(),
70
+ ...(typeof metadataSource["correlationId"] === "string"
71
+ ? { correlationId: metadataSource["correlationId"] }
72
+ : {}),
73
+ ...(typeof metadataSource["causationId"] === "string"
74
+ ? { causationId: metadataSource["causationId"] }
75
+ : {}),
76
+ ...(typeof metadataSource["tenantId"] === "string"
77
+ ? { tenantId: metadataSource["tenantId"] }
78
+ : {}),
79
+ }
80
+ : { timestamp: new Date().toISOString() };
81
+ return createEventEnvelope({
82
+ topic: entry.topic,
83
+ version: entry.version,
84
+ payload: entry.payload,
85
+ metadata: normalizedMetadata,
86
+ });
87
+ });
88
+ }
89
+ catch (error) {
90
+ clearTimeout(timeoutId);
91
+ status = "error";
92
+ if (!errorMessage && error instanceof Error) {
93
+ errorMessage = error.message;
94
+ }
95
+ if (error instanceof Error && error.name === "AbortError") {
96
+ errorMessage = `timeout after ${this.config.timeoutMs}ms`;
97
+ throw new Error(`Event request timeout after ${this.config.timeoutMs}ms`);
98
+ }
99
+ throw error;
100
+ }
101
+ finally {
102
+ const durationMs = performance.now() - start;
103
+ const event = {
104
+ operation: `fetchEvents(${topic})`,
105
+ method: "GET",
106
+ route,
107
+ target: this.targetService,
108
+ status,
109
+ durationMs,
110
+ ...(typeof httpStatus === "number" ? { httpStatus } : {}),
111
+ ...(status === "error" && errorMessage ? { error: errorMessage } : {}),
112
+ ...(typeof bytesReceived === "number" && bytesReceived > 0 ? { bytesReceived } : {}),
113
+ };
114
+ this.recordTelemetryEvent(event);
115
+ }
116
+ }
117
+ recordTelemetryEvent(event) {
118
+ if (!this.telemetry) {
119
+ return;
120
+ }
121
+ this.telemetry.record(event);
122
+ }
123
+ }
124
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,202 @@
1
+ import type { StorageClientTelemetry, StorageClientTelemetryConfig } from "./observability.js";
2
+ /**
3
+ * @qnsp/storage-sdk
4
+ *
5
+ * TypeScript SDK client for the QNSP storage-service API.
6
+ * Provides a high-level interface for document upload, download, and management operations.
7
+ */
8
+ export interface StorageClientConfig {
9
+ readonly baseUrl: string;
10
+ readonly apiKey?: string;
11
+ readonly tenantId: string;
12
+ readonly timeoutMs?: number;
13
+ readonly telemetry?: StorageClientTelemetry | StorageClientTelemetryConfig;
14
+ }
15
+ export interface InitiateUploadOptions {
16
+ readonly name: string;
17
+ readonly mimeType: string;
18
+ readonly sizeBytes: number;
19
+ readonly classification?: string;
20
+ readonly metadata?: Record<string, unknown>;
21
+ readonly tags?: readonly string[];
22
+ readonly retentionPolicy?: {
23
+ readonly mode?: "compliance" | "governance" | null;
24
+ readonly retainUntil?: string | null;
25
+ readonly legalHolds?: readonly string[];
26
+ };
27
+ }
28
+ export interface UploadPartResult {
29
+ readonly uploadId: string;
30
+ readonly partId: number;
31
+ readonly status: string;
32
+ readonly sizeBytes: number;
33
+ readonly checksumSha3: string;
34
+ readonly retries: number;
35
+ readonly totalParts: number;
36
+ readonly completedParts: number;
37
+ readonly bytesReceived: number;
38
+ readonly lastPartNumber: number;
39
+ readonly resumeToken: string | null;
40
+ readonly scan?: {
41
+ readonly status: string;
42
+ readonly signature: string | null;
43
+ readonly engine: string | null;
44
+ };
45
+ }
46
+ export interface CompleteUploadResult {
47
+ readonly documentId: string;
48
+ readonly tenantId: string;
49
+ readonly version: number;
50
+ readonly sizeBytes: number;
51
+ readonly checksumSha3: string;
52
+ readonly parts: readonly {
53
+ readonly partId: number;
54
+ readonly checksumSha3: string;
55
+ readonly sizeBytes: number;
56
+ }[];
57
+ readonly downloadManifest: unknown;
58
+ readonly cdnDownload?: {
59
+ readonly url: string;
60
+ readonly expiresAt: string;
61
+ readonly token: string;
62
+ } | null;
63
+ }
64
+ export interface DownloadDescriptor {
65
+ readonly documentId: string;
66
+ readonly tenantId: string;
67
+ readonly version: number;
68
+ readonly sizeBytes: number;
69
+ readonly checksumSha3: string;
70
+ readonly manifest: unknown;
71
+ }
72
+ export interface UploadStatus {
73
+ readonly uploadId: string;
74
+ readonly documentId: string;
75
+ readonly tenantId: string;
76
+ readonly status: "pending" | "committed" | "aborted" | "quarantined";
77
+ readonly totalParts: number;
78
+ readonly completedParts: number;
79
+ readonly bytesReceived: number;
80
+ readonly lastPartNumber: number;
81
+ readonly chunkSizeBytes: number;
82
+ readonly totalSizeBytes: number;
83
+ readonly expiresAt: string;
84
+ readonly resumeToken: string | null;
85
+ readonly createdAt: string;
86
+ readonly updatedAt: string;
87
+ }
88
+ export interface DocumentPolicies {
89
+ readonly documentId: string;
90
+ readonly tenantId: string;
91
+ readonly compliance: {
92
+ readonly retentionMode: "compliance" | "governance" | null;
93
+ readonly retainUntil: string | null;
94
+ readonly legalHolds: readonly string[];
95
+ readonly wormLockExpiresAt: string | null;
96
+ };
97
+ readonly lifecycle?: {
98
+ readonly currentTier?: "hot" | "warm" | "cold" | "frozen";
99
+ readonly targetTier?: "hot" | "warm" | "cold" | "frozen" | null;
100
+ readonly transitionAfter?: string | null;
101
+ };
102
+ }
103
+ export interface UpdatePoliciesRequest {
104
+ readonly retentionMode?: "compliance" | "governance";
105
+ readonly retainUntil?: string;
106
+ readonly legalHolds?: readonly string[];
107
+ readonly wormLockExpiresAt?: string;
108
+ }
109
+ export interface ApplyLegalHoldRequest {
110
+ readonly holdId: string;
111
+ }
112
+ export interface ScheduleTransitionRequest {
113
+ readonly targetTier: "hot" | "warm" | "cold" | "frozen";
114
+ readonly transitionAfter: string;
115
+ }
116
+ export declare class StorageClient {
117
+ private readonly config;
118
+ private readonly telemetry;
119
+ private readonly targetService;
120
+ constructor(config: StorageClientConfig);
121
+ private request;
122
+ initiateUpload(options: InitiateUploadOptions): Promise<{
123
+ readonly uploadId: string;
124
+ readonly documentId: string;
125
+ readonly tenantId: string;
126
+ readonly chunkSizeBytes: number;
127
+ readonly totalSizeBytes: number;
128
+ readonly totalParts: number;
129
+ readonly expiresAt: string;
130
+ readonly resumeToken: string | null;
131
+ readonly pqc: {
132
+ readonly provider: string;
133
+ readonly algorithm: string;
134
+ readonly keyId: string;
135
+ };
136
+ }>;
137
+ uploadPart(uploadId: string, partId: number, data: ReadableStream<Uint8Array> | Buffer | Uint8Array): Promise<UploadPartResult>;
138
+ getUploadStatus(uploadId: string): Promise<UploadStatus>;
139
+ completeUpload(uploadId: string): Promise<CompleteUploadResult>;
140
+ getDownloadDescriptor(documentId: string, version: number, options?: {
141
+ readonly token?: string | null;
142
+ readonly expiresAt?: number | null;
143
+ readonly signature?: string | null;
144
+ }): Promise<DownloadDescriptor>;
145
+ downloadStream(documentId: string, version: number, options?: {
146
+ readonly token?: string | null;
147
+ readonly expiresAt?: number | null;
148
+ readonly signature?: string | null;
149
+ readonly range?: string | null;
150
+ }): Promise<{
151
+ readonly stream: ReadableStream<Uint8Array>;
152
+ readonly statusCode: 200 | 206;
153
+ readonly totalSize: number;
154
+ readonly contentLength: number;
155
+ readonly range?: {
156
+ readonly start: number;
157
+ readonly end: number;
158
+ };
159
+ readonly checksumSha3: string;
160
+ }>;
161
+ /**
162
+ * Retrieve document policies (compliance + lifecycle summary).
163
+ * Requires x-tenant-id header.
164
+ */
165
+ getDocumentPolicies(documentId: string): Promise<DocumentPolicies>;
166
+ /**
167
+ * Update document retention/WORM/legal hold list atomically.
168
+ * Requires x-tenant-id header.
169
+ */
170
+ updateDocumentPolicies(documentId: string, input: UpdatePoliciesRequest): Promise<DocumentPolicies>;
171
+ /**
172
+ * Apply a legal hold by id. Hold ids are caller-defined.
173
+ * Requires x-tenant-id header.
174
+ */
175
+ applyLegalHold(documentId: string, request: ApplyLegalHoldRequest): Promise<{
176
+ readonly documentId: string;
177
+ readonly tenantId: string;
178
+ readonly legalHolds: readonly string[];
179
+ }>;
180
+ /**
181
+ * Release a legal hold by id.
182
+ * Requires x-tenant-id header.
183
+ */
184
+ releaseLegalHold(documentId: string, holdId: string): Promise<void>;
185
+ /**
186
+ * Schedule a lifecycle tier transition for a document.
187
+ * Requires x-tenant-id header.
188
+ */
189
+ scheduleLifecycleTransition(documentId: string, request: ScheduleTransitionRequest): Promise<{
190
+ readonly documentId: string;
191
+ readonly tenantId: string;
192
+ readonly lifecycle: {
193
+ readonly currentTier?: "hot" | "warm" | "cold" | "frozen";
194
+ readonly targetTier?: "hot" | "warm" | "cold" | "frozen" | null;
195
+ readonly transitionAfter?: string | null;
196
+ };
197
+ }>;
198
+ private recordTelemetryEvent;
199
+ }
200
+ export * from "./events.js";
201
+ export * from "./observability.js";
202
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}