@omerlo/omerlo-webkit 0.0.4 → 0.0.6

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 (64) hide show
  1. package/README.md +24 -24
  2. package/dist/components/OmerloWebkit.svelte +2 -3
  3. package/dist/components/OmerloWebkit.svelte.d.ts +1 -1
  4. package/dist/omerlo/index.d.ts +32 -4
  5. package/dist/omerlo/reader/endpoints/categories.d.ts +18 -0
  6. package/dist/omerlo/reader/endpoints/categories.js +39 -0
  7. package/dist/omerlo/reader/endpoints/content-templates.d.ts +23 -0
  8. package/dist/omerlo/reader/endpoints/content-templates.js +34 -0
  9. package/dist/omerlo/reader/endpoints/contents.d.ts +122 -0
  10. package/dist/omerlo/reader/endpoints/contents.js +187 -0
  11. package/dist/omerlo/reader/endpoints/device.js +1 -1
  12. package/dist/omerlo/reader/endpoints/events.d.ts +32 -0
  13. package/dist/omerlo/reader/endpoints/events.js +45 -0
  14. package/dist/omerlo/reader/endpoints/magazines.d.ts +104 -0
  15. package/dist/omerlo/reader/endpoints/magazines.js +135 -0
  16. package/dist/omerlo/reader/endpoints/media.d.ts +65 -0
  17. package/dist/omerlo/reader/endpoints/media.js +133 -0
  18. package/dist/omerlo/reader/endpoints/menu.d.ts +31 -0
  19. package/dist/omerlo/reader/endpoints/menu.js +49 -0
  20. package/dist/omerlo/reader/endpoints/notification.d.ts +5 -5
  21. package/dist/omerlo/reader/endpoints/notification.js +6 -8
  22. package/dist/omerlo/reader/endpoints/oauth.js +1 -1
  23. package/dist/omerlo/reader/endpoints/organizations.d.ts +40 -0
  24. package/dist/omerlo/reader/endpoints/organizations.js +72 -0
  25. package/dist/omerlo/reader/endpoints/person.d.ts +30 -0
  26. package/dist/omerlo/reader/endpoints/person.js +39 -0
  27. package/dist/omerlo/reader/endpoints/profileType.d.ts +27 -0
  28. package/dist/omerlo/reader/endpoints/profileType.js +28 -0
  29. package/dist/omerlo/reader/endpoints/profiles.d.ts +70 -0
  30. package/dist/omerlo/reader/endpoints/profiles.js +97 -0
  31. package/dist/omerlo/reader/endpoints/projects.d.ts +28 -0
  32. package/dist/omerlo/reader/endpoints/projects.js +37 -0
  33. package/dist/omerlo/reader/endpoints/visuals.d.ts +34 -0
  34. package/dist/omerlo/reader/endpoints/visuals.js +44 -0
  35. package/dist/omerlo/reader/endpoints/webpage.d.ts +20 -0
  36. package/dist/omerlo/reader/endpoints/webpage.js +21 -0
  37. package/dist/omerlo/reader/fetchers.d.ts +30 -2
  38. package/dist/omerlo/reader/fetchers.js +12 -0
  39. package/dist/omerlo/reader/index.d.ts +18 -1
  40. package/dist/omerlo/reader/index.js +18 -0
  41. package/dist/omerlo/reader/server/email.d.ts +12 -0
  42. package/dist/omerlo/reader/server/email.js +30 -0
  43. package/dist/omerlo/reader/server/hooks.d.ts +1 -1
  44. package/dist/omerlo/reader/server/hooks.js +39 -20
  45. package/dist/omerlo/reader/server/index.d.ts +1 -0
  46. package/dist/omerlo/reader/server/index.js +1 -0
  47. package/dist/omerlo/reader/server/token.d.ts +6 -6
  48. package/dist/omerlo/reader/server/token.js +7 -7
  49. package/dist/omerlo/reader/server/utils.d.ts +4 -4
  50. package/dist/omerlo/reader/server/utils.js +13 -7
  51. package/dist/omerlo/reader/stores/user_session.d.ts +2 -2
  52. package/dist/omerlo/reader/stores/user_session.js +11 -9
  53. package/dist/omerlo/reader/utils/api.d.ts +1 -1
  54. package/dist/omerlo/reader/utils/api.js +4 -3
  55. package/dist/omerlo/reader/utils/assocs.d.ts +5 -4
  56. package/dist/omerlo/reader/utils/assocs.js +23 -0
  57. package/dist/omerlo/reader/utils/parseHelpers.d.ts +7 -0
  58. package/dist/omerlo/reader/utils/parseHelpers.js +22 -0
  59. package/dist/omerlo/reader/utils/request.d.ts +10 -8
  60. package/dist/omerlo/reader/utils/request.js +39 -11
  61. package/dist/omerlo/reader/utils/response.d.ts +1 -1
  62. package/dist/omerlo/reader/utils/response.js +1 -1
  63. package/eslint.config.js +11 -2
  64. package/package.json +3 -2
package/README.md CHANGED
@@ -7,8 +7,6 @@ over all window's tab, no need to refresh other tabs.
7
7
 
8
8
  ## Using the omerlo webkit
9
9
 
10
- ###
11
-
12
10
  Install the package `omerlo-webkit`
13
11
 
14
12
  ```sh
@@ -24,17 +22,17 @@ Copy the `.env.dist` to `.env` then update its values to match your Omerlo's app
24
22
  Create (or update) the file `src/hooks.server.ts` and add required hooks as follow
25
23
 
26
24
  ```ts
27
- import type { Handle } from "@sveltejs/kit";
25
+ import type { Handle } from '@sveltejs/kit';
28
26
 
29
27
  import { handleUserToken, handleReaderApi } from 'omerlo-webkit/reader/server';
30
- import { sequence } from "@sveltejs/kit/hooks";
28
+ import { sequence } from '@sveltejs/kit/hooks';
31
29
 
32
30
  // You can add custom hooks too
33
31
  const handleLocale: Handle = async ({ event, resolve }) => {
34
- const userLocale = 'en'; // you can fetch this value from cookie or w.e
35
- event.url.searchParams.append('locale', userLocale);
36
- return resolve(event);
37
- }
32
+ const userLocale = 'en'; // you can fetch this value from cookie or w.e
33
+ event.url.searchParams.append('locale', userLocale);
34
+ return resolve(event);
35
+ };
38
36
 
39
37
  export const handle = sequence(handleLocale, handleUserToken, handleReaderApi);
40
38
  ```
@@ -92,7 +90,7 @@ You'll need to create a login endpoint to add some required params such as the `
92
90
 
93
91
  ```ts
94
92
  // +server.ts
95
- import { error, redirect, type RequestHandler } from "@sveltejs/kit";
93
+ import { error, redirect, type RequestHandler } from '@sveltejs/kit';
96
94
  import { env } from '$env/dynamic/private';
97
95
  import jwt from 'jsonwebtoken';
98
96
 
@@ -104,39 +102,41 @@ export const GET: RequestHandler = ({ url }) => {
104
102
  if (!oauthProviderId) error(400, 'Missing oauthProviderId query parameter');
105
103
 
106
104
  const currentPath = url.searchParams.get('currentPath') || '/';
107
- const state = jwt.sign({ currentPath, oauthProviderId }, env.PRIVATE_JWT_SECRET, { expiresIn: '1h' })
105
+ const state = jwt.sign({ currentPath, oauthProviderId }, env.PRIVATE_JWT_SECRET, {
106
+ expiresIn: '1h'
107
+ });
108
108
 
109
109
  const redirectUrl = new URL(oauthUrl);
110
110
  redirectUrl.searchParams.set('state', state);
111
- redirectUrl.searchParams.set('redirect_uri', url.origin +'/oauth/callback');
111
+ redirectUrl.searchParams.set('redirect_uri', url.origin + '/oauth/callback');
112
112
 
113
113
  redirect(302, redirectUrl);
114
- }
114
+ };
115
115
  ```
116
116
 
117
117
  And then create a callback action.
118
118
 
119
119
  ```ts
120
- import { error, redirect, type RequestHandler } from "@sveltejs/kit";
120
+ import { error, redirect, type RequestHandler } from '@sveltejs/kit';
121
121
  import { env } from '$env/dynamic/private';
122
122
  import jwt from 'jsonwebtoken';
123
- import { exchangeAuthorizationCode, setAuthorizationCookies } from "omerlo-webkit/reader/server";
123
+ import { exchangeAuthorizationCode, setAuthorizationCookies } from 'omerlo-webkit/reader/server';
124
124
 
125
125
  export const GET: RequestHandler = async ({ url, cookies }) => {
126
126
  const redirectUri = url.origin + url.pathname;
127
127
  const state = getRequiredQueryParams(url, 'state');
128
128
  const code = getRequiredQueryParams(url, 'code');
129
- const {oauthProviderId, currentPath} = parseJwt(state);
129
+ const { oauthProviderId, currentPath } = parseJwt(state);
130
130
 
131
131
  try {
132
- const token = await exchangeAuthorizationCode({code, redirectUri, oauthProviderId})
132
+ const token = await exchangeAuthorizationCode({ code, redirectUri, oauthProviderId });
133
133
  setAuthorizationCookies(cookies, token);
134
- } catch(_err) {
135
- error(401, "Could not authenticate from the provider");
134
+ } catch (_err) {
135
+ error(401, 'Could not authenticate from the provider');
136
136
  }
137
137
 
138
138
  redirect(303, currentPath);
139
- }
139
+ };
140
140
 
141
141
  function getRequiredQueryParams(url: URL, paramsName: string): string {
142
142
  const value = url.searchParams.get(paramsName);
@@ -149,14 +149,14 @@ function getRequiredQueryParams(url: URL, paramsName: string): string {
149
149
  }
150
150
 
151
151
  interface State {
152
- oauthProviderId: string,
153
- currentPath: string
152
+ oauthProviderId: string;
153
+ currentPath: string;
154
154
  }
155
155
 
156
156
  function parseJwt(state: string): State {
157
157
  try {
158
158
  return jwt.verify(state, env.PRIVATE_JWT_SECRET) as State;
159
- } catch(_err) {
159
+ } catch (_err) {
160
160
  error(400, 'Invalid state');
161
161
  }
162
162
  }
@@ -168,13 +168,13 @@ To logout your user you can create an endpoint that will drop cookies used for a
168
168
 
169
169
  ```ts
170
170
  // +server.ts
171
- import { json, type RequestHandler } from "@sveltejs/kit";
171
+ import { json, type RequestHandler } from '@sveltejs/kit';
172
172
  import { clearAuthorizationCookies } from 'omerlo-webkit/reader/server';
173
173
 
174
174
  export const DELETE: RequestHandler = ({ cookies }) => {
175
175
  clearAuthorizationCookies(cookies);
176
176
  return json(201);
177
- }
177
+ };
178
178
  ```
179
179
 
180
180
  When a user is logout for any reason (401 or manually logout), the `invalidate('omerlo:user_session)` is triggered,
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
- import { initUserSession, type UserSession } from "../omerlo/reader/stores/user_session";
3
- import { onDestroy, onMount } from "svelte";
2
+ import { initUserSession, type UserSession } from '../omerlo/reader/stores/user_session';
3
+ import { onDestroy, onMount } from 'svelte';
4
4
 
5
5
  export let userSession: UserSession;
6
6
  let selfComponent: HTMLDivElement;
@@ -23,4 +23,3 @@
23
23
  <div id="omerlo-webkit" bind:this={selfComponent}>
24
24
  <slot></slot>
25
25
  </div>
26
-
@@ -1,4 +1,4 @@
1
- import { type UserSession } from "../omerlo/reader/stores/user_session";
1
+ import { type UserSession } from '../omerlo/reader/stores/user_session';
2
2
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
4
  $$bindings?: Bindings;
@@ -1,12 +1,40 @@
1
1
  export declare const useReader: (f: typeof fetch) => {
2
2
  notifications: {
3
- listTopics: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader/endpoints/notification").TopicSummary[]>>;
4
- subscribeToTopic: (params: import("./reader/endpoints/notification").SubscribtionParams) => Promise<import("./reader/utils/api").ApiResponse<unknown>>;
5
- unsubscribeFromTopic: (params: import("./reader/endpoints/notification").SubscribtionParams) => Promise<import("./reader/utils/api").ApiResponse<unknown>>;
3
+ listTopics: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").TopicSummary[]>>;
4
+ subscribeToTopic: (params: import("./reader").SubscriptionParams) => Promise<import("./reader/utils/api").ApiResponse<unknown>>;
5
+ unsubscribeFromTopic: (params: import("./reader").SubscriptionParams) => Promise<import("./reader/utils/api").ApiResponse<unknown>>;
6
6
  };
7
+ magazines: {
8
+ getIssue: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Issue>>;
9
+ getBlocks: (sectionId: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").IssueBlock[]>>;
10
+ searchContents: (issueId: string, q: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").SectionContent[]>>;
11
+ getSectionContents: (sectionId: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Content[]>>;
12
+ };
13
+ getMenu: (key: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Menu>>;
14
+ listMenus: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").MenuSummary[]>>;
15
+ listOrganizations: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").OrganizationSummary[]>>;
16
+ getOrganization: () => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Organization>>;
17
+ getOrgWebpage: (slug: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").OrgWebpage>>;
18
+ listOrgWebpages: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").WebpageSummary[]>>;
19
+ getMedia: () => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Media>>;
20
+ getMediaOrganization: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Organization>>;
21
+ listMediaOrganizations: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").OrganizationSummary[]>>;
22
+ getMediaEvent: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Event>>;
23
+ listMediaEvents: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").EventSummary[]>>;
24
+ listMediaEventBlocks: (id: string, params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").ProfileBlockKind[]>>;
25
+ getMediaPerson: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Person>>;
26
+ listMediaPersons: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").PersonSummary[]>>;
27
+ getMediaProject: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Project>>;
28
+ listMediaProjects: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").ProjectSummary[]>>;
29
+ getMediaProfileType: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").ProfileType>>;
30
+ listMediaProfileTypes: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").ProfileTypeSummary[]>>;
31
+ getContent: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Content>>;
32
+ listContents: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").ContentSummary[]>>;
33
+ listCategories: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Category[]>>;
34
+ getCategory: (id: string) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").Category>>;
7
35
  listOauthProviders: (params?: Partial<import("./reader/utils/api").PagingParams>) => Promise<import("./reader/utils/api").ApiResponse<import("./reader").OauthProviderSummary[]>>;
8
36
  getOauthUser: () => Promise<import("./reader/utils/api").ApiResponse<import("./reader").OauthUser>>;
9
- registerDevice: (params: import("./reader/endpoints/device").DeviceParams) => Promise<import("./reader/utils/api").ApiResponse<unknown>>;
37
+ registerDevice: (params: import("./reader").DeviceParams) => Promise<import("./reader/utils/api").ApiResponse<unknown>>;
10
38
  userInfo: () => Promise<import("./reader/utils/api").ApiResponse<import("./reader").UserInfo>>;
11
39
  verifyAccount: (params: import("./reader").VerifyAccountParams) => void;
12
40
  validateAccount: (params: import("./reader").ValidateAccountParams) => void;
@@ -0,0 +1,18 @@
1
+ import { type LocalesMetadata } from '../utils/response';
2
+ import { type ApiAssocs, type ApiData, type PagingParams } from '../utils/api';
3
+ export declare const categoriesFetchers: (f: typeof fetch) => {
4
+ listCategories: (params?: Partial<PagingParams>) => Promise<import("../utils/api").ApiResponse<Category[]>>;
5
+ getCategory: (id: string) => Promise<import("../utils/api").ApiResponse<Category>>;
6
+ };
7
+ export interface Category {
8
+ id: string;
9
+ svg: string;
10
+ name: string;
11
+ meta: {
12
+ locales: LocalesMetadata;
13
+ };
14
+ updatedAt: Date;
15
+ }
16
+ export declare function getCategory(f: typeof fetch): (id: string) => Promise<import("../utils/api").ApiResponse<Category>>;
17
+ export declare function listCategories(f: typeof fetch): (params?: Partial<PagingParams>) => Promise<import("../utils/api").ApiResponse<Category[]>>;
18
+ export declare function parseCategory(data: ApiData, _assoc: ApiAssocs): Category;
@@ -0,0 +1,39 @@
1
+ import { parseLocalesMetadata } from '../utils/response';
2
+ import { parseMany } from '../utils/api';
3
+ import { requestPublisher } from '../utils/request';
4
+ import { buildMeta } from '../utils/parseHelpers';
5
+ export const categoriesFetchers = (f) => {
6
+ return {
7
+ listCategories: listCategories(f),
8
+ getCategory: getCategory(f)
9
+ };
10
+ };
11
+ export function getCategory(f) {
12
+ return async (id) => {
13
+ const opts = { parser: parseCategory };
14
+ return requestPublisher(f, `media/categories/${id}`, opts);
15
+ };
16
+ }
17
+ export function listCategories(f) {
18
+ return async (params) => {
19
+ const opts = { parser: parseMany(parseCategory), queryParams: params };
20
+ return requestPublisher(f, `media/categories`, opts);
21
+ };
22
+ }
23
+ export function parseCategory(data, _assoc) {
24
+ let meta;
25
+ // NOTE: this is to support publisher public api v2 but also reader api v1
26
+ if (data.meta) {
27
+ meta = { locales: parseLocalesMetadata(data.meta) };
28
+ }
29
+ else {
30
+ meta = buildMeta(data.localized.locale);
31
+ }
32
+ return {
33
+ id: data.id,
34
+ name: data.name,
35
+ svg: data.svg_icon,
36
+ meta,
37
+ updatedAt: data.updated_at
38
+ };
39
+ }
@@ -0,0 +1,23 @@
1
+ import { type LocalesMetadata } from '../utils/response';
2
+ import type { ApiAssocs, ApiData } from '../utils/api';
3
+ export interface ContentTemplate {
4
+ id: string;
5
+ key: string;
6
+ name: string;
7
+ meta: {
8
+ locales: LocalesMetadata;
9
+ };
10
+ metadata: Record<string, string>;
11
+ enabledFields: string[];
12
+ updatedAt: Date;
13
+ }
14
+ export interface ContentBlockTemplate {
15
+ id: string;
16
+ key: string;
17
+ visual: {
18
+ allowedTypes: string[];
19
+ isEnabled: boolean;
20
+ };
21
+ }
22
+ export declare function parseContentBlockTemplate(data: ApiData, _assocs: ApiAssocs): ContentBlockTemplate;
23
+ export declare function parseContentTemplate(data: ApiData, _assocs: ApiAssocs): ContentTemplate;
@@ -0,0 +1,34 @@
1
+ import { parseLocalesMetadata } from '../utils/response';
2
+ import { buildMeta } from '../utils/parseHelpers';
3
+ export function parseContentBlockTemplate(data, _assocs) {
4
+ return {
5
+ id: data.id,
6
+ key: data.key,
7
+ visual: {
8
+ allowedTypes: data.visual.allowed_types,
9
+ isEnabled: data.visual.is_enabled
10
+ }
11
+ };
12
+ }
13
+ export function parseContentTemplate(data, _assocs) {
14
+ let name;
15
+ let meta;
16
+ if (data.localized) {
17
+ // NOTE: this is for retrocompatibility with public publisher api v2
18
+ name = data.localized.name;
19
+ meta = buildMeta(data.localized.locale);
20
+ }
21
+ else {
22
+ name = data.name;
23
+ meta = { locales: parseLocalesMetadata(data.meta) };
24
+ }
25
+ return {
26
+ id: data.id,
27
+ key: data.key,
28
+ name,
29
+ meta,
30
+ metadata: data.metadata,
31
+ enabledFields: data.enabled_fields,
32
+ updatedAt: data.updated_at
33
+ };
34
+ }
@@ -0,0 +1,122 @@
1
+ import type { Category } from './categories';
2
+ import type { ContentBlockTemplate, ContentTemplate } from './content-templates';
3
+ import { type Visual, type Slideshow, type Image, type Video } from './visuals';
4
+ import { type ApiAssocs, type ApiData, type PagingParams } from '../utils/api';
5
+ import { type LocalesMetadata } from '../utils/response';
6
+ import type { PersonSummary } from './person';
7
+ import type { OrganizationSummary } from './organizations';
8
+ export declare const contentsFetchers: (f: typeof fetch) => {
9
+ getContent: (id: string) => Promise<import("../utils/api").ApiResponse<Content>>;
10
+ listContents: (params?: Partial<PagingParams>) => Promise<import("../utils/api").ApiResponse<ContentSummary[]>>;
11
+ };
12
+ export interface ContentSeo {
13
+ title: string;
14
+ description: string;
15
+ }
16
+ export interface ContentSummary {
17
+ id: string;
18
+ template: ContentTemplate;
19
+ canonicalDomain: string | null;
20
+ canonicalUrl: string | null;
21
+ publishedAt: Date | null;
22
+ visibility: string | null;
23
+ categories: Category[];
24
+ showPublishedAt: boolean;
25
+ updatedAt: Date;
26
+ titleHtml: string;
27
+ titleText: string;
28
+ leadHtml: string | null;
29
+ leadText: string | null;
30
+ subtitleHtml: string | null;
31
+ subtitleText: string | null;
32
+ visual: Visual | null;
33
+ meta: {
34
+ locales: LocalesMetadata;
35
+ };
36
+ authors: (PersonSummary | OrganizationSummary)[];
37
+ }
38
+ export interface Content extends ContentSummary {
39
+ metadata: Record<string, string>;
40
+ blocks: ContentBlock[];
41
+ }
42
+ export type ContentBlockRichtext = {
43
+ id: string;
44
+ kind: 'richtext';
45
+ contentHtml: string;
46
+ visual: Visual | null;
47
+ template: ContentBlockTemplate | null;
48
+ };
49
+ export type ContentBlockData = {
50
+ id: string;
51
+ kind: 'data';
52
+ contentType: string;
53
+ data: string;
54
+ visual: Visual | null;
55
+ template: ContentBlockTemplate | null;
56
+ };
57
+ export type ContentBlockHTML = {
58
+ id: string;
59
+ kind: 'html';
60
+ contentHtml: string;
61
+ visual: Visual | null;
62
+ template: ContentBlockTemplate | null;
63
+ };
64
+ export type ContentBlockQuote = {
65
+ id: string;
66
+ kind: 'quote';
67
+ quoteHtml: string;
68
+ quoteText: string;
69
+ author: string;
70
+ visual: Visual | null;
71
+ template: ContentBlockTemplate | null;
72
+ };
73
+ export type ContentBlockRelatedContents = {
74
+ id: string;
75
+ kind: 'related-contents';
76
+ contents: Content[];
77
+ visual: Visual | null;
78
+ template: ContentBlockTemplate | null;
79
+ };
80
+ export type Answer = {
81
+ id: string;
82
+ contentHtml: string;
83
+ contentText: string;
84
+ };
85
+ export type ContentBlockQuestion = {
86
+ id: string;
87
+ kind: 'question';
88
+ questionHtml: string;
89
+ questionText: string;
90
+ acceptVoteUntil: Date;
91
+ answers: Answer[];
92
+ visual: Visual | null;
93
+ template: ContentBlockTemplate | null;
94
+ };
95
+ export type ContentBlockImage = {
96
+ id: string;
97
+ kind: 'image';
98
+ image: Image;
99
+ visual: Visual | null;
100
+ template: ContentBlockTemplate | null;
101
+ };
102
+ export type ContentBlockSlideshow = {
103
+ id: string;
104
+ kind: 'slideshow';
105
+ slideshow: Slideshow;
106
+ visual: Visual | null;
107
+ template: ContentBlockTemplate | null;
108
+ };
109
+ export type ContentBlockVideo = {
110
+ id: string;
111
+ kind: 'video';
112
+ video: Video;
113
+ visual: Visual | null;
114
+ template: ContentBlockTemplate | null;
115
+ };
116
+ export type ContentBlock = ContentBlockRichtext | ContentBlockData | ContentBlockHTML | ContentBlockQuote | ContentBlockRelatedContents | ContentBlockQuestion | ContentBlockImage | ContentBlockSlideshow | ContentBlockVideo;
117
+ export type ContentBlockType = 'richtext' | 'data' | 'html' | 'quote' | 'related-contents' | 'question' | 'image' | 'slideshow' | 'video';
118
+ export declare function getContent(f: typeof fetch): (id: string) => Promise<import("../utils/api").ApiResponse<Content>>;
119
+ export declare function listContents(f: typeof fetch): (params?: Partial<PagingParams>) => Promise<import("../utils/api").ApiResponse<ContentSummary[]>>;
120
+ export declare function parseContentSummary(data: ApiData, assocs: ApiAssocs): ContentSummary;
121
+ export declare function parseContent(data: ApiData, assocs: ApiAssocs): Content;
122
+ export declare function parseContentBlock(block: ApiData, assocs: ApiAssocs): ContentBlock | null;
@@ -0,0 +1,187 @@
1
+ import { parseVideo, parseImage, parseSlideshow, parseVisual } from './visuals';
2
+ import { requestPublisher } from '../utils/request';
3
+ import { parseMany } from '../utils/api';
4
+ import { getAssoc, getAssocs } from '../utils/assocs';
5
+ import { parseLocalesMetadata } from '../utils/response';
6
+ import { buildMeta, parseDate } from '../utils/parseHelpers';
7
+ export const contentsFetchers = (f) => {
8
+ return {
9
+ getContent: getContent(f),
10
+ listContents: listContents(f)
11
+ };
12
+ };
13
+ function baseBlock(data, assocs) {
14
+ return {
15
+ id: data.id,
16
+ kind: data.kind,
17
+ template: getBlockTemplate(data, assocs),
18
+ visual: parseVisual(data.visual, assocs)
19
+ };
20
+ }
21
+ export function getContent(f) {
22
+ return async (id) => {
23
+ const opts = { parser: parseContent };
24
+ return requestPublisher(f, `media/contents/${id}`, opts);
25
+ };
26
+ }
27
+ export function listContents(f) {
28
+ return async (params) => {
29
+ const opts = { parser: parseMany(parseContentSummary), queryParams: params };
30
+ return requestPublisher(f, `media/contents`, opts);
31
+ };
32
+ }
33
+ export function parseContentSummary(data, assocs) {
34
+ if (data.localized) {
35
+ // NOTE: This is to support publisher public api v2
36
+ return {
37
+ id: data.id,
38
+ template: getAssoc(assocs, 'templates', data.template_id),
39
+ canonicalDomain: data.canonical_domain,
40
+ canonicalUrl: data.canonical_url,
41
+ publishedAt: parseDate(data.published_at),
42
+ visibility: data.visibility,
43
+ categories: getAssocs(assocs, 'categories', data.category_ids),
44
+ showPublishedAt: data.show_published_at,
45
+ updatedAt: new Date(data.updated_at),
46
+ titleHtml: data.localized.title_html,
47
+ titleText: data.localized.title_text,
48
+ leadHtml: data.localized.lead_html,
49
+ leadText: data.localized.lead_text,
50
+ subtitleHtml: data.localized.subtitle_html,
51
+ subtitleText: data.localized.subtitle_text,
52
+ visual: parseVisual(data.visual, assocs),
53
+ meta: buildMeta(data.localized.locale),
54
+ authors: getAssocs(assocs, 'profiles', data.localized.author_ids)
55
+ };
56
+ }
57
+ else {
58
+ return {
59
+ id: data.id,
60
+ template: getAssoc(assocs, 'content_templates', data.template_id),
61
+ canonicalDomain: data.canonical_domain,
62
+ canonicalUrl: data.canonical_url,
63
+ publishedAt: parseDate(data.published_at),
64
+ visibility: data.visibility,
65
+ categories: getAssocs(assocs, 'categories', data.category_ids),
66
+ showPublishedAt: data.show_published_at,
67
+ updatedAt: new Date(data.updated_at),
68
+ titleHtml: data.title_html,
69
+ titleText: data.title_text,
70
+ leadHtml: data.lead_html,
71
+ leadText: data.lead_text,
72
+ subtitleHtml: data.subtitle_html,
73
+ subtitleText: data.subtitle_text,
74
+ visual: parseVisual(data.visual, assocs),
75
+ meta: { locales: parseLocalesMetadata(data.meta) },
76
+ authors: getAssocs(assocs, 'profiles', data.author_ids)
77
+ };
78
+ }
79
+ }
80
+ export function parseContent(data, assocs) {
81
+ let seo;
82
+ if (data.localized) {
83
+ seo = { title: data.localized.seo.title, description: data.localized.seo.description };
84
+ }
85
+ else {
86
+ seo = { title: data.seo.title, description: data.seo.description };
87
+ }
88
+ return {
89
+ ...parseContentSummary(data, assocs),
90
+ metadata: data.metadata,
91
+ seo,
92
+ blocks: data.localized.blocks
93
+ .map((block) => parseContentBlock(block, assocs))
94
+ .filter(Boolean)
95
+ };
96
+ }
97
+ const ContentBlockParser = {
98
+ richtext: parseContentBlockRichtext,
99
+ data: parseContentBlockData,
100
+ html: parseContentBlockHTML,
101
+ quote: parseContentBlockQuote,
102
+ 'related-contents': parseContentBlockRelatedContents,
103
+ question: parseContentBlockQuestion,
104
+ image: parseContentBlockImage,
105
+ slideshow: parseContentBlockSlideshow,
106
+ video: parseContentBlockVideo
107
+ };
108
+ export function parseContentBlock(block, assocs) {
109
+ const parser = ContentBlockParser[block.kind];
110
+ return parser ? parser(block, assocs) : null;
111
+ }
112
+ function getBlockTemplate(data, assocs) {
113
+ return data.template_id
114
+ ? getAssoc(assocs, 'block_templates', data.template_id)
115
+ : null;
116
+ }
117
+ function getBlockContent(data, assocs) {
118
+ return data.related_contents ? getAssocs(assocs, 'contents', data.related_contents) : [];
119
+ }
120
+ function parseContentBlockRichtext(data, assocs) {
121
+ return {
122
+ ...baseBlock(data, assocs),
123
+ contentHtml: data.content_html
124
+ };
125
+ }
126
+ function parseContentBlockData(data, assocs) {
127
+ return {
128
+ ...baseBlock(data, assocs),
129
+ contentType: data.content_type,
130
+ data: data.data
131
+ };
132
+ }
133
+ function parseContentBlockHTML(data, assocs) {
134
+ return {
135
+ ...baseBlock(data, assocs),
136
+ contentHtml: data.content_html
137
+ };
138
+ }
139
+ function parseContentBlockQuote(data, assocs) {
140
+ return {
141
+ ...baseBlock(data, assocs),
142
+ quoteHtml: data.quote_html,
143
+ quoteText: data.quote_text,
144
+ author: data.author
145
+ };
146
+ }
147
+ function parseContentBlockRelatedContents(data, assocs) {
148
+ const contents = getBlockContent(data, assocs);
149
+ return {
150
+ ...baseBlock(data, assocs),
151
+ contents
152
+ };
153
+ }
154
+ function parseContentBlockQuestion(data, assocs) {
155
+ return {
156
+ ...baseBlock(data, assocs),
157
+ questionHtml: data.question_html,
158
+ questionText: data.question_text,
159
+ acceptVoteUntil: new Date(data.accept_vote_until),
160
+ answers: data.answers?.map((answer) => parseAnswer(answer)) || []
161
+ };
162
+ }
163
+ function parseAnswer(data) {
164
+ return {
165
+ id: data.id,
166
+ contentHtml: data.content_html,
167
+ contentText: data.content_text
168
+ };
169
+ }
170
+ function parseContentBlockImage(data, assocs) {
171
+ return {
172
+ ...baseBlock(data, assocs),
173
+ image: parseImage(data.image, assocs)
174
+ };
175
+ }
176
+ function parseContentBlockSlideshow(data, assocs) {
177
+ return {
178
+ ...baseBlock(data, assocs),
179
+ slideshow: parseSlideshow(data.slideshow, assocs)
180
+ };
181
+ }
182
+ function parseContentBlockVideo(data, assocs) {
183
+ return {
184
+ ...baseBlock(data, assocs),
185
+ video: parseVideo(data.video, assocs)
186
+ };
187
+ }
@@ -1,7 +1,7 @@
1
1
  import { request } from '../utils/request';
2
2
  export const deviceFetchers = (f) => {
3
3
  return {
4
- registerDevice: registerDevice(f),
4
+ registerDevice: registerDevice(f)
5
5
  };
6
6
  };
7
7
  export function registerDevice(f) {
@@ -0,0 +1,32 @@
1
+ import type { Category } from './categories';
2
+ import { type ApiAssocs, type ApiData } from '../utils/api';
3
+ import type { LocalesMetadata } from '../utils/response';
4
+ import type { ProfileType } from './profileType';
5
+ import type { ProfileAddress, ProfileContact, ProfileDescription } from './profiles';
6
+ export interface EventSummary {
7
+ id: string;
8
+ profileType: ProfileType;
9
+ kind: string;
10
+ type: string;
11
+ isAllDay: boolean;
12
+ profileImageURL: string | null;
13
+ coverImageURL: string | null;
14
+ subscriptionURL: string | null;
15
+ meta: {
16
+ locales: LocalesMetadata;
17
+ };
18
+ name: string | null;
19
+ summaryHtml: string | null;
20
+ summaryText: string | null;
21
+ startsAt: Date | null;
22
+ endsAt: Date | null;
23
+ updatedAt: Date;
24
+ }
25
+ export interface Event extends EventSummary {
26
+ categories: Category[];
27
+ address: ProfileAddress | null;
28
+ contact: ProfileContact | null;
29
+ description: ProfileDescription | null;
30
+ }
31
+ export declare function parseEventSummary(data: ApiData, assocs: ApiAssocs): EventSummary;
32
+ export declare function parseEvent(data: ApiData, assocs: ApiAssocs): Event;