@microsoft/rayfin-guide 1.36.0-alpha.1687 → 1.36.0-alpha.1818
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/app-backend/deep-linking.md +43 -5
- package/assets/docs/app-backend/deploy.md +54 -3
- package/assets/docs/cli/connectors/add.md +11 -1
- package/assets/docs/cli/connectors/index.md +1 -1
- package/assets/docs/cli/connectors/inspect.md +34 -1
- package/assets/docs/cli/connectors/invoke.md +58 -1
- package/assets/docs/cli/functions/deploy.md +5 -1
- package/assets/docs/cli/functions/dev-apply.md +30 -4
- package/assets/docs/cli/functions/index.md +4 -2
- package/assets/docs/cli/functions/init.md +16 -1
- package/assets/docs/cli/index.md +20 -8
- package/assets/docs/cli/secrets.md +18 -8
- package/assets/docs/cli/templates.md +17 -1
- package/assets/docs/functions/connections/add-ado.md +8 -4
- package/assets/docs/functions/connections/add-azure-resource.md +17 -131
- package/assets/docs/functions/connections/add-fabric-resource.md +31 -61
- package/assets/docs/functions/connections/add-foundry.md +11 -4
- package/assets/docs/functions/connections/get-fabric-info.md +7 -25
- package/assets/docs/functions/connections/index.md +127 -22
- package/assets/docs/functions/index.md +39 -1
- package/assets/docs/functions/secrets.md +39 -11
- package/assets/docs/functions/writing-functions.md +27 -23
- package/assets/docs/getting-started/project-structure.md +3 -1
- package/assets/docs/hosting/index.md +12 -1
- package/package.json +1 -1
- package/assets/docs/functions/connections/add-work-iq.md +0 -39
|
@@ -33,6 +33,8 @@ Your app owns the shape of the state object.
|
|
|
33
33
|
npm install @microsoft/rayfin-app-state-fabric
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
If your project uses prerelease Rayfin packages, install the same exact version of `@microsoft/rayfin-app-state-fabric` as the other `@microsoft/rayfin-*` packages in the project.
|
|
37
|
+
|
|
36
38
|
## Create the client
|
|
37
39
|
|
|
38
40
|
Create one client for the lifetime of your app and share it, rather than constructing one per component.
|
|
@@ -40,13 +42,13 @@ Create one client for the lifetime of your app and share it, rather than constru
|
|
|
40
42
|
```typescript
|
|
41
43
|
import { createFabricAppStateClient } from '@microsoft/rayfin-app-state-fabric';
|
|
42
44
|
|
|
43
|
-
const appState = createFabricAppStateClient(
|
|
44
|
-
targetOrigin: 'https://app.fabric.microsoft.com',
|
|
45
|
-
});
|
|
45
|
+
const appState = createFabricAppStateClient();
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
Leave `targetOrigin` unset.
|
|
49
|
+
The parent window is a Fabric extension host, not the portal origin shown in the address bar, and its origin varies by environment.
|
|
50
|
+
Pinning the portal origin makes the browser silently discard every message.
|
|
51
|
+
When `targetOrigin` is omitted, messages are posted with `"*"` and inbound events are not origin-checked.
|
|
50
52
|
|
|
51
53
|
## Read launch state before first render
|
|
52
54
|
|
|
@@ -66,6 +68,36 @@ It resolves from the seeded URL on hosts that support it, so awaiting it does no
|
|
|
66
68
|
Treat launch state as untrusted input.
|
|
67
69
|
Anyone can edit a link before sharing it, so validate it exactly as you would a query parameter before using it to drive queries.
|
|
68
70
|
|
|
71
|
+
## Keep the restored route through sign-in
|
|
72
|
+
|
|
73
|
+
A Rayfin app is authenticated, and its route guard sends a signed-out visitor to the sign-in route.
|
|
74
|
+
That redirect runs after the launch state has been restored, so a guard that does not carry the requested route forward replaces it, and the visitor lands on the default page.
|
|
75
|
+
|
|
76
|
+
This is the normal path for a shared link, because the recipient is usually not signed in yet.
|
|
77
|
+
|
|
78
|
+
Capture the requested route when you redirect to the sign-in route, then return to it after sign-in.
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
if (requireAuth && !isAuthenticated) {
|
|
82
|
+
const redirectState: AuthRedirectState = {
|
|
83
|
+
from: `${location.pathname}${location.search}`,
|
|
84
|
+
};
|
|
85
|
+
return <Navigate to="/auth" replace state={redirectState} />;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!requireAuth && isAuthenticated) {
|
|
89
|
+
return <Navigate to={resolveReturnPath(location.state)} replace />;
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Validate the captured route before navigating back to it.
|
|
94
|
+
Accept only same-origin application paths, and reject the sign-in route itself so sign-in cannot loop.
|
|
95
|
+
|
|
96
|
+
Keeping the sign-in route out of the state you persist is not the same thing.
|
|
97
|
+
A shared link needs both: never write the sign-in route into deep-link state, and carry the requested route across the sign-in redirect.
|
|
98
|
+
|
|
99
|
+
Templates that ship a route guard already carry the requested route through sign-in, so preserve that behavior as you add routes.
|
|
100
|
+
|
|
69
101
|
## Write state as the user navigates
|
|
70
102
|
|
|
71
103
|
Choose between the two writers by asking who caused the change.
|
|
@@ -167,6 +199,12 @@ Validate launch state before using it, and tolerate state written by a different
|
|
|
167
199
|
**`isSupported()` resolves to `undefined`.**
|
|
168
200
|
Either the app is not embedded in the Fabric portal, or deep linking has not reached this tenant yet.
|
|
169
201
|
Both are expected, and your app should fall back to its own routing.
|
|
202
|
+
Also check that the client does not set `targetOrigin`; pinning the portal origin silently prevents communication with the Fabric extension host.
|
|
203
|
+
|
|
204
|
+
**A shared link opens the default page instead of the shared view.**
|
|
205
|
+
The app restored the launch state and then replaced it.
|
|
206
|
+
Check the sign-in redirect first, because the recipient of a shared link is usually signed out.
|
|
207
|
+
See [Keep the restored route through sign-in](#keep-the-restored-route-through-sign-in).
|
|
170
208
|
|
|
171
209
|
**Writes reject with `STATE_TOO_LARGE`.**
|
|
172
210
|
The state exceeds the encoded budget the host reported.
|
|
@@ -62,6 +62,41 @@ npx rayfin up
|
|
|
62
62
|
|
|
63
63
|
If you are not signed in, the CLI launches an interactive login flow automatically.
|
|
64
64
|
|
|
65
|
+
### Prepare Fabric capacity
|
|
66
|
+
|
|
67
|
+
Before creating the Rayfin item, `rayfin up` checks whether the target workspace already has Fabric capacity.
|
|
68
|
+
If the workspace reports an assigned capacity, Rayfin uses it without changing or reevaluating the assignment.
|
|
69
|
+
|
|
70
|
+
On a first interactive deployment without a workspace target or `--capacity-id`, Rayfin asks you to choose:
|
|
71
|
+
|
|
72
|
+
1. `Use new workspace [Recommended]` runs workspace and capacity readiness.
|
|
73
|
+
2. `Select existing workspace` skips capacity readiness and opens the accessible-workspace picker.
|
|
74
|
+
|
|
75
|
+
Explicit workspace options and recorded deployments continue directly to their existing targeting flow without showing this choice.
|
|
76
|
+
Dry-run invocations do not show the choice.
|
|
77
|
+
An interactive invocation with `--capacity-id <id>` automatically prepares a new workspace and assigns that capacity without showing the workspace choice.
|
|
78
|
+
An untargeted non-interactive invocation automatically prepares a new workspace without prompting.
|
|
79
|
+
Pass `--capacity-id <id>` to use a specific capacity for that new workspace.
|
|
80
|
+
Pass an existing workspace target to deploy there instead.
|
|
81
|
+
|
|
82
|
+
When the workspace needs capacity, an interactive deployment asks for confirmation before assigning the selected or trial capacity.
|
|
83
|
+
Pass `--yes` to approve a deterministic capacity assignment without the prompt:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx rayfin up --yes
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
To select a specific existing capacity, pass its Fabric capacity ID.
|
|
90
|
+
This explicitly approves assigning that capacity:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx rayfin up --capacity-id <capacity-guid>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Do not combine `--capacity-id` with `--workspace`, `--workspace-id`, or `--workspace-uri`.
|
|
97
|
+
If multiple premium capacities are available, select one explicitly with `--capacity-id`.
|
|
98
|
+
An existing recorded deployment keeps its current workspace capacity and ignores a newly supplied capacity ID.
|
|
99
|
+
|
|
65
100
|
### Choose a unique Fabric item name
|
|
66
101
|
|
|
67
102
|
By default, `rayfin up` uses the project ID from `rayfin.yml` as the Fabric item name.
|
|
@@ -84,7 +119,7 @@ npx rayfin up \
|
|
|
84
119
|
--output json
|
|
85
120
|
```
|
|
86
121
|
|
|
87
|
-
|
|
122
|
+
The `--yes` option also approves reuse of an existing same-named item, so use it only when both automatic capacity assignment and item reuse are acceptable.
|
|
88
123
|
|
|
89
124
|
### What `rayfin up` does
|
|
90
125
|
|
|
@@ -107,7 +142,9 @@ After deployment, the CLI prints:
|
|
|
107
142
|
|
|
108
143
|
Each deployment is recorded in `rayfin/.deployments.json` (the registry of every workspace you have deployed to from this project), and the corresponding `RAYFIN_PUBLIC_*` variables are merged into `rayfin/.env` so subsequent commands and your frontend pick up the same values.
|
|
109
144
|
|
|
110
|
-
For frontend frameworks, the CLI
|
|
145
|
+
For frontend frameworks, the CLI refreshes a framework-specific `.env.local` (for example, for Vite) before the static build.
|
|
146
|
+
Detection and environment generation use the frontend directory selected by `services.staticHosting.path` and its optional `root`, while the public deployment values come from the project's `rayfin/.env`.
|
|
147
|
+
If detection or environment generation fails, the deployment reports a warning with guidance instead of treating it as a successful refresh.
|
|
111
148
|
|
|
112
149
|
```text title="rayfin/.deployments.json"
|
|
113
150
|
{
|
|
@@ -165,9 +202,23 @@ services:
|
|
|
165
202
|
Use `-n, --dry-run` to see what the CLI would do without creating or modifying any resources:
|
|
166
203
|
|
|
167
204
|
```bash
|
|
168
|
-
npx rayfin up -n
|
|
205
|
+
npx rayfin up -n --workspace-id <workspace-id>
|
|
169
206
|
```
|
|
170
207
|
|
|
208
|
+
Preview validates deterministic local static-hosting inputs before authentication or remote lookup.
|
|
209
|
+
The configured frontend `path` and optional build `root` must exist and be directories.
|
|
210
|
+
When `buildCommand` is configured, the output `folder` may be missing because the build has not run yet.
|
|
211
|
+
Without a build command, the output folder must already exist and contain files.
|
|
212
|
+
Static input checks are skipped when static hosting is disabled or excluded.
|
|
213
|
+
|
|
214
|
+
After local validation, preview uses the same authentication and workspace-selection rules as deployment.
|
|
215
|
+
It makes read-only Fabric requests to resolve the current workspace display name and ID, showing both before the planned operations.
|
|
216
|
+
With `--json`, these values are available as `plan.workspaceName` and `plan.workspaceId`.
|
|
217
|
+
If the workspace cannot be resolved, preview exits nonzero without creating or modifying resources.
|
|
218
|
+
|
|
219
|
+
Preview does not run builds, provision an item, apply settings or schemas, or update project deployment files.
|
|
220
|
+
A successful preview is not a build result or a guarantee that remote deployment operations will succeed.
|
|
221
|
+
|
|
171
222
|
### Skip specific services
|
|
172
223
|
|
|
173
224
|
Use `--exclude-services <names>` to skip the build/package/deploy phase for supported services without touching the rest of the deployment.
|
|
@@ -28,6 +28,15 @@ If you do not already know the workspace and item IDs, run [`connector search`](
|
|
|
28
28
|
| `-y, --yes` | no | Auto-accept overwrite and confirmation prompts (non-interactive). |
|
|
29
29
|
| `-v, --verbose` | no | Verbose diagnostics. |
|
|
30
30
|
|
|
31
|
+
## Authentication
|
|
32
|
+
|
|
33
|
+
`connector add` writes `auth.type: application` for Category A connectors: `fabric-sqlanalytics`, `fabric-warehouse`, and `fabric-sqldatabase`.
|
|
34
|
+
The connector accesses the data source with the app's identity rather than the signed-in end user's identity.
|
|
35
|
+
For per-user data-source access, explicitly set `auth.type: delegated` in `rayfin.yml` before deploying.
|
|
36
|
+
|
|
37
|
+
Category B connectors continue to require `auth.type: delegated`.
|
|
38
|
+
Existing declarations are not migrated, and omitting `auth.type` remains a validation error.
|
|
39
|
+
|
|
31
40
|
## Scoping operations
|
|
32
41
|
|
|
33
42
|
Without `--operations`, `connector add` writes **every** operation the catalog allows for the type. Prefer scoping at add time over hand-editing YAML afterwards:
|
|
@@ -46,7 +55,7 @@ connectors:
|
|
|
46
55
|
workspaceId: ${WS_ID}
|
|
47
56
|
itemId: ${ITEM_ID}
|
|
48
57
|
auth:
|
|
49
|
-
type:
|
|
58
|
+
type: application
|
|
50
59
|
operations:
|
|
51
60
|
- name: read
|
|
52
61
|
- name: update
|
|
@@ -97,6 +106,7 @@ With `--json`, the same information is available under `install`:
|
|
|
97
106
|
|
|
98
107
|
Running `connector add` against a name already in `rayfin.yml` refreshes the declaration.
|
|
99
108
|
It prompts before overwriting, or requires `--yes` when non-interactive.
|
|
109
|
+
This rewrites `auth.type` to the catalog default, so reapply an explicit `delegated` setting for a Category A connector after re-adding it if needed.
|
|
100
110
|
|
|
101
111
|
Your generated entity files under `rayfin/connectors/<name>/` are **preserved**.
|
|
102
112
|
Only `metadata.json` is rewritten, by schema discovery.
|
|
@@ -35,7 +35,7 @@ The commands available to a connector, and the code you write against it, depend
|
|
|
35
35
|
|
|
36
36
|
| | Category A — GraphQL entity connectors | Category B — function-bridge connectors |
|
|
37
37
|
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
|
38
|
-
| **Types** | `fabric-sqlanalytics`, `fabric-warehouse`, `fabric-sqldatabase
|
|
38
|
+
| **Types** | `fabric-sqlanalytics`, `fabric-warehouse`, `fabric-sqldatabase` | `fabric-semanticmodel`; `kusto` (**experimental**) |
|
|
39
39
|
| **App surface** | Generated entity files with typed CRUD through the data client | Named operations carrying raw queries |
|
|
40
40
|
| **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 |
|
|
41
41
|
| **Auth** | `delegated` or configured per project | Must be `delegated` |
|
|
@@ -54,11 +54,44 @@ Applies to `--entity` mode only.
|
|
|
54
54
|
|
|
55
55
|
Applies to `--entity` and `--query` modes.
|
|
56
56
|
|
|
57
|
-
- **SQL** — must start with `SELECT` or `WITH`;
|
|
57
|
+
- **SQL** — must start with `SELECT` or `WITH`; an embedded `;` is rejected while a trailing `;` is allowed; rejects `INSERT`, `UPDATE`, `DELETE`, `MERGE`, `CREATE`, `ALTER`, `DROP`, `TRUNCATE`, `EXEC`/`EXECUTE`, and `INTO` anywhere outside a string literal.
|
|
58
|
+
- **SQL result contract** — the query must produce one result set. If Tedious emits a second result set, inspection rejects the query instead of combining rows with a different column contract.
|
|
58
59
|
- **DAX** — must start with `EVALUATE`.
|
|
59
60
|
- `--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.
|
|
60
61
|
- `--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.
|
|
61
62
|
|
|
63
|
+
## SQL column types and values
|
|
64
|
+
|
|
65
|
+
SQL inspection reads column types from Tedious result metadata, including when a query returns zero rows.
|
|
66
|
+
It never guesses a column type from row values.
|
|
67
|
+
Plain output lists each column as `name (type)` before populated or empty results.
|
|
68
|
+
If the contract exceeds the terminal width, it folds between column entries.
|
|
69
|
+
|
|
70
|
+
The `columns[].type` field in JSON uses this normalized vocabulary:
|
|
71
|
+
|
|
72
|
+
| Normalized type | Tedious metadata types |
|
|
73
|
+
| ------------------ | ------------------------------------------------------------------------ |
|
|
74
|
+
| `integer` | `TinyInt`, `SmallInt`, `Int`, `BigInt`, `IntN` |
|
|
75
|
+
| `decimal` | `Decimal`, `Numeric`, money types, and their nullable forms |
|
|
76
|
+
| `floating-point` | `Real`, `Float`, `FloatN` |
|
|
77
|
+
| `text` | Character and Unicode text types, plus `Xml` |
|
|
78
|
+
| `boolean` | `Bit`, `BitN` |
|
|
79
|
+
| `date` | `Date` |
|
|
80
|
+
| `time` | `Time` |
|
|
81
|
+
| `datetime` | `SmallDateTime`, `DateTime`, `DateTimeN`, `DateTime2`, `DateTimeOffset` |
|
|
82
|
+
| `uniqueidentifier` | `UniqueIdentifier` |
|
|
83
|
+
| `binary` | `Binary`, `VarBinary`, `Image` |
|
|
84
|
+
| `unknown` | `Null`, `Variant`, `UDT`, `TVP`, and unrecognized or custom types |
|
|
85
|
+
|
|
86
|
+
Plain output renders SQL `date` values as `YYYY-MM-DD`, so the calendar value does not shift with the local time zone.
|
|
87
|
+
SQL `time` values render as the UTC time portion `HH:mm:ss.sss`, without Tedious' internal 1970 date anchor.
|
|
88
|
+
SQL `datetime` and `datetime2` are timezone-naive values that Tedious represents using a JavaScript `Date`; plain and JSON output therefore use an ISO value with `Z` by driver convention.
|
|
89
|
+
SQL `datetimeoffset` is also returned as a JavaScript `Date`, so its original offset is not preserved.
|
|
90
|
+
SQL `bigint` row values are strings, while decimal and numeric row values are JavaScript numbers and can carry JavaScript precision limitations.
|
|
91
|
+
Binary and buffer-backed custom values render as terminal-safe `0x` hexadecimal in plain output and use the existing column-width truncation marker when needed.
|
|
92
|
+
JSON row serialization is unchanged: JavaScript `Date` values remain ISO strings, while `columns[].type` now reports the metadata-derived normalized type instead of `unknown`.
|
|
93
|
+
Queries that produce a second SQL result set are rejected when the driver emits its second column contract, including newline-separated batches without semicolons.
|
|
94
|
+
|
|
62
95
|
## Examples
|
|
63
96
|
|
|
64
97
|
```bash
|
|
@@ -5,7 +5,7 @@ sidebar_position: 4
|
|
|
5
5
|
# connector invoke
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx rayfin connector invoke <connector-name> <operation> (--input '<json>' | --file <path>) [--verbose] [--json]
|
|
8
|
+
npx rayfin connector invoke <connector-name> <operation> (--input '<json>' | --file <path>) [--output-file <path>] [--max-inline-bytes <bytes>] [--verbose] [--json]
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
`connector invoke` runs a single named operation against a configured connector and prints the result. It is the loop for exercising [Category B connectors](./index.md#two-categories-of-connector) — `executeQuery` over DAX or KQL — without writing any app code.
|
|
@@ -50,6 +50,8 @@ Two transports, chosen by connector type:
|
|
|
50
50
|
|
|
51
51
|
Success emits `{status: 'ok', connector, operation, output}`. In non-JSON modes it prints `✅ Invoked <name>.<operation>` followed by the output.
|
|
52
52
|
|
|
53
|
+
A result larger than 8 KB is written to a file instead of being printed whole; see [Large results](#large-results).
|
|
54
|
+
|
|
53
55
|
What `output` holds depends on the connector. `fabric-semanticmodel` normalises inside its `invoke` middleware, so `output` is already a discriminated result rather than the raw service envelope: `{status: 'success', table, requestId}`, where `table.columns` are `{name, dataType}` and `table.rows` are column-aligned arrays. No caller-side conversion is needed, and the same shape comes back whether the operation ran locally or through the deployed item.
|
|
54
56
|
|
|
55
57
|
A resolved call is **not** automatically a success, and the failure signal depends on the same distinction. A connector that normalises reports Power BI failures — expired token, missing Build permission, throttling — as `{status: 'error', error, requestId}`, where `error` carries `category`, `message`, and optional `code` and `details`. A connector that returns the raw envelope reports failure as `status: 'Failed'` instead. The CLI reads both, converts either into a non-zero exit, and surfaces the service-supplied request id for tracing.
|
|
@@ -82,6 +84,56 @@ For example, an invalid DAX query exits with code `1` and can emit:
|
|
|
82
84
|
Read `connectorError.code` and `connectorError.details` rather than parsing the display string.
|
|
83
85
|
Service diagnostics may contain query or model content; review them before sharing or recording them in logs.
|
|
84
86
|
|
|
87
|
+
## Large results
|
|
88
|
+
|
|
89
|
+
A query has no upper bound on how much it returns, and printing a multi-megabyte result set floods a terminal — or, when an agent runs the CLI and reads its stdout, burns the agent's context window on rows it cannot use.
|
|
90
|
+
|
|
91
|
+
When the serialized result exceeds **8 KB**, the full payload is written to a file and `output` carries only a preview.
|
|
92
|
+
|
|
93
|
+
That threshold is a token budget, not a byte intuition.
|
|
94
|
+
Connector output tokenizes at roughly 2.8 characters per token, and numeric table data at about 1.8, so 8 KB is around 3k–4.5k tokens — a reasonable cost for one probe.
|
|
95
|
+
For scale, 256 KB of the same data is 93,000–144,000 tokens, which is most of a typical context window.
|
|
96
|
+
|
|
97
|
+
The preview samples bulk data but preserves metadata: arrays of **50 or fewer** entries pass through whole, longer arrays keep their first 20 entries, and long strings are cut.
|
|
98
|
+
That rule is what keeps a column list intact — a sampled column list would report a partial schema with nothing marking it partial, so a caller asking what a query returns would get a confident wrong answer.
|
|
99
|
+
If a 20-entry sample would itself exceed the threshold, the sample shrinks (10, 5, 2, 1) until it fits; only if no setting fits does `output` become `null`.
|
|
100
|
+
|
|
101
|
+
The envelope gains these fields, so this is detectable rather than silent:
|
|
102
|
+
|
|
103
|
+
| Field | Meaning |
|
|
104
|
+
| ----------------- | ------------------------------------------------------------ |
|
|
105
|
+
| `outputFile` | Absolute path the full result was written to. |
|
|
106
|
+
| `outputBytes` | Serialized size of the full result, in bytes. |
|
|
107
|
+
| `outputTruncated` | `true` when `output` is a preview rather than the whole result. |
|
|
108
|
+
| `previewItems` | Entries kept from each sampled array, or `0` when `output` is `null`. |
|
|
109
|
+
|
|
110
|
+
Read `outputFile` instead of re-running the query.
|
|
111
|
+
The file holds exactly what `output` would have held, so it can be passed straight to `jq` or opened by an agent.
|
|
112
|
+
|
|
113
|
+
Spilled results are written to `<project-root>/rayfin/.temp/invoke-results/` with owner-only permissions, and are pruned after 14 days or 20 files, whichever comes first.
|
|
114
|
+
`rayfin/.temp/` is the CLI's existing scratch directory and is covered by the scaffolded `.gitignore`, so query results — which are customer data — cannot be committed by a stray `git add`.
|
|
115
|
+
|
|
116
|
+
Two flags control this:
|
|
117
|
+
|
|
118
|
+
- `--max-inline-bytes <bytes>` — change the threshold. `0` restores the old behavior and always prints the result in full.
|
|
119
|
+
- `--output-file <path>` — always write the full result to `<path>`, whatever its size. The inline result is still shown in full unless it also crosses the threshold.
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"status": "ok",
|
|
124
|
+
"connector": "mymodel",
|
|
125
|
+
"operation": "executeQuery",
|
|
126
|
+
"output": { "status": "success", "table": { "columns": [], "rows": [] } },
|
|
127
|
+
"outputFile": "/path/to/app/rayfin/.temp/invoke-results/2026-09-21T101500.123Z-mymodel-executequery-1a2b3c4d.json",
|
|
128
|
+
"outputBytes": 4821004,
|
|
129
|
+
"outputTruncated": true,
|
|
130
|
+
"previewItems": 20
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If the file cannot be written, the command still succeeds with a truncated `output` and warns — falling back to printing the whole payload would recreate the problem this exists to prevent.
|
|
135
|
+
An explicit `--output-file` that cannot be written fails instead, because the caller named that path.
|
|
136
|
+
|
|
85
137
|
## Examples
|
|
86
138
|
|
|
87
139
|
```bash
|
|
@@ -93,6 +145,9 @@ npx rayfin connector invoke --name mymodel --operation executeQuery --file ./pay
|
|
|
93
145
|
|
|
94
146
|
# Machine-readable (no --verbose allowed alongside)
|
|
95
147
|
npx rayfin connector invoke mymodel executeQuery --input '{"query":"EVALUATE TOPN(1, Sales)"}' --json
|
|
148
|
+
|
|
149
|
+
# Send the full result to a known path instead of hunting for the spill file
|
|
150
|
+
npx rayfin connector invoke mymodel executeQuery --file ./payload.json --output-file ./result.json --json
|
|
96
151
|
```
|
|
97
152
|
|
|
98
153
|
## Errors
|
|
@@ -106,3 +161,5 @@ npx rayfin connector invoke mymodel executeQuery --input '{"query":"EVALUATE TOP
|
|
|
106
161
|
| `missing workspaceId/itemId in rayfin.yml` | Add both under `config:`, or re-run [`connector add`](./add.md). |
|
|
107
162
|
| `Access token has the wrong audience for the Power BI query API` | Unset or replace `RAYFIN_TOKEN`, or re-run without `--json` to consent interactively. |
|
|
108
163
|
| `No remote endpoint configured` | The non-semantic-model transport needs a deployed item — run `npx rayfin up` first. |
|
|
164
|
+
| `Invalid --max-inline-bytes value` | Pass a non-negative whole number of bytes, or `0` to always print inline. |
|
|
165
|
+
| `Could not write the result to <path>` | Point `--output-file` at a writable path, or drop the flag to use the default location. |
|
|
@@ -14,6 +14,10 @@ npx rayfin up functions deploy [-v | --verbose] [--skip-build] [--json]
|
|
|
14
14
|
|
|
15
15
|
`npx rayfin up` already deploys functions as part of a full deployment. Use `up functions deploy` when you want to run **only** the functions step — for example to retry after a functions deploy failed, or to push a functions-only change without redeploying the rest of the app.
|
|
16
16
|
|
|
17
|
+
This standalone command uploads function code; it does not validate or apply `services.functions.auth.type` from YAML or migrate the remote Functions auth mode.
|
|
18
|
+
After setting `services.functions.auth.type: application` for an existing app, run a full `npx rayfin up` to apply project settings.
|
|
19
|
+
See [Application authentication](../../functions/index.md#application-authentication).
|
|
20
|
+
|
|
17
21
|
## Prerequisites
|
|
18
22
|
|
|
19
23
|
Run `npx rayfin up` at least once first. This command deploys to an existing remote item, so a remote endpoint must already exist. If there is no active deployment, run a full `npx rayfin up`.
|
|
@@ -35,4 +39,4 @@ Run `npx rayfin up` at least once first. This command deploys to an existing rem
|
|
|
35
39
|
|
|
36
40
|
- [`functions init`](./init.md) — scaffold and enable functions.
|
|
37
41
|
- [`dev functions apply`](./dev-apply.md) — run and debug functions locally before deploying.
|
|
38
|
-
- [Managing Secrets](../secrets.md) — push secrets that deployed functions read via `ctx.
|
|
42
|
+
- [Managing Secrets](../secrets.md) — push secrets that deployed functions read via `ctx.Secrets`.
|
|
@@ -4,7 +4,8 @@ sidebar_position: 2
|
|
|
4
4
|
|
|
5
5
|
# dev functions apply
|
|
6
6
|
|
|
7
|
-
Start the local Rayfin functions runtime against your active deployment, with
|
|
7
|
+
Start the local Rayfin functions runtime against your active deployment, with automatic recompilation when a `build:watch` script is configured, a live typegen watcher, and debugger support.
|
|
8
|
+
This is the command you run while developing and debugging functions.
|
|
8
9
|
|
|
9
10
|
```bash
|
|
10
11
|
npx rayfin dev functions apply [--port <port>] [--inspect-port <port>] [--no-debug] [--no-emit-env]
|
|
@@ -34,20 +35,44 @@ npx rayfin dev functions apply [--port <port>] [--inspect-port <port>] [--no-deb
|
|
|
34
35
|
5. Preserves the existing same-origin adapter in bundled Vite templates.
|
|
35
36
|
For recognized older or custom Vite clients, the first run patches `functionsBaseUrl` to read the generated URL only during development.
|
|
36
37
|
6. Builds the functions project, runs a one-shot typegen, then starts a visible **typegen watcher** (`[typegen]` prefix) that keeps `src/types.ts` in sync as you edit `function_app.ts`.
|
|
37
|
-
7. Starts `func start`
|
|
38
|
+
7. Starts `func start` alongside the package's `npm run build:watch` compiler watcher when configured, and writes a `.vscode/launch.json` **"Functions: Attach"** configuration for debugging.
|
|
38
39
|
|
|
39
|
-
Press `Ctrl+C` to stop the host and
|
|
40
|
+
Press `Ctrl+C` to stop the host and watchers.
|
|
40
41
|
This command does not start the frontend.
|
|
41
42
|
Run the Vite frontend separately to invoke local functions through `/.rayfin/api/<name>`, or use `npx rayfin dev` to start both together.
|
|
42
43
|
If the local Functions host is unavailable, the Vite adapter returns HTTP 502 instead of invoking deployed function code.
|
|
43
44
|
|
|
45
|
+
This standalone command does not validate or apply the project's Functions auth setting.
|
|
46
|
+
Full `npx rayfin up` and normal `npx rayfin dev` perform that validation when applying project settings.
|
|
47
|
+
Run a full `npx rayfin up` to apply [`services.functions.auth.type: application`](../../functions/index.md#application-authentication) to the remote app.
|
|
48
|
+
For local token identity, see [Local development](../../functions/connections/index.md#local-development).
|
|
49
|
+
|
|
50
|
+
## Automatic recompilation
|
|
51
|
+
|
|
52
|
+
Both `npx rayfin dev functions apply` and `npx rayfin dev` build the functions package once, then run its `build:watch` script alongside the local Functions host if the script is configured.
|
|
53
|
+
Both commands use `services.functions.path` from `rayfin.yml` and preserve `services.functions.buildCommand` for the initial build.
|
|
54
|
+
|
|
55
|
+
To enable automatic recompilation, define a long-running `build:watch` script in the functions package's `package.json`; the TypeScript scaffold uses `"build:watch": "tsc --build --watch"`.
|
|
56
|
+
If you use a custom compiler or bundler, set that script to its watch command instead.
|
|
57
|
+
Source edits are compiled into `dist`, which the host watches to reload handlers.
|
|
58
|
+
The separate typegen watcher keeps `src/types.ts` up to date and does not rewrite the file when the generated types are unchanged.
|
|
59
|
+
|
|
60
|
+
If `build:watch` is absent, the CLI warns and starts the host without a compiler watcher; run the functions package's build command manually after source edits.
|
|
61
|
+
Type generation remains enabled without a compiler watcher.
|
|
62
|
+
An invalid watch script or an unreadable package manifest remains an error.
|
|
63
|
+
An initial build failure prevents host startup; later compiler diagnostics can be fixed without restarting the session.
|
|
64
|
+
If the compiler watcher exits, the session stops rather than serving stale code.
|
|
65
|
+
|
|
66
|
+
Core Tools owns worker reloads; edits made while it is restarting can occasionally leave a stale handler running.
|
|
67
|
+
If the response remains stale after compilation finishes, restart the dev session.
|
|
68
|
+
|
|
44
69
|
## Debugging
|
|
45
70
|
|
|
46
71
|
With debugging enabled (default), attach your debugger to the inspector port (`9229` by default) using the generated **"Functions: Attach"** launch configuration in VS Code. Pass `--no-debug` to run without the inspector.
|
|
47
72
|
|
|
48
73
|
## Secrets in local development
|
|
49
74
|
|
|
50
|
-
Locally there is no deployed secret bag, so `ctx.
|
|
75
|
+
Locally there is no deployed secret bag, so `ctx.Secrets.<NAME>` falls back to `process.env`. To provide a secret, add it under `Values` in `rayfin/functions/local.settings.json`; the functions host loads those entries into `process.env`. See [Managing Secrets](../secrets.md#using-secrets-in-local-development).
|
|
51
76
|
|
|
52
77
|
## Next step
|
|
53
78
|
|
|
@@ -60,3 +85,4 @@ npx rayfin up functions deploy
|
|
|
60
85
|
```
|
|
61
86
|
|
|
62
87
|
See [`up functions deploy`](./deploy.md).
|
|
88
|
+
The standalone deployment uploads function code; it does not apply YAML auth settings or migrate the remote Functions auth mode.
|
|
@@ -7,6 +7,8 @@ sidebar_position: 4
|
|
|
7
7
|
Rayfin functions are server-side user-defined functions (UDFs) that run in the Fabric runtime and are invocable from your frontend through `RayfinClient`. Use them for logic that must run on the backend — secrets and API keys, privileged data access, server-side validation, and anything that should not be exposed or tampered with in client code.
|
|
8
8
|
|
|
9
9
|
The functions project lives at `rayfin/functions/` and is enabled by the `services.functions.enabled` flag in `rayfin.yml` (set for you the first time you run [`functions init`](./init.md)).
|
|
10
|
+
Enabled Functions also require explicit `services.functions.auth.type: application`, which new scaffolds set.
|
|
11
|
+
See [Application authentication](../../functions/index.md#application-authentication) for existing-app configuration and downstream resource permissions.
|
|
10
12
|
|
|
11
13
|
Each command has its own reference page:
|
|
12
14
|
|
|
@@ -34,8 +36,8 @@ functions init → write UDFs in src/function_app.ts → dev functions apply
|
|
|
34
36
|
- `rayfin/functions/src/function_app.ts` — where you register UDFs with `udf.func()`.
|
|
35
37
|
- `rayfin/functions/src/types.ts` — auto-generated `AppFunctionsSchema`; regenerated by `functions init` (one-shot) and by the watcher inside `dev functions apply`.
|
|
36
38
|
- `rayfin/functions/{package.json,host.json,tsconfig.json,local.settings.json}` — the functions app manifest, host config, TypeScript project references, and local settings.
|
|
37
|
-
- `rayfin.yml` — the `services.functions` block (`enabled`, `buildCommand`).
|
|
39
|
+
- `rayfin.yml` — the `services.functions` block (`enabled`, `auth.type`, `buildCommand`).
|
|
38
40
|
|
|
39
41
|
## Secrets
|
|
40
42
|
|
|
41
|
-
Functions read secrets at runtime
|
|
43
|
+
Functions read secrets at runtime as typed properties on `ctx.Secrets`, backed by the host secret bag with a `process.env` fallback. Manage remote secrets with `npx rayfin secret set` — or bulk-set them from a file with `npx rayfin secret set --env-file` — see [Managing Secrets](../secrets.md).
|
|
@@ -24,12 +24,24 @@ Run this from a directory that already contains a `rayfin/` project (i.e. you ha
|
|
|
24
24
|
## What it does
|
|
25
25
|
|
|
26
26
|
1. **Scaffolds** `rayfin/functions/` with a starter function app, `host.json`, `tsconfig.json`, `package.json`, and `local.settings.json`.
|
|
27
|
-
2. **Enables the service** in `rayfin.yml` by setting `services.functions.enabled: true` and `services.functions.buildCommand: 'npm run build'`.
|
|
27
|
+
2. **Enables the scaffolded service** in `rayfin.yml` by setting `services.functions.enabled: true`, `services.functions.auth.type: application`, and `services.functions.buildCommand: 'npm run build'`.
|
|
28
28
|
3. **Installs dependencies** for the functions project.
|
|
29
29
|
4. **Builds** the project.
|
|
30
30
|
5. **Generates types** — runs a one-shot typegen to produce `rayfin/functions/src/types.ts` (the `AppFunctionsSchema`).
|
|
31
31
|
6. **Installs AI agent files** so assistants understand the functions surface.
|
|
32
32
|
|
|
33
|
+
Enabled Functions require explicit application authentication.
|
|
34
|
+
For existing apps, see [Application authentication](../../functions/index.md#application-authentication) for the configuration and full-deployment requirement.
|
|
35
|
+
|
|
36
|
+
## Runtime version
|
|
37
|
+
|
|
38
|
+
Fresh and forced scaffolds pin `@microsoft/fabric-user-data-functions` to the exact version of the running Rayfin CLI, matching connector scaffolding.
|
|
39
|
+
This also applies when `rayfin init` scaffolds the Functions service.
|
|
40
|
+
|
|
41
|
+
The running CLI version may differ from the SDK version already installed in your app.
|
|
42
|
+
Run the CLI release you want the Functions runtime to match.
|
|
43
|
+
Re-running without `--force` preserves the existing Functions `package.json`, including any runtime version you selected.
|
|
44
|
+
|
|
33
45
|
## Scaffolded structure
|
|
34
46
|
|
|
35
47
|
```text
|
|
@@ -51,6 +63,9 @@ rayfin/
|
|
|
51
63
|
- **Without `--force`** on an existing project, it preserves your `function_app.ts` and only refreshes dependencies, build, and generated types.
|
|
52
64
|
- **With `--force`**, it overwrites the scaffold (a warning is shown before your files are replaced).
|
|
53
65
|
|
|
66
|
+
Re-running without `--force` does not rewrite the existing Functions auth setting.
|
|
67
|
+
Set `services.functions.auth.type: application` explicitly in an existing app rather than relying on a re-run to migrate it.
|
|
68
|
+
|
|
54
69
|
## Next step
|
|
55
70
|
|
|
56
71
|
Start the local host and typegen watcher:
|
package/assets/docs/cli/index.md
CHANGED
|
@@ -70,7 +70,7 @@ Functions are server-side user-defined functions (UDFs) that run in the Fabric r
|
|
|
70
70
|
| Command | Description |
|
|
71
71
|
| --- | --- |
|
|
72
72
|
| `npx rayfin functions init [directory]` | Scaffold `rayfin/functions/`, enable the functions service, install dependencies, build, and generate types. See [functions init](./functions/init.md). |
|
|
73
|
-
| `npx rayfin dev functions apply` | Run the local function host with
|
|
73
|
+
| `npx rayfin dev functions apply` | Run the local function host with an optional compiler watcher, live typegen, and debugger support. See [dev functions apply](./functions/dev-apply.md). |
|
|
74
74
|
| `npx rayfin up functions deploy` | Build, package, and deploy functions to the remote Rayfin item. `rayfin up` runs this automatically. See [up functions deploy](./functions/deploy.md). |
|
|
75
75
|
|
|
76
76
|
### Connectors
|
|
@@ -89,7 +89,7 @@ Connectors let a Rayfin app read from — and, for some types, write to — Micr
|
|
|
89
89
|
|
|
90
90
|
### Secrets
|
|
91
91
|
|
|
92
|
-
Secrets are encrypted values stored on your deployed Rayfin item and read at runtime — for example by [functions](./functions/index.md) via `ctx.
|
|
92
|
+
Secrets are encrypted values stored on your deployed Rayfin item and read at runtime — for example by [functions](./functions/index.md) via `ctx.Secrets`. See [Managing Secrets](./secrets.md) for the full guide.
|
|
93
93
|
|
|
94
94
|
| Command | Description |
|
|
95
95
|
| --- | --- |
|
|
@@ -129,18 +129,30 @@ export RAYFIN_TELEMETRY_OPTOUT=1
|
|
|
129
129
|
|
|
130
130
|
## Diagnostic logs
|
|
131
131
|
|
|
132
|
-
`npx rayfin up
|
|
132
|
+
`npx rayfin up`, workflow-based `npx rayfin dev`, and `npx rayfin dev functions apply` record detailed diagnostics under `~/.rayfin/logs/` even when `--verbose` is absent, including when using `--json` or `--output json`.
|
|
133
133
|
After a failure, open the file identified by `Diagnostic log:` to inspect the original invocation without rerunning it.
|
|
134
134
|
JSON failures include the same path in the `diagnosticLog` field of the single result object.
|
|
135
135
|
`dev` JSON failures also include a `hint` with recovery guidance, including provider/configuration preflight errors and unexpected failures.
|
|
136
136
|
|
|
137
|
-
Adding `--verbose` also mirrors diagnostic records to stderr while
|
|
137
|
+
Adding `--verbose` also mirrors diagnostic records to stderr while these commands run.
|
|
138
138
|
The CLI rejects combining `--verbose` with `--json` or `--output json`; detailed diagnostics are still recorded in the log file without `--verbose`.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
Other standalone subcommands and Docker maintenance flags such as `dev --stop` do not record these logs.
|
|
140
|
+
|
|
141
|
+
Local Functions sessions show function endpoints, the debugger address, application output, and warnings or errors by default.
|
|
142
|
+
Recognized host startup and configuration detail, HTTP request metadata, and successful initial build output are kept in diagnostics; use `--verbose` to mirror that detail to the terminal.
|
|
143
|
+
When the initial build fails, human output includes a bounded tail of compiler output, and JSON errors include it in `buildOutput`.
|
|
144
|
+
The tail retains up to 100 complete lines and 64 KiB, with an explicit marker when earlier output is omitted.
|
|
145
|
+
Verbose mode does not replay the same compiler output a second time.
|
|
146
|
+
Terminal output preserves stack-frame paths and line numbers, while masking credentials and email addresses.
|
|
147
|
+
Application lines up to 16 KiB are preserved; oversized lines are replaced with an explicit truncation marker.
|
|
148
|
+
Persistent diagnostic logs continue to apply their separate privacy and size limits.
|
|
149
|
+
Failed HTTP responses show their status and, when request metadata is available, the method and path without query strings.
|
|
150
|
+
Unrecognized output remains visible.
|
|
151
|
+
Frontend output is unchanged.
|
|
152
|
+
Both `dev` and `dev functions apply` flush their logs after cleanup on Ctrl-C, runtime failure, or normal completion.
|
|
142
153
|
Piped runtime and build output is captured with a 1 MiB limit per stream.
|
|
143
|
-
Interactive
|
|
154
|
+
Interactive Functions sessions keep standard input attached for keyboard interaction, while stdout and stderr are piped for filtering and diagnostic capture.
|
|
155
|
+
Other interactive runtimes that inherit the terminal keep their keyboard and TTY behavior; their console output is not captured, and the log records that limitation alongside lifecycle events.
|
|
144
156
|
|
|
145
157
|
Logs stay on your machine and are independent of telemetry opt-out.
|
|
146
158
|
The log directory is shared across projects on your machine, so the retention limits below apply across all projects using it.
|
|
@@ -4,7 +4,7 @@ sidebar_position: 50
|
|
|
4
4
|
|
|
5
5
|
# Managing Secrets
|
|
6
6
|
|
|
7
|
-
Secrets are encrypted values — API keys, connection strings, tokens — that your app needs at runtime but must never ship in client code. They are stored securely on your deployed Rayfin item and read on the server by [functions](./functions/index.md) via `ctx.
|
|
7
|
+
Secrets are encrypted values — API keys, connection strings, tokens — that your app needs at runtime but must never ship in client code. They are stored securely on your deployed Rayfin item and read on the server by [functions](./functions/index.md) via `ctx.Secrets`.
|
|
8
8
|
|
|
9
9
|
Manage secrets with the `npx rayfin secret` command group:
|
|
10
10
|
|
|
@@ -105,18 +105,28 @@ Deleting a secret that does not exist reports a not-found error — run `npx ray
|
|
|
105
105
|
|
|
106
106
|
## Reading secrets from functions
|
|
107
107
|
|
|
108
|
-
Server-side functions read secrets at runtime
|
|
108
|
+
Server-side functions read secrets at runtime as typed properties on `ctx.Secrets`, which resolve against the deployed item's secret bag and fall back to `process.env`. Set a secret with `npx rayfin secret set <name>`, then read it by the same name inside your handler:
|
|
109
109
|
|
|
110
110
|
```ts
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
import { type RayfinContext } from "@microsoft/fabric-user-data-functions";
|
|
112
|
+
|
|
113
|
+
udf.func(
|
|
114
|
+
"summarize",
|
|
115
|
+
async (ctx: RayfinContext<AppSchema>, input: { text: string }) => {
|
|
116
|
+
const apiKey = ctx.Secrets.OPENAI_KEY;
|
|
117
|
+
// ... call the API with apiKey
|
|
118
|
+
},
|
|
119
|
+
[],
|
|
120
|
+
);
|
|
115
121
|
```
|
|
116
122
|
|
|
123
|
+
The `RayfinContext<AppSchema>` annotation is what makes this type-safe. An unannotated `ctx` is contextually `any`, so `ctx.Secrets.OPENAI_KEY` compiles whether or not the secret is declared — and the annotation is also how typegen recognises the parameter as the injected context rather than a request-body argument.
|
|
124
|
+
|
|
125
|
+
Setting the secret is what types it: the CLI regenerates `rayfin/functions/src/secrets.generated.ts`, so `ctx.Secrets.OPENAI_KEY` is a `string` and an undeclared name is a compile error. See [Secrets](../functions/secrets.md) for the full model.
|
|
126
|
+
|
|
117
127
|
## Using secrets in local development
|
|
118
128
|
|
|
119
|
-
When you run functions locally with [`npx rayfin dev functions apply`](./functions/dev-apply.md), there is no deployed secret bag, so `ctx.
|
|
129
|
+
When you run functions locally with [`npx rayfin dev functions apply`](./functions/dev-apply.md), there is no deployed secret bag, so `ctx.Secrets.<NAME>` falls back to `process.env`. To make a secret available locally, add it under `Values` in `rayfin/functions/local.settings.json` — the Azure Functions host loads those entries into `process.env`:
|
|
120
130
|
|
|
121
131
|
```json
|
|
122
132
|
{
|
|
@@ -166,6 +176,6 @@ If `secret delete` reports the secret was not found:
|
|
|
166
176
|
|
|
167
177
|
## See also
|
|
168
178
|
|
|
169
|
-
- [Functions](./functions/index.md) — read secrets from server-side functions with `ctx.
|
|
179
|
+
- [Functions](./functions/index.md) — read secrets from server-side functions with `ctx.Secrets`.
|
|
170
180
|
- [CLI quickstart](./quickstart.md)
|
|
171
181
|
- [Environment configuration](./env-interpolation.md)
|