Todas as coleções

Sistema de arquivos

Quando você clona uma branch, a CLI grava um app Bubble normalizado e 'fragmentado'. Este artigo é a referência para o que reside em cada lugar, que forma assume e o que você não deve tocar.

O sistema de arquivos não é um dump JSON fiel do seu app Bubble. É uma projeção projetada para edição: campos voláteis são removidos, campos derivados são recalculados ao aplicar e vários campos são elevados para a estrutura de diretórios.

Layout de nível superior

my-app/                       # app root (one per Bubble app)
  .buildprint/                # internal state — never edit
    app.json                  # { schemaVersion, appId, tokenRef }
    remote.git/               # shared bare repo
  test/                       # branch workspace (git worktree)
    .git                      # gitlink into the shared bare repo
    .gitignore                # ignores /.buildprint/
    app.json                  # top-level Bubble scalars
    settings/
    data_types/
    option_sets/
    styles/
    pages/
    element-definitions/
    mobile-views/
    global-elements/
    api/

A raiz do app (app root) é compartilhada por todas as branches de um app Bubble. Cada branch do Bubble se materializa como uma pasta irmã dentro dela. O nome da pasta da branch deve corresponder à branch do git em checkout — veja Workspace para o ciclo de vida e travas de segurança.

Conteúdo da pasta da branch

Cada diretório dentro de uma pasta de branch mapeia para um conceito do Bubble:

  • app.json — escalares de nível superior para o app (nome, plano, padrões). Campos que pertencem a outros lugares foram removidos.

  • settings/ — configurações do Bubble. settings/client-safe.json contém o corpo principal das configurações; settings/api-connector/<plugin-id>/plugin.json e settings/api-connector/<plugin-id>/calls/<call-id>.json contêm definições do conector de API.

  • data_types/<type-id>/type.json — uma pasta por tipo de dado. A lista de campos está embutida no corpo.

  • option_sets/<set-id>/option-set.json — uma pasta por conjunto de opções. Os valores estão embutidos, ordenados por sort_factor.

  • styles/ — estilos agrupados por tipo de elemento: styles/<ElementType>/<style-id>.json. Tokens de design são elevados para arquivos irmãos: styles/tokens.json, styles/defaults.json, styles/fonts.json.

  • pages/<page-id>/ — uma pasta por página. Arquivo de corpo page.json; elementos sob elements/; workflows sob workflows/ (veja abaixo).

  • element-definitions/<id>/ — elementos reutilizáveis. Mesma estrutura das páginas; arquivo de corpo é reusable.json.

  • mobile-views/<id>/ — telas móveis. Mesma estrutura das páginas.

  • global-elements/<id>/ — elementos globais (superfícies de todo o app). Mesma estrutura das páginas.

  • api/ — workflows de backend, opcionalmente agrupados em pastas de workflow do Bubble (veja Pastas de workflow abaixo).

Páginas, reutilizáveis, visualizações móveis, elementos globais

Estes quatro diretórios usam a mesma estrutura. O arquivo de corpo na raiz da pasta contém as propriedades da entidade; elementos filhos e workflows vivem em subdiretórios irmãos.

pages/<page-id>/
  page.json                   # page properties + children manifest
  elements/
    <element-key>/
      element.json            # element properties, type, style, states
      <child-element-key>/    # nested folder per child element
        element.json
        <grandchild-key>/
          element.json
  workflows/
    <workflow-id>/
      workflow.json           # trigger and metadata
      actions/
        0.json                # integer filenames = insertion order
        1.json
        2.json

Pastas de elementos

  • O nome da pasta é a chave de mapa (map key) do elemento (a chave que ele possui dentro do objeto elements do pai), não o campo id dentro do corpo. Estes podem diferir; referências em outras partes do app usam a chave de mapa.

  • Elementos filhos vivem como subpastas de seu pai. A árvore no disco reflete a árvore de contenção no Bubble.

Workflows e ações

  • Cada workflow ganha sua própria pasta contendo workflow.json (gatilho, metadados) e uma pasta actions/ com um arquivo por ação.

  • Os nomes dos arquivos de ação são inteiros em formato de string0.json, 1.json, 2.json. Eles codificam a ordem de execução.

  • Intervalos na sequência são válidos e preservados literalmente (algumas estruturas do Bubble usam intencionalmente chaves inteiras esparsas).

Pastas de workflow

O Bubble permite agrupar workflows em pastas nomeadas. No disco, uma pasta de workflow é um diretório com um config.json ao lado dos workflows que ele contém:

api/
  <folder-id>/
    config.json               # { "name": "Billing" }
    <wf-id>/
      workflow.json
      actions/0.json
  <wf-id>/                    # workflow with no parent folder
    workflow.json
    actions/0.json
  • Os metadados da pasta vivem em config.json. Para renomear uma pasta, edite esse arquivo.

  • Para mover um workflow entre pastas, mova o próprio diretório do workflow.

  • Pastas de workflow sob api/ não podem ser aninhadas — apenas um nível. A regra de verificação api-folder-flat impõe isso.

  • Os corpos dos workflows não carregam um campo wf_folder — a pasta pai é derivada da árvore de diretórios. Adicionar esse campo ao workflow.json não faz nada; reorganize as pastas em vez disso.

A mesma estrutura se aplica em pages/<page-id>/workflows/, element-definitions/<id>/workflows/, mobile-views/<id>/workflows/ e global-elements/<id>/workflows/.

Estilos

Os estilos são divididos por tipo de elemento. Cada subdiretório contém um arquivo JSON por estilo:

styles/
  Button/
    primary.json
    secondary.json
  Text/
    heading.json
    body.json
  tokens.json                 # color_tokens, color_tokens_user
  defaults.json               # default_styles, default_icon_set
  fonts.json                  # font_tokens, font_tokens_user, fonts

Os três arquivos elevados no topo de styles/ foram movidos para fora de settings/ para que os tokens de design residam em um único lugar previsível.

Forma canônica de JSON

Cada arquivo JSON que a CLI grava passa por um único formatador canônico. As regras:

  • UTF-8 com finais de linha LF e uma nova linha no final.

  • Indentação de dois espaços. Um valor por linha em objetos; um elemento por linha em arrays não triviais.

  • Sem tabulações, sem caracteres CR, sem espaços em branco no final.

  • Chaves de objeto que não são inteiras são classificadas alfabeticamente. Mapas com chaves inteiras (actions de workflow, states de elemento, TextExpression.entries) preservam a ordem de inserção.

A saída idêntica em bytes para a mesma entrada mantém os diffs de sync limpos e conflitos de mesclagem mínimos. Se você editar um arquivo manualmente e a formatação mudar, a regra de verificação canonical-form sinalizará — execute novamente o comando que produziu o arquivo ou passe-o por um formatador JSON.

IDs e nomes de arquivos

  • Buildprint gera seus próprios IDs.

  • Novos IDs vêm de buildprint utils generate-ids <n> (um por linha, ordem lexicográfica, entre 1 e 100 por vez). Chame isso antes de criar entidades manualmente.

  • Apps existentes podem conter dois formatos de ID do Bubble (short-uid e timestamp-random). Os leitores lidam com ambos; os gravadores sempre emitem a forma canônica do Buildprint.

  • Chaves com o prefixo _bp_ ou bp- prefix são reservadas para a CLI. Ocasionalmente, você verá arquivos de marcação internos e sentinelas (por exemplo, bp_dir.json ou uma pasta bp_no_type/ sob estilos) — trate-os como internos e não os edite manualmente.

Manifestos de filhos

Todo pai que contém elementos mantém um manifesto de seus filhos em seu arquivo de corpo:

{
  "children": ["hdr_0001", "content_0002", "footer_0003"]
}

A invariante: o conjunto de subpastas filhas sob elements/ deve corresponder ao conjunto de chaves listadas em children, e a ordem em children é a ordem de exibição canônica. Entradas pendentes ou pastas órfãs são erros sinalizados pela regra de verificação children-manifest.

A ordem de renderização é separada: properties.order (ordem flex) e properties.zindex (empilhamento) descrevem preocupações de CSS e residem em elementos individuais quando definidos. A CLI não inventa valores para estes — apenas o Bubble faz isso.

O que não editar

  • .buildprint/ — o repositório git bare compartilhado e a configuração do app. Gitignorado no worktree. Não mexa nisso.

  • Internos do .git/ — trate o worktree como qualquer outro checkout do git.

  • Campos elevados - qualquer coisa que tenha sido movida de um arquivo de corpo para a estrutura de diretórios. Escrever properties.wf_folder de volta no workflow.json, ou type de volta em um corpo de estilo, não tem efeito e pode disparar erros de verificação.

  • Campos voláteis - se você vir um campo perdido como last_change, creation_date, _id, screenshot ou uid_counter reaparecer após uma edição manual, remova-o. A CLI os remove na fragmentação e não os regenerará.

  • Arquivos de marcação internos — sentinelas sob pastas ou arquivos __bp_*. Eles existem para que a CLI possa lidar com casos especiais (colisões sem distinção entre maiúsculas e minúsculas, estilos sem tipo). Não os crie nem os renomeie.

Modelo Git

A pasta da branch é um git worktree real apoiado pelo repositório bare em <app-root>/.buildprint/remote.git/. Você pode usar git status, git diff, git log, git add e git commit normalmente.

Vale a pena conhecer quatro refs:

  • refs/heads/<branch> — seus commits locais. É aqui que você edita.

  • refs/remotes/buildprint/<branch> — o último commit local que foi aplicado com sucesso ao Bubble. Use git log buildprint/<branch>..HEAD para ver o que está localmente à frente.

  • refs/bubble/<branch> — o snapshot mais recente do Bubble (reside no repositório bare). buildprint sync atualiza esta ref e a mescla em sua branch.

  • refs/published/<branch> — ref de controle interno dentro do repositório bare, espelhada para buildprint/<branch> pelo git fetch.

Isso foi útil?