@@ -413,4 +413,115 @@ export let provider = Slate.create({
413413 token : 'expired-token-refreshed'
414414 } ) ;
415415 } ) ;
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+ } ) ;
416527} ) ;
0 commit comments