@microsoft/rayfin-guide 1.33.2 → 1.34.0-alpha.1148
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/docs/cli/environment-variables.md +6 -0
- package/assets/docs/cli/index.md +1 -1
- package/assets/docs/cli/quickstart.md +1 -1
- package/assets/docs/cli/templates.md +391 -0
- package/assets/docs/data/graphql.md +39 -5
- package/assets/docs/data/validation.md +4 -0
- package/assets/docs/deprecations.md +41 -0
- package/assets/docs/getting-started/project-structure.md +3 -0
- package/assets/docs/index.md +1 -0
- package/assets/docs/known-limitations.md +4 -0
- package/package.json +1 -1
|
@@ -17,6 +17,7 @@ The `rayfin env` command (or the auto-emit built into `rayfin up`) maps them to
|
|
|
17
17
|
| `RAYFIN_PUBLIC_TENANT_ID` | Entra ID tenant for workspace disambiguation. | `rayfin up` |
|
|
18
18
|
| `RAYFIN_PUBLIC_PORTAL_URL` | Fabric Portal base URL (for example, `https://app.fabric.microsoft.com/`). | `rayfin up` |
|
|
19
19
|
| `RAYFIN_PUBLIC_SERVICE_MODE` | `rayfin` (real backend) or `mock` (local testing). | User-set in `rayfin/.env` |
|
|
20
|
+
| `RAYFIN_PUBLIC_FRONTEND_PORT` | Stable per-project frontend dev-server port. Assigned once and reused so the dev server pins a deterministic origin the deployed backend can allow-list. | `rayfin dev` / `rayfin up` |
|
|
20
21
|
|
|
21
22
|
### Framework mapping
|
|
22
23
|
|
|
@@ -31,9 +32,14 @@ The `rayfin env` command (or the auto-emit built into `rayfin up`) maps them to
|
|
|
31
32
|
| `RAYFIN_PUBLIC_TENANT_ID` | `VITE_FABRIC_TENANT_ID` | `NEXT_PUBLIC_FABRIC_TENANT_ID` | `TENANT_ID` |
|
|
32
33
|
| `RAYFIN_PUBLIC_PORTAL_URL` | `VITE_FABRIC_PORTAL_URL` | `NEXT_PUBLIC_FABRIC_PORTAL_URL` | `PORTAL_URL` |
|
|
33
34
|
| `RAYFIN_PUBLIC_SERVICE_MODE` | `VITE_SERVICE_MODE` | `NEXT_PUBLIC_SERVICE_MODE` | `SERVICE_MODE` |
|
|
35
|
+
| `RAYFIN_PUBLIC_FRONTEND_PORT` | `VITE_PORT` | `PORT` | `FRONTEND_PORT` |
|
|
34
36
|
|
|
35
37
|
Custom `RAYFIN_PUBLIC_*` variables you add follow a generic pattern: `RAYFIN_PUBLIC_FOO` becomes `VITE_RAYFIN_FOO` (Vite), `NEXT_PUBLIC_RAYFIN_FOO` (Next.js), or `FOO` (plain).
|
|
36
38
|
|
|
39
|
+
`RAYFIN_PUBLIC_FRONTEND_PORT` maps to the port variable each dev server reads (`VITE_PORT` for Vite, `PORT` for Next.js).
|
|
40
|
+
The sample `vite.config.ts` files pin the server to it with `strictPort`, so if the assigned port is already taken the dev server fails fast instead of silently drifting to another port.
|
|
41
|
+
To run on a different port, set `RAYFIN_PUBLIC_FRONTEND_PORT` in `rayfin/.env` (then re-run `rayfin env`); `rayfin up` registers whatever value is assigned in the deployed redirect allow-list.
|
|
42
|
+
|
|
37
43
|
## Tooling overrides
|
|
38
44
|
|
|
39
45
|
These variables configure CLI and extension behavior.
|
package/assets/docs/cli/index.md
CHANGED
|
@@ -32,7 +32,7 @@ For the full walkthrough, see the [CLI Quickstart](./quickstart.md) or the [Buil
|
|
|
32
32
|
| Command | Description |
|
|
33
33
|
| --- | --- |
|
|
34
34
|
| `npm install --save-dev @microsoft/rayfin-cli` | Install the Rayfin CLI as a dev dependency. Not needed if you scaffolded with `npm create @microsoft/rayfin@latest`. |
|
|
35
|
-
| `npm create @microsoft/rayfin <name>` | Scaffold a new project from a template.
|
|
35
|
+
| `npm create @microsoft/rayfin <name>` | Scaffold a new project from a template. See [Project templates](./templates.md) for choosing a built-in template, scaffolding from a git URL, registering your own template sources, and authoring templates. |
|
|
36
36
|
| `npx rayfin init [directory]` | Initialize a new Rayfin project interactively. Prompts for project name, services (Auth, Data), and auth methods. Creates the `rayfin/` directory with starter files. |
|
|
37
37
|
| `npx rayfin init ai-files install` | Install or refresh the [agent context files](./ai-files.md) (`AGENTS.md`, `.mcp.json`, `.agents/skills/rayfin/SKILL.md`) so coding agents know how to work with your project. Idempotent; auto-runs as part of the scaffold pipeline. |
|
|
38
38
|
| `npx rayfin init ai-files status` | Print the current state of each agent file. Add `--json` for machine-readable output. |
|
|
@@ -20,7 +20,7 @@ The project name is a **positional argument** — not a flag.
|
|
|
20
20
|
Provide a valid directory name like `my-app`, or use `.` to scaffold into the current directory.
|
|
21
21
|
|
|
22
22
|
- The CLI prompts for a template and database dialect interactively.
|
|
23
|
-
-
|
|
23
|
+
- See [Project templates](./templates.md) for skipping the prompt with `-t, --template`, scaffolding from a git URL, or authoring your own templates.
|
|
24
24
|
- Expected result: `✔ Project created`.
|
|
25
25
|
|
|
26
26
|
## Add Rayfin to an existing project
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 3
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Project templates
|
|
6
|
+
|
|
7
|
+
Templates let Rayfin builders scaffold a project from a known starting point: a built-in starter, a local directory, a git repository your team maintains, or a registered third-party source.
|
|
8
|
+
|
|
9
|
+
This page covers using templates and authoring your own.
|
|
10
|
+
|
|
11
|
+
## Where templates come from
|
|
12
|
+
|
|
13
|
+
Every `npm create @microsoft/rayfin@latest` or `npx rayfin init` invocation can pull from any of these sources:
|
|
14
|
+
|
|
15
|
+
- **Built-in templates** ship inside `@microsoft/rayfin-cli` and work offline.
|
|
16
|
+
- **Local template directories** let you test or reuse a template on disk.
|
|
17
|
+
- **External git repositories** are cloned on demand from any HTTPS, SSH, or `git@` URL.
|
|
18
|
+
- **Template registries** are YAML files that name git URLs you (or your team) want to surface alongside the built-ins.
|
|
19
|
+
|
|
20
|
+
External and local template sources are discovered through `rayfin-template.yml` manifests inside the selected source directory.
|
|
21
|
+
Built-in templates are packaged with the CLI and appear in `--list-templates` automatically.
|
|
22
|
+
|
|
23
|
+
## List available templates
|
|
24
|
+
|
|
25
|
+
Use `--list-templates` to see every template the CLI can scaffold from in your current directory:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx rayfin init --list-templates
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The output is a JSON document on stdout, suitable for piping to a script or AI agent.
|
|
32
|
+
The shape is versioned by `schemaVersion`:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"schemaVersion": 1,
|
|
37
|
+
"bundled": [
|
|
38
|
+
{
|
|
39
|
+
"name": "todoapp",
|
|
40
|
+
"displayName": "Basic Todo App",
|
|
41
|
+
"description": "End-to-end Fabric-authenticated todo CRUD with a Rayfin data model and per-user row-level security",
|
|
42
|
+
"source": "built-in"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"registry": [
|
|
46
|
+
{
|
|
47
|
+
"name": "team-templates",
|
|
48
|
+
"displayName": "Team Templates",
|
|
49
|
+
"description": "Our team's starter collection",
|
|
50
|
+
"url": "https://github.com/example-org/rayfin-templates.git",
|
|
51
|
+
"ref": "v1.2.0",
|
|
52
|
+
"path": "catalogs/official",
|
|
53
|
+
"source": "C:\\Users\\you\\.rayfin\\template-registries.yml"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If any registry file fails to load or contains conflicts, a `warnings` array is appended to the output.
|
|
60
|
+
The list does **not** include arbitrary git URLs — it shows only built-ins plus what is registered through `template-registries.yml` files.
|
|
61
|
+
Template names in examples can change over time; run `--list-templates` for the current copy/paste-ready names.
|
|
62
|
+
|
|
63
|
+
## Scaffold from a built-in template
|
|
64
|
+
|
|
65
|
+
The default flow prompts you to pick a template interactively:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm create @microsoft/rayfin@latest my-app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
To skip the prompt, pass `-t`/`--template <name>` using one of the names from `--list-templates`:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm create @microsoft/rayfin@latest my-app -- --template todoapp
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Scaffold from an external git repository
|
|
78
|
+
|
|
79
|
+
Pass any git URL to `-t`/`--template`:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx rayfin init my-app -t https://github.com/example-org/my-template.git
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Supported URL formats are HTTPS, SSH, `git@host:org/repo.git`, and `file://`.
|
|
86
|
+
The CLI does a shallow clone into a temp directory, scaffolds, then deletes the clone.
|
|
87
|
+
|
|
88
|
+
To pin to a specific branch, tag, or commit, append `#<ref>` to the URL:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx rayfin init my-app -t https://github.com/example-org/my-template.git#v1.2.0
|
|
92
|
+
npx rayfin init my-app -t https://github.com/example-org/my-template.git#main
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use a branch name, tag name, or **full** 40-character commit SHA.
|
|
96
|
+
Abbreviated SHAs are rejected because `git clone --branch` would treat them ambiguously.
|
|
97
|
+
For repeated use, register the repo in a `template-registries.yml` so the `ref` is kept in configuration (see [Add a template registry](#add-a-template-registry)) — then `-t <registry-name>` clones the pinned ref automatically.
|
|
98
|
+
|
|
99
|
+
## Scaffold from a local template directory
|
|
100
|
+
|
|
101
|
+
Pass a relative or absolute path to `-t`/`--template` when the template is already on disk:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npx rayfin init my-app -t ./my-template
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Local templates use the same `rayfin-template.yml` file format as git-backed templates for top-level entries.
|
|
108
|
+
|
|
109
|
+
> **Bare names resolve as template names, not paths.**
|
|
110
|
+
> Use `./`, `../`, or an absolute path when pointing at a local directory:
|
|
111
|
+
>
|
|
112
|
+
> POSIX shells:
|
|
113
|
+
>
|
|
114
|
+
> ```bash
|
|
115
|
+
> npx rayfin init my-app -t ./my-templates # local relative path
|
|
116
|
+
> npx rayfin init my-app -t ../shared/templates # parent directory
|
|
117
|
+
> npx rayfin init my-app -t /opt/templates/web # POSIX absolute
|
|
118
|
+
> ```
|
|
119
|
+
>
|
|
120
|
+
> PowerShell:
|
|
121
|
+
>
|
|
122
|
+
> ```powershell
|
|
123
|
+
> npx rayfin init my-app -t C:\templates\web # Windows absolute
|
|
124
|
+
> ```
|
|
125
|
+
>
|
|
126
|
+
> A bare value like `-t my-templates` is treated as a template name and looked up against the built-ins and registries.
|
|
127
|
+
|
|
128
|
+
### Authentication for private repositories
|
|
129
|
+
|
|
130
|
+
The CLI uses your existing git credentials — SSH keys, Git Credential Manager, GitHub CLI auth, or whatever your environment already provides.
|
|
131
|
+
No credentials are stored or managed by Rayfin.
|
|
132
|
+
|
|
133
|
+
Interactive credential prompts are disabled, so a misconfigured environment fails fast instead of hanging.
|
|
134
|
+
For GitHub repos, run `gh auth setup-git` to wire credentials through Git Credential Manager.
|
|
135
|
+
|
|
136
|
+
### Multi-template repositories
|
|
137
|
+
|
|
138
|
+
A single repository can publish multiple templates via the `entries` array in its `rayfin-template.yml` manifest (see [Author a template](#author-a-template)).
|
|
139
|
+
|
|
140
|
+
When you scaffold from a multi-template source interactively, the CLI shows a picker.
|
|
141
|
+
For non-interactive flows, pass `--template-name` with the entry's `name` or `path`:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx rayfin init my-app \
|
|
145
|
+
-t https://github.com/example-org/templates.git \
|
|
146
|
+
--template-name api-service \
|
|
147
|
+
--yes
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`--template-name` requires `--template`/`-t` pointing at a multi-template source — passing it on its own is an error.
|
|
151
|
+
The value must match one of the source's entry `name` or `path` values; against a built-in template name it has no effect.
|
|
152
|
+
|
|
153
|
+
## Add a template registry
|
|
154
|
+
|
|
155
|
+
A registry is a YAML file that lists template repositories you want to surface in `--list-templates` and the interactive picker.
|
|
156
|
+
Edit a `template-registries.yml` file at one of these locations:
|
|
157
|
+
|
|
158
|
+
| Tier | Path | When to use |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| **User-global** | `~/.rayfin/template-registries.yml` | Templates you use across many projects on this machine |
|
|
161
|
+
| **Project-local** | `<projectDir>/.rayfin/template-registries.yml` | Templates pinned to a specific project (commit alongside the repo) |
|
|
162
|
+
|
|
163
|
+
Both files are optional — the CLI also loads a bundled registry that ships with `@microsoft/rayfin-cli` itself.
|
|
164
|
+
The bundled registry that ships with current CLI releases may be empty.
|
|
165
|
+
Some templates the CLI ships with are protected and can't be overridden by a user or project entry that reuses their `name`; the rest can (see [Conflict handling](#conflict-handling) below).
|
|
166
|
+
|
|
167
|
+
> **Manage registries by hand-editing the YAML files.** There is no CLI command to add or remove registry entries.
|
|
168
|
+
|
|
169
|
+
### Registry file format
|
|
170
|
+
|
|
171
|
+
```yaml
|
|
172
|
+
registries:
|
|
173
|
+
- name: team-templates
|
|
174
|
+
displayName: Team Templates
|
|
175
|
+
description: Our team's reusable starters
|
|
176
|
+
url: https://github.com/example-org/rayfin-templates.git
|
|
177
|
+
ref: v1.2.0
|
|
178
|
+
path: catalogs/official
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Each entry supports the following fields:
|
|
182
|
+
|
|
183
|
+
| Field | Required | Description |
|
|
184
|
+
| --- | --- | --- |
|
|
185
|
+
| `name` | Yes | Unique identifier for this entry |
|
|
186
|
+
| `url` | Yes | Git URL of the template repository (HTTPS, SSH, `git@`, or `file://`) |
|
|
187
|
+
| `displayName` | No | Human-readable label (defaults to `name`) |
|
|
188
|
+
| `description` | No | Short description shown in pickers and `--list-templates` |
|
|
189
|
+
| `ref` | No | Git tag, branch, or full commit SHA to pin to (defaults to the repository's default branch) |
|
|
190
|
+
| `path` | No | Subdirectory inside the repo where the manifest lives |
|
|
191
|
+
| `templateName` | No | For a multi-template repo, the entry `name` or `path` to pre-select so consumers skip the picker |
|
|
192
|
+
|
|
193
|
+
### Conflict handling
|
|
194
|
+
|
|
195
|
+
The CLI loads registries in tier order (bundled → user-global → project-local).
|
|
196
|
+
The first occurrence of any `name` wins; later tiers with the same name are skipped and listed under `warnings` in `--list-templates` output.
|
|
197
|
+
A few templates the CLI ships with are protected: a user or project entry that reuses their `name` is ignored and gets a dedicated warning.
|
|
198
|
+
Other name conflicts still resolve by tier order; rename one of the conflicting entries to resolve.
|
|
199
|
+
|
|
200
|
+
## Author a template
|
|
201
|
+
|
|
202
|
+
A template is a directory with a `rayfin-template.yml` manifest at its root.
|
|
203
|
+
Template files are copied into the target directory, then Rayfin applies a small fixed set of scaffold transforms.
|
|
204
|
+
If your template includes `package.json`, Rayfin rewrites its `name` field to the generated project slug.
|
|
205
|
+
If `package.json` is not valid JSON, Rayfin leaves it as-is.
|
|
206
|
+
If your template includes `README.md`, Rayfin replaces the supported placeholders listed below.
|
|
207
|
+
Other file contents are not templated.
|
|
208
|
+
`__projectName__` placeholders in **filenames** are replaced with the user's project name.
|
|
209
|
+
|
|
210
|
+
The user's project name comes from the `[directory]` positional (`npm create @microsoft/rayfin@latest my-app` → `my-app`) unless they pass `--project-name` to override.
|
|
211
|
+
|
|
212
|
+
### Minimal template
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
my-template/
|
|
216
|
+
├── rayfin-template.yml
|
|
217
|
+
└── template/
|
|
218
|
+
├── package.json
|
|
219
|
+
├── README.md
|
|
220
|
+
└── src/
|
|
221
|
+
└── __projectName__.config.ts
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`rayfin-template.yml`:
|
|
225
|
+
|
|
226
|
+
```yaml
|
|
227
|
+
apiVersion: v1
|
|
228
|
+
metadata:
|
|
229
|
+
name: my-starter
|
|
230
|
+
displayName: My Starter
|
|
231
|
+
description: A starter template for Rayfin projects
|
|
232
|
+
entries:
|
|
233
|
+
- name: my-starter
|
|
234
|
+
path: ./template
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
When scaffolded into `my-app/`, the file `src/__projectName__.config.ts` is written as `src/my-app.config.ts`.
|
|
238
|
+
|
|
239
|
+
### Publish and share an external template repository
|
|
240
|
+
|
|
241
|
+
Once your template is working, share it as a git repository so your team (or anyone else) can scaffold from it.
|
|
242
|
+
|
|
243
|
+
#### 1. Initialize a git repo for the template
|
|
244
|
+
|
|
245
|
+
From your template directory:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
git init
|
|
249
|
+
git add .
|
|
250
|
+
git commit -m "Initial template"
|
|
251
|
+
git remote add origin https://github.com/example-org/my-template.git
|
|
252
|
+
git push -u origin main
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### 2. Tag a release
|
|
256
|
+
|
|
257
|
+
Don't ask consumers to scaffold from the moving `main` branch — pin to a tag so their scaffolds are reproducible:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
git tag v1.0.0
|
|
261
|
+
git push origin v1.0.0
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Bump the tag whenever you ship a meaningful change to the template.
|
|
265
|
+
|
|
266
|
+
#### 3. Share the URL
|
|
267
|
+
|
|
268
|
+
The simplest path is to hand consumers the git URL. They scaffold with:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
npx rayfin init my-app -t https://github.com/example-org/my-template.git#v1.0.0
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### 4. (Optional) Surface it through a registry
|
|
275
|
+
|
|
276
|
+
If you want the template to appear in `rayfin init --list-templates` and the interactive picker — without consumers having to remember the URL — add it to a `template-registries.yml` file (see [Add a template registry](#add-a-template-registry)).
|
|
277
|
+
|
|
278
|
+
A team-shared `.rayfin/template-registries.yml` committed to the project root, or a personal `~/.rayfin/template-registries.yml`, both work:
|
|
279
|
+
|
|
280
|
+
```yaml
|
|
281
|
+
registries:
|
|
282
|
+
- name: my-starter
|
|
283
|
+
displayName: My Starter
|
|
284
|
+
description: Our team's Rayfin starter
|
|
285
|
+
url: https://github.com/example-org/my-template.git
|
|
286
|
+
ref: v1.0.0
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
After that, consumers scaffold by name:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
npx rayfin init my-app -t my-starter
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
When you ship a new tag, update the `ref` and (ideally) commit the registry change so everyone on the team picks it up.
|
|
296
|
+
|
|
297
|
+
### Try it locally before publishing
|
|
298
|
+
|
|
299
|
+
Test your template against a local path before pushing or tagging:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
npx rayfin init test-output -t ./my-template --yes
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Manifest reference
|
|
306
|
+
|
|
307
|
+
```yaml
|
|
308
|
+
apiVersion: v1 # required, must be 'v1'
|
|
309
|
+
metadata:
|
|
310
|
+
name: my-collection # required, identifier for the manifest
|
|
311
|
+
displayName: My Collection
|
|
312
|
+
description: Optional description
|
|
313
|
+
version: 1.2.0 # accepted, currently informational only
|
|
314
|
+
tags: [todo, auth] # accepted, currently informational only
|
|
315
|
+
entries: # required, at least one entry
|
|
316
|
+
- name: api-service # template entry: scaffolds files from path
|
|
317
|
+
path: ./api-service
|
|
318
|
+
description: REST API with Rayfin data layer
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
`metadata.displayName` and `metadata.description` are shown when scaffolding from this template.
|
|
322
|
+
`metadata.version` and `metadata.tags` are accepted by the manifest schema but are not surfaced in the CLI today.
|
|
323
|
+
Entry-level `description` is shown in the local multi-template picker.
|
|
324
|
+
For git-backed nested navigation, group descriptions are shown; template entry descriptions are not.
|
|
325
|
+
|
|
326
|
+
### Single-entry vs multi-entry manifests
|
|
327
|
+
|
|
328
|
+
A single-entry manifest auto-selects with no picker:
|
|
329
|
+
|
|
330
|
+
```yaml
|
|
331
|
+
entries:
|
|
332
|
+
- name: my-starter
|
|
333
|
+
path: .
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
A multi-entry manifest shows an interactive picker (or requires `--template-name` for non-interactive flows):
|
|
337
|
+
|
|
338
|
+
```yaml
|
|
339
|
+
entries:
|
|
340
|
+
- name: api-service
|
|
341
|
+
path: ./templates/api-service
|
|
342
|
+
- name: fullstack
|
|
343
|
+
path: ./templates/fullstack
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
For local template directories, keep entries at the top level of `entries`.
|
|
347
|
+
Grouped nested navigation is available for git-backed template sources.
|
|
348
|
+
|
|
349
|
+
### Group entries for nested navigation
|
|
350
|
+
|
|
351
|
+
Use `group` entries to organize larger collections.
|
|
352
|
+
Groups can nest, and the picker walks users through the hierarchy:
|
|
353
|
+
|
|
354
|
+
```yaml
|
|
355
|
+
entries:
|
|
356
|
+
- group:
|
|
357
|
+
name: starters
|
|
358
|
+
displayName: Starter Apps
|
|
359
|
+
entries:
|
|
360
|
+
- name: hello-world
|
|
361
|
+
path: ./starters/hello-world
|
|
362
|
+
- name: todo-app
|
|
363
|
+
path: ./starters/todo-app
|
|
364
|
+
- name: standalone-app
|
|
365
|
+
path: ./standalone-app
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### What's currently supported
|
|
369
|
+
|
|
370
|
+
Templates are intentionally minimal:
|
|
371
|
+
|
|
372
|
+
- Most file contents are copied as-is.
|
|
373
|
+
- `README.md` supports `{{PROJECT_NAME}}`, `{{PROJECT_NAME_KEBAB}}`, and `{{PROJECT_NAME_PASCAL}}` placeholders.
|
|
374
|
+
- `package.json` `name` is set to the generated project slug.
|
|
375
|
+
- The only filename placeholder is `__projectName__`, replaced with the user's project name and with path separators sanitized.
|
|
376
|
+
- Files matching `rayfin-template.yml`, `.git`, `node_modules`, `.DS_Store`, and `Thumbs.db` are skipped during scaffolding.
|
|
377
|
+
- Symlinks are not followed.
|
|
378
|
+
- After scaffolding, the CLI installs its own agent files (`mcpServers.rayfin` inside `.mcp.json`, `.agents/skills/rayfin/`) into the project. You can ship `.mcp.json` with your own MCP servers, but do not include a `mcpServers.rayfin` key because the CLI manages that key. You can also ship an `AGENTS.md`; it's a one-time install and the CLI won't overwrite a template-provided one.
|
|
379
|
+
|
|
380
|
+
## Gotchas
|
|
381
|
+
|
|
382
|
+
- `--list-templates` lists built-in and registered templates only — arbitrary git URLs you pass with `-t` are not in the list.
|
|
383
|
+
- The CLI clones a single ref shallowly. Tools that depend on git history or other branches won't have them at scaffold time.
|
|
384
|
+
- Private repositories rely on ambient git credentials. Interactive prompts are disabled, so missing credentials produce an immediate auth error.
|
|
385
|
+
- Non-interactive scaffolding from a multi-entry source fails unless `--template-name` is provided. The error message lists the available names.
|
|
386
|
+
- Bare values passed to `-t` resolve as template names. Use `./`, `../`, or an absolute path for local directories.
|
|
387
|
+
|
|
388
|
+
## Related
|
|
389
|
+
|
|
390
|
+
- [CLI Quickstart](./quickstart.md) — common scaffolding workflows
|
|
391
|
+
- [Environment variables](./environment-variables.md) — runtime configuration after scaffolding
|
|
@@ -36,7 +36,7 @@ Some older examples may show `client.data.gql.<Entity>`.
|
|
|
36
36
|
|
|
37
37
|
### Read multiple records
|
|
38
38
|
|
|
39
|
-
Here is an example to read
|
|
39
|
+
Here is an example to read records and order by a column.
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
42
|
const notes = await this.rayfinClient.data.Note.select([
|
|
@@ -61,6 +61,11 @@ const notes = await this.rayfinClient.data.Note.select([
|
|
|
61
61
|
return this.sortWithPinnedFirst(notes);
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
> **`.execute()` returns a single page (100 records by default).**
|
|
65
|
+
> The Data API caps a single response at its default page size (100 records).
|
|
66
|
+
> `.first(n)` raises the page size, but `.execute()` still returns only that one page and does **not** signal whether more records exist - so a list longer than the page is silently truncated.
|
|
67
|
+
> If your entity can grow beyond a single page (or you need a guaranteed-complete result set), use [pagination](#paginate-large-lists) instead of `.execute()`.
|
|
68
|
+
|
|
64
69
|
### Filter records
|
|
65
70
|
|
|
66
71
|
Use `where` to filter results.
|
|
@@ -78,7 +83,16 @@ const pinnedNotes = await this.rayfinClient.data.Note.select([
|
|
|
78
83
|
|
|
79
84
|
### Paginate Large Lists
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
Because `.execute()` returns only a single page (100 records by default) and gives no indication that more exist, use cursor pagination whenever a query can return more than one page.
|
|
87
|
+
Pagination uses `.first(n)` to set the page size and `.executePaginated()` to return one page plus the cursor metadata needed to fetch the next one.
|
|
88
|
+
|
|
89
|
+
**When to paginate vs. when `.execute()` is fine:**
|
|
90
|
+
|
|
91
|
+
- Use `.execute()` only for queries you know are bounded under one page (for example a `.where(...)` filter that can match at most a handful of rows, or a small lookup table).
|
|
92
|
+
- Use pagination for any unbounded or growing list - a user's notes, an order history, a product catalog. When in doubt, paginate.
|
|
93
|
+
- If you are building a UI list and aren't sure how large it will get, ask the user whether they want infinite scroll / a "load more" button (page-at-a-time) or the complete set up front (loop until `hasNextPage` is `false`, shown below).
|
|
94
|
+
|
|
95
|
+
**Fetch a single page:**
|
|
82
96
|
|
|
83
97
|
```typescript
|
|
84
98
|
const page = await this.rayfinClient.data.Note.select([
|
|
@@ -90,11 +104,29 @@ const page = await this.rayfinClient.data.Note.select([
|
|
|
90
104
|
.first(25)
|
|
91
105
|
.executePaginated();
|
|
92
106
|
|
|
93
|
-
const items = page.items;
|
|
94
|
-
const cursor = page.endCursor;
|
|
95
|
-
const hasNextPage = page.hasNextPage;
|
|
107
|
+
const items = page.items; // up to 25 records
|
|
108
|
+
const cursor = page.endCursor; // pass to .after(cursor) for the next page
|
|
109
|
+
const hasNextPage = page.hasNextPage; // true if more records remain
|
|
96
110
|
```
|
|
97
111
|
|
|
112
|
+
**Fetch the next page** by passing the previous `endCursor` to `.after()`:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const nextPage = await this.rayfinClient.data.Note.select(['id', 'title', 'createdAt'])
|
|
116
|
+
.orderBy({ createdAt: 'desc' })
|
|
117
|
+
.first(25)
|
|
118
|
+
.after(cursor)
|
|
119
|
+
.executePaginated();
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Fetch every record** by repeating the call in a loop, passing each page's `endCursor` to `.after()`, until `hasNextPage` is `false`.
|
|
123
|
+
Keep the `.select()`, `.where()`, and `.orderBy()` clauses identical across pages - a stable sort order is required for the cursor to advance correctly.
|
|
124
|
+
|
|
125
|
+
> **`.first(n)` is bounded by DAB's maximum page size (100,000).**
|
|
126
|
+
> Rayfin returns a single default page of 100 records when a query omits `.first(n)`.
|
|
127
|
+
> For large result sets, the recommended pattern is to page through results with `.after()` rather than requesting everything in one large `.first(n)`.
|
|
128
|
+
> `.first(-1)` requests an unbounded page (all matching records), which DAB still caps at the maximum - so it works only when the full result set fits under that limit.
|
|
129
|
+
|
|
98
130
|
### Fetch a Single Record
|
|
99
131
|
|
|
100
132
|
Here is an example to fetch a single record.
|
|
@@ -198,6 +230,8 @@ await this.rayfinClient.data.Note.delete({ id });
|
|
|
198
230
|
|
|
199
231
|
## Limitations and Workarounds
|
|
200
232
|
|
|
233
|
+
- `.execute()` returns only a single page (100 records by default) and does not signal whether more records exist, so lists longer than one page are silently truncated.
|
|
234
|
+
Use `.first(n)` with `.executePaginated()` and `.after(endCursor)` to page through the full result set.
|
|
201
235
|
- `count()` is not implemented today; select the identifiers you need and use `results.length` or a custom aggregate.
|
|
202
236
|
- `totalCount` appears on the `PagedResult` type but DAB does not populate it in paginated queries.
|
|
203
237
|
|
|
@@ -7,6 +7,10 @@ sidebar_position: 4
|
|
|
7
7
|
Rayfin can generate a [Standard Schema](https://standardschema.dev) validator directly from your decorated entity classes.
|
|
8
8
|
This lets you validate form input on the client without adding a separate validation library like Zod or Yup.
|
|
9
9
|
|
|
10
|
+
> **Note:** Rayfin entities use TC39 Stage 3 decorators, so any build tooling that compiles your client code must target **ES2022** (or later).
|
|
11
|
+
> If you see `Expression expected` errors on `@entity()` (or other decorators) when calling `toStandardSchema` or `getFieldConstraints`, your bundler is compiling to an older target.
|
|
12
|
+
> For Vite, set `target: 'es2022'` in your `vite.config.ts` — see [Vite configuration](../getting-started/project-structure.md#vite-configuration) — and use the default `@vitejs/plugin-react` (esbuild) plugin, since `@vitejs/plugin-react-swc` does not support these decorators regardless of the `target` setting.
|
|
13
|
+
|
|
10
14
|
## Build a validator from an entity
|
|
11
15
|
|
|
12
16
|
Use `toStandardSchema` to create a validator from any `@entity()` class.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 75
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Deprecation Warnings
|
|
6
|
+
|
|
7
|
+
Rayfin may emit deprecation warnings when your application uses an API or option that will change in a future release.
|
|
8
|
+
Warnings are printed with `console.warn` and include a stable code such as `[RAYFIN_DEP_USE_PROXY]` so you can search for the affected usage.
|
|
9
|
+
|
|
10
|
+
## Silence warnings in application code
|
|
11
|
+
|
|
12
|
+
Use `setDeprecationsSilenced(true)` when you have reviewed the warnings and want to hide them for a specific environment.
|
|
13
|
+
Import the setting from `@microsoft/rayfin-client` and call it early in application startup before creating Rayfin clients or using deprecated APIs.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { setDeprecationsSilenced } from '@microsoft/rayfin-client';
|
|
17
|
+
|
|
18
|
+
setDeprecationsSilenced(true);
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
You can call `setDeprecationsSilenced(false)` to enable warnings again.
|
|
22
|
+
Use `isDeprecationSilenced()` when you need to check the current setting.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { isDeprecationSilenced } from '@microsoft/rayfin-client';
|
|
26
|
+
|
|
27
|
+
console.log(isDeprecationSilenced());
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Silence warnings in Node.js
|
|
31
|
+
|
|
32
|
+
For Node.js scripts, tests, or server-side tools, set `RAYFIN_NO_DEPRECATION` to `1` or `true`.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
RAYFIN_NO_DEPRECATION=1 npm run dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Browser apps
|
|
39
|
+
|
|
40
|
+
Browser environments do not provide the Node.js environment variable that Rayfin checks.
|
|
41
|
+
Use the programmatic toggle in browser apps, and call it during startup before code paths that could emit deprecation warnings.
|
|
@@ -273,6 +273,9 @@ export default defineConfig({
|
|
|
273
273
|
|
|
274
274
|
> **Tip:** Templates created with `npm create @microsoft/rayfin@latest` already include these settings.
|
|
275
275
|
> If you are integrating Rayfin into an existing Vite project, add the three `target` entries shown above.
|
|
276
|
+
>
|
|
277
|
+
> **Note:** Use the default `@vitejs/plugin-react` plugin (esbuild-based).
|
|
278
|
+
> `@vitejs/plugin-react-swc` only supports legacy/experimental decorators and fails to parse Rayfin's TC39 decorators with an `Expression expected` error — regardless of the `target` setting.
|
|
276
279
|
|
|
277
280
|
### Environment variables
|
|
278
281
|
|
package/assets/docs/index.md
CHANGED
|
@@ -96,4 +96,5 @@ It can scaffold new projects, launch local infrastructure, sync schema changes,
|
|
|
96
96
|
- Configure authentication with [Rayfin Auth](./auth/overview.md).
|
|
97
97
|
- Deploy frontends with [Static Content Hosting](./hosting/index.md).
|
|
98
98
|
- Explore CLI capabilities in [CLI Guide](./cli/index.md).
|
|
99
|
+
- Learn how to manage [Deprecation Warnings](./deprecations.md).
|
|
99
100
|
- Review [Known Limitations](./known-limitations.md) for current behaviors and workarounds.
|
|
@@ -18,6 +18,10 @@ Use an explicit join entity with two `@one()` navigations instead.
|
|
|
18
18
|
Some query limitations are imposed by Data API Builder.
|
|
19
19
|
See [Data known limitations](./data/index.md#known-limitations).
|
|
20
20
|
|
|
21
|
+
- Collection queries return only one page unless the client pages through them.
|
|
22
|
+
The default page size is 100 records and the maximum page size is 100,000 records.
|
|
23
|
+
Use `.first(n)` with `.executePaginated()` and `.after(endCursor)` for lists that can exceed one page.
|
|
24
|
+
|
|
21
25
|
## Relationships
|
|
22
26
|
|
|
23
27
|
- Rayfin auto-generates foreign key columns when you define `@one()` or `@many()` navigation decorators.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/rayfin-guide",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.0-alpha.1148",
|
|
4
4
|
"description": "Cross-cutting Builder guides for the Rayfin platform — discovered by `@microsoft/rayfin-docs` via the `rayfinDocs` package.json field convention.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|