@nebulr-group/bridge-svelte 0.6.0 → 0.6.2
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/dist/client/stores/config.store.d.ts +14 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -0
- package/dist/shared/types/config.d.ts +28 -41
- package/dist/shared/types/published-config-type.test.d.ts +1 -0
- package/dist/shared/types/published-config-type.test.js +92 -0
- package/package.json +1 -1
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { RouteGuardConfig } from '../../auth/route-guard.js';
|
|
2
|
+
import type { BridgeConfig } from '../../shared/types/config.js';
|
|
3
|
+
interface ConfigStoreState {
|
|
4
|
+
config: BridgeConfig | null;
|
|
5
|
+
routeConfig: RouteGuardConfig | null;
|
|
6
|
+
loaded: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const bridgeConfig: {
|
|
9
|
+
subscribe: (this: void, run: import("svelte/store").Subscriber<ConfigStoreState>, invalidate?: () => void) => import("svelte/store").Unsubscriber;
|
|
10
|
+
initConfig: (config: BridgeConfig, routeConfig?: RouteGuardConfig) => void;
|
|
11
|
+
};
|
|
4
12
|
export declare const configReady: import("svelte/store").Readable<boolean>;
|
|
5
|
-
export declare
|
|
13
|
+
export declare const readonlyConfig: import("svelte/store").Readable<BridgeConfig | null>;
|
|
6
14
|
export declare function getConfig(): BridgeConfig;
|
|
15
|
+
export declare function getRouteGuardConfig(): RouteGuardConfig;
|
|
16
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -51,3 +51,5 @@ export type { Operator, AttributeType, Condition, ConditionValue, ValidationErro
|
|
|
51
51
|
export type { FlagResponse, CreateFlagInput, UpdateFlagInput, FlagSchedule, } from '@nebulr-group/bridge-auth-core';
|
|
52
52
|
export { DEFAULT_RETURN_TO_PARAM, readReturnTo, sanitizeReturnTo, withReturnTo, } from '@nebulr-group/bridge-auth-core';
|
|
53
53
|
export type { ReturnToConfig } from '@nebulr-group/bridge-auth-core';
|
|
54
|
+
export { createTranslator, en, hasLocale, interpolate, LOCALES, normalizeLocale, sv, } from '@nebulr-group/bridge-auth-core';
|
|
55
|
+
export type { MessageKey, MessageOverrides, Messages, Translator, } from '@nebulr-group/bridge-auth-core';
|
package/dist/index.js
CHANGED
|
@@ -71,3 +71,12 @@ export { BridgeFlags, BridgeIdentity, MemoryIdentityStorage, attachIdentity, gen
|
|
|
71
71
|
// login page can import the reader (and its open-redirect validation) from the
|
|
72
72
|
// same package it already depends on, instead of reaching past bridge-svelte.
|
|
73
73
|
export { DEFAULT_RETURN_TO_PARAM, readReturnTo, sanitizeReturnTo, withReturnTo, } from '@nebulr-group/bridge-auth-core';
|
|
74
|
+
// TBP-630 — SDK auth copy / translations. Re-exported from auth-core for the
|
|
75
|
+
// same reason as the return-to helpers above: a consumer building its own
|
|
76
|
+
// locale catalogue should import from the package it already depends on rather
|
|
77
|
+
// than reaching past bridge-svelte to a peer dependency it never declared —
|
|
78
|
+
// which pnpm's default layout and Yarn PnP refuse outright.
|
|
79
|
+
//
|
|
80
|
+
// bridge-react, -angular and -nextjs already export this surface; svelte was
|
|
81
|
+
// the odd one out.
|
|
82
|
+
export { createTranslator, en, hasLocale, interpolate, LOCALES, normalizeLocale, sv, } from '@nebulr-group/bridge-auth-core';
|
|
@@ -1,42 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* @default '/login'
|
|
30
|
-
*/
|
|
31
|
-
loginRoute?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Debug mode
|
|
34
|
-
* @default false
|
|
35
|
-
*/
|
|
36
|
-
debug?: boolean;
|
|
37
|
-
}
|
|
38
|
-
export interface TokenSet {
|
|
39
|
-
accessToken: string;
|
|
40
|
-
refreshToken: string;
|
|
41
|
-
idToken: string;
|
|
1
|
+
import type { BridgeAuthConfig, MessageOverrides } from '@nebulr-group/bridge-auth-core';
|
|
2
|
+
export type { TokenSet } from '@nebulr-group/bridge-auth-core';
|
|
3
|
+
export interface BridgeConfig extends BridgeAuthConfig {
|
|
4
|
+
/** Route where your signup page lives (e.g. '/auth/signup').
|
|
5
|
+
* Used by LoginForm to link to the signup page. */
|
|
6
|
+
signupRoute?: string;
|
|
7
|
+
/** UI language for the SDK auth components, e.g. 'sv' or 'sv-SE' (TBP-630).
|
|
8
|
+
* Region variants resolve to their primary subtag; an unknown locale falls
|
|
9
|
+
* back to English rather than throwing.
|
|
10
|
+
* @default 'en' */
|
|
11
|
+
locale?: string;
|
|
12
|
+
/** Per-key copy overrides applied on top of the resolved locale, for wording
|
|
13
|
+
* an app genuinely needs to differ. Highest precedence in the chain. */
|
|
14
|
+
messages?: MessageOverrides;
|
|
15
|
+
/** Billing paywall configuration. When set, Bridge redirects unauthenticated
|
|
16
|
+
* or plan-less users to `paywallRoute` before the page renders. */
|
|
17
|
+
billing?: {
|
|
18
|
+
/** Route to redirect to when the tenant has no plan selected.
|
|
19
|
+
* e.g. '/onboarding/plan' or '/subscription' */
|
|
20
|
+
paywallRoute?: string;
|
|
21
|
+
/** Route to redirect to when a Stripe checkout confirmation fails.
|
|
22
|
+
* Defaults to '/payment-error'. */
|
|
23
|
+
paymentErrorRoute?: string;
|
|
24
|
+
/** Route where your plan/billing management page lives — the default
|
|
25
|
+
* destination of the Upgrade/Manage CTA in <BridgeQuotaBanner> and
|
|
26
|
+
* <BridgeBillingNotice>. Defaults to '/billing'. */
|
|
27
|
+
manageRoute?: string;
|
|
28
|
+
};
|
|
42
29
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guard: the declaration files we SHIP must be generated from source, never
|
|
3
|
+
* hand-written next to it (TBP-630).
|
|
4
|
+
*
|
|
5
|
+
* ## What went wrong
|
|
6
|
+
*
|
|
7
|
+
* `src/lib/shared/types/` held both `config.ts` and a hand-written
|
|
8
|
+
* `config.d.ts`. `svelte-package` copies a `.d.ts` it finds in `src/lib`
|
|
9
|
+
* straight through to `dist` instead of emitting one from the sibling `.ts`, so
|
|
10
|
+
* the stale hand-written file WON in the published package. `bridge-svelte@0.6.0`
|
|
11
|
+
* shipped a `BridgeConfig` that declared seven fields and omitted `signupRoute`,
|
|
12
|
+
* `billing`, `locale` and `messages` — and typed `appId` as required, which the
|
|
13
|
+
* real interface does not.
|
|
14
|
+
*
|
|
15
|
+
* The consequence was not cosmetic. TBP-630's documented path — set the language
|
|
16
|
+
* once via `config.locale` — did not compile for a TypeScript consumer:
|
|
17
|
+
*
|
|
18
|
+
* const c: BridgeConfig = { appId: 'x', locale: 'sv' };
|
|
19
|
+
* // Object literal may only specify known properties,
|
|
20
|
+
* // and 'locale' does not exist in type 'BridgeConfig'.
|
|
21
|
+
*
|
|
22
|
+
* The runtime read `locale` correctly the whole time. Only the type lied, which
|
|
23
|
+
* is the worst version of this: everything works until you try to write it down.
|
|
24
|
+
*
|
|
25
|
+
* ## Why the guard is shaped like this
|
|
26
|
+
*
|
|
27
|
+
* The obvious test — assign `{ appId, locale }` to `BridgeConfig` and see it
|
|
28
|
+
* compile — passes against SOURCE and always would have. It cannot see the bug,
|
|
29
|
+
* because the bug is in what packaging chose to copy. So the assertion has to be
|
|
30
|
+
* about the file layout that made packaging choose wrong: under `src/lib`, a
|
|
31
|
+
* `.d.ts` may not sit beside a `.ts` of the same name.
|
|
32
|
+
*
|
|
33
|
+
* Two other files had the same shadow and the same rot: `config.store.d.ts`
|
|
34
|
+
* declared `initConfig` as a free function (it is a method on `bridgeConfig`)
|
|
35
|
+
* and omitted `getRouteGuardConfig` entirely. This was never about one field.
|
|
36
|
+
*/
|
|
37
|
+
import { describe, it, expect } from 'vitest';
|
|
38
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
39
|
+
import { join, dirname, resolve } from 'node:path';
|
|
40
|
+
import { fileURLToPath } from 'node:url';
|
|
41
|
+
const LIB_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
|
|
42
|
+
function walk(dir) {
|
|
43
|
+
const out = [];
|
|
44
|
+
for (const entry of readdirSync(dir)) {
|
|
45
|
+
const full = join(dir, entry);
|
|
46
|
+
if (statSync(full).isDirectory()) {
|
|
47
|
+
out.push(...walk(full));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
out.push(full);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
describe('packaged declarations are generated, not hand-written', () => {
|
|
56
|
+
const files = walk(LIB_ROOT);
|
|
57
|
+
it('finds the lib root it is supposed to be scanning', () => {
|
|
58
|
+
// Without this, a bad path would make every assertion below vacuously true —
|
|
59
|
+
// the guard would report green precisely when it had stopped looking.
|
|
60
|
+
expect(files.length).toBeGreaterThan(50);
|
|
61
|
+
expect(files.some((f) => f.endsWith('/shared/types/config.ts'))).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
it('has no .d.ts shadowing a sibling .ts anywhere under src/lib', () => {
|
|
64
|
+
const shadowed = files
|
|
65
|
+
.filter((f) => f.endsWith('.d.ts'))
|
|
66
|
+
.filter((f) => files.includes(`${f.slice(0, -'.d.ts'.length)}.ts`))
|
|
67
|
+
.map((f) => f.slice(LIB_ROOT.length + 1));
|
|
68
|
+
// svelte-package copies these verbatim into dist, so whatever they say is
|
|
69
|
+
// what consumers get — regardless of what the .ts next to them says.
|
|
70
|
+
expect(shadowed).toEqual([]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
/**
|
|
75
|
+
* Compile-time half, checked by `svelte-check` in CI.
|
|
76
|
+
*
|
|
77
|
+
* This is the assertion the consumer asked for, and on its own it is NOT the
|
|
78
|
+
* guard — it passed throughout the broken release, because source was always
|
|
79
|
+
* right. It earns its place by covering the other direction: somebody deleting
|
|
80
|
+
* `locale` from `config.ts` rather than packaging shipping the wrong file.
|
|
81
|
+
*/
|
|
82
|
+
const _localeIsAssignable = {
|
|
83
|
+
appId: 'x',
|
|
84
|
+
locale: 'sv',
|
|
85
|
+
messages: { 'login.submit': 'Logga in' },
|
|
86
|
+
};
|
|
87
|
+
describe('BridgeConfig accepts the documented i18n fields', () => {
|
|
88
|
+
it('compiles and carries them at runtime', () => {
|
|
89
|
+
expect(_localeIsAssignable.locale).toBe('sv');
|
|
90
|
+
expect(_localeIsAssignable.messages?.['login.submit']).toBe('Logga in');
|
|
91
|
+
});
|
|
92
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebulr-group/bridge-svelte",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Bridge Svelte library, This library helps you to add bridge authentication and feature flags, and payments to your svelte application.",
|
|
5
5
|
"author": "Iman Pouya",
|
|
6
6
|
"license": "MIT",
|