@mediaviz/sdk 0.1.0 → 1.0.59

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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/dist/sdk.cjs +33 -240
  3. package/dist/sdk.esm.js +34 -239
  4. package/dist/sdk.umd.js +33 -240
  5. package/package.json +14 -8
  6. package/MediaViz.js +0 -126
  7. package/_oauth.js +0 -3
  8. package/admin.js +0 -93
  9. package/ai_model_credits.js +0 -22
  10. package/company.js +0 -54
  11. package/curated_albums.js +0 -85
  12. package/custom_albums.js +0 -78
  13. package/email_tokens.js +0 -64
  14. package/errors.js +0 -81
  15. package/health.js +0 -20
  16. package/index.js +0 -21
  17. package/keywords.js +0 -123
  18. package/oauth/.prettierrc +0 -6
  19. package/oauth/README.md +0 -76
  20. package/oauth/browser-smoke-test.html +0 -45
  21. package/oauth/implementation_plan.json +0 -106
  22. package/oauth/package-lock.json +0 -5236
  23. package/oauth/package.json +0 -28
  24. package/oauth/rollup.config.js +0 -21
  25. package/oauth/smoke-test.js +0 -27
  26. package/oauth/spec.md +0 -187
  27. package/oauth/src/__tests__/browser-smoke-test.test.js +0 -38
  28. package/oauth/src/__tests__/client.test.js +0 -556
  29. package/oauth/src/__tests__/errors.test.js +0 -73
  30. package/oauth/src/__tests__/http.test.js +0 -102
  31. package/oauth/src/__tests__/index.test.js +0 -53
  32. package/oauth/src/__tests__/package-fields.test.js +0 -29
  33. package/oauth/src/__tests__/pkce.test.js +0 -55
  34. package/oauth/src/__tests__/rollup-build.test.js +0 -58
  35. package/oauth/src/__tests__/smoke-test.test.js +0 -26
  36. package/oauth/src/__tests__/types.test.js +0 -29
  37. package/oauth/src/client.js +0 -180
  38. package/oauth/src/errors.js +0 -32
  39. package/oauth/src/http.js +0 -52
  40. package/oauth/src/index.js +0 -7
  41. package/oauth/src/pkce.js +0 -50
  42. package/oauth/src/types.js +0 -67
  43. package/oauth_authorization.js +0 -53
  44. package/oauth_clients.js +0 -18
  45. package/oauth_login.js +0 -24
  46. package/oauth_token.js +0 -30
  47. package/person.js +0 -54
  48. package/photos.js +0 -106
  49. package/photoupload.js +0 -55
  50. package/projects.js +0 -191
  51. package/rollup.config.js +0 -12
  52. package/search.js +0 -99
  53. package/users.js +0 -137
@@ -1,22 +0,0 @@
1
- export class AiModelCredits {
2
- constructor(ctx) { this._ctx = ctx; }
3
-
4
- async getModelCreditRelationship(modelName) {
5
- this._ctx.requireTokens();
6
- const path = `/api/v1/model_credit/${encodeURIComponent(modelName)}`;
7
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
8
- return data;
9
- }
10
-
11
- async upsertModelCreditRelationship({ modelName, newCreditValue } = {}) {
12
- this._ctx.requireTokens();
13
- let path = `/api/v1/model_credit/upsert`;
14
- const query = new URLSearchParams();
15
- if (modelName !== undefined) (Array.isArray(modelName) ? modelName : [modelName]).forEach(v => query.append('model_name', v));
16
- if (newCreditValue !== undefined) (Array.isArray(newCreditValue) ? newCreditValue : [newCreditValue]).forEach(v => query.append('new_credit_value', v));
17
- const qs = query.toString();
18
- if (qs) path += '?' + qs;
19
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken);
20
- return data;
21
- }
22
- }
package/company.js DELETED
@@ -1,54 +0,0 @@
1
- export class Company {
2
- constructor(ctx) { this._ctx = ctx; }
3
-
4
- async getAllCompanies() {
5
- this._ctx.requireTokens();
6
- const path = `/api/v1/company/`;
7
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
8
- return data;
9
- }
10
-
11
- async getCompanyById(companyId) {
12
- this._ctx.requireTokens();
13
- const path = `/api/v1/company/${encodeURIComponent(companyId)}`;
14
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
15
- return data;
16
- }
17
-
18
- async confirmCompanyCreditBalance(companyId, { photoCount, modelsList } = {}) {
19
- this._ctx.requireTokens();
20
- let path = `/api/v1/company/credit_balance/${encodeURIComponent(companyId)}`;
21
- const query = new URLSearchParams();
22
- if (photoCount !== undefined) (Array.isArray(photoCount) ? photoCount : [photoCount]).forEach(v => query.append('photo_count', v));
23
- if (modelsList !== undefined) (Array.isArray(modelsList) ? modelsList : [modelsList]).forEach(v => query.append('models_list', v));
24
- const qs = query.toString();
25
- if (qs) path += '?' + qs;
26
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
27
- return data;
28
- }
29
-
30
- async adminListActiveCompanyTokens() {
31
- this._ctx.requireTokens();
32
- const path = `/api/v1/company/admin_create/`;
33
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
34
- return data;
35
- }
36
-
37
- async adminCreateCompanyToken({ email } = {}) {
38
- this._ctx.requireTokens();
39
- let path = `/api/v1/company/admin_create/`;
40
- const query = new URLSearchParams();
41
- if (email !== undefined) (Array.isArray(email) ? email : [email]).forEach(v => query.append('email', v));
42
- const qs = query.toString();
43
- if (qs) path += '?' + qs;
44
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken);
45
- return data;
46
- }
47
-
48
- async adminRevokeCompanyToken(tokenId) {
49
- this._ctx.requireTokens();
50
- const path = `/api/v1/company/admin_create/${encodeURIComponent(tokenId)}/revoke/`;
51
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken);
52
- return data;
53
- }
54
- }
package/curated_albums.js DELETED
@@ -1,85 +0,0 @@
1
- function stripUndef(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
2
-
3
- export class CuratedAlbums {
4
- constructor(ctx) { this._ctx = ctx; }
5
-
6
- async createCuratedAlbum(projectTableName, name, description = undefined, confidenceValue = undefined) {
7
- this._ctx.requireTokens();
8
- const path = `/api/v1/curated_album/project/${encodeURIComponent(projectTableName)}`;
9
- const body = stripUndef({
10
- name: name,
11
- description: description,
12
- confidence_value: confidenceValue,
13
- });
14
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken, body);
15
- return data;
16
- }
17
-
18
- async getAllProjectCuratedAlbums(projectTableName) {
19
- this._ctx.requireTokens();
20
- const path = `/api/v1/curated_album/project/${encodeURIComponent(projectTableName)}`;
21
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
22
- return data;
23
- }
24
-
25
- async getCuratedAlbumPhotos(albumId, { ascOrDesc, lastId, limit, confidenceValue } = {}) {
26
- this._ctx.requireTokens();
27
- let path = `/api/v1/curated_album/photos/${encodeURIComponent(albumId)}/`;
28
- const query = new URLSearchParams();
29
- if (ascOrDesc !== undefined) (Array.isArray(ascOrDesc) ? ascOrDesc : [ascOrDesc]).forEach(v => query.append('asc_or_desc', v));
30
- if (lastId !== undefined) (Array.isArray(lastId) ? lastId : [lastId]).forEach(v => query.append('last_id', v));
31
- if (limit !== undefined) (Array.isArray(limit) ? limit : [limit]).forEach(v => query.append('limit', v));
32
- if (confidenceValue !== undefined) (Array.isArray(confidenceValue) ? confidenceValue : [confidenceValue]).forEach(v => query.append('confidence_value', v));
33
- const qs = query.toString();
34
- if (qs) path += '?' + qs;
35
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
36
- return data;
37
- }
38
-
39
- async getCuratedAlbumPhotosRanked(albumId, { ascOrDesc, lastId, limit, confidenceValue } = {}) {
40
- this._ctx.requireTokens();
41
- let path = `/api/v1/curated_album/photos/ranked/${encodeURIComponent(albumId)}/`;
42
- const query = new URLSearchParams();
43
- if (ascOrDesc !== undefined) (Array.isArray(ascOrDesc) ? ascOrDesc : [ascOrDesc]).forEach(v => query.append('asc_or_desc', v));
44
- if (lastId !== undefined) (Array.isArray(lastId) ? lastId : [lastId]).forEach(v => query.append('last_id', v));
45
- if (limit !== undefined) (Array.isArray(limit) ? limit : [limit]).forEach(v => query.append('limit', v));
46
- if (confidenceValue !== undefined) (Array.isArray(confidenceValue) ? confidenceValue : [confidenceValue]).forEach(v => query.append('confidence_value', v));
47
- const qs = query.toString();
48
- if (qs) path += '?' + qs;
49
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
50
- return data;
51
- }
52
-
53
- async getCuratedAlbumById(albumId) {
54
- this._ctx.requireTokens();
55
- const path = `/api/v1/curated_album/${encodeURIComponent(albumId)}`;
56
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
57
- return data;
58
- }
59
-
60
- async updateCuratedAlbum(albumId, { name, description, confidenceValue } = {}) {
61
- this._ctx.requireTokens();
62
- const path = `/api/v1/curated_album/${encodeURIComponent(albumId)}`;
63
- const body = stripUndef({
64
- name: name,
65
- description: description,
66
- confidence_value: confidenceValue,
67
- });
68
- const { data } = await this._ctx.client.request(path, 'PUT', this._ctx.accessToken, this._ctx.refreshToken, body);
69
- return data;
70
- }
71
-
72
- async deleteCuratedAlbum(albumId) {
73
- this._ctx.requireTokens();
74
- const path = `/api/v1/curated_album/${encodeURIComponent(albumId)}`;
75
- const { data } = await this._ctx.client.request(path, 'DELETE', this._ctx.accessToken, this._ctx.refreshToken);
76
- return data;
77
- }
78
-
79
- async convertCuratedAlbumToCustom(albumId) {
80
- this._ctx.requireTokens();
81
- const path = `/api/v1/curated_album/${encodeURIComponent(albumId)}/convert`;
82
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken);
83
- return data;
84
- }
85
- }
package/custom_albums.js DELETED
@@ -1,78 +0,0 @@
1
- function stripUndef(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
2
-
3
- export class CustomAlbums {
4
- constructor(ctx) { this._ctx = ctx; }
5
-
6
- async getCustomAlbumDetailById(customAlbumId) {
7
- this._ctx.requireTokens();
8
- const path = `/api/v1/custom_album/${encodeURIComponent(customAlbumId)}`;
9
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
10
- return data;
11
- }
12
-
13
- async getAllProjectCustomAlbums(projectTableName) {
14
- this._ctx.requireTokens();
15
- const path = `/api/v1/custom_album/project/${encodeURIComponent(projectTableName)}`;
16
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
17
- return data;
18
- }
19
-
20
- async getCustomAlbumPhotosById(customAlbumId, { ascOrDesc, lastId, limit } = {}) {
21
- this._ctx.requireTokens();
22
- let path = `/api/v1/custom_album/photos/${encodeURIComponent(customAlbumId)}/`;
23
- const query = new URLSearchParams();
24
- if (ascOrDesc !== undefined) (Array.isArray(ascOrDesc) ? ascOrDesc : [ascOrDesc]).forEach(v => query.append('asc_or_desc', v));
25
- if (lastId !== undefined) (Array.isArray(lastId) ? lastId : [lastId]).forEach(v => query.append('last_id', v));
26
- if (limit !== undefined) (Array.isArray(limit) ? limit : [limit]).forEach(v => query.append('limit', v));
27
- const qs = query.toString();
28
- if (qs) path += '?' + qs;
29
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
30
- return data;
31
- }
32
-
33
- async getRankedCustomAlbumById(customAlbumId, { ascOrDesc, lastId, limit } = {}) {
34
- this._ctx.requireTokens();
35
- let path = `/api/v1/custom_album/photos/ranked/${encodeURIComponent(customAlbumId)}/`;
36
- const query = new URLSearchParams();
37
- if (ascOrDesc !== undefined) (Array.isArray(ascOrDesc) ? ascOrDesc : [ascOrDesc]).forEach(v => query.append('asc_or_desc', v));
38
- if (lastId !== undefined) (Array.isArray(lastId) ? lastId : [lastId]).forEach(v => query.append('last_id', v));
39
- if (limit !== undefined) (Array.isArray(limit) ? limit : [limit]).forEach(v => query.append('limit', v));
40
- const qs = query.toString();
41
- if (qs) path += '?' + qs;
42
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
43
- return data;
44
- }
45
-
46
- async createProjectCustomAlbum(projectTableName, { name, description, photoIdInclusionList, photoIdRemovalList } = {}) {
47
- this._ctx.requireTokens();
48
- const path = `/api/v1/custom_album/project/${encodeURIComponent(projectTableName)}`;
49
- const body = stripUndef({
50
- name: name,
51
- description: description,
52
- photo_id_inclusion_list: photoIdInclusionList,
53
- photo_id_removal_list: photoIdRemovalList,
54
- });
55
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken, body);
56
- return data;
57
- }
58
-
59
- async updateCustomAlbum(albumId, { name, description, photoIdInclusionList, photoIdRemovalList } = {}) {
60
- this._ctx.requireTokens();
61
- const path = `/api/v1/custom_album/${encodeURIComponent(albumId)}`;
62
- const body = stripUndef({
63
- name: name,
64
- description: description,
65
- photo_id_inclusion_list: photoIdInclusionList,
66
- photo_id_removal_list: photoIdRemovalList,
67
- });
68
- const { data } = await this._ctx.client.request(path, 'PUT', this._ctx.accessToken, this._ctx.refreshToken, body);
69
- return data;
70
- }
71
-
72
- async deleteCustomAlbum(albumId) {
73
- this._ctx.requireTokens();
74
- const path = `/api/v1/custom_album/${encodeURIComponent(albumId)}`;
75
- const { data } = await this._ctx.client.request(path, 'DELETE', this._ctx.accessToken, this._ctx.refreshToken);
76
- return data;
77
- }
78
- }
package/email_tokens.js DELETED
@@ -1,64 +0,0 @@
1
- import { handleResponse } from './errors.js';
2
-
3
- function stripUndef(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
4
-
5
- export class EmailTokens {
6
- constructor(ctx) { this._ctx = ctx; }
7
-
8
- async requestEmailVerification({ email } = {}) {
9
- let path = `/api/v1/request-email-verification`;
10
- const query = new URLSearchParams();
11
- if (email !== undefined) (Array.isArray(email) ? email : [email]).forEach(v => query.append('email', v));
12
- const qs = query.toString();
13
- if (qs) path += '?' + qs;
14
- const resp = await fetch(this._ctx.baseUrl + path, { method: 'POST' });
15
- return handleResponse(resp);
16
- }
17
-
18
- async verifyEmail(token) {
19
- const resp = await fetch(this._ctx.baseUrl + `/api/v1/verify-email/${encodeURIComponent(token)}`, { method: 'POST' });
20
- return handleResponse(resp);
21
- }
22
-
23
- async requestPasswordReset({ email } = {}) {
24
- let path = `/api/v1/request-password-reset`;
25
- const query = new URLSearchParams();
26
- if (email !== undefined) (Array.isArray(email) ? email : [email]).forEach(v => query.append('email', v));
27
- const qs = query.toString();
28
- if (qs) path += '?' + qs;
29
- const resp = await fetch(this._ctx.baseUrl + path, { method: 'POST' });
30
- return handleResponse(resp);
31
- }
32
-
33
- async validateToken(token) {
34
- const body = stripUndef({
35
- token: token,
36
- });
37
- const resp = await fetch(this._ctx.baseUrl + `/api/v1/validate-token`, {
38
- method: 'POST',
39
- headers: { 'Content-Type': 'application/json' },
40
- body: JSON.stringify(body),
41
- });
42
- return handleResponse(resp);
43
- }
44
-
45
- async resetPassword(token, newPassword) {
46
- const body = stripUndef({
47
- token: token,
48
- new_password: newPassword,
49
- });
50
- const resp = await fetch(this._ctx.baseUrl + `/api/v1/reset-password`, {
51
- method: 'POST',
52
- headers: { 'Content-Type': 'application/json' },
53
- body: JSON.stringify(body),
54
- });
55
- return handleResponse(resp);
56
- }
57
-
58
- async deleteUserEmailTokens(userId) {
59
- this._ctx.requireTokens();
60
- const path = `/api/v1/admin/email_tokens/by_user/${encodeURIComponent(userId)}`;
61
- const { data } = await this._ctx.client.request(path, 'DELETE', this._ctx.accessToken, this._ctx.refreshToken);
62
- return data;
63
- }
64
- }
package/errors.js DELETED
@@ -1,81 +0,0 @@
1
- // Auto-generated — do not edit
2
-
3
- export class ApiError extends Error {
4
- constructor(message, status, requestId, body) {
5
- super(message);
6
- this.name = 'ApiError';
7
- this.status = status;
8
- this.requestId = requestId;
9
- this.body = body;
10
- }
11
- }
12
-
13
- export class ValidationError extends ApiError {
14
- constructor(body, status, requestId) {
15
- const detail = body.detail ?? [];
16
- const message = Array.isArray(detail)
17
- ? detail.map(d => `${d.loc.join('.')}: ${d.msg}`).join('; ')
18
- : String(detail);
19
- super(message, status, requestId, body);
20
- this.name = 'ValidationError';
21
- this.fieldErrors = Array.isArray(detail)
22
- ? detail.map(d => ({ loc: d.loc, msg: d.msg, type: d.type }))
23
- : [];
24
- }
25
- }
26
-
27
- export class NotFoundError extends ApiError {
28
- constructor(body, status, requestId) {
29
- super(body.detail ?? 'Resource not found', status, requestId, body);
30
- this.name = 'NotFoundError';
31
- }
32
- }
33
-
34
- export class RateLimitError extends ApiError {
35
- constructor(body, status, requestId, headers) {
36
- super(body.detail ?? 'Rate limited', status, requestId, body);
37
- this.name = 'RateLimitError';
38
- this.retryAfter = parseInt(headers.get('retry-after') ?? '', 10) || null;
39
- }
40
- }
41
-
42
- export class ServerError extends ApiError {
43
- constructor(body, status, requestId) {
44
- super(body.detail ?? 'Internal server error', status, requestId, body);
45
- this.name = 'ServerError';
46
- }
47
- }
48
-
49
- export async function handleResponse(response) {
50
- const requestId = response.headers.get('x-request-id');
51
-
52
- if (response.ok) {
53
- return response.status === 204 ? null : response.json();
54
- }
55
-
56
- let body;
57
- try {
58
- body = await response.json();
59
- } catch {
60
- body = { detail: response.statusText };
61
- }
62
-
63
- switch (response.status) {
64
- case 422:
65
- throw new ValidationError(body, response.status, requestId);
66
- case 404:
67
- throw new NotFoundError(body, response.status, requestId);
68
- case 429:
69
- throw new RateLimitError(body, response.status, requestId, response.headers);
70
- default:
71
- if (response.status >= 500) {
72
- throw new ServerError(body, response.status, requestId);
73
- }
74
- throw new ApiError(
75
- body.detail ?? 'Unknown error',
76
- response.status,
77
- requestId,
78
- body
79
- );
80
- }
81
- }
package/health.js DELETED
@@ -1,20 +0,0 @@
1
- import { handleResponse } from './errors.js';
2
-
3
- export class Health {
4
- constructor(ctx) { this._ctx = ctx; }
5
-
6
- async healthCheck() {
7
- const resp = await fetch(this._ctx.baseUrl + `/api/v1/health/`, { method: 'GET' });
8
- return handleResponse(resp);
9
- }
10
-
11
- async livenessCheck() {
12
- const resp = await fetch(this._ctx.baseUrl + `/api/v1/health/live/`, { method: 'GET' });
13
- return handleResponse(resp);
14
- }
15
-
16
- async readinessCheck() {
17
- const resp = await fetch(this._ctx.baseUrl + `/api/v1/health/ready`, { method: 'GET' });
18
- return handleResponse(resp);
19
- }
20
- }
package/index.js DELETED
@@ -1,21 +0,0 @@
1
- export { MediaViz } from './MediaViz.js';
2
- export * from './errors.js';
3
- export * from './_oauth.js';
4
- export * from './admin.js';
5
- export * from './ai_model_credits.js';
6
- export * from './company.js';
7
- export * from './curated_albums.js';
8
- export * from './custom_albums.js';
9
- export * from './email_tokens.js';
10
- export * from './health.js';
11
- export * from './keywords.js';
12
- export * from './oauth_authorization.js';
13
- export * from './oauth_clients.js';
14
- export * from './oauth_login.js';
15
- export * from './oauth_token.js';
16
- export * from './person.js';
17
- export * from './photos.js';
18
- export * from './photoupload.js';
19
- export * from './projects.js';
20
- export * from './search.js';
21
- export * from './users.js';
package/keywords.js DELETED
@@ -1,123 +0,0 @@
1
- function stripUndef(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
2
-
3
- export class Keywords {
4
- constructor(ctx) { this._ctx = ctx; }
5
-
6
- async createKeywordFilteringList(name, projectList = undefined) {
7
- this._ctx.requireTokens();
8
- const path = `/api/v1/keyword/`;
9
- const body = stripUndef({
10
- name: name,
11
- project_list: projectList,
12
- });
13
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken, body);
14
- return data;
15
- }
16
-
17
- async getUserKeywordFilteringLists() {
18
- this._ctx.requireTokens();
19
- const path = `/api/v1/keyword/user`;
20
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
21
- return data;
22
- }
23
-
24
- async getKeywordFilteringListAndProjectsById(keywordListId) {
25
- this._ctx.requireTokens();
26
- const path = `/api/v1/keyword/${encodeURIComponent(keywordListId)}`;
27
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
28
- return data;
29
- }
30
-
31
- async getKeywordFilteringListById(keywordListId) {
32
- this._ctx.requireTokens();
33
- const path = `/api/v1/keyword/list/${encodeURIComponent(keywordListId)}`;
34
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
35
- return data;
36
- }
37
-
38
- async getExistingKeywordFilteringListByProject(projectTableName) {
39
- this._ctx.requireTokens();
40
- const path = `/api/v1/keyword/project/${encodeURIComponent(projectTableName)}`;
41
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
42
- return data;
43
- }
44
-
45
- async getDefaultKeywordFilteringListByProject(projectTableName) {
46
- this._ctx.requireTokens();
47
- const path = `/api/v1/keyword/project/${encodeURIComponent(projectTableName)}/default`;
48
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
49
- return data;
50
- }
51
-
52
- async updateKeywordFilteringListLabels(keywordListId, listKeywordsToInclude, listKeywordsToExclude) {
53
- this._ctx.requireTokens();
54
- const path = `/api/v1/keyword/${encodeURIComponent(keywordListId)}`;
55
- const body = stripUndef({
56
- list_keywords_to_include: listKeywordsToInclude,
57
- list_keywords_to_exclude: listKeywordsToExclude,
58
- });
59
- const { data } = await this._ctx.client.request(path, 'PUT', this._ctx.accessToken, this._ctx.refreshToken, body);
60
- return data;
61
- }
62
-
63
- async updateKeywordFilteringListDetails(keywordListId, { name, projectList } = {}) {
64
- this._ctx.requireTokens();
65
- const path = `/api/v1/keyword/details/${encodeURIComponent(keywordListId)}`;
66
- const body = stripUndef({
67
- name: name,
68
- project_list: projectList,
69
- });
70
- const { data } = await this._ctx.client.request(path, 'PUT', this._ctx.accessToken, this._ctx.refreshToken, body);
71
- return data;
72
- }
73
-
74
- async addProjectsToKeywordFilteringList(keywordListId, { projectIds } = {}) {
75
- this._ctx.requireTokens();
76
- let path = `/api/v1/keyword/${encodeURIComponent(keywordListId)}/projects`;
77
- const query = new URLSearchParams();
78
- if (projectIds !== undefined) (Array.isArray(projectIds) ? projectIds : [projectIds]).forEach(v => query.append('project_ids', v));
79
- const qs = query.toString();
80
- if (qs) path += '?' + qs;
81
- const { data } = await this._ctx.client.request(path, 'POST', this._ctx.accessToken, this._ctx.refreshToken);
82
- return data;
83
- }
84
-
85
- async requestKeywordListExport(keywordListId) {
86
- this._ctx.requireTokens();
87
- const path = `/api/v1/keyword/export/${encodeURIComponent(keywordListId)}`;
88
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
89
- return data;
90
- }
91
-
92
- async requestKeywordListExportStatus(keywordListId) {
93
- this._ctx.requireTokens();
94
- const path = `/api/v1/keyword/export_status/${encodeURIComponent(keywordListId)}`;
95
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
96
- return data;
97
- }
98
-
99
- async getKeywordsAndIds() {
100
- this._ctx.requireTokens();
101
- const path = `/api/v1/keyword/all_keywords/id/label`;
102
- const { data } = await this._ctx.client.request(path, 'GET', this._ctx.accessToken, this._ctx.refreshToken);
103
- return data;
104
- }
105
-
106
- async removeProjectsFromKeywordFilteringList(keywordListId, { projectIds } = {}) {
107
- this._ctx.requireTokens();
108
- let path = `/api/v1/keyword/${encodeURIComponent(keywordListId)}/projects`;
109
- const query = new URLSearchParams();
110
- if (projectIds !== undefined) (Array.isArray(projectIds) ? projectIds : [projectIds]).forEach(v => query.append('project_ids', v));
111
- const qs = query.toString();
112
- if (qs) path += '?' + qs;
113
- const { data } = await this._ctx.client.request(path, 'DELETE', this._ctx.accessToken, this._ctx.refreshToken);
114
- return data;
115
- }
116
-
117
- async deleteKeywordFilteringListById(keywordListId) {
118
- this._ctx.requireTokens();
119
- const path = `/api/v1/keyword/${encodeURIComponent(keywordListId)}`;
120
- const { data } = await this._ctx.client.request(path, 'DELETE', this._ctx.accessToken, this._ctx.refreshToken);
121
- return data;
122
- }
123
- }
package/oauth/.prettierrc DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "singleQuote": true,
3
- "trailingComma": "all",
4
- "semi": true,
5
- "printWidth": 100
6
- }
package/oauth/README.md DELETED
@@ -1,76 +0,0 @@
1
- # @yourorg/oauth-sdk
2
-
3
- JavaScript SDK for the OAuth 2.0 Authorization Server. Implements Authorization Code + PKCE flow, token refresh, token revocation, and JWT payload decoding for confidential (server-side) clients.
4
-
5
- ## Installation
6
-
7
- ```sh
8
- npm install @yourorg/oauth-sdk
9
- ```
10
-
11
- ## Quick start
12
-
13
- ```js
14
- const { OAuthClient } = require('@yourorg/oauth-sdk');
15
-
16
- const oauthClient = new OAuthClient({
17
- baseUrl: 'https://api.example.com',
18
- clientId: process.env.OAUTH_CLIENT_ID,
19
- clientSecret: process.env.OAUTH_CLIENT_SECRET,
20
- redirectUri: 'https://myapp.com/callback',
21
- });
22
-
23
- // Step 1: initiate login
24
- app.get('/login', (req, res) => {
25
- const { url, state, code_verifier } = oauthClient.generateAuthorizationUrl();
26
- req.session.oauthState = state;
27
- req.session.codeVerifier = code_verifier;
28
- res.redirect(url);
29
- });
30
-
31
- // Step 2: handle callback
32
- app.get('/callback', async (req, res) => {
33
- const { code, state } = req.query;
34
- if (state !== req.session.oauthState) throw new Error('State mismatch');
35
-
36
- const tokens = await oauthClient.exchangeCode(code, req.session.codeVerifier);
37
- const payload = oauthClient.decodeAccessToken(tokens.access_token);
38
-
39
- req.session.userId = payload.user_id;
40
- req.session.accessToken = tokens.access_token;
41
- req.session.refreshToken = tokens.refresh_token;
42
- res.redirect('/dashboard');
43
- });
44
-
45
- // Step 3: make authenticated requests
46
- app.get('/dashboard', async (req, res) => {
47
- const { data, updated_tokens } = await oauthClient.request(
48
- 'https://api.example.com/me',
49
- 'GET',
50
- req.session.accessToken,
51
- req.session.refreshToken,
52
- );
53
-
54
- if (updated_tokens) {
55
- req.session.accessToken = updated_tokens.access_token;
56
- req.session.refreshToken = updated_tokens.refresh_token;
57
- }
58
-
59
- res.json(data);
60
- });
61
- ```
62
-
63
- > **Important:** `generateAuthorizationUrl()` returns `{ url, state, code_verifier }`. You **must** persist `state` and `code_verifier` (e.g. in an encrypted server-side session or short-lived encrypted cookie) and pass `code_verifier` back to `exchangeCode()` in the callback handler. The SDK does not store any state between calls.
64
-
65
- ## Method reference
66
-
67
- | Method | Description | Returns |
68
- |--------|-------------|---------|
69
- | `generateAuthorizationUrl(state?)` | Generates PKCE verifier + challenge, builds `/oauth/authorize` URL | `AuthorizationUrlResult` |
70
- | `exchangeCode(code, codeVerifier, redirectUri?)` | Exchanges authorization code for tokens | `Promise<TokenResponse>` |
71
- | `refreshAccessToken(refreshToken)` | Issues new tokens using a refresh token | `Promise<TokenResponse>` |
72
- | `revokeToken(token, tokenTypeHint?)` | Revokes an access or refresh token (RFC 7009) | `Promise<void>` |
73
- | `decodeAccessToken(accessToken)` | Decodes JWT payload without signature verification | `TokenPayload` |
74
- | `request(url, method, accessToken, refreshToken, body?)` | Authenticated request with automatic 401 retry | `Promise<AuthenticatedResponse>` |
75
-
76
- See [spec.md](../../spec.md) for full API documentation.