@hypercerts-org/sdk-core 0.6.0-beta.0 → 0.8.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1242,11 +1242,11 @@ interface CreateHypercertParams {
1242
1242
  */
1243
1243
  description?: string;
1244
1244
  /**
1245
- * Spatial Reference System identifier.
1245
+ * Spatial Reference System identifier (required if location is provided).
1246
1246
  *
1247
1247
  * @example "EPSG:4326" for WGS84
1248
1248
  */
1249
- srs?: string;
1249
+ srs: string;
1250
1250
  /**
1251
1251
  * GeoJSON file as a Blob for precise boundaries.
1252
1252
  */
@@ -1723,13 +1723,18 @@ interface HypercertOperations extends EventEmitter<HypercertEvents> {
1723
1723
  *
1724
1724
  * @param uri - AT-URI of the hypercert
1725
1725
  * @param location - Location data
1726
+ * @param location.value - Location value (address, coordinates, or description)
1727
+ * @param location.srs - Spatial Reference System (required). Use 'EPSG:4326' for WGS84 lat/lon coordinates.
1728
+ * @param location.name - Optional human-readable location name
1729
+ * @param location.description - Optional description of the location
1730
+ * @param location.geojson - Optional GeoJSON blob for precise boundaries
1726
1731
  * @returns Promise resolving to location record result
1727
1732
  */
1728
1733
  attachLocation(uri: string, location: {
1729
1734
  value: string;
1730
1735
  name?: string;
1731
1736
  description?: string;
1732
- srs?: string;
1737
+ srs: string;
1733
1738
  geojson?: Blob;
1734
1739
  }): Promise<CreateResult>;
1735
1740
  /**
@@ -2987,6 +2992,69 @@ declare class ATProtoSDK {
2987
2992
  */
2988
2993
  declare function createATProtoSDK(config: ATProtoSDKConfig): ATProtoSDK;
2989
2994
 
2995
+ /**
2996
+ * ConfigurableAgent - Agent with configurable service URL routing.
2997
+ *
2998
+ * This module provides an Agent extension that allows routing requests to
2999
+ * a specific server URL, overriding the default URL from the OAuth session.
3000
+ *
3001
+ * @packageDocumentation
3002
+ */
3003
+
3004
+ /**
3005
+ * Agent subclass that routes requests to a configurable service URL.
3006
+ *
3007
+ * The standard Agent uses the service URL embedded in the OAuth session's
3008
+ * fetch handler. This class allows overriding that URL to route requests
3009
+ * to different servers (e.g., PDS vs SDS, or multiple SDS instances).
3010
+ *
3011
+ * @remarks
3012
+ * This is particularly useful for:
3013
+ * - Routing to a Shared Data Server (SDS) while authenticated via PDS
3014
+ * - Supporting multiple SDS instances for different organizations
3015
+ * - Testing against different server environments
3016
+ *
3017
+ * @example Basic usage
3018
+ * ```typescript
3019
+ * const session = await sdk.authorize("user.bsky.social");
3020
+ *
3021
+ * // Create agent routing to SDS instead of session's default PDS
3022
+ * const sdsAgent = new ConfigurableAgent(session, "https://sds.hypercerts.org");
3023
+ *
3024
+ * // All requests will now go to the SDS
3025
+ * await sdsAgent.com.atproto.repo.createRecord({...});
3026
+ * ```
3027
+ *
3028
+ * @example Multiple SDS instances
3029
+ * ```typescript
3030
+ * // Route to organization A's SDS
3031
+ * const orgAAgent = new ConfigurableAgent(session, "https://sds-org-a.example.com");
3032
+ *
3033
+ * // Route to organization B's SDS
3034
+ * const orgBAgent = new ConfigurableAgent(session, "https://sds-org-b.example.com");
3035
+ * ```
3036
+ */
3037
+ declare class ConfigurableAgent extends Agent {
3038
+ private customServiceUrl;
3039
+ /**
3040
+ * Creates a ConfigurableAgent that routes to a specific service URL.
3041
+ *
3042
+ * @param session - OAuth session for authentication
3043
+ * @param serviceUrl - Base URL of the server to route requests to
3044
+ *
3045
+ * @remarks
3046
+ * The agent wraps the session's fetch handler to intercept requests and
3047
+ * prepend the custom service URL instead of using the session's default.
3048
+ */
3049
+ constructor(session: Session, serviceUrl: string);
3050
+ /**
3051
+ * Gets the service URL this agent routes to.
3052
+ *
3053
+ * @returns The base URL of the configured service
3054
+ */
3055
+ getServiceUrl(): string;
3056
+ }
3057
+
2990
3058
  /**
2991
3059
  * Base error class for all SDK errors.
2992
3060
  *
@@ -3464,5 +3532,5 @@ declare class InMemoryStateStore implements StateStore {
3464
3532
  clear(): void;
3465
3533
  }
3466
3534
 
3467
- export { ATProtoSDK, ATProtoSDKConfigSchema, ATProtoSDKError, AuthenticationError, CollaboratorPermissionsSchema, CollaboratorSchema, InMemorySessionStore, InMemoryStateStore, LexiconRegistry, NetworkError, OAuthConfigSchema, OrganizationSchema, Repository, SDSRequiredError, ServerConfigSchema, SessionExpiredError, TimeoutConfigSchema, ValidationError, createATProtoSDK };
3535
+ export { ATProtoSDK, ATProtoSDKConfigSchema, ATProtoSDKError, AuthenticationError, CollaboratorPermissionsSchema, CollaboratorSchema, ConfigurableAgent, InMemorySessionStore, InMemoryStateStore, LexiconRegistry, NetworkError, OAuthConfigSchema, OrganizationSchema, Repository, SDSRequiredError, ServerConfigSchema, SessionExpiredError, TimeoutConfigSchema, ValidationError, createATProtoSDK };
3468
3536
  export type { ATProtoSDKConfig, AuthorizeOptions, BlobOperations, BlobRef, CacheInterface, Collaborator, CollaboratorOperations, CollaboratorPermissions, CreateHypercertParams, CreateHypercertResult, CreateResult, DID, HypercertClaim, HypercertCollection, HypercertCollectionClaimItem, HypercertContribution, HypercertEvaluation, HypercertEvents, HypercertEvidence, HypercertImage, HypercertLocation, HypercertMeasurement, HypercertOperations, HypercertRights, HypercertWithMetadata, ListParams, LoggerInterface, Organization, OrganizationInfo, OrganizationOperations, PaginatedList, ProfileOperations, ProgressStep, RecordOperations, RepositoryAccessGrant, RepositoryOptions, RepositoryRole, Session, SessionStore, StateStore, StrongRef, UpdateResult, ValidationResult };
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { JoseKey, NodeOAuthClient } from '@atproto/oauth-client-node';
2
2
  import { Lexicons } from '@atproto/lexicon';
3
- import { Agent } from '@atproto/api';
4
3
  import { HYPERCERT_COLLECTIONS, HYPERCERT_LEXICONS } from '@hypercerts-org/lexicon';
5
4
  export { AppCertifiedLocation, ComAtprotoRepoStrongRef, HYPERCERT_COLLECTIONS, HYPERCERT_LEXICONS, OrgHypercertsClaim, OrgHypercertsClaimContribution, OrgHypercertsClaimEvaluation, OrgHypercertsClaimEvidence, OrgHypercertsClaimMeasurement, OrgHypercertsClaimRights, OrgHypercertsCollection, ids, lexicons, schemaDict, schemas, validate } from '@hypercerts-org/lexicon';
5
+ import { Agent } from '@atproto/api';
6
6
  import { EventEmitter } from 'eventemitter3';
7
7
  import { z } from 'zod';
8
8
 
@@ -1245,6 +1245,80 @@ class LexiconRegistry {
1245
1245
  }
1246
1246
  }
1247
1247
 
1248
+ /**
1249
+ * ConfigurableAgent - Agent with configurable service URL routing.
1250
+ *
1251
+ * This module provides an Agent extension that allows routing requests to
1252
+ * a specific server URL, overriding the default URL from the OAuth session.
1253
+ *
1254
+ * @packageDocumentation
1255
+ */
1256
+ /**
1257
+ * Agent subclass that routes requests to a configurable service URL.
1258
+ *
1259
+ * The standard Agent uses the service URL embedded in the OAuth session's
1260
+ * fetch handler. This class allows overriding that URL to route requests
1261
+ * to different servers (e.g., PDS vs SDS, or multiple SDS instances).
1262
+ *
1263
+ * @remarks
1264
+ * This is particularly useful for:
1265
+ * - Routing to a Shared Data Server (SDS) while authenticated via PDS
1266
+ * - Supporting multiple SDS instances for different organizations
1267
+ * - Testing against different server environments
1268
+ *
1269
+ * @example Basic usage
1270
+ * ```typescript
1271
+ * const session = await sdk.authorize("user.bsky.social");
1272
+ *
1273
+ * // Create agent routing to SDS instead of session's default PDS
1274
+ * const sdsAgent = new ConfigurableAgent(session, "https://sds.hypercerts.org");
1275
+ *
1276
+ * // All requests will now go to the SDS
1277
+ * await sdsAgent.com.atproto.repo.createRecord({...});
1278
+ * ```
1279
+ *
1280
+ * @example Multiple SDS instances
1281
+ * ```typescript
1282
+ * // Route to organization A's SDS
1283
+ * const orgAAgent = new ConfigurableAgent(session, "https://sds-org-a.example.com");
1284
+ *
1285
+ * // Route to organization B's SDS
1286
+ * const orgBAgent = new ConfigurableAgent(session, "https://sds-org-b.example.com");
1287
+ * ```
1288
+ */
1289
+ class ConfigurableAgent extends Agent {
1290
+ /**
1291
+ * Creates a ConfigurableAgent that routes to a specific service URL.
1292
+ *
1293
+ * @param session - OAuth session for authentication
1294
+ * @param serviceUrl - Base URL of the server to route requests to
1295
+ *
1296
+ * @remarks
1297
+ * The agent wraps the session's fetch handler to intercept requests and
1298
+ * prepend the custom service URL instead of using the session's default.
1299
+ */
1300
+ constructor(session, serviceUrl) {
1301
+ // Create a custom fetch handler that uses our service URL
1302
+ const customFetchHandler = async (pathname, init) => {
1303
+ // Construct the full URL with our custom service
1304
+ const url = new URL(pathname, serviceUrl).toString();
1305
+ // Use the session's fetch handler for authentication (DPoP, etc.)
1306
+ return session.fetchHandler(url, init);
1307
+ };
1308
+ // Initialize the parent Agent with our custom fetch handler
1309
+ super(customFetchHandler);
1310
+ this.customServiceUrl = serviceUrl;
1311
+ }
1312
+ /**
1313
+ * Gets the service URL this agent routes to.
1314
+ *
1315
+ * @returns The base URL of the configured service
1316
+ */
1317
+ getServiceUrl() {
1318
+ return this.customServiceUrl;
1319
+ }
1320
+ }
1321
+
1248
1322
  /**
1249
1323
  * RecordOperationsImpl - Low-level record CRUD operations.
1250
1324
  *
@@ -2195,6 +2269,7 @@ class HypercertOperationsImpl extends EventEmitter {
2195
2269
  // Step 2: Create rights record
2196
2270
  this.emitProgress(params.onProgress, { name: "createRights", status: "start" });
2197
2271
  const rightsRecord = {
2272
+ $type: HYPERCERT_COLLECTIONS.RIGHTS,
2198
2273
  rightsName: params.rights.name,
2199
2274
  rightsType: params.rights.type,
2200
2275
  rightsDescription: params.rights.description,
@@ -2223,6 +2298,7 @@ class HypercertOperationsImpl extends EventEmitter {
2223
2298
  // Step 3: Create hypercert record
2224
2299
  this.emitProgress(params.onProgress, { name: "createHypercert", status: "start" });
2225
2300
  const hypercertRecord = {
2301
+ $type: HYPERCERT_COLLECTIONS.CLAIM,
2226
2302
  title: params.title,
2227
2303
  description: params.description,
2228
2304
  workScope: params.workScope,
@@ -2570,6 +2646,7 @@ class HypercertOperationsImpl extends EventEmitter {
2570
2646
  * await repo.hypercerts.attachLocation(hypercertUri, {
2571
2647
  * value: "San Francisco, CA",
2572
2648
  * name: "SF Bay Area",
2649
+ * srs: "EPSG:4326",
2573
2650
  * });
2574
2651
  * ```
2575
2652
  *
@@ -2588,32 +2665,54 @@ class HypercertOperationsImpl extends EventEmitter {
2588
2665
  */
2589
2666
  async attachLocation(hypercertUri, location) {
2590
2667
  try {
2591
- // Get hypercert to get CID
2592
- const hypercert = await this.get(hypercertUri);
2668
+ // Validate required srs field
2669
+ if (!location.srs) {
2670
+ throw new ValidationError("srs (Spatial Reference System) is required. Example: 'EPSG:4326' for WGS84 coordinates, or 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' for CRS84.");
2671
+ }
2672
+ // Validate that hypercert exists (unused but confirms hypercert is valid)
2673
+ await this.get(hypercertUri);
2593
2674
  const createdAt = new Date().toISOString();
2594
- let locationValue = location.value;
2675
+ // Determine location type and prepare location data
2676
+ let locationData;
2677
+ let locationType;
2595
2678
  if (location.geojson) {
2679
+ // Upload GeoJSON as a blob
2596
2680
  const arrayBuffer = await location.geojson.arrayBuffer();
2597
2681
  const uint8Array = new Uint8Array(arrayBuffer);
2598
2682
  const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {
2599
2683
  encoding: location.geojson.type || "application/geo+json",
2600
2684
  });
2601
2685
  if (uploadResult.success) {
2602
- locationValue = {
2686
+ locationData = {
2603
2687
  $type: "blob",
2604
2688
  ref: { $link: uploadResult.data.blob.ref.toString() },
2605
2689
  mimeType: uploadResult.data.blob.mimeType,
2606
2690
  size: uploadResult.data.blob.size,
2607
2691
  };
2692
+ locationType = "geojson-point";
2693
+ }
2694
+ else {
2695
+ throw new NetworkError("Failed to upload GeoJSON blob");
2608
2696
  }
2609
2697
  }
2698
+ else {
2699
+ // Use value as a URI reference
2700
+ locationData = {
2701
+ $type: "app.certified.defs#uri",
2702
+ uri: location.value,
2703
+ };
2704
+ locationType = "coordinate-decimal";
2705
+ }
2706
+ // Build location record according to app.certified.location lexicon
2610
2707
  const locationRecord = {
2611
- hypercert: { uri: hypercert.uri, cid: hypercert.cid },
2612
- value: locationValue,
2708
+ $type: HYPERCERT_COLLECTIONS.LOCATION,
2709
+ lpVersion: "1.0",
2710
+ srs: location.srs,
2711
+ locationType,
2712
+ location: locationData,
2613
2713
  createdAt,
2614
2714
  name: location.name,
2615
2715
  description: location.description,
2616
- srs: location.srs,
2617
2716
  };
2618
2717
  const validation = this.lexiconRegistry.validate(HYPERCERT_COLLECTIONS.LOCATION, locationRecord);
2619
2718
  if (!validation.valid) {
@@ -2700,10 +2799,12 @@ class HypercertOperationsImpl extends EventEmitter {
2700
2799
  try {
2701
2800
  const createdAt = new Date().toISOString();
2702
2801
  const contributionRecord = {
2802
+ $type: HYPERCERT_COLLECTIONS.CONTRIBUTION,
2703
2803
  contributors: params.contributors,
2704
2804
  role: params.role,
2705
2805
  createdAt,
2706
2806
  description: params.description,
2807
+ hypercert: { uri: "", cid: "" }, // Will be set below if hypercertUri provided
2707
2808
  };
2708
2809
  if (params.hypercertUri) {
2709
2810
  const hypercert = await this.get(params.hypercertUri);
@@ -2764,6 +2865,7 @@ class HypercertOperationsImpl extends EventEmitter {
2764
2865
  const hypercert = await this.get(params.hypercertUri);
2765
2866
  const createdAt = new Date().toISOString();
2766
2867
  const measurementRecord = {
2868
+ $type: HYPERCERT_COLLECTIONS.MEASUREMENT,
2767
2869
  hypercert: { uri: hypercert.uri, cid: hypercert.cid },
2768
2870
  measurers: params.measurers,
2769
2871
  metric: params.metric,
@@ -2819,6 +2921,7 @@ class HypercertOperationsImpl extends EventEmitter {
2819
2921
  const subject = await this.get(params.subjectUri);
2820
2922
  const createdAt = new Date().toISOString();
2821
2923
  const evaluationRecord = {
2924
+ $type: HYPERCERT_COLLECTIONS.EVALUATION,
2822
2925
  subject: { uri: subject.uri, cid: subject.cid },
2823
2926
  evaluators: params.evaluators,
2824
2927
  summary: params.summary,
@@ -2893,6 +2996,7 @@ class HypercertOperationsImpl extends EventEmitter {
2893
2996
  }
2894
2997
  }
2895
2998
  const collectionRecord = {
2999
+ $type: HYPERCERT_COLLECTIONS.COLLECTION,
2896
3000
  title: params.title,
2897
3001
  claims: params.claims.map((c) => ({ claim: { uri: c.uri, cid: c.cid }, weight: c.weight })),
2898
3002
  createdAt,
@@ -3771,11 +3875,10 @@ class Repository {
3771
3875
  this.lexiconRegistry = lexiconRegistry;
3772
3876
  this._isSDS = isSDS;
3773
3877
  this.logger = logger;
3774
- // Create Agent with OAuth session
3775
- this.agent = new Agent(session);
3776
- // Configure Agent to use the specified server URL (PDS or SDS)
3777
- // This ensures queries are routed to the correct server
3778
- this.agent.api.xrpc.uri = new URL(serverUrl);
3878
+ // Create a ConfigurableAgent that routes requests to the specified server URL
3879
+ // This allows routing to PDS, SDS, or any custom server while maintaining
3880
+ // the OAuth session's authentication
3881
+ this.agent = new ConfigurableAgent(session, serverUrl);
3779
3882
  this.lexiconRegistry.addToAgent(this.agent);
3780
3883
  // Register hypercert lexicons
3781
3884
  this.lexiconRegistry.registerMany(HYPERCERT_LEXICONS);
@@ -4625,5 +4728,5 @@ const CollaboratorSchema = z.object({
4625
4728
  revokedAt: z.string().optional(),
4626
4729
  });
4627
4730
 
4628
- export { ATProtoSDK, ATProtoSDKConfigSchema, ATProtoSDKError, AuthenticationError, CollaboratorPermissionsSchema, CollaboratorSchema, InMemorySessionStore, InMemoryStateStore, LexiconRegistry, NetworkError, OAuthConfigSchema, OrganizationSchema, Repository, SDSRequiredError, ServerConfigSchema, SessionExpiredError, TimeoutConfigSchema, ValidationError, createATProtoSDK };
4731
+ export { ATProtoSDK, ATProtoSDKConfigSchema, ATProtoSDKError, AuthenticationError, CollaboratorPermissionsSchema, CollaboratorSchema, ConfigurableAgent, InMemorySessionStore, InMemoryStateStore, LexiconRegistry, NetworkError, OAuthConfigSchema, OrganizationSchema, Repository, SDSRequiredError, ServerConfigSchema, SessionExpiredError, TimeoutConfigSchema, ValidationError, createATProtoSDK };
4629
4732
  //# sourceMappingURL=index.mjs.map