@microsoft/rayfin-connector-fabric-graphql 1.36.0-alpha.1601 → 1.36.0-alpha.1663
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/README.md +1 -5
- package/assets/docs/entities.md +9 -8
- package/assets/docs/index.md +4 -3
- package/assets/docs/mutations.md +2 -2
- package/assets/docs/querying.md +100 -2
- package/assets/docs/troubleshooting.md +21 -3
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
# @microsoft/rayfin-connector-fabric-graphql
|
|
2
2
|
|
|
3
|
-
> **Experimental** — this package is experimental and may change substantially in the near future.
|
|
4
|
-
> Mount the typed connectors runtime via the experimental subpath of
|
|
5
|
-
> `@microsoft/rayfin-client` rather than the stable `RayfinClient` entry.
|
|
6
|
-
|
|
7
3
|
Base types for Rayfin's Category A (GraphQL-backed) connectors:
|
|
8
|
-
`fabric-
|
|
4
|
+
`fabric-sqldatabase`, `fabric-warehouse`, `fabric-sqlanalytics`, and `fabric-graphql`.
|
|
9
5
|
|
|
10
6
|
This package contributes nothing at runtime — it only exports the types
|
|
11
7
|
needed to make
|
package/assets/docs/entities.md
CHANGED
|
@@ -54,6 +54,11 @@ Generate `<EntityName>.ts` from `metadata.json` following every rule below. **`m
|
|
|
54
54
|
- `className = pascalCase(table.tableName)` (`product_category` → `ProductCategory`). One file `<className>.ts` per table, no nesting.
|
|
55
55
|
- **Pluralize only idempotently.** Pluralizing a singular name is fine (`Order` → `Orders`); an already-plural name (`Orders`, `Categories`) stays as-is — never double-pluralize. Keep the `@entity` name and the `client.connectors.<name>.<Entity>` path consistent with whatever you pick.
|
|
56
56
|
- **Names are global across all connectors.** Before finalizing, scan every other `rayfin/connectors/*/` dir and the entities already generated here for the same name. Only on a real collision, prefix the source database name (PascalCased, from `metadata.json` `source`): `Product` → `SalesDbProduct`; if that database name also collides, use the PascalCased connector name. Never prefix a name that does not collide. On a rename, use the new name everywhere (class, file, `@entity`, `TSchema` key, re-export, access path) and tell the user.
|
|
57
|
+
- **Never use a reserved GraphQL type name.**
|
|
58
|
+
The generated schema already defines the built-in scalars and the operation root types, so an entity called `Date` or `Query` redefines an existing type and the deploy is rejected.
|
|
59
|
+
Matching is case-sensitive and exact — `TaskDate` and `OrderDate` are fine.
|
|
60
|
+
The authoritative list is the "Reserved entity names" section of `@microsoft/rayfin-core/assets/docs/decorators.md` — read it there rather than relying on memory.
|
|
61
|
+
When `pascalCase(table.tableName)` lands on a reserved name, append a domain suffix (`Date` → `DateRecord`, `Query` → `QueryRecord`), keep `Source({ table: '...' })` pointed at the original table, and tell the user about the rename.
|
|
57
62
|
|
|
58
63
|
### 2. Primary keys
|
|
59
64
|
|
|
@@ -121,11 +126,7 @@ Build the option object in order (omit unused keys): `optional: true` if `column
|
|
|
121
126
|
|
|
122
127
|
Server-generated columns have **no** decorator option marking them as such — do not invent one; the only change is the `AutoGenerated<T>` wrapper from 4a. Surface a one-line note per such column (for example `'<table>.<column>' is server-generated (identity); omit it on create()`). A server-generated key still follows the key rules in §2.
|
|
123
128
|
|
|
124
|
-
### 6.
|
|
125
|
-
|
|
126
|
-
If `pascalCase(table.tableName)` equals a column's TS type (for example a table `Date` with a `datetime2` column), the unqualified type resolves to the entity class. Render it as `globalThis.Date` in that one annotation only.
|
|
127
|
-
|
|
128
|
-
### 7. Relationships
|
|
129
|
+
### 6. Relationships
|
|
129
130
|
|
|
130
131
|
Emit `@one` (forward) and `@many` (reverse) from foreign-key metadata **only** — never infer from column names or values. Group `table.foreignKeys` by `constraintName`: one group = one relationship; rows in a group are the ordered column pairs of a composite FK.
|
|
131
132
|
|
|
@@ -157,18 +158,18 @@ When a referenced/other table is not in the set you are generating (subset mode)
|
|
|
157
158
|
|
|
158
159
|
`singularize`: `ies→y` (len>3); `xes|ses|ches|shes→ drop -es`; `<non-s>s→ drop -s`; else unchanged. `pluralize` (idempotent): already-plural → unchanged; `<non-vowel>y→ -ies`; `x|z|ch|sh→ +es`; else `+s`.
|
|
159
160
|
|
|
160
|
-
###
|
|
161
|
+
### 7. Missing metadata
|
|
161
162
|
|
|
162
163
|
No PK metadata → warn `No PK metadata available for <tableName>; generated as a keyless entity.` No FK metadata (and no incoming FK) → warn `No FK metadata available for <tableName>; relationships omitted.` For Lakehouse these are known limitations, not a cue to infer. The file still generates keyless and relationship-free; the Builder may add logical keys/relationships manually, but never add them without that input.
|
|
163
164
|
|
|
164
|
-
###
|
|
165
|
+
### 8. Imports
|
|
165
166
|
|
|
166
167
|
- Always include `entity`, then append — in this exact order — the decorators actually used: `boolean`, `date`, `decimal`, `int`, `text`, `uuid`, `one`, `many`. Skip unused. All from `@microsoft/rayfin-core`.
|
|
167
168
|
- Always include `Source` from `@microsoft/rayfin-connectors`, on its own import line.
|
|
168
169
|
- If any column is server-generated, also add `import type { AutoGenerated } from '@microsoft/rayfin-connectors';`.
|
|
169
170
|
- For each relationship target class, add an alphabetized sibling import `import { <Class> } from './<Class>.js';` (self-references get none; subset-skipped relationships contribute none).
|
|
170
171
|
|
|
171
|
-
###
|
|
172
|
+
### 9. Canonical example
|
|
172
173
|
|
|
173
174
|
```ts
|
|
174
175
|
import { entity, uuid, text, int, date, one, many } from '@microsoft/rayfin-core';
|
package/assets/docs/index.md
CHANGED
|
@@ -83,9 +83,10 @@ export type InventorySchema = GraphQLBackedConnector<
|
|
|
83
83
|
|
|
84
84
|
### The `entities` map
|
|
85
85
|
|
|
86
|
-
`connectorConfig.entities`
|
|
86
|
+
`connectorConfig.entities` supplies the **default column selection** used by `findMany()`, `findFirst()`, and `findByKey()` when the call passes no selection. **It is required** — omit it and those calls throw `SELECTION_REQUIRED`.
|
|
87
87
|
|
|
88
88
|
- List the generated entity **classes**, e.g. `entities: { Order, Customer }`. The client reads each class to derive the default column selection and relationship cardinality.
|
|
89
|
+
- The default does **not** reach the query chain. A read that starts with `.select()` / `.where()` / `.orderBy()` / `.first()` must carry an explicit `.select([...])`, or `.execute()` throws `SELECTION_REQUIRED` no matter what `entities` contains. See [Querying](./querying.md#which-reads-need-an-explicit-select).
|
|
89
90
|
|
|
90
91
|
### Keep operations in one place
|
|
91
92
|
|
|
@@ -93,10 +94,10 @@ export type InventorySchema = GraphQLBackedConnector<
|
|
|
93
94
|
|
|
94
95
|
## Wire the client
|
|
95
96
|
|
|
96
|
-
Deploying a connector does not make it callable. Expose it through a `ConnectorsRayfinClient` so it appears as `client.connectors.<name>`. Import that client from the `@microsoft/rayfin-client
|
|
97
|
+
Deploying a connector does not make it callable. Expose it through a `ConnectorsRayfinClient` so it appears as `client.connectors.<name>`. Import that client from the main `@microsoft/rayfin-client` entry. The connector key must be identical in three places: `name` in `rayfin.yml`, the `AppConnectorsSchema` property, and the `connectors` option.
|
|
97
98
|
|
|
98
99
|
```ts
|
|
99
|
-
import { ConnectorsRayfinClient } from '@microsoft/rayfin-client
|
|
100
|
+
import { ConnectorsRayfinClient } from '@microsoft/rayfin-client';
|
|
100
101
|
import { InventorySchema, connectorConfig as inventoryConfig } from '../../rayfin/connectors/inventory/schema';
|
|
101
102
|
|
|
102
103
|
type AppConnectorsSchema = { inventory: InventorySchema };
|
package/assets/docs/mutations.md
CHANGED
|
@@ -39,12 +39,12 @@ client.connectors.analytics.Sales.create({ /* ... */ }); // compile error: read-
|
|
|
39
39
|
|
|
40
40
|
**Server-generated columns** (`AutoGenerated<T>`: `IDENTITY`, `DEFAULT`, computed) are optional on write and come back populated in the returned row. Most reject a value; a plain `DEFAULT` is the exception (omit for the default, or pass to override).
|
|
41
41
|
|
|
42
|
-
By-key `update` / `delete` take the same full key object as `findByKey`. A keyless entity
|
|
42
|
+
By-key `update` / `delete` take the same full key object as `findByKey`. A **keyless** entity (`primaryKey: []`, common on Lakehouse and Warehouse where `metadata.json` carries no key) drops `findByKey`, `update`, and `delete` at compile time — there is no key to address a row by. `create` is unaffected and stays available whenever `operations:` and `@role(...)` allow it, since an insert needs no key.
|
|
43
43
|
|
|
44
44
|
## Quick guide
|
|
45
45
|
|
|
46
46
|
- **Lakehouse (`fabric-sqlanalytics`)** — reads only.
|
|
47
47
|
- **SQL Database (`fabric-sqldatabase`)** — full CRUD; mutations return the full row, render it directly.
|
|
48
|
-
- **Warehouse (`fabric-warehouse`)** — full CRUD; mutations return `DbOperationResult`, so re-query with `findByKey`/`select` if you need the persisted values.
|
|
48
|
+
- **Warehouse (`fabric-warehouse`)** — full CRUD; mutations return `DbOperationResult`, so re-query with `findByKey`/`select` if you need the persisted values. On a keyless entity that re-query has to go through the chain with a `where` filter.
|
|
49
49
|
|
|
50
50
|
For roll-ups (`groupBy` / `aggregate`), connector entities use the same fluent aggregation API as the app-schema GraphQL client, reached via `client.connectors.<name>.<Entity>`. See the `@microsoft/rayfin-data` package docs (`aggregations.md`) for the full spec.
|
package/assets/docs/querying.md
CHANGED
|
@@ -8,16 +8,55 @@ Reading entities: the query chain, by-key lookups, and related columns. For roll
|
|
|
8
8
|
|
|
9
9
|
Each entity is reached via `client.connectors.<name>.<Entity>`. The surface depends on `operations:` (which verbs) and the dialect (what writes return). **Reads are identical on Lakehouse, Warehouse, and SQL Database.**
|
|
10
10
|
|
|
11
|
+
## Which reads need an explicit `select`
|
|
12
|
+
|
|
13
|
+
There are two read surfaces, and they treat selection differently. Getting this wrong is the most common Category A runtime error.
|
|
14
|
+
|
|
15
|
+
| Surface | Entry points | Selection | Ordering / row limit |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| Convenience methods | `findMany`, `findFirst`, `findByKey` | Optional — falls back to the default columns from `connectorConfig.entities` | Not available |
|
|
18
|
+
| Query chain | `.select()`, `.where()`, `.orderBy()`, `.first()` → `.execute()` / `.executePaginated()` | **Mandatory `.select([...])`** | `.orderBy()` / `.first(n)` / `.after(cursor)` |
|
|
19
|
+
|
|
20
|
+
The default selection from `connectorConfig.entities` **never** reaches the query chain. A chain that reaches `.execute()` with no `.select()` throws `SELECTION_REQUIRED` even when `entities` is fully populated:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// ❌ throws SELECTION_REQUIRED — .first() does not inherit the default columns.
|
|
24
|
+
await client.connectors.inventory.Order.first(20).execute();
|
|
25
|
+
|
|
26
|
+
// ✅ chain with an explicit selection.
|
|
27
|
+
await client.connectors.inventory.Order
|
|
28
|
+
.select(['orderId', 'customerEmail', 'total'])
|
|
29
|
+
.first(20)
|
|
30
|
+
.execute();
|
|
31
|
+
|
|
32
|
+
// ✅ no selection needed — findMany uses the default columns.
|
|
33
|
+
await client.connectors.inventory.Order.findMany();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Because `findMany` accepts only a selection and a filter, any read that needs `orderBy` or a row cap must use the chain — and therefore must name its columns.
|
|
37
|
+
|
|
11
38
|
## Reads
|
|
12
39
|
|
|
13
40
|
```ts
|
|
14
|
-
// Query chain: select -> where -> orderBy -> execute
|
|
41
|
+
// Query chain: select -> where -> orderBy -> first -> execute.
|
|
42
|
+
// .select() is required on every chain.
|
|
15
43
|
const orders = await client.connectors.inventory.Order
|
|
16
44
|
.select(['orderId', 'customerEmail', 'total'])
|
|
17
45
|
.where({ total: { gt: 100 } })
|
|
18
46
|
.orderBy({ total: 'desc' })
|
|
47
|
+
.first(20)
|
|
19
48
|
.execute();
|
|
20
49
|
|
|
50
|
+
// findMany / findFirst: `(fields?, filter?)` or `(filter?)`.
|
|
51
|
+
// An array first argument is the selection; anything else is the filter.
|
|
52
|
+
const all = await client.connectors.inventory.Order.findMany();
|
|
53
|
+
const big = await client.connectors.inventory.Order.findMany({ total: { gt: 100 } });
|
|
54
|
+
const cols = await client.connectors.inventory.Order.findMany(
|
|
55
|
+
['orderId', 'total'],
|
|
56
|
+
{ total: { gt: 100 } },
|
|
57
|
+
);
|
|
58
|
+
const one = await client.connectors.inventory.Order.findFirst({ orderId: { eq: 'o-1' } });
|
|
59
|
+
|
|
21
60
|
// By-key: full key object; select is optional.
|
|
22
61
|
// Omit select -> full row; pass a scalar-only select -> just those columns.
|
|
23
62
|
const order = await client.connectors.inventory.Order.findByKey({ orderId: 'o-1' });
|
|
@@ -34,14 +73,73 @@ const lineItem = await client.connectors.sales.OrderItem.findByKey({
|
|
|
34
73
|
});
|
|
35
74
|
```
|
|
36
75
|
|
|
76
|
+
`.execute()` and `findMany` return a plain array of rows; `findFirst` and `findByKey` return `Row | null`. For a cursor envelope, end the chain with `.executePaginated()` instead — see [Paging](#paging).
|
|
77
|
+
|
|
37
78
|
`findByKey` takes the full primary key (required) and an **optional** scalar-only
|
|
38
79
|
`select`. With no `select` it returns the full `Row | null`; with one it returns
|
|
39
80
|
`Pick<Row, selected> | null`. It is scalar-only — read relationships through the
|
|
40
81
|
query chain. Omitting a composite-key part is a compile error.
|
|
41
82
|
|
|
83
|
+
Keyless entities (`primaryKey: []`, common on Lakehouse and Warehouse) drop `findByKey`, `update`, and `delete` at compile time — reads go through the chain, `findMany`, and `findFirst`, and `create` is still available if `operations:` allows it.
|
|
84
|
+
|
|
85
|
+
## Filters
|
|
86
|
+
|
|
87
|
+
`.where(...)` and the filter argument of `findMany` / `findFirst` take the same DAB filter object: one entry per column, each an operator map. The operators available depend on the column kind.
|
|
88
|
+
|
|
89
|
+
| Column kind | Operators |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| string (`@text`, `@uuid`, `@email`) | `eq`, `neq`, `gt`, `gte`, `lt`, `lte` (lexicographic), `contains`, `notContains`, `startsWith`, `endsWith`, `isNull`, `in` |
|
|
92
|
+
| number (`@int`, `@decimal`) | `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `isNull`, `in` |
|
|
93
|
+
| `@date` | `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `isNull`, `in` |
|
|
94
|
+
| `@boolean` | `eq`, `neq`, `isNull`, `in` |
|
|
95
|
+
|
|
96
|
+
Sibling entries are ANDed. Combine alternatives with `and` / `or` — lowercase per the DAB spec, each taking an **array** of filter objects. There is no `not`.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
await client.connectors.inventory.Order
|
|
100
|
+
.select(['orderId', 'status', 'total'])
|
|
101
|
+
.where({
|
|
102
|
+
status: { in: ['open', 'pending'] },
|
|
103
|
+
shippedUtc: { isNull: true },
|
|
104
|
+
or: [{ total: { gte: 1000 } }, { customerEmail: { endsWith: '@contoso.com' } }],
|
|
105
|
+
})
|
|
106
|
+
.execute();
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`isNull: true` matches nulls, `isNull: false` matches non-nulls.
|
|
110
|
+
|
|
111
|
+
## Paging
|
|
112
|
+
|
|
113
|
+
`.first(n)` returns a single page. `n` is bounded by DAB's maximum page size (100,000); `-1` requests an unbounded page, which DAB still caps at that maximum. `.execute()` and `findMany` hand back that one page as a plain array, so a table larger than the page size needs cursors.
|
|
114
|
+
|
|
115
|
+
Finish the chain with `.executePaginated()` and feed `endCursor` into `.after()` on the next chain:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const page = await client.connectors.inventory.Order
|
|
119
|
+
.select(['orderId', 'total'])
|
|
120
|
+
.orderBy({ orderId: 'asc' })
|
|
121
|
+
.first(500)
|
|
122
|
+
.executePaginated();
|
|
123
|
+
|
|
124
|
+
if (page.hasNextPage && page.endCursor) {
|
|
125
|
+
const next = await client.connectors.inventory.Order
|
|
126
|
+
.select(['orderId', 'total'])
|
|
127
|
+
.orderBy({ orderId: 'asc' })
|
|
128
|
+
.first(500)
|
|
129
|
+
.after(page.endCursor)
|
|
130
|
+
.executePaginated();
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`executePaginated()` returns `PagedResult<Row>` — `{ items, hasNextPage, endCursor?, totalCount? }`. Pagination is forward-only; DAB has no `last` / `before`.
|
|
135
|
+
|
|
136
|
+
`.after()` and `.executePaginated()` live on the builder, not on the entity client, so the chain still has to start with `.select([...])` / `.where(...)` — and `.executePaginated()` requires the same explicit selection as `.execute()`.
|
|
137
|
+
|
|
42
138
|
## Related columns
|
|
43
139
|
|
|
44
|
-
`select` pulls columns from a `@one` or `@many` navigation field as a **dotted path**. Name the leaf column (`category.name`), never the bare relationship (`category`) — that is a compile error. Paths nest to any depth
|
|
140
|
+
`select` pulls columns from a `@one` or `@many` navigation field as a **dotted path**. Name the leaf column (`category.name`), never the bare relationship (`category`) — that is a compile error. Paths nest to any depth.
|
|
141
|
+
|
|
142
|
+
Segment validation is typed only as far as `TSchema` describes the hop, and cardinality is resolved at runtime from `connectorConfig.entities`. A path that gets past the compiler still throws: `INVALID_RELATIONSHIP_SELECTION` when a segment is not a `@one` / `@many` field, and `ENTITIES_REQUIRED_FOR_RELATIONSHIP_SELECT` when the entity classes were never registered. Register every entity a path traverses, not just the root.
|
|
45
143
|
|
|
46
144
|
```ts
|
|
47
145
|
const products = await client.connectors.inventory.Product
|
|
@@ -9,7 +9,8 @@ Anti-patterns and a symptom to cause to fix matrix for `fabric-sqlanalytics`, `f
|
|
|
9
9
|
## Anti-patterns
|
|
10
10
|
|
|
11
11
|
- Never leave `schema.ts` as bare re-exports — the client import of `<Name>Schema` and `connectorConfig` fails.
|
|
12
|
-
- Populate `connectorConfig.entities` with the generated entity **classes** (e.g. `entities: { Order, Customer }`), never omit it. Omitting it makes every no-selection
|
|
12
|
+
- Populate `connectorConfig.entities` with the generated entity **classes** (e.g. `entities: { Order, Customer }`), never omit it. Omitting it makes every no-selection `findMany` / `findFirst` / `findByKey` throw `SELECTION_REQUIRED`.
|
|
13
|
+
- Never rely on `entities` to cover a query chain. `.where()` / `.orderBy()` / `.first()` do not inherit the default selection — always pair them with `.select([...])`.
|
|
13
14
|
- In subset mode, list in `TSchema` only entities you actually generated.
|
|
14
15
|
- Keep `connectorConfig.operations` identical to the YAML `operations:`, and each entity `@role(...)` action a subset of that pair. Narrow YAML first; never widen a decorator just to match the connector.
|
|
15
16
|
- Policies use the typed `claims` / `item` DSL — never raw SQL or DAB-policy strings.
|
|
@@ -24,9 +25,26 @@ Anti-patterns and a symptom to cause to fix matrix for `fabric-sqlanalytics`, `f
|
|
|
24
25
|
| --- | --- | --- |
|
|
25
26
|
| `rayfin up connector apply` fails on a role action | Entity `@role(...)` includes an action not in the YAML `operations:` | Narrow the decorator to match YAML. |
|
|
26
27
|
| `rayfin up connector apply` fails with a duplicate GraphQL type | Two connectors generated an entity with the same name — names are global | Disambiguate by prefixing the source database name; update the class, file, `@entity`, `TSchema` key, and access path together, then re-apply. |
|
|
28
|
+
| `Reserved GraphQL type names detected in connector entities` | An entity is named after a built-in scalar or an operation root type (`Date`, `Int`, `Query`, …), which the generated schema already defines | Rename the class (`Date` → `DateRecord`), keep `Source({ table: '...' })` on the original table, update the `@entity`, `TSchema` key, re-export, and access path, then re-apply. |
|
|
27
29
|
| `rayfin connector add` writes the YAML entry but no entity files | Expected — the CLI never emits entity files | Generate them from `metadata.json` per the contract. If `metadata.json` is also missing, discovery failed. |
|
|
28
30
|
| `Property '<name>' does not exist on connectors` | Connector key in `AppConnectorsSchema` does not match the `connectors` option | Use the `rayfin.yml` `name` in all three places. |
|
|
29
31
|
| A CRUD method is missing from autocomplete | Expected: `<Name>Schema` narrows methods to `operations` | Widen via `rayfin connector add --operations`, then re-import. |
|
|
30
|
-
| Import of `ConnectorsRayfinClient` fails to resolve | Imported from the
|
|
32
|
+
| Import of `ConnectorsRayfinClient` fails to resolve | Imported from the removed or misspelled experimental subpath | Import from the stable `@microsoft/rayfin-client` entry. |
|
|
31
33
|
| `Cannot find module '@microsoft/rayfin-connector-fabric-graphql'` | Connector packages never installed — `connector add` does not add them | Run the pinned `npm install` that `connector add` printed. |
|
|
32
|
-
| A
|
|
34
|
+
| A query chain throws `SELECTION_REQUIRED` | The chain (`.where()` / `.orderBy()` / `.first()` → `.execute()`) has no `.select()`. `connectorConfig.entities` does not supply a default here — only `findMany` / `findFirst` / `findByKey` read it | Add `.select([...])` to the chain, or drop to `findMany(filter)` if you need neither ordering nor a row limit. |
|
|
35
|
+
| `findMany` / `findFirst` / `findByKey` throws `SELECTION_REQUIRED` | `connectorConfig.entities` is missing, so there is no default column list | Add the entity class to `connectorConfig.entities`, or pass an explicit selection to the call. |
|
|
36
|
+
|
|
37
|
+
## Error codes
|
|
38
|
+
|
|
39
|
+
Every runtime failure on the connector path is a `ConnectorsError` carrying one of these codes.
|
|
40
|
+
|
|
41
|
+
| Code | Thrown when | Fix |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| `SELECTION_REQUIRED` | A chain reached `.execute()` / `.executePaginated()` with no `.select()`, or a no-selection `findMany` / `findFirst` / `findByKey` ran while `connectorConfig.entities` was unpopulated | Add `.select([...])`, or register the entity class in `connectorConfig.entities`. |
|
|
44
|
+
| `ENTITIES_REQUIRED_FOR_RELATIONSHIP_SELECT` | A dotted path (`category.name`) was selected but `connectorConfig.entities` is unpopulated, so relationship cardinality is unknown | Register every entity the path traverses, not just the root. |
|
|
45
|
+
| `INVALID_RELATIONSHIP_SELECTION` | A segment of a dotted path is not a `@one` / `@many` field on that entity | Fix the path, or select the column directly if it is a plain scalar. |
|
|
46
|
+
| `INVALID_COLUMN_NAME` | A selection or mutation input used a name that is not a legal GraphQL name | Use the entity **property** name, never the raw SQL column — the `column:` option maps between them. |
|
|
47
|
+
| `EMPTY_MUTATION_SELECTION` | A mutation had no columns left to return | Pass at least one input column, or register the entity in `connectorConfig.entities` so server-generated columns are returned. |
|
|
48
|
+
| `MUTATION_NO_RESULT` | The server ran the mutation but returned no data | Usually a `@role` policy filtering the row out, or a key that matches nothing — verify both. |
|
|
49
|
+
| `OPERATION_NOT_ALLOWED` | A CRUD method was reached that is outside the connector's `operations:` (the runtime gate behind the compile-time narrowing) | Widen `operations:` in `rayfin.yml` **and** `connectorConfig`, re-apply, then re-import. |
|
|
50
|
+
| `UNKNOWN_CONNECTOR` | A connector was accessed that was never passed in the client's `connectors` option | Add it to `connectors: { <name>: connectorConfig }` — the key must match the `rayfin.yml` `name`. |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/rayfin-connector-fabric-graphql",
|
|
3
|
-
"version": "1.36.0-alpha.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.36.0-alpha.1663",
|
|
4
|
+
"description": "Cat A GraphQL-backed connector types for the Rayfin SDK. Provides the entity-oriented marker (GraphQLBackedConnector) and CRUD operation gating used by the typed client.connectors.<name>.<Entity>.select(...).execute() surface.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"rimraf": "~6.0.1"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@microsoft/rayfin-
|
|
30
|
-
"@microsoft/rayfin-
|
|
29
|
+
"@microsoft/rayfin-connectors": "1.36.0-alpha.1663",
|
|
30
|
+
"@microsoft/rayfin-data": "1.36.0-alpha.1663"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"registry": "https://npm.pkg.github.com",
|