@fias/create-fias-plugin 1.9.1 → 1.10.1
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.18.0 -->
|
|
2
2
|
|
|
3
3
|
# FIAS Plugin Development Guide
|
|
4
4
|
|
|
@@ -728,6 +728,18 @@ const { referenceId } = await vault.attach(documentId, {
|
|
|
728
728
|
await vault.detach(documentId, referenceId);
|
|
729
729
|
```
|
|
730
730
|
|
|
731
|
+
**Saving into the user's OWN files** — `upload(bytes, { ..., userVisible: true })`. By default everything your app writes here is _arche-private_: yours to read and write, invisible in the user's Fias files, unusable by other arches. That is the right home for your app's own state (caches, session snapshots, working files). It is the wrong home for the artifact the user made and asked you to keep — an edited image, an exported document — because they will go looking for it and it will not be there.
|
|
732
|
+
|
|
733
|
+
```tsx
|
|
734
|
+
const saved = await vault.upload(bytes, {
|
|
735
|
+
name: 'sunset.png',
|
|
736
|
+
mimeType: 'image/png',
|
|
737
|
+
userVisible: true,
|
|
738
|
+
});
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
Requires the `vault:user-documents:write` permission, and the HOST asks the user to confirm each save by name — you cannot script it, batch it, or pre-approve it. A decline rejects with `SAVE_DECLINED`; that is a normal outcome, not an error to retry. The file lands in `/My-Fias/<your arche's folder>/`, which the platform assigns — you cannot choose it, and `folderPath` is rejected alongside `userVisible`. Your arche must be registered for a user-visible folder platform-side (`ARCHE_NOT_REGISTERED_FOR_USER_VAULT` if not). Passing `replacesDocumentId` saves a new version in place; a version keeps its predecessor's visibility, so you cannot flip a user's visible file to private or vice versa (`VISIBILITY_MISMATCH`). Not available in preview or the dev harness — test it in the published plugin.
|
|
742
|
+
|
|
731
743
|
**Sensitivity tiers** (`'standard'` | `'confidential'` | `'proprietary'`) gate downstream read access per the Vault's standard matrix. Defaults to `'standard'`.
|
|
732
744
|
|
|
733
745
|
**`fetchVaultDocumentDownloadUrl(documentId)`** — non-React function that shares the hook's client-side URL cache. Use from PDF exporters, image preloaders, or other non-component code paths.
|
|
@@ -770,6 +782,34 @@ const { bytes } = await userDocs.getBytes(id); // raw bytes for PROCESSING binar
|
|
|
770
782
|
- Revocation behaves differently per method: `getBytes` and `get` re-check the grant on every call, so they start failing immediately. A URL already handed out by `getDownloadUrl` keeps working until it expires (1 hour) — that is the documented contract, not a bug.
|
|
771
783
|
- **Testable in the dev harness (mock mode).** `pick()` grants a small fixture set — a text file, a real PDF, and one deliberately over the 15 MB cap — and `list` / `get` / `getDownloadUrl` / `getBytes` all resolve against it, including the refusals (`BINARY_DOCUMENT` on a text read of a PDF, `CONSENTED_DOCUMENT_TOO_LARGE`, `DOCUMENT_NOT_FOUND`). Run the harness with `FIAS_HARNESS_VAULT_PICK=canceled` to exercise the cancel branch. Not available in the builder preview — `pick()` resolves `{ canceled: true }` there.
|
|
772
784
|
|
|
785
|
+
### `useArcheHandoff()` — Receive a document the user asked to open in your app
|
|
786
|
+
|
|
787
|
+
**Permission:** none to receive. Reading the document is a separate act (`vault:user-documents:read`, via `useVaultUserDocuments().getBytes`).
|
|
788
|
+
|
|
789
|
+
Fires when the user sends a document your way — "open this in <your app>" from the Fias AI assistant, from an email attachment, from any Vault document's "open in" affordance. You are only offered as a destination if the platform has registered your arche for document intake; declaring this hook does not enrol you.
|
|
790
|
+
|
|
791
|
+
```tsx
|
|
792
|
+
import { useArcheHandoff, useVaultUserDocuments } from '@fias/arche-sdk';
|
|
793
|
+
|
|
794
|
+
const userDocs = useVaultUserDocuments();
|
|
795
|
+
|
|
796
|
+
useArcheHandoff((payload) => {
|
|
797
|
+
if (payload.kind !== 'open_document') return; // switch on kind — the union grows
|
|
798
|
+
void (async () => {
|
|
799
|
+
const { bytes } = await userDocs.getBytes(payload.documentId);
|
|
800
|
+
// Open it as a NEW, UNSAVED document in your editor.
|
|
801
|
+
})();
|
|
802
|
+
});
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
**The contract:**
|
|
806
|
+
|
|
807
|
+
- You get a **reference, not bytes** — and the host grants you that one document as it relays the handoff, so `getBytes(documentId)` works without a `pick()` first. The grant is per-document and revocable in Vault → App Access exactly like a picked one. You must declare `vault:user-documents:read`; without it the grant is refused and the file never reaches you.
|
|
808
|
+
- **Open it as an unsaved copy.** A later save must create a NEW document. The source may be someone's email attachment or a shared file; it is never yours to mutate.
|
|
809
|
+
- **You are the type gate.** If you cannot open this file, say so plainly in your UI. Half-opening it is worse than refusing.
|
|
810
|
+
- Fires **once per handoff**, and one that arrives before your hook mounts is buffered and delivered on registration — so the first handoff of a session is never lost.
|
|
811
|
+
- Nothing hands documents to a preview, so the handler only fires in the published plugin.
|
|
812
|
+
|
|
773
813
|
### `useFiasAIActions()` — Let the platform's Fias AI assistant operate your plugin
|
|
774
814
|
|
|
775
815
|
**Permission:** `ai:actions`
|
|
@@ -939,8 +979,28 @@ navigateTo('/settings'); // within THIS arche's route space
|
|
|
939
979
|
// best-effort — the browser may block the popup, in which case the host
|
|
940
980
|
// navigates in the same tab instead.
|
|
941
981
|
openArche('arc_0123456789abcdef0123456789abcdef', { newTab: true });
|
|
982
|
+
|
|
983
|
+
// Land on a SPECIFIC page of the target arche instead of its home screen.
|
|
984
|
+
// `path` has no leading slash and is one or two `[A-Za-z0-9_-]` segments.
|
|
985
|
+
// Accepted for `arc_…` targets only — a path aimed at a first-party
|
|
986
|
+
// `arche_…` arche is rejected, as is a malformed one (you get an error, never
|
|
987
|
+
// a silent landing on the home screen).
|
|
988
|
+
openArche('arc_0123456789abcdef0123456789abcdef', { path: 'map' });
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
**Receiving a deep link.** There is nothing extra to opt into: `currentPath` in
|
|
992
|
+
the init payload is the full platform path the host loaded you at, so an arche
|
|
993
|
+
that wants to be a deep-link target just reads it once at boot.
|
|
994
|
+
|
|
995
|
+
```tsx
|
|
996
|
+
const { currentPath } = useFiasNavigation();
|
|
997
|
+
// e.g. '/a/arc_0123…/map' → 'map'
|
|
998
|
+
const page = currentPath.split('/').slice(3).join('/') || 'home';
|
|
942
999
|
```
|
|
943
1000
|
|
|
1001
|
+
It is set once, when your app mounts. A deep link from another arche always
|
|
1002
|
+
mounts you fresh, so that is exactly when you need it.
|
|
1003
|
+
|
|
944
1004
|
### Opening external links
|
|
945
1005
|
|
|
946
1006
|
To send the user to an external website (a YouTube video, docs, your homepage),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- fias-sdk-guide-version: 2.
|
|
1
|
+
<!-- fias-sdk-guide-version: 2.18.0 -->
|
|
2
2
|
|
|
3
3
|
# FIAS Plugin Development Guide
|
|
4
4
|
|
|
@@ -728,6 +728,18 @@ const { referenceId } = await vault.attach(documentId, {
|
|
|
728
728
|
await vault.detach(documentId, referenceId);
|
|
729
729
|
```
|
|
730
730
|
|
|
731
|
+
**Saving into the user's OWN files** — `upload(bytes, { ..., userVisible: true })`. By default everything your app writes here is _arche-private_: yours to read and write, invisible in the user's Fias files, unusable by other arches. That is the right home for your app's own state (caches, session snapshots, working files). It is the wrong home for the artifact the user made and asked you to keep — an edited image, an exported document — because they will go looking for it and it will not be there.
|
|
732
|
+
|
|
733
|
+
```tsx
|
|
734
|
+
const saved = await vault.upload(bytes, {
|
|
735
|
+
name: 'sunset.png',
|
|
736
|
+
mimeType: 'image/png',
|
|
737
|
+
userVisible: true,
|
|
738
|
+
});
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
Requires the `vault:user-documents:write` permission, and the HOST asks the user to confirm each save by name — you cannot script it, batch it, or pre-approve it. A decline rejects with `SAVE_DECLINED`; that is a normal outcome, not an error to retry. The file lands in `/My-Fias/<your arche's folder>/`, which the platform assigns — you cannot choose it, and `folderPath` is rejected alongside `userVisible`. Your arche must be registered for a user-visible folder platform-side (`ARCHE_NOT_REGISTERED_FOR_USER_VAULT` if not). Passing `replacesDocumentId` saves a new version in place; a version keeps its predecessor's visibility, so you cannot flip a user's visible file to private or vice versa (`VISIBILITY_MISMATCH`). Not available in preview or the dev harness — test it in the published plugin.
|
|
742
|
+
|
|
731
743
|
**Sensitivity tiers** (`'standard'` | `'confidential'` | `'proprietary'`) gate downstream read access per the Vault's standard matrix. Defaults to `'standard'`.
|
|
732
744
|
|
|
733
745
|
**`fetchVaultDocumentDownloadUrl(documentId)`** — non-React function that shares the hook's client-side URL cache. Use from PDF exporters, image preloaders, or other non-component code paths.
|
|
@@ -770,6 +782,34 @@ const { bytes } = await userDocs.getBytes(id); // raw bytes for PROCESSING binar
|
|
|
770
782
|
- Revocation behaves differently per method: `getBytes` and `get` re-check the grant on every call, so they start failing immediately. A URL already handed out by `getDownloadUrl` keeps working until it expires (1 hour) — that is the documented contract, not a bug.
|
|
771
783
|
- **Testable in the dev harness (mock mode).** `pick()` grants a small fixture set — a text file, a real PDF, and one deliberately over the 15 MB cap — and `list` / `get` / `getDownloadUrl` / `getBytes` all resolve against it, including the refusals (`BINARY_DOCUMENT` on a text read of a PDF, `CONSENTED_DOCUMENT_TOO_LARGE`, `DOCUMENT_NOT_FOUND`). Run the harness with `FIAS_HARNESS_VAULT_PICK=canceled` to exercise the cancel branch. Not available in the builder preview — `pick()` resolves `{ canceled: true }` there.
|
|
772
784
|
|
|
785
|
+
### `useArcheHandoff()` — Receive a document the user asked to open in your app
|
|
786
|
+
|
|
787
|
+
**Permission:** none to receive. Reading the document is a separate act (`vault:user-documents:read`, via `useVaultUserDocuments().getBytes`).
|
|
788
|
+
|
|
789
|
+
Fires when the user sends a document your way — "open this in <your app>" from the Fias AI assistant, from an email attachment, from any Vault document's "open in" affordance. You are only offered as a destination if the platform has registered your arche for document intake; declaring this hook does not enrol you.
|
|
790
|
+
|
|
791
|
+
```tsx
|
|
792
|
+
import { useArcheHandoff, useVaultUserDocuments } from '@fias/arche-sdk';
|
|
793
|
+
|
|
794
|
+
const userDocs = useVaultUserDocuments();
|
|
795
|
+
|
|
796
|
+
useArcheHandoff((payload) => {
|
|
797
|
+
if (payload.kind !== 'open_document') return; // switch on kind — the union grows
|
|
798
|
+
void (async () => {
|
|
799
|
+
const { bytes } = await userDocs.getBytes(payload.documentId);
|
|
800
|
+
// Open it as a NEW, UNSAVED document in your editor.
|
|
801
|
+
})();
|
|
802
|
+
});
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
**The contract:**
|
|
806
|
+
|
|
807
|
+
- You get a **reference, not bytes** — and the host grants you that one document as it relays the handoff, so `getBytes(documentId)` works without a `pick()` first. The grant is per-document and revocable in Vault → App Access exactly like a picked one. You must declare `vault:user-documents:read`; without it the grant is refused and the file never reaches you.
|
|
808
|
+
- **Open it as an unsaved copy.** A later save must create a NEW document. The source may be someone's email attachment or a shared file; it is never yours to mutate.
|
|
809
|
+
- **You are the type gate.** If you cannot open this file, say so plainly in your UI. Half-opening it is worse than refusing.
|
|
810
|
+
- Fires **once per handoff**, and one that arrives before your hook mounts is buffered and delivered on registration — so the first handoff of a session is never lost.
|
|
811
|
+
- Nothing hands documents to a preview, so the handler only fires in the published plugin.
|
|
812
|
+
|
|
773
813
|
### `useFiasAIActions()` — Let the platform's Fias AI assistant operate your plugin
|
|
774
814
|
|
|
775
815
|
**Permission:** `ai:actions`
|
|
@@ -939,8 +979,28 @@ navigateTo('/settings'); // within THIS arche's route space
|
|
|
939
979
|
// best-effort — the browser may block the popup, in which case the host
|
|
940
980
|
// navigates in the same tab instead.
|
|
941
981
|
openArche('arc_0123456789abcdef0123456789abcdef', { newTab: true });
|
|
982
|
+
|
|
983
|
+
// Land on a SPECIFIC page of the target arche instead of its home screen.
|
|
984
|
+
// `path` has no leading slash and is one or two `[A-Za-z0-9_-]` segments.
|
|
985
|
+
// Accepted for `arc_…` targets only — a path aimed at a first-party
|
|
986
|
+
// `arche_…` arche is rejected, as is a malformed one (you get an error, never
|
|
987
|
+
// a silent landing on the home screen).
|
|
988
|
+
openArche('arc_0123456789abcdef0123456789abcdef', { path: 'map' });
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
**Receiving a deep link.** There is nothing extra to opt into: `currentPath` in
|
|
992
|
+
the init payload is the full platform path the host loaded you at, so an arche
|
|
993
|
+
that wants to be a deep-link target just reads it once at boot.
|
|
994
|
+
|
|
995
|
+
```tsx
|
|
996
|
+
const { currentPath } = useFiasNavigation();
|
|
997
|
+
// e.g. '/a/arc_0123…/map' → 'map'
|
|
998
|
+
const page = currentPath.split('/').slice(3).join('/') || 'home';
|
|
942
999
|
```
|
|
943
1000
|
|
|
1001
|
+
It is set once, when your app mounts. A deep link from another arche always
|
|
1002
|
+
mounts you fresh, so that is exactly when you need it.
|
|
1003
|
+
|
|
944
1004
|
### Opening external links
|
|
945
1005
|
|
|
946
1006
|
To send the user to an external website (a YouTube video, docs, your homepage),
|