decentraland-dapps 24.8.0 → 24.9.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.
@@ -1,6 +1,13 @@
1
- import { ContentfulResponse, LocalizedField, LocalizedFieldType } from '@dcl/schemas';
1
+ import { ContentfulEntry, LocalizedField, LocalizedFieldType, ContentfulAsset, ContentfulLocale } from '@dcl/schemas';
2
2
  import { BaseClient } from '../../lib';
3
+ import { ContentfulEntryWithoutLocales, Fields } from './ContentfulClient.types';
3
4
  export declare class ContentfulClient extends BaseClient {
4
5
  constructor();
5
- fetchEntry<T extends Record<string, LocalizedField<LocalizedFieldType>>>(space: string, environment: string, id: string, contentType: string, token: string): Promise<ContentfulResponse<T>>;
6
+ fetchEntry<T extends Fields>(space: string, environment: string, id: string, locale?: ContentfulLocale): Promise<ContentfulEntryWithoutLocales<T>>;
7
+ fetchEntryAllLocales<T extends Record<string, LocalizedField<LocalizedFieldType>>>(space: string, environment: string, id: string): Promise<T>;
8
+ isWebpSupported(): boolean;
9
+ private optimize;
10
+ fetchAsset(space: string, environment: string, id: string): Promise<ContentfulAsset>;
11
+ fetchAssetsFromEntryFields<T extends Record<string, LocalizedField<LocalizedFieldType>>>(space: string, environment: string, fieldsInArray: T[]): Promise<Record<string, ContentfulAsset>>;
12
+ fetchEntriesFromEntryFields<T extends Record<string, LocalizedField<LocalizedFieldType>>>(space: string, environment: string, fields: T): Promise<Record<string, ContentfulEntry<T>>>;
6
13
  }
@@ -1,23 +1,178 @@
1
+ import { ContentfulLocale } from '@dcl/schemas';
1
2
  import { BaseClient } from '../../lib';
2
3
  export class ContentfulClient extends BaseClient {
3
4
  constructor() {
4
- super('https://cdn.contentful.com');
5
+ super('https://cms.decentraland.org');
5
6
  }
6
- async fetchEntry(space, environment, id, contentType, token) {
7
- const response = await this.rawFetch(`/spaces/${space}/environments/${environment}/entries/?` +
7
+ async fetchEntry(space, environment, id, locale = ContentfulLocale.enUS) {
8
+ const response = await this.rawFetch(`/spaces/${space}/environments/${environment}/entries/${id}/?` +
8
9
  new URLSearchParams({
9
- 'sys.id': id,
10
- content_type: contentType,
11
- locale: '*'
12
- }), {
13
- headers: {
14
- Authorization: `Bearer ${token}`
15
- }
16
- });
10
+ locale: locale
11
+ }));
17
12
  if (!response.ok) {
18
13
  throw new Error('Failed to fetch entity data');
19
14
  }
20
15
  return response.json();
21
16
  }
17
+ async fetchEntryAllLocales(space, environment, id) {
18
+ try {
19
+ const [responseEn, responseEs, responseZh] = await Promise.all([
20
+ this.fetchEntry(space, environment, id, ContentfulLocale.enUS),
21
+ this.fetchEntry(space, environment, id, ContentfulLocale.es),
22
+ this.fetchEntry(space, environment, id, ContentfulLocale.zh)
23
+ ]);
24
+ const combinedFields = Object.entries(responseEn.fields).reduce((acc, [key, value]) => {
25
+ const field = {
26
+ [ContentfulLocale.enUS]: value[ContentfulLocale.enUS]
27
+ };
28
+ if (responseEs.fields[key]?.[ContentfulLocale.es]) {
29
+ field[ContentfulLocale.es] =
30
+ responseEs.fields[key][ContentfulLocale.es];
31
+ }
32
+ if (responseZh.fields[key]?.[ContentfulLocale.zh]) {
33
+ field[ContentfulLocale.zh] =
34
+ responseZh.fields[key][ContentfulLocale.zh];
35
+ }
36
+ acc[key] = field;
37
+ return acc;
38
+ }, {});
39
+ return combinedFields;
40
+ }
41
+ catch (error) {
42
+ throw new Error('Error fetching entry in all locales');
43
+ }
44
+ }
45
+ isWebpSupported() {
46
+ const elem = typeof document !== 'undefined' && document.createElement('canvas');
47
+ if (elem && elem.getContext && elem.getContext('2d')) {
48
+ // was able or not to get WebP representation
49
+ return elem.toDataURL('image/webp').startsWith('data:image/webp');
50
+ }
51
+ // very old browser like IE 8, canvas not supported
52
+ return false;
53
+ }
54
+ optimize(image) {
55
+ if (!image) {
56
+ return {};
57
+ }
58
+ try {
59
+ if (image.startsWith('//')) {
60
+ image = `https:${image}`;
61
+ }
62
+ const url = new URL(image);
63
+ url.hostname = 'cms-images.decentraland.org';
64
+ url.searchParams.set('q', '80');
65
+ const jpg = new URL(url);
66
+ jpg.searchParams.set('fm', 'jpg');
67
+ jpg.searchParams.set('fl', 'progressive');
68
+ const png = new URL(url);
69
+ png.searchParams.set('fm', 'png');
70
+ const webp = new URL(url);
71
+ webp.searchParams.set('fm', 'webp');
72
+ const gif = new URL(url);
73
+ gif.searchParams.set('fm', 'gif');
74
+ const optimized = url.pathname.endsWith('.jpg') || url.pathname.endsWith('.jpeg')
75
+ ? this.isWebpSupported()
76
+ ? webp
77
+ : jpg
78
+ : url.pathname.endsWith('.webp')
79
+ ? webp
80
+ : url.pathname.endsWith('.png')
81
+ ? png
82
+ : url.pathname.endsWith('.gif')
83
+ ? gif
84
+ : undefined;
85
+ const originalFormat = url.pathname.endsWith('.jpg') || url.pathname.endsWith('.jpeg')
86
+ ? 'jpg'
87
+ : url.pathname.endsWith('.png')
88
+ ? 'png'
89
+ : url.pathname.endsWith('.webp')
90
+ ? 'webp'
91
+ : url.pathname.endsWith('.gif')
92
+ ? 'gif'
93
+ : undefined;
94
+ return {
95
+ jpg: jpg.toString(),
96
+ png: png.toString(),
97
+ webp: webp.toString(),
98
+ gif: gif.toString(),
99
+ original: url.toString(),
100
+ optimized: optimized && optimized.toString(),
101
+ originalFormat
102
+ };
103
+ }
104
+ catch (err) {
105
+ console.error(`Error optimizing:`, image, err);
106
+ return {};
107
+ }
108
+ }
109
+ async fetchAsset(space, environment, id) {
110
+ const response = await this.rawFetch(`/spaces/${space}/environments/${environment}/assets/${id}/`);
111
+ if (!response.ok) {
112
+ throw new Error('Failed to fetch asset data');
113
+ }
114
+ const asset = await response.json();
115
+ const locale = ContentfulLocale.enUS;
116
+ const transformedFields = {
117
+ title: {
118
+ [locale]: asset.fields.title
119
+ },
120
+ description: {
121
+ [locale]: asset.fields.description
122
+ },
123
+ file: {
124
+ [locale]: {
125
+ ...asset.fields.file,
126
+ url: this.optimize(asset.fields.file.url).optimized ||
127
+ asset.fields.file.url
128
+ }
129
+ }
130
+ };
131
+ return {
132
+ ...asset,
133
+ fields: transformedFields
134
+ };
135
+ }
136
+ async fetchAssetsFromEntryFields(space, environment, fieldsInArray) {
137
+ const assetIds = new Set();
138
+ fieldsInArray.forEach(fields => {
139
+ Object.values(fields).forEach(field => {
140
+ Object.values(field).forEach(content => {
141
+ if (content?.sys?.linkType === 'Asset') {
142
+ assetIds.add(content.sys.id);
143
+ }
144
+ });
145
+ });
146
+ });
147
+ if (assetIds.size === 0) {
148
+ return {};
149
+ }
150
+ const assets = await Promise.all(Array.from(assetIds).map(id => this.fetchAsset(space, environment, id)));
151
+ return assets.reduce((acc, asset) => {
152
+ acc[asset.sys.id] = asset;
153
+ return acc;
154
+ }, {});
155
+ }
156
+ async fetchEntriesFromEntryFields(space, environment, fields) {
157
+ const entryIds = new Set();
158
+ Object.values(fields).forEach(field => {
159
+ Object.values(field).forEach(content => {
160
+ if (content?.sys?.linkType === 'Entry') {
161
+ entryIds.add(content.sys.id);
162
+ }
163
+ });
164
+ });
165
+ if (entryIds.size === 0) {
166
+ return {};
167
+ }
168
+ const entries = await Promise.all(Array.from(entryIds).map(id => this.fetchEntryAllLocales(space, environment, id).then(fields => ({
169
+ sys: { id },
170
+ fields
171
+ }))));
172
+ return entries.reduce((acc, entry) => {
173
+ acc[entry.sys.id] = entry;
174
+ return acc;
175
+ }, {});
176
+ }
22
177
  }
23
178
  //# sourceMappingURL=ContentfulClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContentfulClient.js","sourceRoot":"","sources":["../../../src/modules/campaign/ContentfulClient.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C;QACE,KAAK,CAAC,4BAA4B,CAAC,CAAA;IACrC,CAAC;IAED,KAAK,CAAC,UAAU,CAGd,KAAa,EACb,WAAmB,EACnB,EAAU,EACV,WAAmB,EACnB,KAAa;QAEb,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAClC,WAAW,KAAK,iBAAiB,WAAW,YAAY;YACtD,IAAI,eAAe,CAAC;gBAClB,QAAQ,EAAE,EAAE;gBACZ,YAAY,EAAE,WAAW;gBACzB,MAAM,EAAE,GAAG;aACZ,CAAC,EACJ;YACE,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;SACF,CACF,CAAA;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAChD,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;IACxB,CAAC;CACF"}
1
+ {"version":3,"file":"ContentfulClient.js","sourceRoot":"","sources":["../../../src/modules/campaign/ContentfulClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { AlignmentFieldType, SysLink } from "@dcl/schemas";
2
+ type MarketingAdminFieldsWithoutLocales = {
3
+ name: string;
4
+ campaign?: SysLink<'Entry'>;
5
+ marketplaceHomepageBanner?: SysLink<'Entry'>;
6
+ marketplaceCollectiblesBanner?: SysLink<'Entry'>;
7
+ marketplaceCampaignCollectiblesBanner?: SysLink<'Entry'>;
8
+ builderCampaignBanner?: SysLink<'Entry'>;
9
+ };
10
+ type Fields = Record<string, any>;
11
+ type ContentfulContentWithoutLocales<X extends 'Asset' | 'Entry', T> = {
12
+ metadata: {
13
+ tags: string[];
14
+ concepts: string[];
15
+ };
16
+ sys: {
17
+ space: SysLink<'Space'>;
18
+ id: string;
19
+ type: X;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ environment: SysLink<'Environment'>;
23
+ publishedVersion: number;
24
+ revision: number;
25
+ } & (X extends 'Entry' ? {
26
+ contentType: SysLink<'ContentType'>;
27
+ } : {});
28
+ fields: T;
29
+ };
30
+ type ContentfulEntryWithoutLocales<T extends Fields> = ContentfulContentWithoutLocales<'Entry', T>;
31
+ type ContentfulAssetWithoutLocales<T extends Fields> = ContentfulContentWithoutLocales<'Asset', T>;
32
+ type BannerFieldsWithoutLocales = {
33
+ desktopTitle: string;
34
+ desktopTitleAlignment: AlignmentFieldType;
35
+ mobileTitle: string;
36
+ mobileTitleAlignment: AlignmentFieldType;
37
+ desktopText: any;
38
+ desktopTextAlignment: AlignmentFieldType;
39
+ mobileText: any;
40
+ mobileTextAlignment: AlignmentFieldType;
41
+ showButton: boolean;
42
+ buttonLink?: string;
43
+ buttonsText?: string;
44
+ desktopButtonAlignment: AlignmentFieldType;
45
+ mobileButtonAlignment: AlignmentFieldType;
46
+ fullSizeBackground: SysLink<'Asset'>;
47
+ mobileBackground: SysLink<'Asset'>;
48
+ logo?: SysLink<'Asset'>;
49
+ };
50
+ export type { MarketingAdminFieldsWithoutLocales, Fields, ContentfulContentWithoutLocales, ContentfulEntryWithoutLocales, ContentfulAssetWithoutLocales, BannerFieldsWithoutLocales };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ContentfulClient.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContentfulClient.types.js","sourceRoot":"","sources":["../../../src/modules/campaign/ContentfulClient.types.ts"],"names":[],"mappings":""}
@@ -3,5 +3,4 @@ export declare function campaignSagas(client: ContentfulClient, config: {
3
3
  space: string;
4
4
  environment: string;
5
5
  id: string;
6
- token: string;
7
6
  }): Generator<import("redux-saga/effects").ForkEffect<never>, void, unknown>;
@@ -3,30 +3,27 @@ import { ContentfulLocale, isSysLink } from '@dcl/schemas';
3
3
  import { isErrorWithMessage } from '../../lib';
4
4
  import { FETCH_CAMPAIGN_REQUEST } from './actions';
5
5
  import { fetchCampaignSuccess, fetchCampaignFailure } from './actions';
6
- const ADMIN_CONTENT_TYPE = 'admin';
7
6
  const BANNER_CONTENT_TYPE = 'banner';
8
7
  const MARKETING_CAMPAIGN_CONTENT_TYPE = 'marketingCampaign';
9
8
  export function* campaignSagas(client, config) {
10
9
  yield takeEvery(FETCH_CAMPAIGN_REQUEST, handleFetchCampaignRequest);
11
10
  function* handleFetchCampaignRequest(_) {
12
11
  try {
13
- const { items, includes } = (yield call([client, 'fetchEntry'], config.space, config.environment, config.id, ADMIN_CONTENT_TYPE, config.token));
14
- if (!items || (items && items.length === 0)) {
12
+ const { fields } = (yield call([client, 'fetchEntryAllLocales'], config.space, config.environment, config.id));
13
+ if (!fields) {
15
14
  throw new Error('Failed to fetch campaign data');
16
15
  }
17
- const assets = (includes.Asset ?? []).reduce((acc, asset) => {
18
- acc[asset.sys.id] = asset;
19
- return acc;
20
- }, {});
21
- const entries = (includes.Entry ?? []).reduce((acc, entry) => {
22
- acc[entry.sys.id] = entry;
23
- return acc;
24
- }, {});
25
- const banners = Object.entries(items[0].fields).reduce((acc, [key, value]) => {
16
+ const entries = (yield call([client, 'fetchEntriesFromEntryFields'], config.space, config.environment, fields));
17
+ const arrayOfFields = [
18
+ fields,
19
+ ...Object.values(entries).map(entry => entry.fields)
20
+ ];
21
+ const assets = (yield call([client, 'fetchAssetsFromEntryFields'], config.space, config.environment, arrayOfFields));
22
+ const banners = Object.entries(fields).reduce((acc, [key, value]) => {
26
23
  const fieldOnLocale = value[ContentfulLocale.enUS];
27
24
  if (isSysLink(fieldOnLocale)) {
28
25
  const linkedEntryId = fieldOnLocale.sys.id;
29
- const bannerEntry = entries[linkedEntryId];
26
+ const bannerEntry = Object.values(entries).find(entry => entry.sys.id === linkedEntryId);
30
27
  if (bannerEntry &&
31
28
  bannerEntry.sys.contentType.sys.id === BANNER_CONTENT_TYPE) {
32
29
  acc[key] = {
@@ -37,11 +34,12 @@ export function* campaignSagas(client, config) {
37
34
  }
38
35
  return acc;
39
36
  }, {});
40
- const campaignField = Object.values(items[0].fields).find(field => {
37
+ const campaignField = Object.values(fields).find(field => {
41
38
  const fieldOnLocale = field[ContentfulLocale.enUS];
42
39
  if (isSysLink(fieldOnLocale)) {
43
- const entry = entries[fieldOnLocale.sys.id];
44
- if (entry.sys.contentType.sys.id === MARKETING_CAMPAIGN_CONTENT_TYPE) {
40
+ const entry = Object.values(entries).find(entry => entry.sys.id === fieldOnLocale.sys.id);
41
+ if (entry &&
42
+ entry.sys.contentType.sys.id === MARKETING_CAMPAIGN_CONTENT_TYPE) {
45
43
  return entry.fields;
46
44
  }
47
45
  }
@@ -49,7 +47,7 @@ export function* campaignSagas(client, config) {
49
47
  });
50
48
  const campaignFields = campaignField?.[ContentfulLocale.enUS].sys.id
51
49
  ? entries[campaignField?.[ContentfulLocale.enUS].sys.id]
52
- ?.fields
50
+ .fields
53
51
  : undefined;
54
52
  yield put(fetchCampaignSuccess(banners, assets, campaignFields?.name, campaignFields?.marketplaceTabName, campaignFields?.mainTag?.[ContentfulLocale.enUS], campaignFields?.additionalTags?.[ContentfulLocale.enUS]));
55
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sagas.js","sourceRoot":"","sources":["../../../src/modules/campaign/sagas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sagas.js","sourceRoot":"","sources":["../../../src/modules/campaign/sagas.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "decentraland-dapps",
3
- "version": "24.8.0",
3
+ "version": "24.9.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -25,7 +25,7 @@
25
25
  "decentraland-crypto-fetch": "^2.0.1",
26
26
  "decentraland-transactions": "^2.18.3",
27
27
  "decentraland-ui": "^6.13.0",
28
- "decentraland-ui2": "^0.11.5",
28
+ "decentraland-ui2": "^0.12.0",
29
29
  "ethers": "^5.7.2",
30
30
  "events": "^3.3.0",
31
31
  "flat": "^5.0.2",