@slates/profiles 1.0.0-rc.4 → 1.0.0-rc.5

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.cjs CHANGED
@@ -378,20 +378,25 @@ var createSlatesClientFromProfile = async (profile, opts = {}) => {
378
378
  } : null
379
379
  }
380
380
  });
381
- if (firstAuth) {
381
+ if (firstAuth && opts.autoRefresh !== false) {
382
382
  attachAutoRefresh(client, profile, firstAuth, opts.store);
383
383
  }
384
384
  return client;
385
385
  };
386
386
  var EXPIRY_BUFFER_MS = 60 * 1e3;
387
- var shouldRefreshOAuthAuth = (auth) => {
388
- if (auth.authType !== "auth.oauth") return false;
389
- if (!auth.clientId || !auth.clientSecret) return false;
390
- if (typeof auth.output?.refreshToken !== "string" || !auth.output.refreshToken) return false;
387
+ var hasExpiredOrExpiringOutput = (auth) => {
391
388
  if (typeof auth.output?.expiresAt !== "string" || !auth.output.expiresAt) return false;
392
389
  let expiresAt = Date.parse(auth.output.expiresAt);
393
390
  return Number.isFinite(expiresAt) && expiresAt <= Date.now() + EXPIRY_BUFFER_MS;
394
391
  };
392
+ var shouldRefreshAuth = (auth) => {
393
+ if (!hasExpiredOrExpiringOutput(auth)) return false;
394
+ if (auth.authType === "auth.oauth") {
395
+ if (!auth.clientId || !auth.clientSecret) return false;
396
+ if (typeof auth.output?.refreshToken !== "string" || !auth.output.refreshToken) return false;
397
+ }
398
+ return true;
399
+ };
395
400
  var attachAutoRefresh = (client, profile, storedAuth, store) => {
396
401
  let baseRequest = client.request.bind(client);
397
402
  let inflightRefresh = null;
@@ -400,7 +405,7 @@ var attachAutoRefresh = (client, profile, storedAuth, store) => {
400
405
  await inflightRefresh;
401
406
  return;
402
407
  }
403
- if (!shouldRefreshOAuthAuth(storedAuth)) {
408
+ if (!shouldRefreshAuth(storedAuth)) {
404
409
  return;
405
410
  }
406
411
  inflightRefresh = (async () => {
package/dist/index.d.cts CHANGED
@@ -120,6 +120,7 @@ declare let openSlatesCliStore: (opts?: {
120
120
  declare let createSlatesClientFromProfile: (profile: SlatesProfileRecord, opts?: {
121
121
  cwd?: string;
122
122
  store?: SlatesCliStore;
123
+ autoRefresh?: boolean;
123
124
  }) => Promise<_slates_client.SlatesProtocolClient>;
124
125
 
125
126
  export { SlatesCliStore, type SlatesCliStoreData, type SlatesCliStoreScope, type SlatesLocalProfileTarget, type SlatesOAuthCredentialRecord, type SlatesProfileRecord, type SlatesProfileTarget, type SlatesStoredAuth, createSlatesClientFromProfile, openSlatesCliStore, resolveSlatesCliDir, resolveSlatesCliProfilesDir, resolveSlatesCliRoot };
package/dist/index.d.ts CHANGED
@@ -120,6 +120,7 @@ declare let openSlatesCliStore: (opts?: {
120
120
  declare let createSlatesClientFromProfile: (profile: SlatesProfileRecord, opts?: {
121
121
  cwd?: string;
122
122
  store?: SlatesCliStore;
123
+ autoRefresh?: boolean;
123
124
  }) => Promise<_slates_client.SlatesProtocolClient>;
124
125
 
125
126
  export { SlatesCliStore, type SlatesCliStoreData, type SlatesCliStoreScope, type SlatesLocalProfileTarget, type SlatesOAuthCredentialRecord, type SlatesProfileRecord, type SlatesProfileTarget, type SlatesStoredAuth, createSlatesClientFromProfile, openSlatesCliStore, resolveSlatesCliDir, resolveSlatesCliProfilesDir, resolveSlatesCliRoot };
@@ -337,20 +337,25 @@ var createSlatesClientFromProfile = async (profile, opts = {}) => {
337
337
  } : null
338
338
  }
339
339
  });
340
- if (firstAuth) {
340
+ if (firstAuth && opts.autoRefresh !== false) {
341
341
  attachAutoRefresh(client, profile, firstAuth, opts.store);
342
342
  }
343
343
  return client;
344
344
  };
345
345
  var EXPIRY_BUFFER_MS = 60 * 1e3;
346
- var shouldRefreshOAuthAuth = (auth) => {
347
- if (auth.authType !== "auth.oauth") return false;
348
- if (!auth.clientId || !auth.clientSecret) return false;
349
- if (typeof auth.output?.refreshToken !== "string" || !auth.output.refreshToken) return false;
346
+ var hasExpiredOrExpiringOutput = (auth) => {
350
347
  if (typeof auth.output?.expiresAt !== "string" || !auth.output.expiresAt) return false;
351
348
  let expiresAt = Date.parse(auth.output.expiresAt);
352
349
  return Number.isFinite(expiresAt) && expiresAt <= Date.now() + EXPIRY_BUFFER_MS;
353
350
  };
351
+ var shouldRefreshAuth = (auth) => {
352
+ if (!hasExpiredOrExpiringOutput(auth)) return false;
353
+ if (auth.authType === "auth.oauth") {
354
+ if (!auth.clientId || !auth.clientSecret) return false;
355
+ if (typeof auth.output?.refreshToken !== "string" || !auth.output.refreshToken) return false;
356
+ }
357
+ return true;
358
+ };
354
359
  var attachAutoRefresh = (client, profile, storedAuth, store) => {
355
360
  let baseRequest = client.request.bind(client);
356
361
  let inflightRefresh = null;
@@ -359,7 +364,7 @@ var attachAutoRefresh = (client, profile, storedAuth, store) => {
359
364
  await inflightRefresh;
360
365
  return;
361
366
  }
362
- if (!shouldRefreshOAuthAuth(storedAuth)) {
367
+ if (!shouldRefreshAuth(storedAuth)) {
363
368
  return;
364
369
  }
365
370
  inflightRefresh = (async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slates/profiles",
3
- "version": "1.0.0-rc.4",
3
+ "version": "1.0.0-rc.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -31,11 +31,11 @@
31
31
  "typecheck": "tsc --noEmit"
32
32
  },
33
33
  "dependencies": {
34
- "@slates/client": "1.0.0-rc.6",
35
- "@slates/proto": "1.0.0-rc.8"
34
+ "@slates/client": "1.0.0-rc.7",
35
+ "@slates/proto": "1.0.0-rc.9"
36
36
  },
37
37
  "devDependencies": {
38
- "@slates/provider": "1.0.0-rc.10",
38
+ "@slates/provider": "1.0.0-rc.11",
39
39
  "@slates/tsconfig": "1.0.0-rc.1",
40
40
  "typescript": "5.8.2",
41
41
  "vitest": "^3.1.2",
package/src/client.ts CHANGED
@@ -43,7 +43,7 @@ let loadSlateFromProfile = async (
43
43
 
44
44
  export let createSlatesClientFromProfile = async (
45
45
  profile: SlatesProfileRecord,
46
- opts: { cwd?: string; store?: SlatesCliStore } = {}
46
+ opts: { cwd?: string; store?: SlatesCliStore; autoRefresh?: boolean } = {}
47
47
  ) => {
48
48
  let firstAuth = Object.values(profile.auth)[0];
49
49
  let slate = await loadSlateFromProfile(profile, opts);
@@ -61,7 +61,7 @@ export let createSlatesClientFromProfile = async (
61
61
  }
62
62
  });
63
63
 
64
- if (firstAuth) {
64
+ if (firstAuth && opts.autoRefresh !== false) {
65
65
  attachAutoRefresh(client, profile, firstAuth, opts.store);
66
66
  }
67
67
 
@@ -70,16 +70,24 @@ export let createSlatesClientFromProfile = async (
70
70
 
71
71
  let EXPIRY_BUFFER_MS = 60 * 1000;
72
72
 
73
- let shouldRefreshOAuthAuth = (auth: SlatesStoredAuth) => {
74
- if (auth.authType !== 'auth.oauth') return false;
75
- if (!auth.clientId || !auth.clientSecret) return false;
76
- if (typeof auth.output?.refreshToken !== 'string' || !auth.output.refreshToken) return false;
73
+ let hasExpiredOrExpiringOutput = (auth: SlatesStoredAuth) => {
77
74
  if (typeof auth.output?.expiresAt !== 'string' || !auth.output.expiresAt) return false;
78
75
 
79
76
  let expiresAt = Date.parse(auth.output.expiresAt);
80
77
  return Number.isFinite(expiresAt) && expiresAt <= Date.now() + EXPIRY_BUFFER_MS;
81
78
  };
82
79
 
80
+ let shouldRefreshAuth = (auth: SlatesStoredAuth) => {
81
+ if (!hasExpiredOrExpiringOutput(auth)) return false;
82
+
83
+ if (auth.authType === 'auth.oauth') {
84
+ if (!auth.clientId || !auth.clientSecret) return false;
85
+ if (typeof auth.output?.refreshToken !== 'string' || !auth.output.refreshToken) return false;
86
+ }
87
+
88
+ return true;
89
+ };
90
+
83
91
  let attachAutoRefresh = (
84
92
  client: ReturnType<typeof createSlatesClient>,
85
93
  profile: SlatesProfileRecord,
@@ -95,7 +103,7 @@ let attachAutoRefresh = (
95
103
  return;
96
104
  }
97
105
 
98
- if (!shouldRefreshOAuthAuth(storedAuth)) {
106
+ if (!shouldRefreshAuth(storedAuth)) {
99
107
  return;
100
108
  }
101
109
 
package/src/store.test.ts CHANGED
@@ -413,4 +413,115 @@ export let provider = Slate.create({
413
413
  token: 'expired-token-refreshed'
414
414
  });
415
415
  });
416
+
417
+ it('refreshes expired custom auth automatically in the profile-backed client', async () => {
418
+ let cwd = await createTempDir();
419
+ let entry = path.join(cwd, 'custom-slate.mjs');
420
+ await writeFile(
421
+ entry,
422
+ `
423
+ import { Slate, SlateAuth, SlateConfig, SlateSpecification, SlateTool } from '@slates/provider';
424
+ import { z } from 'zod';
425
+
426
+ let config = SlateConfig.create(z.object({})).getDefaultConfig(() => ({}));
427
+ let auth = SlateAuth.create()
428
+ .output(
429
+ z.object({
430
+ token: z.string(),
431
+ expiresAt: z.string().optional()
432
+ })
433
+ )
434
+ .addCustomAuth({
435
+ type: 'auth.custom',
436
+ key: 'custom',
437
+ name: 'Custom',
438
+ inputSchema: z.object({
439
+ tokenPrefix: z.string()
440
+ }),
441
+ getOutput: async ctx => ({
442
+ output: {
443
+ token: \`\${ctx.input.tokenPrefix}-initial\`,
444
+ expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString()
445
+ }
446
+ }),
447
+ handleTokenRefresh: async ctx => ({
448
+ output: {
449
+ token: \`\${ctx.input.tokenPrefix}-refreshed\`,
450
+ expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString()
451
+ }
452
+ })
453
+ });
454
+
455
+ let spec = SlateSpecification.create({
456
+ key: 'custom-demo',
457
+ name: 'Custom Demo',
458
+ description: 'Custom auth test slate',
459
+ config,
460
+ auth
461
+ });
462
+
463
+ let tool = SlateTool.create(spec, {
464
+ key: 'whoami',
465
+ name: 'Who Am I'
466
+ })
467
+ .input(z.object({}))
468
+ .output(
469
+ z.object({
470
+ token: z.string()
471
+ })
472
+ )
473
+ .handleInvocation(async ctx => ({
474
+ output: {
475
+ token: ctx.auth.token
476
+ }
477
+ }))
478
+ .build();
479
+
480
+ export let provider = Slate.create({
481
+ spec,
482
+ tools: [tool],
483
+ triggers: []
484
+ });
485
+ `,
486
+ 'utf-8'
487
+ );
488
+
489
+ let store = await SlatesCliStore.open({
490
+ cwd,
491
+ scope: {
492
+ key: 'integrations/demo',
493
+ name: 'demo'
494
+ }
495
+ });
496
+ let profile = store.upsertProfile({
497
+ name: 'Demo',
498
+ target: {
499
+ type: 'local',
500
+ entry: './custom-slate.mjs',
501
+ exportName: 'provider'
502
+ }
503
+ });
504
+ store.setProfileConfig(profile.id, {});
505
+ store.upsertAuth(profile.id, {
506
+ authMethodId: 'custom',
507
+ authType: 'auth.custom',
508
+ input: {
509
+ tokenPrefix: 'custom-token'
510
+ },
511
+ output: {
512
+ token: 'expired-token',
513
+ expiresAt: new Date(Date.now() - 60 * 1000).toISOString()
514
+ },
515
+ scopes: []
516
+ });
517
+ await store.save();
518
+
519
+ let client = await createSlatesClientFromProfile(profile, { cwd, store });
520
+ let result = await client.invokeTool('whoami', {});
521
+
522
+ expect(result.output).toEqual({ token: 'custom-token-refreshed' });
523
+ expect(store.getAuth(profile.id, 'custom')?.output).toMatchObject({
524
+ token: 'custom-token-refreshed'
525
+ });
526
+ });
416
527
  });