Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="Typesync CLI is released under the MIT license." /></a>
</p>

Typesync is an open-source schema management tool that simplifies managing [Firestore](https://cloud.google.com/firestore) databases. Typesync allows you to maintain a single source of truth for your Firestore architecture in a special _schema_. With this schema in place, you can seamlessly auto-generate type definitions for multiple platforms like TypeScript, Swift, Python, and more using the CLI tool.
Typesync is an open-source schema management tool for [Firestore](https://cloud.google.com/firestore) databases. You maintain a single source of truth for your Firestore architecture in a _schema_, then use the CLI to generate code and validate data from that schema.

Typesync keeps your database and application code consistent and up-to-date at all times. In addition to type definitions, it lets you generate other useful things like Security Rules, Mermaid graphs visualizing your database architecture and documentation for your data models.
Typesync helps keep your database, generated application code, and validation checks aligned as your schema changes.

# How Typesync Helps You

- Generate Firestore models for TypeScript, Swift, and Python from one schema.
- Validate live Firestore documents with `typesync validate-data`.
- Generate Security Rules validators from the same model definitions.
- Visualize your Firestore architecture with Mermaid graphs.
- Carry schema documentation into generated model output.

[**View the full documentation (docs) ▸**](https://docs.typesync.org)

Expand All @@ -42,6 +50,7 @@ Explore our comprehensive [documentation](https://docs.typesync.org) for detaile
- [Quickstart](https://docs.typesync.org/quickstart): Get up and running with Typesync quickly.
- [Upgrading](https://docs.typesync.org/upgrading): Guidelines on upgrading to the latest version of the CLI.
- [Types](https://docs.typesync.org/schema/types): Details on the types supported by Typesync’s type system.
- [validate-data](https://docs.typesync.org/cli/validate-data): Validate Firestore documents against your schema.

# License

Expand Down
29 changes: 12 additions & 17 deletions docs/cli/generate-graph.mdx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
title: "generate-graph"
icon: "rectangle-terminal"
title: 'generate-graph'
icon: 'rectangle-terminal'
---

import DefinitionOption from "/snippets/cli-option-definition.mdx";
import OutFileOption from "/snippets/cli-option-out-file.mdx";
import IndentationOption from "/snippets/cli-option-indentation.mdx";
import DebugOption from "/snippets/cli-option-debug.mdx";
import ExampleDefinitionGraph from "/snippets/example-definition-graph.mdx";
import ExampleGenerationGraphBefore from "/snippets/example-generation-graph-before.mdx";
import ExampleGenerationGraph from "/snippets/example-generation-graph.mdx";
import DebugOption from '/snippets/cli-option-debug.mdx';
import DefinitionOption from '/snippets/cli-option-definition.mdx';
import IndentationOption from '/snippets/cli-option-indentation.mdx';
import OutFileOption from '/snippets/cli-option-out-file.mdx';
import ExampleDefinitionGraph from '/snippets/example-definition-graph.mdx';
import ExampleGenerationGraphBefore from '/snippets/example-generation-graph-before.mdx';
import ExampleGenerationGraph from '/snippets/example-generation-graph.mdx';

Generates a [Mermaid](https://mermaid.js.org) graph for the specified schema and injects it into the specified Markdown file. The generated graph is the visual representation of the database architecture inferred from your schema. You can specify where the graph is inserted within the file using the `--startMarker` and `--endMarker` options. For a detailed guide, see the full [example](#example) below.

Expand Down Expand Up @@ -39,14 +39,9 @@ typesync generate-graph --definition <filePathOrPattern> --outFile <filePath> --
the `<!--` (see [example](#example)).
</ParamField>

<ParamField
type='"vertical" | "horizontal"'
path="orientation"
default="horizontal"
>
The orientation of the generated Mermaid graph. Can be either `"vertical"` or
`"horizontal"` which correspond to the `"TB"` and `"LR"` Mermaid options,
respectively.
<ParamField type='"vertical" | "horizontal"' path="orientation" default="horizontal">
The orientation of the generated Mermaid graph. Can be either `"vertical"` or `"horizontal"` which correspond to the
`"TB"` and `"LR"` Mermaid options, respectively.
</ParamField>

<DebugOption />
Expand Down
19 changes: 9 additions & 10 deletions docs/cli/generate-py.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: "generate-py"
icon: "rectangle-terminal"
title: 'generate-py'
icon: 'rectangle-terminal'
---

import DefinitionOption from "/snippets/cli-option-definition.mdx";
import OutFileOption from "/snippets/cli-option-out-file.mdx";
import TargetOption from "/snippets/cli-option-target.mdx";
import IndentationOption from "/snippets/cli-option-indentation.mdx";
import DebugOption from "/snippets/cli-option-debug.mdx";
import DebugOption from '/snippets/cli-option-debug.mdx';
import DefinitionOption from '/snippets/cli-option-definition.mdx';
import IndentationOption from '/snippets/cli-option-indentation.mdx';
import OutFileOption from '/snippets/cli-option-out-file.mdx';
import TargetOption from '/snippets/cli-option-target.mdx';

Generates Python/Pydantic type definitions for the specified schema and writes them to the specified file. Typesync first “flattens” your schema, creating new aliases for inline types defined within. It then generates the classes, enums, aliases, etc. including serializers and deserializers.

Expand All @@ -34,9 +34,8 @@ Example values:
</ParamField>

<ParamField type="string" path="undefinedSentinelName" default="UNDEFINED">
The name of the sentinel value used to indicate that a field should be missing
from a given object. This is generated as a variable alongside your model
definitions.
The name of the sentinel value used to indicate that a field should be missing from a given object. This is generated
as a variable alongside your model definitions.
</ParamField>

<IndentationOption />
Expand Down
90 changes: 44 additions & 46 deletions docs/cli/generate-rules.mdx
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
---
title: "generate-rules"
icon: "rectangle-terminal"
title: 'generate-rules'
icon: 'rectangle-terminal'
---

import DefinitionOption from "/snippets/cli-option-definition.mdx";
import OutFileOption from "/snippets/cli-option-out-file.mdx";
import IndentationOption from "/snippets/cli-option-indentation.mdx";
import DebugOption from "/snippets/cli-option-debug.mdx";
import ExampleDefinition from "/snippets/example-definition.mdx";
import ExampleGenerationRulesBefore from "/snippets/example-generation-rules-before.mdx";
import ExampleGenerationRules from "/snippets/example-generation-rules.mdx";
import DebugOption from '/snippets/cli-option-debug.mdx';
import DefinitionOption from '/snippets/cli-option-definition.mdx';
import IndentationOption from '/snippets/cli-option-indentation.mdx';
import OutFileOption from '/snippets/cli-option-out-file.mdx';
import ExampleDefinition from '/snippets/example-definition.mdx';
import ExampleGenerationRulesBefore from '/snippets/example-generation-rules-before.mdx';
import ExampleGenerationRules from '/snippets/example-generation-rules.mdx';

Generates validator functions for Firestore Security Rules (version 2) and injects them into the specified file. These validators ensure that request data adheres to defined model interfaces and detect any modifications to read-only fields during write operations.

Since Security Rules are centralized in a single file (typically `firestore.rules`), and developers often implement custom rules alongside type validations, Typesync inserts only the necessary validator functions, without overriding your custom rules. You can specify where these validators are added within the file using the `--startMarker` and `--endMarker` options. For a detailed guide, see the full [example](#example) below.

<Info>
Note that these validators must adhere to the intrinsic limitations of
Security Rules. For example, while it's feasible to verify if `x` is a list
with the `x is list` predicate, determining whether it's a list of strings is
not possible since loop constructs are not available in Security Rules.
Typesync will provide the most stringent validation possible within these
constraints.
Note that these validators must adhere to the intrinsic limitations of Security Rules. For example, while it's
feasible to verify if `x` is a list with the `x is list` predicate, determining whether it's a list of strings is not
possible since loop constructs are not available in Security Rules. Typesync will provide the most stringent
validation possible within these constraints.
</Info>

## Usage
Expand All @@ -44,10 +42,9 @@ typesync generate-rules --definition <filePathOrPattern> --outFile <filePath> --
</ParamField>

<ParamField type="string" path="endMarker" default="typesync-end">
A marker that indicates the line before which the generated code should be
inserted. Make sure to use a string that is unique within the file. The line
containing the marker must be commented i.e. the marker needs to appear after
the `//` (see [example](#example)).
A marker that indicates the line before which the generated code should be inserted. Make sure to use a string that is
unique within the file. The line containing the marker must be commented i.e. the marker needs to appear after the
`//` (see [example](#example)).
</ParamField>

<ParamField
Expand All @@ -68,40 +65,42 @@ typesync generate-rules --definition <filePathOrPattern> --outFile <filePath> --
The name of the parameter taken by each type validator.
</ParamField>

{/* <ParamField
type="string"
path="readonlyFieldValidatorNamePattern"
default="isReadonlyFieldAffectedFor{modelName}"
>
The pattern that specifies how the generated readonly field validators are named. The pattern must be a string that contains the `"{modelName}"` substring (this is a literal value).
Example values:
{/\* <ParamField
type="string"
path="readonlyFieldValidatorNamePattern"
default="isReadonlyFieldAffectedFor{modelName}"

> The pattern that specifies how the generated readonly field validators are named. The pattern must be a string that contains the `"{modelName}"` substring (this is a literal value).

Example values:

- `"isReadonlyFieldAffectedFor{modelName}"` -> produces validators like `isReadonlyFieldAffectedForUser`, `isReadonlyFieldAffectedForProject`, `isReadonlyFieldAffectedForAccount` etc.
- `"affectsReadonlyFieldFor{modelName}"` -> produces validators like `affectsReadonlyFieldForUser`, `affectsReadonlyFieldForProject`, `affectsReadonlyFieldForAccount` etc.

</ParamField> */}

{/* <ParamField
type="string"
path="readonlyFieldValidatorPrevDataParamName"
default="prevData"
>
The name of the first parameter taken by each readonly field validator
representing previous data. This parameter used when computing the diff
between next data and previous data to determine whether a readonly field has
been affected by a write.
{/\* <ParamField
type="string"
path="readonlyFieldValidatorPrevDataParamName"
default="prevData"

> The name of the first parameter taken by each readonly field validator
> representing previous data. This parameter used when computing the diff
> between next data and previous data to determine whether a readonly field has
> been affected by a write.

</ParamField> */}

{/* <ParamField
type="string"
path="readonlyFieldValidatorNextDataParamName"
default="nextData"
>
The name of the second parameter taken by each readonly field validator
representing next data. This parameter used when computing the diff between
next data and previous data to determine whether a readonly field has been
affected by a write.
{/\* <ParamField
type="string"
path="readonlyFieldValidatorNextDataParamName"
default="nextData"

> The name of the second parameter taken by each readonly field validator
> representing next data. This parameter used when computing the diff between
> next data and previous data to determine whether a readonly field has been
> affected by a write.

</ParamField> */}

<IndentationOption />
Expand All @@ -116,7 +115,6 @@ Suppose you have a schema definition file named `models.yml` and a Security Rule
<ExampleGenerationRulesBefore />
</CodeGroup>


{/* TODO: Update */}

To generate validators for the defined models and inject them between the `typesync-start` and `typesync-end` markers in the `firestore.rules` file, you can run the following command:
Expand Down
77 changes: 69 additions & 8 deletions docs/cli/generate-swift.mdx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
---
title: "generate-swift"
icon: "rectangle-terminal"
title: 'generate-swift'
icon: 'rectangle-terminal'
---

import DefinitionOption from "/snippets/cli-option-definition.mdx";
import OutFileOption from "/snippets/cli-option-out-file.mdx";
import TargetOption from "/snippets/cli-option-target.mdx";
import IndentationOption from "/snippets/cli-option-indentation.mdx";
import DebugOption from "/snippets/cli-option-debug.mdx";
import DebugOption from '/snippets/cli-option-debug.mdx';
import DefinitionOption from '/snippets/cli-option-definition.mdx';
import IndentationOption from '/snippets/cli-option-indentation.mdx';
import OutFileOption from '/snippets/cli-option-out-file.mdx';
import TargetOption from '/snippets/cli-option-target.mdx';

Generates Swift type definitions for the specified schema and writes them to the specified file. Typesync first "flattens" your schema, creating new aliases for inline types defined within. It then generates the primary and auxiliary structs, enums, aliases, etc. including encoders and decoders.
Generates Swift type definitions for the specified schema and writes them to the specified file. Typesync first "flattens" your schema, creating new aliases for inline types defined within. It then generates the primary and auxiliary structs, enums, aliases, encoders, and decoders.

For document models, generated Swift structs include an `@DocumentID var id: String?` property by default. The Firebase Apple SDK fills this value from the document path when decoding and excludes it from the encoded document body when writing.

## Usage

Expand All @@ -28,3 +30,62 @@ typesync generate-swift --definition <filePathOrPattern> --target <targetEnviron
## Targets

- `firebase@10`: For Swift projects that rely on the [Firebase Apple SDK (v10)](https://github.com/firebase/firebase-ios-sdk).

## Document IDs

Document model structs import `FirebaseFirestore` and include an `@DocumentID`
property:

```swift
import FirebaseFirestore

struct User: Codable {
@DocumentID var id: String?
var username: String
}
```

If a document body already has a Firestore field named `id`, rename the generated
document ID property on that document model:

```yaml
User:
model: document
path: users/{userId}
swift:
documentIdProperty:
name: documentId
type:
type: object
fields:
id:
type: string
username:
type: string
```

This produces `@DocumentID var documentId: String?` while keeping the body field
named `id`.

## Swift field names

Use `swift.name` on a field when the generated Swift property name should differ
from the Firestore field name. Typesync keeps encoding and decoding aligned with
the original Firestore key through `CodingKeys`.

```yaml
User:
model: document
path: users/{userId}
type:
type: object
fields:
class:
type: string
swift:
name: userClass
```

Typesync fails generation if two fields resolve to the same Swift property name,
or if a body field conflicts with the generated `@DocumentID` property. Rename
one of the properties with `swift.name` or `swift.documentIdProperty.name`.
14 changes: 7 additions & 7 deletions docs/cli/generate-ts.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: "generate-ts"
icon: "rectangle-terminal"
title: 'generate-ts'
icon: 'rectangle-terminal'
---

import DefinitionOption from "/snippets/cli-option-definition.mdx";
import OutFileOption from "/snippets/cli-option-out-file.mdx";
import TargetOption from "/snippets/cli-option-target.mdx";
import IndentationOption from "/snippets/cli-option-indentation.mdx";
import DebugOption from "/snippets/cli-option-debug.mdx";
import DebugOption from '/snippets/cli-option-debug.mdx';
import DefinitionOption from '/snippets/cli-option-definition.mdx';
import IndentationOption from '/snippets/cli-option-indentation.mdx';
import OutFileOption from '/snippets/cli-option-out-file.mdx';
import TargetOption from '/snippets/cli-option-target.mdx';

Generates TypeScript type definitions for the specified schema and writes them to the specified file.

Expand Down
Loading
Loading