@aigne/afs-omada 1.11.0-beta.12

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.md ADDED
@@ -0,0 +1,26 @@
1
+ # Proprietary License
2
+
3
+ Copyright (c) 2024-2025 ArcBlock, Inc. All Rights Reserved.
4
+
5
+ This software and associated documentation files (the "Software") are proprietary
6
+ and confidential. Unauthorized copying, modification, distribution, or use of
7
+ this Software, via any medium, is strictly prohibited.
8
+
9
+ The Software is provided for internal use only within ArcBlock, Inc. and its
10
+ authorized affiliates.
11
+
12
+ ## No License Granted
13
+
14
+ No license, express or implied, is granted to any party for any purpose.
15
+ All rights are reserved by ArcBlock, Inc.
16
+
17
+ ## Public Artifact Distribution
18
+
19
+ Portions of this Software may be released publicly under separate open-source
20
+ licenses (such as MIT License) through designated public repositories. Such
21
+ public releases are governed by their respective licenses and do not affect
22
+ the proprietary nature of this repository.
23
+
24
+ ## Contact
25
+
26
+ For licensing inquiries, contact: legal@arcblock.io
@@ -0,0 +1,11 @@
1
+
2
+ //#region \0@oxc-project+runtime@0.108.0/helpers/decorate.js
3
+ function __decorate(decorators, target, key, desc) {
4
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
6
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
7
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
8
+ }
9
+
10
+ //#endregion
11
+ exports.__decorate = __decorate;
@@ -0,0 +1,10 @@
1
+ //#region \0@oxc-project+runtime@0.108.0/helpers/decorate.js
2
+ function __decorate(decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ }
8
+
9
+ //#endregion
10
+ export { __decorate };
package/dist/cache.cjs ADDED
@@ -0,0 +1,59 @@
1
+
2
+ //#region src/cache.ts
3
+ var OmadaCache = class {
4
+ store = /* @__PURE__ */ new Map();
5
+ ttlMs;
6
+ constructor(ttlSeconds) {
7
+ this.ttlMs = ttlSeconds * 1e3;
8
+ }
9
+ /**
10
+ * Get a cached value, or undefined if expired/missing.
11
+ */
12
+ get(key) {
13
+ if (this.ttlMs <= 0) return void 0;
14
+ const entry = this.store.get(key);
15
+ if (!entry) return void 0;
16
+ if (Date.now() >= entry.expiresAt) {
17
+ this.store.delete(key);
18
+ return;
19
+ }
20
+ return entry.data;
21
+ }
22
+ /**
23
+ * Set a cached value with TTL.
24
+ */
25
+ set(key, data) {
26
+ if (this.ttlMs <= 0) return;
27
+ this.store.set(key, {
28
+ data,
29
+ expiresAt: Date.now() + this.ttlMs
30
+ });
31
+ }
32
+ /**
33
+ * Invalidate a specific cache key.
34
+ */
35
+ invalidate(key) {
36
+ this.store.delete(key);
37
+ }
38
+ /**
39
+ * Invalidate all cache keys matching a prefix.
40
+ */
41
+ invalidatePrefix(prefix) {
42
+ for (const key of this.store.keys()) if (key.startsWith(prefix)) this.store.delete(key);
43
+ }
44
+ /**
45
+ * Clear the entire cache.
46
+ */
47
+ clear() {
48
+ this.store.clear();
49
+ }
50
+ /**
51
+ * Get the number of cached entries (for testing).
52
+ */
53
+ get size() {
54
+ return this.store.size;
55
+ }
56
+ };
57
+
58
+ //#endregion
59
+ exports.OmadaCache = OmadaCache;
@@ -0,0 +1,39 @@
1
+ //#region src/cache.d.ts
2
+ /**
3
+ * TTL cache for Omada API responses.
4
+ *
5
+ * Provides per-key caching with configurable TTL and manual invalidation.
6
+ * Cache keys include siteId to prevent cross-site data mixing.
7
+ */
8
+ declare class OmadaCache {
9
+ private store;
10
+ private ttlMs;
11
+ constructor(ttlSeconds: number);
12
+ /**
13
+ * Get a cached value, or undefined if expired/missing.
14
+ */
15
+ get<T>(key: string): T | undefined;
16
+ /**
17
+ * Set a cached value with TTL.
18
+ */
19
+ set<T>(key: string, data: T): void;
20
+ /**
21
+ * Invalidate a specific cache key.
22
+ */
23
+ invalidate(key: string): void;
24
+ /**
25
+ * Invalidate all cache keys matching a prefix.
26
+ */
27
+ invalidatePrefix(prefix: string): void;
28
+ /**
29
+ * Clear the entire cache.
30
+ */
31
+ clear(): void;
32
+ /**
33
+ * Get the number of cached entries (for testing).
34
+ */
35
+ get size(): number;
36
+ }
37
+ //#endregion
38
+ export { OmadaCache };
39
+ //# sourceMappingURL=cache.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.cts","names":[],"sources":["../src/cache.ts"],"mappings":";;AAYA;;;;;cAAa,UAAA;EAAA,QACH,KAAA;EAAA,QACA,KAAA;cAEI,UAAA;EAOR;;;EAAJ,GAAA,GAAA,CAAO,GAAA,WAAc,CAAA;EAiBjB;;;EAAJ,GAAA,GAAA,CAAO,GAAA,UAAa,IAAA,EAAM,CAAA;EAY1B;;;EAAA,UAAA,CAAW,GAAA;EAkBX;;;EAXA,gBAAA,CAAiB,MAAA;;;;EAWjB,KAAA,CAAA;;;;MAOI,IAAA,CAAA;AAAA"}
@@ -0,0 +1,39 @@
1
+ //#region src/cache.d.ts
2
+ /**
3
+ * TTL cache for Omada API responses.
4
+ *
5
+ * Provides per-key caching with configurable TTL and manual invalidation.
6
+ * Cache keys include siteId to prevent cross-site data mixing.
7
+ */
8
+ declare class OmadaCache {
9
+ private store;
10
+ private ttlMs;
11
+ constructor(ttlSeconds: number);
12
+ /**
13
+ * Get a cached value, or undefined if expired/missing.
14
+ */
15
+ get<T>(key: string): T | undefined;
16
+ /**
17
+ * Set a cached value with TTL.
18
+ */
19
+ set<T>(key: string, data: T): void;
20
+ /**
21
+ * Invalidate a specific cache key.
22
+ */
23
+ invalidate(key: string): void;
24
+ /**
25
+ * Invalidate all cache keys matching a prefix.
26
+ */
27
+ invalidatePrefix(prefix: string): void;
28
+ /**
29
+ * Clear the entire cache.
30
+ */
31
+ clear(): void;
32
+ /**
33
+ * Get the number of cached entries (for testing).
34
+ */
35
+ get size(): number;
36
+ }
37
+ //#endregion
38
+ export { OmadaCache };
39
+ //# sourceMappingURL=cache.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.mts","names":[],"sources":["../src/cache.ts"],"mappings":";;AAYA;;;;;cAAa,UAAA;EAAA,QACH,KAAA;EAAA,QACA,KAAA;cAEI,UAAA;EAOR;;;EAAJ,GAAA,GAAA,CAAO,GAAA,WAAc,CAAA;EAiBjB;;;EAAJ,GAAA,GAAA,CAAO,GAAA,UAAa,IAAA,EAAM,CAAA;EAY1B;;;EAAA,UAAA,CAAW,GAAA;EAkBX;;;EAXA,gBAAA,CAAiB,MAAA;;;;EAWjB,KAAA,CAAA;;;;MAOI,IAAA,CAAA;AAAA"}
package/dist/cache.mjs ADDED
@@ -0,0 +1,59 @@
1
+ //#region src/cache.ts
2
+ var OmadaCache = class {
3
+ store = /* @__PURE__ */ new Map();
4
+ ttlMs;
5
+ constructor(ttlSeconds) {
6
+ this.ttlMs = ttlSeconds * 1e3;
7
+ }
8
+ /**
9
+ * Get a cached value, or undefined if expired/missing.
10
+ */
11
+ get(key) {
12
+ if (this.ttlMs <= 0) return void 0;
13
+ const entry = this.store.get(key);
14
+ if (!entry) return void 0;
15
+ if (Date.now() >= entry.expiresAt) {
16
+ this.store.delete(key);
17
+ return;
18
+ }
19
+ return entry.data;
20
+ }
21
+ /**
22
+ * Set a cached value with TTL.
23
+ */
24
+ set(key, data) {
25
+ if (this.ttlMs <= 0) return;
26
+ this.store.set(key, {
27
+ data,
28
+ expiresAt: Date.now() + this.ttlMs
29
+ });
30
+ }
31
+ /**
32
+ * Invalidate a specific cache key.
33
+ */
34
+ invalidate(key) {
35
+ this.store.delete(key);
36
+ }
37
+ /**
38
+ * Invalidate all cache keys matching a prefix.
39
+ */
40
+ invalidatePrefix(prefix) {
41
+ for (const key of this.store.keys()) if (key.startsWith(prefix)) this.store.delete(key);
42
+ }
43
+ /**
44
+ * Clear the entire cache.
45
+ */
46
+ clear() {
47
+ this.store.clear();
48
+ }
49
+ /**
50
+ * Get the number of cached entries (for testing).
51
+ */
52
+ get size() {
53
+ return this.store.size;
54
+ }
55
+ };
56
+
57
+ //#endregion
58
+ export { OmadaCache };
59
+ //# sourceMappingURL=cache.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.mjs","names":[],"sources":["../src/cache.ts"],"sourcesContent":["/**\n * TTL cache for Omada API responses.\n *\n * Provides per-key caching with configurable TTL and manual invalidation.\n * Cache keys include siteId to prevent cross-site data mixing.\n */\n\ninterface CacheEntry<T> {\n data: T;\n expiresAt: number;\n}\n\nexport class OmadaCache {\n private store = new Map<string, CacheEntry<unknown>>();\n private ttlMs: number;\n\n constructor(ttlSeconds: number) {\n this.ttlMs = ttlSeconds * 1000;\n }\n\n /**\n * Get a cached value, or undefined if expired/missing.\n */\n get<T>(key: string): T | undefined {\n if (this.ttlMs <= 0) return undefined;\n\n const entry = this.store.get(key);\n if (!entry) return undefined;\n\n if (Date.now() >= entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n\n return entry.data as T;\n }\n\n /**\n * Set a cached value with TTL.\n */\n set<T>(key: string, data: T): void {\n if (this.ttlMs <= 0) return;\n\n this.store.set(key, {\n data,\n expiresAt: Date.now() + this.ttlMs,\n });\n }\n\n /**\n * Invalidate a specific cache key.\n */\n invalidate(key: string): void {\n this.store.delete(key);\n }\n\n /**\n * Invalidate all cache keys matching a prefix.\n */\n invalidatePrefix(prefix: string): void {\n for (const key of this.store.keys()) {\n if (key.startsWith(prefix)) {\n this.store.delete(key);\n }\n }\n }\n\n /**\n * Clear the entire cache.\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the number of cached entries (for testing).\n */\n get size(): number {\n return this.store.size;\n }\n}\n"],"mappings":";AAYA,IAAa,aAAb,MAAwB;CACtB,AAAQ,wBAAQ,IAAI,KAAkC;CACtD,AAAQ;CAER,YAAY,YAAoB;AAC9B,OAAK,QAAQ,aAAa;;;;;CAM5B,IAAO,KAA4B;AACjC,MAAI,KAAK,SAAS,EAAG,QAAO;EAE5B,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,KAAK,KAAK,IAAI,MAAM,WAAW;AACjC,QAAK,MAAM,OAAO,IAAI;AACtB;;AAGF,SAAO,MAAM;;;;;CAMf,IAAO,KAAa,MAAe;AACjC,MAAI,KAAK,SAAS,EAAG;AAErB,OAAK,MAAM,IAAI,KAAK;GAClB;GACA,WAAW,KAAK,KAAK,GAAG,KAAK;GAC9B,CAAC;;;;;CAMJ,WAAW,KAAmB;AAC5B,OAAK,MAAM,OAAO,IAAI;;;;;CAMxB,iBAAiB,QAAsB;AACrC,OAAK,MAAM,OAAO,KAAK,MAAM,MAAM,CACjC,KAAI,IAAI,WAAW,OAAO,CACxB,MAAK,MAAM,OAAO,IAAI;;;;;CAQ5B,QAAc;AACZ,OAAK,MAAM,OAAO;;;;;CAMpB,IAAI,OAAe;AACjB,SAAO,KAAK,MAAM"}
@@ -0,0 +1,168 @@
1
+ let ufo = require("ufo");
2
+
3
+ //#region src/client.ts
4
+ /** Validate that an ID-like string is safe for URL path construction. */
5
+ function validateIdParam(value, name) {
6
+ if (!/^[\w-]+$/.test(value)) throw new Error(`Invalid ${name}: must be alphanumeric with hyphens/underscores`);
7
+ }
8
+ /**
9
+ * OmadaApiClient manages authentication and API calls to the Omada SDN Controller.
10
+ *
11
+ * Handles:
12
+ * - OAuth2 client credentials token acquisition
13
+ * - Non-standard Omada auth headers (Cookie + Csrf-Token)
14
+ * - Token refresh before expiration
15
+ * - Concurrent refresh prevention
16
+ * - omadacId auto-discovery from /api/info
17
+ */
18
+ var OmadaApiClient = class {
19
+ tokenState = null;
20
+ refreshPromise = null;
21
+ omadacId;
22
+ /** Base URL for Omada controller (read-only, validated at construction) */
23
+ baseUrl;
24
+ /** Whether to skip TLS certificate verification (for self-signed certs) */
25
+ tlsRejectUnauthorized;
26
+ #clientId;
27
+ #clientSecret;
28
+ constructor(baseUrl, clientId, clientSecret, omadacId, strictSsl) {
29
+ this.baseUrl = baseUrl;
30
+ this.#clientId = clientId;
31
+ this.#clientSecret = clientSecret;
32
+ this.omadacId = omadacId;
33
+ this.tlsRejectUnauthorized = strictSsl;
34
+ }
35
+ /**
36
+ * Ensure omadacId is available, discovering it if not provided.
37
+ */
38
+ async ensureOmadacId() {
39
+ if (this.omadacId) return this.omadacId;
40
+ this.omadacId = await this.discoverOmadacId();
41
+ return this.omadacId;
42
+ }
43
+ /**
44
+ * Discover omadacId from GET /api/info endpoint (no auth required).
45
+ */
46
+ async discoverOmadacId() {
47
+ const url = (0, ufo.joinURL)(this.baseUrl, "/api/info");
48
+ const resp = await this.rawFetch(url);
49
+ if (!resp.ok) throw new Error(`Failed to discover omadacId: HTTP ${resp.status}`);
50
+ const data = await resp.json();
51
+ if (data.errorCode !== 0) throw new Error(`Omada API error discovering omadacId: errorCode=${data.errorCode}`);
52
+ if (!data.result?.omadacId) throw new Error("Omada API /api/info response missing result.omadacId field");
53
+ validateIdParam(data.result.omadacId, "omadacId (discovered)");
54
+ return data.result.omadacId;
55
+ }
56
+ /**
57
+ * Acquire or refresh OAuth2 token.
58
+ * Prevents concurrent refreshes using a shared promise.
59
+ */
60
+ async authorize() {
61
+ if (this.refreshPromise) {
62
+ await this.refreshPromise;
63
+ return;
64
+ }
65
+ this.refreshPromise = this._doAuthorize();
66
+ try {
67
+ await this.refreshPromise;
68
+ } finally {
69
+ this.refreshPromise = null;
70
+ }
71
+ }
72
+ async _doAuthorize() {
73
+ const omadacId = await this.ensureOmadacId();
74
+ const url = (0, ufo.joinURL)(this.baseUrl, `/${omadacId}/openapi/authorize/token`);
75
+ const body = {
76
+ omadacId,
77
+ client_id: this.#clientId,
78
+ client_secret: this.#clientSecret,
79
+ grant_type: "client_credentials"
80
+ };
81
+ if (this.tokenState?.refreshToken) {
82
+ body.grant_type = "refresh_token";
83
+ body.refresh_token = this.tokenState.refreshToken;
84
+ }
85
+ const resp = await this.rawFetch(url, {
86
+ method: "POST",
87
+ headers: { "Content-Type": "application/json" },
88
+ body: JSON.stringify(body)
89
+ });
90
+ if (!resp.ok) throw new Error(`Omada authorization failed: HTTP ${resp.status}`);
91
+ const data = await resp.json();
92
+ if (data.errorCode !== 0 || !data.result?.accessToken) throw new Error(`Omada authorization failed: errorCode=${data.errorCode}`);
93
+ this.tokenState = {
94
+ accessToken: data.result.accessToken,
95
+ refreshToken: data.result.refreshToken,
96
+ expiresAt: Date.now() + (data.result.expiresIn - 60) * 1e3
97
+ };
98
+ }
99
+ /**
100
+ * Ensure we have a valid token, refreshing if needed.
101
+ */
102
+ async ensureToken() {
103
+ if (!this.tokenState || Date.now() >= this.tokenState.expiresAt) await this.authorize();
104
+ return this.tokenState.accessToken;
105
+ }
106
+ /**
107
+ * Make an authenticated GET API call to the Omada controller.
108
+ * Automatically handles token acquisition and the non-standard auth headers.
109
+ */
110
+ async request(path, options = {}) {
111
+ const token = await this.ensureToken();
112
+ const omadacId = await this.ensureOmadacId();
113
+ let url = (0, ufo.joinURL)(this.baseUrl, `/${omadacId}/openapi/v1`, path);
114
+ if (options.params) {
115
+ const searchParams = new URLSearchParams();
116
+ for (const [key, value] of Object.entries(options.params)) searchParams.set(key, String(value));
117
+ url = `${url}?${searchParams.toString()}`;
118
+ }
119
+ const headers = {
120
+ "Content-Type": "application/json",
121
+ Cookie: `TPLINK_OMADA_SESSIONID=${token}`,
122
+ "Csrf-Token": token
123
+ };
124
+ const fetchOptions = {
125
+ method: options.method || "GET",
126
+ headers
127
+ };
128
+ if (options.body) fetchOptions.body = JSON.stringify(options.body);
129
+ const resp = await this.rawFetch(url, fetchOptions);
130
+ if (!resp.ok) throw new Error(`Omada API error: HTTP ${resp.status} for ${options.method || "GET"} ${path}`);
131
+ const data = await resp.json();
132
+ if (data.errorCode !== 0) throw new Error(`Omada API error: errorCode=${data.errorCode}${data.msg ? ` msg=${data.msg}` : ""} for ${path}`);
133
+ return data.result;
134
+ }
135
+ /**
136
+ * Convenience wrapper for POST requests.
137
+ */
138
+ async post(path, body) {
139
+ return this.request(path, {
140
+ method: "POST",
141
+ body
142
+ });
143
+ }
144
+ /**
145
+ * Convenience wrapper for PATCH requests.
146
+ */
147
+ async patch(path, body) {
148
+ return this.request(path, {
149
+ method: "PATCH",
150
+ body
151
+ });
152
+ }
153
+ /**
154
+ * Raw fetch wrapper that handles TLS certificate verification.
155
+ * When tlsRejectUnauthorized=false, skips certificate validation
156
+ * (common for self-signed certs on Omada controllers).
157
+ */
158
+ rawFetch(url, options) {
159
+ if (!this.tlsRejectUnauthorized) return fetch(url, {
160
+ ...options,
161
+ tls: { rejectUnauthorized: false }
162
+ });
163
+ return fetch(url, options);
164
+ }
165
+ };
166
+
167
+ //#endregion
168
+ exports.OmadaApiClient = OmadaApiClient;
@@ -0,0 +1,66 @@
1
+ //#region src/client.d.ts
2
+ /**
3
+ * OmadaApiClient manages authentication and API calls to the Omada SDN Controller.
4
+ *
5
+ * Handles:
6
+ * - OAuth2 client credentials token acquisition
7
+ * - Non-standard Omada auth headers (Cookie + Csrf-Token)
8
+ * - Token refresh before expiration
9
+ * - Concurrent refresh prevention
10
+ * - omadacId auto-discovery from /api/info
11
+ */
12
+ declare class OmadaApiClient {
13
+ #private;
14
+ private tokenState;
15
+ private refreshPromise;
16
+ private omadacId;
17
+ /** Base URL for Omada controller (read-only, validated at construction) */
18
+ readonly baseUrl: string;
19
+ /** Whether to skip TLS certificate verification (for self-signed certs) */
20
+ readonly tlsRejectUnauthorized: boolean;
21
+ constructor(baseUrl: string, clientId: string, clientSecret: string, omadacId: string | undefined, strictSsl: boolean);
22
+ /**
23
+ * Ensure omadacId is available, discovering it if not provided.
24
+ */
25
+ ensureOmadacId(): Promise<string>;
26
+ /**
27
+ * Discover omadacId from GET /api/info endpoint (no auth required).
28
+ */
29
+ discoverOmadacId(): Promise<string>;
30
+ /**
31
+ * Acquire or refresh OAuth2 token.
32
+ * Prevents concurrent refreshes using a shared promise.
33
+ */
34
+ authorize(): Promise<void>;
35
+ private _doAuthorize;
36
+ /**
37
+ * Ensure we have a valid token, refreshing if needed.
38
+ */
39
+ private ensureToken;
40
+ /**
41
+ * Make an authenticated GET API call to the Omada controller.
42
+ * Automatically handles token acquisition and the non-standard auth headers.
43
+ */
44
+ request<T = unknown>(path: string, options?: {
45
+ method?: string;
46
+ body?: unknown;
47
+ params?: Record<string, string | number>;
48
+ }): Promise<T>;
49
+ /**
50
+ * Convenience wrapper for POST requests.
51
+ */
52
+ post<T = unknown>(path: string, body?: unknown): Promise<T>;
53
+ /**
54
+ * Convenience wrapper for PATCH requests.
55
+ */
56
+ patch<T = unknown>(path: string, body?: unknown): Promise<T>;
57
+ /**
58
+ * Raw fetch wrapper that handles TLS certificate verification.
59
+ * When tlsRejectUnauthorized=false, skips certificate validation
60
+ * (common for self-signed certs on Omada controllers).
61
+ */
62
+ private rawFetch;
63
+ }
64
+ //#endregion
65
+ export { OmadaApiClient };
66
+ //# sourceMappingURL=client.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.cts","names":[],"sources":["../src/client.ts"],"mappings":";;AA4BA;;;;;;;;;cAAa,cAAA;EAAA;UACH,UAAA;EAAA,QACA,cAAA;EAAA,QACA,QAAA;EAmNuD;EAAA,SAhNtD,OAAA;EALD;EAAA,SAQC,qBAAA;cAOP,OAAA,UACA,QAAA,UACA,YAAA,UACA,QAAA,sBACA,SAAA;EAdO;;;EA0BH,cAAA,CAAA,GAAkB,OAAA;EAftB;;;EAwBI,gBAAA,CAAA,GAAoB,OAAA;EATpB;;;;EAsCA,SAAA,CAAA,GAAa,OAAA;EAAA,QAeL,YAAA;EAAA;;;EAAA,QAoDA,WAAA;EAYZ;;;;EADI,OAAA,aAAA,CACJ,IAAA,UACA,OAAA;IACE,MAAA;IACA,IAAA;IACA,MAAA,GAAS,MAAA;EAAA,IAEV,OAAA,CAAQ,CAAA;EAoDA;;;EAAL,IAAA,aAAA,CAAkB,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAAA;;;EAOzD,KAAA,aAAA,CAAmB,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAAzB;;;;;EAAA,QAS/B,QAAA;AAAA"}
@@ -0,0 +1,66 @@
1
+ //#region src/client.d.ts
2
+ /**
3
+ * OmadaApiClient manages authentication and API calls to the Omada SDN Controller.
4
+ *
5
+ * Handles:
6
+ * - OAuth2 client credentials token acquisition
7
+ * - Non-standard Omada auth headers (Cookie + Csrf-Token)
8
+ * - Token refresh before expiration
9
+ * - Concurrent refresh prevention
10
+ * - omadacId auto-discovery from /api/info
11
+ */
12
+ declare class OmadaApiClient {
13
+ #private;
14
+ private tokenState;
15
+ private refreshPromise;
16
+ private omadacId;
17
+ /** Base URL for Omada controller (read-only, validated at construction) */
18
+ readonly baseUrl: string;
19
+ /** Whether to skip TLS certificate verification (for self-signed certs) */
20
+ readonly tlsRejectUnauthorized: boolean;
21
+ constructor(baseUrl: string, clientId: string, clientSecret: string, omadacId: string | undefined, strictSsl: boolean);
22
+ /**
23
+ * Ensure omadacId is available, discovering it if not provided.
24
+ */
25
+ ensureOmadacId(): Promise<string>;
26
+ /**
27
+ * Discover omadacId from GET /api/info endpoint (no auth required).
28
+ */
29
+ discoverOmadacId(): Promise<string>;
30
+ /**
31
+ * Acquire or refresh OAuth2 token.
32
+ * Prevents concurrent refreshes using a shared promise.
33
+ */
34
+ authorize(): Promise<void>;
35
+ private _doAuthorize;
36
+ /**
37
+ * Ensure we have a valid token, refreshing if needed.
38
+ */
39
+ private ensureToken;
40
+ /**
41
+ * Make an authenticated GET API call to the Omada controller.
42
+ * Automatically handles token acquisition and the non-standard auth headers.
43
+ */
44
+ request<T = unknown>(path: string, options?: {
45
+ method?: string;
46
+ body?: unknown;
47
+ params?: Record<string, string | number>;
48
+ }): Promise<T>;
49
+ /**
50
+ * Convenience wrapper for POST requests.
51
+ */
52
+ post<T = unknown>(path: string, body?: unknown): Promise<T>;
53
+ /**
54
+ * Convenience wrapper for PATCH requests.
55
+ */
56
+ patch<T = unknown>(path: string, body?: unknown): Promise<T>;
57
+ /**
58
+ * Raw fetch wrapper that handles TLS certificate verification.
59
+ * When tlsRejectUnauthorized=false, skips certificate validation
60
+ * (common for self-signed certs on Omada controllers).
61
+ */
62
+ private rawFetch;
63
+ }
64
+ //#endregion
65
+ export { OmadaApiClient };
66
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;AA4BA;;;;;;;;;cAAa,cAAA;EAAA;UACH,UAAA;EAAA,QACA,cAAA;EAAA,QACA,QAAA;EAmNuD;EAAA,SAhNtD,OAAA;EALD;EAAA,SAQC,qBAAA;cAOP,OAAA,UACA,QAAA,UACA,YAAA,UACA,QAAA,sBACA,SAAA;EAdO;;;EA0BH,cAAA,CAAA,GAAkB,OAAA;EAftB;;;EAwBI,gBAAA,CAAA,GAAoB,OAAA;EATpB;;;;EAsCA,SAAA,CAAA,GAAa,OAAA;EAAA,QAeL,YAAA;EAAA;;;EAAA,QAoDA,WAAA;EAYZ;;;;EADI,OAAA,aAAA,CACJ,IAAA,UACA,OAAA;IACE,MAAA;IACA,IAAA;IACA,MAAA,GAAS,MAAA;EAAA,IAEV,OAAA,CAAQ,CAAA;EAoDA;;;EAAL,IAAA,aAAA,CAAkB,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAAA;;;EAOzD,KAAA,aAAA,CAAmB,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAAzB;;;;;EAAA,QAS/B,QAAA;AAAA"}