@microsoft/rayfin-guide 1.36.0-alpha.1593 → 1.36.0-alpha.1620
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/{experimental/cli → cli}/connectors/add.md +2 -0
- package/assets/docs/{experimental/cli → cli}/connectors/category-a-entities.md +1 -1
- package/assets/docs/{experimental/cli → cli}/connectors/category-b-function-bridge.md +38 -12
- package/assets/docs/cli/connectors/eventhouse.md +21 -0
- package/assets/docs/{experimental/cli → cli}/connectors/index.md +7 -22
- package/assets/docs/{experimental/cli → cli}/connectors/invoke.md +4 -0
- package/assets/docs/{experimental/cli → cli}/connectors/search.md +4 -2
- package/assets/docs/cli/environment-variables.md +2 -2
- package/assets/docs/cli/functions/deploy.md +38 -0
- package/assets/docs/cli/functions/dev-apply.md +62 -0
- package/assets/docs/cli/functions/index.md +41 -0
- package/assets/docs/cli/functions/init.md +62 -0
- package/assets/docs/cli/index.md +35 -1
- package/assets/docs/cli/secrets.md +97 -122
- package/assets/docs/cli/templates.md +7 -0
- package/assets/docs/functions/connections/add-ado.md +39 -0
- package/assets/docs/functions/connections/add-azure-resource.md +171 -0
- package/assets/docs/functions/connections/add-fabric-resource.md +186 -0
- package/assets/docs/functions/connections/add-foundry.md +46 -0
- package/assets/docs/functions/connections/add-work-iq.md +39 -0
- package/assets/docs/functions/connections/get-fabric-info.md +159 -0
- package/assets/docs/functions/connections/index.md +89 -0
- package/assets/docs/functions/index.md +91 -0
- package/assets/docs/functions/invoking-from-frontend.md +94 -0
- package/assets/docs/functions/secrets.md +70 -0
- package/assets/docs/functions/typegen.md +44 -0
- package/assets/docs/functions/writing-functions.md +140 -0
- package/assets/docs/getting-started/project-structure.md +91 -2
- package/package.json +1 -1
- /package/assets/docs/{experimental/cli → cli}/connectors/inspect.md +0 -0
|
@@ -4,193 +4,168 @@ sidebar_position: 50
|
|
|
4
4
|
|
|
5
5
|
# Managing Secrets
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
Secrets are encrypted and stored securely in your Rayfin item workload.
|
|
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.getSecret(name)`.
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
Manage secrets with the `npx rayfin secret` command group:
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
| Command | Description |
|
|
12
|
+
| ----------------------------------------- | ---------------------------------------------------- |
|
|
13
|
+
| `npx rayfin secret set <name>` | Set one secret (masked prompt or `--stdin`). |
|
|
14
|
+
| `npx rayfin secret set --env-file <path>` | Bulk-set every `KEY=VALUE` entry from a dotenv file. |
|
|
15
|
+
| `npx rayfin secret list` | List secret names and timestamps (never values). |
|
|
16
|
+
| `npx rayfin secret delete <name>` | Delete a secret. |
|
|
14
17
|
|
|
15
|
-
##
|
|
18
|
+
## Prerequisite: deploy first
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Create a `rayfin/.env` file with secrets prefixed using `RAYFIN_SECRET_`:
|
|
20
|
+
Secrets live on the remote Rayfin item, so you must deploy before managing them:
|
|
20
21
|
|
|
21
22
|
```bash
|
|
22
|
-
|
|
23
|
-
RAYFIN_SECRET_API_KEY=sk-prod-abc123xyz789
|
|
24
|
-
RAYFIN_SECRET_DATABASE_PASSWORD=secure-db-pass-123
|
|
25
|
-
RAYFIN_SECRET_AUTH_TOKEN=token-abcdefg-hijklmn
|
|
26
|
-
RAYFIN_SECRET_OPENAI_KEY=sk-openai-your-key-here
|
|
23
|
+
npx rayfin up
|
|
27
24
|
```
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
Every `secret` command resolves the remote endpoint from your active deployment. If none exists, the CLI stops with:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
❌ No remote endpoint configured
|
|
30
|
+
Run 'npx rayfin up' first to deploy your item to Fabric.
|
|
31
|
+
```
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
## Setting a secret
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
By default, `secret set` prompts for the value with masked input:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
npx rayfin
|
|
38
|
+
npx rayfin secret set OPENAI_KEY
|
|
39
|
+
# ? Enter secret value for "OPENAI_KEY" ********
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
### 3. Apply secrets
|
|
44
|
-
|
|
45
|
-
Apply your secrets to the remote workload:
|
|
42
|
+
For non-interactive use (CI, scripts), pipe the value in with `--stdin`:
|
|
46
43
|
|
|
47
44
|
```bash
|
|
48
|
-
npx rayfin
|
|
45
|
+
echo "sk-openai-your-key-here" | npx rayfin secret set OPENAI_KEY --stdin
|
|
49
46
|
```
|
|
50
47
|
|
|
51
|
-
|
|
52
|
-
1. Read your `rayfin/.env` file
|
|
53
|
-
2. Extract all `RAYFIN_SECRET_*` variables
|
|
54
|
-
3. Securely send each secret to your workload
|
|
55
|
-
4. Encrypt and persist the secrets
|
|
56
|
-
5. Validate that all secrets were successfully saved
|
|
57
|
-
|
|
58
|
-
### 4. Verify secrets
|
|
48
|
+
### Recording a description in `rayfin.yml`
|
|
59
49
|
|
|
60
|
-
|
|
50
|
+
Use `--describe` to record a human-readable description alongside the secret's metadata in `rayfin/rayfin.yml` (the value itself is never written to `rayfin.yml`). The flag **must** use the `=` syntax:
|
|
61
51
|
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
✓ Token acquired
|
|
65
|
-
📤 Sending 4 secret(s) to workload...
|
|
66
|
-
✓ Secrets sent to workload (4 persisted)
|
|
67
|
-
✅ Validating secrets persisted to workload...
|
|
68
|
-
✓ All secrets validated
|
|
69
|
-
|
|
70
|
-
✨ Secrets applied successfully (4/4)
|
|
71
|
-
✓ API_KEY
|
|
72
|
-
✓ DATABASE_PASSWORD
|
|
73
|
-
✓ AUTH_TOKEN
|
|
74
|
-
✓ OPENAI_KEY
|
|
52
|
+
```bash
|
|
53
|
+
npx rayfin secret set OPENAI_KEY --describe="OpenAI API key for the chat function"
|
|
75
54
|
```
|
|
76
55
|
|
|
77
|
-
|
|
56
|
+
Passing `--describe "..."` with a space is rejected — always use `--describe="..."`.
|
|
78
57
|
|
|
79
|
-
|
|
58
|
+
## Bulk-setting from a file
|
|
80
59
|
|
|
81
|
-
|
|
60
|
+
To set many secrets at once, keep them in a dotenv file and point `secret set` at it with `--env-file`:
|
|
82
61
|
|
|
83
62
|
```bash
|
|
84
|
-
|
|
63
|
+
# rayfin/.env.secrets
|
|
64
|
+
OPENAI_KEY=sk-openai-your-key-here
|
|
65
|
+
DATABASE_PASSWORD=secure-db-pass-123
|
|
66
|
+
AUTH_TOKEN=token-abcdefg-hijklmn
|
|
85
67
|
```
|
|
86
68
|
|
|
87
|
-
### JSON output
|
|
88
|
-
|
|
89
|
-
For automation or scripting, use `--json` for machine-readable output:
|
|
90
|
-
|
|
91
69
|
```bash
|
|
92
|
-
npx rayfin
|
|
70
|
+
npx rayfin secret set --env-file rayfin/.env.secrets
|
|
93
71
|
```
|
|
94
72
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
```json
|
|
98
|
-
{
|
|
99
|
-
"status": "success",
|
|
100
|
-
"message": "All secrets applied and validated",
|
|
101
|
-
"secretsCount": 4,
|
|
102
|
-
"persisted": 4,
|
|
103
|
-
"validated": true,
|
|
104
|
-
"secrets": [
|
|
105
|
-
{
|
|
106
|
-
"name": "API_KEY",
|
|
107
|
-
"id": "secret-123",
|
|
108
|
-
"createdAt": "2026-04-17T10:30:00Z"
|
|
109
|
-
}
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
```
|
|
73
|
+
Every `KEY=VALUE` line becomes a secret named `KEY` — there is **no prefix convention**; the key is used verbatim. Blank lines and `#` comments are ignored, and surrounding single or double quotes are stripped from values. Do not pass a `<name>` together with `--env-file`, and do not combine `--env-file` with `--stdin`.
|
|
113
74
|
|
|
114
|
-
|
|
75
|
+
> **Keep secret files out of version control.** Add your secrets file to `.gitignore` — it is for authoring only, never committed:
|
|
76
|
+
>
|
|
77
|
+
> ```bash
|
|
78
|
+
> echo "rayfin/.env.secrets" >> .gitignore
|
|
79
|
+
> ```
|
|
115
80
|
|
|
116
|
-
|
|
81
|
+
## Listing secrets
|
|
117
82
|
|
|
118
83
|
```bash
|
|
119
|
-
npx rayfin
|
|
84
|
+
npx rayfin secret list
|
|
120
85
|
```
|
|
121
86
|
|
|
122
|
-
|
|
87
|
+
Only names and created/updated timestamps are returned — values are never read back:
|
|
123
88
|
|
|
124
|
-
|
|
89
|
+
```text
|
|
90
|
+
📋 Secrets (3):
|
|
125
91
|
|
|
126
|
-
|
|
127
|
-
|
|
92
|
+
Name: OPENAI_KEY
|
|
93
|
+
Created: 4/17/2026, 10:30:00 AM
|
|
94
|
+
Last Updated: 4/17/2026, 10:30:00 AM
|
|
128
95
|
```
|
|
129
96
|
|
|
130
|
-
##
|
|
97
|
+
## Deleting a secret
|
|
131
98
|
|
|
132
|
-
|
|
99
|
+
```bash
|
|
100
|
+
npx rayfin secret delete OPENAI_KEY # prompts for confirmation
|
|
101
|
+
npx rayfin secret delete OPENAI_KEY --yes # skips the prompt (-y)
|
|
102
|
+
```
|
|
133
103
|
|
|
134
|
-
|
|
135
|
-
The workload endpoint encrypts and persists secrets securely.
|
|
136
|
-
Secrets are never logged or displayed after being sent to the workload.
|
|
104
|
+
Deleting a secret that does not exist reports a not-found error — run `npx rayfin secret list` to see what is currently stored.
|
|
137
105
|
|
|
138
|
-
|
|
106
|
+
## Reading secrets from functions
|
|
139
107
|
|
|
140
|
-
|
|
141
|
-
Add `.env` to your `.gitignore`:
|
|
108
|
+
Server-side functions read secrets at runtime with `ctx.getSecret(name)`, which resolves against the deployed item's secret bag and falls back to `process.env`. Set a secret with `npx rayfin secret set <name>`, then read it by the same name inside your handler:
|
|
142
109
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
110
|
+
```ts
|
|
111
|
+
udf.func("summarize", async (ctx, input: { text: string }) => {
|
|
112
|
+
const apiKey = ctx.getSecret("OPENAI_KEY");
|
|
113
|
+
// ... call the API with apiKey
|
|
114
|
+
});
|
|
115
|
+
```
|
|
146
116
|
|
|
147
|
-
|
|
117
|
+
## Using secrets in local development
|
|
148
118
|
|
|
149
|
-
|
|
150
|
-
export RAYFIN_SECRET_API_KEY=prod-key-from-vault
|
|
151
|
-
npx rayfin up secrets apply
|
|
152
|
-
```
|
|
119
|
+
When you run functions locally with [`npx rayfin dev functions apply`](./functions/dev-apply.md), there is no deployed secret bag, so `ctx.getSecret(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`:
|
|
153
120
|
|
|
154
|
-
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"IsEncrypted": false,
|
|
124
|
+
"Values": {
|
|
125
|
+
"OPENAI_KEY": "sk-local-dev-key"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
155
129
|
|
|
156
|
-
|
|
130
|
+
`npx rayfin dev functions apply` **merges** its own CLI-managed values into `local.settings.json` and preserves any keys you add, so your local secrets survive re-runs. Keep `local.settings.json` out of version control — it is for local development only.
|
|
157
131
|
|
|
158
|
-
##
|
|
132
|
+
## Automation and JSON output
|
|
159
133
|
|
|
160
|
-
|
|
134
|
+
Every `secret` command accepts the global `--json` flag for machine-readable output and `--verbose` for detailed logging:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx rayfin secret list --json
|
|
138
|
+
npx rayfin secret set OPENAI_KEY --stdin --json < key.txt
|
|
139
|
+
```
|
|
161
140
|
|
|
162
|
-
|
|
141
|
+
## Security notes
|
|
163
142
|
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
-
|
|
143
|
+
- Secrets are transmitted over HTTPS and encrypted at rest on the workload. They are never logged or displayed after being sent.
|
|
144
|
+
- `npx rayfin secret list` returns only names and timestamps — never values.
|
|
145
|
+
- Use separate secret values per environment, and rotate them by re-running `npx rayfin secret set` with the new value.
|
|
167
146
|
|
|
168
|
-
|
|
147
|
+
## Troubleshooting
|
|
169
148
|
|
|
170
|
-
|
|
149
|
+
### No remote endpoint configured
|
|
171
150
|
|
|
172
|
-
|
|
173
|
-
- Check that you have valid Entra ID credentials
|
|
174
|
-
- On containers or restricted environments, use `--encryption-fallback-enabled` or set `RAYFIN_ENCRYPTION_FALLBACK_ENABLED=true`
|
|
151
|
+
Run `npx rayfin up` first to deploy your item, then retry. Secrets cannot be managed before an initial deployment exists.
|
|
175
152
|
|
|
176
|
-
###
|
|
153
|
+
### Authentication failed
|
|
177
154
|
|
|
178
|
-
If
|
|
155
|
+
If acquiring a token fails:
|
|
179
156
|
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
- Run `npx rayfin up status` to confirm deployment health
|
|
183
|
-
- Re-run `npx rayfin up secrets apply` to retry
|
|
157
|
+
- Run `npx rayfin login` to sign in and confirm you have valid Entra ID credentials.
|
|
158
|
+
- On containers or restricted environments without an OS keychain, pass `--encryption-fallback-enabled` to allow plaintext token storage.
|
|
184
159
|
|
|
185
|
-
###
|
|
160
|
+
### Secret not found on delete
|
|
186
161
|
|
|
187
|
-
If
|
|
162
|
+
If `secret delete` reports the secret was not found:
|
|
188
163
|
|
|
189
|
-
-
|
|
190
|
-
-
|
|
191
|
-
- Run `npx rayfin login --select` to choose a different account/tenant
|
|
164
|
+
- It may already be deleted — run `npx rayfin secret list` to confirm.
|
|
165
|
+
- Secret management may not be enabled for the item; verify the deployment with `npx rayfin up status`.
|
|
192
166
|
|
|
193
167
|
## See also
|
|
194
168
|
|
|
169
|
+
- [Functions](./functions/index.md) — read secrets from server-side functions with `ctx.getSecret`.
|
|
195
170
|
- [CLI quickstart](./quickstart.md)
|
|
196
171
|
- [Environment configuration](./env-interpolation.md)
|
|
@@ -20,6 +20,13 @@ Every `npm create @microsoft/rayfin@latest` or `npx rayfin init` invocation can
|
|
|
20
20
|
External and local template sources are discovered through `rayfin-template.yml` manifests inside the selected source directory.
|
|
21
21
|
Built-in templates are packaged with the CLI and appear in `--list-templates` automatically.
|
|
22
22
|
|
|
23
|
+
> **Universal App is distributed by the Rayfin Copilot plugin.**
|
|
24
|
+
> It is a hidden built-in template: it does not appear in `--list-templates`,
|
|
25
|
+
> but it can be selected explicitly with `--template universal-app`.
|
|
26
|
+
> The plugin selects that bundled template and distributes its committed workspace
|
|
27
|
+
> template directly.
|
|
28
|
+
> This does not change support for ordinary local directories, git repositories, or registered templates.
|
|
29
|
+
|
|
23
30
|
## List available templates
|
|
24
31
|
|
|
25
32
|
Use `--list-templates` to see every template the CLI can scaffold from in your current directory:
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 5
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Add Azure DevOps
|
|
6
|
+
|
|
7
|
+
Call the [Azure DevOps REST API](https://learn.microsoft.com/en-us/rest/api/azure/devops/) from a function **as the signed-in user**, using `AudienceType.ADO`.
|
|
8
|
+
|
|
9
|
+
Provide your Azure DevOps **organization** (and project, if the call needs one) — e.g. `https://dev.azure.com/<org>`. The token is a standard bearer token — send it with `fetch`:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
UserDataFunctions,
|
|
14
|
+
AudienceType,
|
|
15
|
+
type RayfinContext,
|
|
16
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
17
|
+
|
|
18
|
+
const udf = new UserDataFunctions();
|
|
19
|
+
|
|
20
|
+
// Use your real organization URL.
|
|
21
|
+
const ORG = "https://dev.azure.com/<org>";
|
|
22
|
+
|
|
23
|
+
udf.func(
|
|
24
|
+
"listProjects",
|
|
25
|
+
async (ctx: RayfinContext): Promise<unknown> => {
|
|
26
|
+
const token = ctx.getToken(AudienceType.ADO);
|
|
27
|
+
const res = await fetch(`${ORG}/_apis/projects?api-version=7.1`, {
|
|
28
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
throw new Error(`Azure DevOps returned ${res.status}`);
|
|
32
|
+
}
|
|
33
|
+
return res.json();
|
|
34
|
+
},
|
|
35
|
+
[udf.connection({ audienceType: AudienceType.ADO })],
|
|
36
|
+
);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
See [Connecting to external resources](./index.md) for the shared connection model.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 3
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Add an Azure resource
|
|
6
|
+
|
|
7
|
+
Connect a function to an **Azure service** — Key Vault, Cosmos DB, Blob Storage, or Event Grid — and call it **as the signed-in user**.
|
|
8
|
+
|
|
9
|
+
These are Azure resources, not Fabric items, so their endpoints come from the **Azure portal** (there is no Fabric lookup). Each pattern declares the connection, reads the token with `ctx.getToken()`, and wraps it with the [`ContextTokenCredential`](./index.md#wrapping-the-token-for-azure-sdk-clients) helper for the Azure SDK. See [Connecting to external resources](./index.md) for the shared model.
|
|
10
|
+
|
|
11
|
+
## Key Vault
|
|
12
|
+
|
|
13
|
+
Read secrets from Azure Key Vault using `AudienceType.KeyVault`.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd rayfin/functions
|
|
17
|
+
npm install @azure/keyvault-secrets @azure/identity
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import {
|
|
22
|
+
UserDataFunctions,
|
|
23
|
+
AudienceType,
|
|
24
|
+
type RayfinContext,
|
|
25
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
26
|
+
import { SecretClient } from "@azure/keyvault-secrets";
|
|
27
|
+
|
|
28
|
+
const udf = new UserDataFunctions();
|
|
29
|
+
|
|
30
|
+
udf.func(
|
|
31
|
+
"getVaultSecret",
|
|
32
|
+
async (
|
|
33
|
+
ctx: RayfinContext,
|
|
34
|
+
kvUrl: string,
|
|
35
|
+
secretName: string,
|
|
36
|
+
): Promise<string> => {
|
|
37
|
+
const credential = new ContextTokenCredential(
|
|
38
|
+
ctx.getToken(AudienceType.KeyVault),
|
|
39
|
+
);
|
|
40
|
+
const client = new SecretClient(kvUrl, credential);
|
|
41
|
+
const secret = await client.getSecret(secretName);
|
|
42
|
+
return secret.value ?? "";
|
|
43
|
+
},
|
|
44
|
+
[udf.connection({ audienceType: AudienceType.KeyVault })],
|
|
45
|
+
);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Provide the vault URL (e.g. `https://my-vault.vault.azure.net/`).
|
|
49
|
+
|
|
50
|
+
> To read secrets stored with Rayfin itself (rather than an external Key Vault), use [`ctx.getSecret()`](../secrets.md) instead — no connection required.
|
|
51
|
+
|
|
52
|
+
## Cosmos DB
|
|
53
|
+
|
|
54
|
+
Connect to Azure Cosmos DB using `AudienceType.CosmosDB`. Pass the credential as `aadCredentials`:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cd rayfin/functions
|
|
58
|
+
npm install @azure/cosmos
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import {
|
|
63
|
+
UserDataFunctions,
|
|
64
|
+
AudienceType,
|
|
65
|
+
type RayfinContext,
|
|
66
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
67
|
+
import { CosmosClient } from "@azure/cosmos";
|
|
68
|
+
|
|
69
|
+
const udf = new UserDataFunctions();
|
|
70
|
+
|
|
71
|
+
udf.func(
|
|
72
|
+
"readItems",
|
|
73
|
+
async (
|
|
74
|
+
ctx: RayfinContext,
|
|
75
|
+
endpoint: string,
|
|
76
|
+
databaseId: string,
|
|
77
|
+
containerId: string,
|
|
78
|
+
): Promise<unknown[]> => {
|
|
79
|
+
const credential = new ContextTokenCredential(
|
|
80
|
+
ctx.getToken(AudienceType.CosmosDB),
|
|
81
|
+
);
|
|
82
|
+
const client = new CosmosClient({ endpoint, aadCredentials: credential });
|
|
83
|
+
const { resources } = await client
|
|
84
|
+
.database(databaseId)
|
|
85
|
+
.container(containerId)
|
|
86
|
+
.items.readAll()
|
|
87
|
+
.fetchAll();
|
|
88
|
+
return resources;
|
|
89
|
+
},
|
|
90
|
+
[udf.connection({ audienceType: AudienceType.CosmosDB })],
|
|
91
|
+
);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Provide the account endpoint and the database / container names.
|
|
95
|
+
|
|
96
|
+
## Blob Storage
|
|
97
|
+
|
|
98
|
+
Connect to Azure Blob / Table / Queue storage using `AudienceType.Storage`:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
cd rayfin/functions
|
|
102
|
+
npm install @azure/storage-blob
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { BlobServiceClient } from "@azure/storage-blob";
|
|
107
|
+
|
|
108
|
+
udf.func(
|
|
109
|
+
"listBlobs",
|
|
110
|
+
async (ctx: RayfinContext, accountUrl: string): Promise<string[]> => {
|
|
111
|
+
const credential = new ContextTokenCredential(
|
|
112
|
+
ctx.getToken(AudienceType.Storage),
|
|
113
|
+
);
|
|
114
|
+
const service = new BlobServiceClient(accountUrl, credential);
|
|
115
|
+
const names: string[] = [];
|
|
116
|
+
for await (const container of service.listContainers()) {
|
|
117
|
+
names.push(container.name);
|
|
118
|
+
}
|
|
119
|
+
return names;
|
|
120
|
+
},
|
|
121
|
+
[udf.connection({ audienceType: AudienceType.Storage })],
|
|
122
|
+
);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Provide the storage account URL (e.g. `https://<account>.blob.core.windows.net`).
|
|
126
|
+
|
|
127
|
+
> `AudienceType.Storage` also covers **OneLake** files — that Fabric case is documented in [Add a Fabric resource → OneLake files](./add-fabric-resource.md#onelake-files).
|
|
128
|
+
|
|
129
|
+
## Event Grid
|
|
130
|
+
|
|
131
|
+
Publish events to an Azure Event Grid topic using `AudienceType.EventGrid`. The topic endpoint is in the Azure portal → your topic → **Overview** → _Topic Endpoint_.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
cd rayfin/functions
|
|
135
|
+
npm install @azure/eventgrid
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import {
|
|
140
|
+
UserDataFunctions,
|
|
141
|
+
AudienceType,
|
|
142
|
+
type RayfinContext,
|
|
143
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
144
|
+
import { EventGridPublisherClient } from "@azure/eventgrid";
|
|
145
|
+
|
|
146
|
+
const udf = new UserDataFunctions();
|
|
147
|
+
|
|
148
|
+
const TOPIC_ENDPOINT =
|
|
149
|
+
"https://<topic>.<region>.eventgrid.azure.net/api/events";
|
|
150
|
+
|
|
151
|
+
udf.func(
|
|
152
|
+
"publishEvent",
|
|
153
|
+
async (ctx: RayfinContext, subject: string): Promise<string> => {
|
|
154
|
+
const client = new EventGridPublisherClient(
|
|
155
|
+
TOPIC_ENDPOINT,
|
|
156
|
+
"EventGrid",
|
|
157
|
+
new ContextTokenCredential(ctx.getToken(AudienceType.EventGrid)),
|
|
158
|
+
);
|
|
159
|
+
await client.send([
|
|
160
|
+
{
|
|
161
|
+
eventType: "Rayfin.Function.Event",
|
|
162
|
+
subject,
|
|
163
|
+
dataVersion: "1.0",
|
|
164
|
+
data: { source: "user-data-function" },
|
|
165
|
+
},
|
|
166
|
+
]);
|
|
167
|
+
return "published";
|
|
168
|
+
},
|
|
169
|
+
[udf.connection({ audienceType: AudienceType.EventGrid })],
|
|
170
|
+
);
|
|
171
|
+
```
|