Vue

Provider, composables y el botón hospedado en una aplicación de Vue.

bash
npm install @andco/sdk @andco/sdk-vue

Montar el provider

src/App.vuevue
<script setup lang="ts">
import { AndcoProvider } from "@andco/sdk-vue";
import Account from "./Account.vue";

const clientOptions = {
  clientId: import.meta.env.VITE_ANDCO_CLIENT_ID,
  redirectTo: new URL("/", window.location.origin).href,
  initialScopes: ["openid", "email", "profile"],
};
</script>

<template>
  <AndcoProvider :client-options="clientOptions">
    <Account />
  </AndcoProvider>
</template>

Es un componente y no un plugin global a propósito: un plugin construiría el mismo contexto con el mismo código, pero haría imposible tener dos instancias y dejaría estado global vivo después de desmontar.

Leer la sesión

src/Account.vuevue
<script setup lang="ts">
import { useAndcoSession } from "@andco/sdk-vue";

const session = useAndcoSession();
</script>

<template>
  <p v-if="session === undefined">Cargando…</p>
  <p v-else-if="session">{{ session.user.email }}</p>
  <p v-else>Sin sesión</p>
</template>

useAndcoSession() devuelve un Ref<AndcoSession | null | undefined> con los tres estados y cambia en cada republicación, rotaciones incluidas. useAndcoUser() devuelve un ComputedRef<AndcoUser | null | undefined> — no la persona directamente — que cambia solo cuando cambia la persona.

El botón

vue
<script setup lang="ts">
import { AndcoButton } from "@andco/sdk-vue";
</script>

<template>
  <AndcoButton
    :authorization="{ scopes: ['openid', 'email', 'profile'] }"
    @complete="reload"
    @error="(error) => (message = error.message)"
  />
</template>

Autenticar y llamar a la API

useAndco() devuelve un objeto de getters, no un ref: andco.rest y andco.auth se leen en vivo, sin .value.

vue
<script setup lang="ts">
import { useAndco } from "@andco/sdk-vue";
import { onMounted, ref } from "vue";

const andco = useAndco();
const accounts = ref<{ id: string; name: string }[]>([]);

async function signIn() {
  await andco.auth.signIn({ scopes: ["openid", "email"] });
}

onMounted(async () => {
  const { data, error } = await andco.rest.http.GET("/accounts");
  if (!error) accounts.value = data.data;
});
</script>

Mostrar un fallo del callback

ts
onMounted(async () => {
  const { error } = await andco.session.ready;
  if (error) message.value = error.message;
});

Con Nuxt

El provider toca window, así que en Nuxt va dentro de <ClientOnly>, o bien le entregas la sesión que el servidor ya resolvió para que el primer cuadro sea real:

vue
<AndcoProvider :client-options="clientOptions" :initial-session="serverSession">
  <NuxtPage />
</AndcoProvider>