Start with a product or guide

  • Start here

↑↓to moveto openEscto close
CloudBuilder and Guard

Builder and Guard

The Mezair Builder turns a Cell project into inspectable output. Mezair Guard is the trust gateway before local runtime or preview deploy: it checks that Cell server code stays inside the declared contract instead of quietly reaching for provider APIs, process globals, or effects the manifest cannot explain.

Build pipeline

mezair cloud check and mezair cloud build share the same pipeline. check runs it without writing artifacts; build writes output.

Pipeline:

  1. Load mezair.json.
  2. Resolve server and client entrypoints.
  3. Run import and capability policy checks.
  4. Run TypeScript typecheck.
  5. Bundle the server entrypoint.
  6. Import the server bundle and extract the app manifest.
  7. Bundle the client entrypoint.
  8. Write manifest, generated client, generated types, and build metadata.

If any error-level diagnostic appears, the pipeline stops at the failing phase.

Output directories

Text
.mezair/
  dist/
    client/
      index.html
      assets/
        cell.client.js
    server/
      index.mjs
    manifest.json
    build-meta.json
  generated/
    api.d.ts
    client.ts

Diagnostics

Diagnostics include:

  • code
  • severity
  • message
  • file
  • line and column where available
  • hint where available

CLI JSON output keeps these shapes stable enough for scripts and agents.

Example:

JSON
{
  "ok": false,
  "phase": "import-policy",
  "diagnostics": [
    {
      "code": "FORBIDDEN_IMPORT",
      "severity": "error",
      "message": "Import '@aws-sdk/client-s3' is not allowed in Cell server code.",
      "file": "src/cell.server.ts",
      "line": 1,
      "column": 26,
      "hint": "Use declared Mezair capabilities such as ctx.db or ctx.files."
    }
  ],
  "errors": [
    {
      "code": "FORBIDDEN_IMPORT",
      "severity": "error",
      "message": "Import '@aws-sdk/client-s3' is not allowed in Cell server code."
    }
  ]
}

errors is a compatibility alias for older automation. New code should read diagnostics.

Import policy

Cell server code must stay statically inspectable. Current forbidden imports include:

Import Why
fs, node:fs Use ctx.files for Cell-owned file storage.
child_process, node:child_process Move background work into declared jobs.
@aws-sdk/* Provider access belongs in the AWS adapter.
aws-cdk-lib Cell code must not author provider infrastructure directly.
sst, sst/* Provider tooling belongs inside deployment adapters.
cdktf, @cdktf/* Terraform/CDKTF authoring belongs inside deployment adapters.
pulumi, @pulumi/* Provider infrastructure belongs inside deployment adapters.

Dynamic import is also forbidden in Cell server code.

Capability checks

Guard can detect some undeclared effects:

  • global fetch requires capabilities.outboundFetch
  • literal fetch("https://...") hosts must match capabilities.outboundFetch.allow
  • fetch targets must be static absolute http or https URL literals so Guard can check the host
  • scheduled jobs require capabilities.scheduledJobs
  • ctx.db requires capabilities.database
  • ctx.files requires capabilities.files
  • ctx.events requires capabilities.events
  • ctx.jobs requires capabilities.jobs
  • ctx.workflows and workflow(...) require capabilities.workflows
  • service(...) requires capabilities.services
  • direct process.env is rejected; use ctx.env.get() or ctx.env.require()
  • handler use of capabilities should match declared Cell capabilities where alpha can inspect it

Current direct environment checks catch straightforward static forms such as process.env and process["env"]. Guard is not a perfect JavaScript sandbox; it is a policy check for normal Cell code and a clear signal to reviewers.

This is not a perfect sandbox. It is a practical alpha control that narrows the contract and catches common ways app code escapes into provider-specific behavior.

Outbound fetch policy

Declare outbound fetch explicitly:

TypeScript
export default app({
  capabilities: {
    outboundFetch: { allow: ["api.example.test"] }
  },
  mutations: {
    sync: mutation({
      handler: async () => {
        await fetch("https://api.example.test/sync");
        return { ok: true };
      }
    })
  }
});

For now, Guard requires literal absolute http or https URL strings so it can check the host. These are rejected:

TypeScript
const target = "https://api.example.test/sync";
await fetch(target);
await fetch("/internal");

Literal URLs let Guard check every destination before deployment. Dynamic network targets cannot be verified this way.

Typecheck

The builder runs TypeScript against the Cell project. This catches app-code mistakes before bundle and manifest extraction.

Use:

Terminal
mezair cloud check --json

before:

Terminal
mezair cloud build --json

Manifest extraction

After the server bundle is built, the builder imports it and verifies that the default export is an app() definition.

If manifest extraction fails, the builder returns SERVER_EXPORT_INVALID or MANIFEST_EXTRACTION_FAILED diagnostics.

Generated client output

The builder emits generated client metadata under .mezair/generated so browser code can call queries and mutations through stable names instead of hand-written string paths.

Read Generated client for client-side usage.

What to trust before deploy

Before preview deploy, inspect:

  • mezair cloud check --json diagnostics
  • mezair cloud build --json output
  • .mezair/dist/manifest.json
  • .mezair/generated/client.ts
  • .mezair/dist/build-meta.json
  • deployment plan and CloudFormation template from mezair cloud deploy --preview --json

If these disagree, fix the discrepancy before deploying.

Practical rule

If a Cell needs a new capability, declare it and add support in the runtime and adapters. Keep provider-specific access in the adapter so the deployment plan can account for it.

Suggest an edit to this page on GitHub