@authon/angular 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/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # @authon/angular
2
+
3
+ Angular SDK for [Authon](https://authon.dev) — service, guard, and interceptor.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @authon/angular
9
+ # or
10
+ pnpm add @authon/angular
11
+ ```
12
+
13
+ Requires `@angular/core >= 16.0.0`.
14
+
15
+ ## Quick Start
16
+
17
+ ### 1. Import Module
18
+
19
+ ```ts
20
+ // app.config.ts
21
+ import { provideAuthon } from '@authon/angular';
22
+
23
+ export const appConfig = {
24
+ providers: [
25
+ provideAuthon({
26
+ publishableKey: 'pk_live_...',
27
+ }),
28
+ ],
29
+ };
30
+ ```
31
+
32
+ ### 2. Use the Service
33
+
34
+ ```ts
35
+ import { Component } from '@angular/core';
36
+ import { AuthonService } from '@authon/angular';
37
+
38
+ @Component({
39
+ selector: 'app-header',
40
+ template: `
41
+ @if (auth.isSignedIn()) {
42
+ <button (click)="auth.signOut()">Sign Out</button>
43
+ <p>{{ auth.user()?.displayName }}</p>
44
+ } @else {
45
+ <button (click)="auth.openSignIn()">Sign In</button>
46
+ }
47
+ `,
48
+ })
49
+ export class HeaderComponent {
50
+ constructor(public auth: AuthonService) {}
51
+ }
52
+ ```
53
+
54
+ ### 3. Route Guard
55
+
56
+ ```ts
57
+ // app.routes.ts
58
+ import { authGuard } from '@authon/angular';
59
+
60
+ export const routes = [
61
+ { path: 'dashboard', component: DashboardComponent, canActivate: [authGuard] },
62
+ { path: 'login', component: LoginComponent },
63
+ ];
64
+ ```
65
+
66
+ ### 4. HTTP Interceptor
67
+
68
+ Automatically attach the access token to outgoing requests:
69
+
70
+ ```ts
71
+ // app.config.ts
72
+ import { provideAuthon, authInterceptor } from '@authon/angular';
73
+ import { provideHttpClient, withInterceptors } from '@angular/common/http';
74
+
75
+ export const appConfig = {
76
+ providers: [
77
+ provideAuthon({ publishableKey: 'pk_live_...' }),
78
+ provideHttpClient(withInterceptors([authInterceptor])),
79
+ ],
80
+ };
81
+ ```
82
+
83
+ ## API Reference
84
+
85
+ ### `AuthonService`
86
+
87
+ | Property / Method | Type | Description |
88
+ |-------------------|------|-------------|
89
+ | `user()` | `Signal<AuthonUser \| null>` | Current user signal |
90
+ | `isSignedIn()` | `Signal<boolean>` | Whether signed in |
91
+ | `isLoading()` | `Signal<boolean>` | Loading state |
92
+ | `openSignIn()` | `Promise<void>` | Open sign-in modal |
93
+ | `openSignUp()` | `Promise<void>` | Open sign-up modal |
94
+ | `signOut()` | `Promise<void>` | Sign out |
95
+ | `getToken()` | `string \| null` | Get current access token |
96
+
97
+ ### Guard
98
+
99
+ | Export | Description |
100
+ |--------|-------------|
101
+ | `authGuard` | `CanActivateFn` that redirects unauthenticated users |
102
+
103
+ ### Interceptor
104
+
105
+ | Export | Description |
106
+ |--------|-------------|
107
+ | `authInterceptor` | `HttpInterceptorFn` that adds Bearer token to requests |
108
+
109
+ ## Documentation
110
+
111
+ [authon.dev/docs](https://authon.dev/docs)
112
+
113
+ ## License
114
+
115
+ [MIT](../../LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AUTHON_CONFIG: () => AUTHON_CONFIG,
24
+ AuthonService: () => AuthonService,
25
+ authGuard: () => authGuard,
26
+ provideAuthon: () => provideAuthon
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/service.ts
31
+ var import_js = require("@authon/js");
32
+ var AUTHON_CONFIG = "AUTHON_CONFIG";
33
+ var AuthonService = class {
34
+ client;
35
+ _user = null;
36
+ _isSignedIn = false;
37
+ _isLoading = true;
38
+ _listeners = [];
39
+ constructor(config) {
40
+ this.client = new import_js.Authon(config.publishableKey, config.config);
41
+ this.client.on("signedIn", (user) => {
42
+ this._user = user;
43
+ this._isSignedIn = true;
44
+ this._isLoading = false;
45
+ this.notifyListeners();
46
+ });
47
+ this.client.on("signedOut", () => {
48
+ this._user = null;
49
+ this._isSignedIn = false;
50
+ this.notifyListeners();
51
+ });
52
+ this.client.on("error", () => {
53
+ this._isLoading = false;
54
+ this.notifyListeners();
55
+ });
56
+ this._isLoading = false;
57
+ }
58
+ get user() {
59
+ return this._user;
60
+ }
61
+ get isSignedIn() {
62
+ return this._isSignedIn;
63
+ }
64
+ get isLoading() {
65
+ return this._isLoading;
66
+ }
67
+ async openSignIn() {
68
+ await this.client.openSignIn();
69
+ }
70
+ async openSignUp() {
71
+ await this.client.openSignUp();
72
+ }
73
+ async signOut() {
74
+ await this.client.signOut();
75
+ this._user = null;
76
+ this._isSignedIn = false;
77
+ this.notifyListeners();
78
+ }
79
+ getToken() {
80
+ return this.client.getToken();
81
+ }
82
+ getClient() {
83
+ return this.client;
84
+ }
85
+ /**
86
+ * Subscribe to auth state changes.
87
+ * Returns an unsubscribe function.
88
+ */
89
+ onStateChange(callback) {
90
+ this._listeners.push(callback);
91
+ return () => {
92
+ this._listeners = this._listeners.filter((l) => l !== callback);
93
+ };
94
+ }
95
+ destroy() {
96
+ this.client.destroy();
97
+ this._listeners = [];
98
+ }
99
+ notifyListeners() {
100
+ for (const listener of this._listeners) {
101
+ listener();
102
+ }
103
+ }
104
+ };
105
+
106
+ // src/guard.ts
107
+ function authGuard(authonService, redirectTo = "/sign-in") {
108
+ if (authonService.isLoading) {
109
+ return false;
110
+ }
111
+ if (!authonService.isSignedIn) {
112
+ return { path: redirectTo };
113
+ }
114
+ return true;
115
+ }
116
+
117
+ // src/helpers.ts
118
+ function provideAuthon(config) {
119
+ const service = new AuthonService(config);
120
+ return [
121
+ { provide: AUTHON_CONFIG, useValue: config },
122
+ { provide: "AuthonService", useValue: service }
123
+ ];
124
+ }
125
+ // Annotate the CommonJS export names for ESM import in node:
126
+ 0 && (module.exports = {
127
+ AUTHON_CONFIG,
128
+ AuthonService,
129
+ authGuard,
130
+ provideAuthon
131
+ });
132
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/service.ts","../src/guard.ts","../src/helpers.ts"],"sourcesContent":["export { AuthonService, AUTHON_CONFIG, type AuthonServiceConfig } from './service';\nexport { authGuard } from './guard';\nexport { provideAuthon } from './helpers';\n","import { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\n/**\n * Injection token key for Authon configuration.\n * Used with Angular's InjectionToken.\n */\nexport const AUTHON_CONFIG = 'AUTHON_CONFIG';\n\nexport interface AuthonServiceConfig {\n publishableKey: string;\n config?: Omit<AuthonConfig, 'mode'>;\n}\n\n/**\n * Plain class wrapping @authon/js for Angular dependency injection.\n *\n * Since tsup cannot compile Angular decorators, this is a plain class.\n * Users should wrap it in their own injectable service:\n *\n * ```ts\n * import { Injectable } from '@angular/core';\n * import { AuthonService as BaseAuthonService } from '@authon/angular';\n *\n * @Injectable({ providedIn: 'root' })\n * export class AuthonService extends BaseAuthonService {\n * constructor() {\n * super({ publishableKey: 'pk_live_...' });\n * }\n * }\n * ```\n *\n * Or use the `provideAuthon()` helper for standalone components.\n */\nexport class AuthonService {\n private client: Authon;\n private _user: AuthonUser | null = null;\n private _isSignedIn = false;\n private _isLoading = true;\n private _listeners: Array<() => void> = [];\n\n constructor(config: AuthonServiceConfig) {\n this.client = new Authon(config.publishableKey, config.config);\n\n this.client.on('signedIn', (user) => {\n this._user = user as AuthonUser;\n this._isSignedIn = true;\n this._isLoading = false;\n this.notifyListeners();\n });\n\n this.client.on('signedOut', () => {\n this._user = null;\n this._isSignedIn = false;\n this.notifyListeners();\n });\n\n this.client.on('error', () => {\n this._isLoading = false;\n this.notifyListeners();\n });\n\n this._isLoading = false;\n }\n\n get user(): AuthonUser | null {\n return this._user;\n }\n\n get isSignedIn(): boolean {\n return this._isSignedIn;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n async openSignIn(): Promise<void> {\n await this.client.openSignIn();\n }\n\n async openSignUp(): Promise<void> {\n await this.client.openSignUp();\n }\n\n async signOut(): Promise<void> {\n await this.client.signOut();\n this._user = null;\n this._isSignedIn = false;\n this.notifyListeners();\n }\n\n getToken(): string | null {\n return this.client.getToken();\n }\n\n getClient(): Authon {\n return this.client;\n }\n\n /**\n * Subscribe to auth state changes.\n * Returns an unsubscribe function.\n */\n onStateChange(callback: () => void): () => void {\n this._listeners.push(callback);\n return () => {\n this._listeners = this._listeners.filter((l) => l !== callback);\n };\n }\n\n destroy(): void {\n this.client.destroy();\n this._listeners = [];\n }\n\n private notifyListeners(): void {\n for (const listener of this._listeners) {\n listener();\n }\n }\n}\n","import type { AuthonService } from './service';\n\n/**\n * Route guard factory for Angular Router (CanActivateFn style).\n *\n * Since tsup can't compile Angular decorators, this returns a plain function.\n * Users wire it up in their route config:\n *\n * ```ts\n * import { inject } from '@angular/core';\n * import { authGuard } from '@authon/angular';\n * import { AuthonService } from './authon.service'; // your injectable wrapper\n *\n * const routes = [\n * {\n * path: 'dashboard',\n * component: DashboardComponent,\n * canActivate: [() => {\n * const authon = inject(AuthonService);\n * return authGuard(authon, '/login');\n * }],\n * },\n * ];\n * ```\n */\nexport function authGuard(\n authonService: AuthonService,\n redirectTo = '/sign-in',\n): boolean | { path: string } {\n if (authonService.isLoading) {\n return false;\n }\n\n if (!authonService.isSignedIn) {\n return { path: redirectTo };\n }\n\n return true;\n}\n","import { AuthonService, AUTHON_CONFIG, type AuthonServiceConfig } from './service';\n\n/**\n * Provider factory for Angular standalone components.\n *\n * Usage in app.config.ts:\n * ```ts\n * import { provideAuthon } from '@authon/angular';\n *\n * export const appConfig = {\n * providers: [\n * ...provideAuthon({ publishableKey: 'pk_live_...' }),\n * ],\n * };\n * ```\n *\n * Then inject in your components:\n * ```ts\n * import { Inject } from '@angular/core';\n * import { AUTHON_CONFIG, AuthonService } from '@authon/angular';\n *\n * constructor(@Inject('AuthonService') private authon: AuthonService) {}\n * ```\n */\nexport function provideAuthon(config: AuthonServiceConfig) {\n const service = new AuthonService(config);\n\n return [\n { provide: AUTHON_CONFIG, useValue: config },\n { provide: 'AuthonService', useValue: service },\n ];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,gBAAuB;AAQhB,IAAM,gBAAgB;AA2BtB,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA,QAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,aAAa;AAAA,EACb,aAAgC,CAAC;AAAA,EAEzC,YAAY,QAA6B;AACvC,SAAK,SAAS,IAAI,iBAAO,OAAO,gBAAgB,OAAO,MAAM;AAE7D,SAAK,OAAO,GAAG,YAAY,CAAC,SAAS;AACnC,WAAK,QAAQ;AACb,WAAK,cAAc;AACnB,WAAK,aAAa;AAClB,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAED,SAAK,OAAO,GAAG,aAAa,MAAM;AAChC,WAAK,QAAQ;AACb,WAAK,cAAc;AACnB,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAED,SAAK,OAAO,GAAG,SAAS,MAAM;AAC5B,WAAK,aAAa;AAClB,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAED,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,IAAI,OAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,KAAK,OAAO,WAAW;AAAA,EAC/B;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,KAAK,OAAO,WAAW;AAAA,EAC/B;AAAA,EAEA,MAAM,UAAyB;AAC7B,UAAM,KAAK,OAAO,QAAQ;AAC1B,SAAK,QAAQ;AACb,SAAK,cAAc;AACnB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,WAA0B;AACxB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,UAAkC;AAC9C,SAAK,WAAW,KAAK,QAAQ;AAC7B,WAAO,MAAM;AACX,WAAK,aAAa,KAAK,WAAW,OAAO,CAAC,MAAM,MAAM,QAAQ;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,QAAQ;AACpB,SAAK,aAAa,CAAC;AAAA,EACrB;AAAA,EAEQ,kBAAwB;AAC9B,eAAW,YAAY,KAAK,YAAY;AACtC,eAAS;AAAA,IACX;AAAA,EACF;AACF;;;ACjGO,SAAS,UACd,eACA,aAAa,YACe;AAC5B,MAAI,cAAc,WAAW;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,cAAc,YAAY;AAC7B,WAAO,EAAE,MAAM,WAAW;AAAA,EAC5B;AAEA,SAAO;AACT;;;ACdO,SAAS,cAAc,QAA6B;AACzD,QAAM,UAAU,IAAI,cAAc,MAAM;AAExC,SAAO;AAAA,IACL,EAAE,SAAS,eAAe,UAAU,OAAO;AAAA,IAC3C,EAAE,SAAS,iBAAiB,UAAU,QAAQ;AAAA,EAChD;AACF;","names":[]}
@@ -0,0 +1,114 @@
1
+ import { AuthonConfig, Authon } from '@authon/js';
2
+ import { AuthonUser } from '@authon/shared';
3
+
4
+ /**
5
+ * Injection token key for Authon configuration.
6
+ * Used with Angular's InjectionToken.
7
+ */
8
+ declare const AUTHON_CONFIG = "AUTHON_CONFIG";
9
+ interface AuthonServiceConfig {
10
+ publishableKey: string;
11
+ config?: Omit<AuthonConfig, 'mode'>;
12
+ }
13
+ /**
14
+ * Plain class wrapping @authon/js for Angular dependency injection.
15
+ *
16
+ * Since tsup cannot compile Angular decorators, this is a plain class.
17
+ * Users should wrap it in their own injectable service:
18
+ *
19
+ * ```ts
20
+ * import { Injectable } from '@angular/core';
21
+ * import { AuthonService as BaseAuthonService } from '@authon/angular';
22
+ *
23
+ * @Injectable({ providedIn: 'root' })
24
+ * export class AuthonService extends BaseAuthonService {
25
+ * constructor() {
26
+ * super({ publishableKey: 'pk_live_...' });
27
+ * }
28
+ * }
29
+ * ```
30
+ *
31
+ * Or use the `provideAuthon()` helper for standalone components.
32
+ */
33
+ declare class AuthonService {
34
+ private client;
35
+ private _user;
36
+ private _isSignedIn;
37
+ private _isLoading;
38
+ private _listeners;
39
+ constructor(config: AuthonServiceConfig);
40
+ get user(): AuthonUser | null;
41
+ get isSignedIn(): boolean;
42
+ get isLoading(): boolean;
43
+ openSignIn(): Promise<void>;
44
+ openSignUp(): Promise<void>;
45
+ signOut(): Promise<void>;
46
+ getToken(): string | null;
47
+ getClient(): Authon;
48
+ /**
49
+ * Subscribe to auth state changes.
50
+ * Returns an unsubscribe function.
51
+ */
52
+ onStateChange(callback: () => void): () => void;
53
+ destroy(): void;
54
+ private notifyListeners;
55
+ }
56
+
57
+ /**
58
+ * Route guard factory for Angular Router (CanActivateFn style).
59
+ *
60
+ * Since tsup can't compile Angular decorators, this returns a plain function.
61
+ * Users wire it up in their route config:
62
+ *
63
+ * ```ts
64
+ * import { inject } from '@angular/core';
65
+ * import { authGuard } from '@authon/angular';
66
+ * import { AuthonService } from './authon.service'; // your injectable wrapper
67
+ *
68
+ * const routes = [
69
+ * {
70
+ * path: 'dashboard',
71
+ * component: DashboardComponent,
72
+ * canActivate: [() => {
73
+ * const authon = inject(AuthonService);
74
+ * return authGuard(authon, '/login');
75
+ * }],
76
+ * },
77
+ * ];
78
+ * ```
79
+ */
80
+ declare function authGuard(authonService: AuthonService, redirectTo?: string): boolean | {
81
+ path: string;
82
+ };
83
+
84
+ /**
85
+ * Provider factory for Angular standalone components.
86
+ *
87
+ * Usage in app.config.ts:
88
+ * ```ts
89
+ * import { provideAuthon } from '@authon/angular';
90
+ *
91
+ * export const appConfig = {
92
+ * providers: [
93
+ * ...provideAuthon({ publishableKey: 'pk_live_...' }),
94
+ * ],
95
+ * };
96
+ * ```
97
+ *
98
+ * Then inject in your components:
99
+ * ```ts
100
+ * import { Inject } from '@angular/core';
101
+ * import { AUTHON_CONFIG, AuthonService } from '@authon/angular';
102
+ *
103
+ * constructor(@Inject('AuthonService') private authon: AuthonService) {}
104
+ * ```
105
+ */
106
+ declare function provideAuthon(config: AuthonServiceConfig): ({
107
+ provide: string;
108
+ useValue: AuthonServiceConfig;
109
+ } | {
110
+ provide: string;
111
+ useValue: AuthonService;
112
+ })[];
113
+
114
+ export { AUTHON_CONFIG, AuthonService, type AuthonServiceConfig, authGuard, provideAuthon };
@@ -0,0 +1,114 @@
1
+ import { AuthonConfig, Authon } from '@authon/js';
2
+ import { AuthonUser } from '@authon/shared';
3
+
4
+ /**
5
+ * Injection token key for Authon configuration.
6
+ * Used with Angular's InjectionToken.
7
+ */
8
+ declare const AUTHON_CONFIG = "AUTHON_CONFIG";
9
+ interface AuthonServiceConfig {
10
+ publishableKey: string;
11
+ config?: Omit<AuthonConfig, 'mode'>;
12
+ }
13
+ /**
14
+ * Plain class wrapping @authon/js for Angular dependency injection.
15
+ *
16
+ * Since tsup cannot compile Angular decorators, this is a plain class.
17
+ * Users should wrap it in their own injectable service:
18
+ *
19
+ * ```ts
20
+ * import { Injectable } from '@angular/core';
21
+ * import { AuthonService as BaseAuthonService } from '@authon/angular';
22
+ *
23
+ * @Injectable({ providedIn: 'root' })
24
+ * export class AuthonService extends BaseAuthonService {
25
+ * constructor() {
26
+ * super({ publishableKey: 'pk_live_...' });
27
+ * }
28
+ * }
29
+ * ```
30
+ *
31
+ * Or use the `provideAuthon()` helper for standalone components.
32
+ */
33
+ declare class AuthonService {
34
+ private client;
35
+ private _user;
36
+ private _isSignedIn;
37
+ private _isLoading;
38
+ private _listeners;
39
+ constructor(config: AuthonServiceConfig);
40
+ get user(): AuthonUser | null;
41
+ get isSignedIn(): boolean;
42
+ get isLoading(): boolean;
43
+ openSignIn(): Promise<void>;
44
+ openSignUp(): Promise<void>;
45
+ signOut(): Promise<void>;
46
+ getToken(): string | null;
47
+ getClient(): Authon;
48
+ /**
49
+ * Subscribe to auth state changes.
50
+ * Returns an unsubscribe function.
51
+ */
52
+ onStateChange(callback: () => void): () => void;
53
+ destroy(): void;
54
+ private notifyListeners;
55
+ }
56
+
57
+ /**
58
+ * Route guard factory for Angular Router (CanActivateFn style).
59
+ *
60
+ * Since tsup can't compile Angular decorators, this returns a plain function.
61
+ * Users wire it up in their route config:
62
+ *
63
+ * ```ts
64
+ * import { inject } from '@angular/core';
65
+ * import { authGuard } from '@authon/angular';
66
+ * import { AuthonService } from './authon.service'; // your injectable wrapper
67
+ *
68
+ * const routes = [
69
+ * {
70
+ * path: 'dashboard',
71
+ * component: DashboardComponent,
72
+ * canActivate: [() => {
73
+ * const authon = inject(AuthonService);
74
+ * return authGuard(authon, '/login');
75
+ * }],
76
+ * },
77
+ * ];
78
+ * ```
79
+ */
80
+ declare function authGuard(authonService: AuthonService, redirectTo?: string): boolean | {
81
+ path: string;
82
+ };
83
+
84
+ /**
85
+ * Provider factory for Angular standalone components.
86
+ *
87
+ * Usage in app.config.ts:
88
+ * ```ts
89
+ * import { provideAuthon } from '@authon/angular';
90
+ *
91
+ * export const appConfig = {
92
+ * providers: [
93
+ * ...provideAuthon({ publishableKey: 'pk_live_...' }),
94
+ * ],
95
+ * };
96
+ * ```
97
+ *
98
+ * Then inject in your components:
99
+ * ```ts
100
+ * import { Inject } from '@angular/core';
101
+ * import { AUTHON_CONFIG, AuthonService } from '@authon/angular';
102
+ *
103
+ * constructor(@Inject('AuthonService') private authon: AuthonService) {}
104
+ * ```
105
+ */
106
+ declare function provideAuthon(config: AuthonServiceConfig): ({
107
+ provide: string;
108
+ useValue: AuthonServiceConfig;
109
+ } | {
110
+ provide: string;
111
+ useValue: AuthonService;
112
+ })[];
113
+
114
+ export { AUTHON_CONFIG, AuthonService, type AuthonServiceConfig, authGuard, provideAuthon };
package/dist/index.js ADDED
@@ -0,0 +1,102 @@
1
+ // src/service.ts
2
+ import { Authon } from "@authon/js";
3
+ var AUTHON_CONFIG = "AUTHON_CONFIG";
4
+ var AuthonService = class {
5
+ client;
6
+ _user = null;
7
+ _isSignedIn = false;
8
+ _isLoading = true;
9
+ _listeners = [];
10
+ constructor(config) {
11
+ this.client = new Authon(config.publishableKey, config.config);
12
+ this.client.on("signedIn", (user) => {
13
+ this._user = user;
14
+ this._isSignedIn = true;
15
+ this._isLoading = false;
16
+ this.notifyListeners();
17
+ });
18
+ this.client.on("signedOut", () => {
19
+ this._user = null;
20
+ this._isSignedIn = false;
21
+ this.notifyListeners();
22
+ });
23
+ this.client.on("error", () => {
24
+ this._isLoading = false;
25
+ this.notifyListeners();
26
+ });
27
+ this._isLoading = false;
28
+ }
29
+ get user() {
30
+ return this._user;
31
+ }
32
+ get isSignedIn() {
33
+ return this._isSignedIn;
34
+ }
35
+ get isLoading() {
36
+ return this._isLoading;
37
+ }
38
+ async openSignIn() {
39
+ await this.client.openSignIn();
40
+ }
41
+ async openSignUp() {
42
+ await this.client.openSignUp();
43
+ }
44
+ async signOut() {
45
+ await this.client.signOut();
46
+ this._user = null;
47
+ this._isSignedIn = false;
48
+ this.notifyListeners();
49
+ }
50
+ getToken() {
51
+ return this.client.getToken();
52
+ }
53
+ getClient() {
54
+ return this.client;
55
+ }
56
+ /**
57
+ * Subscribe to auth state changes.
58
+ * Returns an unsubscribe function.
59
+ */
60
+ onStateChange(callback) {
61
+ this._listeners.push(callback);
62
+ return () => {
63
+ this._listeners = this._listeners.filter((l) => l !== callback);
64
+ };
65
+ }
66
+ destroy() {
67
+ this.client.destroy();
68
+ this._listeners = [];
69
+ }
70
+ notifyListeners() {
71
+ for (const listener of this._listeners) {
72
+ listener();
73
+ }
74
+ }
75
+ };
76
+
77
+ // src/guard.ts
78
+ function authGuard(authonService, redirectTo = "/sign-in") {
79
+ if (authonService.isLoading) {
80
+ return false;
81
+ }
82
+ if (!authonService.isSignedIn) {
83
+ return { path: redirectTo };
84
+ }
85
+ return true;
86
+ }
87
+
88
+ // src/helpers.ts
89
+ function provideAuthon(config) {
90
+ const service = new AuthonService(config);
91
+ return [
92
+ { provide: AUTHON_CONFIG, useValue: config },
93
+ { provide: "AuthonService", useValue: service }
94
+ ];
95
+ }
96
+ export {
97
+ AUTHON_CONFIG,
98
+ AuthonService,
99
+ authGuard,
100
+ provideAuthon
101
+ };
102
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/service.ts","../src/guard.ts","../src/helpers.ts"],"sourcesContent":["import { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\n/**\n * Injection token key for Authon configuration.\n * Used with Angular's InjectionToken.\n */\nexport const AUTHON_CONFIG = 'AUTHON_CONFIG';\n\nexport interface AuthonServiceConfig {\n publishableKey: string;\n config?: Omit<AuthonConfig, 'mode'>;\n}\n\n/**\n * Plain class wrapping @authon/js for Angular dependency injection.\n *\n * Since tsup cannot compile Angular decorators, this is a plain class.\n * Users should wrap it in their own injectable service:\n *\n * ```ts\n * import { Injectable } from '@angular/core';\n * import { AuthonService as BaseAuthonService } from '@authon/angular';\n *\n * @Injectable({ providedIn: 'root' })\n * export class AuthonService extends BaseAuthonService {\n * constructor() {\n * super({ publishableKey: 'pk_live_...' });\n * }\n * }\n * ```\n *\n * Or use the `provideAuthon()` helper for standalone components.\n */\nexport class AuthonService {\n private client: Authon;\n private _user: AuthonUser | null = null;\n private _isSignedIn = false;\n private _isLoading = true;\n private _listeners: Array<() => void> = [];\n\n constructor(config: AuthonServiceConfig) {\n this.client = new Authon(config.publishableKey, config.config);\n\n this.client.on('signedIn', (user) => {\n this._user = user as AuthonUser;\n this._isSignedIn = true;\n this._isLoading = false;\n this.notifyListeners();\n });\n\n this.client.on('signedOut', () => {\n this._user = null;\n this._isSignedIn = false;\n this.notifyListeners();\n });\n\n this.client.on('error', () => {\n this._isLoading = false;\n this.notifyListeners();\n });\n\n this._isLoading = false;\n }\n\n get user(): AuthonUser | null {\n return this._user;\n }\n\n get isSignedIn(): boolean {\n return this._isSignedIn;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n async openSignIn(): Promise<void> {\n await this.client.openSignIn();\n }\n\n async openSignUp(): Promise<void> {\n await this.client.openSignUp();\n }\n\n async signOut(): Promise<void> {\n await this.client.signOut();\n this._user = null;\n this._isSignedIn = false;\n this.notifyListeners();\n }\n\n getToken(): string | null {\n return this.client.getToken();\n }\n\n getClient(): Authon {\n return this.client;\n }\n\n /**\n * Subscribe to auth state changes.\n * Returns an unsubscribe function.\n */\n onStateChange(callback: () => void): () => void {\n this._listeners.push(callback);\n return () => {\n this._listeners = this._listeners.filter((l) => l !== callback);\n };\n }\n\n destroy(): void {\n this.client.destroy();\n this._listeners = [];\n }\n\n private notifyListeners(): void {\n for (const listener of this._listeners) {\n listener();\n }\n }\n}\n","import type { AuthonService } from './service';\n\n/**\n * Route guard factory for Angular Router (CanActivateFn style).\n *\n * Since tsup can't compile Angular decorators, this returns a plain function.\n * Users wire it up in their route config:\n *\n * ```ts\n * import { inject } from '@angular/core';\n * import { authGuard } from '@authon/angular';\n * import { AuthonService } from './authon.service'; // your injectable wrapper\n *\n * const routes = [\n * {\n * path: 'dashboard',\n * component: DashboardComponent,\n * canActivate: [() => {\n * const authon = inject(AuthonService);\n * return authGuard(authon, '/login');\n * }],\n * },\n * ];\n * ```\n */\nexport function authGuard(\n authonService: AuthonService,\n redirectTo = '/sign-in',\n): boolean | { path: string } {\n if (authonService.isLoading) {\n return false;\n }\n\n if (!authonService.isSignedIn) {\n return { path: redirectTo };\n }\n\n return true;\n}\n","import { AuthonService, AUTHON_CONFIG, type AuthonServiceConfig } from './service';\n\n/**\n * Provider factory for Angular standalone components.\n *\n * Usage in app.config.ts:\n * ```ts\n * import { provideAuthon } from '@authon/angular';\n *\n * export const appConfig = {\n * providers: [\n * ...provideAuthon({ publishableKey: 'pk_live_...' }),\n * ],\n * };\n * ```\n *\n * Then inject in your components:\n * ```ts\n * import { Inject } from '@angular/core';\n * import { AUTHON_CONFIG, AuthonService } from '@authon/angular';\n *\n * constructor(@Inject('AuthonService') private authon: AuthonService) {}\n * ```\n */\nexport function provideAuthon(config: AuthonServiceConfig) {\n const service = new AuthonService(config);\n\n return [\n { provide: AUTHON_CONFIG, useValue: config },\n { provide: 'AuthonService', useValue: service },\n ];\n}\n"],"mappings":";AAAA,SAAS,cAAc;AAQhB,IAAM,gBAAgB;AA2BtB,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA,QAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,aAAa;AAAA,EACb,aAAgC,CAAC;AAAA,EAEzC,YAAY,QAA6B;AACvC,SAAK,SAAS,IAAI,OAAO,OAAO,gBAAgB,OAAO,MAAM;AAE7D,SAAK,OAAO,GAAG,YAAY,CAAC,SAAS;AACnC,WAAK,QAAQ;AACb,WAAK,cAAc;AACnB,WAAK,aAAa;AAClB,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAED,SAAK,OAAO,GAAG,aAAa,MAAM;AAChC,WAAK,QAAQ;AACb,WAAK,cAAc;AACnB,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAED,SAAK,OAAO,GAAG,SAAS,MAAM;AAC5B,WAAK,aAAa;AAClB,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAED,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,IAAI,OAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,KAAK,OAAO,WAAW;AAAA,EAC/B;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,KAAK,OAAO,WAAW;AAAA,EAC/B;AAAA,EAEA,MAAM,UAAyB;AAC7B,UAAM,KAAK,OAAO,QAAQ;AAC1B,SAAK,QAAQ;AACb,SAAK,cAAc;AACnB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,WAA0B;AACxB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,UAAkC;AAC9C,SAAK,WAAW,KAAK,QAAQ;AAC7B,WAAO,MAAM;AACX,WAAK,aAAa,KAAK,WAAW,OAAO,CAAC,MAAM,MAAM,QAAQ;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,QAAQ;AACpB,SAAK,aAAa,CAAC;AAAA,EACrB;AAAA,EAEQ,kBAAwB;AAC9B,eAAW,YAAY,KAAK,YAAY;AACtC,eAAS;AAAA,IACX;AAAA,EACF;AACF;;;ACjGO,SAAS,UACd,eACA,aAAa,YACe;AAC5B,MAAI,cAAc,WAAW;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,cAAc,YAAY;AAC7B,WAAO,EAAE,MAAM,WAAW;AAAA,EAC5B;AAEA,SAAO;AACT;;;ACdO,SAAS,cAAc,QAA6B;AACzD,QAAM,UAAU,IAAI,cAAc,MAAM;AAExC,SAAO;AAAA,IACL,EAAE,SAAS,eAAe,UAAU,OAAO;AAAA,IAC3C,EAAE,SAAS,iBAAiB,UAAU,QAAQ;AAAA,EAChD;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@authon/angular",
3
+ "version": "0.1.0",
4
+ "description": "Authon Angular SDK — service, guard, and components",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": ["dist"],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "dev": "tsup --watch"
20
+ },
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/mikusnuz/authon-sdk.git",
25
+ "directory": "packages/angular"
26
+ },
27
+ "homepage": "https://github.com/mikusnuz/authon-sdk/tree/main/packages/angular",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "keywords": ["authon", "angular", "auth", "guard"],
32
+ "dependencies": {
33
+ "@authon/js": "workspace:*",
34
+ "@authon/shared": "workspace:*"
35
+ },
36
+ "peerDependencies": {
37
+ "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "tsup": "^8.0.0",
41
+ "typescript": "^5.9.3"
42
+ }
43
+ }