|
| 1 | +--- |
| 2 | +title: "generate-rules" |
| 3 | +icon: "rectangle-terminal" |
| 4 | +--- |
| 5 | + |
| 6 | +import DefinitionOption from "/snippets/cli-option-definition.mdx"; |
| 7 | +import OutFileOption from "/snippets/cli-option-out-file.mdx"; |
| 8 | +import IndentationOption from "/snippets/cli-option-indentation.mdx"; |
| 9 | +import DebugOption from "/snippets/cli-option-debug.mdx"; |
| 10 | +import ExampleDefinition from "/snippets/example-definition.mdx"; |
| 11 | +import ExampleGenerationRulesBefore from "/snippets/example-generation-rules-before.mdx"; |
| 12 | +import ExampleGenerationRules from "/snippets/example-generation-rules.mdx"; |
| 13 | + |
| 14 | +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. |
| 15 | + |
| 16 | +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. |
| 17 | + |
| 18 | +<Info> |
| 19 | + Note that these validators must adhere to the intrinsic limitations of |
| 20 | + Security Rules. For example, while it's feasible to verify if `x` is a list |
| 21 | + with the `x is list` predicate, determining whether it's a list of strings is |
| 22 | + not possible since loop constructs are not available in Security Rules. |
| 23 | + Typesync will provide the most stringent validation possible within these |
| 24 | + constraints. |
| 25 | +</Info> |
| 26 | + |
| 27 | +## Usage |
| 28 | + |
| 29 | +```bash |
| 30 | +typesync generate-rules --definition <filePathOrPattern> --outFile <filePath> --startMarker <startMarker> --endMarker <endMarker> --typeValidatorNamePattern <typeValidatorNamePattern> --typeValidatorParamName <typeValidatorParamName> --indentation <indentation> --debug <debug> |
| 31 | +``` |
| 32 | + |
| 33 | +## Options |
| 34 | + |
| 35 | +<DefinitionOption /> |
| 36 | +<OutFileOption /> |
| 37 | + |
| 38 | +<ParamField type="string" path="startMarker" default="typesync-start"> |
| 39 | + A marker that indicates the line after which the generated code should be |
| 40 | + inserted. Make sure to use a string that is unique within the file. The line |
| 41 | + containing the marker must be commented i.e. the marker needs to appear after |
| 42 | + the `//` (see [example](#example)). |
| 43 | + |
| 44 | + </ParamField> |
| 45 | + |
| 46 | +<ParamField type="string" path="endMarker" default="typesync-end"> |
| 47 | + A marker that indicates the line before which the generated code should be |
| 48 | + inserted. Make sure to use a string that is unique within the file. The line |
| 49 | + containing the marker must be commented i.e. the marker needs to appear after |
| 50 | + the `//` (see [example](#example)). |
| 51 | +</ParamField> |
| 52 | + |
| 53 | +<ParamField |
| 54 | + type="string" |
| 55 | + path="typeValidatorNamePattern" |
| 56 | + default="isValid{modelName}" |
| 57 | +> |
| 58 | + The pattern that specifies how the generated type validators are named. The pattern must be a string that contains the `"{modelName}"` substring (this is a literal value). |
| 59 | + |
| 60 | + Example values: |
| 61 | + |
| 62 | + - `"isValid{modelName}"` -> produces validators like `isValidUser`, `isValidProject`, `isValidAccount` etc. |
| 63 | + - `"is{modelName}"` -> produces validators like `isUser`, `isProject`, `isAccount` etc. |
| 64 | + |
| 65 | + </ParamField> |
| 66 | + |
| 67 | +<ParamField type="string" path="typeValidatorParamName" default="data"> |
| 68 | + The name of the parameter taken by each type validator. |
| 69 | +</ParamField> |
| 70 | + |
| 71 | +{/* <ParamField |
| 72 | + type="string" |
| 73 | + path="readonlyFieldValidatorNamePattern" |
| 74 | + default="isReadonlyFieldAffectedFor{modelName}" |
| 75 | +> |
| 76 | + 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). |
| 77 | + |
| 78 | + Example values: |
| 79 | +
|
| 80 | + - `"isReadonlyFieldAffectedFor{modelName}"` -> produces validators like `isReadonlyFieldAffectedForUser`, `isReadonlyFieldAffectedForProject`, `isReadonlyFieldAffectedForAccount` etc. |
| 81 | + - `"affectsReadonlyFieldFor{modelName}"` -> produces validators like `affectsReadonlyFieldForUser`, `affectsReadonlyFieldForProject`, `affectsReadonlyFieldForAccount` etc. |
| 82 | +
|
| 83 | + </ParamField> */} |
| 84 | + |
| 85 | +{/* <ParamField |
| 86 | + type="string" |
| 87 | + path="readonlyFieldValidatorPrevDataParamName" |
| 88 | + default="prevData" |
| 89 | +> |
| 90 | + The name of the first parameter taken by each readonly field validator |
| 91 | + representing previous data. This parameter used when computing the diff |
| 92 | + between next data and previous data to determine whether a readonly field has |
| 93 | + been affected by a write. |
| 94 | +</ParamField> */} |
| 95 | + |
| 96 | +{/* <ParamField |
| 97 | + type="string" |
| 98 | + path="readonlyFieldValidatorNextDataParamName" |
| 99 | + default="nextData" |
| 100 | +> |
| 101 | + The name of the second parameter taken by each readonly field validator |
| 102 | + representing next data. This parameter used when computing the diff between |
| 103 | + next data and previous data to determine whether a readonly field has been |
| 104 | + affected by a write. |
| 105 | +</ParamField> */} |
| 106 | + |
| 107 | +<IndentationOption /> |
| 108 | +<DebugOption /> |
| 109 | + |
| 110 | +## Example |
| 111 | + |
| 112 | +Suppose you have a schema definition file named `models.yml` and a Security Rules file named `firestore.rules`. |
| 113 | + |
| 114 | +<CodeGroup> |
| 115 | + <ExampleDefinition /> |
| 116 | + <ExampleGenerationRulesBefore /> |
| 117 | +</CodeGroup> |
| 118 | + |
| 119 | + |
| 120 | +{/* TODO: Update */} |
| 121 | + |
| 122 | +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: |
| 123 | + |
| 124 | +```bash |
| 125 | +typesync generate-rules --definition definition.yml --outFile firestore.rules --startMarker typesync-start --endMarker typesync-end |
| 126 | +``` |
| 127 | + |
| 128 | +Typesync will insert the `isValidUserRole()` and `isValidUser()` validators into the file. You can then use these validators as needed in your custom rules. |
| 129 | + |
| 130 | +<ExampleGenerationRules /> |
0 commit comments