@microsoft/rayfin-guide 1.35.0-alpha.1541 → 1.36.0-alpha.1581

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.
@@ -192,6 +192,7 @@ These variables are read from the shell environment and are never written to fil
192
192
  | `RAYFIN_FEATURE_FLAGS` | Comma-separated list of experimental feature names to enable (case-insensitive). Recognized values include `docker-local-dev`, `functions`, and `postgresql`. |
193
193
  | `RAYFIN_WEBSERVICE_IMAGE_NAME` | **Experimental.** Override the webservice container image used by `rayfin dev --provider docker` and Docker Compose. Defaults to `ghcr.io/microsoft/project-rayfin/webservice:cli-<version>`. |
194
194
  | `RAYFIN_APPINSIGHTS_CONNECTION_STRING` | Override the telemetry endpoint for the CLI and VS Code extension. |
195
+ | `RAYFIN_TELEMETRY_ENV` | Override the CLI and `create-rayfin` telemetry environment label. Values are trimmed and lowercased. Known labels include `github-actions`, `azure-pipelines`, `gitlab-ci`, `jenkins`, `codespaces`, `devcontainer`, `local`, and `other`; custom labels may contain 1–64 ASCII letters, digits, hyphens, or underscores. Invalid non-empty values map to `other`, while an empty value uses automatic detection. Do not include identifying or sensitive values. |
195
196
 
196
197
  ### Recognized `RAYFIN_FEATURE_FLAGS` values
197
198
 
@@ -64,20 +64,6 @@ For the full walkthrough, see the [CLI Quickstart](./quickstart.md) or the [Buil
64
64
  | `npx rayfin up secrets apply` | Read secrets from `rayfin/.env` file (prefixed with `RAYFIN_SECRET_`) and securely apply them to the remote Rayfin item workload. Validates that secrets are persisted. Use `--env-file <path>` to specify a custom .env file location. |
65
65
  | `npx rayfin up staticapp deploy` | Build, package, and deploy static content to the remote Rayfin item. Add `--skip-build` to deploy existing build output without rebuilding. |
66
66
 
67
- ### Connectors
68
-
69
- Connectors let a Rayfin app read from existing Fabric sources. The `connector` command group is only registered when `RAYFIN_FEATURE_FLAGS` contains `connectors`. See [Connectors](./connectors/index.md) for the full guide.
70
-
71
- | Command | Description |
72
- | --- | --- |
73
- | `npx rayfin connector search [query]` | Discover Fabric sources you can connect to. See [Searching for sources](./connectors/search.md). |
74
- | `npx rayfin connector add` | Declare a connector in `rayfin.yml` and run schema discovery. See [Adding a connector](./connectors/add.md). |
75
- | `npx rayfin connector list` | List the connectors declared in the current project. |
76
- | `npx rayfin connector remove <name>` | Remove a connector's `rayfin.yml` entry and its `rayfin/connectors/<name>/` directory. |
77
- | `npx rayfin connector inspect` | Run a read-only sample query against a connector's source. See [Inspecting a source](./connectors/inspect.md). |
78
- | `npx rayfin connector invoke <name> <operation>` | Run one named operation against a configured connector. See [Invoking an operation](./connectors/invoke.md). |
79
- | `npx rayfin up connector apply` | Re-apply connector configuration to the remote Rayfin item. |
80
-
81
67
  ## Update the CLI
82
68
 
83
69
  To get the latest version of the Rayfin CLI and its dependencies:
@@ -54,8 +54,6 @@ If you omit it, the server generates a UUID automatically.
54
54
  - Composite or non-`id` primary keys are not supported.
55
55
 
56
56
  **Scope:** the rules above apply to entities you own under `rayfin/data/`.
57
- Connector entities under `rayfin/connectors/` model an existing, external Fabric SQL source and follow different rules — the primary key is whatever the source actually declares, of any name and any datatype, including composite keys or no key at all.
58
- See [Entity generation contract](../cli/connectors/category-a-entities.md#entity-generation-contract) for the connector-path key rules.
59
57
 
60
58
  ```typescript
61
59
  @entity()
@@ -43,8 +43,7 @@ Always narrow YAML first, then add `@role(...)` to entities.
43
43
  Example: a `fabric-warehouse` connector with `operations: [read, update]` and an `Order` entity locked to read-only:
44
44
 
45
45
  ```ts
46
- import { entity, int, text, decimal, Source } from '@microsoft/rayfin-core/experimental';
47
- import { role } from '@microsoft/rayfin-core';
46
+ import { entity, int, text, decimal, Source, role } from '@microsoft/rayfin-core';
48
47
 
49
48
  @role('authenticated', ['read'])
50
49
  @entity()
@@ -197,7 +196,6 @@ The map also accepts entity classes, but do not use that form here: it puts the
197
196
  **Use the entity's property names, not the database column names.**
198
197
  These are the names on the generated class — the same keys that appear in the row type — not the `columnName` values in `metadata.json`.
199
198
  For `@uuid({ column: 'ProductID' }) productId!: string`, the entry is `productId`.
200
- The one exception is a field that declares `graphqlName`, in which case use that name.
201
199
  Include every scalar field and leave relationship fields out, since those need nested sub-selections.
202
200
 
203
201
  **Relationship selects need the class form.**
@@ -585,8 +583,8 @@ Build the import line deterministically:
585
583
 
586
584
  - Always include `entity` and `Source`.
587
585
  - Then append, in this exact order, any decorator names actually used in the file: `boolean`, `date`, `decimal`, `int`, `text`, `uuid`, `one`, `many`. Skip any not used.
588
- - All from `@microsoft/rayfin-core/experimental`.
589
- - If any column is server-generated, also add `import type { AutoGenerated } from '@microsoft/rayfin-core/experimental';`.
586
+ - All from `@microsoft/rayfin-core`.
587
+ - If any column is server-generated, also add `import type { AutoGenerated } from '@microsoft/rayfin-core';`.
590
588
  - For every relationship target that is a different class, add a sibling import: `import { <SiblingClass> } from './<SiblingClass>.js';`. Sibling imports are alphabetised; self-references get no sibling import.
591
589
  - In subset mode, only relationships that survived the subset skip contribute sibling imports.
592
590
 
@@ -595,8 +593,8 @@ Build the import line deterministically:
595
593
  ```ts
596
594
  // @generated — do not edit.
597
595
 
598
- import { entity, uuid, text, int, date, one, many, Source } from '@microsoft/rayfin-core/experimental';
599
- import type { AutoGenerated } from '@microsoft/rayfin-core/experimental';
596
+ import { entity, uuid, text, int, date, one, many, Source } from '@microsoft/rayfin-core';
597
+ import type { AutoGenerated } from '@microsoft/rayfin-core';
600
598
  import { Category } from './Category.js';
601
599
  import { OrderItem } from './OrderItem.js';
602
600
 
@@ -672,4 +670,4 @@ Absence means "unknown / not exposed", not permission to synthesize keys or rela
672
670
  | `Cannot find module '@microsoft/rayfin-connector-fabric-graphql'` | The connector packages were never installed — `connector add` does not add them | Run the pinned `npm install` command `connector add` printed, or rebuild it from `rayfin connector types --json`. |
673
671
  | Deployed page is blank with `Uncaught SyntaxError: Invalid or unexpected token`, though build, tests and deploy all passed | `schema.ts` imports or re-exports entity classes as values, so the decorated classes were bundled into the browser build | Switch every entity import and re-export in `schema.ts` to `import type` / `export type`, and give `connectorConfig.entities` column-name arrays instead of classes. |
674
672
  | A read throws `SELECTION_REQUIRED` | `connectorConfig.entities` is missing, so there is no default column list | Add the entity's property names, or pass an explicit `select([...])`. |
675
- | A read returns null or errors on a field that exists in the database | `entities` lists database column names instead of the entity's property names | Use the names declared on the generated class (or `graphqlName` where set), for example `productId`, not `ProductID`. |
673
+ | A read returns null or errors on a field that exists in the database | `entities` lists database column names instead of the entity's property names | Use the names declared on the generated class, for example `productId`, not `ProductID`. |
@@ -30,7 +30,7 @@ Each command has its own reference page:
30
30
 
31
31
  - [`connector search`](./search.md) — discover Fabric sources the signed-in identity can add.
32
32
  - [`connector add`](./add.md) — declare a connector in `rayfin.yml` and scaffold its files.
33
- - [`connector inspect`](./inspect.md) — run a single read-only sample query against a source.
33
+ - [`connector inspect`](./inspect.md) — list a source's entity names, or run a single read-only sample query against one.
34
34
  - [`connector invoke`](./invoke.md) — run one named operation against a configured connector.
35
35
 
36
36
  Each category has its own contract page — read the one that matches your connector type, not both:
@@ -44,16 +44,16 @@ A typical loop is search → add → inspect (Category A) or search → add →
44
44
 
45
45
  The commands available to a connector, and the code you write against it, depend on its category.
46
46
 
47
- | | Category A — GraphQL entity connectors | Category B — function-bridge connectors |
48
- | ------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------ |
49
- | **Types** | `fabric-sqlanalytics`, `fabric-warehouse`, `fabric-sqldatabase` | `kusto`, `fabric-semanticmodel` |
50
- | **App surface** | Generated entity files with typed CRUD through the data client | A single `executeQuery` operation carrying a raw query |
47
+ | | Category A — GraphQL entity connectors | Category B — function-bridge connectors |
48
+ | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
49
+ | **Types** | `fabric-sqlanalytics`, `fabric-warehouse`, `fabric-sqldatabase` | `kusto`, `fabric-semanticmodel` |
50
+ | **App surface** | Generated entity files with typed CRUD through the data client | A single `executeQuery` operation carrying a raw query |
51
51
  | **Operations** | `read` only for `fabric-sqlanalytics` (Lakehouse SQL endpoints are read-only); `read`, `create`, `update`, `delete` for `fabric-warehouse` and `fabric-sqldatabase` (narrowable) | `executeQuery` only |
52
- | **Auth** | `delegated` or configured per project | Must be `delegated` |
53
- | **Entity files and `@role` policies** | Yes | No |
54
- | **`metadata.json` entities** | Yes | No |
55
- | **`connector inspect`** | Supported | `fabric-semanticmodel` only — `kusto` is not supported |
56
- | **`connector invoke`** | Rarely needed | The main way to exercise the connector |
52
+ | **Auth** | `delegated` or configured per project | Must be `delegated` |
53
+ | **Entity files and `@role` policies** | Yes | No |
54
+ | **`metadata.json` entities** | Yes | No |
55
+ | **`connector inspect`** | Supported | `fabric-semanticmodel` only — `kusto` is not supported |
56
+ | **`connector invoke`** | Rarely needed | The main way to exercise the connector |
57
57
 
58
58
  Category B connectors are pinned to an adapter version and expose no GraphQL entities, so there is nothing to generate and no row-level security to author.
59
59
 
@@ -5,28 +5,43 @@ sidebar_position: 3
5
5
  # connector inspect
6
6
 
7
7
  ```bash
8
- npx rayfin connector inspect (--name <name> | <direct-selector-flags>) (--entity <name> | --query <path>) [--rows <n>] [--verbose] [--json]
8
+ npx rayfin connector inspect (--name <name> | <direct-selector-flags>) [--entity <name> | --query <path>] [--rows <n>] [--verbose] [--json]
9
9
  ```
10
10
 
11
11
  `connector inspect` takes no positional arguments — every selector and query mode is a flag.
12
12
 
13
- `connector inspect` runs a single read-only sample query against a connector's underlying source, before you have written any app code. Use it to check a table's real data and shape ahead of entity generation, or to debug a row-level-security or query issue on an already-wired connector. It is a development aid — never use it to power app functionality.
13
+ `connector inspect` explores a connector's underlying source in read-only mode, before you have written any app code. Run it with just a selector to **list the entity/table names** the source exposes; add `--entity` to sample one of them, or `--query` to run a `.sql`/`.dax` file of your own. Use it to check a table's real data and shape ahead of entity generation, or to debug a row-level-security or query issue on an already-wired connector. It is a development aid — never use it to power app functionality.
14
14
 
15
15
  Supported types: the three Category A SQL types (`fabric-sqlanalytics`, `fabric-warehouse`, `fabric-sqldatabase`) and `fabric-semanticmodel` (DAX). `kusto` is **not** supported today — the command errors with `Unsupported connector type: kusto`.
16
16
 
17
- ## Pick exactly one selector and one query mode
17
+ ## Pick exactly one selector, and at most one query mode
18
18
 
19
- Two independent choices, each a mutually exclusive pair. Passing zero or both options in a pair fails validation before any network call.
19
+ Two independent choices. The **selector** is a mutually exclusive pair passing zero or both fails validation before any network call. The **query mode** has three options, and omitting it is a mode of its own rather than an error; only passing `--entity` and `--query` together fails.
20
20
 
21
- | Choice | Option A | Option B |
22
- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
- | **Selector** — which connector or item to query | `--name <name>` a connector already declared in `rayfin.yml` | Direct mode — `--workspace-id`/`--workspace <name>` plus `--item-id`/`--item <name>` plus `--type <type>`, or `--url <portal-url>` for a semantic model (auto-extracts workspace and item IDs) |
24
- | **Query mode** | `--entity <name>` structured: builds `SELECT TOP (n) * FROM <entity>` (SQL) or `EVALUATE TOPN(n, '<entity>')` (DAX) for you | `--query <path>` raw: runs the literal `.sql` or `.dax` file verbatim, still capped and validated |
21
+ | Selector which connector or item to query | Meaning |
22
+ | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
+ | `--name <name>` | A connector already declared in `rayfin.yml`. |
24
+ | Direct mode | `--workspace-id`/`--workspace <name>` plus `--item-id`/`--item <name>` plus `--type <type>`, or `--url <portal-url>` for a semantic model (auto-extracts workspace and item IDs). |
25
25
 
26
- All four combinations of `{--name, direct} × {--entity, --query}` are valid.
26
+ | Query mode | What it runs |
27
+ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
28
+ | _omit both_ — entity listing | Lists the entity/table names the source exposes, so you have something to pass to `--entity`. This is the default. |
29
+ | `--entity <name>` — structured | Builds `SELECT TOP (n) * FROM <entity>` (SQL) or `EVALUATE TOPN(n, '<entity>')` (DAX) for you. |
30
+ | `--query <path>` — raw | Runs the literal `.sql` or `.dax` file verbatim, still capped and validated. |
31
+
32
+ All six combinations of `{--name, direct} × {listing, --entity, --query}` are valid.
27
33
 
28
34
  `--workspace` and `--item` accept display names and are resolved to IDs the same way [`connector add`](./add.md) fuzzy matching works; `--workspace-id` and `--item-id` take literal IDs directly.
29
35
 
36
+ ## Entity listing
37
+
38
+ Omitting both `--entity` and `--query` lists the entity names available on the source. This is the starting point when you don't know the names yet — the output is what you feed back into `--entity`, and the command prints a ready-to-run `--entity` suggestion carrying the same selector flags you just used.
39
+
40
+ - **SQL types** — reads `INFORMATION_SCHEMA.TABLES`, returning `TABLE_SCHEMA` and `TABLE_NAME`.
41
+ - **`fabric-semanticmodel`** — reads `INFO.TABLES()`, returning table names.
42
+
43
+ Listing honours `--rows` and `--json` like any other mode, and the `--json` envelope reports `queryMode: "entities"`.
44
+
30
45
  ## Entity resolution
31
46
 
32
47
  Applies to `--entity` mode only.
@@ -37,22 +52,28 @@ Applies to `--entity` mode only.
37
52
 
38
53
  ## Validation
39
54
 
40
- Applies to both query modes.
55
+ Applies to `--entity` and `--query` modes.
41
56
 
42
57
  - **SQL** — must start with `SELECT` or `WITH`; must be a single statement (a trailing `;` is fine, an embedded one is not); rejects `INSERT`, `UPDATE`, `DELETE`, `MERGE`, `CREATE`, `ALTER`, `DROP`, `TRUNCATE`, `EXEC`/`EXECUTE`, and `INTO` anywhere outside a string literal.
43
58
  - **DAX** — must start with `EVALUATE`.
44
59
  - `--query <path>` must resolve to a `.sql` or `.dax` file inside the project root; paths outside it are rejected. The project root is the directory containing `rayfin/rayfin.yml` when one is found. Direct mode (no `--name`) falls back to the current working directory if no `rayfin.yml` exists, so `--query` never requires a Rayfin project.
45
- - `--rows <n>` caps the sample size — default 10, maximum 100. The result reports `truncated: true` when the source had more rows than the cap.
60
+ - `--rows <n>` caps the sample size — maximum 100. The default is mode-specific: entity listing (neither `--entity` nor `--query`) defaults to **100**, while `--entity` and `--query` sampling default to **10**. The result reports `truncated: true` when the source had more rows than the cap; inspect fetches one row beyond the cap to detect that, then discards it.
46
61
 
47
62
  ## Examples
48
63
 
49
64
  ```bash
65
+ # --name selector, no query mode: list the entity names on the source
66
+ npx rayfin connector inspect --name inventory
67
+
50
68
  # --name selector + structured entity mode
51
69
  npx rayfin connector inspect --name inventory --entity Order
52
70
 
53
71
  # --name selector + raw query file
54
72
  npx rayfin connector inspect --name inventory --query rayfin/queries/order.sql
55
73
 
74
+ # Direct selector, no query mode: list the entity names on the source
75
+ npx rayfin connector inspect --workspace-id <ws-id> --item-id <item-id> --type fabric-warehouse
76
+
56
77
  # Direct selector (literal IDs) + structured entity mode
57
78
  npx rayfin connector inspect --workspace-id <ws-id> --item-id <item-id> --type fabric-warehouse --entity Order
58
79
 
@@ -63,7 +84,7 @@ npx rayfin connector inspect --workspace "Sales Analytics" --item "Inventory War
63
84
  npx rayfin connector inspect --url <fabric-portal-semantic-model-url> --query rayfin/queries/model.dax
64
85
  ```
65
86
 
66
- Combine `--workspace-id`, `--item-id`, and `--type` with either `--entity` or `--query` freely — none of the four combinations require `--name` or a `rayfin.yml` entry to exist.
87
+ Combine `--workspace-id`, `--item-id`, and `--type` with entity listing, `--entity`, or `--query` freely — none of the six combinations require `--name` or a `rayfin.yml` entry to exist.
67
88
 
68
89
  ## Errors
69
90
 
@@ -78,6 +78,8 @@ services:
78
78
  data:
79
79
  enabled: true
80
80
  dialect: mssql
81
+ storage:
82
+ enabled: false
81
83
  staticHosting:
82
84
  enabled: true
83
85
  root: .
@@ -158,6 +160,12 @@ Configure an email provider for magic links, password resets, and email verifica
158
160
  | `useStartTls` | `boolean` | `false` | Use STARTTLS for the SMTP connection. |
159
161
  | `webPort` | `number` | `1080` | MailDev web UI port (local development only). |
160
162
 
163
+ #### `services.storage`
164
+
165
+ | Field | Type | Default | Description |
166
+ | --- | --- | --- | --- |
167
+ | `enabled` | `boolean` | `false` | Enable the storage service. |
168
+
161
169
  #### `services.staticHosting`
162
170
 
163
171
  | Field | Type | Default | Description |
@@ -167,6 +175,10 @@ Configure an email provider for magic links, password resets, and email verifica
167
175
  | `folder` | `string` | `"dist"` | Directory containing built static assets (relative to `root`). |
168
176
  | `buildCommand` | `string` | — | Shell command to run before packaging (e.g. `npm run build`). |
169
177
  | `indexDocument` | `string` | — | Default document served for the root path (e.g. `index.html`). |
178
+ | `anonymousAccess` | `boolean` | — | Whether visitors can open the app without signing in. Required when static hosting is enabled. |
179
+
180
+ `anonymousAccess` has no default.
181
+ See [Static hosting](../hosting/index.md) for the posture table.
170
182
 
171
183
  > **Tip:** All string values support environment variable interpolation with `${VAR}` and `${VAR:-default}` syntax.
172
184
  > Variables are resolved from `rayfin/.env` and the shell environment.
@@ -37,6 +37,54 @@ services:
37
37
  | `root` | No | Project root | Root directory of the frontend project, relative to the project root. |
38
38
  | `buildCommand` | No | — | Shell command to run before packaging (for example, `npm run build`). |
39
39
  | `indexDocument` | No | — | Default document to serve for directory requests (for example, `index.html`). |
40
+ | `anonymousAccess` | Yes | — | Whether visitors can open the app without signing in. |
41
+
42
+ ### Access posture
43
+
44
+ `anonymousAccess` selects who can open your deployed app.
45
+ Set `anonymousAccess` explicitly — leaving it out is not the same as setting it to `false`, and once your tenant enforces static-hosting access control a deployment that omits `anonymousAccess` is rejected.
46
+
47
+ | Posture | `anonymousAccess` | Who can open the app |
48
+ | --- | --- | --- |
49
+ | Signed-in users only | `false` | Visitors must sign in. |
50
+ | Public | `true` | Anyone with the link, no sign-in. |
51
+
52
+ ```yaml
53
+ services:
54
+ staticHosting:
55
+ enabled: true
56
+ folder: dist
57
+ anonymousAccess: false
58
+ ```
59
+
60
+ `rayfin up` asks you to choose a posture the first time it deploys a project that has not recorded one, then writes your choice to `rayfin.yml` so later deploys never ask again.
61
+ In automation — `--yes`, a non-interactive terminal, or `CI=true` — it never prompts: add `anonymousAccess` to `rayfin.yml` and re-run.
62
+ `anonymousAccess` must be `true` or `false`; a value that is neither, such as an environment variable that did not resolve, is rejected before anything is deployed.
63
+
64
+ A newly scaffolded project already has `anonymousAccess: false`, so it is private from the moment it exists and deploys without a prompt.
65
+ The prompt exists for projects created before this property did: those apps are being served publicly today, so `rayfin up` asks once and never guesses on your behalf.
66
+ Choosing public does not turn off Rayfin auth — it decides who may load the site, not whether the app can sign users in.
67
+
68
+ `rayfin up staticapp deploy` does not set an access posture.
69
+ It publishes content only, so the app keeps whatever posture the last full `rayfin up` recorded.
70
+
71
+ ### Declared package versions
72
+
73
+ Every `rayfin up` records which packages produced the deployment, under `packageVersions` in the runtime settings it uploads:
74
+
75
+ | Key | When it is sent |
76
+ | --- | --- |
77
+ | `@microsoft/rayfin-cli` | Always, set to the running CLI's version. |
78
+ | `@microsoft/rayfin-auth` | When your frontend package has the auth SDK installed, set to the installed version. |
79
+
80
+ You do not author this.
81
+ Run `rayfin up --dry-run` to see exactly which versions a deploy would declare, without deploying.
82
+
83
+ Once your tenant enforces static-hosting access control, a CLI too old to record its version cannot deploy a static-hosted app, and the deployment is rejected with instructions to upgrade:
84
+
85
+ ```bash
86
+ npm install -g @microsoft/rayfin-cli@latest
87
+ ```
40
88
 
41
89
  ### Example with a separate frontend directory
42
90
 
@@ -133,7 +181,7 @@ The deploy tool updates the configuration and pushes it to the backend during de
133
181
 
134
182
  - The compressed ZIP archive must not exceed **100 MB**.
135
183
  - The CLI uses maximum compression to minimize upload size.
136
- - If your build output exceeds the limit, consider excluding large assets from the deployed bundle.
184
+ - If your build output exceeds the limit, consider excluding large assets or using the storage service for binary files.
137
185
 
138
186
  ## Complete example
139
187
 
@@ -182,6 +230,7 @@ If the ZIP exceeds 100 MB:
182
230
 
183
231
  - Review your build output for unnecessary files (source maps, unoptimized images).
184
232
  - Configure your bundler to exclude development artifacts from the production build.
233
+ - Move large binary assets to Rayfin storage instead of bundling them as static content.
185
234
 
186
235
  ### No remote endpoint configured
187
236
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/rayfin-guide",
3
- "version": "1.35.0-alpha.1541",
3
+ "version": "1.36.0-alpha.1581",
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": [