@legendsoflearning/lol-sdk-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/dist/auth/index.d.mts +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.js +12 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +3 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/cache/index.d.mts +26 -0
- package/dist/cache/index.d.ts +26 -0
- package/dist/cache/index.js +63 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/index.mjs +60 -0
- package/dist/cache/index.mjs.map +1 -0
- package/dist/chunk-Q4UXELOU.mjs +284 -0
- package/dist/chunk-Q4UXELOU.mjs.map +1 -0
- package/dist/chunk-WWN77BBN.js +286 -0
- package/dist/chunk-WWN77BBN.js.map +1 -0
- package/dist/generated/admins/index.d.mts +2566 -0
- package/dist/generated/admins/index.d.ts +2566 -0
- package/dist/generated/admins/index.js +110 -0
- package/dist/generated/admins/index.js.map +1 -0
- package/dist/generated/admins/index.mjs +97 -0
- package/dist/generated/admins/index.mjs.map +1 -0
- package/dist/generated/developers/index.d.mts +330 -0
- package/dist/generated/developers/index.d.ts +330 -0
- package/dist/generated/developers/index.js +30 -0
- package/dist/generated/developers/index.js.map +1 -0
- package/dist/generated/developers/index.mjs +25 -0
- package/dist/generated/developers/index.mjs.map +1 -0
- package/dist/generated/parents/index.d.mts +1097 -0
- package/dist/generated/parents/index.d.ts +1097 -0
- package/dist/generated/parents/index.js +112 -0
- package/dist/generated/parents/index.js.map +1 -0
- package/dist/generated/parents/index.mjs +99 -0
- package/dist/generated/parents/index.mjs.map +1 -0
- package/dist/generated/play/index.d.mts +1060 -0
- package/dist/generated/play/index.d.ts +1060 -0
- package/dist/generated/play/index.js +109 -0
- package/dist/generated/play/index.js.map +1 -0
- package/dist/generated/play/index.mjs +96 -0
- package/dist/generated/play/index.mjs.map +1 -0
- package/dist/generated/public/index.d.mts +791 -0
- package/dist/generated/public/index.d.ts +791 -0
- package/dist/generated/public/index.js +39 -0
- package/dist/generated/public/index.js.map +1 -0
- package/dist/generated/public/index.mjs +33 -0
- package/dist/generated/public/index.mjs.map +1 -0
- package/dist/generated/teachers/index.d.mts +6205 -0
- package/dist/generated/teachers/index.d.ts +6205 -0
- package/dist/generated/teachers/index.js +353 -0
- package/dist/generated/teachers/index.js.map +1 -0
- package/dist/generated/teachers/index.mjs +282 -0
- package/dist/generated/teachers/index.mjs.map +1 -0
- package/dist/index-vM3xPKfV.d.mts +173 -0
- package/dist/index-vM3xPKfV.d.ts +173 -0
- package/dist/index.d.mts +154 -0
- package/dist/index.d.ts +154 -0
- package/dist/index.js +352 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +336 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +111 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { d as Auth, a as AuthConfig, g as AuthMode, k as createAuth } from '../index-vM3xPKfV.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { d as Auth, a as AuthConfig, g as AuthMode, k as createAuth } from '../index-vM3xPKfV.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkWWN77BBN_js = require('../chunk-WWN77BBN.js');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "createAuth", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkWWN77BBN_js.createAuth; }
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { InMemoryCacheConfig, TypePolicies } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cache utilities for the Legends SDK.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface CacheConfig extends InMemoryCacheConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Enable persistent cache in localStorage.
|
|
10
|
+
*/
|
|
11
|
+
persist?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Key for persistent storage.
|
|
14
|
+
*/
|
|
15
|
+
persistKey?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Default type policies for Legends data.
|
|
19
|
+
*/
|
|
20
|
+
declare const defaultTypePolicies: TypePolicies;
|
|
21
|
+
/**
|
|
22
|
+
* Create cache configuration with sensible defaults.
|
|
23
|
+
*/
|
|
24
|
+
declare function createCacheConfig(config?: Partial<CacheConfig>): CacheConfig;
|
|
25
|
+
|
|
26
|
+
export { type CacheConfig, createCacheConfig, defaultTypePolicies };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { InMemoryCacheConfig, TypePolicies } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cache utilities for the Legends SDK.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface CacheConfig extends InMemoryCacheConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Enable persistent cache in localStorage.
|
|
10
|
+
*/
|
|
11
|
+
persist?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Key for persistent storage.
|
|
14
|
+
*/
|
|
15
|
+
persistKey?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Default type policies for Legends data.
|
|
19
|
+
*/
|
|
20
|
+
declare const defaultTypePolicies: TypePolicies;
|
|
21
|
+
/**
|
|
22
|
+
* Create cache configuration with sensible defaults.
|
|
23
|
+
*/
|
|
24
|
+
declare function createCacheConfig(config?: Partial<CacheConfig>): CacheConfig;
|
|
25
|
+
|
|
26
|
+
export { type CacheConfig, createCacheConfig, defaultTypePolicies };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/cache/index.ts
|
|
4
|
+
var defaultTypePolicies = {
|
|
5
|
+
Query: {
|
|
6
|
+
fields: {
|
|
7
|
+
// Pagination support for list queries
|
|
8
|
+
students: {
|
|
9
|
+
keyArgs: ["search", "filter"],
|
|
10
|
+
merge(existing, incoming, { args }) {
|
|
11
|
+
if (!args?.after) {
|
|
12
|
+
return incoming;
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
...incoming,
|
|
16
|
+
edges: [...existing?.edges ?? [], ...incoming.edges]
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
rosters: {
|
|
21
|
+
keyArgs: ["archived"],
|
|
22
|
+
merge(existing, incoming, { args }) {
|
|
23
|
+
if (!args?.after) {
|
|
24
|
+
return incoming;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
...incoming,
|
|
28
|
+
edges: [...existing?.edges ?? [], ...incoming.edges]
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
Teacher: {
|
|
35
|
+
keyFields: ["id"]
|
|
36
|
+
},
|
|
37
|
+
Student: {
|
|
38
|
+
keyFields: ["id"]
|
|
39
|
+
},
|
|
40
|
+
Roster: {
|
|
41
|
+
keyFields: ["id"]
|
|
42
|
+
},
|
|
43
|
+
School: {
|
|
44
|
+
keyFields: ["id"]
|
|
45
|
+
},
|
|
46
|
+
District: {
|
|
47
|
+
keyFields: ["id"]
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
function createCacheConfig(config = {}) {
|
|
51
|
+
return {
|
|
52
|
+
typePolicies: {
|
|
53
|
+
...defaultTypePolicies,
|
|
54
|
+
...config.typePolicies
|
|
55
|
+
},
|
|
56
|
+
...config
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
exports.createCacheConfig = createCacheConfig;
|
|
61
|
+
exports.defaultTypePolicies = defaultTypePolicies;
|
|
62
|
+
//# sourceMappingURL=index.js.map
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cache/index.ts"],"names":[],"mappings":";;;AAqBO,IAAM,mBAAA,GAAoC;AAAA,EAC/C,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ;AAAA;AAAA,MAEN,QAAA,EAAU;AAAA,QACR,OAAA,EAAS,CAAC,QAAA,EAAU,QAAQ,CAAA;AAAA,QAC5B,KAAA,CAAM,QAAA,EAAU,QAAA,EAAU,EAAE,MAAK,EAAG;AAClC,UAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAChB,YAAA,OAAO,QAAA;AAAA,UACT;AACA,UAAA,OAAO;AAAA,YACL,GAAG,QAAA;AAAA,YACH,KAAA,EAAO,CAAC,GAAI,QAAA,EAAU,SAAS,EAAC,EAAI,GAAG,QAAA,CAAS,KAAK;AAAA,WACvD;AAAA,QACF;AAAA,OACF;AAAA,MACA,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,CAAC,UAAU,CAAA;AAAA,QACpB,KAAA,CAAM,QAAA,EAAU,QAAA,EAAU,EAAE,MAAK,EAAG;AAClC,UAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAChB,YAAA,OAAO,QAAA;AAAA,UACT;AACA,UAAA,OAAO;AAAA,YACL,GAAG,QAAA;AAAA,YACH,KAAA,EAAO,CAAC,GAAI,QAAA,EAAU,SAAS,EAAC,EAAI,GAAG,QAAA,CAAS,KAAK;AAAA,WACvD;AAAA,QACF;AAAA;AACF;AACF,GACF;AAAA,EACA,OAAA,EAAS;AAAA,IACP,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,OAAA,EAAS;AAAA,IACP,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,SAAA,EAAW,CAAC,IAAI;AAAA;AAEpB;AAKO,SAAS,iBAAA,CAAkB,MAAA,GAA+B,EAAC,EAAgB;AAChF,EAAA,OAAO;AAAA,IACL,YAAA,EAAc;AAAA,MACZ,GAAG,mBAAA;AAAA,MACH,GAAG,MAAA,CAAO;AAAA,KACZ;AAAA,IACA,GAAG;AAAA,GACL;AACF","file":"index.js","sourcesContent":["/**\n * Cache utilities for the Legends SDK.\n */\n\nimport type { InMemoryCacheConfig, TypePolicies } from '@apollo/client'\n\nexport interface CacheConfig extends InMemoryCacheConfig {\n /**\n * Enable persistent cache in localStorage.\n */\n persist?: boolean\n\n /**\n * Key for persistent storage.\n */\n persistKey?: string\n}\n\n/**\n * Default type policies for Legends data.\n */\nexport const defaultTypePolicies: TypePolicies = {\n Query: {\n fields: {\n // Pagination support for list queries\n students: {\n keyArgs: ['search', 'filter'],\n merge(existing, incoming, { args }) {\n if (!args?.after) {\n return incoming\n }\n return {\n ...incoming,\n edges: [...(existing?.edges ?? []), ...incoming.edges],\n }\n },\n },\n rosters: {\n keyArgs: ['archived'],\n merge(existing, incoming, { args }) {\n if (!args?.after) {\n return incoming\n }\n return {\n ...incoming,\n edges: [...(existing?.edges ?? []), ...incoming.edges],\n }\n },\n },\n },\n },\n Teacher: {\n keyFields: ['id'],\n },\n Student: {\n keyFields: ['id'],\n },\n Roster: {\n keyFields: ['id'],\n },\n School: {\n keyFields: ['id'],\n },\n District: {\n keyFields: ['id'],\n },\n}\n\n/**\n * Create cache configuration with sensible defaults.\n */\nexport function createCacheConfig(config: Partial<CacheConfig> = {}): CacheConfig {\n return {\n typePolicies: {\n ...defaultTypePolicies,\n ...config.typePolicies,\n },\n ...config,\n }\n}\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// src/cache/index.ts
|
|
2
|
+
var defaultTypePolicies = {
|
|
3
|
+
Query: {
|
|
4
|
+
fields: {
|
|
5
|
+
// Pagination support for list queries
|
|
6
|
+
students: {
|
|
7
|
+
keyArgs: ["search", "filter"],
|
|
8
|
+
merge(existing, incoming, { args }) {
|
|
9
|
+
if (!args?.after) {
|
|
10
|
+
return incoming;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
...incoming,
|
|
14
|
+
edges: [...existing?.edges ?? [], ...incoming.edges]
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
rosters: {
|
|
19
|
+
keyArgs: ["archived"],
|
|
20
|
+
merge(existing, incoming, { args }) {
|
|
21
|
+
if (!args?.after) {
|
|
22
|
+
return incoming;
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
...incoming,
|
|
26
|
+
edges: [...existing?.edges ?? [], ...incoming.edges]
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
Teacher: {
|
|
33
|
+
keyFields: ["id"]
|
|
34
|
+
},
|
|
35
|
+
Student: {
|
|
36
|
+
keyFields: ["id"]
|
|
37
|
+
},
|
|
38
|
+
Roster: {
|
|
39
|
+
keyFields: ["id"]
|
|
40
|
+
},
|
|
41
|
+
School: {
|
|
42
|
+
keyFields: ["id"]
|
|
43
|
+
},
|
|
44
|
+
District: {
|
|
45
|
+
keyFields: ["id"]
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
function createCacheConfig(config = {}) {
|
|
49
|
+
return {
|
|
50
|
+
typePolicies: {
|
|
51
|
+
...defaultTypePolicies,
|
|
52
|
+
...config.typePolicies
|
|
53
|
+
},
|
|
54
|
+
...config
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { createCacheConfig, defaultTypePolicies };
|
|
59
|
+
//# sourceMappingURL=index.mjs.map
|
|
60
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cache/index.ts"],"names":[],"mappings":";AAqBO,IAAM,mBAAA,GAAoC;AAAA,EAC/C,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ;AAAA;AAAA,MAEN,QAAA,EAAU;AAAA,QACR,OAAA,EAAS,CAAC,QAAA,EAAU,QAAQ,CAAA;AAAA,QAC5B,KAAA,CAAM,QAAA,EAAU,QAAA,EAAU,EAAE,MAAK,EAAG;AAClC,UAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAChB,YAAA,OAAO,QAAA;AAAA,UACT;AACA,UAAA,OAAO;AAAA,YACL,GAAG,QAAA;AAAA,YACH,KAAA,EAAO,CAAC,GAAI,QAAA,EAAU,SAAS,EAAC,EAAI,GAAG,QAAA,CAAS,KAAK;AAAA,WACvD;AAAA,QACF;AAAA,OACF;AAAA,MACA,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,CAAC,UAAU,CAAA;AAAA,QACpB,KAAA,CAAM,QAAA,EAAU,QAAA,EAAU,EAAE,MAAK,EAAG;AAClC,UAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAChB,YAAA,OAAO,QAAA;AAAA,UACT;AACA,UAAA,OAAO;AAAA,YACL,GAAG,QAAA;AAAA,YACH,KAAA,EAAO,CAAC,GAAI,QAAA,EAAU,SAAS,EAAC,EAAI,GAAG,QAAA,CAAS,KAAK;AAAA,WACvD;AAAA,QACF;AAAA;AACF;AACF,GACF;AAAA,EACA,OAAA,EAAS;AAAA,IACP,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,OAAA,EAAS;AAAA,IACP,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,SAAA,EAAW,CAAC,IAAI;AAAA,GAClB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,SAAA,EAAW,CAAC,IAAI;AAAA;AAEpB;AAKO,SAAS,iBAAA,CAAkB,MAAA,GAA+B,EAAC,EAAgB;AAChF,EAAA,OAAO;AAAA,IACL,YAAA,EAAc;AAAA,MACZ,GAAG,mBAAA;AAAA,MACH,GAAG,MAAA,CAAO;AAAA,KACZ;AAAA,IACA,GAAG;AAAA,GACL;AACF","file":"index.mjs","sourcesContent":["/**\n * Cache utilities for the Legends SDK.\n */\n\nimport type { InMemoryCacheConfig, TypePolicies } from '@apollo/client'\n\nexport interface CacheConfig extends InMemoryCacheConfig {\n /**\n * Enable persistent cache in localStorage.\n */\n persist?: boolean\n\n /**\n * Key for persistent storage.\n */\n persistKey?: string\n}\n\n/**\n * Default type policies for Legends data.\n */\nexport const defaultTypePolicies: TypePolicies = {\n Query: {\n fields: {\n // Pagination support for list queries\n students: {\n keyArgs: ['search', 'filter'],\n merge(existing, incoming, { args }) {\n if (!args?.after) {\n return incoming\n }\n return {\n ...incoming,\n edges: [...(existing?.edges ?? []), ...incoming.edges],\n }\n },\n },\n rosters: {\n keyArgs: ['archived'],\n merge(existing, incoming, { args }) {\n if (!args?.after) {\n return incoming\n }\n return {\n ...incoming,\n edges: [...(existing?.edges ?? []), ...incoming.edges],\n }\n },\n },\n },\n },\n Teacher: {\n keyFields: ['id'],\n },\n Student: {\n keyFields: ['id'],\n },\n Roster: {\n keyFields: ['id'],\n },\n School: {\n keyFields: ['id'],\n },\n District: {\n keyFields: ['id'],\n },\n}\n\n/**\n * Create cache configuration with sensible defaults.\n */\nexport function createCacheConfig(config: Partial<CacheConfig> = {}): CacheConfig {\n return {\n typePolicies: {\n ...defaultTypePolicies,\n ...config.typePolicies,\n },\n ...config,\n }\n}\n"]}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// src/auth/index.ts
|
|
2
|
+
var STORAGE_KEY = "lol_sdk_session";
|
|
3
|
+
var MemoryStorage = class {
|
|
4
|
+
data = {};
|
|
5
|
+
getItem(key) {
|
|
6
|
+
return this.data[key] ?? null;
|
|
7
|
+
}
|
|
8
|
+
setItem(key, value) {
|
|
9
|
+
this.data[key] = value;
|
|
10
|
+
}
|
|
11
|
+
removeItem(key) {
|
|
12
|
+
delete this.data[key];
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var TEACHER_SIGN_IN_MUTATION = `
|
|
16
|
+
mutation TeacherSignIn($email: String!, $password: String!, $rememberMe: Boolean) {
|
|
17
|
+
teacherSignIn(email: $email, password: $password, rememberMe: $rememberMe) {
|
|
18
|
+
success
|
|
19
|
+
user { id }
|
|
20
|
+
teacher { id code email givenName familyName }
|
|
21
|
+
sessionToken
|
|
22
|
+
errors { field message }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
var API_AUTH_CONFIG = {
|
|
27
|
+
teachers: {
|
|
28
|
+
signInMutation: TEACHER_SIGN_IN_MUTATION,
|
|
29
|
+
signInField: "teacherSignIn",
|
|
30
|
+
oauthUrl: (baseUrl, provider) => {
|
|
31
|
+
if (provider === "google") {
|
|
32
|
+
return `${baseUrl}/oauth/google?role=lol_teacher&sign_in=true&frontend=v2`;
|
|
33
|
+
}
|
|
34
|
+
if (provider === "clever") {
|
|
35
|
+
return `${baseUrl}/clever/login`;
|
|
36
|
+
}
|
|
37
|
+
return `${baseUrl}/oauth/${provider}?role=lol_teacher`;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
parents: {
|
|
41
|
+
signInMutation: TEACHER_SIGN_IN_MUTATION.replace(/teacher/gi, "parent"),
|
|
42
|
+
signInField: "parentSignIn",
|
|
43
|
+
oauthUrl: (baseUrl, provider) => `${baseUrl}/oauth/${provider}?role=parent`
|
|
44
|
+
},
|
|
45
|
+
play: {
|
|
46
|
+
signInMutation: "",
|
|
47
|
+
signInField: "",
|
|
48
|
+
oauthUrl: (baseUrl, provider) => `${baseUrl}/oauth/${provider}?role=student`
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
function createAuth(config) {
|
|
52
|
+
const {
|
|
53
|
+
api,
|
|
54
|
+
baseUrl,
|
|
55
|
+
mode = "cookie",
|
|
56
|
+
storage = "localStorage",
|
|
57
|
+
autoRefresh = true,
|
|
58
|
+
clientId,
|
|
59
|
+
redirectUri = typeof window !== "undefined" ? `${window.location.origin}/auth/callback` : ""
|
|
60
|
+
} = config;
|
|
61
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
62
|
+
let refreshTimeout = null;
|
|
63
|
+
const apiAuthConfig = API_AUTH_CONFIG[api] || API_AUTH_CONFIG.teachers;
|
|
64
|
+
const storageAdapter = (() => {
|
|
65
|
+
if (typeof storage === "object") return storage;
|
|
66
|
+
if (typeof window === "undefined") return new MemoryStorage();
|
|
67
|
+
switch (storage) {
|
|
68
|
+
case "localStorage":
|
|
69
|
+
return window.localStorage;
|
|
70
|
+
case "sessionStorage":
|
|
71
|
+
return window.sessionStorage;
|
|
72
|
+
case "memory":
|
|
73
|
+
return new MemoryStorage();
|
|
74
|
+
default:
|
|
75
|
+
return window.localStorage;
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
function notifyListeners(session) {
|
|
79
|
+
listeners.forEach((callback) => callback(session));
|
|
80
|
+
}
|
|
81
|
+
function saveSession(session) {
|
|
82
|
+
storageAdapter.setItem(STORAGE_KEY, JSON.stringify(session));
|
|
83
|
+
notifyListeners(session);
|
|
84
|
+
if (autoRefresh) {
|
|
85
|
+
scheduleRefresh(session);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function clearSession() {
|
|
89
|
+
storageAdapter.removeItem(STORAGE_KEY);
|
|
90
|
+
notifyListeners(null);
|
|
91
|
+
if (refreshTimeout) {
|
|
92
|
+
clearTimeout(refreshTimeout);
|
|
93
|
+
refreshTimeout = null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function scheduleRefresh(session) {
|
|
97
|
+
if (refreshTimeout) {
|
|
98
|
+
clearTimeout(refreshTimeout);
|
|
99
|
+
}
|
|
100
|
+
const expiresAt = new Date(session.expiresAt).getTime();
|
|
101
|
+
const now = Date.now();
|
|
102
|
+
const refreshIn = expiresAt - now - 6e4;
|
|
103
|
+
if (refreshIn > 0) {
|
|
104
|
+
refreshTimeout = setTimeout(() => {
|
|
105
|
+
auth.refreshToken();
|
|
106
|
+
}, refreshIn);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const auth = {
|
|
110
|
+
async signIn(credentials) {
|
|
111
|
+
const graphqlEndpoint = `${baseUrl}/api2/${api}/graphql`;
|
|
112
|
+
const headers = {
|
|
113
|
+
"Content-Type": "application/json"
|
|
114
|
+
};
|
|
115
|
+
const response = await fetch(graphqlEndpoint, {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers,
|
|
118
|
+
credentials: mode === "cookie" ? "include" : "omit",
|
|
119
|
+
body: JSON.stringify({
|
|
120
|
+
query: apiAuthConfig.signInMutation,
|
|
121
|
+
variables: {
|
|
122
|
+
email: credentials.email,
|
|
123
|
+
password: credentials.password,
|
|
124
|
+
rememberMe: credentials.rememberMe ?? false
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
const result = await response.json();
|
|
129
|
+
const data = result.data?.[apiAuthConfig.signInField];
|
|
130
|
+
if (!data?.success) {
|
|
131
|
+
const errorMessages = data?.errors?.map((e) => e.message).join(", ");
|
|
132
|
+
return {
|
|
133
|
+
success: false,
|
|
134
|
+
error: errorMessages || "Sign in failed"
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const session = {
|
|
138
|
+
user: {
|
|
139
|
+
id: data.user?.id || data.teacher?.id,
|
|
140
|
+
email: data.teacher?.email,
|
|
141
|
+
firstName: data.teacher?.givenName,
|
|
142
|
+
lastName: data.teacher?.familyName
|
|
143
|
+
},
|
|
144
|
+
token: data.sessionToken,
|
|
145
|
+
// Used for X-Session-Token header in token mode
|
|
146
|
+
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3)
|
|
147
|
+
// 7 days default
|
|
148
|
+
};
|
|
149
|
+
saveSession(session);
|
|
150
|
+
return { success: true, session };
|
|
151
|
+
},
|
|
152
|
+
async signUp(_input) {
|
|
153
|
+
return {
|
|
154
|
+
success: false,
|
|
155
|
+
error: "Please use the signup page at /sign-up"
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
async signInWithOAuth(provider) {
|
|
159
|
+
if (clientId && mode === "token") {
|
|
160
|
+
const params = new URLSearchParams({
|
|
161
|
+
client_id: clientId,
|
|
162
|
+
redirect_uri: redirectUri,
|
|
163
|
+
response_type: "code",
|
|
164
|
+
provider,
|
|
165
|
+
role: api === "teachers" ? "lol_teacher" : api === "parents" ? "parent" : "student"
|
|
166
|
+
});
|
|
167
|
+
window.location.href = `${baseUrl}/oauth/authorize?${params}`;
|
|
168
|
+
return new Promise(() => {
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const oauthUrl = apiAuthConfig.oauthUrl(baseUrl, provider);
|
|
172
|
+
window.location.href = oauthUrl;
|
|
173
|
+
return new Promise(() => {
|
|
174
|
+
});
|
|
175
|
+
},
|
|
176
|
+
async handleOAuthCallback(params) {
|
|
177
|
+
const { code, error } = params;
|
|
178
|
+
if (error) {
|
|
179
|
+
return { success: false, error };
|
|
180
|
+
}
|
|
181
|
+
if (!code) {
|
|
182
|
+
return { success: false, error: "No authorization code received" };
|
|
183
|
+
}
|
|
184
|
+
const response = await fetch(`${baseUrl}/oauth/token`, {
|
|
185
|
+
method: "POST",
|
|
186
|
+
headers: {
|
|
187
|
+
"Content-Type": "application/json"
|
|
188
|
+
},
|
|
189
|
+
body: JSON.stringify({
|
|
190
|
+
grant_type: "authorization_code",
|
|
191
|
+
code,
|
|
192
|
+
client_id: clientId,
|
|
193
|
+
redirect_uri: redirectUri
|
|
194
|
+
})
|
|
195
|
+
});
|
|
196
|
+
const data = await response.json();
|
|
197
|
+
if (!response.ok || data.error) {
|
|
198
|
+
return {
|
|
199
|
+
success: false,
|
|
200
|
+
error: data.error_description || data.error || "Token exchange failed"
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const session = {
|
|
204
|
+
user: {
|
|
205
|
+
id: data.user?.id,
|
|
206
|
+
email: data.user?.email,
|
|
207
|
+
firstName: data.user?.first_name,
|
|
208
|
+
lastName: data.user?.last_name
|
|
209
|
+
},
|
|
210
|
+
token: data.access_token || data.session_token,
|
|
211
|
+
expiresAt: new Date(Date.now() + (data.expires_in || 7 * 24 * 60 * 60) * 1e3)
|
|
212
|
+
};
|
|
213
|
+
saveSession(session);
|
|
214
|
+
return { success: true, session };
|
|
215
|
+
},
|
|
216
|
+
async signOut() {
|
|
217
|
+
const session = auth.getSession();
|
|
218
|
+
try {
|
|
219
|
+
const headers = {
|
|
220
|
+
"Content-Type": "application/json"
|
|
221
|
+
};
|
|
222
|
+
if (mode === "token" && session?.token) {
|
|
223
|
+
headers["X-Session-Token"] = session.token;
|
|
224
|
+
}
|
|
225
|
+
await fetch(`${baseUrl}/accounts/signout`, {
|
|
226
|
+
method: "POST",
|
|
227
|
+
headers,
|
|
228
|
+
credentials: mode === "cookie" ? "include" : "omit"
|
|
229
|
+
});
|
|
230
|
+
} catch {
|
|
231
|
+
}
|
|
232
|
+
clearSession();
|
|
233
|
+
},
|
|
234
|
+
getSession() {
|
|
235
|
+
const stored = storageAdapter.getItem(STORAGE_KEY);
|
|
236
|
+
if (!stored) return null;
|
|
237
|
+
try {
|
|
238
|
+
const session = JSON.parse(stored);
|
|
239
|
+
session.expiresAt = new Date(session.expiresAt);
|
|
240
|
+
if (session.expiresAt.getTime() < Date.now()) {
|
|
241
|
+
clearSession();
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
return session;
|
|
245
|
+
} catch {
|
|
246
|
+
clearSession();
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
getAuthHeaders() {
|
|
251
|
+
const session = auth.getSession();
|
|
252
|
+
const headers = {};
|
|
253
|
+
if (mode === "token" && session?.token) {
|
|
254
|
+
headers["X-Session-Token"] = session.token;
|
|
255
|
+
}
|
|
256
|
+
return headers;
|
|
257
|
+
},
|
|
258
|
+
getMode() {
|
|
259
|
+
return mode;
|
|
260
|
+
},
|
|
261
|
+
onAuthChange(callback) {
|
|
262
|
+
listeners.add(callback);
|
|
263
|
+
callback(auth.getSession());
|
|
264
|
+
return () => {
|
|
265
|
+
listeners.delete(callback);
|
|
266
|
+
};
|
|
267
|
+
},
|
|
268
|
+
async refreshToken() {
|
|
269
|
+
return auth.getSession();
|
|
270
|
+
},
|
|
271
|
+
_handleAuthError() {
|
|
272
|
+
clearSession();
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
const existingSession = auth.getSession();
|
|
276
|
+
if (existingSession && autoRefresh) {
|
|
277
|
+
scheduleRefresh(existingSession);
|
|
278
|
+
}
|
|
279
|
+
return auth;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export { createAuth };
|
|
283
|
+
//# sourceMappingURL=chunk-Q4UXELOU.mjs.map
|
|
284
|
+
//# sourceMappingURL=chunk-Q4UXELOU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth/index.ts"],"names":[],"mappings":"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","file":"chunk-Q4UXELOU.mjs","sourcesContent":["/**\n * Authentication module for the Legends SDK.\n *\n * Supports two auth modes:\n * - 'cookie' (default): Uses session cookies, best for same-domain apps\n * - 'token': Uses X-Session-Token header, works cross-domain\n */\n\nimport type { ApiType } from '../api'\nimport type {\n Session,\n Credentials,\n SignUpInput,\n AuthResult,\n OAuthProvider,\n Unsubscribe,\n AuthCallback,\n} from '../types'\n\nexport type AuthMode = 'cookie' | 'token'\n\nexport interface AuthConfig {\n /**\n * Authentication mode.\n * - 'cookie': Uses session cookies (same-domain only)\n * - 'token': Uses X-Session-Token header (cross-domain)\n * @default 'cookie'\n */\n mode?: AuthMode\n\n /**\n * Storage mechanism for session data.\n * @default 'localStorage'\n */\n storage?: 'localStorage' | 'sessionStorage' | 'memory' | Storage\n\n /**\n * Auto-refresh tokens before expiry.\n * @default true\n */\n autoRefresh?: boolean\n\n /**\n * Callback when auth state changes.\n */\n onAuthChange?: AuthCallback\n\n /**\n * Client ID for OAuth flows (for registered third-party apps).\n */\n clientId?: string\n\n /**\n * Redirect URI for OAuth flows.\n * @default window.location.origin + '/auth/callback'\n */\n redirectUri?: string\n}\n\nexport interface Auth {\n /**\n * Sign in with email and password.\n */\n signIn(credentials: Credentials): Promise<AuthResult>\n\n /**\n * Sign up with email, password, and profile info.\n */\n signUp(input: SignUpInput): Promise<AuthResult>\n\n /**\n * Sign in with OAuth provider.\n * For third-party apps, this initiates the OAuth authorization flow.\n */\n signInWithOAuth(provider: OAuthProvider): Promise<AuthResult>\n\n /**\n * Handle OAuth callback (for third-party apps).\n * Call this on your redirect_uri page to complete the OAuth flow.\n */\n handleOAuthCallback(params: { code?: string; error?: string }): Promise<AuthResult>\n\n /**\n * Sign out and clear session.\n */\n signOut(): Promise<void>\n\n /**\n * Get the current session.\n */\n getSession(): Session | null\n\n /**\n * Get auth headers for API requests (token mode only).\n * Returns headers object with X-Session-Token if authenticated.\n */\n getAuthHeaders(): Record<string, string>\n\n /**\n * Get the current auth mode.\n */\n getMode(): AuthMode\n\n /**\n * Subscribe to auth state changes.\n */\n onAuthChange(callback: AuthCallback): Unsubscribe\n\n /**\n * Refresh the current token.\n */\n refreshToken(): Promise<Session | null>\n\n /**\n * @internal Handle auth errors from the API.\n */\n _handleAuthError(): void\n}\n\ninterface StorageAdapter {\n getItem(key: string): string | null\n setItem(key: string, value: string): void\n removeItem(key: string): void\n}\n\nconst STORAGE_KEY = 'lol_sdk_session'\n\nclass MemoryStorage implements StorageAdapter {\n private data: Record<string, string> = {}\n\n getItem(key: string): string | null {\n return this.data[key] ?? null\n }\n\n setItem(key: string, value: string): void {\n this.data[key] = value\n }\n\n removeItem(key: string): void {\n delete this.data[key]\n }\n}\n\n// GraphQL mutation for teacher sign in\nconst TEACHER_SIGN_IN_MUTATION = `\n mutation TeacherSignIn($email: String!, $password: String!, $rememberMe: Boolean) {\n teacherSignIn(email: $email, password: $password, rememberMe: $rememberMe) {\n success\n user { id }\n teacher { id code email givenName familyName }\n sessionToken\n errors { field message }\n }\n }\n`\n\n// Map API types to their GraphQL endpoints and mutations\nconst API_AUTH_CONFIG: Record<string, {\n signInMutation: string\n signInField: string\n oauthUrl: (baseUrl: string, provider: string) => string\n}> = {\n teachers: {\n signInMutation: TEACHER_SIGN_IN_MUTATION,\n signInField: 'teacherSignIn',\n oauthUrl: (baseUrl, provider) => {\n if (provider === 'google') {\n return `${baseUrl}/oauth/google?role=lol_teacher&sign_in=true&frontend=v2`\n }\n if (provider === 'clever') {\n return `${baseUrl}/clever/login`\n }\n return `${baseUrl}/oauth/${provider}?role=lol_teacher`\n },\n },\n parents: {\n signInMutation: TEACHER_SIGN_IN_MUTATION.replace(/teacher/gi, 'parent'),\n signInField: 'parentSignIn',\n oauthUrl: (baseUrl, provider) => `${baseUrl}/oauth/${provider}?role=parent`,\n },\n play: {\n signInMutation: '',\n signInField: '',\n oauthUrl: (baseUrl, provider) => `${baseUrl}/oauth/${provider}?role=student`,\n },\n}\n\nexport function createAuth(\n config: AuthConfig & { api: ApiType; baseUrl: string }\n): Auth {\n const {\n api,\n baseUrl,\n mode = 'cookie',\n storage = 'localStorage',\n autoRefresh = true,\n clientId,\n redirectUri = typeof window !== 'undefined'\n ? `${window.location.origin}/auth/callback`\n : '',\n } = config\n\n const listeners: Set<AuthCallback> = new Set()\n let refreshTimeout: ReturnType<typeof setTimeout> | null = null\n const apiAuthConfig = API_AUTH_CONFIG[api] || API_AUTH_CONFIG.teachers\n\n // Initialize storage adapter\n const storageAdapter: StorageAdapter = (() => {\n if (typeof storage === 'object') return storage\n if (typeof window === 'undefined') return new MemoryStorage()\n\n switch (storage) {\n case 'localStorage':\n return window.localStorage\n case 'sessionStorage':\n return window.sessionStorage\n case 'memory':\n return new MemoryStorage()\n default:\n return window.localStorage\n }\n })()\n\n function notifyListeners(session: Session | null): void {\n listeners.forEach((callback) => callback(session))\n }\n\n function saveSession(session: Session): void {\n storageAdapter.setItem(STORAGE_KEY, JSON.stringify(session))\n notifyListeners(session)\n\n if (autoRefresh) {\n scheduleRefresh(session)\n }\n }\n\n function clearSession(): void {\n storageAdapter.removeItem(STORAGE_KEY)\n notifyListeners(null)\n\n if (refreshTimeout) {\n clearTimeout(refreshTimeout)\n refreshTimeout = null\n }\n }\n\n function scheduleRefresh(session: Session): void {\n if (refreshTimeout) {\n clearTimeout(refreshTimeout)\n }\n\n const expiresAt = new Date(session.expiresAt).getTime()\n const now = Date.now()\n const refreshIn = expiresAt - now - 60000 // Refresh 1 minute before expiry\n\n if (refreshIn > 0) {\n refreshTimeout = setTimeout(() => {\n auth.refreshToken()\n }, refreshIn)\n }\n }\n\n const auth: Auth = {\n async signIn(credentials) {\n // Use GraphQL mutation for sign in\n const graphqlEndpoint = `${baseUrl}/api2/${api}/graphql`\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n const response = await fetch(graphqlEndpoint, {\n method: 'POST',\n headers,\n credentials: mode === 'cookie' ? 'include' : 'omit',\n body: JSON.stringify({\n query: apiAuthConfig.signInMutation,\n variables: {\n email: credentials.email,\n password: credentials.password,\n rememberMe: credentials.rememberMe ?? false,\n },\n }),\n })\n\n const result = await response.json()\n const data = result.data?.[apiAuthConfig.signInField]\n\n if (!data?.success) {\n const errorMessages = data?.errors?.map((e: { message: string }) => e.message).join(', ')\n return {\n success: false,\n error: errorMessages || 'Sign in failed',\n }\n }\n\n // Store session info - token is used for cross-domain auth\n const session: Session = {\n user: {\n id: data.user?.id || data.teacher?.id,\n email: data.teacher?.email,\n firstName: data.teacher?.givenName,\n lastName: data.teacher?.familyName,\n },\n token: data.sessionToken, // Used for X-Session-Token header in token mode\n expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days default\n }\n\n saveSession(session)\n\n return { success: true, session }\n },\n\n async signUp(_input) {\n // For now, redirect to the signup page - signup flow is complex\n return {\n success: false,\n error: 'Please use the signup page at /sign-up',\n }\n },\n\n async signInWithOAuth(provider) {\n // For third-party apps with clientId, use OAuth authorization flow\n if (clientId && mode === 'token') {\n // Build OAuth authorization URL for third-party app flow\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: 'code',\n provider,\n role: api === 'teachers' ? 'lol_teacher' : api === 'parents' ? 'parent' : 'student',\n })\n window.location.href = `${baseUrl}/oauth/authorize?${params}`\n return new Promise(() => {})\n }\n\n // For first-party apps (Legends' own apps), use direct OAuth redirect\n // Third-party apps should use clientId with the OAuth authorization flow above\n const oauthUrl = apiAuthConfig.oauthUrl(baseUrl, provider)\n window.location.href = oauthUrl\n\n // Return a pending promise since we're redirecting\n return new Promise(() => {})\n },\n\n async handleOAuthCallback(params) {\n const { code, error } = params\n\n if (error) {\n return { success: false, error }\n }\n\n if (!code) {\n return { success: false, error: 'No authorization code received' }\n }\n\n // Exchange code for token\n const response = await fetch(`${baseUrl}/oauth/token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n code,\n client_id: clientId,\n redirect_uri: redirectUri,\n }),\n })\n\n const data = await response.json()\n\n if (!response.ok || data.error) {\n return {\n success: false,\n error: data.error_description || data.error || 'Token exchange failed',\n }\n }\n\n // Store session from OAuth response\n const session: Session = {\n user: {\n id: data.user?.id,\n email: data.user?.email,\n firstName: data.user?.first_name,\n lastName: data.user?.last_name,\n },\n token: data.access_token || data.session_token,\n expiresAt: new Date(Date.now() + (data.expires_in || 7 * 24 * 60 * 60) * 1000),\n }\n\n saveSession(session)\n\n return { success: true, session }\n },\n\n async signOut() {\n const session = auth.getSession()\n\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n // In token mode, include the token in headers\n if (mode === 'token' && session?.token) {\n headers['X-Session-Token'] = session.token\n }\n\n await fetch(`${baseUrl}/accounts/signout`, {\n method: 'POST',\n headers,\n credentials: mode === 'cookie' ? 'include' : 'omit',\n })\n } catch {\n // Ignore errors, clear session anyway\n }\n\n clearSession()\n },\n\n getSession() {\n const stored = storageAdapter.getItem(STORAGE_KEY)\n if (!stored) return null\n\n try {\n const session = JSON.parse(stored) as Session\n session.expiresAt = new Date(session.expiresAt)\n\n // Check if expired\n if (session.expiresAt.getTime() < Date.now()) {\n clearSession()\n return null\n }\n\n return session\n } catch {\n clearSession()\n return null\n }\n },\n\n getAuthHeaders(): Record<string, string> {\n const session = auth.getSession()\n const headers: Record<string, string> = {}\n\n if (mode === 'token' && session?.token) {\n headers['X-Session-Token'] = session.token\n }\n\n return headers\n },\n\n getMode() {\n return mode\n },\n\n onAuthChange(callback) {\n listeners.add(callback)\n\n // Immediately call with current state\n callback(auth.getSession())\n\n return () => {\n listeners.delete(callback)\n }\n },\n\n async refreshToken() {\n // Cookie-based auth doesn't need token refresh\n // The session cookie is refreshed automatically by the server\n return auth.getSession()\n },\n\n _handleAuthError() {\n clearSession()\n },\n }\n\n // Initialize: check for existing session and schedule refresh\n const existingSession = auth.getSession()\n if (existingSession && autoRefresh) {\n scheduleRefresh(existingSession)\n }\n\n return auth\n}\n"]}
|