@djangocfg/api 2.1.582 → 2.1.583
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 +18 -0
- package/dist/auth.cjs +272 -80
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +272 -80
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +243 -54
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +243 -54
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +243 -54
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +243 -54
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +248 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -1
- package/dist/index.d.ts +85 -1
- package/dist/index.mjs +248 -54
- package/dist/index.mjs.map +1 -1
- package/dist/storage.cjs +269 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +85 -0
- package/dist/storage.d.ts +85 -0
- package/dist/storage.mjs +248 -0
- package/dist/storage.mjs.map +1 -0
- package/package.json +8 -2
- package/src/__tests__/noStorageLiterals.test.ts +27 -0
- package/src/__tests__/storage.test.ts +134 -0
- package/src/__tests__/storageSsr.test.ts +14 -0
- package/src/_api/generated/helpers/auth.ts +27 -64
- package/src/_api/generated/helpers/index.ts +12 -0
- package/src/_api/generated/helpers/keys.ts +328 -0
- package/src/auth/__tests__/authRedirect.test.ts +1 -1
- package/src/auth/__tests__/profileCache.test.ts +1 -1
- package/src/auth/context/AuthContext.tsx +2 -1
- package/src/auth/hooks/useAuthRedirect.ts +3 -2
- package/src/auth/hooks/useGithubAuth.ts +13 -8
- package/src/auth/hooks/useLocalStorage.ts +7 -7
- package/src/auth/hooks/useProfileCache.ts +2 -1
- package/src/auth/hooks/useSessionStorage.ts +7 -7
- package/src/storage.ts +21 -0
package/dist/clients.cjs
CHANGED
|
@@ -93,77 +93,264 @@ var APIError = class extends Error {
|
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
// src/_api/generated/helpers/
|
|
97
|
-
var
|
|
98
|
-
var
|
|
99
|
-
var
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
96
|
+
// src/_api/generated/helpers/keys.ts
|
|
97
|
+
var k = /* @__PURE__ */ __name((key, store, personal) => ({ key, store, personal }), "k");
|
|
98
|
+
var f = /* @__PURE__ */ __name((prefix, store, personal) => ({ prefix, store, personal }), "f");
|
|
99
|
+
var CFG_KEYS = {
|
|
100
|
+
accessToken: k("cfg.auth.access_token", "local", true),
|
|
101
|
+
refreshToken: k("cfg.auth.refresh_token", "local", true),
|
|
102
|
+
apiKey: k("cfg.auth.api_key", "local", true),
|
|
103
|
+
email: k("cfg.auth.email", "local", false),
|
|
104
|
+
emailTs: k("cfg.auth.email_ts", "local", false),
|
|
105
|
+
redirectUrl: k("cfg.auth.redirect_url", "session", true),
|
|
106
|
+
redirectUrlTs: k("cfg.auth.redirect_url_ts", "session", true),
|
|
107
|
+
oauthState: k("cfg.auth.oauth_state", "session", true),
|
|
108
|
+
oauthProvider: k("cfg.auth.oauth_provider", "session", true),
|
|
109
|
+
oauthRememberMe: k("cfg.auth.oauth_remember_me", "session", true),
|
|
110
|
+
profileCache: k("cfg.profile.cache", "local", true),
|
|
111
|
+
monitorSessionId: k("cfg.monitor.session_id", "local", false),
|
|
112
|
+
monitorSessionCookie: k("cfg.monitor.session_id", "cookie", false),
|
|
113
|
+
monitorDebug: k("cfg.monitor.debug", "local", false),
|
|
114
|
+
uiTabId: k("cfg.ui.tab_id", "session", false),
|
|
115
|
+
uiRouterSerial: k("cfg.ui.router_serial", "session", false),
|
|
116
|
+
uiState: k("cfg.ui.state", "local", false),
|
|
117
|
+
chatSpeechLanguage: k("cfg.chat.speech_language", "local", false),
|
|
118
|
+
chatRecentTools: k("cfg.chat.recent_tools", "local", false),
|
|
119
|
+
formsSpeechDebug: k("cfg.forms.speech_debug", "local", false),
|
|
120
|
+
formsSpeechPrefs: k("cfg.forms.speech_prefs", "local", false),
|
|
121
|
+
agentPlaygroundApiKeyId: k("cfg.agent.playground_api_key_id", "session", true),
|
|
122
|
+
agentPlaygroundBearer: k("cfg.agent.playground_bearer", "session", true),
|
|
123
|
+
agentEndpointDoc: k("cfg.agent.endpoint_doc", "session", false)
|
|
124
|
+
};
|
|
125
|
+
var CFG_FAMILIES = {
|
|
126
|
+
chatDraft: f("cfg.chat.draft.", "session", true),
|
|
127
|
+
dataTree: f("cfg.data.tree.", "local", false),
|
|
128
|
+
agentEndpointDraft: f("cfg.agent.endpoint_draft.", "local", false)
|
|
129
|
+
};
|
|
130
|
+
var OWNER_RE = /^[a-z][a-z0-9_]*$/;
|
|
131
|
+
function normalizeSegment(raw) {
|
|
132
|
+
return raw.trim().toLowerCase().replace(/[^a-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
133
|
+
}
|
|
134
|
+
__name(normalizeSegment, "normalizeSegment");
|
|
135
|
+
var hasWindow = /* @__PURE__ */ __name(() => typeof window !== "undefined", "hasWindow");
|
|
136
|
+
function nativeStorage(store) {
|
|
137
|
+
if (!hasWindow()) return null;
|
|
138
|
+
try {
|
|
139
|
+
return store === "session" ? window.sessionStorage : window.localStorage;
|
|
140
|
+
} catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
__name(nativeStorage, "nativeStorage");
|
|
145
|
+
function cookieNames() {
|
|
146
|
+
if (!hasWindow()) return [];
|
|
147
|
+
try {
|
|
148
|
+
return document.cookie.split("; ").map((part) => decodeURIComponent(part.split("=")[0] ?? "")).filter(Boolean);
|
|
149
|
+
} catch {
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
__name(cookieNames, "cookieNames");
|
|
154
|
+
function createStorage(owner, options = {}) {
|
|
155
|
+
if (!OWNER_RE.test(owner)) {
|
|
156
|
+
throw new TypeError(`createStorage: owner "${owner}" must match ${OWNER_RE}`);
|
|
157
|
+
}
|
|
158
|
+
const prefix = `${owner}.`;
|
|
159
|
+
const pattern = owner === "cfg" ? /^cfg(\.[a-z0-9_]+)+$/ : new RegExp(`^(cfg|${owner})(\\.[a-z0-9_]+)+$`);
|
|
160
|
+
const cookieMaxAge = options.cookieMaxAgeSeconds ?? 60 * 60 * 24 * 30;
|
|
161
|
+
const specs = Object.values(options.keys ?? {});
|
|
162
|
+
const families = Object.values(options.families ?? {});
|
|
163
|
+
const specByKey = /* @__PURE__ */ new Map();
|
|
164
|
+
for (const spec of specs) specByKey.set(spec.key, [...specByKey.get(spec.key) ?? [], spec]);
|
|
165
|
+
const memory = {
|
|
166
|
+
local: /* @__PURE__ */ new Map(),
|
|
167
|
+
session: /* @__PURE__ */ new Map(),
|
|
168
|
+
cookie: /* @__PURE__ */ new Map()
|
|
169
|
+
};
|
|
170
|
+
const isValid = /* @__PURE__ */ __name((key) => pattern.test(key), "isValid");
|
|
171
|
+
const assertValid = /* @__PURE__ */ __name((key) => {
|
|
172
|
+
if (!isValid(key)) throw new TypeError(`storage key "${key}" must match ${pattern}`);
|
|
173
|
+
}, "assertValid");
|
|
174
|
+
const assertOwned = /* @__PURE__ */ __name((key) => {
|
|
175
|
+
assertValid(key);
|
|
176
|
+
if (!key.startsWith(prefix)) throw new TypeError(`storage key "${key}" is not owned by "${owner}"`);
|
|
177
|
+
}, "assertOwned");
|
|
178
|
+
function rawGet(store, key) {
|
|
179
|
+
if (!hasWindow()) return null;
|
|
180
|
+
if (store === "cookie") {
|
|
181
|
+
try {
|
|
182
|
+
const escaped = encodeURIComponent(key).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
183
|
+
const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${escaped}=([^;]*)`));
|
|
184
|
+
if (match?.[1] !== void 0) return decodeURIComponent(match[1]);
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
return memory.cookie.get(key) ?? null;
|
|
108
188
|
}
|
|
109
|
-
},
|
|
110
|
-
set(key, value) {
|
|
111
|
-
if (!isBrowser) return;
|
|
112
189
|
try {
|
|
113
|
-
|
|
114
|
-
|
|
190
|
+
const value = nativeStorage(store)?.getItem(key) ?? null;
|
|
191
|
+
if (value !== null) return value;
|
|
115
192
|
} catch {
|
|
116
193
|
}
|
|
194
|
+
return memory[store].get(key) ?? null;
|
|
117
195
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (!isBrowser) return null;
|
|
196
|
+
__name(rawGet, "rawGet");
|
|
197
|
+
function rawSet(store, key, value) {
|
|
198
|
+
if (!hasWindow()) return false;
|
|
122
199
|
try {
|
|
123
|
-
|
|
200
|
+
if (store === "cookie") {
|
|
201
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
202
|
+
document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; Path=/; Max-Age=${cookieMaxAge}; SameSite=Lax${secure}`;
|
|
203
|
+
if (rawGet("cookie", key) === value && !memory.cookie.has(key)) return true;
|
|
204
|
+
memory.cookie.set(key, value);
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
const native = nativeStorage(store);
|
|
208
|
+
if (!native) throw new Error("storage unavailable");
|
|
209
|
+
native.setItem(key, value);
|
|
210
|
+
memory[store].delete(key);
|
|
211
|
+
return true;
|
|
124
212
|
} catch {
|
|
125
|
-
|
|
213
|
+
memory[store].set(key, value);
|
|
214
|
+
return false;
|
|
126
215
|
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
216
|
+
}
|
|
217
|
+
__name(rawSet, "rawSet");
|
|
218
|
+
function rawRemove(store, key) {
|
|
219
|
+
memory[store].delete(key);
|
|
220
|
+
if (!hasWindow()) return;
|
|
130
221
|
try {
|
|
131
|
-
if (
|
|
132
|
-
|
|
222
|
+
if (store === "cookie") {
|
|
223
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
224
|
+
document.cookie = `${encodeURIComponent(key)}=; Path=/; Max-Age=0; SameSite=Lax${secure}`;
|
|
225
|
+
} else {
|
|
226
|
+
nativeStorage(store)?.removeItem(key);
|
|
227
|
+
}
|
|
133
228
|
} catch {
|
|
134
229
|
}
|
|
135
230
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
231
|
+
__name(rawRemove, "rawRemove");
|
|
232
|
+
function resolveStore(key, store) {
|
|
233
|
+
return store ?? specByKey.get(key)?.[0]?.store ?? "local";
|
|
234
|
+
}
|
|
235
|
+
__name(resolveStore, "resolveStore");
|
|
236
|
+
function listKeys(store, startsWith) {
|
|
237
|
+
const out = [];
|
|
141
238
|
try {
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
239
|
+
const native = nativeStorage(store);
|
|
240
|
+
if (native) {
|
|
241
|
+
for (let i = 0; i < native.length; i += 1) {
|
|
242
|
+
const name = native.key(i);
|
|
243
|
+
if (name?.startsWith(startsWith)) out.push(name);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
146
246
|
} catch {
|
|
147
|
-
return null;
|
|
148
247
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
248
|
+
for (const name of memory[store].keys()) if (name.startsWith(startsWith) && !out.includes(name)) out.push(name);
|
|
249
|
+
return out;
|
|
250
|
+
}
|
|
251
|
+
__name(listKeys, "listKeys");
|
|
252
|
+
const familyKey = /* @__PURE__ */ __name((family, id) => {
|
|
253
|
+
const part = normalizeSegment(id);
|
|
254
|
+
if (!part) throw new TypeError("storage family id is empty after normalisation");
|
|
255
|
+
return family.prefix + part;
|
|
256
|
+
}, "familyKey");
|
|
257
|
+
const api = {
|
|
258
|
+
owner,
|
|
259
|
+
key(...parts) {
|
|
260
|
+
const segments = parts.map(normalizeSegment);
|
|
261
|
+
if (segments.length === 0 || segments.some((segment) => !segment)) {
|
|
262
|
+
throw new TypeError(`storage key parts must be non-empty: ${JSON.stringify(parts)}`);
|
|
160
263
|
}
|
|
161
|
-
|
|
264
|
+
return `${prefix}${segments.join(".")}`;
|
|
265
|
+
},
|
|
266
|
+
familyKey,
|
|
267
|
+
isValid,
|
|
268
|
+
read(key, store) {
|
|
269
|
+
assertValid(key);
|
|
270
|
+
const target = resolveStore(key, store);
|
|
271
|
+
return rawGet(target, key);
|
|
272
|
+
},
|
|
273
|
+
write(key, value, store) {
|
|
274
|
+
assertOwned(key);
|
|
275
|
+
const target = resolveStore(key, store);
|
|
276
|
+
return rawSet(target, key, value);
|
|
277
|
+
},
|
|
278
|
+
remove(key, store) {
|
|
279
|
+
assertOwned(key);
|
|
280
|
+
const target = resolveStore(key, store);
|
|
281
|
+
rawRemove(target, key);
|
|
282
|
+
},
|
|
283
|
+
readJSON(key, store) {
|
|
284
|
+
const raw = api.read(key, store);
|
|
285
|
+
if (raw === null) return null;
|
|
286
|
+
try {
|
|
287
|
+
return JSON.parse(raw);
|
|
288
|
+
} catch {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
writeJSON(key, value, store) {
|
|
293
|
+
return api.write(key, JSON.stringify(value), store);
|
|
294
|
+
},
|
|
295
|
+
keys(store = "local") {
|
|
296
|
+
return listKeys(store, prefix);
|
|
297
|
+
},
|
|
298
|
+
clearAll({ all = false } = {}) {
|
|
299
|
+
for (const spec of specs) {
|
|
300
|
+
if (!all && !spec.personal) continue;
|
|
301
|
+
rawRemove(spec.store, spec.key);
|
|
302
|
+
}
|
|
303
|
+
for (const family of families) {
|
|
304
|
+
if (!all && !family.personal) continue;
|
|
305
|
+
for (const name of listKeys(family.store, family.prefix)) rawRemove(family.store, name);
|
|
306
|
+
}
|
|
307
|
+
if (all) {
|
|
308
|
+
for (const store of ["local", "session"]) {
|
|
309
|
+
for (const name of listKeys(store, prefix)) rawRemove(store, name);
|
|
310
|
+
}
|
|
311
|
+
for (const name of cookieNames()) if (name.startsWith(prefix)) rawRemove("cookie", name);
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
onChange(key, listener, store = "local") {
|
|
315
|
+
assertValid(key);
|
|
316
|
+
if (!hasWindow()) return () => {
|
|
317
|
+
};
|
|
318
|
+
const handler = /* @__PURE__ */ __name((event) => {
|
|
319
|
+
if (event.storageArea !== nativeStorage(store)) return;
|
|
320
|
+
if (event.key === null || event.key === key) listener(event.key === null ? null : event.newValue);
|
|
321
|
+
}, "handler");
|
|
322
|
+
window.addEventListener("storage", handler);
|
|
323
|
+
return () => window.removeEventListener("storage", handler);
|
|
162
324
|
}
|
|
163
|
-
}
|
|
325
|
+
};
|
|
326
|
+
return api;
|
|
327
|
+
}
|
|
328
|
+
__name(createStorage, "createStorage");
|
|
329
|
+
var cfgStorage = createStorage("cfg", {
|
|
330
|
+
keys: CFG_KEYS,
|
|
331
|
+
families: CFG_FAMILIES
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// src/_api/generated/helpers/auth.ts
|
|
335
|
+
var ACCESS_KEY = "cfg.auth.access_token";
|
|
336
|
+
var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
337
|
+
var API_KEY_KEY = "cfg.auth.api_key";
|
|
338
|
+
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
339
|
+
var isBrowser = typeof window !== "undefined";
|
|
340
|
+
var STORE_OF = {
|
|
341
|
+
localStorage: "local",
|
|
342
|
+
sessionStorage: "session",
|
|
343
|
+
cookie: "cookie"
|
|
164
344
|
};
|
|
165
345
|
function backendFor(mode) {
|
|
166
|
-
|
|
346
|
+
const store = STORE_OF[mode];
|
|
347
|
+
return {
|
|
348
|
+
get: /* @__PURE__ */ __name((key) => storage.read(key, store), "get"),
|
|
349
|
+
set(key, value) {
|
|
350
|
+
if (value === null) storage.remove(key, store);
|
|
351
|
+
else storage.write(key, value, store);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
167
354
|
}
|
|
168
355
|
__name(backendFor, "backendFor");
|
|
169
356
|
var _storageMode = "localStorage";
|
|
@@ -352,10 +539,12 @@ var auth = {
|
|
|
352
539
|
notifySessionChanged();
|
|
353
540
|
},
|
|
354
541
|
clearTokens() {
|
|
355
|
-
for (const
|
|
542
|
+
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
543
|
+
const backend = backendFor(mode);
|
|
356
544
|
backend.set(ACCESS_KEY, null);
|
|
357
545
|
backend.set(REFRESH_KEY, null);
|
|
358
546
|
}
|
|
547
|
+
storage.clearAll();
|
|
359
548
|
notifySessionChanged();
|
|
360
549
|
},
|
|
361
550
|
/** Session-aware: token PRESENT and not past its `exp` (or a live refresh
|
|
@@ -547,7 +736,7 @@ function dpopEnabled() {
|
|
|
547
736
|
}
|
|
548
737
|
}
|
|
549
738
|
__name(dpopEnabled, "dpopEnabled");
|
|
550
|
-
var _DPOP_DB = "cfg
|
|
739
|
+
var _DPOP_DB = "cfg.auth.dpop";
|
|
551
740
|
var _DPOP_STORE = "keys";
|
|
552
741
|
var _DPOP_KEY_ID = "dpop-ec-p256";
|
|
553
742
|
function _idbOpen() {
|