@onesi/genesis 0.0.1-stage → 0.1.13
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 +29 -0
- package/dist/beacons.d.ts +103 -0
- package/dist/beacons.js +77 -0
- package/dist/blinds-owner-enrollment.d.ts +171 -0
- package/dist/blinds-owner-enrollment.js +150 -0
- package/dist/client.d.ts +19996 -0
- package/dist/client.js +277 -0
- package/dist/context.d.ts +50 -0
- package/dist/context.js +153 -0
- package/dist/dials.d.ts +299 -0
- package/dist/dials.js +100 -0
- package/dist/errors.d.ts +35 -0
- package/dist/errors.js +66 -0
- package/dist/flares.d.ts +170 -0
- package/dist/flares.js +56 -0
- package/dist/fleets.d.ts +186 -0
- package/dist/fleets.js +136 -0
- package/dist/flocks.d.ts +155 -0
- package/dist/flocks.js +39 -0
- package/dist/foundry-billing.d.ts +97 -0
- package/dist/foundry-billing.js +107 -0
- package/dist/gears.d.ts +107 -0
- package/dist/gears.js +20 -0
- package/dist/generated/operations.d.ts +19949 -0
- package/dist/generated/operations.js +23846 -0
- package/dist/generated/schema.d.ts +35413 -0
- package/dist/generated/schema.js +1 -0
- package/dist/genesis.d.ts +2926 -0
- package/dist/genesis.js +206 -0
- package/dist/genesis.openapi.json +49321 -0
- package/dist/henry.d.ts +168 -0
- package/dist/henry.js +45 -0
- package/dist/hives-cells.d.ts +127 -0
- package/dist/hives-cells.js +151 -0
- package/dist/hives-environment.d.ts +28 -0
- package/dist/hives-environment.js +58 -0
- package/dist/hives-functions.d.ts +36 -0
- package/dist/hives-functions.js +185 -0
- package/dist/hives-marketplace.d.ts +128 -0
- package/dist/hives-marketplace.js +187 -0
- package/dist/hives-node.d.ts +9 -0
- package/dist/hives-node.js +152 -0
- package/dist/hives-operations.d.ts +337 -0
- package/dist/hives-operations.js +41 -0
- package/dist/hives-queue-consumer.d.ts +56 -0
- package/dist/hives-queue-consumer.js +95 -0
- package/dist/hives-queue-funding.d.ts +28 -0
- package/dist/hives-queue-funding.js +81 -0
- package/dist/hives-queues.d.ts +137 -0
- package/dist/hives-queues.js +143 -0
- package/dist/hives-resources-transport.d.ts +23 -0
- package/dist/hives-resources-transport.js +204 -0
- package/dist/hives-response.d.ts +2 -0
- package/dist/hives-response.js +32 -0
- package/dist/hives-runtimes.d.ts +34 -0
- package/dist/hives-runtimes.js +32 -0
- package/dist/hives-topics.d.ts +51 -0
- package/dist/hives-topics.js +79 -0
- package/dist/hives-upload.d.ts +9 -0
- package/dist/hives-upload.js +23 -0
- package/dist/hives-volumes.d.ts +64 -0
- package/dist/hives-volumes.js +117 -0
- package/dist/idempotency.d.ts +4 -0
- package/dist/idempotency.js +17 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +25 -0
- package/dist/instances.d.ts +25 -0
- package/dist/instances.js +11 -0
- package/dist/lanes.d.ts +267 -0
- package/dist/lanes.js +41 -0
- package/dist/minds-agent.d.ts +60 -0
- package/dist/minds-agent.js +190 -0
- package/dist/minds-owner.d.ts +110 -0
- package/dist/minds-owner.js +226 -0
- package/dist/minds.d.ts +269 -0
- package/dist/minds.js +193 -0
- package/dist/relays-enrollment.d.ts +33 -0
- package/dist/relays-enrollment.js +115 -0
- package/dist/runner-grant.d.ts +10 -0
- package/dist/runner-grant.js +133 -0
- package/dist/runner.d.ts +68 -0
- package/dist/runner.js +116 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.js +1 -0
- package/dist/urls.d.ts +6 -0
- package/dist/urls.js +31 -0
- package/package.json +49 -1
package/dist/henry.d.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { GenesisClient } from './client.js';
|
|
2
|
+
import type { OperationInput } from './types.js';
|
|
3
|
+
/** Henry always derives its organization from the gateway's verified caller. */
|
|
4
|
+
export declare function henryModule(client: GenesisClient): {
|
|
5
|
+
config: () => Promise<{
|
|
6
|
+
credential_configured: boolean;
|
|
7
|
+
models: {
|
|
8
|
+
id: string;
|
|
9
|
+
}[];
|
|
10
|
+
}>;
|
|
11
|
+
credential: (api_key: string) => Promise<{
|
|
12
|
+
credential_configured: boolean;
|
|
13
|
+
models: {
|
|
14
|
+
id: string;
|
|
15
|
+
}[];
|
|
16
|
+
}>;
|
|
17
|
+
/** Foundry models the stored organization key can run; 409 when no key is stored. */
|
|
18
|
+
models: () => Promise<{
|
|
19
|
+
models: {
|
|
20
|
+
id: string;
|
|
21
|
+
}[];
|
|
22
|
+
}>;
|
|
23
|
+
receipts: {
|
|
24
|
+
/** Current standalone Henry public signer. Pin through trusted deployment custody before verifying a receipt. */
|
|
25
|
+
verificationKey: () => Promise<{
|
|
26
|
+
keyId: string;
|
|
27
|
+
publicKeyBase64: string;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
runs: {
|
|
31
|
+
list: (page_token?: string) => Promise<{
|
|
32
|
+
runs: import("./index.js").components["schemas"]["Henry.Run"][];
|
|
33
|
+
next_page_token?: string | null;
|
|
34
|
+
}>;
|
|
35
|
+
create: (body: NonNullable<OperationInput<"henry_createRun">["body"]>) => Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
task: string;
|
|
38
|
+
model: string;
|
|
39
|
+
status: "ready" | "running" | "acting" | "paused" | "awaiting_approval" | "completed" | "cancelled" | "failed" | "waiting_input";
|
|
40
|
+
created_at: string;
|
|
41
|
+
updated_at: string;
|
|
42
|
+
activity: {
|
|
43
|
+
id: string;
|
|
44
|
+
at: string;
|
|
45
|
+
type: string;
|
|
46
|
+
detail: string;
|
|
47
|
+
}[];
|
|
48
|
+
approvals: {
|
|
49
|
+
id: string;
|
|
50
|
+
action: string;
|
|
51
|
+
url: string;
|
|
52
|
+
status: string;
|
|
53
|
+
requested_at: string;
|
|
54
|
+
}[];
|
|
55
|
+
phases: {
|
|
56
|
+
id?: string;
|
|
57
|
+
code?: number;
|
|
58
|
+
receipt?: Record<string, never>;
|
|
59
|
+
usage?: Record<string, never> | null;
|
|
60
|
+
}[];
|
|
61
|
+
messages: ({
|
|
62
|
+
role: string;
|
|
63
|
+
content?: string | null;
|
|
64
|
+
} & {
|
|
65
|
+
[key: string]: unknown;
|
|
66
|
+
})[];
|
|
67
|
+
}>;
|
|
68
|
+
get: (run_id: string) => Promise<{
|
|
69
|
+
id: string;
|
|
70
|
+
task: string;
|
|
71
|
+
model: string;
|
|
72
|
+
status: "ready" | "running" | "acting" | "paused" | "awaiting_approval" | "completed" | "cancelled" | "failed" | "waiting_input";
|
|
73
|
+
created_at: string;
|
|
74
|
+
updated_at: string;
|
|
75
|
+
activity: {
|
|
76
|
+
id: string;
|
|
77
|
+
at: string;
|
|
78
|
+
type: string;
|
|
79
|
+
detail: string;
|
|
80
|
+
}[];
|
|
81
|
+
approvals: {
|
|
82
|
+
id: string;
|
|
83
|
+
action: string;
|
|
84
|
+
url: string;
|
|
85
|
+
status: string;
|
|
86
|
+
requested_at: string;
|
|
87
|
+
}[];
|
|
88
|
+
phases: {
|
|
89
|
+
id?: string;
|
|
90
|
+
code?: number;
|
|
91
|
+
receipt?: Record<string, never>;
|
|
92
|
+
usage?: Record<string, never> | null;
|
|
93
|
+
}[];
|
|
94
|
+
messages: ({
|
|
95
|
+
role: string;
|
|
96
|
+
content?: string | null;
|
|
97
|
+
} & {
|
|
98
|
+
[key: string]: unknown;
|
|
99
|
+
})[];
|
|
100
|
+
}>;
|
|
101
|
+
command: (run_id: string, action: "pause" | "resume" | "cancel" | "input", text?: string) => Promise<{
|
|
102
|
+
id: string;
|
|
103
|
+
task: string;
|
|
104
|
+
model: string;
|
|
105
|
+
status: "ready" | "running" | "acting" | "paused" | "awaiting_approval" | "completed" | "cancelled" | "failed" | "waiting_input";
|
|
106
|
+
created_at: string;
|
|
107
|
+
updated_at: string;
|
|
108
|
+
activity: {
|
|
109
|
+
id: string;
|
|
110
|
+
at: string;
|
|
111
|
+
type: string;
|
|
112
|
+
detail: string;
|
|
113
|
+
}[];
|
|
114
|
+
approvals: {
|
|
115
|
+
id: string;
|
|
116
|
+
action: string;
|
|
117
|
+
url: string;
|
|
118
|
+
status: string;
|
|
119
|
+
requested_at: string;
|
|
120
|
+
}[];
|
|
121
|
+
phases: {
|
|
122
|
+
id?: string;
|
|
123
|
+
code?: number;
|
|
124
|
+
receipt?: Record<string, never>;
|
|
125
|
+
usage?: Record<string, never> | null;
|
|
126
|
+
}[];
|
|
127
|
+
messages: ({
|
|
128
|
+
role: string;
|
|
129
|
+
content?: string | null;
|
|
130
|
+
} & {
|
|
131
|
+
[key: string]: unknown;
|
|
132
|
+
})[];
|
|
133
|
+
}>;
|
|
134
|
+
approval: (run_id: string, approval_id: string, decision: "approve" | "reject") => Promise<{
|
|
135
|
+
id: string;
|
|
136
|
+
task: string;
|
|
137
|
+
model: string;
|
|
138
|
+
status: "ready" | "running" | "acting" | "paused" | "awaiting_approval" | "completed" | "cancelled" | "failed" | "waiting_input";
|
|
139
|
+
created_at: string;
|
|
140
|
+
updated_at: string;
|
|
141
|
+
activity: {
|
|
142
|
+
id: string;
|
|
143
|
+
at: string;
|
|
144
|
+
type: string;
|
|
145
|
+
detail: string;
|
|
146
|
+
}[];
|
|
147
|
+
approvals: {
|
|
148
|
+
id: string;
|
|
149
|
+
action: string;
|
|
150
|
+
url: string;
|
|
151
|
+
status: string;
|
|
152
|
+
requested_at: string;
|
|
153
|
+
}[];
|
|
154
|
+
phases: {
|
|
155
|
+
id?: string;
|
|
156
|
+
code?: number;
|
|
157
|
+
receipt?: Record<string, never>;
|
|
158
|
+
usage?: Record<string, never> | null;
|
|
159
|
+
}[];
|
|
160
|
+
messages: ({
|
|
161
|
+
role: string;
|
|
162
|
+
content?: string | null;
|
|
163
|
+
} & {
|
|
164
|
+
[key: string]: unknown;
|
|
165
|
+
})[];
|
|
166
|
+
}>;
|
|
167
|
+
};
|
|
168
|
+
};
|
package/dist/henry.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { GenesisError } from './errors.js';
|
|
2
|
+
function receiptVerificationKey(value) {
|
|
3
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
4
|
+
throw new Error('Henry returned an invalid receipt verification key.');
|
|
5
|
+
const key = value;
|
|
6
|
+
if (Object.keys(key).length !== 2 || !Object.hasOwn(key, 'keyId') || !Object.hasOwn(key, 'publicKeyBase64')
|
|
7
|
+
|| typeof key.keyId !== 'string' || !key.keyId.trim() || key.keyId.length > 256 || /[\x00-\x1f\x7f]/.test(key.keyId)
|
|
8
|
+
|| typeof key.publicKeyBase64 !== 'string' || key.publicKeyBase64.length !== 44
|
|
9
|
+
|| !/^[A-Za-z0-9+/]{42}[AEIMQUYcgkosw048]=$/.test(key.publicKeyBase64)) {
|
|
10
|
+
throw new Error('Henry returned an invalid receipt verification key.');
|
|
11
|
+
}
|
|
12
|
+
return { keyId: key.keyId, publicKeyBase64: key.publicKeyBase64 };
|
|
13
|
+
}
|
|
14
|
+
/** Henry always derives its organization from the gateway's verified caller. */
|
|
15
|
+
export function henryModule(client) {
|
|
16
|
+
return {
|
|
17
|
+
config: () => client.request('henry_getConfig'),
|
|
18
|
+
credential: async (api_key) => {
|
|
19
|
+
if (typeof api_key !== 'string' || !api_key || new TextEncoder().encode(api_key).byteLength > 4096 || /[\r\n\0]/.test(api_key)) {
|
|
20
|
+
throw new GenesisError({ status: 0, type: 'invalid_request', operationId: 'henry_putCredential', message: 'Foundry key must contain 1–4096 UTF-8 bytes without CR, LF or NUL.' });
|
|
21
|
+
}
|
|
22
|
+
return client.request('henry_putCredential', { body: { api_key } });
|
|
23
|
+
},
|
|
24
|
+
/** Foundry models the stored organization key can run; 409 when no key is stored. */
|
|
25
|
+
models: () => client.request('henry_listFoundryModels'),
|
|
26
|
+
receipts: {
|
|
27
|
+
/** Current standalone Henry public signer. Pin through trusted deployment custody before verifying a receipt. */
|
|
28
|
+
verificationKey: async () => {
|
|
29
|
+
try {
|
|
30
|
+
return receiptVerificationKey(await client.request('henry_getReceiptVerificationKey'));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error('Henry returned an invalid receipt verification key.');
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
runs: {
|
|
38
|
+
list: (page_token) => client.request('henry_listRuns', page_token ? { page_token } : {}),
|
|
39
|
+
create: (body) => client.request('henry_createRun', { body: { ...body, run_id: body.run_id ?? globalThis.crypto.randomUUID() } }),
|
|
40
|
+
get: (run_id) => client.request('henry_getRun', { run_id }),
|
|
41
|
+
command: (run_id, action, text) => client.request('henry_commandRun', { run_id, body: { action, ...(text === undefined ? {} : { text }) } }),
|
|
42
|
+
approval: (run_id, approval_id, decision) => client.request('henry_decideApproval', { run_id, approval_id, body: { decision } }),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { GenesisClient } from './client.js';
|
|
2
|
+
import { type HivesResourceOptions } from './hives-resources-transport.js';
|
|
3
|
+
export interface HivesCorsRule {
|
|
4
|
+
allowed_origins: string[];
|
|
5
|
+
allowed_methods: string[];
|
|
6
|
+
allowed_headers: string[];
|
|
7
|
+
exposed_headers: string[];
|
|
8
|
+
max_age_secs: number;
|
|
9
|
+
}
|
|
10
|
+
export interface HivesBucket {
|
|
11
|
+
id: string;
|
|
12
|
+
tenant_id: string;
|
|
13
|
+
project_id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
region: string;
|
|
16
|
+
visibility: string;
|
|
17
|
+
status: string;
|
|
18
|
+
object_count: number | null;
|
|
19
|
+
size_bytes: number | null;
|
|
20
|
+
statistics_scope: 'unmeasured_provider_inventory' | 'retained_legacy_metadata';
|
|
21
|
+
created_at: string;
|
|
22
|
+
provider_binding: {
|
|
23
|
+
provider: 'gcs';
|
|
24
|
+
region: string;
|
|
25
|
+
state: string;
|
|
26
|
+
requires_reconciliation: boolean;
|
|
27
|
+
} | null;
|
|
28
|
+
operation_state: string | null;
|
|
29
|
+
}
|
|
30
|
+
export interface HivesObject {
|
|
31
|
+
key: string;
|
|
32
|
+
bucket_id: string;
|
|
33
|
+
size_bytes: number;
|
|
34
|
+
etag: string;
|
|
35
|
+
last_modified: string;
|
|
36
|
+
generation: string;
|
|
37
|
+
content_type: string | null;
|
|
38
|
+
metadata: Record<string, string> | null;
|
|
39
|
+
metadata_scope: string;
|
|
40
|
+
}
|
|
41
|
+
export interface HivesObjectAcknowledgement {
|
|
42
|
+
bucket_id: string;
|
|
43
|
+
key: string;
|
|
44
|
+
size_bytes: number;
|
|
45
|
+
etag: string;
|
|
46
|
+
generation: string;
|
|
47
|
+
content_type: string | null;
|
|
48
|
+
}
|
|
49
|
+
export interface HivesObjectList {
|
|
50
|
+
objects: HivesObject[];
|
|
51
|
+
common_prefixes: string[];
|
|
52
|
+
is_truncated: boolean;
|
|
53
|
+
next_continuation_token: string | null;
|
|
54
|
+
total: number | null;
|
|
55
|
+
}
|
|
56
|
+
export interface HivesBucketList {
|
|
57
|
+
data: HivesBucket[];
|
|
58
|
+
pagination: {
|
|
59
|
+
page: number;
|
|
60
|
+
per_page: number;
|
|
61
|
+
total: number;
|
|
62
|
+
total_pages: number;
|
|
63
|
+
has_next: boolean;
|
|
64
|
+
has_prev: boolean;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface HivesCreateBucket {
|
|
68
|
+
name: string;
|
|
69
|
+
region?: 'us-central1';
|
|
70
|
+
visibility?: 'private' | 'publicread';
|
|
71
|
+
cors_rules?: HivesCorsRule[];
|
|
72
|
+
}
|
|
73
|
+
export interface HivesPresign {
|
|
74
|
+
key: string;
|
|
75
|
+
method?: 'GET' | 'PUT';
|
|
76
|
+
expires_in_secs?: number;
|
|
77
|
+
content_type?: string;
|
|
78
|
+
content_length?: number;
|
|
79
|
+
}
|
|
80
|
+
export interface HivesPresignedUrl {
|
|
81
|
+
url: string;
|
|
82
|
+
expires_at: string;
|
|
83
|
+
method: 'GET' | 'PUT';
|
|
84
|
+
required_headers?: Record<string, string>;
|
|
85
|
+
}
|
|
86
|
+
export declare function hivesObjectKey(key: string): string;
|
|
87
|
+
export declare function hivesCells(client: GenesisClient): {
|
|
88
|
+
list(project: string, query?: {
|
|
89
|
+
page?: number;
|
|
90
|
+
per_page?: number;
|
|
91
|
+
}, options?: HivesResourceOptions): Promise<HivesBucketList>;
|
|
92
|
+
get(project: string, id: string, options?: HivesResourceOptions): Promise<HivesBucket>;
|
|
93
|
+
/** A pending provider_binding is an uncertain outcome, never a completed-create claim. */
|
|
94
|
+
create(project: string, body: HivesCreateBucket, options?: HivesResourceOptions): Promise<HivesBucket>;
|
|
95
|
+
remove(project: string, id: string, options?: HivesResourceOptions): Promise<{
|
|
96
|
+
id: string;
|
|
97
|
+
success: boolean;
|
|
98
|
+
message: string;
|
|
99
|
+
}>;
|
|
100
|
+
reconcile(project: string, id: string, options?: HivesResourceOptions): Promise<{
|
|
101
|
+
bucket: HivesBucket;
|
|
102
|
+
outcome: string;
|
|
103
|
+
}>;
|
|
104
|
+
cors: {
|
|
105
|
+
get: (project: string, id: string, options?: HivesResourceOptions) => Promise<HivesCorsRule[]>;
|
|
106
|
+
set: (project: string, id: string, rules: HivesCorsRule[], options?: HivesResourceOptions) => Promise<HivesCorsRule[]>;
|
|
107
|
+
};
|
|
108
|
+
objects: {
|
|
109
|
+
list(project: string, id: string, query?: {
|
|
110
|
+
prefix?: string;
|
|
111
|
+
delimiter?: string;
|
|
112
|
+
continuation_token?: string;
|
|
113
|
+
max_keys?: number;
|
|
114
|
+
}, options?: HivesResourceOptions): Promise<HivesObjectList>;
|
|
115
|
+
put(project: string, id: string, key: string, bytes: Blob | ArrayBuffer | ArrayBufferView, options?: HivesResourceOptions & {
|
|
116
|
+
content_type?: string;
|
|
117
|
+
}): Promise<HivesObjectAcknowledgement>;
|
|
118
|
+
remove: (project: string, id: string, key: string, options?: HivesResourceOptions) => Promise<void>;
|
|
119
|
+
download: (project: string, id: string, key: string, options?: HivesResourceOptions) => Promise<Response>;
|
|
120
|
+
/** Existing flat-key path compatibility; nested keys use canonical collection methods above. */
|
|
121
|
+
putFlat(project: string, id: string, key: string, bytes: Blob | ArrayBuffer | ArrayBufferView, options?: HivesResourceOptions & {
|
|
122
|
+
content_type?: string;
|
|
123
|
+
}): Promise<HivesObjectAcknowledgement>;
|
|
124
|
+
removeFlat: (project: string, id: string, key: string, options?: HivesResourceOptions) => Promise<void>;
|
|
125
|
+
};
|
|
126
|
+
presign(project: string, id: string, body: HivesPresign, options?: HivesResourceOptions): Promise<HivesPresignedUrl>;
|
|
127
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { HIVES_OBJECT_BYTES, hivesResourceCall, hivesResourceId, hivesObjectBody, hivesContentType, resourceError } from './hives-resources-transport.js';
|
|
2
|
+
export function hivesObjectKey(key) {
|
|
3
|
+
const bytes = new TextEncoder().encode(key);
|
|
4
|
+
if (typeof key !== 'string' || !key || bytes.length > 1024 || new TextDecoder('utf-8', { fatal: true }).decode(bytes) !== key
|
|
5
|
+
|| key.startsWith('/') || key.endsWith('/') || /[\u0000-\u001f\u007f-\u009f\\]/.test(key) || key.split('/').some(p => !p || p === '.' || p === '..'))
|
|
6
|
+
throw resourceError(0);
|
|
7
|
+
let binary = '';
|
|
8
|
+
for (const byte of bytes)
|
|
9
|
+
binary += String.fromCharCode(byte);
|
|
10
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
11
|
+
}
|
|
12
|
+
function cors(rules) {
|
|
13
|
+
if (!Array.isArray(rules) || rules.length > 100)
|
|
14
|
+
throw resourceError(0);
|
|
15
|
+
return rules.map(rule => {
|
|
16
|
+
if (!rule || typeof rule !== 'object' || Object.keys(rule).some(k => !['allowed_origins', 'allowed_methods', 'allowed_headers', 'exposed_headers', 'max_age_secs'].includes(k))
|
|
17
|
+
|| !Array.isArray(rule.allowed_origins) || !rule.allowed_origins.length || rule.allowed_origins.length > 100
|
|
18
|
+
|| !Array.isArray(rule.allowed_methods) || !rule.allowed_methods.length || rule.allowed_methods.length > 6
|
|
19
|
+
|| !Array.isArray(rule.allowed_headers) || rule.allowed_headers.length !== 1 || rule.allowed_headers[0] !== '*'
|
|
20
|
+
|| !Array.isArray(rule.exposed_headers) || rule.exposed_headers.length > 100
|
|
21
|
+
|| !Number.isInteger(rule.max_age_secs) || rule.max_age_secs < 0 || rule.max_age_secs > 86400)
|
|
22
|
+
throw resourceError(0);
|
|
23
|
+
for (const origin of rule.allowed_origins) {
|
|
24
|
+
if (origin === '*')
|
|
25
|
+
continue;
|
|
26
|
+
if (typeof origin !== 'string')
|
|
27
|
+
throw resourceError(0);
|
|
28
|
+
let url;
|
|
29
|
+
try {
|
|
30
|
+
url = new URL(origin);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw resourceError(0);
|
|
34
|
+
}
|
|
35
|
+
if (!['http:', 'https:'].includes(url.protocol) || !url.hostname || url.username || url.password || url.pathname !== '/' || url.search || url.hash)
|
|
36
|
+
throw resourceError(0);
|
|
37
|
+
}
|
|
38
|
+
if (rule.allowed_methods.some(m => !['GET', 'HEAD', 'PUT', 'POST', 'DELETE'].includes(m))
|
|
39
|
+
|| rule.exposed_headers.some(h => typeof h !== 'string' || h.length > 256 || !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(h)))
|
|
40
|
+
throw resourceError(0);
|
|
41
|
+
return { allowed_origins: [...rule.allowed_origins], allowed_methods: [...rule.allowed_methods], allowed_headers: ['*'], exposed_headers: [...rule.exposed_headers], max_age_secs: rule.max_age_secs };
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function bucket(value, project, id) {
|
|
45
|
+
if (!value || typeof value !== 'object' || value.project_id !== project || typeof value.id !== 'string' || id !== undefined && value.id !== id
|
|
46
|
+
|| !['unmeasured_provider_inventory', 'retained_legacy_metadata'].includes(value.statistics_scope)
|
|
47
|
+
|| [value.object_count, value.size_bytes].some(v => v !== null && (!Number.isSafeInteger(v) || v < 0))
|
|
48
|
+
|| (value.statistics_scope === 'unmeasured_provider_inventory' && (value.object_count !== null || value.size_bytes !== null)))
|
|
49
|
+
throw resourceError(0);
|
|
50
|
+
if (value.statistics_scope === 'unmeasured_provider_inventory' && !value.provider_binding)
|
|
51
|
+
throw resourceError(0);
|
|
52
|
+
if (value.provider_binding !== null && (!value.provider_binding || value.provider_binding.provider !== 'gcs' || typeof value.provider_binding.state !== 'string' || typeof value.provider_binding.requires_reconciliation !== 'boolean'))
|
|
53
|
+
throw resourceError(0);
|
|
54
|
+
return Object.fromEntries(['id', 'tenant_id', 'project_id', 'name', 'region', 'visibility', 'status', 'object_count', 'size_bytes', 'statistics_scope', 'created_at', 'provider_binding', 'operation_state'].map(k => [k, value[k]]));
|
|
55
|
+
}
|
|
56
|
+
function object(value, id) {
|
|
57
|
+
if (!value || value.bucket_id !== id || typeof value.key !== 'string' || !Number.isSafeInteger(value.size_bytes) || value.size_bytes < 0 || typeof value.generation !== 'string')
|
|
58
|
+
throw resourceError(0);
|
|
59
|
+
hivesObjectKey(value.key);
|
|
60
|
+
return Object.fromEntries(['key', 'bucket_id', 'size_bytes', 'etag', 'last_modified', 'generation', 'content_type', 'metadata', 'metadata_scope'].map(k => [k, value[k]]));
|
|
61
|
+
}
|
|
62
|
+
function acknowledgement(value, key, id, size) {
|
|
63
|
+
if (!value || value.bucket_id !== id || value.key !== key || value.size_bytes !== size || !Number.isSafeInteger(value.size_bytes) || value.size_bytes < 0 || typeof value.etag !== 'string' || typeof value.generation !== 'string' || value.content_type !== null && typeof value.content_type !== 'string')
|
|
64
|
+
throw resourceError(0);
|
|
65
|
+
return { key: value.key, bucket_id: value.bucket_id, size_bytes: value.size_bytes, etag: value.etag, generation: value.generation, content_type: value.content_type };
|
|
66
|
+
}
|
|
67
|
+
export function hivesCells(client) {
|
|
68
|
+
const ids = (project_id, bucket_id) => ({ project_id: hivesResourceId(project_id), ...(bucket_id === undefined ? {} : { bucket_id: hivesResourceId(bucket_id) }) });
|
|
69
|
+
const call = (id, input, options, mode = 'json', limit = 2 * 1024 * 1024) => hivesResourceCall(client, id, input, options, mode, limit, 100_000);
|
|
70
|
+
return {
|
|
71
|
+
async list(project, query = {}, options) {
|
|
72
|
+
if (Object.keys(query).some(k => !['page', 'per_page'].includes(k)) || query.page !== undefined && (!Number.isInteger(query.page) || query.page < 1 || query.page > 10000) || query.per_page !== undefined && (!Number.isInteger(query.per_page) || query.per_page < 1 || query.per_page > 100))
|
|
73
|
+
throw resourceError(0);
|
|
74
|
+
const result = await call('hives_list_buckets', { ...query, ...ids(project) }, options);
|
|
75
|
+
if (!result || !Array.isArray(result.data) || !result.pagination)
|
|
76
|
+
throw resourceError(0);
|
|
77
|
+
return { ...result, data: result.data.map(row => bucket(row, project)) };
|
|
78
|
+
},
|
|
79
|
+
async get(project, id, options) { return bucket(await call('hives_get_bucket', ids(project, id), options), project, id); },
|
|
80
|
+
/** A pending provider_binding is an uncertain outcome, never a completed-create claim. */
|
|
81
|
+
async create(project, body, options) {
|
|
82
|
+
if (!body || typeof body.name !== 'string' || !/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(body.name) || body.region !== undefined && body.region !== 'us-central1'
|
|
83
|
+
|| body.visibility !== undefined && !['private', 'publicread'].includes(body.visibility) || Object.keys(body).some(k => !['name', 'region', 'visibility', 'cors_rules'].includes(k)))
|
|
84
|
+
throw resourceError(0);
|
|
85
|
+
const checked = { ...body, ...(body.cors_rules === undefined ? {} : { cors_rules: cors(body.cors_rules) }) };
|
|
86
|
+
return bucket(await call('hives_create_bucket', { ...ids(project), body: checked }, options), project);
|
|
87
|
+
},
|
|
88
|
+
async remove(project, id, options) {
|
|
89
|
+
const result = await call('hives_delete_bucket', ids(project, id), options);
|
|
90
|
+
if (!result || result.id !== id || result.success !== true)
|
|
91
|
+
throw resourceError(0);
|
|
92
|
+
return result;
|
|
93
|
+
},
|
|
94
|
+
async reconcile(project, id, options) {
|
|
95
|
+
const result = await call('hives_reconcile', ids(project, id), options);
|
|
96
|
+
if (!result || typeof result.outcome !== 'string' || result.bucket?.id !== id)
|
|
97
|
+
throw resourceError(0);
|
|
98
|
+
return { ...result, bucket: bucket(result.bucket, project) };
|
|
99
|
+
},
|
|
100
|
+
cors: {
|
|
101
|
+
get: async (project, id, options) => cors(await call('hives_get_cors_config', ids(project, id), options)),
|
|
102
|
+
set: async (project, id, rules, options) => cors(await call('hives_set_cors_config', { ...ids(project, id), body: { rules: cors(rules) } }, options)),
|
|
103
|
+
},
|
|
104
|
+
objects: {
|
|
105
|
+
async list(project, id, query = {}, options) {
|
|
106
|
+
if (query.max_keys !== undefined && (!Number.isInteger(query.max_keys) || query.max_keys < 1 || query.max_keys > 1000))
|
|
107
|
+
throw resourceError(0);
|
|
108
|
+
const result = await call('hives_list_objects', { ...query, ...ids(project, id) }, options);
|
|
109
|
+
if (!result || !Array.isArray(result.objects) || !Array.isArray(result.common_prefixes) || typeof result.is_truncated !== 'boolean' || result.total !== null)
|
|
110
|
+
throw resourceError(0);
|
|
111
|
+
return { ...result, objects: result.objects.map(row => object(row, id)) };
|
|
112
|
+
},
|
|
113
|
+
async put(project, id, key, bytes, options = {}) {
|
|
114
|
+
const body = await hivesObjectBody(bytes);
|
|
115
|
+
const content_type = hivesContentType(options.content_type);
|
|
116
|
+
return acknowledgement(await call('hives_upload_object_by_key', { ...ids(project, id), key_base64url: hivesObjectKey(key), body, content_type }, options), key, id, body.byteLength);
|
|
117
|
+
},
|
|
118
|
+
remove: (project, id, key, options) => call('hives_delete_object_by_key', { ...ids(project, id), key_base64url: hivesObjectKey(key) }, options, 'empty'),
|
|
119
|
+
download: (project, id, key, options) => call('hives_download_object_by_key', { ...ids(project, id), key_base64url: hivesObjectKey(key) }, options, 'binary', HIVES_OBJECT_BYTES),
|
|
120
|
+
/** Existing flat-key path compatibility; nested keys use canonical collection methods above. */
|
|
121
|
+
async putFlat(project, id, key, bytes, options = {}) {
|
|
122
|
+
hivesObjectKey(key);
|
|
123
|
+
if (!/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*$/.test(key))
|
|
124
|
+
throw resourceError(0);
|
|
125
|
+
const body = await hivesObjectBody(bytes);
|
|
126
|
+
return acknowledgement(await call('hives_upload_object', { ...ids(project, id), key, body, content_type: hivesContentType(options.content_type) }, options), key, id, body.byteLength);
|
|
127
|
+
},
|
|
128
|
+
removeFlat: (project, id, key, options) => { hivesObjectKey(key); if (!/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*$/.test(key))
|
|
129
|
+
throw resourceError(0); return call('hives_delete_object', { ...ids(project, id), key }, options, 'empty'); },
|
|
130
|
+
},
|
|
131
|
+
async presign(project, id, body, options) {
|
|
132
|
+
hivesObjectKey(body.key);
|
|
133
|
+
const method = body.method ?? 'GET';
|
|
134
|
+
if (!['GET', 'PUT'].includes(method) || body.expires_in_secs !== undefined && (!Number.isInteger(body.expires_in_secs) || body.expires_in_secs < 60 || body.expires_in_secs > 900)
|
|
135
|
+
|| method === 'PUT' && (body.content_length === undefined || !Number.isInteger(body.content_length) || body.content_length < 0 || body.content_length > HIVES_OBJECT_BYTES))
|
|
136
|
+
throw resourceError(0);
|
|
137
|
+
if (body.content_type !== undefined)
|
|
138
|
+
hivesContentType(body.content_type);
|
|
139
|
+
const result = await call('hives_generate_presigned_url', { ...ids(project, id), body }, options);
|
|
140
|
+
if (!result || typeof result.url !== 'string' || result.method !== method || typeof result.expires_at !== 'string')
|
|
141
|
+
throw resourceError(0);
|
|
142
|
+
const url = new URL(result.url);
|
|
143
|
+
if (url.protocol !== 'https:' || url.hostname !== 'storage.googleapis.com' || url.username || url.password || url.hash)
|
|
144
|
+
throw resourceError(0);
|
|
145
|
+
const headers = result.required_headers;
|
|
146
|
+
if (headers !== undefined && (!headers || typeof headers !== 'object' || Array.isArray(headers) || Object.entries(headers).some(([k, v]) => !['content-type', 'content-length', 'x-goog-if-generation-match'].includes(k.toLowerCase()) || typeof v !== 'string' || /[\u0000-\u001f\u007f]/.test(v))))
|
|
147
|
+
throw resourceError(0);
|
|
148
|
+
return { url: result.url, expires_at: result.expires_at, method: result.method, ...(headers ? { required_headers: { ...headers } } : {}) };
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Environment metadata never carries stored values. Reveals are explicit. */
|
|
2
|
+
export declare function validateHivesEnvironment(input: unknown): Record<string, string>;
|
|
3
|
+
export declare function hivesEnvironmentMetadata(value: unknown, project: unknown, updated: boolean): {
|
|
4
|
+
project_id: string;
|
|
5
|
+
updated: {
|
|
6
|
+
name: string;
|
|
7
|
+
}[];
|
|
8
|
+
data?: undefined;
|
|
9
|
+
pagination?: undefined;
|
|
10
|
+
} | {
|
|
11
|
+
project_id: string;
|
|
12
|
+
data: {
|
|
13
|
+
name: string;
|
|
14
|
+
}[];
|
|
15
|
+
pagination: {
|
|
16
|
+
page: unknown;
|
|
17
|
+
per_page: unknown;
|
|
18
|
+
total: unknown;
|
|
19
|
+
total_pages: unknown;
|
|
20
|
+
has_next: boolean;
|
|
21
|
+
has_prev: boolean;
|
|
22
|
+
};
|
|
23
|
+
updated?: undefined;
|
|
24
|
+
};
|
|
25
|
+
export declare function hivesEnvironmentReveal(value: unknown, key: unknown): {
|
|
26
|
+
name: string;
|
|
27
|
+
value: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Environment metadata never carries stored values. Reveals are explicit. */
|
|
2
|
+
export function validateHivesEnvironment(input) {
|
|
3
|
+
if (!input || typeof input !== 'object' || Array.isArray(input))
|
|
4
|
+
throw new Error('Environment input must be a flat JSON map of names to string values.');
|
|
5
|
+
const entries = Object.entries(input);
|
|
6
|
+
if (entries.length < 1 || entries.length > 100)
|
|
7
|
+
throw new Error('Environment updates require 1–100 names.');
|
|
8
|
+
const result = Object.create(null);
|
|
9
|
+
for (const [name, value] of entries) {
|
|
10
|
+
if (name.length > 255 || !/^[A-Za-z][A-Za-z0-9_]*$/.test(name))
|
|
11
|
+
throw new Error('Environment names must start with a letter and contain only letters, numbers and underscores (up to 255 characters).');
|
|
12
|
+
if (typeof value !== 'string' || new TextEncoder().encode(value).length > 65536)
|
|
13
|
+
throw new Error('Environment values must be strings of at most 65,536 UTF-8 bytes. Empty values are allowed.');
|
|
14
|
+
result[name] = value;
|
|
15
|
+
}
|
|
16
|
+
if (new TextEncoder().encode(JSON.stringify(result)).length > 2 * 1024 * 1024)
|
|
17
|
+
throw new Error('Environment input exceeds 2 MiB. Split it into smaller batches.');
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
function record(value) {
|
|
21
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
22
|
+
throw new Error('Hives returned invalid environment metadata.');
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
function names(value) {
|
|
26
|
+
if (!Array.isArray(value))
|
|
27
|
+
throw new Error('Hives returned invalid environment metadata.');
|
|
28
|
+
return value.map((value) => {
|
|
29
|
+
const row = record(value);
|
|
30
|
+
if (typeof row.name !== 'string')
|
|
31
|
+
throw new Error('Hives returned invalid environment metadata.');
|
|
32
|
+
return { name: row.name };
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function hivesEnvironmentMetadata(value, project, updated) {
|
|
36
|
+
const data = record(value);
|
|
37
|
+
if (typeof project !== 'string' || data.project_id !== project)
|
|
38
|
+
throw new Error('Hives returned environment metadata for a different project.');
|
|
39
|
+
if (updated)
|
|
40
|
+
return { project_id: project, updated: names(data.updated) };
|
|
41
|
+
const pagination = record(data.pagination);
|
|
42
|
+
for (const key of ['page', 'per_page', 'total', 'total_pages']) {
|
|
43
|
+
if (!Number.isSafeInteger(pagination[key]) || pagination[key] < (key === 'page' || key === 'per_page' ? 1 : 0))
|
|
44
|
+
throw new Error('Hives returned invalid environment pagination.');
|
|
45
|
+
}
|
|
46
|
+
if (typeof pagination.has_next !== 'boolean' || typeof pagination.has_prev !== 'boolean')
|
|
47
|
+
throw new Error('Hives returned invalid environment pagination.');
|
|
48
|
+
return { project_id: project, data: names(data.data), pagination: {
|
|
49
|
+
page: pagination.page, per_page: pagination.per_page, total: pagination.total, total_pages: pagination.total_pages,
|
|
50
|
+
has_next: pagination.has_next, has_prev: pagination.has_prev,
|
|
51
|
+
} };
|
|
52
|
+
}
|
|
53
|
+
export function hivesEnvironmentReveal(value, key) {
|
|
54
|
+
const data = record(value);
|
|
55
|
+
if (typeof key !== 'string' || data.name !== key || typeof data.value !== 'string' || new TextEncoder().encode(data.value).length > 65536)
|
|
56
|
+
throw new Error('Hives returned invalid environment reveal data.');
|
|
57
|
+
return { name: data.name, value: data.value };
|
|
58
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { GenesisError } from './errors.js';
|
|
2
|
+
/** The service separately bounds its serialized guest stdin envelope at 10 MiB. */
|
|
3
|
+
export declare const MAX_FUNCTION_BODY_BYTES: number;
|
|
4
|
+
export declare const MAX_FUNCTION_JSON_BYTES: number;
|
|
5
|
+
export interface HivesInvokeRequest {
|
|
6
|
+
method?: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
body?: unknown;
|
|
10
|
+
body_base64?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface HivesInvokeOptions {
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
idempotencyKey?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface HivesOperationStatus {
|
|
17
|
+
operation_id: string;
|
|
18
|
+
state: 'prepared' | 'reserve_unknown' | 'reserved' | 'dispatch_unknown' | 'dispatch_authorized' | 'dispatched' | 'settle_unknown' | 'settled' | 'release_pending' | 'released';
|
|
19
|
+
code: string;
|
|
20
|
+
funding_source: 'sandbox_allowance' | 'stripe_test_metered' | null;
|
|
21
|
+
reservation_id: string | null;
|
|
22
|
+
retry_execution: false;
|
|
23
|
+
}
|
|
24
|
+
export declare function hivesInvokeHeaders(options: HivesInvokeOptions): Record<string, string>;
|
|
25
|
+
export declare function hivesOperationStatus(value: unknown, expected: string): HivesOperationStatus;
|
|
26
|
+
export declare class HivesOperationError extends GenesisError {
|
|
27
|
+
readonly operation: HivesOperationStatus;
|
|
28
|
+
constructor(status: number, operation: HivesOperationStatus);
|
|
29
|
+
}
|
|
30
|
+
/** Read only the small platform receipt; never retain reflected guest request data. */
|
|
31
|
+
export declare function hivesOperationError(response: Response): Promise<HivesOperationError | undefined>;
|
|
32
|
+
export declare function validateHivesInvocation(input: unknown): asserts input is HivesInvokeRequest;
|
|
33
|
+
/** Safe display/transport headers; customer headers never establish identity. */
|
|
34
|
+
export declare function hivesFunctionResponseHeaders(headers: Headers): Headers;
|
|
35
|
+
/** Metadata contracts cannot accidentally expose an upstream env/ciphertext field. */
|
|
36
|
+
export declare function hivesFunctionMetadata(input: unknown, project: unknown, expectedId?: unknown): Record<string, unknown>;
|