diff --git a/README.md b/README.md index fefa919..e822e31 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,17 @@ Typesync CLI is released under the MIT license.

-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) @@ -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 diff --git a/docs/cli/generate-graph.mdx b/docs/cli/generate-graph.mdx index 5e2592e..53a6feb 100644 --- a/docs/cli/generate-graph.mdx +++ b/docs/cli/generate-graph.mdx @@ -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. @@ -39,14 +39,9 @@ typesync generate-graph --definition --outFile -- the ` + ```mermaid graph LR node1["authors"] --> node2["{authorId}"] @@ -19,3 +20,4 @@ graph LR This graph is automatically generated. ``` +```` diff --git a/docs/snippets/example-generation-py.mdx b/docs/snippets/example-generation-py.mdx index 39a4de7..a43e1a4 100644 --- a/docs/snippets/example-generation-py.mdx +++ b/docs/snippets/example-generation-py.mdx @@ -30,4 +30,4 @@ class User(TypesyncModel): if name == "website_url" and value is None: raise ValueError("'website_url' field cannot be set to None") super().__setattr__(name, value) -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-generation-rules-before.mdx b/docs/snippets/example-generation-rules-before.mdx index 4c8b178..84459cf 100644 --- a/docs/snippets/example-generation-rules-before.mdx +++ b/docs/snippets/example-generation-rules-before.mdx @@ -12,4 +12,4 @@ service cloud.firestore { } } } -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-generation-rules.mdx b/docs/snippets/example-generation-rules.mdx index 0de6107..47c0e51 100644 --- a/docs/snippets/example-generation-rules.mdx +++ b/docs/snippets/example-generation-rules.mdx @@ -26,4 +26,4 @@ service cloud.firestore { } } } -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-generation-swift.mdx b/docs/snippets/example-generation-swift.mdx index 3d84cce..8aae73d 100644 --- a/docs/snippets/example-generation-swift.mdx +++ b/docs/snippets/example-generation-swift.mdx @@ -1,5 +1,6 @@ ```swift models.swift import Foundation +import FirebaseFirestore /// Represents a user's role within a project. enum UserRole: String, Codable { @@ -10,6 +11,7 @@ enum UserRole: String, Codable { /// Represents a user that belongs to a project. struct User: Codable { + @DocumentID var id: String? /// A string that uniquely identifies the user within a project. var username: String var role: UserRole @@ -23,4 +25,4 @@ struct User: Codable { case createdAt = "created_at" } } -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-generation-ts-backend.mdx b/docs/snippets/example-generation-ts-backend.mdx index 66454e6..08164f6 100644 --- a/docs/snippets/example-generation-ts-backend.mdx +++ b/docs/snippets/example-generation-ts-backend.mdx @@ -12,4 +12,4 @@ export interface User { website_url?: string; created_at: firestore.Timestamp; } -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-generation-ts-frontend.mdx b/docs/snippets/example-generation-ts-frontend.mdx index 7026db6..2a75137 100644 --- a/docs/snippets/example-generation-ts-frontend.mdx +++ b/docs/snippets/example-generation-ts-frontend.mdx @@ -12,4 +12,4 @@ export interface User { website_url?: string; created_at: firestore.Timestamp; } -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-usage-py.mdx b/docs/snippets/example-usage-py.mdx index 15a3c28..453beb9 100644 --- a/docs/snippets/example-usage-py.mdx +++ b/docs/snippets/example-usage-py.mdx @@ -7,4 +7,4 @@ db = firestore.client() doc_ref = db.collection('users').document('adam') snapshot = doc_ref.get() user = User.model_validate(snapshot.to_dict()) # is a User instance -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-usage-swift.mdx b/docs/snippets/example-usage-swift.mdx index 333263e..bb80183 100644 --- a/docs/snippets/example-usage-swift.mdx +++ b/docs/snippets/example-usage-swift.mdx @@ -5,7 +5,7 @@ let db = Firestore.firestore() db.document("users/adam").getDocument { snapshot, err in if let user = try! snapshot?.data(as: User.self) { - print(user) // is a User instance + print(user.id) // "adam" } } -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-usage-ts-backend.mdx b/docs/snippets/example-usage-ts-backend.mdx index 1784c3b..dbe535a 100644 --- a/docs/snippets/example-usage-ts-backend.mdx +++ b/docs/snippets/example-usage-ts-backend.mdx @@ -1,10 +1,9 @@ ```ts app.ts (backend) -import { firestore } from "firebase-admin"; -import type { User } from "./models"; +import { firestore } from 'firebase-admin'; -const usersColRef = firestore().collection( - "users" -) as firestore.CollectionReference; -const userSnap = await usersColRef.doc("adam").get(); +import type { User } from './models'; + +const usersColRef = firestore().collection('users') as firestore.CollectionReference; +const userSnap = await usersColRef.doc('adam').get(); const user = userSnap.data(); // is a User object -``` \ No newline at end of file +``` diff --git a/docs/snippets/example-usage-ts-frontend.mdx b/docs/snippets/example-usage-ts-frontend.mdx index d46047e..76d51ac 100644 --- a/docs/snippets/example-usage-ts-frontend.mdx +++ b/docs/snippets/example-usage-ts-frontend.mdx @@ -1,16 +1,11 @@ ```ts app.ts (frontend) -import { - getFirestore, - doc, - getDoc, - collection, - type CollectionReference, -} from "firebase/firestore"; -import type { User } from "./models"; +import { type CollectionReference, collection, doc, getDoc, getFirestore } from 'firebase/firestore'; + +import type { User } from './models'; const firestore = getFirestore(); -const usersColRef = collection(firestore, "users") as CollectionReference; -const userDocRef = doc(usersColRef, "adam"); +const usersColRef = collection(firestore, 'users') as CollectionReference; +const userDocRef = doc(usersColRef, 'adam'); const userSnap = await getDoc(userDocRef); const user = userSnap.data(); // is a User object -``` \ No newline at end of file +``` diff --git a/docs/upgrading.mdx b/docs/upgrading.mdx index 441724a..0915ca5 100644 --- a/docs/upgrading.mdx +++ b/docs/upgrading.mdx @@ -1,15 +1,15 @@ --- -title: "Upgrading" +title: 'Upgrading' --- -import ExampleDefinition from "/snippets/example-definition.mdx"; -import ExampleGenerationTSBackend from "/snippets/example-generation-ts-backend.mdx"; +import ExampleDefinition from '/snippets/example-definition.mdx'; +import ExampleGenerationTSBackend from '/snippets/example-generation-ts-backend.mdx'; Upgrading your Typesync version is an important step to ensure you benefit from the latest features, bug fixes, and improvements. - Until we reach our v1 release, breaking changes may occur between minor - versions (e.g. when upgrading from v0.6 to v0.7). + Until we reach our v1 release, breaking changes may occur between minor versions (e.g. when upgrading from v0.6 to + v0.7). Here's how to manage upgrades smoothly: