@fias/create-fias-plugin 1.14.0 → 1.15.0
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/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- fias-sdk-guide-version: 2.
|
|
1
|
+
<!-- fias-sdk-guide-version: 2.23.0 -->
|
|
2
2
|
|
|
3
3
|
# FIAS Plugin Development Guide
|
|
4
4
|
|
|
@@ -1308,6 +1308,36 @@ Three things to design around:
|
|
|
1308
1308
|
|
|
1309
1309
|
Only images the user made or uploaded in **their own** Fias files can be published (pass the `fileId` from a `useImageGeneration()` result). PNG/JPEG/WebP only; every image is re-encoded to a canonical PNG with metadata stripped. Publishers can `unpublish()` their own assets, and any user can `report()` one for review.
|
|
1310
1310
|
|
|
1311
|
+
### `useCompanyEmail()` — Send email as the Company the app is used in
|
|
1312
|
+
|
|
1313
|
+
**Permission:** `email:company:send`
|
|
1314
|
+
**Returns:** `CompanyEmailApi`
|
|
1315
|
+
|
|
1316
|
+
For apps built for an approved partner Company: send email **from the Company's own verified domain** (e.g. `team@example.com`), not from Fias. Declaring the permission is not enough — a Company admin must also authorize your app to send, and chooses who it may email: members of the workspace it is used in, members of the whole Company, or anyone. Until then every call is refused with `COMPANY_EMAIL_NOT_AUTHORIZED`.
|
|
1317
|
+
|
|
1318
|
+
```tsx
|
|
1319
|
+
import { useCompanyEmail } from '@fias/arche-sdk';
|
|
1320
|
+
|
|
1321
|
+
const email = useCompanyEmail();
|
|
1322
|
+
const { results, sent } = await email.send({
|
|
1323
|
+
requestKey: `digest-${weekId}`, // reuse on retry — never double-sends
|
|
1324
|
+
to: members.map((m) => ({ userId: m.userId })),
|
|
1325
|
+
subject: 'Your weekly digest',
|
|
1326
|
+
text: digestText, // required
|
|
1327
|
+
html: digestHtml, // optional, sanitized
|
|
1328
|
+
});
|
|
1329
|
+
// results[i]: { index, status: 'accepted' | 'unknown' | 'failed' | 'muted' | 'not_sent' }
|
|
1330
|
+
```
|
|
1331
|
+
|
|
1332
|
+
- **You never choose the From address** — it is the address the Company assigned your app. You choose recipients and content.
|
|
1333
|
+
- **Name members by `userId`**; you never see their addresses. Raw `{ email }` recipients work only if the Company let your app email anyone. One recipient outside what the Company allowed refuses the whole call (without saying which).
|
|
1334
|
+
- **The user must be working in one of the Company's workspaces, with edit access.** Each recipient is charged to that user, like any paid call; up to 50 recipients per call, and a daily limit per app per Company.
|
|
1335
|
+
- **Retry with the same `requestKey`.** A recipient already sent under that key is not sent again. `unknown` means it may have gone out — do not resend it under a new key.
|
|
1336
|
+
- **HTML is sanitized** to the email allow-list: tables, inline presentational styles, `https` images and `https`/`mailto` links are kept; `<script>`, `<form>`, `<iframe>` and similar refuse the send (`EMAIL_CONTENT_REJECTED`).
|
|
1337
|
+
- **Attachments:** up to 5 files, 5 MB total, and only `.pdf`, `.png`, `.jpg`/`.jpeg`, `.gif`, `.csv`, `.txt`, `.ics`, `.docx`, `.xlsx`. `contentType` must match the extension (e.g. `application/pdf`), and the bytes must be that format; anything else refuses the send (`EMAIL_CONTENT_REJECTED`).
|
|
1338
|
+
- **Every email carries one-click unsubscribe.** Recipients who used it come back as `muted`; the Company may also show a "Stop emails from this arche" line, which is always shown for `kind: 'marketing'`.
|
|
1339
|
+
- Not available in the builder preview or the local dev harness — it sends real email. Other refusals: `WORKSPACE_REQUIRED`, `RECIPIENT_NOT_ALLOWED`, `COMPANY_EMAIL_UNAVAILABLE` (the Company's domain is not ready or paused), `DAILY_EMAIL_LIMIT_REACHED`, `INSUFFICIENT_CREDITS`.
|
|
1340
|
+
|
|
1311
1341
|
### `useFiasStore()` — In-app purchases (IAP)
|
|
1312
1342
|
|
|
1313
1343
|
**Permission:** `store:purchase`
|
|
@@ -1405,7 +1435,23 @@ the user moves the host themselves with browser back/forward. So a router
|
|
|
1405
1435
|
driven off `currentPath` stays in step with the address bar, and the back
|
|
1406
1436
|
button works the way your users expect — you do not have to mirror the path in
|
|
1407
1437
|
your own state. The dev harness echoes navigations the same way, so what you
|
|
1408
|
-
see locally is what ships.
|
|
1438
|
+
see locally is what ships. To test a deep link locally, open the harness with
|
|
1439
|
+
`?path=/map` (a root-relative path in your route space) and `currentPath`
|
|
1440
|
+
starts there instead of at `/`.
|
|
1441
|
+
|
|
1442
|
+
**Correcting the URL.** Every `navigateTo` pushes a history entry by default,
|
|
1443
|
+
which is right for navigation the user asked for. When you are CORRECTING the
|
|
1444
|
+
address bar instead — normalizing a link you were opened at (`/Map/` →
|
|
1445
|
+
`/map`), or putting it back after refusing a route — pass `{ replace: true }`
|
|
1446
|
+
so Back does not land on the URL you just corrected:
|
|
1447
|
+
|
|
1448
|
+
```tsx
|
|
1449
|
+
navigateTo('/map', { replace: true });
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1452
|
+
A host older than this option ignores it and pushes. If you correct paths
|
|
1453
|
+
automatically as they arrive, never repeat the same correction twice in a
|
|
1454
|
+
row, or a push-only host can trap the Back button between two URLs.
|
|
1409
1455
|
|
|
1410
1456
|
### Opening external links
|
|
1411
1457
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- fias-sdk-guide-version: 2.
|
|
1
|
+
<!-- fias-sdk-guide-version: 2.23.0 -->
|
|
2
2
|
|
|
3
3
|
# FIAS Plugin Development Guide
|
|
4
4
|
|
|
@@ -1308,6 +1308,36 @@ Three things to design around:
|
|
|
1308
1308
|
|
|
1309
1309
|
Only images the user made or uploaded in **their own** Fias files can be published (pass the `fileId` from a `useImageGeneration()` result). PNG/JPEG/WebP only; every image is re-encoded to a canonical PNG with metadata stripped. Publishers can `unpublish()` their own assets, and any user can `report()` one for review.
|
|
1310
1310
|
|
|
1311
|
+
### `useCompanyEmail()` — Send email as the Company the app is used in
|
|
1312
|
+
|
|
1313
|
+
**Permission:** `email:company:send`
|
|
1314
|
+
**Returns:** `CompanyEmailApi`
|
|
1315
|
+
|
|
1316
|
+
For apps built for an approved partner Company: send email **from the Company's own verified domain** (e.g. `team@example.com`), not from Fias. Declaring the permission is not enough — a Company admin must also authorize your app to send, and chooses who it may email: members of the workspace it is used in, members of the whole Company, or anyone. Until then every call is refused with `COMPANY_EMAIL_NOT_AUTHORIZED`.
|
|
1317
|
+
|
|
1318
|
+
```tsx
|
|
1319
|
+
import { useCompanyEmail } from '@fias/arche-sdk';
|
|
1320
|
+
|
|
1321
|
+
const email = useCompanyEmail();
|
|
1322
|
+
const { results, sent } = await email.send({
|
|
1323
|
+
requestKey: `digest-${weekId}`, // reuse on retry — never double-sends
|
|
1324
|
+
to: members.map((m) => ({ userId: m.userId })),
|
|
1325
|
+
subject: 'Your weekly digest',
|
|
1326
|
+
text: digestText, // required
|
|
1327
|
+
html: digestHtml, // optional, sanitized
|
|
1328
|
+
});
|
|
1329
|
+
// results[i]: { index, status: 'accepted' | 'unknown' | 'failed' | 'muted' | 'not_sent' }
|
|
1330
|
+
```
|
|
1331
|
+
|
|
1332
|
+
- **You never choose the From address** — it is the address the Company assigned your app. You choose recipients and content.
|
|
1333
|
+
- **Name members by `userId`**; you never see their addresses. Raw `{ email }` recipients work only if the Company let your app email anyone. One recipient outside what the Company allowed refuses the whole call (without saying which).
|
|
1334
|
+
- **The user must be working in one of the Company's workspaces, with edit access.** Each recipient is charged to that user, like any paid call; up to 50 recipients per call, and a daily limit per app per Company.
|
|
1335
|
+
- **Retry with the same `requestKey`.** A recipient already sent under that key is not sent again. `unknown` means it may have gone out — do not resend it under a new key.
|
|
1336
|
+
- **HTML is sanitized** to the email allow-list: tables, inline presentational styles, `https` images and `https`/`mailto` links are kept; `<script>`, `<form>`, `<iframe>` and similar refuse the send (`EMAIL_CONTENT_REJECTED`).
|
|
1337
|
+
- **Attachments:** up to 5 files, 5 MB total, and only `.pdf`, `.png`, `.jpg`/`.jpeg`, `.gif`, `.csv`, `.txt`, `.ics`, `.docx`, `.xlsx`. `contentType` must match the extension (e.g. `application/pdf`), and the bytes must be that format; anything else refuses the send (`EMAIL_CONTENT_REJECTED`).
|
|
1338
|
+
- **Every email carries one-click unsubscribe.** Recipients who used it come back as `muted`; the Company may also show a "Stop emails from this arche" line, which is always shown for `kind: 'marketing'`.
|
|
1339
|
+
- Not available in the builder preview or the local dev harness — it sends real email. Other refusals: `WORKSPACE_REQUIRED`, `RECIPIENT_NOT_ALLOWED`, `COMPANY_EMAIL_UNAVAILABLE` (the Company's domain is not ready or paused), `DAILY_EMAIL_LIMIT_REACHED`, `INSUFFICIENT_CREDITS`.
|
|
1340
|
+
|
|
1311
1341
|
### `useFiasStore()` — In-app purchases (IAP)
|
|
1312
1342
|
|
|
1313
1343
|
**Permission:** `store:purchase`
|
|
@@ -1405,7 +1435,23 @@ the user moves the host themselves with browser back/forward. So a router
|
|
|
1405
1435
|
driven off `currentPath` stays in step with the address bar, and the back
|
|
1406
1436
|
button works the way your users expect — you do not have to mirror the path in
|
|
1407
1437
|
your own state. The dev harness echoes navigations the same way, so what you
|
|
1408
|
-
see locally is what ships.
|
|
1438
|
+
see locally is what ships. To test a deep link locally, open the harness with
|
|
1439
|
+
`?path=/map` (a root-relative path in your route space) and `currentPath`
|
|
1440
|
+
starts there instead of at `/`.
|
|
1441
|
+
|
|
1442
|
+
**Correcting the URL.** Every `navigateTo` pushes a history entry by default,
|
|
1443
|
+
which is right for navigation the user asked for. When you are CORRECTING the
|
|
1444
|
+
address bar instead — normalizing a link you were opened at (`/Map/` →
|
|
1445
|
+
`/map`), or putting it back after refusing a route — pass `{ replace: true }`
|
|
1446
|
+
so Back does not land on the URL you just corrected:
|
|
1447
|
+
|
|
1448
|
+
```tsx
|
|
1449
|
+
navigateTo('/map', { replace: true });
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1452
|
+
A host older than this option ignores it and pushes. If you correct paths
|
|
1453
|
+
automatically as they arrive, never repeat the same correction twice in a
|
|
1454
|
+
row, or a push-only host can trap the Back button between two URLs.
|
|
1409
1455
|
|
|
1410
1456
|
### Opening external links
|
|
1411
1457
|
|