@objectstack/client 4.0.3 → 4.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectstack/client",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Official Client SDK for ObjectStack Protocol",
6
6
  "main": "dist/index.js",
@@ -13,20 +13,20 @@
13
13
  }
14
14
  },
15
15
  "dependencies": {
16
- "@objectstack/core": "4.0.3",
17
- "@objectstack/spec": "4.0.3"
16
+ "@objectstack/core": "4.0.4",
17
+ "@objectstack/spec": "4.0.4"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@hono/node-server": "^1.19.14",
21
21
  "msw": "^2.13.2",
22
22
  "typescript": "^6.0.2",
23
23
  "vitest": "^4.1.4",
24
- "@objectstack/driver-memory": "4.0.3",
25
- "@objectstack/hono": "4.0.3",
26
- "@objectstack/objectql": "4.0.3",
27
- "@objectstack/plugin-hono-server": "4.0.3",
28
- "@objectstack/plugin-msw": "4.0.3",
29
- "@objectstack/runtime": "4.0.3"
24
+ "@objectstack/driver-memory": "4.0.4",
25
+ "@objectstack/hono": "4.0.4",
26
+ "@objectstack/objectql": "4.0.4",
27
+ "@objectstack/plugin-hono-server": "4.0.4",
28
+ "@objectstack/plugin-msw": "4.0.4",
29
+ "@objectstack/runtime": "4.0.4"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsup --config ../../tsup.config.ts",
@@ -107,11 +107,19 @@ describe('ObjectStackClient (with Hono Server)', () => {
107
107
  baseUrl = `http://localhost:${port}`;
108
108
 
109
109
  console.log(`Test server running at ${baseUrl}`);
110
- });
110
+ }, 30_000);
111
111
 
112
112
  afterAll(async () => {
113
- if (kernel) await kernel.shutdown();
114
- });
113
+ if (kernel) {
114
+ // Race shutdown against a hard deadline.
115
+ // kernel.shutdown() can hang when pino's flush callback never fires
116
+ // in CI (worker-thread transport timing issues), so cap the wait.
117
+ await Promise.race([
118
+ kernel.shutdown(),
119
+ new Promise<void>((resolve) => setTimeout(resolve, 10_000)),
120
+ ]);
121
+ }
122
+ }, 30_000);
115
123
 
116
124
  it('should connect to hono server and discover endpoints', async () => {
117
125
  const client = new ObjectStackClient({ baseUrl });
package/src/index.ts CHANGED
@@ -253,12 +253,26 @@ export class ObjectStackClient {
253
253
  */
254
254
  async connect() {
255
255
  this.logger.debug('Connecting to ObjectStack server', { baseUrl: this.baseUrl });
256
-
256
+
257
257
  try {
258
258
  let data: DiscoveryResult | undefined;
259
259
 
260
- // 1. Try Standard Discovery (.well-known)
260
+ // 1. Try Protocol-standard Discovery Path /api/v1/discovery (primary)
261
261
  try {
262
+ const discoveryUrl = `${this.baseUrl}/api/v1/discovery`;
263
+ this.logger.debug('Probing protocol-standard discovery endpoint', { url: discoveryUrl });
264
+ const res = await this.fetchImpl(discoveryUrl);
265
+ if (res.ok) {
266
+ const body = await res.json();
267
+ data = body.data || body;
268
+ this.logger.debug('Discovered via /api/v1/discovery');
269
+ }
270
+ } catch (e) {
271
+ this.logger.debug('Protocol-standard discovery probe failed', { error: (e as Error).message });
272
+ }
273
+
274
+ // 2. Fallback to Standard Discovery (.well-known)
275
+ if (!data) {
262
276
  let wellKnownUrl: string;
263
277
  try {
264
278
  // If baseUrl is absolute, get origin
@@ -269,24 +283,10 @@ export class ObjectStackClient {
269
283
  wellKnownUrl = '/.well-known/objectstack';
270
284
  }
271
285
 
272
- this.logger.debug('Probing .well-known discovery', { url: wellKnownUrl });
286
+ this.logger.debug('Falling back to .well-known discovery', { url: wellKnownUrl });
273
287
  const res = await this.fetchImpl(wellKnownUrl);
274
- if (res.ok) {
275
- const body = await res.json();
276
- data = body.data || body;
277
- this.logger.debug('Discovered via .well-known');
278
- }
279
- } catch (e) {
280
- this.logger.debug('Standard discovery probe failed', { error: (e as Error).message });
281
- }
282
-
283
- // 2. Fallback to Protocol-standard Discovery Path /api/v1/discovery
284
- if (!data) {
285
- const fallbackUrl = `${this.baseUrl}/api/v1/discovery`;
286
- this.logger.debug('Falling back to standard discovery endpoint', { url: fallbackUrl });
287
- const res = await this.fetchImpl(fallbackUrl);
288
288
  if (!res.ok) {
289
- throw new Error(`Failed to connect to ${fallbackUrl}: ${res.statusText}`);
289
+ throw new Error(`Failed to connect to ${wellKnownUrl}: ${res.statusText}`);
290
290
  }
291
291
  const body = await res.json();
292
292
  data = body.data || body;
@@ -297,13 +297,13 @@ export class ObjectStackClient {
297
297
  }
298
298
 
299
299
  this.discoveryInfo = data;
300
-
301
- this.logger.info('Connected to ObjectStack server', {
300
+
301
+ this.logger.info('Connected to ObjectStack server', {
302
302
  version: data.version,
303
303
  apiName: data.apiName,
304
- services: data.services
304
+ services: data.services
305
305
  });
306
-
306
+
307
307
  return data as DiscoveryResult;
308
308
  } catch (e) {
309
309
  this.logger.error('Failed to connect to ObjectStack server', e as Error, { baseUrl: this.baseUrl });
@@ -578,6 +578,16 @@ export class ObjectStackClient {
578
578
  * Authentication Services
579
579
  */
580
580
  auth = {
581
+ /**
582
+ * Get authentication configuration
583
+ * Returns available auth providers and features
584
+ */
585
+ getConfig: async () => {
586
+ const route = this.getRoute('auth');
587
+ const res = await this.fetch(`${this.baseUrl}${route}/config`);
588
+ return this.unwrapResponse(res);
589
+ },
590
+
581
591
  /**
582
592
  * Login with email and password
583
593
  * Uses better-auth endpoint: POST /sign-in/email
@@ -1872,4 +1882,8 @@ export type {
1872
1882
  SubscribeResponse,
1873
1883
  UnsubscribeResponse,
1874
1884
  WellKnownCapabilities,
1885
+ GetAuthConfigResponse,
1886
+ AuthProviderInfo,
1887
+ EmailPasswordConfigPublic,
1888
+ AuthFeaturesConfig,
1875
1889
  } from '@objectstack/spec/api';
@@ -13,15 +13,15 @@ import { ObjectStackClient } from '../../src/index';
13
13
  const TEST_SERVER_URL = process.env.TEST_SERVER_URL || 'http://localhost:3000';
14
14
 
15
15
  describe('Discovery & Connection', () => {
16
- describe('TC-DISC-001: Standard Discovery via .well-known', () => {
17
- test('should discover API from .well-known/objectstack', async () => {
18
- const client = new ObjectStackClient({
16
+ describe('TC-DISC-001: Protocol-standard Discovery via /api/v1/discovery', () => {
17
+ test('should discover API from /api/v1/discovery', async () => {
18
+ const client = new ObjectStackClient({
19
19
  baseUrl: TEST_SERVER_URL,
20
20
  debug: true
21
21
  });
22
-
22
+
23
23
  const discovery = await client.connect();
24
-
24
+
25
25
  expect(discovery.version).toBeDefined();
26
26
  expect(discovery.apiName).toBeDefined();
27
27
  expect(discovery.routes).toBeDefined();