@innspel/core 0.1.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/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/index.cjs +1441 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +579 -0
- package/dist/index.d.ts +579 -0
- package/dist/index.js +1432 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Niclas Amundsen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# @innspel/core
|
|
2
|
+
|
|
3
|
+
Kjernen i Innspels SDK. Ren TypeScript: ingen nettleser-API-er, ingen
|
|
4
|
+
runtime-avhengigheter (K19), ingen stabil identifikator på enheten (K20).
|
|
5
|
+
Lagring og identitet injiseres av verten.
|
|
6
|
+
|
|
7
|
+
Bygger du en React Native-app, installer [`@innspel/react-native`](../react-native)
|
|
8
|
+
i stedet — den gir deg widgeten og en lagringsadapter, og bruker denne pakken under.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @innspel/core
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quickstart
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { init } from '@innspel/core';
|
|
18
|
+
|
|
19
|
+
const innspel = init({
|
|
20
|
+
baseUrl: 'https://api.innspel.example', // din plattform-URL
|
|
21
|
+
tenantKey: 'ik_pub_xxxxxxxx', // offentlig SDK-nøkkel fra panelet
|
|
22
|
+
identityProvider: hentFeedbackToken, // eller null = anonym modus
|
|
23
|
+
storage, // se «Lagring» under
|
|
24
|
+
context: { platform: 'ios', appVersion: '1.4.2' },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
await innspel.capture({ type: 'feil', text: 'Dørlista er tom etter kl. 22.' });
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Det er hele veien til første innsending. Alt annet under er valgfritt.
|
|
31
|
+
|
|
32
|
+
## De fire opsjonene du må gi
|
|
33
|
+
|
|
34
|
+
| Opsjon | Hva |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `baseUrl` | Plattformens API-rot. Ingen standard — SDK-et skal aldri gjette hvor dataene dine havner. |
|
|
37
|
+
| `tenantKey` | Den offentlige SDK-nøkkelen. Skrivende, bundet til bundle-ID eller origin, kan aldri lese andres data (K3). Den hører hjemme i appens konfig, ikke i en hemmelighet. |
|
|
38
|
+
| `identityProvider` | Funksjon som gir et ferskt feedback-token, eller `null` for anonym modus. Se under. |
|
|
39
|
+
| `storage` | Tre metoder. Offline-køen bor her. |
|
|
40
|
+
|
|
41
|
+
`context.platform` er påkrevd; `appVersion`, `build`, `os`, `screen` og `locale` er
|
|
42
|
+
valgfrie. Feltlista er en **lukket hviteliste** (K5) — et ukjent felt avvises av
|
|
43
|
+
plattformen med `unknown_field`, og SDK-et sender aldri enhets-ID eller IP.
|
|
44
|
+
|
|
45
|
+
### Identitet
|
|
46
|
+
|
|
47
|
+
Plattformen eier aldri sluttbrukerne dine. Du utsteder et kortlevd token, den
|
|
48
|
+
verifiserer det og lærer aldri hvem det peker på:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const hentFeedbackToken = async () => {
|
|
52
|
+
const res = await fetch('https://din-app.example/api/innspel-token', {
|
|
53
|
+
headers: { Authorization: `Bearer ${dinEgenSesjon}` },
|
|
54
|
+
});
|
|
55
|
+
return (await res.json()).token; // ES256-JWT, aud=innspel, exp ≤ 15 min
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Token-endepunktet er det eneste du må bygge selv.
|
|
60
|
+
[Integrasjonsguiden](../../../docs/sdk/README.md) viser det med kjørbar kode.
|
|
61
|
+
|
|
62
|
+
`identityProvider: null` er **anonym modus**: innsendinger sendes uten avsender,
|
|
63
|
+
teller aldri i distinkt Reach og kan ikke følges opp. Det er et eksplisitt valg —
|
|
64
|
+
en glemt opsjon gir en feilmelding, aldri stille anonymitet.
|
|
65
|
+
|
|
66
|
+
Kaster funksjonen din, eller returnerer den `null`, faller SDK-et tilbake til
|
|
67
|
+
anonym modus for det kallet og logger `[innspel]` til konsollen. Innsenderen skal
|
|
68
|
+
kunne melde fra selv om innloggingen din er nede.
|
|
69
|
+
|
|
70
|
+
### Lagring
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
interface InnspelStorage {
|
|
74
|
+
get(key: string): Promise<string | null>;
|
|
75
|
+
set(key: string, value: string): Promise<void>;
|
|
76
|
+
remove(key: string): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Bruk hva du vil — MMKV, AsyncStorage, SQLite, et objekt i minnet.
|
|
81
|
+
`@innspel/react-native` gir deg en ferdig.
|
|
82
|
+
|
|
83
|
+
## API
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
innspel.capture({ type, text, context?, correlation?, relatedKnownIssueId?, clientRef? })
|
|
87
|
+
innspel.knownIssues.for({ screen?, version?, platform? }) // kortene som vises FØR feltet
|
|
88
|
+
innspel.knownIssues.confirm(id) // «Ja, jeg også» — Reach +1, ingen ny sak
|
|
89
|
+
innspel.subjects.submissions() // «Mine innspill», inkl. det som venter på nett
|
|
90
|
+
innspel.subjects.status(submissionId) // status for én egen innsending
|
|
91
|
+
innspel.programs.list() // invitasjoner, deltakelser, oppfølginger
|
|
92
|
+
innspel.queue.pending() // det som ligger i offline-køen
|
|
93
|
+
innspel.queue.flush() // sendes ellers automatisk
|
|
94
|
+
innspel.scanText(text) // mønstervarsel, se under
|
|
95
|
+
innspel.openFeedback() // krever @innspel/react-native
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Alt er dokumentert med TSDoc i editoren din. Typene er generert fra API-kontrakten,
|
|
99
|
+
så feltdokumentasjonen er den samme som plattformen håndhever.
|
|
100
|
+
|
|
101
|
+
### Offline-køen
|
|
102
|
+
|
|
103
|
+
Faller nettet, køes innsendingen lokalt — **kun teksten**, aldri et skjermbilde.
|
|
104
|
+
Taket er 30; innsending nummer 31 avvises med en synlig melding i stedet for å
|
|
105
|
+
kaste den eldste (DD-41). Køen tømmes når widgeten åpnes eller nettet kommer
|
|
106
|
+
tilbake, **aldri ved oppstart**, og hver flush henter et ferskt token — det gamle
|
|
107
|
+
er utløpt for lengst.
|
|
108
|
+
|
|
109
|
+
Vis køen for brukeren. `queue.pending()` gir deg radene, og «Venter på nett —
|
|
110
|
+
sendes automatisk» er teksten widgeten bruker.
|
|
111
|
+
|
|
112
|
+
### Mønstervarsel
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
innspel.scanText('Kontoen min er kari@example.com');
|
|
116
|
+
// [{ kind: 'email', match: 'kari@example.com', start: 15, end: 32 }]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Finner e-post, telefonnummer, kortnummer (Luhn-validert), IP-adresser og
|
|
120
|
+
token-lignende strenger. **Den fjerner aldri noe** (DD-46) — du viser funnet,
|
|
121
|
+
brukeren velger «Fjern» eller «Behold». Innsenderen skal alltid se hva som sendes.
|
|
122
|
+
|
|
123
|
+
### Telemetri
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
init({ …, telemetry: { emit: (e) => minAnalytics.track(e.name, e) } });
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Standard er `noop`. Hendelsene bærer aldri tekst, skjermbilde eller pseudonym.
|
|
130
|
+
Utelater du opsjonen, sendes ingenting noe sted.
|
|
131
|
+
|
|
132
|
+
## Feil
|
|
133
|
+
|
|
134
|
+
Alt fra plattformen kommer som `InnspelApiError` med en `code` du kan forgrene på —
|
|
135
|
+
aldri på meldingsteksten:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
try {
|
|
139
|
+
await innspel.capture({ type: 'feil', text });
|
|
140
|
+
} catch (e) {
|
|
141
|
+
if (e instanceof InnspelApiError && e.code === 'text_too_short') { … }
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`feedback_token_expired` håndteres internt: SDK-et ber `identityProvider` om et
|
|
146
|
+
nytt token og prøver på nytt, én gang. Den ser du aldri.
|
|
147
|
+
|
|
148
|
+
## Versjoner
|
|
149
|
+
|
|
150
|
+
Semver fra `0.1.0`. **Før `1.0.0` kan en minor bryte** — pin en eksakt versjon om
|
|
151
|
+
du trenger ro. Endringer i API-kontrakten er alltid minst minor, fordi de er en
|
|
152
|
+
SDK-endring hos deg.
|
|
153
|
+
|
|
154
|
+
## Grenser SDK-et holder
|
|
155
|
+
|
|
156
|
+
- Ingen tredjeparts-SDK: ingen analytics, ingen crash-rapportering, ingen annonser (K19)
|
|
157
|
+
- Ingen install-ID, ingen device-ID, ingen fingeravtrykk (K20). `clientRef` er en ny
|
|
158
|
+
UUID per innsending og identifiserer aldri enheten
|
|
159
|
+
- Ingen nettleser-API-er: `localStorage`, `document`, `window` og `navigator` finnes
|
|
160
|
+
ikke i denne pakken
|
|
161
|
+
- Under 10 kB gzip
|
|
162
|
+
|
|
163
|
+
## Lisens
|
|
164
|
+
|
|
165
|
+
MIT. Klientpakkene er permissivt lisensiert fordi koden kjører hos deg og må
|
|
166
|
+
kunne leses og granskes der. Plattformen bak — API, panel og drift — er det ikke.
|