Skip to content

Commit

Permalink
doc: add loader visibility docs (#388)
Browse files Browse the repository at this point in the history
  • Loading branch information
IncognitaDev authored Jan 21, 2025
1 parent 56c7c28 commit 43ec33a
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 17 deletions.
73 changes: 73 additions & 0 deletions docs/developing-capabilities/manage-block-access/en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
since: 1.109.0
---

# Managing Loader/Action Access

By default, all loaders and actions in deco.cx are publicly accessible. However, you may need to restrict access to certain loaders/actions that handle sensitive operations or private APIs. This guide explains how to control loader/action visibility.

## Visibility Options

There are two visibility levels available:

- `private`: Can only be invoked server-side through `ctx.invoke`
- `public`: Can be called from both server and client through:
- Runtime `invoke` calls
- Direct path access via `/live/invoke/{path/to/block.ts}`

## Setting Default Visibility

To set the visibility level for a loader/action, export a `defaultVisibility` variable:

```typescript
// Make the loader publicly accessible
export const defaultVisibility = 'public'

// Make the loader private (server-side only)
export const defaultVisibility = 'private'
```

## Overriding Visibility

You can override the default visibility settings in your `fresh.config.ts` file using the `visibilityOverrides` option:

```typescript
import { defineConfig } from "$fresh/server.ts";
import { plugins } from "deco/plugins/deco.ts";
import manifest from "./manifest.gen.ts";

export default defineConfig({
plugins: plugins<typeof manifest>({
manifest,
htmx: true,
visibilityOverrides: {
"site/loaders/minicart.ts": "public",
"vtex/loaders/cart.ts": "private"
},
}),
});
```

## Security Best Practices

When deciding visibility levels:

### Use `private` for

- Accessing private/internal APIs
- Operations involving credentials or secrets
- Processing sensitive user/business data
- Backend integrations requiring authentication

### Use `public` for

- Reading public product data
- Fetching public content
- Client-side data loading
- User-facing operations that don't expose sensitive data

## Related Documentation

- [Fetching Data](/docs/en/developing-guide/fetching-data)
- [Client-side Data Loading](/docs/en/developing-capabilities/islands/fetching-data-client)
- [Core Concepts: Loaders](/docs/en/concepts/loader)
73 changes: 73 additions & 0 deletions docs/developing-capabilities/manage-block-access/pt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
since: 1.109.0
---

# Gerenciando Acesso de Loaders/Actions

Por padrão, todos os loaders e actions no deco.cx são publicamente acessíveis. No entanto, você pode precisar restringir o acesso a certos loaders/actions que lidam com operações sensíveis ou APIs privadas. Este guia explica como controlar a visibilidade de loaders/actions.

## Opções de Visibilidade

Existem dois níveis de visibilidade disponíveis:

- `private`: Pode ser invocado apenas no lado do servidor através do `ctx.invoke`
- `public`: Pode ser chamado tanto do servidor quanto do cliente através de:
- Chamadas `invoke` em tempo de execução
- Acesso direto via path `/live/invoke/{path/to/block.ts}`

## Definindo Visibilidade Padrão

Para definir o nível de visibilidade de um loader/action, exporte uma variável `defaultVisibility`:

```typescript
// Torna o loader publicamente acessível
export const defaultVisibility = 'public'

// Torna o loader privado (apenas lado do servidor)
export const defaultVisibility = 'private'
```

## Sobrescrevendo Visibilidade

Você pode sobrescrever as configurações de visibilidade padrão no seu arquivo `fresh.config.ts` usando a opção `visibilityOverrides`:

```typescript
import { defineConfig } from "$fresh/server.ts";
import { plugins } from "deco/plugins/deco.ts";
import manifest from "./manifest.gen.ts";

export default defineConfig({
plugins: plugins<typeof manifest>({
manifest,
htmx: true,
visibilityOverrides: {
"site/loaders/minicart.ts": "public",
"vtex/loaders/cart.ts": "private"
},
}),
});
```

## Boas Práticas de Segurança

Ao decidir os níveis de visibilidade:

### Use `private` para

- Acessar APIs privadas/internas
- Operações envolvendo credenciais ou segredos
- Processamento de dados sensíveis de usuários/negócios
- Integrações backend que requerem autenticação

### Use `public` para

- Leitura de dados públicos de produtos
- Busca de conteúdo público
- Carregamento de dados no lado do cliente
- Operações voltadas ao usuário que não expõem dados sensíveis

## Documentação Relacionada

- [Buscando Dados](/docs/pt/developing-guide/fetching-data)
- [Carregamento de Dados no Cliente](/docs/pt/developing-capabilities/islands/fetching-data-client)
- [Conceitos Principais: Loaders](/docs/pt/concepts/loader)
45 changes: 28 additions & 17 deletions docs/toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,7 @@ const tableOfContents: TableOfContents = [
pt: "Dados padronizados",
en: "Standard data types",
},
slug:
"developing-capabilities/section-properties/standard-data-types",
slug: "developing-capabilities/section-properties/standard-data-types",
},
{
title: {
Expand Down Expand Up @@ -387,6 +386,7 @@ const tableOfContents: TableOfContents = [
{
title: { pt: "Loaders", en: "Loaders" },
slug: "developing-capabilities/loaders",

},
{
title: { pt: "Islands", en: "Islands" },
Expand Down Expand Up @@ -442,6 +442,13 @@ const tableOfContents: TableOfContents = [
},
slug: "developing-capabilities/modifying-status",
},
{
title: {
pt: "Gerenciando o Acesso de um Bloco",
en: "Managing Block Access",
},
slug: "developing-capabilities/manage-block-access",
},
{
title: {
pt: "E-commerce Analytics",
Expand Down Expand Up @@ -657,7 +664,7 @@ const tableOfContentsBySlug = tableOfContents.reduce((acc, cur) => {

function addEntriesToAccumulator(
acc: Record<string, TopLevelEntry>,
entry: TopLevelEntry,
entry: TopLevelEntry
) {
if (entry.slug) {
acc[entry.slug] = entry;
Expand Down Expand Up @@ -692,37 +699,41 @@ type NextOrPrevious = { title?: string; category?: string; href?: string };

const getNextPreviousForEntry = (
language: SupportedLanguages,
entry: TopLevelEntry,
entry: TopLevelEntry
): NextOrPrevious => ({
href: `/docs/${language}/${entry.slug}`,
title: entry.title?.[language],
});

export const getNextAndPreviousPost = (
language: SupportedLanguages,
slug: string,
slug: string
) => {
const tableOfContentsEntries = tableOfContents.reduce((entries, cur) => {
return entries.concat(
[cur, ...(cur.children || [])].filter(({ slug }) => slug),
[cur, ...(cur.children || [])].filter(({ slug }) => slug)
);
}, [] as TopLevelEntry[]);

const currentIndex = tableOfContentsEntries.findLastIndex(
({ slug: currentSlug }) => currentSlug && slug.includes(currentSlug),
({ slug: currentSlug }) => currentSlug && slug.includes(currentSlug)
);

const previous = currentIndex === 0 ? undefined : getNextPreviousForEntry(
language,
tableOfContentsEntries[currentIndex - 1],
);
const previous =
currentIndex === 0
? undefined
: getNextPreviousForEntry(
language,
tableOfContentsEntries[currentIndex - 1]
);

const next = currentIndex === tableOfContentsEntries.length - 1
? undefined
: getNextPreviousForEntry(
language,
tableOfContentsEntries[currentIndex + 1],
);
const next =
currentIndex === tableOfContentsEntries.length - 1
? undefined
: getNextPreviousForEntry(
language,
tableOfContentsEntries[currentIndex + 1]
);

return {
previous,
Expand Down

0 comments on commit 43ec33a

Please sign in to comment.