@ariestools/aries-datalake-core 0.1.19 → 0.1.21
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/dist/browser/browser.d.ts +1 -0
- package/dist/browser/browser.d.ts.map +1 -1
- package/dist/browser/browser.mjs +34 -1
- package/dist/browser/browser.mjs.map +3 -3
- package/dist/browser/types/DatalakeConfig.d.ts +19 -1
- package/dist/browser/types/DatalakeConfig.d.ts.map +1 -1
- package/dist/node/auth/sessionTokenCodec.d.ts.map +1 -1
- package/dist/node/auth/tokenCodec.d.ts.map +1 -1
- package/dist/node/browser.d.ts +1 -0
- package/dist/node/browser.d.ts.map +1 -1
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.mjs +44 -7
- package/dist/node/index.mjs.map +3 -3
- package/dist/node/types/DatalakeConfig.d.ts +19 -1
- package/dist/node/types/DatalakeConfig.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -7,6 +7,7 @@ export type { CreateDatalakeBody, GrantBody, MintTokenBody, } from './api/reques
|
|
|
7
7
|
export type { AclEntry } from './types/AclEntry.ts';
|
|
8
8
|
export type { DatalakeInsertSummary, InsertPayloadsBody, InsertPayloadsResponse, InsertPayloadsResult, JsonObject, JsonPrimitive, JsonValue, NextPayloadsOptions, NextPayloadsResponse, NextPayloadsResult, Payload, StorageMeta, StoredPayload, WithStorageMeta, } from './types/BrowserPayload.ts';
|
|
9
9
|
export type { DatalakeConfig, RateLimitOverrides } from './types/DatalakeConfig.ts';
|
|
10
|
+
export { validateDatalakeAdmissionConfig } from './types/DatalakeConfig.ts';
|
|
10
11
|
export type { DatalakeDescriptor, DatalakeUsage } from './types/DatalakeDescriptor.ts';
|
|
11
12
|
export type { DatalakePrincipal, DatalakeRole } from './types/Principal.ts';
|
|
12
13
|
export { isPublicPrincipal, PUBLIC_PRINCIPAL } from './types/Principal.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,kBAAkB,EAAE,SAAS,EAAE,aAAa,GAC7C,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,OAAO,EACP,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnF,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AACtF,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACpE,YAAY,EACV,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,GACnE,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,kBAAkB,EAAE,SAAS,EAAE,aAAa,GAC7C,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,OAAO,EACP,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnF,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;AAC3E,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AACtF,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACpE,YAAY,EACV,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,GACnE,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/browser/browser.mjs
CHANGED
|
@@ -72,6 +72,38 @@ function datalakePlaneUsagePath(id) {
|
|
|
72
72
|
return `${datalakePlaneResourcePath(id)}/usage`;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
// src/types/DatalakeConfig.ts
|
|
76
|
+
function validateDatalakeAdmissionConfig(config) {
|
|
77
|
+
if (config.schemaPolicy !== void 0 && config.schemaPolicy !== "allowlist") {
|
|
78
|
+
throw new TypeError("schemaPolicy must be allowlist when supplied");
|
|
79
|
+
}
|
|
80
|
+
if (config.schemaPolicy === "allowlist" && !Array.isArray(config.allowedSchemas)) {
|
|
81
|
+
throw new TypeError("allowedSchemas must be explicitly supplied in allowlist mode; use [] to accept no payloads");
|
|
82
|
+
}
|
|
83
|
+
for (const [name, schemas] of [["allowedSchemas", config.allowedSchemas], ["disallowedSchemas", config.disallowedSchemas]]) {
|
|
84
|
+
if (schemas !== void 0 && (!Array.isArray(schemas) || schemas.some((schema) => typeof schema !== "string" || schema.length === 0))) {
|
|
85
|
+
throw new TypeError(`${name} must be an array of non-empty schema strings`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (config.maxPayloadBytes !== void 0 || config.schemaPolicy === "allowlist") {
|
|
89
|
+
requireByteLimit(config.maxPayloadBytes, "maxPayloadBytes");
|
|
90
|
+
}
|
|
91
|
+
if (config.schemaMaxPayloadBytes !== void 0) {
|
|
92
|
+
if (!config.schemaMaxPayloadBytes || typeof config.schemaMaxPayloadBytes !== "object" || Array.isArray(config.schemaMaxPayloadBytes)) {
|
|
93
|
+
throw new TypeError("schemaMaxPayloadBytes must map schema strings to positive byte limits");
|
|
94
|
+
}
|
|
95
|
+
for (const [schema, limit] of Object.entries(config.schemaMaxPayloadBytes)) {
|
|
96
|
+
if (schema.length === 0) throw new TypeError("schemaMaxPayloadBytes keys must be non-empty schema strings");
|
|
97
|
+
requireByteLimit(limit, `schemaMaxPayloadBytes[${schema}]`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function requireByteLimit(value, field) {
|
|
102
|
+
if (!Number.isSafeInteger(value) || (value ?? 0) <= 0) {
|
|
103
|
+
throw new TypeError(`${field} must be a finite positive safe integer byte count`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
75
107
|
// src/types/Principal.ts
|
|
76
108
|
var PUBLIC_PRINCIPAL = "public";
|
|
77
109
|
function isPublicPrincipal(principal) {
|
|
@@ -139,6 +171,7 @@ export {
|
|
|
139
171
|
datalakeTokensPath,
|
|
140
172
|
isDatalakeControlOperation,
|
|
141
173
|
isDatalakeDataOperation,
|
|
142
|
-
isPublicPrincipal
|
|
174
|
+
isPublicPrincipal,
|
|
175
|
+
validateDatalakeAdmissionConfig
|
|
143
176
|
};
|
|
144
177
|
//# sourceMappingURL=browser.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/api/errors.ts", "../../src/api/paths.ts", "../../src/api/planePaths.ts", "../../src/types/Principal.ts", "../../src/types/Region.ts", "../../src/types/Scope.ts", "../../src/types/Tier.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Standard error body returned by the control plane for any non-2xx response.\n * The `code` is a stable machine-readable identifier; `message` is the\n * human-readable description.\n */\nexport interface ApiErrorBody {\n code: ApiErrorCode\n message: string\n /**\n Optional request-correlation id for server logs.\n */\n requestId?: string\n}\n\nexport type ApiErrorCode\n = | 'bad_request'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'conflict'\n | 'unprocessable'\n | 'rate_limited'\n | 'internal'\n\nexport const API_ERROR_STATUS: Record<ApiErrorCode, number> = {\n bad_request: 400,\n unauthorized: 401,\n forbidden: 403,\n not_found: 404,\n conflict: 409,\n unprocessable: 422,\n rate_limited: 429,\n internal: 500,\n}\n\n/**\n * Thrown by `RestDatalakeClient` when the server returns a non-2xx response.\n * Carries the structured error body so callers can branch on `.code`.\n */\nexport class DatalakeApiError extends Error {\n readonly code: ApiErrorCode\n readonly requestId?: string\n readonly status: number\n\n constructor(status: number, body: ApiErrorBody) {\n super(body.message)\n this.name = 'DatalakeApiError'\n this.code = body.code\n this.status = status\n this.requestId = body.requestId\n }\n}\n", "/**\n * Canonical path builders for the datalake control-plane HTTP API.\n * Both the REST client and the control-plane service import from here so\n * the wire contract has a single source of truth.\n */\n\nexport const DATALAKE_API_VERSION = 'v1'\n\nexport function datalakeCollectionPath(): string {\n return `/${DATALAKE_API_VERSION}/datalakes`\n}\n\nexport function datalakeResourcePath(idOrName: string): string {\n return `${datalakeCollectionPath()}/${encodeURIComponent(idOrName)}`\n}\n\nexport function datalakeGrantsPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/grants`\n}\n\nexport function datalakeGrantPath(idOrName: string, principal: string): string {\n return `${datalakeGrantsPath(idOrName)}/${encodeURIComponent(principal)}`\n}\n\nexport function datalakeTokensPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/tokens`\n}\n\nexport function datalakeHealthPath(): string {\n return `/${DATALAKE_API_VERSION}/health`\n}\n", "/**\n * Data-plane path builders. The data plane is addressed by datalake id\n * (globally unique), not by name (which is scoped to owner). Route names\n * mirror the XYO archivist REST middleware (`/insert`, `/get/:hash`, `/next`)\n * so a generic archivist client can talk to a datalake-plane after picking\n * the per-datalake prefix.\n */\n\nimport { DATALAKE_API_VERSION } from './paths.ts'\n\n/**\n * Header that conveys how many payloads in the insert request were skipped\n * because their hash already existed in the datalake.\n */\nexport const DATALAKE_HEADER_DUPLICATES = 'x-datalake-duplicates'\n\n/**\n * Header that conveys the comma-separated list of archivist-computed\n * `_hash` values rejected by the datalake's schema policy.\n */\nexport const DATALAKE_HEADER_REJECTED = 'x-datalake-rejected'\n\n/**\n * Header that conveys the cursor (`_sequence`) of the last payload in a\n * `next` response page, when more pages may exist.\n */\nexport const DATALAKE_HEADER_NEXT_CURSOR = 'x-datalake-next-cursor'\n\nexport function datalakePlaneResourcePath(id: string): string {\n return `/${DATALAKE_API_VERSION}/datalakes/${encodeURIComponent(id)}`\n}\n\nexport function datalakePlaneInsertPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/insert`\n}\n\nexport function datalakePlaneGetPath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/get/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneGetManyPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/get`\n}\n\nexport function datalakePlaneNextPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/next`\n}\n\nexport function datalakePlaneDeletePath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/delete/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneClearPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/clear`\n}\n\nexport function datalakePlaneUsagePath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/usage`\n}\n", "/**\n * Access-control role granted to a principal on a datalake.\n * Maps 1:1 to XL1's DataLakeViewer (read) and DataLakeRunner (read/write) monikers.\n */\nexport type DatalakeRole = 'viewer' | 'runner'\n\n/**\n * A principal identifier. Either a control-plane user id, or the reserved\n * value `PUBLIC_PRINCIPAL` (`'public'`) which opens access to unauthenticated\n * callers at the granted role.\n */\nexport type DatalakePrincipal = string\n\nexport const PUBLIC_PRINCIPAL = 'public'\n\n/**\n * Type guard for the reserved `public` principal.\n */\nexport function isPublicPrincipal(principal: DatalakePrincipal): boolean {\n return principal === PUBLIC_PRINCIPAL\n}\n", "/**\n * Cloud regions where datalakes can be provisioned. Starts with AWS us-west-2;\n * additional regions are added as the control plane expands.\n */\nexport type DatalakeRegion = 'us-west-2' | 'us-east-1' | 'eu-west-1'\n\nexport const DATALAKE_REGIONS: readonly DatalakeRegion[] = ['us-west-2', 'us-east-1', 'eu-west-1'] as const\n\nexport const DEFAULT_REGION: DatalakeRegion = 'us-west-2'\n", "/**\nAudience used by browser wallet JWTs for control-plane operations.\n*/\nexport const DATALAKE_CONTROL_AUDIENCE = 'aries-datalake-control'\n\n/**\nSchema required on every wallet sign-in JWT accepted by Aries.\n*/\nexport const DATALAKE_WALLET_JWT_SCHEMA = 'network.xyo.auth.signin'\n\n/**\nBrowser operations intentionally exposed by the datalake control plane.\n*/\nexport const DATALAKE_CONTROL_OPERATIONS = [\n 'datalake:create',\n 'datalake:describe',\n 'datalake:list',\n] as const\n\n/**\nBrowser operations intentionally exposed by the datalake data plane.\n*/\nexport const DATALAKE_DATA_OPERATIONS = [\n 'payload:append',\n 'payload:read',\n 'usage:read',\n] as const\n\nexport type DatalakeControlOperation = typeof DATALAKE_CONTROL_OPERATIONS[number]\nexport type DatalakeDataOperation = typeof DATALAKE_DATA_OPERATIONS[number]\nexport type DatalakeOperation = DatalakeControlOperation | DatalakeDataOperation\n\n/**\nCanonical complete scope strings used when requesting browser wallet approval.\n*/\nexport const DATALAKE_CONTROL_SCOPE = DATALAKE_CONTROL_OPERATIONS.join(' ')\nexport const DATALAKE_DATA_SCOPE = DATALAKE_DATA_OPERATIONS.join(' ')\n\nexport function isDatalakeControlOperation(value: string): value is DatalakeControlOperation {\n return (DATALAKE_CONTROL_OPERATIONS as readonly string[]).includes(value)\n}\n\nexport function isDatalakeDataOperation(value: string): value is DatalakeDataOperation {\n return (DATALAKE_DATA_OPERATIONS as readonly string[]).includes(value)\n}\n", "/**\n * Datalake service tiers. Each tier maps to a storage driver + resource profile\n * on the control plane: small/medium use the shared hot pool, large gets a\n * dedicated RestDataLake pod, archive uses the S3 + DynamoDB cold driver.\n */\nexport type DatalakeTier = 'small' | 'medium' | 'large' | 'archive'\n\nexport const DATALAKE_TIERS: readonly DatalakeTier[] = ['small', 'medium', 'large', 'archive'] as const\n"],
|
|
5
|
-
"mappings": ";AAwBO,IAAM,mBAAiD;AAAA,EAC5D,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA,EACf,cAAc;AAAA,EACd,UAAU;AACZ;AAMO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,MAAoB;AAC9C,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,SAAS;AACd,SAAK,YAAY,KAAK;AAAA,EACxB;AACF;;;AC7CO,IAAM,uBAAuB;AAE7B,SAAS,yBAAiC;AAC/C,SAAO,IAAI,oBAAoB;AACjC;AAEO,SAAS,qBAAqB,UAA0B;AAC7D,SAAO,GAAG,uBAAuB,CAAC,IAAI,mBAAmB,QAAQ,CAAC;AACpE;AAEO,SAAS,mBAAmB,UAA0B;AAC3D,SAAO,GAAG,qBAAqB,QAAQ,CAAC;AAC1C;AAEO,SAAS,kBAAkB,UAAkB,WAA2B;AAC7E,SAAO,GAAG,mBAAmB,QAAQ,CAAC,IAAI,mBAAmB,SAAS,CAAC;AACzE;AAEO,SAAS,mBAAmB,UAA0B;AAC3D,SAAO,GAAG,qBAAqB,QAAQ,CAAC;AAC1C;AAEO,SAAS,qBAA6B;AAC3C,SAAO,IAAI,oBAAoB;AACjC;;;AChBO,IAAM,6BAA6B;AAMnC,IAAM,2BAA2B;AAMjC,IAAM,8BAA8B;AAEpC,SAAS,0BAA0B,IAAoB;AAC5D,SAAO,IAAI,oBAAoB,cAAc,mBAAmB,EAAE,CAAC;AACrE;AAEO,SAAS,wBAAwB,IAAoB;AAC1D,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,qBAAqB,IAAY,MAAsB;AACrE,SAAO,GAAG,0BAA0B,EAAE,CAAC,QAAQ,mBAAmB,IAAI,CAAC;AACzE;AAEO,SAAS,yBAAyB,IAAoB;AAC3D,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,sBAAsB,IAAoB;AACxD,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,wBAAwB,IAAY,MAAsB;AACxE,SAAO,GAAG,0BAA0B,EAAE,CAAC,WAAW,mBAAmB,IAAI,CAAC;AAC5E;AAEO,SAAS,uBAAuB,IAAoB;AACzD,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,uBAAuB,IAAoB;AACzD,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;;;
|
|
3
|
+
"sources": ["../../src/api/errors.ts", "../../src/api/paths.ts", "../../src/api/planePaths.ts", "../../src/types/DatalakeConfig.ts", "../../src/types/Principal.ts", "../../src/types/Region.ts", "../../src/types/Scope.ts", "../../src/types/Tier.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Standard error body returned by the control plane for any non-2xx response.\n * The `code` is a stable machine-readable identifier; `message` is the\n * human-readable description.\n */\nexport interface ApiErrorBody {\n code: ApiErrorCode\n message: string\n /**\n Optional request-correlation id for server logs.\n */\n requestId?: string\n}\n\nexport type ApiErrorCode\n = | 'bad_request'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'conflict'\n | 'unprocessable'\n | 'rate_limited'\n | 'internal'\n\nexport const API_ERROR_STATUS: Record<ApiErrorCode, number> = {\n bad_request: 400,\n unauthorized: 401,\n forbidden: 403,\n not_found: 404,\n conflict: 409,\n unprocessable: 422,\n rate_limited: 429,\n internal: 500,\n}\n\n/**\n * Thrown by `RestDatalakeClient` when the server returns a non-2xx response.\n * Carries the structured error body so callers can branch on `.code`.\n */\nexport class DatalakeApiError extends Error {\n readonly code: ApiErrorCode\n readonly requestId?: string\n readonly status: number\n\n constructor(status: number, body: ApiErrorBody) {\n super(body.message)\n this.name = 'DatalakeApiError'\n this.code = body.code\n this.status = status\n this.requestId = body.requestId\n }\n}\n", "/**\n * Canonical path builders for the datalake control-plane HTTP API.\n * Both the REST client and the control-plane service import from here so\n * the wire contract has a single source of truth.\n */\n\nexport const DATALAKE_API_VERSION = 'v1'\n\nexport function datalakeCollectionPath(): string {\n return `/${DATALAKE_API_VERSION}/datalakes`\n}\n\nexport function datalakeResourcePath(idOrName: string): string {\n return `${datalakeCollectionPath()}/${encodeURIComponent(idOrName)}`\n}\n\nexport function datalakeGrantsPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/grants`\n}\n\nexport function datalakeGrantPath(idOrName: string, principal: string): string {\n return `${datalakeGrantsPath(idOrName)}/${encodeURIComponent(principal)}`\n}\n\nexport function datalakeTokensPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/tokens`\n}\n\nexport function datalakeHealthPath(): string {\n return `/${DATALAKE_API_VERSION}/health`\n}\n", "/**\n * Data-plane path builders. The data plane is addressed by datalake id\n * (globally unique), not by name (which is scoped to owner). Route names\n * mirror the XYO archivist REST middleware (`/insert`, `/get/:hash`, `/next`)\n * so a generic archivist client can talk to a datalake-plane after picking\n * the per-datalake prefix.\n */\n\nimport { DATALAKE_API_VERSION } from './paths.ts'\n\n/**\n * Header that conveys how many payloads in the insert request were skipped\n * because their hash already existed in the datalake.\n */\nexport const DATALAKE_HEADER_DUPLICATES = 'x-datalake-duplicates'\n\n/**\n * Header that conveys the comma-separated list of archivist-computed\n * `_hash` values rejected by the datalake's schema policy.\n */\nexport const DATALAKE_HEADER_REJECTED = 'x-datalake-rejected'\n\n/**\n * Header that conveys the cursor (`_sequence`) of the last payload in a\n * `next` response page, when more pages may exist.\n */\nexport const DATALAKE_HEADER_NEXT_CURSOR = 'x-datalake-next-cursor'\n\nexport function datalakePlaneResourcePath(id: string): string {\n return `/${DATALAKE_API_VERSION}/datalakes/${encodeURIComponent(id)}`\n}\n\nexport function datalakePlaneInsertPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/insert`\n}\n\nexport function datalakePlaneGetPath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/get/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneGetManyPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/get`\n}\n\nexport function datalakePlaneNextPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/next`\n}\n\nexport function datalakePlaneDeletePath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/delete/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneClearPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/clear`\n}\n\nexport function datalakePlaneUsagePath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/usage`\n}\n", "import type { DatalakeRegion } from './Region.ts'\nimport type { DatalakeTier } from './Tier.ts'\n\n/**\n * User-supplied configuration for provisioning a new datalake. All fields are\n * optional except tier; the control plane applies defaults for the rest.\n */\nexport interface DatalakeConfig {\n /**\n Payload schemas allowed for insert. In allowlist mode an explicit empty\n array accepts no schemas; otherwise an empty array retains legacy unrestricted admission.\n */\n allowedSchemas?: string[]\n /**\n Payload schemas disallowed for insert.\n */\n disallowedSchemas?: string[]\n /**\n Provisioned IOPS target. Ignored for the archive tier.\n */\n iops?: number\n /**\n * Maximum UTF-8 JSON bytes per payload, excluding server storage metadata\n * but including client metadata, before compression. Required in allowlist mode.\n */\n maxPayloadBytes?: number\n /**\n * Per-datalake rate-limit overrides. When omitted, the data plane's\n * default limits apply. Use this to tighten compliance-sensitive\n * datalakes or relax a limit for a trusted internal tenant.\n */\n rateLimits?: RateLimitOverrides\n /**\n Deployment region.\n */\n region?: DatalakeRegion\n /**\n Retention policy in days. `null` means keep forever.\n */\n retentionDays?: number | null\n /**\n * Optional per-schema byte ceilings. A schema limit can only tighten\n * maxPayloadBytes, never raise the global ceiling.\n */\n schemaMaxPayloadBytes?: Record<string, number>\n /**\n * Explicit strict admission. Requires allowedSchemas to be supplied and a\n * finite positive maxPayloadBytes. Omission retains legacy schema semantics.\n */\n schemaPolicy?: 'allowlist'\n /**\n Provisioned capacity in bytes. Ignored for the archive tier.\n */\n sizeBytes?: number\n /**\n Service tier (controls storage driver, IOPS ceiling, compute shape).\n */\n tier: DatalakeTier\n /**\n * Reserved. The archivist always recomputes `_hash` and `_dataHash` from\n * payload bytes trustlessly, so this flag is a no-op. Kept on the type so\n * older configs still parse; will be removed in a future major.\n *\n * @deprecated archivist is the trustless authority \u2014 no client-supplied\n * hash is honored.\n */\n verifyHashes?: boolean\n}\n\n/** Validate admission settings before persisting or applying a policy. */\nexport function validateDatalakeAdmissionConfig(config: DatalakeConfig): void {\n if (config.schemaPolicy !== undefined && config.schemaPolicy !== 'allowlist') {\n throw new TypeError('schemaPolicy must be allowlist when supplied')\n }\n if (config.schemaPolicy === 'allowlist' && !Array.isArray(config.allowedSchemas)) {\n throw new TypeError('allowedSchemas must be explicitly supplied in allowlist mode; use [] to accept no payloads')\n }\n for (const [name, schemas] of [['allowedSchemas', config.allowedSchemas], ['disallowedSchemas', config.disallowedSchemas]] as const) {\n if (schemas !== undefined && (!Array.isArray(schemas) || schemas.some(schema => typeof schema !== 'string' || schema.length === 0))) {\n throw new TypeError(`${name} must be an array of non-empty schema strings`)\n }\n }\n if (config.maxPayloadBytes !== undefined || config.schemaPolicy === 'allowlist') {\n requireByteLimit(config.maxPayloadBytes, 'maxPayloadBytes')\n }\n if (config.schemaMaxPayloadBytes !== undefined) {\n if (!config.schemaMaxPayloadBytes || typeof config.schemaMaxPayloadBytes !== 'object' || Array.isArray(config.schemaMaxPayloadBytes)) {\n throw new TypeError('schemaMaxPayloadBytes must map schema strings to positive byte limits')\n }\n for (const [schema, limit] of Object.entries(config.schemaMaxPayloadBytes)) {\n if (schema.length === 0) throw new TypeError('schemaMaxPayloadBytes keys must be non-empty schema strings')\n requireByteLimit(limit, `schemaMaxPayloadBytes[${schema}]`)\n }\n }\n}\n\nfunction requireByteLimit(value: number | undefined, field: string): void {\n if (!Number.isSafeInteger(value) || (value ?? 0) <= 0) {\n throw new TypeError(`${field} must be a finite positive safe integer byte count`)\n }\n}\n\nexport interface RateLimitOverrides {\n /**\n Max anonymous requests per minute.\n */\n anonymousPerMinute?: number\n /**\n Max authenticated requests per minute.\n */\n authenticatedPerMinute?: number\n /**\n * Burst multiplier (1 = no burst). Bucket capacity = perMinute * burstFactor.\n */\n burstFactor?: number\n}\n", "/**\n * Access-control role granted to a principal on a datalake.\n * Maps 1:1 to XL1's DataLakeViewer (read) and DataLakeRunner (read/write) monikers.\n */\nexport type DatalakeRole = 'viewer' | 'runner'\n\n/**\n * A principal identifier. Either a control-plane user id, or the reserved\n * value `PUBLIC_PRINCIPAL` (`'public'`) which opens access to unauthenticated\n * callers at the granted role.\n */\nexport type DatalakePrincipal = string\n\nexport const PUBLIC_PRINCIPAL = 'public'\n\n/**\n * Type guard for the reserved `public` principal.\n */\nexport function isPublicPrincipal(principal: DatalakePrincipal): boolean {\n return principal === PUBLIC_PRINCIPAL\n}\n", "/**\n * Cloud regions where datalakes can be provisioned. Starts with AWS us-west-2;\n * additional regions are added as the control plane expands.\n */\nexport type DatalakeRegion = 'us-west-2' | 'us-east-1' | 'eu-west-1'\n\nexport const DATALAKE_REGIONS: readonly DatalakeRegion[] = ['us-west-2', 'us-east-1', 'eu-west-1'] as const\n\nexport const DEFAULT_REGION: DatalakeRegion = 'us-west-2'\n", "/**\nAudience used by browser wallet JWTs for control-plane operations.\n*/\nexport const DATALAKE_CONTROL_AUDIENCE = 'aries-datalake-control'\n\n/**\nSchema required on every wallet sign-in JWT accepted by Aries.\n*/\nexport const DATALAKE_WALLET_JWT_SCHEMA = 'network.xyo.auth.signin'\n\n/**\nBrowser operations intentionally exposed by the datalake control plane.\n*/\nexport const DATALAKE_CONTROL_OPERATIONS = [\n 'datalake:create',\n 'datalake:describe',\n 'datalake:list',\n] as const\n\n/**\nBrowser operations intentionally exposed by the datalake data plane.\n*/\nexport const DATALAKE_DATA_OPERATIONS = [\n 'payload:append',\n 'payload:read',\n 'usage:read',\n] as const\n\nexport type DatalakeControlOperation = typeof DATALAKE_CONTROL_OPERATIONS[number]\nexport type DatalakeDataOperation = typeof DATALAKE_DATA_OPERATIONS[number]\nexport type DatalakeOperation = DatalakeControlOperation | DatalakeDataOperation\n\n/**\nCanonical complete scope strings used when requesting browser wallet approval.\n*/\nexport const DATALAKE_CONTROL_SCOPE = DATALAKE_CONTROL_OPERATIONS.join(' ')\nexport const DATALAKE_DATA_SCOPE = DATALAKE_DATA_OPERATIONS.join(' ')\n\nexport function isDatalakeControlOperation(value: string): value is DatalakeControlOperation {\n return (DATALAKE_CONTROL_OPERATIONS as readonly string[]).includes(value)\n}\n\nexport function isDatalakeDataOperation(value: string): value is DatalakeDataOperation {\n return (DATALAKE_DATA_OPERATIONS as readonly string[]).includes(value)\n}\n", "/**\n * Datalake service tiers. Each tier maps to a storage driver + resource profile\n * on the control plane: small/medium use the shared hot pool, large gets a\n * dedicated RestDataLake pod, archive uses the S3 + DynamoDB cold driver.\n */\nexport type DatalakeTier = 'small' | 'medium' | 'large' | 'archive'\n\nexport const DATALAKE_TIERS: readonly DatalakeTier[] = ['small', 'medium', 'large', 'archive'] as const\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -6,7 +6,8 @@ import type { DatalakeTier } from './Tier.ts';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface DatalakeConfig {
|
|
8
8
|
/**
|
|
9
|
-
Payload schemas allowed for insert
|
|
9
|
+
Payload schemas allowed for insert. In allowlist mode an explicit empty
|
|
10
|
+
array accepts no schemas; otherwise an empty array retains legacy unrestricted admission.
|
|
10
11
|
*/
|
|
11
12
|
allowedSchemas?: string[];
|
|
12
13
|
/**
|
|
@@ -17,6 +18,11 @@ export interface DatalakeConfig {
|
|
|
17
18
|
Provisioned IOPS target. Ignored for the archive tier.
|
|
18
19
|
*/
|
|
19
20
|
iops?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum UTF-8 JSON bytes per payload, excluding server storage metadata
|
|
23
|
+
* but including client metadata, before compression. Required in allowlist mode.
|
|
24
|
+
*/
|
|
25
|
+
maxPayloadBytes?: number;
|
|
20
26
|
/**
|
|
21
27
|
* Per-datalake rate-limit overrides. When omitted, the data plane's
|
|
22
28
|
* default limits apply. Use this to tighten compliance-sensitive
|
|
@@ -31,6 +37,16 @@ export interface DatalakeConfig {
|
|
|
31
37
|
Retention policy in days. `null` means keep forever.
|
|
32
38
|
*/
|
|
33
39
|
retentionDays?: number | null;
|
|
40
|
+
/**
|
|
41
|
+
* Optional per-schema byte ceilings. A schema limit can only tighten
|
|
42
|
+
* maxPayloadBytes, never raise the global ceiling.
|
|
43
|
+
*/
|
|
44
|
+
schemaMaxPayloadBytes?: Record<string, number>;
|
|
45
|
+
/**
|
|
46
|
+
* Explicit strict admission. Requires allowedSchemas to be supplied and a
|
|
47
|
+
* finite positive maxPayloadBytes. Omission retains legacy schema semantics.
|
|
48
|
+
*/
|
|
49
|
+
schemaPolicy?: 'allowlist';
|
|
34
50
|
/**
|
|
35
51
|
Provisioned capacity in bytes. Ignored for the archive tier.
|
|
36
52
|
*/
|
|
@@ -49,6 +65,8 @@ export interface DatalakeConfig {
|
|
|
49
65
|
*/
|
|
50
66
|
verifyHashes?: boolean;
|
|
51
67
|
}
|
|
68
|
+
/** Validate admission settings before persisting or applying a policy. */
|
|
69
|
+
export declare function validateDatalakeAdmissionConfig(config: DatalakeConfig): void;
|
|
52
70
|
export interface RateLimitOverrides {
|
|
53
71
|
/**
|
|
54
72
|
Max anonymous requests per minute.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatalakeConfig.d.ts","sourceRoot":"","sources":["../../../src/types/DatalakeConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B
|
|
1
|
+
{"version":3,"file":"DatalakeConfig.d.ts","sourceRoot":"","sources":["../../../src/types/DatalakeConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;MAGE;IACF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB;;MAEE;IACF,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B;;MAEE;IACF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAA;IAC/B;;MAEE;IACF,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB;;MAEE;IACF,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9C;;;OAGG;IACH,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B;;MAEE;IACF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;MAEE;IACF,IAAI,EAAE,YAAY,CAAA;IAClB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,0EAA0E;AAC1E,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAwB5E;AAQD,MAAM,WAAW,kBAAkB;IACjC;;MAEE;IACF,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;MAEE;IACF,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionTokenCodec.d.ts","sourceRoot":"","sources":["../../../src/auth/sessionTokenCodec.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AAEH,MAAM,WAAW,mBAAmB;IAClC;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,SAAS,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd;AAOD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"sessionTokenCodec.d.ts","sourceRoot":"","sources":["../../../src/auth/sessionTokenCodec.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AAEH,MAAM,WAAW,mBAAmB;IAClC;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,SAAS,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd;AAOD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,kBAAkB,CAmBjF;AAED,MAAM,MAAM,iCAAiC,GAAG,WAAW,GAAG,eAAe,GAAG,SAAS,GAAG,eAAe,GAAG,YAAY,CAAA;AAE1H,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,IAAI,EAAE,iCAAiC,CAAA;gBAEpC,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,MAAM;CAKrE;AAED,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,mBAAmB,CAkCtF;AAED;;;;;GAKG;AAEH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,WAAW,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,CAmBxE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,qBAAqB,CAmCxH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenCodec.d.ts","sourceRoot":"","sources":["../../../src/auth/tokenCodec.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAKtD;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B;;MAEE;IACF,EAAE,EAAE,MAAM,CAAA;IACV;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,IAAI,EAAE,YAAY,CAAA;IAClB;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,YAAY,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;CACZ;AAOD,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"tokenCodec.d.ts","sourceRoot":"","sources":["../../../src/auth/tokenCodec.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAKtD;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B;;MAEE;IACF,EAAE,EAAE,MAAM,CAAA;IACV;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;IACX;;MAEE;IACF,IAAI,EAAE,YAAY,CAAA;IAClB;;MAEE;IACF,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,YAAY,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;CACZ;AAOD,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,aAAa,CAuB9D;AAED,MAAM,MAAM,0BAA0B,GAAG,WAAW,GAAG,eAAe,GAAG,SAAS,GAAG,eAAe,CAAA;AAEpG,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAA;gBAE7B,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM;CAK9D;AAED,MAAM,WAAW,gBAAgB;IAC/B;;MAEE;IACF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAwCjE"}
|
package/dist/node/browser.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type { CreateDatalakeBody, GrantBody, MintTokenBody, } from './api/reques
|
|
|
7
7
|
export type { AclEntry } from './types/AclEntry.ts';
|
|
8
8
|
export type { DatalakeInsertSummary, InsertPayloadsBody, InsertPayloadsResponse, InsertPayloadsResult, JsonObject, JsonPrimitive, JsonValue, NextPayloadsOptions, NextPayloadsResponse, NextPayloadsResult, Payload, StorageMeta, StoredPayload, WithStorageMeta, } from './types/BrowserPayload.ts';
|
|
9
9
|
export type { DatalakeConfig, RateLimitOverrides } from './types/DatalakeConfig.ts';
|
|
10
|
+
export { validateDatalakeAdmissionConfig } from './types/DatalakeConfig.ts';
|
|
10
11
|
export type { DatalakeDescriptor, DatalakeUsage } from './types/DatalakeDescriptor.ts';
|
|
11
12
|
export type { DatalakePrincipal, DatalakeRole } from './types/Principal.ts';
|
|
12
13
|
export { isPublicPrincipal, PUBLIC_PRINCIPAL } from './types/Principal.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,kBAAkB,EAAE,SAAS,EAAE,aAAa,GAC7C,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,OAAO,EACP,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnF,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AACtF,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACpE,YAAY,EACV,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,GACnE,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,kBAAkB,EAAE,SAAS,EAAE,aAAa,GAC7C,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,OAAO,EACP,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnF,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;AAC3E,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AACtF,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACpE,YAAY,EACV,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,GACnE,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/node/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type { DatalakeStore } from './store/DatalakeStore.ts';
|
|
|
12
12
|
export { ROLE_RANK } from './store/DatalakeStore.ts';
|
|
13
13
|
export type { AclEntry } from './types/AclEntry.ts';
|
|
14
14
|
export type { DatalakeConfig, RateLimitOverrides } from './types/DatalakeConfig.ts';
|
|
15
|
+
export { validateDatalakeAdmissionConfig } from './types/DatalakeConfig.ts';
|
|
15
16
|
export type { DatalakeDescriptor, DatalakeUsage } from './types/DatalakeDescriptor.ts';
|
|
16
17
|
export type { DatalakeInsertSummary, InsertPayloadsBody, InsertPayloadsResponse, InsertPayloadsResult, NextPayloadsOptions, NextPayloadsResponse, NextPayloadsResult, Payload, StoredPayload, WithStorageMeta, } from './types/Payload.ts';
|
|
17
18
|
export type { DatalakePrincipal, DatalakeRole } from './types/Principal.ts';
|
package/dist/node/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,kBAAkB,EAAE,SAAS,EAAE,aAAa,GAC7C,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,iCAAiC,EACjC,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,6BAA6B,EAC7B,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,6BAA6B,CAAA;AACpC,YAAY,EACV,cAAc,EACd,YAAY,EACZ,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,SAAS,EAAE,sBAAsB,EAAE,WAAW,GAC/C,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnF,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AACtF,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACpE,YAAY,EACV,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,GACnE,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,kBAAkB,EAAE,SAAS,EAAE,aAAa,GAC7C,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,iCAAiC,EACjC,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,6BAA6B,EAC7B,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,6BAA6B,CAAA;AACpC,YAAY,EACV,cAAc,EACd,YAAY,EACZ,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,SAAS,EAAE,sBAAsB,EAAE,WAAW,GAC/C,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnF,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;AAC3E,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AACtF,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACpE,YAAY,EACV,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,GACnE,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/node/index.mjs
CHANGED
|
@@ -103,14 +103,14 @@ function verifyStrictHs256(token, signingSecret) {
|
|
|
103
103
|
return { payload: decodeJsonObject(payloadPart, "Payload") };
|
|
104
104
|
}
|
|
105
105
|
function assertExactKeys(value, expected, label) {
|
|
106
|
-
const actual = Object.keys(value).
|
|
107
|
-
const canonical = [...expected].
|
|
106
|
+
const actual = Object.keys(value).toSorted();
|
|
107
|
+
const canonical = [...expected].toSorted();
|
|
108
108
|
if (actual.length !== canonical.length || actual.some((key, index) => key !== canonical[index])) {
|
|
109
109
|
throw new StrictHs256Error("malformed", `${label} fields must be exactly: ${canonical.join(", ")}`);
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
function isFiniteInteger(value) {
|
|
113
|
-
return typeof value === "number" && Number.isFinite(value) && Number.
|
|
113
|
+
return typeof value === "number" && Number.isFinite(value) && Number.isSafeInteger(value);
|
|
114
114
|
}
|
|
115
115
|
function isNonEmptyString(value) {
|
|
116
116
|
return typeof value === "string" && value.length > 0;
|
|
@@ -118,7 +118,8 @@ function isNonEmptyString(value) {
|
|
|
118
118
|
function decodeJsonObject(value, label) {
|
|
119
119
|
let parsed;
|
|
120
120
|
try {
|
|
121
|
-
|
|
121
|
+
const decoder = new TextDecoder();
|
|
122
|
+
parsed = JSON.parse(decoder.decode(decodeBase64Url(value, label)));
|
|
122
123
|
} catch (error) {
|
|
123
124
|
if (error instanceof StrictHs256Error) throw error;
|
|
124
125
|
throw new StrictHs256Error("malformed", `${label} is not valid JSON`);
|
|
@@ -158,9 +159,10 @@ function signSessionToken(input) {
|
|
|
158
159
|
const body = base64UrlEncode(JSON.stringify(payload));
|
|
159
160
|
const toSign = `${header}.${body}`;
|
|
160
161
|
const signature = createHmac2("sha256", input.signingSecret).update(toSign).digest("base64url");
|
|
162
|
+
const expiresAtDate = new Date(expiresAt * 1e3);
|
|
161
163
|
return {
|
|
162
164
|
token: `${toSign}.${signature}`,
|
|
163
|
-
expiresAt:
|
|
165
|
+
expiresAt: expiresAtDate.toISOString()
|
|
164
166
|
};
|
|
165
167
|
}
|
|
166
168
|
var SessionTokenVerificationError = class extends Error {
|
|
@@ -219,9 +221,10 @@ function signChallenge(input) {
|
|
|
219
221
|
const body = base64UrlEncode(JSON.stringify(payload));
|
|
220
222
|
const toSign = `${header}.${body}`;
|
|
221
223
|
const signature = createHmac2("sha256", input.signingSecret).update(toSign).digest("base64url");
|
|
224
|
+
const expiresAtDate = new Date(expiresAt * 1e3);
|
|
222
225
|
return {
|
|
223
226
|
challenge: `${toSign}.${signature}`,
|
|
224
|
-
expiresAt:
|
|
227
|
+
expiresAt: expiresAtDate.toISOString()
|
|
225
228
|
};
|
|
226
229
|
}
|
|
227
230
|
function verifyChallenge(input) {
|
|
@@ -282,11 +285,12 @@ function signToken(input) {
|
|
|
282
285
|
const body = base64UrlEncode2(JSON.stringify(payload));
|
|
283
286
|
const toSign = `${header}.${body}`;
|
|
284
287
|
const signature = createHmac3("sha256", input.signingSecret).update(toSign).digest("base64url");
|
|
288
|
+
const expiresAtDate = new Date(expiresAt * 1e3);
|
|
285
289
|
return {
|
|
286
290
|
token: `${toSign}.${signature}`,
|
|
287
291
|
datalakeId: input.datalakeId,
|
|
288
292
|
role: input.role,
|
|
289
|
-
expiresAt:
|
|
293
|
+
expiresAt: expiresAtDate.toISOString(),
|
|
290
294
|
url: input.url
|
|
291
295
|
};
|
|
292
296
|
}
|
|
@@ -342,6 +346,38 @@ var ROLE_RANK = {
|
|
|
342
346
|
runner: 2
|
|
343
347
|
};
|
|
344
348
|
|
|
349
|
+
// src/types/DatalakeConfig.ts
|
|
350
|
+
function validateDatalakeAdmissionConfig(config) {
|
|
351
|
+
if (config.schemaPolicy !== void 0 && config.schemaPolicy !== "allowlist") {
|
|
352
|
+
throw new TypeError("schemaPolicy must be allowlist when supplied");
|
|
353
|
+
}
|
|
354
|
+
if (config.schemaPolicy === "allowlist" && !Array.isArray(config.allowedSchemas)) {
|
|
355
|
+
throw new TypeError("allowedSchemas must be explicitly supplied in allowlist mode; use [] to accept no payloads");
|
|
356
|
+
}
|
|
357
|
+
for (const [name, schemas] of [["allowedSchemas", config.allowedSchemas], ["disallowedSchemas", config.disallowedSchemas]]) {
|
|
358
|
+
if (schemas !== void 0 && (!Array.isArray(schemas) || schemas.some((schema) => typeof schema !== "string" || schema.length === 0))) {
|
|
359
|
+
throw new TypeError(`${name} must be an array of non-empty schema strings`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (config.maxPayloadBytes !== void 0 || config.schemaPolicy === "allowlist") {
|
|
363
|
+
requireByteLimit(config.maxPayloadBytes, "maxPayloadBytes");
|
|
364
|
+
}
|
|
365
|
+
if (config.schemaMaxPayloadBytes !== void 0) {
|
|
366
|
+
if (!config.schemaMaxPayloadBytes || typeof config.schemaMaxPayloadBytes !== "object" || Array.isArray(config.schemaMaxPayloadBytes)) {
|
|
367
|
+
throw new TypeError("schemaMaxPayloadBytes must map schema strings to positive byte limits");
|
|
368
|
+
}
|
|
369
|
+
for (const [schema, limit] of Object.entries(config.schemaMaxPayloadBytes)) {
|
|
370
|
+
if (schema.length === 0) throw new TypeError("schemaMaxPayloadBytes keys must be non-empty schema strings");
|
|
371
|
+
requireByteLimit(limit, `schemaMaxPayloadBytes[${schema}]`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function requireByteLimit(value, field) {
|
|
376
|
+
if (!Number.isSafeInteger(value) || (value ?? 0) <= 0) {
|
|
377
|
+
throw new TypeError(`${field} must be a finite positive safe integer byte count`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
345
381
|
// src/types/Principal.ts
|
|
346
382
|
var PUBLIC_PRINCIPAL = "public";
|
|
347
383
|
function isPublicPrincipal(principal) {
|
|
@@ -416,6 +452,7 @@ export {
|
|
|
416
452
|
signChallenge,
|
|
417
453
|
signSessionToken,
|
|
418
454
|
signToken,
|
|
455
|
+
validateDatalakeAdmissionConfig,
|
|
419
456
|
verifyChallenge,
|
|
420
457
|
verifySessionToken,
|
|
421
458
|
verifyToken
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/api/errors.ts", "../../src/api/paths.ts", "../../src/api/planePaths.ts", "../../src/auth/sessionTokenCodec.ts", "../../src/auth/strictHs256.ts", "../../src/auth/tokenCodec.ts", "../../src/store/DatalakeStore.ts", "../../src/types/Principal.ts", "../../src/types/Region.ts", "../../src/types/Scope.ts", "../../src/types/Tier.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Standard error body returned by the control plane for any non-2xx response.\n * The `code` is a stable machine-readable identifier; `message` is the\n * human-readable description.\n */\nexport interface ApiErrorBody {\n code: ApiErrorCode\n message: string\n /**\n Optional request-correlation id for server logs.\n */\n requestId?: string\n}\n\nexport type ApiErrorCode\n = | 'bad_request'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'conflict'\n | 'unprocessable'\n | 'rate_limited'\n | 'internal'\n\nexport const API_ERROR_STATUS: Record<ApiErrorCode, number> = {\n bad_request: 400,\n unauthorized: 401,\n forbidden: 403,\n not_found: 404,\n conflict: 409,\n unprocessable: 422,\n rate_limited: 429,\n internal: 500,\n}\n\n/**\n * Thrown by `RestDatalakeClient` when the server returns a non-2xx response.\n * Carries the structured error body so callers can branch on `.code`.\n */\nexport class DatalakeApiError extends Error {\n readonly code: ApiErrorCode\n readonly requestId?: string\n readonly status: number\n\n constructor(status: number, body: ApiErrorBody) {\n super(body.message)\n this.name = 'DatalakeApiError'\n this.code = body.code\n this.status = status\n this.requestId = body.requestId\n }\n}\n", "/**\n * Canonical path builders for the datalake control-plane HTTP API.\n * Both the REST client and the control-plane service import from here so\n * the wire contract has a single source of truth.\n */\n\nexport const DATALAKE_API_VERSION = 'v1'\n\nexport function datalakeCollectionPath(): string {\n return `/${DATALAKE_API_VERSION}/datalakes`\n}\n\nexport function datalakeResourcePath(idOrName: string): string {\n return `${datalakeCollectionPath()}/${encodeURIComponent(idOrName)}`\n}\n\nexport function datalakeGrantsPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/grants`\n}\n\nexport function datalakeGrantPath(idOrName: string, principal: string): string {\n return `${datalakeGrantsPath(idOrName)}/${encodeURIComponent(principal)}`\n}\n\nexport function datalakeTokensPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/tokens`\n}\n\nexport function datalakeHealthPath(): string {\n return `/${DATALAKE_API_VERSION}/health`\n}\n", "/**\n * Data-plane path builders. The data plane is addressed by datalake id\n * (globally unique), not by name (which is scoped to owner). Route names\n * mirror the XYO archivist REST middleware (`/insert`, `/get/:hash`, `/next`)\n * so a generic archivist client can talk to a datalake-plane after picking\n * the per-datalake prefix.\n */\n\nimport { DATALAKE_API_VERSION } from './paths.ts'\n\n/**\n * Header that conveys how many payloads in the insert request were skipped\n * because their hash already existed in the datalake.\n */\nexport const DATALAKE_HEADER_DUPLICATES = 'x-datalake-duplicates'\n\n/**\n * Header that conveys the comma-separated list of archivist-computed\n * `_hash` values rejected by the datalake's schema policy.\n */\nexport const DATALAKE_HEADER_REJECTED = 'x-datalake-rejected'\n\n/**\n * Header that conveys the cursor (`_sequence`) of the last payload in a\n * `next` response page, when more pages may exist.\n */\nexport const DATALAKE_HEADER_NEXT_CURSOR = 'x-datalake-next-cursor'\n\nexport function datalakePlaneResourcePath(id: string): string {\n return `/${DATALAKE_API_VERSION}/datalakes/${encodeURIComponent(id)}`\n}\n\nexport function datalakePlaneInsertPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/insert`\n}\n\nexport function datalakePlaneGetPath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/get/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneGetManyPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/get`\n}\n\nexport function datalakePlaneNextPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/next`\n}\n\nexport function datalakePlaneDeletePath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/delete/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneClearPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/clear`\n}\n\nexport function datalakePlaneUsagePath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/usage`\n}\n", "import { createHmac, randomBytes } from 'node:crypto'\n\nimport {\n assertExactKeys, isFiniteInteger, isNonEmptyString, StrictHs256Error, verifyStrictHs256,\n} from './strictHs256.ts'\n\n/**\n * Session tokens issued after a successful XYO Wallet sign-in. The wire\n * format mirrors `tokenCodec.ts` (HS256 JWT) but the payload carries no\n * `dl` claim \u2014 sessions are scoped to a user (wallet address), not a\n * single datalake. The control plane mints these; both planes verify\n * them via `verifySessionToken`.\n */\n\nexport interface SessionTokenPayload {\n /**\n Expiration (seconds since epoch).\n */\n exp: number\n /**\n Issued-at (seconds since epoch).\n */\n iat: number\n /**\n Unique token id.\n */\n jti: string\n /**\n Wallet address that authenticated; used as the `ownerId`.\n */\n sub: string\n /**\n Token kind. Always `'session'` for this codec.\n */\n typ: 'session'\n}\n\nexport interface SignSessionTokenInput {\n address: string\n signingSecret: string\n ttlSeconds: number\n}\n\nexport interface SignedSessionToken {\n expiresAt: string\n token: string\n}\n\nfunction base64UrlEncode(input: Buffer | string): string {\n const buffer = typeof input === 'string' ? Buffer.from(input) : input\n return buffer.toString('base64url')\n}\n\nexport function signSessionToken(input: SignSessionTokenInput): SignedSessionToken {\n const issuedAt = Math.floor(Date.now() / 1000)\n const expiresAt = issuedAt + input.ttlSeconds\n const payload: SessionTokenPayload = {\n sub: input.address.toLowerCase(),\n typ: 'session',\n iat: issuedAt,\n exp: expiresAt,\n jti: randomBytes(8).toString('hex'),\n }\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))\n const body = base64UrlEncode(JSON.stringify(payload))\n const toSign = `${header}.${body}`\n const signature = createHmac('sha256', input.signingSecret).update(toSign).digest('base64url')\n return {\n token: `${toSign}.${signature}`,\n expiresAt: new Date(expiresAt * 1000).toISOString(),\n }\n}\n\nexport type SessionTokenVerificationErrorCode = 'malformed' | 'bad_signature' | 'expired' | 'not_yet_valid' | 'wrong_type'\n\nexport class SessionTokenVerificationError extends Error {\n readonly code: SessionTokenVerificationErrorCode\n\n constructor(code: SessionTokenVerificationErrorCode, message: string) {\n super(message)\n this.name = 'SessionTokenVerificationError'\n this.code = code\n }\n}\n\nexport interface VerifySessionTokenInput {\n now?: number\n signingSecret: string\n token: string\n}\n\nexport function verifySessionToken(input: VerifySessionTokenInput): SessionTokenPayload {\n let raw: Record<string, unknown>\n try {\n raw = verifyStrictHs256(input.token, input.signingSecret).payload\n assertExactKeys(raw, ['exp', 'iat', 'jti', 'sub', 'typ'], 'Payload')\n } catch (error) {\n if (error instanceof StrictHs256Error) {\n throw new SessionTokenVerificationError(error.code, error.message)\n }\n throw error\n }\n if (raw.typ !== 'session') {\n throw new SessionTokenVerificationError('wrong_type', 'Not a session token')\n }\n if (!isNonEmptyString(raw.sub)) throw new SessionTokenVerificationError('malformed', 'Payload sub must be a non-empty string')\n if (!isNonEmptyString(raw.jti)) throw new SessionTokenVerificationError('malformed', 'Payload jti must be a non-empty string')\n if (!isFiniteInteger(raw.iat)) throw new SessionTokenVerificationError('malformed', 'Payload iat must be a finite integer')\n if (!isFiniteInteger(raw.exp)) throw new SessionTokenVerificationError('malformed', 'Payload exp must be a finite integer')\n if (raw.exp <= raw.iat) throw new SessionTokenVerificationError('malformed', 'Payload exp must be greater than iat')\n\n const now = input.now ?? Math.floor(Date.now() / 1000)\n if (raw.exp <= now) {\n throw new SessionTokenVerificationError('expired', 'Token has expired')\n }\n if (raw.iat > now + 60) {\n throw new SessionTokenVerificationError('not_yet_valid', 'Token issued in the future')\n }\n return {\n sub: raw.sub,\n typ: raw.typ,\n iat: raw.iat,\n exp: raw.exp,\n jti: raw.jti,\n }\n}\n\n/**\n * Single-use challenge token. The wallet signs the entire `token` string\n * (the wallet doesn't need to parse it). The server stores no state \u2014 it\n * just verifies its own signature on the challenge then verifies the\n * wallet's signature over the challenge string.\n */\n\nexport interface ChallengeTokenPayload {\n address: string\n exp: number\n iat: number\n jti: string\n typ: 'challenge'\n}\n\nexport interface SignChallengeInput {\n address: string\n signingSecret: string\n ttlSeconds: number\n}\n\nexport interface SignedChallenge {\n challenge: string\n expiresAt: string\n}\n\nexport function signChallenge(input: SignChallengeInput): SignedChallenge {\n const issuedAt = Math.floor(Date.now() / 1000)\n const expiresAt = issuedAt + input.ttlSeconds\n const payload: ChallengeTokenPayload = {\n address: input.address.toLowerCase(),\n typ: 'challenge',\n iat: issuedAt,\n exp: expiresAt,\n jti: randomBytes(8).toString('hex'),\n }\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))\n const body = base64UrlEncode(JSON.stringify(payload))\n const toSign = `${header}.${body}`\n const signature = createHmac('sha256', input.signingSecret).update(toSign).digest('base64url')\n return {\n challenge: `${toSign}.${signature}`,\n expiresAt: new Date(expiresAt * 1000).toISOString(),\n }\n}\n\nexport function verifyChallenge(input: { challenge: string; now?: number; signingSecret: string }): ChallengeTokenPayload {\n let raw: Record<string, unknown>\n try {\n raw = verifyStrictHs256(input.challenge, input.signingSecret).payload\n assertExactKeys(raw, ['address', 'exp', 'iat', 'jti', 'typ'], 'Challenge payload')\n } catch (error) {\n if (error instanceof StrictHs256Error) {\n throw new SessionTokenVerificationError(error.code, error.message)\n }\n throw error\n }\n if (raw.typ !== 'challenge') {\n throw new SessionTokenVerificationError('wrong_type', 'Not a challenge token')\n }\n if (!isNonEmptyString(raw.address) || !/^(?:0x)?[\\da-fA-F]{40}$/.test(raw.address)) {\n throw new SessionTokenVerificationError('malformed', 'Challenge address must be a 20-byte hex address')\n }\n if (!isNonEmptyString(raw.jti)) throw new SessionTokenVerificationError('malformed', 'Challenge jti must be a non-empty string')\n if (!isFiniteInteger(raw.iat)) throw new SessionTokenVerificationError('malformed', 'Challenge iat must be a finite integer')\n if (!isFiniteInteger(raw.exp)) throw new SessionTokenVerificationError('malformed', 'Challenge exp must be a finite integer')\n if (raw.exp <= raw.iat) throw new SessionTokenVerificationError('malformed', 'Challenge exp must be greater than iat')\n const now = input.now ?? Math.floor(Date.now() / 1000)\n if (raw.exp <= now) {\n throw new SessionTokenVerificationError('expired', 'Challenge has expired')\n }\n if (raw.iat > now + 60) {\n throw new SessionTokenVerificationError('not_yet_valid', 'Challenge issued in the future')\n }\n return {\n address: raw.address,\n typ: raw.typ,\n iat: raw.iat,\n exp: raw.exp,\n jti: raw.jti,\n }\n}\n", "import { createHmac, timingSafeEqual } from 'node:crypto'\n\nexport type StrictHs256ErrorCode = 'bad_signature' | 'malformed'\n\nexport class StrictHs256Error extends Error {\n readonly code: StrictHs256ErrorCode\n\n constructor(code: StrictHs256ErrorCode, message: string) {\n super(message)\n this.name = 'StrictHs256Error'\n this.code = code\n }\n}\n\nexport interface StrictHs256Parts {\n payload: Record<string, unknown>\n}\n\nexport function verifyStrictHs256(token: string, signingSecret: string): StrictHs256Parts {\n const parts = token.split('.')\n if (parts.length !== 3) {\n throw new StrictHs256Error('malformed', 'Token is not a JWS compact serialization')\n }\n const [headerPart, payloadPart, signaturePart] = parts as [string, string, string]\n const header = decodeJsonObject(headerPart, 'Header')\n assertExactKeys(header, ['alg', 'typ'], 'Header')\n if (header.alg !== 'HS256') throw new StrictHs256Error('malformed', 'Header alg must be HS256')\n if (header.typ !== 'JWT') throw new StrictHs256Error('malformed', 'Header typ must be JWT')\n\n const provided = decodeBase64Url(signaturePart, 'Signature')\n const expected = createHmac('sha256', signingSecret)\n .update(`${headerPart}.${payloadPart}`)\n .digest()\n if (provided.length !== expected.length || !timingSafeEqual(provided, expected)) {\n throw new StrictHs256Error('bad_signature', 'Signature mismatch')\n }\n\n return { payload: decodeJsonObject(payloadPart, 'Payload') }\n}\n\nexport function assertExactKeys(\n value: Record<string, unknown>,\n expected: readonly string[],\n label: string,\n): void {\n const actual = Object.keys(value).sort()\n const canonical = [...expected].sort()\n if (actual.length !== canonical.length || actual.some((key, index) => key !== canonical[index])) {\n throw new StrictHs256Error('malformed', `${label} fields must be exactly: ${canonical.join(', ')}`)\n }\n}\n\nexport function isFiniteInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value)\n}\n\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n\nfunction decodeJsonObject(value: string, label: string): Record<string, unknown> {\n let parsed: unknown\n try {\n parsed = JSON.parse(decodeBase64Url(value, label).toString('utf8'))\n } catch (error) {\n if (error instanceof StrictHs256Error) throw error\n throw new StrictHs256Error('malformed', `${label} is not valid JSON`)\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new StrictHs256Error('malformed', `${label} must be a JSON object`)\n }\n return parsed as Record<string, unknown>\n}\n\nfunction decodeBase64Url(value: string, label: string): Buffer {\n if (value.length === 0 || !/^[\\w-]+$/.test(value)) {\n throw new StrictHs256Error('malformed', `${label} is not canonical base64url`)\n }\n const decoded = Buffer.from(value, 'base64url')\n if (decoded.toString('base64url') !== value) {\n throw new StrictHs256Error('malformed', `${label} is not canonical base64url`)\n }\n return decoded\n}\n", "import { createHmac, randomBytes } from 'node:crypto'\n\nimport type { DatalakeRole } from '../types/Principal.ts'\nimport type { DatalakeToken } from '../types/Token.ts'\nimport {\n assertExactKeys, isFiniteInteger, isNonEmptyString, StrictHs256Error, verifyStrictHs256,\n} from './strictHs256.ts'\n\n/**\n * HS256 token layout used for data-plane access. The signature is a small\n * subset of RFC 7519 \u2014 enough to interoperate with any JWT verifier but tiny\n * enough to implement without pulling a full JWT library. Replace with a\n * proper OIDC-signed JWT in P3.\n */\n\nexport interface TokenPayload {\n /**\n Datalake id the token grants access to.\n */\n dl: string\n /**\n Expiration (seconds since epoch).\n */\n exp: number\n /**\n Issued-at (seconds since epoch).\n */\n iat: number\n /**\n Unique token id \u2014 helpful for future revocation lists.\n */\n jti: string\n /**\n Role granted.\n */\n role: DatalakeRole\n /**\n Owner (user id) that minted the token.\n */\n sub: string\n}\n\nexport interface SignTokenInput {\n datalakeId: string\n ownerId: string\n role: DatalakeRole\n signingSecret: string\n ttlSeconds: number\n url: string\n}\n\nfunction base64UrlEncode(input: Buffer | string): string {\n const buffer = typeof input === 'string' ? Buffer.from(input) : input\n return buffer.toString('base64url')\n}\n\nexport function signToken(input: SignTokenInput): DatalakeToken {\n const issuedAt = Math.floor(Date.now() / 1000)\n const expiresAt = issuedAt + input.ttlSeconds\n const payload: TokenPayload = {\n sub: input.ownerId,\n dl: input.datalakeId,\n role: input.role,\n iat: issuedAt,\n exp: expiresAt,\n jti: randomBytes(8).toString('hex'),\n }\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))\n const body = base64UrlEncode(JSON.stringify(payload))\n const toSign = `${header}.${body}`\n const signature = createHmac('sha256', input.signingSecret).update(toSign).digest('base64url')\n return {\n token: `${toSign}.${signature}`,\n datalakeId: input.datalakeId,\n role: input.role,\n expiresAt: new Date(expiresAt * 1000).toISOString(),\n url: input.url,\n }\n}\n\nexport type TokenVerificationErrorCode = 'malformed' | 'bad_signature' | 'expired' | 'not_yet_valid'\n\nexport class TokenVerificationError extends Error {\n readonly code: TokenVerificationErrorCode\n\n constructor(code: TokenVerificationErrorCode, message: string) {\n super(message)\n this.name = 'TokenVerificationError'\n this.code = code\n }\n}\n\nexport interface VerifyTokenInput {\n /**\n Current wall-clock time (seconds since epoch). Injectable for tests.\n */\n now?: number\n signingSecret: string\n token: string\n}\n\n/**\n * Verifies an HS256 token issued by `signToken` and returns its payload.\n * Throws `TokenVerificationError` if the token is malformed, bears a bad\n * signature, or has expired.\n */\nexport function verifyToken(input: VerifyTokenInput): TokenPayload {\n let raw: Record<string, unknown>\n try {\n raw = verifyStrictHs256(input.token, input.signingSecret).payload\n assertExactKeys(raw, ['dl', 'exp', 'iat', 'jti', 'role', 'sub'], 'Payload')\n } catch (error) {\n if (error instanceof StrictHs256Error) {\n throw new TokenVerificationError(error.code, error.message)\n }\n throw error\n }\n\n if (!isNonEmptyString(raw.sub)) throw new TokenVerificationError('malformed', 'Payload sub must be a non-empty string')\n if (!isNonEmptyString(raw.dl)) throw new TokenVerificationError('malformed', 'Payload dl must be a non-empty string')\n if (raw.role !== 'viewer' && raw.role !== 'runner') {\n throw new TokenVerificationError('malformed', 'Payload role must be viewer or runner')\n }\n if (!isFiniteInteger(raw.iat)) throw new TokenVerificationError('malformed', 'Payload iat must be a finite integer')\n if (!isFiniteInteger(raw.exp)) throw new TokenVerificationError('malformed', 'Payload exp must be a finite integer')\n if (!isNonEmptyString(raw.jti)) throw new TokenVerificationError('malformed', 'Payload jti must be a non-empty string')\n if (raw.exp <= raw.iat) throw new TokenVerificationError('malformed', 'Payload exp must be greater than iat')\n\n const payload: TokenPayload = {\n sub: raw.sub,\n dl: raw.dl,\n role: raw.role,\n iat: raw.iat,\n exp: raw.exp,\n jti: raw.jti,\n }\n\n const now = input.now ?? Math.floor(Date.now() / 1000)\n if (payload.exp <= now) {\n throw new TokenVerificationError('expired', 'Token has expired')\n }\n if (payload.iat > now + 60) {\n // Allow 60 seconds of clock skew into the future.\n throw new TokenVerificationError('not_yet_valid', 'Token issued in the future')\n }\n return payload\n}\n", "import type { AclEntry } from '../types/AclEntry.ts'\nimport type { DatalakeDescriptor } from '../types/DatalakeDescriptor.ts'\nimport type { DatalakePrincipal, DatalakeRole } from '../types/Principal.ts'\n\n/**\n * Storage interface for the control plane. Lives in `datalake-core` so\n * decorators (`@ariestools/aries-datalake-k8s-bridge`) and alternate\n * implementations can depend on the contract without taking a dependency\n * on the full control plane.\n *\n * The in-memory implementation is used in development and for tests; a\n * Postgres-backed implementation handles production. Both ship in\n * `@ariestools/aries-datalake-control`.\n */\nexport interface DatalakeStore {\n /**\n Find by globally unique id (no owner scoping). Used by the data plane.\n */\n findById(id: string): Promise<DatalakeDescriptor | undefined>\n /**\n Find by id or name, scoped to a single owner.\n */\n findByIdOrName(ownerId: string, idOrName: string): Promise<DatalakeDescriptor | undefined>\n /**\n Insert a fresh descriptor. Caller fills in id/timestamps.\n */\n insert(descriptor: DatalakeDescriptor): Promise<void>\n /**\n Return all datalakes owned by the given user.\n */\n listByOwner(ownerId: string): Promise<DatalakeDescriptor[]>\n /**\n Remove a datalake.\n */\n remove(id: string): Promise<void>\n /**\n Drop an ACL entry by principal.\n */\n removeAcl(id: string, principal: DatalakePrincipal): Promise<DatalakeDescriptor>\n /**\n Replace an existing descriptor (full update).\n */\n update(descriptor: DatalakeDescriptor): Promise<void>\n /**\n Add or overwrite an ACL entry on a datalake, returning the updated descriptor.\n */\n upsertAcl(id: string, entry: AclEntry): Promise<DatalakeDescriptor>\n}\n\n/**\n * Roles considered higher privilege than others. Used when merging grants.\n */\nexport const ROLE_RANK: Record<DatalakeRole, number> = {\n viewer: 1,\n runner: 2,\n}\n", "/**\n * Access-control role granted to a principal on a datalake.\n * Maps 1:1 to XL1's DataLakeViewer (read) and DataLakeRunner (read/write) monikers.\n */\nexport type DatalakeRole = 'viewer' | 'runner'\n\n/**\n * A principal identifier. Either a control-plane user id, or the reserved\n * value `PUBLIC_PRINCIPAL` (`'public'`) which opens access to unauthenticated\n * callers at the granted role.\n */\nexport type DatalakePrincipal = string\n\nexport const PUBLIC_PRINCIPAL = 'public'\n\n/**\n * Type guard for the reserved `public` principal.\n */\nexport function isPublicPrincipal(principal: DatalakePrincipal): boolean {\n return principal === PUBLIC_PRINCIPAL\n}\n", "/**\n * Cloud regions where datalakes can be provisioned. Starts with AWS us-west-2;\n * additional regions are added as the control plane expands.\n */\nexport type DatalakeRegion = 'us-west-2' | 'us-east-1' | 'eu-west-1'\n\nexport const DATALAKE_REGIONS: readonly DatalakeRegion[] = ['us-west-2', 'us-east-1', 'eu-west-1'] as const\n\nexport const DEFAULT_REGION: DatalakeRegion = 'us-west-2'\n", "/**\nAudience used by browser wallet JWTs for control-plane operations.\n*/\nexport const DATALAKE_CONTROL_AUDIENCE = 'aries-datalake-control'\n\n/**\nSchema required on every wallet sign-in JWT accepted by Aries.\n*/\nexport const DATALAKE_WALLET_JWT_SCHEMA = 'network.xyo.auth.signin'\n\n/**\nBrowser operations intentionally exposed by the datalake control plane.\n*/\nexport const DATALAKE_CONTROL_OPERATIONS = [\n 'datalake:create',\n 'datalake:describe',\n 'datalake:list',\n] as const\n\n/**\nBrowser operations intentionally exposed by the datalake data plane.\n*/\nexport const DATALAKE_DATA_OPERATIONS = [\n 'payload:append',\n 'payload:read',\n 'usage:read',\n] as const\n\nexport type DatalakeControlOperation = typeof DATALAKE_CONTROL_OPERATIONS[number]\nexport type DatalakeDataOperation = typeof DATALAKE_DATA_OPERATIONS[number]\nexport type DatalakeOperation = DatalakeControlOperation | DatalakeDataOperation\n\n/**\nCanonical complete scope strings used when requesting browser wallet approval.\n*/\nexport const DATALAKE_CONTROL_SCOPE = DATALAKE_CONTROL_OPERATIONS.join(' ')\nexport const DATALAKE_DATA_SCOPE = DATALAKE_DATA_OPERATIONS.join(' ')\n\nexport function isDatalakeControlOperation(value: string): value is DatalakeControlOperation {\n return (DATALAKE_CONTROL_OPERATIONS as readonly string[]).includes(value)\n}\n\nexport function isDatalakeDataOperation(value: string): value is DatalakeDataOperation {\n return (DATALAKE_DATA_OPERATIONS as readonly string[]).includes(value)\n}\n", "/**\n * Datalake service tiers. Each tier maps to a storage driver + resource profile\n * on the control plane: small/medium use the shared hot pool, large gets a\n * dedicated RestDataLake pod, archive uses the S3 + DynamoDB cold driver.\n */\nexport type DatalakeTier = 'small' | 'medium' | 'large' | 'archive'\n\nexport const DATALAKE_TIERS: readonly DatalakeTier[] = ['small', 'medium', 'large', 'archive'] as const\n"],
|
|
5
|
-
"mappings": ";AAwBO,IAAM,mBAAiD;AAAA,EAC5D,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA,EACf,cAAc;AAAA,EACd,UAAU;AACZ;AAMO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,MAAoB;AAC9C,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,SAAS;AACd,SAAK,YAAY,KAAK;AAAA,EACxB;AACF;;;AC7CO,IAAM,uBAAuB;AAE7B,SAAS,yBAAiC;AAC/C,SAAO,IAAI,oBAAoB;AACjC;AAEO,SAAS,qBAAqB,UAA0B;AAC7D,SAAO,GAAG,uBAAuB,CAAC,IAAI,mBAAmB,QAAQ,CAAC;AACpE;AAEO,SAAS,mBAAmB,UAA0B;AAC3D,SAAO,GAAG,qBAAqB,QAAQ,CAAC;AAC1C;AAEO,SAAS,kBAAkB,UAAkB,WAA2B;AAC7E,SAAO,GAAG,mBAAmB,QAAQ,CAAC,IAAI,mBAAmB,SAAS,CAAC;AACzE;AAEO,SAAS,mBAAmB,UAA0B;AAC3D,SAAO,GAAG,qBAAqB,QAAQ,CAAC;AAC1C;AAEO,SAAS,qBAA6B;AAC3C,SAAO,IAAI,oBAAoB;AACjC;;;AChBO,IAAM,6BAA6B;AAMnC,IAAM,2BAA2B;AAMjC,IAAM,8BAA8B;AAEpC,SAAS,0BAA0B,IAAoB;AAC5D,SAAO,IAAI,oBAAoB,cAAc,mBAAmB,EAAE,CAAC;AACrE;AAEO,SAAS,wBAAwB,IAAoB;AAC1D,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,qBAAqB,IAAY,MAAsB;AACrE,SAAO,GAAG,0BAA0B,EAAE,CAAC,QAAQ,mBAAmB,IAAI,CAAC;AACzE;AAEO,SAAS,yBAAyB,IAAoB;AAC3D,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,sBAAsB,IAAoB;AACxD,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,wBAAwB,IAAY,MAAsB;AACxE,SAAO,GAAG,0BAA0B,EAAE,CAAC,WAAW,mBAAmB,IAAI,CAAC;AAC5E;AAEO,SAAS,uBAAuB,IAAoB;AACzD,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;AAEO,SAAS,uBAAuB,IAAoB;AACzD,SAAO,GAAG,0BAA0B,EAAE,CAAC;AACzC;;;AC1DA,SAAS,cAAAA,aAAY,mBAAmB;;;ACAxC,SAAS,YAAY,uBAAuB;AAIrC,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACjC;AAAA,EAET,YAAY,MAA4B,SAAiB;AACvD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAMO,SAAS,kBAAkB,OAAe,eAAyC;AACxF,QAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,IAAI,iBAAiB,aAAa,0CAA0C;AAAA,EACpF;AACA,QAAM,CAAC,YAAY,aAAa,aAAa,IAAI;AACjD,QAAM,SAAS,iBAAiB,YAAY,QAAQ;AACpD,kBAAgB,QAAQ,CAAC,OAAO,KAAK,GAAG,QAAQ;AAChD,MAAI,OAAO,QAAQ,QAAS,OAAM,IAAI,iBAAiB,aAAa,0BAA0B;AAC9F,MAAI,OAAO,QAAQ,MAAO,OAAM,IAAI,iBAAiB,aAAa,wBAAwB;AAE1F,QAAM,WAAW,gBAAgB,eAAe,WAAW;AAC3D,QAAM,WAAW,WAAW,UAAU,aAAa,EAChD,OAAO,GAAG,UAAU,IAAI,WAAW,EAAE,EACrC,OAAO;AACV,MAAI,SAAS,WAAW,SAAS,UAAU,CAAC,gBAAgB,UAAU,QAAQ,GAAG;AAC/E,UAAM,IAAI,iBAAiB,iBAAiB,oBAAoB;AAAA,EAClE;AAEA,SAAO,EAAE,SAAS,iBAAiB,aAAa,SAAS,EAAE;AAC7D;AAEO,SAAS,gBACd,OACA,UACA,OACM;AACN,QAAM,SAAS,OAAO,KAAK,KAAK,EAAE,KAAK;AACvC,QAAM,YAAY,CAAC,GAAG,QAAQ,EAAE,KAAK;AACrC,MAAI,OAAO,WAAW,UAAU,UAAU,OAAO,KAAK,CAAC,KAAK,UAAU,QAAQ,UAAU,KAAK,CAAC,GAAG;AAC/F,UAAM,IAAI,iBAAiB,aAAa,GAAG,KAAK,4BAA4B,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,EACpG;AACF;AAEO,SAAS,gBAAgB,OAAiC;AAC/D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,OAAO,UAAU,KAAK;AACtF;AAEO,SAAS,iBAAiB,OAAiC;AAChE,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS;AACrD;AAEA,SAAS,iBAAiB,OAAe,OAAwC;AAC/E,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,gBAAgB,OAAO,KAAK,EAAE,SAAS,MAAM,CAAC;AAAA,EACpE,SAAS,OAAO;AACd,QAAI,iBAAiB,iBAAkB,OAAM;AAC7C,UAAM,IAAI,iBAAiB,aAAa,GAAG,KAAK,oBAAoB;AAAA,EACtE;AACA,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAC1E,UAAM,IAAI,iBAAiB,aAAa,GAAG,KAAK,wBAAwB;AAAA,EAC1E;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAe,OAAuB;AAC7D,MAAI,MAAM,WAAW,KAAK,CAAC,WAAW,KAAK,KAAK,GAAG;AACjD,UAAM,IAAI,iBAAiB,aAAa,GAAG,KAAK,6BAA6B;AAAA,EAC/E;AACA,QAAM,UAAU,OAAO,KAAK,OAAO,WAAW;AAC9C,MAAI,QAAQ,SAAS,WAAW,MAAM,OAAO;AAC3C,UAAM,IAAI,iBAAiB,aAAa,GAAG,KAAK,6BAA6B;AAAA,EAC/E;AACA,SAAO;AACT;;;ADnCA,SAAS,gBAAgB,OAAgC;AACvD,QAAM,SAAS,OAAO,UAAU,WAAW,OAAO,KAAK,KAAK,IAAI;AAChE,SAAO,OAAO,SAAS,WAAW;AACpC;AAEO,SAAS,iBAAiB,OAAkD;AACjF,QAAM,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC7C,QAAM,YAAY,WAAW,MAAM;AACnC,QAAM,UAA+B;AAAA,IACnC,KAAK,MAAM,QAAQ,YAAY;AAAA,IAC/B,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,YAAY,CAAC,EAAE,SAAS,KAAK;AAAA,EACpC;AACA,QAAM,SAAS,gBAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC;AAC3E,QAAM,OAAO,gBAAgB,KAAK,UAAU,OAAO,CAAC;AACpD,QAAM,SAAS,GAAG,MAAM,IAAI,IAAI;AAChC,QAAM,YAAYC,YAAW,UAAU,MAAM,aAAa,EAAE,OAAO,MAAM,EAAE,OAAO,WAAW;AAC7F,SAAO;AAAA,IACL,OAAO,GAAG,MAAM,IAAI,SAAS;AAAA,IAC7B,WAAW,IAAI,KAAK,YAAY,GAAI,EAAE,YAAY;AAAA,EACpD;AACF;AAIO,IAAM,gCAAN,cAA4C,MAAM;AAAA,EAC9C;AAAA,EAET,YAAY,MAAyC,SAAiB;AACpE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAQO,SAAS,mBAAmB,OAAqD;AACtF,MAAI;AACJ,MAAI;AACF,UAAM,kBAAkB,MAAM,OAAO,MAAM,aAAa,EAAE;AAC1D,oBAAgB,KAAK,CAAC,OAAO,OAAO,OAAO,OAAO,KAAK,GAAG,SAAS;AAAA,EACrE,SAAS,OAAO;AACd,QAAI,iBAAiB,kBAAkB;AACrC,YAAM,IAAI,8BAA8B,MAAM,MAAM,MAAM,OAAO;AAAA,IACnE;AACA,UAAM;AAAA,EACR;AACA,MAAI,IAAI,QAAQ,WAAW;AACzB,UAAM,IAAI,8BAA8B,cAAc,qBAAqB;AAAA,EAC7E;AACA,MAAI,CAAC,iBAAiB,IAAI,GAAG,EAAG,OAAM,IAAI,8BAA8B,aAAa,wCAAwC;AAC7H,MAAI,CAAC,iBAAiB,IAAI,GAAG,EAAG,OAAM,IAAI,8BAA8B,aAAa,wCAAwC;AAC7H,MAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,OAAM,IAAI,8BAA8B,aAAa,sCAAsC;AAC1H,MAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,OAAM,IAAI,8BAA8B,aAAa,sCAAsC;AAC1H,MAAI,IAAI,OAAO,IAAI,IAAK,OAAM,IAAI,8BAA8B,aAAa,sCAAsC;AAEnH,QAAM,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACrD,MAAI,IAAI,OAAO,KAAK;AAClB,UAAM,IAAI,8BAA8B,WAAW,mBAAmB;AAAA,EACxE;AACA,MAAI,IAAI,MAAM,MAAM,IAAI;AACtB,UAAM,IAAI,8BAA8B,iBAAiB,4BAA4B;AAAA,EACvF;AACA,SAAO;AAAA,IACL,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,EACX;AACF;AA4BO,SAAS,cAAc,OAA4C;AACxE,QAAM,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC7C,QAAM,YAAY,WAAW,MAAM;AACnC,QAAM,UAAiC;AAAA,IACrC,SAAS,MAAM,QAAQ,YAAY;AAAA,IACnC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,YAAY,CAAC,EAAE,SAAS,KAAK;AAAA,EACpC;AACA,QAAM,SAAS,gBAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC;AAC3E,QAAM,OAAO,gBAAgB,KAAK,UAAU,OAAO,CAAC;AACpD,QAAM,SAAS,GAAG,MAAM,IAAI,IAAI;AAChC,QAAM,YAAYA,YAAW,UAAU,MAAM,aAAa,EAAE,OAAO,MAAM,EAAE,OAAO,WAAW;AAC7F,SAAO;AAAA,IACL,WAAW,GAAG,MAAM,IAAI,SAAS;AAAA,IACjC,WAAW,IAAI,KAAK,YAAY,GAAI,EAAE,YAAY;AAAA,EACpD;AACF;AAEO,SAAS,gBAAgB,OAA0F;AACxH,MAAI;AACJ,MAAI;AACF,UAAM,kBAAkB,MAAM,WAAW,MAAM,aAAa,EAAE;AAC9D,oBAAgB,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO,KAAK,GAAG,mBAAmB;AAAA,EACnF,SAAS,OAAO;AACd,QAAI,iBAAiB,kBAAkB;AACrC,YAAM,IAAI,8BAA8B,MAAM,MAAM,MAAM,OAAO;AAAA,IACnE;AACA,UAAM;AAAA,EACR;AACA,MAAI,IAAI,QAAQ,aAAa;AAC3B,UAAM,IAAI,8BAA8B,cAAc,uBAAuB;AAAA,EAC/E;AACA,MAAI,CAAC,iBAAiB,IAAI,OAAO,KAAK,CAAC,0BAA0B,KAAK,IAAI,OAAO,GAAG;AAClF,UAAM,IAAI,8BAA8B,aAAa,iDAAiD;AAAA,EACxG;AACA,MAAI,CAAC,iBAAiB,IAAI,GAAG,EAAG,OAAM,IAAI,8BAA8B,aAAa,0CAA0C;AAC/H,MAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,OAAM,IAAI,8BAA8B,aAAa,wCAAwC;AAC5H,MAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,OAAM,IAAI,8BAA8B,aAAa,wCAAwC;AAC5H,MAAI,IAAI,OAAO,IAAI,IAAK,OAAM,IAAI,8BAA8B,aAAa,wCAAwC;AACrH,QAAM,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACrD,MAAI,IAAI,OAAO,KAAK;AAClB,UAAM,IAAI,8BAA8B,WAAW,uBAAuB;AAAA,EAC5E;AACA,MAAI,IAAI,MAAM,MAAM,IAAI;AACtB,UAAM,IAAI,8BAA8B,iBAAiB,gCAAgC;AAAA,EAC3F;AACA,SAAO;AAAA,IACL,SAAS,IAAI;AAAA,IACb,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,EACX;AACF;;;AEhNA,SAAS,cAAAC,aAAY,eAAAC,oBAAmB;AAmDxC,SAASC,iBAAgB,OAAgC;AACvD,QAAM,SAAS,OAAO,UAAU,WAAW,OAAO,KAAK,KAAK,IAAI;AAChE,SAAO,OAAO,SAAS,WAAW;AACpC;AAEO,SAAS,UAAU,OAAsC;AAC9D,QAAM,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC7C,QAAM,YAAY,WAAW,MAAM;AACnC,QAAM,UAAwB;AAAA,IAC5B,KAAK,MAAM;AAAA,IACX,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAKC,aAAY,CAAC,EAAE,SAAS,KAAK;AAAA,EACpC;AACA,QAAM,SAASD,iBAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC;AAC3E,QAAM,OAAOA,iBAAgB,KAAK,UAAU,OAAO,CAAC;AACpD,QAAM,SAAS,GAAG,MAAM,IAAI,IAAI;AAChC,QAAM,YAAYE,YAAW,UAAU,MAAM,aAAa,EAAE,OAAO,MAAM,EAAE,OAAO,WAAW;AAC7F,SAAO;AAAA,IACL,OAAO,GAAG,MAAM,IAAI,SAAS;AAAA,IAC7B,YAAY,MAAM;AAAA,IAClB,MAAM,MAAM;AAAA,IACZ,WAAW,IAAI,KAAK,YAAY,GAAI,EAAE,YAAY;AAAA,IAClD,KAAK,MAAM;AAAA,EACb;AACF;AAIO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EACvC;AAAA,EAET,YAAY,MAAkC,SAAiB;AAC7D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAgBO,SAAS,YAAY,OAAuC;AACjE,MAAI;AACJ,MAAI;AACF,UAAM,kBAAkB,MAAM,OAAO,MAAM,aAAa,EAAE;AAC1D,oBAAgB,KAAK,CAAC,MAAM,OAAO,OAAO,OAAO,QAAQ,KAAK,GAAG,SAAS;AAAA,EAC5E,SAAS,OAAO;AACd,QAAI,iBAAiB,kBAAkB;AACrC,YAAM,IAAI,uBAAuB,MAAM,MAAM,MAAM,OAAO;AAAA,IAC5D;AACA,UAAM;AAAA,EACR;AAEA,MAAI,CAAC,iBAAiB,IAAI,GAAG,EAAG,OAAM,IAAI,uBAAuB,aAAa,wCAAwC;AACtH,MAAI,CAAC,iBAAiB,IAAI,EAAE,EAAG,OAAM,IAAI,uBAAuB,aAAa,uCAAuC;AACpH,MAAI,IAAI,SAAS,YAAY,IAAI,SAAS,UAAU;AAClD,UAAM,IAAI,uBAAuB,aAAa,uCAAuC;AAAA,EACvF;AACA,MAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,OAAM,IAAI,uBAAuB,aAAa,sCAAsC;AACnH,MAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,OAAM,IAAI,uBAAuB,aAAa,sCAAsC;AACnH,MAAI,CAAC,iBAAiB,IAAI,GAAG,EAAG,OAAM,IAAI,uBAAuB,aAAa,wCAAwC;AACtH,MAAI,IAAI,OAAO,IAAI,IAAK,OAAM,IAAI,uBAAuB,aAAa,sCAAsC;AAE5G,QAAM,UAAwB;AAAA,IAC5B,KAAK,IAAI;AAAA,IACT,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,EACX;AAEA,QAAM,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACrD,MAAI,QAAQ,OAAO,KAAK;AACtB,UAAM,IAAI,uBAAuB,WAAW,mBAAmB;AAAA,EACjE;AACA,MAAI,QAAQ,MAAM,MAAM,IAAI;AAE1B,UAAM,IAAI,uBAAuB,iBAAiB,4BAA4B;AAAA,EAChF;AACA,SAAO;AACT;;;AC9FO,IAAM,YAA0C;AAAA,EACrD,QAAQ;AAAA,EACR,QAAQ;AACV;;;AC1CO,IAAM,mBAAmB;AAKzB,SAAS,kBAAkB,WAAuC;AACvE,SAAO,cAAc;AACvB;;;ACdO,IAAM,mBAA8C,CAAC,aAAa,aAAa,WAAW;AAE1F,IAAM,iBAAiC;;;ACLvC,IAAM,4BAA4B;AAKlC,IAAM,6BAA6B;AAKnC,IAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF;AASO,IAAM,yBAAyB,4BAA4B,KAAK,GAAG;AACnE,IAAM,sBAAsB,yBAAyB,KAAK,GAAG;AAE7D,SAAS,2BAA2B,OAAkD;AAC3F,SAAQ,4BAAkD,SAAS,KAAK;AAC1E;AAEO,SAAS,wBAAwB,OAA+C;AACrF,SAAQ,yBAA+C,SAAS,KAAK;AACvE;;;ACrCO,IAAM,iBAA0C,CAAC,SAAS,UAAU,SAAS,SAAS;",
|
|
3
|
+
"sources": ["../../src/api/errors.ts", "../../src/api/paths.ts", "../../src/api/planePaths.ts", "../../src/auth/sessionTokenCodec.ts", "../../src/auth/strictHs256.ts", "../../src/auth/tokenCodec.ts", "../../src/store/DatalakeStore.ts", "../../src/types/DatalakeConfig.ts", "../../src/types/Principal.ts", "../../src/types/Region.ts", "../../src/types/Scope.ts", "../../src/types/Tier.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Standard error body returned by the control plane for any non-2xx response.\n * The `code` is a stable machine-readable identifier; `message` is the\n * human-readable description.\n */\nexport interface ApiErrorBody {\n code: ApiErrorCode\n message: string\n /**\n Optional request-correlation id for server logs.\n */\n requestId?: string\n}\n\nexport type ApiErrorCode\n = | 'bad_request'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'conflict'\n | 'unprocessable'\n | 'rate_limited'\n | 'internal'\n\nexport const API_ERROR_STATUS: Record<ApiErrorCode, number> = {\n bad_request: 400,\n unauthorized: 401,\n forbidden: 403,\n not_found: 404,\n conflict: 409,\n unprocessable: 422,\n rate_limited: 429,\n internal: 500,\n}\n\n/**\n * Thrown by `RestDatalakeClient` when the server returns a non-2xx response.\n * Carries the structured error body so callers can branch on `.code`.\n */\nexport class DatalakeApiError extends Error {\n readonly code: ApiErrorCode\n readonly requestId?: string\n readonly status: number\n\n constructor(status: number, body: ApiErrorBody) {\n super(body.message)\n this.name = 'DatalakeApiError'\n this.code = body.code\n this.status = status\n this.requestId = body.requestId\n }\n}\n", "/**\n * Canonical path builders for the datalake control-plane HTTP API.\n * Both the REST client and the control-plane service import from here so\n * the wire contract has a single source of truth.\n */\n\nexport const DATALAKE_API_VERSION = 'v1'\n\nexport function datalakeCollectionPath(): string {\n return `/${DATALAKE_API_VERSION}/datalakes`\n}\n\nexport function datalakeResourcePath(idOrName: string): string {\n return `${datalakeCollectionPath()}/${encodeURIComponent(idOrName)}`\n}\n\nexport function datalakeGrantsPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/grants`\n}\n\nexport function datalakeGrantPath(idOrName: string, principal: string): string {\n return `${datalakeGrantsPath(idOrName)}/${encodeURIComponent(principal)}`\n}\n\nexport function datalakeTokensPath(idOrName: string): string {\n return `${datalakeResourcePath(idOrName)}/tokens`\n}\n\nexport function datalakeHealthPath(): string {\n return `/${DATALAKE_API_VERSION}/health`\n}\n", "/**\n * Data-plane path builders. The data plane is addressed by datalake id\n * (globally unique), not by name (which is scoped to owner). Route names\n * mirror the XYO archivist REST middleware (`/insert`, `/get/:hash`, `/next`)\n * so a generic archivist client can talk to a datalake-plane after picking\n * the per-datalake prefix.\n */\n\nimport { DATALAKE_API_VERSION } from './paths.ts'\n\n/**\n * Header that conveys how many payloads in the insert request were skipped\n * because their hash already existed in the datalake.\n */\nexport const DATALAKE_HEADER_DUPLICATES = 'x-datalake-duplicates'\n\n/**\n * Header that conveys the comma-separated list of archivist-computed\n * `_hash` values rejected by the datalake's schema policy.\n */\nexport const DATALAKE_HEADER_REJECTED = 'x-datalake-rejected'\n\n/**\n * Header that conveys the cursor (`_sequence`) of the last payload in a\n * `next` response page, when more pages may exist.\n */\nexport const DATALAKE_HEADER_NEXT_CURSOR = 'x-datalake-next-cursor'\n\nexport function datalakePlaneResourcePath(id: string): string {\n return `/${DATALAKE_API_VERSION}/datalakes/${encodeURIComponent(id)}`\n}\n\nexport function datalakePlaneInsertPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/insert`\n}\n\nexport function datalakePlaneGetPath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/get/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneGetManyPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/get`\n}\n\nexport function datalakePlaneNextPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/next`\n}\n\nexport function datalakePlaneDeletePath(id: string, hash: string): string {\n return `${datalakePlaneResourcePath(id)}/delete/${encodeURIComponent(hash)}`\n}\n\nexport function datalakePlaneClearPath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/clear`\n}\n\nexport function datalakePlaneUsagePath(id: string): string {\n return `${datalakePlaneResourcePath(id)}/usage`\n}\n", "import { createHmac, randomBytes } from 'node:crypto'\n\nimport {\n assertExactKeys, isFiniteInteger, isNonEmptyString, StrictHs256Error, verifyStrictHs256,\n} from './strictHs256.ts'\n\n/**\n * Session tokens issued after a successful XYO Wallet sign-in. The wire\n * format mirrors `tokenCodec.ts` (HS256 JWT) but the payload carries no\n * `dl` claim \u2014 sessions are scoped to a user (wallet address), not a\n * single datalake. The control plane mints these; both planes verify\n * them via `verifySessionToken`.\n */\n\nexport interface SessionTokenPayload {\n /**\n Expiration (seconds since epoch).\n */\n exp: number\n /**\n Issued-at (seconds since epoch).\n */\n iat: number\n /**\n Unique token id.\n */\n jti: string\n /**\n Wallet address that authenticated; used as the `ownerId`.\n */\n sub: string\n /**\n Token kind. Always `'session'` for this codec.\n */\n typ: 'session'\n}\n\nexport interface SignSessionTokenInput {\n address: string\n signingSecret: string\n ttlSeconds: number\n}\n\nexport interface SignedSessionToken {\n expiresAt: string\n token: string\n}\n\nfunction base64UrlEncode(input: Buffer | string): string {\n const buffer = typeof input === 'string' ? Buffer.from(input) : input\n return buffer.toString('base64url')\n}\n\nexport function signSessionToken(input: SignSessionTokenInput): SignedSessionToken {\n const issuedAt = Math.floor(Date.now() / 1000)\n const expiresAt = issuedAt + input.ttlSeconds\n const payload: SessionTokenPayload = {\n sub: input.address.toLowerCase(),\n typ: 'session',\n iat: issuedAt,\n exp: expiresAt,\n jti: randomBytes(8).toString('hex'),\n }\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))\n const body = base64UrlEncode(JSON.stringify(payload))\n const toSign = `${header}.${body}`\n const signature = createHmac('sha256', input.signingSecret).update(toSign).digest('base64url')\n const expiresAtDate = new Date(expiresAt * 1000)\n return {\n token: `${toSign}.${signature}`,\n expiresAt: expiresAtDate.toISOString(),\n }\n}\n\nexport type SessionTokenVerificationErrorCode = 'malformed' | 'bad_signature' | 'expired' | 'not_yet_valid' | 'wrong_type'\n\nexport class SessionTokenVerificationError extends Error {\n readonly code: SessionTokenVerificationErrorCode\n\n constructor(code: SessionTokenVerificationErrorCode, message: string) {\n super(message)\n this.name = 'SessionTokenVerificationError'\n this.code = code\n }\n}\n\nexport interface VerifySessionTokenInput {\n now?: number\n signingSecret: string\n token: string\n}\n\nexport function verifySessionToken(input: VerifySessionTokenInput): SessionTokenPayload {\n let raw: Record<string, unknown>\n try {\n raw = verifyStrictHs256(input.token, input.signingSecret).payload\n assertExactKeys(raw, ['exp', 'iat', 'jti', 'sub', 'typ'], 'Payload')\n } catch (error) {\n if (error instanceof StrictHs256Error) {\n throw new SessionTokenVerificationError(error.code, error.message)\n }\n throw error\n }\n if (raw.typ !== 'session') {\n throw new SessionTokenVerificationError('wrong_type', 'Not a session token')\n }\n if (!isNonEmptyString(raw.sub)) throw new SessionTokenVerificationError('malformed', 'Payload sub must be a non-empty string')\n if (!isNonEmptyString(raw.jti)) throw new SessionTokenVerificationError('malformed', 'Payload jti must be a non-empty string')\n if (!isFiniteInteger(raw.iat)) throw new SessionTokenVerificationError('malformed', 'Payload iat must be a finite integer')\n if (!isFiniteInteger(raw.exp)) throw new SessionTokenVerificationError('malformed', 'Payload exp must be a finite integer')\n if (raw.exp <= raw.iat) throw new SessionTokenVerificationError('malformed', 'Payload exp must be greater than iat')\n\n const now = input.now ?? Math.floor(Date.now() / 1000)\n if (raw.exp <= now) {\n throw new SessionTokenVerificationError('expired', 'Token has expired')\n }\n if (raw.iat > now + 60) {\n throw new SessionTokenVerificationError('not_yet_valid', 'Token issued in the future')\n }\n return {\n sub: raw.sub,\n typ: raw.typ,\n iat: raw.iat,\n exp: raw.exp,\n jti: raw.jti,\n }\n}\n\n/**\n * Single-use challenge token. The wallet signs the entire `token` string\n * (the wallet doesn't need to parse it). The server stores no state \u2014 it\n * just verifies its own signature on the challenge then verifies the\n * wallet's signature over the challenge string.\n */\n\nexport interface ChallengeTokenPayload {\n address: string\n exp: number\n iat: number\n jti: string\n typ: 'challenge'\n}\n\nexport interface SignChallengeInput {\n address: string\n signingSecret: string\n ttlSeconds: number\n}\n\nexport interface SignedChallenge {\n challenge: string\n expiresAt: string\n}\n\nexport function signChallenge(input: SignChallengeInput): SignedChallenge {\n const issuedAt = Math.floor(Date.now() / 1000)\n const expiresAt = issuedAt + input.ttlSeconds\n const payload: ChallengeTokenPayload = {\n address: input.address.toLowerCase(),\n typ: 'challenge',\n iat: issuedAt,\n exp: expiresAt,\n jti: randomBytes(8).toString('hex'),\n }\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))\n const body = base64UrlEncode(JSON.stringify(payload))\n const toSign = `${header}.${body}`\n const signature = createHmac('sha256', input.signingSecret).update(toSign).digest('base64url')\n const expiresAtDate = new Date(expiresAt * 1000)\n return {\n challenge: `${toSign}.${signature}`,\n expiresAt: expiresAtDate.toISOString(),\n }\n}\n\nexport function verifyChallenge(input: { challenge: string; now?: number; signingSecret: string }): ChallengeTokenPayload {\n let raw: Record<string, unknown>\n try {\n raw = verifyStrictHs256(input.challenge, input.signingSecret).payload\n assertExactKeys(raw, ['address', 'exp', 'iat', 'jti', 'typ'], 'Challenge payload')\n } catch (error) {\n if (error instanceof StrictHs256Error) {\n throw new SessionTokenVerificationError(error.code, error.message)\n }\n throw error\n }\n if (raw.typ !== 'challenge') {\n throw new SessionTokenVerificationError('wrong_type', 'Not a challenge token')\n }\n if (!isNonEmptyString(raw.address) || !/^(?:0x)?[\\da-fA-F]{40}$/.test(raw.address)) {\n throw new SessionTokenVerificationError('malformed', 'Challenge address must be a 20-byte hex address')\n }\n if (!isNonEmptyString(raw.jti)) throw new SessionTokenVerificationError('malformed', 'Challenge jti must be a non-empty string')\n if (!isFiniteInteger(raw.iat)) throw new SessionTokenVerificationError('malformed', 'Challenge iat must be a finite integer')\n if (!isFiniteInteger(raw.exp)) throw new SessionTokenVerificationError('malformed', 'Challenge exp must be a finite integer')\n if (raw.exp <= raw.iat) throw new SessionTokenVerificationError('malformed', 'Challenge exp must be greater than iat')\n const now = input.now ?? Math.floor(Date.now() / 1000)\n if (raw.exp <= now) {\n throw new SessionTokenVerificationError('expired', 'Challenge has expired')\n }\n if (raw.iat > now + 60) {\n throw new SessionTokenVerificationError('not_yet_valid', 'Challenge issued in the future')\n }\n return {\n address: raw.address,\n typ: raw.typ,\n iat: raw.iat,\n exp: raw.exp,\n jti: raw.jti,\n }\n}\n", "import { createHmac, timingSafeEqual } from 'node:crypto'\n\nexport type StrictHs256ErrorCode = 'bad_signature' | 'malformed'\n\nexport class StrictHs256Error extends Error {\n readonly code: StrictHs256ErrorCode\n\n constructor(code: StrictHs256ErrorCode, message: string) {\n super(message)\n this.name = 'StrictHs256Error'\n this.code = code\n }\n}\n\nexport interface StrictHs256Parts {\n payload: Record<string, unknown>\n}\n\nexport function verifyStrictHs256(token: string, signingSecret: string): StrictHs256Parts {\n const parts = token.split('.')\n if (parts.length !== 3) {\n throw new StrictHs256Error('malformed', 'Token is not a JWS compact serialization')\n }\n const [headerPart, payloadPart, signaturePart] = parts as [string, string, string]\n const header = decodeJsonObject(headerPart, 'Header')\n assertExactKeys(header, ['alg', 'typ'], 'Header')\n if (header.alg !== 'HS256') throw new StrictHs256Error('malformed', 'Header alg must be HS256')\n if (header.typ !== 'JWT') throw new StrictHs256Error('malformed', 'Header typ must be JWT')\n\n const provided = decodeBase64Url(signaturePart, 'Signature')\n const expected = createHmac('sha256', signingSecret)\n .update(`${headerPart}.${payloadPart}`)\n .digest()\n if (provided.length !== expected.length || !timingSafeEqual(provided, expected)) {\n throw new StrictHs256Error('bad_signature', 'Signature mismatch')\n }\n\n return { payload: decodeJsonObject(payloadPart, 'Payload') }\n}\n\nexport function assertExactKeys(\n value: Record<string, unknown>,\n expected: readonly string[],\n label: string,\n): void {\n const actual = Object.keys(value).toSorted()\n const canonical = [...expected].toSorted()\n if (actual.length !== canonical.length || actual.some((key, index) => key !== canonical[index])) {\n throw new StrictHs256Error('malformed', `${label} fields must be exactly: ${canonical.join(', ')}`)\n }\n}\n\nexport function isFiniteInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && Number.isSafeInteger(value)\n}\n\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n\nfunction decodeJsonObject(value: string, label: string): Record<string, unknown> {\n let parsed: unknown\n try {\n const decoder = new TextDecoder()\n parsed = JSON.parse(decoder.decode(decodeBase64Url(value, label)))\n } catch (error) {\n if (error instanceof StrictHs256Error) throw error\n throw new StrictHs256Error('malformed', `${label} is not valid JSON`)\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new StrictHs256Error('malformed', `${label} must be a JSON object`)\n }\n return parsed as Record<string, unknown>\n}\n\nfunction decodeBase64Url(value: string, label: string): Uint8Array {\n if (value.length === 0 || !/^[\\w-]+$/.test(value)) {\n throw new StrictHs256Error('malformed', `${label} is not canonical base64url`)\n }\n const decoded = Buffer.from(value, 'base64url')\n if (decoded.toString('base64url') !== value) {\n throw new StrictHs256Error('malformed', `${label} is not canonical base64url`)\n }\n return decoded\n}\n", "import { createHmac, randomBytes } from 'node:crypto'\n\nimport type { DatalakeRole } from '../types/Principal.ts'\nimport type { DatalakeToken } from '../types/Token.ts'\nimport {\n assertExactKeys, isFiniteInteger, isNonEmptyString, StrictHs256Error, verifyStrictHs256,\n} from './strictHs256.ts'\n\n/**\n * HS256 token layout used for data-plane access. The signature is a small\n * subset of RFC 7519 \u2014 enough to interoperate with any JWT verifier but tiny\n * enough to implement without pulling a full JWT library. Replace with a\n * proper OIDC-signed JWT in P3.\n */\n\nexport interface TokenPayload {\n /**\n Datalake id the token grants access to.\n */\n dl: string\n /**\n Expiration (seconds since epoch).\n */\n exp: number\n /**\n Issued-at (seconds since epoch).\n */\n iat: number\n /**\n Unique token id \u2014 helpful for future revocation lists.\n */\n jti: string\n /**\n Role granted.\n */\n role: DatalakeRole\n /**\n Owner (user id) that minted the token.\n */\n sub: string\n}\n\nexport interface SignTokenInput {\n datalakeId: string\n ownerId: string\n role: DatalakeRole\n signingSecret: string\n ttlSeconds: number\n url: string\n}\n\nfunction base64UrlEncode(input: Buffer | string): string {\n const buffer = typeof input === 'string' ? Buffer.from(input) : input\n return buffer.toString('base64url')\n}\n\nexport function signToken(input: SignTokenInput): DatalakeToken {\n const issuedAt = Math.floor(Date.now() / 1000)\n const expiresAt = issuedAt + input.ttlSeconds\n const payload: TokenPayload = {\n sub: input.ownerId,\n dl: input.datalakeId,\n role: input.role,\n iat: issuedAt,\n exp: expiresAt,\n jti: randomBytes(8).toString('hex'),\n }\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))\n const body = base64UrlEncode(JSON.stringify(payload))\n const toSign = `${header}.${body}`\n const signature = createHmac('sha256', input.signingSecret).update(toSign).digest('base64url')\n const expiresAtDate = new Date(expiresAt * 1000)\n return {\n token: `${toSign}.${signature}`,\n datalakeId: input.datalakeId,\n role: input.role,\n expiresAt: expiresAtDate.toISOString(),\n url: input.url,\n }\n}\n\nexport type TokenVerificationErrorCode = 'malformed' | 'bad_signature' | 'expired' | 'not_yet_valid'\n\nexport class TokenVerificationError extends Error {\n readonly code: TokenVerificationErrorCode\n\n constructor(code: TokenVerificationErrorCode, message: string) {\n super(message)\n this.name = 'TokenVerificationError'\n this.code = code\n }\n}\n\nexport interface VerifyTokenInput {\n /**\n Current wall-clock time (seconds since epoch). Injectable for tests.\n */\n now?: number\n signingSecret: string\n token: string\n}\n\n/**\n * Verifies an HS256 token issued by `signToken` and returns its payload.\n * Throws `TokenVerificationError` if the token is malformed, bears a bad\n * signature, or has expired.\n */\nexport function verifyToken(input: VerifyTokenInput): TokenPayload {\n let raw: Record<string, unknown>\n try {\n raw = verifyStrictHs256(input.token, input.signingSecret).payload\n assertExactKeys(raw, ['dl', 'exp', 'iat', 'jti', 'role', 'sub'], 'Payload')\n } catch (error) {\n if (error instanceof StrictHs256Error) {\n throw new TokenVerificationError(error.code, error.message)\n }\n throw error\n }\n\n if (!isNonEmptyString(raw.sub)) throw new TokenVerificationError('malformed', 'Payload sub must be a non-empty string')\n if (!isNonEmptyString(raw.dl)) throw new TokenVerificationError('malformed', 'Payload dl must be a non-empty string')\n if (raw.role !== 'viewer' && raw.role !== 'runner') {\n throw new TokenVerificationError('malformed', 'Payload role must be viewer or runner')\n }\n if (!isFiniteInteger(raw.iat)) throw new TokenVerificationError('malformed', 'Payload iat must be a finite integer')\n if (!isFiniteInteger(raw.exp)) throw new TokenVerificationError('malformed', 'Payload exp must be a finite integer')\n if (!isNonEmptyString(raw.jti)) throw new TokenVerificationError('malformed', 'Payload jti must be a non-empty string')\n if (raw.exp <= raw.iat) throw new TokenVerificationError('malformed', 'Payload exp must be greater than iat')\n\n const payload: TokenPayload = {\n sub: raw.sub,\n dl: raw.dl,\n role: raw.role,\n iat: raw.iat,\n exp: raw.exp,\n jti: raw.jti,\n }\n\n const now = input.now ?? Math.floor(Date.now() / 1000)\n if (payload.exp <= now) {\n throw new TokenVerificationError('expired', 'Token has expired')\n }\n if (payload.iat > now + 60) {\n // Allow 60 seconds of clock skew into the future.\n throw new TokenVerificationError('not_yet_valid', 'Token issued in the future')\n }\n return payload\n}\n", "import type { AclEntry } from '../types/AclEntry.ts'\nimport type { DatalakeDescriptor } from '../types/DatalakeDescriptor.ts'\nimport type { DatalakePrincipal, DatalakeRole } from '../types/Principal.ts'\n\n/**\n * Storage interface for the control plane. Lives in `datalake-core` so\n * decorators (`@ariestools/aries-datalake-k8s-bridge`) and alternate\n * implementations can depend on the contract without taking a dependency\n * on the full control plane.\n *\n * The in-memory implementation is used in development and for tests; a\n * Postgres-backed implementation handles production. Both ship in\n * `@ariestools/aries-datalake-control`.\n */\nexport interface DatalakeStore {\n /**\n Find by globally unique id (no owner scoping). Used by the data plane.\n */\n findById(id: string): Promise<DatalakeDescriptor | undefined>\n /**\n Find by id or name, scoped to a single owner.\n */\n findByIdOrName(ownerId: string, idOrName: string): Promise<DatalakeDescriptor | undefined>\n /**\n Insert a fresh descriptor. Caller fills in id/timestamps.\n */\n insert(descriptor: DatalakeDescriptor): Promise<void>\n /**\n Return all datalakes owned by the given user.\n */\n listByOwner(ownerId: string): Promise<DatalakeDescriptor[]>\n /**\n Remove a datalake.\n */\n remove(id: string): Promise<void>\n /**\n Drop an ACL entry by principal.\n */\n removeAcl(id: string, principal: DatalakePrincipal): Promise<DatalakeDescriptor>\n /**\n Replace an existing descriptor (full update).\n */\n update(descriptor: DatalakeDescriptor): Promise<void>\n /**\n Add or overwrite an ACL entry on a datalake, returning the updated descriptor.\n */\n upsertAcl(id: string, entry: AclEntry): Promise<DatalakeDescriptor>\n}\n\n/**\n * Roles considered higher privilege than others. Used when merging grants.\n */\nexport const ROLE_RANK: Record<DatalakeRole, number> = {\n viewer: 1,\n runner: 2,\n}\n", "import type { DatalakeRegion } from './Region.ts'\nimport type { DatalakeTier } from './Tier.ts'\n\n/**\n * User-supplied configuration for provisioning a new datalake. All fields are\n * optional except tier; the control plane applies defaults for the rest.\n */\nexport interface DatalakeConfig {\n /**\n Payload schemas allowed for insert. In allowlist mode an explicit empty\n array accepts no schemas; otherwise an empty array retains legacy unrestricted admission.\n */\n allowedSchemas?: string[]\n /**\n Payload schemas disallowed for insert.\n */\n disallowedSchemas?: string[]\n /**\n Provisioned IOPS target. Ignored for the archive tier.\n */\n iops?: number\n /**\n * Maximum UTF-8 JSON bytes per payload, excluding server storage metadata\n * but including client metadata, before compression. Required in allowlist mode.\n */\n maxPayloadBytes?: number\n /**\n * Per-datalake rate-limit overrides. When omitted, the data plane's\n * default limits apply. Use this to tighten compliance-sensitive\n * datalakes or relax a limit for a trusted internal tenant.\n */\n rateLimits?: RateLimitOverrides\n /**\n Deployment region.\n */\n region?: DatalakeRegion\n /**\n Retention policy in days. `null` means keep forever.\n */\n retentionDays?: number | null\n /**\n * Optional per-schema byte ceilings. A schema limit can only tighten\n * maxPayloadBytes, never raise the global ceiling.\n */\n schemaMaxPayloadBytes?: Record<string, number>\n /**\n * Explicit strict admission. Requires allowedSchemas to be supplied and a\n * finite positive maxPayloadBytes. Omission retains legacy schema semantics.\n */\n schemaPolicy?: 'allowlist'\n /**\n Provisioned capacity in bytes. Ignored for the archive tier.\n */\n sizeBytes?: number\n /**\n Service tier (controls storage driver, IOPS ceiling, compute shape).\n */\n tier: DatalakeTier\n /**\n * Reserved. The archivist always recomputes `_hash` and `_dataHash` from\n * payload bytes trustlessly, so this flag is a no-op. Kept on the type so\n * older configs still parse; will be removed in a future major.\n *\n * @deprecated archivist is the trustless authority \u2014 no client-supplied\n * hash is honored.\n */\n verifyHashes?: boolean\n}\n\n/** Validate admission settings before persisting or applying a policy. */\nexport function validateDatalakeAdmissionConfig(config: DatalakeConfig): void {\n if (config.schemaPolicy !== undefined && config.schemaPolicy !== 'allowlist') {\n throw new TypeError('schemaPolicy must be allowlist when supplied')\n }\n if (config.schemaPolicy === 'allowlist' && !Array.isArray(config.allowedSchemas)) {\n throw new TypeError('allowedSchemas must be explicitly supplied in allowlist mode; use [] to accept no payloads')\n }\n for (const [name, schemas] of [['allowedSchemas', config.allowedSchemas], ['disallowedSchemas', config.disallowedSchemas]] as const) {\n if (schemas !== undefined && (!Array.isArray(schemas) || schemas.some(schema => typeof schema !== 'string' || schema.length === 0))) {\n throw new TypeError(`${name} must be an array of non-empty schema strings`)\n }\n }\n if (config.maxPayloadBytes !== undefined || config.schemaPolicy === 'allowlist') {\n requireByteLimit(config.maxPayloadBytes, 'maxPayloadBytes')\n }\n if (config.schemaMaxPayloadBytes !== undefined) {\n if (!config.schemaMaxPayloadBytes || typeof config.schemaMaxPayloadBytes !== 'object' || Array.isArray(config.schemaMaxPayloadBytes)) {\n throw new TypeError('schemaMaxPayloadBytes must map schema strings to positive byte limits')\n }\n for (const [schema, limit] of Object.entries(config.schemaMaxPayloadBytes)) {\n if (schema.length === 0) throw new TypeError('schemaMaxPayloadBytes keys must be non-empty schema strings')\n requireByteLimit(limit, `schemaMaxPayloadBytes[${schema}]`)\n }\n }\n}\n\nfunction requireByteLimit(value: number | undefined, field: string): void {\n if (!Number.isSafeInteger(value) || (value ?? 0) <= 0) {\n throw new TypeError(`${field} must be a finite positive safe integer byte count`)\n }\n}\n\nexport interface RateLimitOverrides {\n /**\n Max anonymous requests per minute.\n */\n anonymousPerMinute?: number\n /**\n Max authenticated requests per minute.\n */\n authenticatedPerMinute?: number\n /**\n * Burst multiplier (1 = no burst). Bucket capacity = perMinute * burstFactor.\n */\n burstFactor?: number\n}\n", "/**\n * Access-control role granted to a principal on a datalake.\n * Maps 1:1 to XL1's DataLakeViewer (read) and DataLakeRunner (read/write) monikers.\n */\nexport type DatalakeRole = 'viewer' | 'runner'\n\n/**\n * A principal identifier. Either a control-plane user id, or the reserved\n * value `PUBLIC_PRINCIPAL` (`'public'`) which opens access to unauthenticated\n * callers at the granted role.\n */\nexport type DatalakePrincipal = string\n\nexport const PUBLIC_PRINCIPAL = 'public'\n\n/**\n * Type guard for the reserved `public` principal.\n */\nexport function isPublicPrincipal(principal: DatalakePrincipal): boolean {\n return principal === PUBLIC_PRINCIPAL\n}\n", "/**\n * Cloud regions where datalakes can be provisioned. Starts with AWS us-west-2;\n * additional regions are added as the control plane expands.\n */\nexport type DatalakeRegion = 'us-west-2' | 'us-east-1' | 'eu-west-1'\n\nexport const DATALAKE_REGIONS: readonly DatalakeRegion[] = ['us-west-2', 'us-east-1', 'eu-west-1'] as const\n\nexport const DEFAULT_REGION: DatalakeRegion = 'us-west-2'\n", "/**\nAudience used by browser wallet JWTs for control-plane operations.\n*/\nexport const DATALAKE_CONTROL_AUDIENCE = 'aries-datalake-control'\n\n/**\nSchema required on every wallet sign-in JWT accepted by Aries.\n*/\nexport const DATALAKE_WALLET_JWT_SCHEMA = 'network.xyo.auth.signin'\n\n/**\nBrowser operations intentionally exposed by the datalake control plane.\n*/\nexport const DATALAKE_CONTROL_OPERATIONS = [\n 'datalake:create',\n 'datalake:describe',\n 'datalake:list',\n] as const\n\n/**\nBrowser operations intentionally exposed by the datalake data plane.\n*/\nexport const DATALAKE_DATA_OPERATIONS = [\n 'payload:append',\n 'payload:read',\n 'usage:read',\n] as const\n\nexport type DatalakeControlOperation = typeof DATALAKE_CONTROL_OPERATIONS[number]\nexport type DatalakeDataOperation = typeof DATALAKE_DATA_OPERATIONS[number]\nexport type DatalakeOperation = DatalakeControlOperation | DatalakeDataOperation\n\n/**\nCanonical complete scope strings used when requesting browser wallet approval.\n*/\nexport const DATALAKE_CONTROL_SCOPE = DATALAKE_CONTROL_OPERATIONS.join(' ')\nexport const DATALAKE_DATA_SCOPE = DATALAKE_DATA_OPERATIONS.join(' ')\n\nexport function isDatalakeControlOperation(value: string): value is DatalakeControlOperation {\n return (DATALAKE_CONTROL_OPERATIONS as readonly string[]).includes(value)\n}\n\nexport function isDatalakeDataOperation(value: string): value is DatalakeDataOperation {\n return (DATALAKE_DATA_OPERATIONS as readonly string[]).includes(value)\n}\n", "/**\n * Datalake service tiers. Each tier maps to a storage driver + resource profile\n * on the control plane: small/medium use the shared hot pool, large gets a\n * dedicated RestDataLake pod, archive uses the S3 + DynamoDB cold driver.\n */\nexport type DatalakeTier = 'small' | 'medium' | 'large' | 'archive'\n\nexport const DATALAKE_TIERS: readonly DatalakeTier[] = ['small', 'medium', 'large', 'archive'] as const\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["createHmac", "createHmac", "createHmac", "randomBytes", "base64UrlEncode", "randomBytes", "createHmac"]
|
|
7
7
|
}
|
|
@@ -6,7 +6,8 @@ import type { DatalakeTier } from './Tier.ts';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface DatalakeConfig {
|
|
8
8
|
/**
|
|
9
|
-
Payload schemas allowed for insert
|
|
9
|
+
Payload schemas allowed for insert. In allowlist mode an explicit empty
|
|
10
|
+
array accepts no schemas; otherwise an empty array retains legacy unrestricted admission.
|
|
10
11
|
*/
|
|
11
12
|
allowedSchemas?: string[];
|
|
12
13
|
/**
|
|
@@ -17,6 +18,11 @@ export interface DatalakeConfig {
|
|
|
17
18
|
Provisioned IOPS target. Ignored for the archive tier.
|
|
18
19
|
*/
|
|
19
20
|
iops?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum UTF-8 JSON bytes per payload, excluding server storage metadata
|
|
23
|
+
* but including client metadata, before compression. Required in allowlist mode.
|
|
24
|
+
*/
|
|
25
|
+
maxPayloadBytes?: number;
|
|
20
26
|
/**
|
|
21
27
|
* Per-datalake rate-limit overrides. When omitted, the data plane's
|
|
22
28
|
* default limits apply. Use this to tighten compliance-sensitive
|
|
@@ -31,6 +37,16 @@ export interface DatalakeConfig {
|
|
|
31
37
|
Retention policy in days. `null` means keep forever.
|
|
32
38
|
*/
|
|
33
39
|
retentionDays?: number | null;
|
|
40
|
+
/**
|
|
41
|
+
* Optional per-schema byte ceilings. A schema limit can only tighten
|
|
42
|
+
* maxPayloadBytes, never raise the global ceiling.
|
|
43
|
+
*/
|
|
44
|
+
schemaMaxPayloadBytes?: Record<string, number>;
|
|
45
|
+
/**
|
|
46
|
+
* Explicit strict admission. Requires allowedSchemas to be supplied and a
|
|
47
|
+
* finite positive maxPayloadBytes. Omission retains legacy schema semantics.
|
|
48
|
+
*/
|
|
49
|
+
schemaPolicy?: 'allowlist';
|
|
34
50
|
/**
|
|
35
51
|
Provisioned capacity in bytes. Ignored for the archive tier.
|
|
36
52
|
*/
|
|
@@ -49,6 +65,8 @@ export interface DatalakeConfig {
|
|
|
49
65
|
*/
|
|
50
66
|
verifyHashes?: boolean;
|
|
51
67
|
}
|
|
68
|
+
/** Validate admission settings before persisting or applying a policy. */
|
|
69
|
+
export declare function validateDatalakeAdmissionConfig(config: DatalakeConfig): void;
|
|
52
70
|
export interface RateLimitOverrides {
|
|
53
71
|
/**
|
|
54
72
|
Max anonymous requests per minute.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatalakeConfig.d.ts","sourceRoot":"","sources":["../../../src/types/DatalakeConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B
|
|
1
|
+
{"version":3,"file":"DatalakeConfig.d.ts","sourceRoot":"","sources":["../../../src/types/DatalakeConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;MAGE;IACF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB;;MAEE;IACF,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B;;MAEE;IACF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAA;IAC/B;;MAEE;IACF,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB;;MAEE;IACF,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9C;;;OAGG;IACH,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B;;MAEE;IACF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;MAEE;IACF,IAAI,EAAE,YAAY,CAAA;IAClB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,0EAA0E;AAC1E,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAwB5E;AAQD,MAAM,WAAW,kBAAkB;IACjC;;MAEE;IACF,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;MAEE;IACF,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ariestools/aries-datalake-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "Shared types and contracts for Aries on-demand XL1 datalake provisioning",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"xylabs",
|
|
@@ -42,16 +42,16 @@
|
|
|
42
42
|
"README.md"
|
|
43
43
|
],
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@ariestools/toolchain": "~
|
|
46
|
-
"@ariestools/tsconfig": "~
|
|
47
|
-
"@types/node": "~26.
|
|
48
|
-
"@xyo-network/sdk-protocol": "~7.
|
|
45
|
+
"@ariestools/toolchain": "~10.0.6",
|
|
46
|
+
"@ariestools/tsconfig": "~10.0.6",
|
|
47
|
+
"@types/node": "~26.5.1",
|
|
48
|
+
"@xyo-network/sdk-protocol": "~7.4.2",
|
|
49
49
|
"typescript": "~6.0.3",
|
|
50
|
-
"vite": "~8.
|
|
51
|
-
"vitest": "~
|
|
50
|
+
"vite": "~8.3.0",
|
|
51
|
+
"vitest": "~5.0.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@xyo-network/sdk-protocol": "^7.
|
|
54
|
+
"@xyo-network/sdk-protocol": "^7.4"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|
|
57
57
|
"node": ">=18.17.1"
|